RasterControllerHeadDorado.mesa
Copyright Ó 1985, 1986, 1987 by Xerox Corporation. All rights reserved.
Tim Diebert, September 4, 1985 3:24:58 pm PDT
Eric Nickell, April 28, 1986 3:03:30 pm PDT
Dave Rumph, February 26, 1987 3:56:04 pm PST
DIRECTORY
Basics USING [BITAND, BITXOR, bitsPerWord],
DoradoInputOutput USING [InputNoPE, Output],
PrincOps USING [zMISC, NoTimeout],
PrincOpsUtils USING [AllocateNakedCondition, ConditionPointer],
Process USING [Detach, InitializeCondition, priorityRealTime, SetPriority],
RasterControllerDorado,
RasterControllerFace;
RasterControllerHeadDorado: CEDAR MONITOR
IMPORTS Basics, DoradoInputOutput, PrincOpsUtils, Process, RasterControllerDorado, RasterControllerFace
EXPORTS RasterControllerFace
~
BEGIN
OPEN RasterControllerDorado, RasterControllerFace;
Stuff for the software.
hardwareScanlineWords: PUBLIC NAT ← 4096;
hardwareScanlinePages: PUBLIC NAT ← hardwareScanlineWords / wordsPerPage;
hardwareScanlineBits: NAT ← hardwareScanlineWords * Basics.bitsPerWord;
interruptMask: WORD;
ltMicrocodeCondition: PrincOpsUtils.ConditionPointer;
channelProcs: ARRAY ExtendedChannel OF ChannelProc ← ALL[NIL];
mrbInUse: MRBPointer ← NIL; -- This is what we are really monitoring
RegisterChannelProc:
PUBLIC
ENTRY
PROC [channel: ExtendedChannel, proc: ChannelProc] ~ {
ENABLE UNWIND => NULL;
channelProcs[channel] ← proc;
};
Stuff for the hardware.
StartMicrocode:
PUBLIC
ENTRY
PROC [mrb: MRBPointer]
RETURNS [ok:
BOOL] ~
TRUSTED {
ENABLE UNWIND => NULL;
CallMicrocode:
PROC [MRBPointer]
RETURNS [ok:
BOOL] ~
TRUSTED
MACHINE
CODE
{PrincOps.zMISC, 245B};
mrb.status ← nullLTStatus;
IF ok ← CallMicrocode[mrb]
THEN {
mrbInUse ← mrb;
Process.Detach[FORK WatchMicrocodeCondition[]];
};
RETURN[ok];
};
WatchMicrocodeCondition:
ENTRY
PROC ~
TRUSTED {
ENABLE UNWIND => NULL;
Xor:
PROC [arg1, arg2: LTStatus]
RETURNS [LTStatus] ~
TRUSTED
INLINE {
RETURN[LOOPHOLE[Basics.BITXOR[LOOPHOLE[arg1], LOOPHOLE[arg2]]]];
};
oldStatus, newStatus, status: LTStatus ← nullLTStatus;
Process.SetPriority[Process.priorityRealTime];
UNTIL newStatus.microcodeDone
DO
oldStatus ← newStatus;
WHILE mrbInUse#
NIL
AND oldStatus = (newStatus ← mrbInUse.status)
DO
WAIT ltMicrocodeCondition;
ENDLOOP;
IF mrbInUse=NIL THEN EXIT;
status ← Xor[oldStatus, newStatus]; -- isolate only what changed
FOR chan: ExtendedChannel
IN ExtendedChannel
DO
proc: ChannelProc ← channelProcs[chan];
IF proc#NIL AND (status.channels[chan]#nullChannelStatus OR newStatus.microcodeDone) THEN proc[chan, status, newStatus];
ENDLOOP;
ENDLOOP;
mrbInUse ← NIL;
};
KillMicrocodeWatcher:
ENTRY
PROC ~
TRUSTED {
ENABLE UNWIND => NULL;
IF mrbInUse#
NIL
THEN {
mrbInUse.status.microcodeDone ← TRUE;
NOTIFY ltMicrocodeCondition^;
};
};
The printer microcode can be shut down by resetting the hardware:
ResetMicrocode:
PUBLIC
PROC [] =
TRUSTED
BEGIN
resetAll: WORD ~ 400B;
DoradoInputOutput.Output[resetAll, taskCmd];
KillMicrocodeWatcher[];
END;
ShutupMicrocode:
PUBLIC
PROC [] =
TRUSTED
BEGIN
shutupAll: WORD ~ 140000B;
DoradoInputOutput.Output[shutupAll, taskCmd];
KillMicrocodeWatcher[];
END;
config0: Config0 ← [FALSE, 0, TRUE, FALSE, 0, FALSE, 0]; -- On𡤊HSync'dly
SetUpForRealLineSync:
PUBLIC
PROC ~
TRUSTED {
config0.AHSyncGetsROSSync ← TRUE;
DoradoInputOutput.Output[LOOPHOLE[config0], config0Cmd];
};
SetUpForFakeLineSync:
PUBLIC
PROC ~
TRUSTED {
config0.AHSyncGetsROSSync ← FALSE;
DoradoInputOutput.Output[LOOPHOLE[config0], config0Cmd];
};
SetUpForRosClock:
PUBLIC
PROC ~
TRUSTED {
config0.ABGetsAEdgeClk ← TRUE;
config0.ABGetsTestClk ← FALSE;
DoradoInputOutput.Output[LOOPHOLE[config0], config0Cmd];
};
SetUpForFakeClock:
PUBLIC
PROC ~
TRUSTED {
config0.ABGetsAEdgeClk ← FALSE;
config0.ABGetsTestClk ← FALSE;
DoradoInputOutput.Output[LOOPHOLE[config0], config0Cmd];
};
SetUpForTestClock:
PUBLIC
PROC ~
TRUSTED {
config0.ABGetsAEdgeClk ← FALSE;
config0.ABGetsTestClk ← TRUE;
DoradoInputOutput.Output[LOOPHOLE[config0], config0Cmd];
};
LineSync:
PUBLIC
PROC ~
TRUSTED {
DoradoInputOutput.Output[2000B, taskCmd];
};
FakePixelClock:
PUBLIC
PROC ~
TRUSTED {
DoradoInputOutput.Output[1000B, taskCmd];
};
CheckConfig:
PUBLIC
PROC
RETURNS [HardwareConfig] ~
TRUSTED {
RETURN[LOOPHOLE[DoradoInputOutput.InputNoPE[config1Cmd], HardwareConfig]];
};
The definition of the control block stuff used by this microcode is as follows:
InitializeMRB:
PUBLIC
PROC [mrb: MRBPointer,
stb: STBPointer ←
NIL,
aRCB, bRCB, cRCB: RCBPointer ←
NIL,
ccb: CCBPointer ←
NIL,
flags:
CARDINAL ← 0
] ~
TRUSTED {
mrb.seal ← goodMRBSeal;
mrb.stb ← stb;
mrb.rcb[A] ← aRCB;
mrb.rcb[B] ← bRCB;
mrb.rcb[C] ← cRCB;
mrb.ccb ← ccb;
mrb.flags ← flags;
mrb.interruptMask ← interruptMask;
mrb.status ← nullLTStatus;
};
InitializeRCB:
PUBLIC
PROC [
rcb, next: RCBPointer ←
NIL,
bitmap:
LONG
POINTER ←
NIL,
activeWordsPerLine:
CARDINAL ← 0,
wordsPerLine:
CARDINAL ← 0,
lines:
INTEGER ← 0,
--Total number of scans to read
fMargin:
CARDINAL ← 0,
sRepeat, fRepeat:
INTEGER ← 0,
sReverse, fReverse:
BOOL ←
FALSE,
mosaic:
BOOL ←
FALSE,
bitsPerSample: [0..bitsPerWord] ← 1] ~
TRUSTED {
samplesPerWord: CARDINAL ~ 16/bitsPerSample;
indexMask:
CARDINAL ~
SELECT bitsPerSample
FROM
1 => 177777B,
2 => 177776B,
4 => 177774B,
8 => 177770B,
10, 12, 16 => 177760B,
ENDCASE => ERROR; -- BadItemSize[bitsPerSample];
bmValid: BOOL ~ bitmap#NIL;
munches: INTEGER ← (activeWordsPerLine+15)/16; --Picks up an extra
realBPS: [0..bitsPerWord]
← SELECT bitsPerSample
FROM
1 => 1,
2 => 2,
4 => 4,
8 => 8,
10, 12, 16 => 16,
ENDCASE => ERROR;
packedFMargin: CARDINAL ← fMargin*realBPS; --align it for the hardware
wordsPerLine ← RoundUpC[wordsPerLine, 16]; --Actually should generate ERROR if wordsPerLine#words
rcb^ ← [
seal: goodRCBSeal,
next: next,
extraLines: lines-2,
repeatCnt: sRepeat-1,
ccr: [
itemClockRes: 15-fRepeat,
reverse: fReverse,
mosaic: mosaic,
itemIs10Bit: bitsPerSample >= 10,
itemIs12Bit: bitsPerSample >= 12,
itemSize:
SELECT bitsPerSample
FROM
1 => b1,
2 => b2,
4 => b4,
8 => b8,
10 => b10,
12 => b12,
16 => b12, -- hardware can handle at most 12 bits
ENDCASE => ERROR
],
handshake: [bmValid, 0],
bitmap: IF sReverse THEN bitmap+(LONG[lines-1]*LONG[wordsPerLine]) ELSE bitmap,
activeMunches: munches-1,
wordsPerLine: IF sReverse THEN -wordsPerLine ELSE wordsPerLine,
indexIntoBuffer: Basics.BITAND[(IF fReverse
THEN (activeWordsPerLine*16)+packedFMargin-1
ELSE hardwareScanlineBits-packedFMargin), indexMask],
status: [
bitmapAddrValid: FALSE,
ws: 0,
rcbComplete: FALSE
]
];
};
InitializeCCB:
PUBLIC
PROC [
ccb, next: CCBPointer ←
NIL,
bitmap:
LONG
POINTER ←
NIL,
words:
CARDINAL ← 0,
lines:
INTEGER ← 0,
--Total number of scans to read
fMargin:
CARDINAL ← 0,
sRepeat, fRepeat:
INTEGER ← 0,
sReverse, fReverse:
BOOL ←
FALSE,
bitsPerSample: [0..bitsPerWord] ← 1,
cursorCtl: CursorCtl ← defaultCursorCtl,
modeCtl: ModeCtl ← defaultModeCtl,
halftoneCtl: HalftoneCtl ← defaultHalftoneCtl,
selCtl: SelCtl ← defaultSelCtl] ~
TRUSTED {
samplesPerWord: CARDINAL ~ 16/bitsPerSample;
alignedFMargin: CARDINAL ~ RoundUpC[fMargin, samplesPerWord];
fMarginWords: CARDINAL ~ alignedFMargin/samplesPerWord;
bmValid: BOOL ~ bitmap#NIL;
munches: INTEGER ← (fMarginWords+words+15)/16; --Picks up an extra
wordsPerLine: CARDINAL ← RoundUpC[words, 16]; --Actually should generate ERROR if wordsPerLine#words
ccb^ ← [
seal: goodRCBSeal,
next: next,
extraLines: lines-2,
repeatCnt: sRepeat-1,
ccr: [
itemClockRes: 15-fRepeat,
reverse: fReverse,
itemIs10Bit: bitsPerSample >= 10,
itemIs12Bit: bitsPerSample >= 12,
itemSize:
SELECT bitsPerSample
FROM
1 => b1,
2 => b2,
4 => b4,
8 => b8,
10 => b10,
12 => b12,
16 => b12, -- hardware can handle at most 12 bits
ENDCASE => ERROR
],
handshake: [bmValid, 0],
bitmap: IF sReverse THEN bitmap+(LONG[lines-1]*LONG[wordsPerLine]) ELSE bitmap,
activeMunches: munches-1,
wordsPerLine: IF sReverse THEN -wordsPerLine ELSE wordsPerLine,
indexIntoBuffer: IF fReverse THEN (wordsPerLine+fMarginWords)*16-1 ELSE 0,
status: [
bitmapAddrValid: FALSE,
ws: 0,
rcbComplete: FALSE
],
cursorCtl: cursorCtl,
modeCtl: modeCtl,
halftoneCtl: halftoneCtl,
selCtl: selCtl
];
};
BitsPerSample:
PUBLIC
PROC [lgBitsPerPixel: [0..4]]
RETURNS [[0..bitsPerWord]] ~ {
RETURN [
SELECT lgBitsPerPixel
FROM
0 => 1,
1 => 2,
2 => 4,
3 => 8,
4 => 16,
ENDCASE => ERROR];
};
PixelsPerWord:
PROC [lgBitsPerPixel: [0..4]]
RETURNS [[0..bitsPerWord]] ~ {
RETURN [
SELECT lgBitsPerPixel
FROM
0 => 16,
1 => 8,
2 => 4,
3 => 2,
4 => 1,
ENDCASE => ERROR];
};
Init:
PROC ~
TRUSTED {
[ltMicrocodeCondition, interruptMask] ← PrincOpsUtils.AllocateNakedCondition[];
Process.InitializeCondition[ltMicrocodeCondition, PrincOps.NoTimeout];
};
Init[];
END.