-- DicentraDiskDriverUtilsImpl.mesa -- Driver for Century Data AMS-315 disk drive and Xylogics SMD controller -- Jim Gasbarro 19-Mar-84 10:18:45 DIRECTORY DicentraDiskDriverUtils, DicentraInputOutput, Inline, Process USING [Pause, SecondsToTicks], ProcessorFace USING [SetMP]; DicentraDiskDriverUtilsImpl: PROGRAM IMPORTS DicentraInputOutput, Inline, Process, ProcessorFace EXPORTS DicentraDiskDriverUtils = BEGIN K64Words: LONG CARDINAL = LONG[64]*1024; FallenOffTheEndOfHyperspace: PUBLIC ERROR = CODE; HyperStore: PUBLIC PROC [ sourcePtr: LONG POINTER TO WORD, destOffset: LONG CARDINAL, wordCount: LONG CARDINAL] = BEGIN -- The destination area is referred to by an offset from the beginning of hyperspace. -- The microcode that implements WriteHyper has a feature that prevents it writing data across a 64K hyperspace boundary. Thats why some transfers have to be done in two parts. IF LOOPHOLE[DicentraDiskDriverUtils.hyperStart+destOffset+wordCount, LONG CARDINAL] > LOOPHOLE[DicentraDiskDriverUtils.hyperEndPlus1, LONG CARDINAL] THEN ERROR FallenOffTheEndOfHyperspace; WHILE wordCount>0 DO toNextBoundary: LONG CARDINAL ← K64Words - Inline.LowHalf[destOffset]; -- use Inline.LowHalf above because MOD on LONG CARDINAL generates bad code xferSize: CARDINAL ← CARDINAL[MIN[wordCount, toNextBoundary, K64Words-1]]; DicentraInputOutput.WriteHyper[from: sourcePtr, to: DicentraDiskDriverUtils.hyperStart+destOffset, words: xferSize]; sourcePtr ← sourcePtr + xferSize; destOffset ← destOffset + xferSize; wordCount ← wordCount - xferSize; ENDLOOP; END; HyperRead: PUBLIC PROC [destPtr: LONG POINTER TO WORD, sourceOffset: LONG CARDINAL, wordCount: LONG CARDINAL] = BEGIN -- The destination area is referred to by an offset from the beginning of hyperspace. -- Has to cope with microcode feature which will not transfer across 64K boundaries WHILE wordCount>0 DO toNextBoundary: LONG CARDINAL ← K64Words - Inline.LowHalf[sourceOffset]; xferSize: CARDINAL ← CARDINAL[MIN[wordCount, toNextBoundary, K64Words-1]]; IF Inline.HighHalf[DicentraDiskDriverUtils.hyperStart+sourceOffset] # Inline.HighHalf[DicentraDiskDriverUtils.hyperStart+sourceOffset+xferSize-1] THEN ERROR; DicentraInputOutput.ReadHyper[from: DicentraDiskDriverUtils.hyperStart+sourceOffset, to: destPtr, words: xferSize]; destPtr ← destPtr + xferSize; sourceOffset ← sourceOffset + xferSize; wordCount ← wordCount - xferSize; ENDLOOP; END; ShowMP: PUBLIC PROC [n: CARDINAL] = BEGIN ProcessorFace.SetMP[n]; Process.Pause[Process.SecondsToTicks[2]]; END; END.