SparcSoftcardOpsImpl.Mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Christophe Cuenod, September 1, 1988 2:03:55 pm PDT
Bill Jackson (bj) April 19, 1988 3:34:37 am PDT
DIRECTORY
Basics USING [ BITAND, LowByte, HighHalf, LowHalf ],
DoveInputOutput USING [ Noop, Peek, Poke ],
Rope USING [ ],
PrincOps USING [ PageNumber, RealPageNumber, wordsPerPage ],
SparcSoftcard,
SparcSoftcardOps;
Test for the presence of a Sparc softcard and initialize the map properly for the CP and the IOP.
Daybreak range [1.5 thru 3.5 Mbytes] is mapped onto [0 thru 2.0 Mbytes] of the Sparc softcard.
SparcSoftcardOpsImpl: CEDAR PROGRAM
IMPORTS Basics, DoveInputOutput
EXPORTS SparcSoftcardOps ~ {
OPEN SparcSoftcard;
ControlBitWrite: PUBLIC PROC [ address: CARD32, polarity: Polarity, value: BOOL ] ~ {
SELECT TRUE FROM
( ( polarity = ActiveLow ) AND ( value ) ) =>
{ DoveInputOutput.Poke[address, 0] };
( ( polarity = ActiveLow ) AND ( NOT value ) ) =>
{ DoveInputOutput.Poke[address, commandBitMask] };
( ( polarity = ActiveHigh ) AND ( value ) ) =>
{ DoveInputOutput.Poke[address, commandBitMask] };
( ( polarity = ActiveHigh ) AND ( NOT value ) ) =>
{ DoveInputOutput.Poke[address, 0] };
ENDCASE;
};
ControlBitRead: PUBLIC PROC [ address: CARD32, polarity: Polarity ]
RETURNS [ value: BOOL ] ~ {
read: CARD16 ~ Basics.BITAND[commandBitMask, DoveInputOutput.Peek[address]];
SELECT TRUE FROM
( ( polarity = ActiveLow ) AND ( read = 0) ) => { value ← TRUE };
( ( polarity = ActiveLow ) AND ( read # 0) ) => { value ← FALSE };
( ( polarity = ActiveHigh ) AND ( read = 0) ) => { value ← FALSE };
( ( polarity = ActiveHigh ) AND ( read # 0) ) => { value ← TRUE };
ENDCASE;
};
SparcReset: PUBLIC PROC ~ {
ControlBitWrite[sparcResetRegisterWord16, sparcResetPolarity, TRUE];
};
SparcResetAndStart: PUBLIC PROC ~ {
ControlBitWrite[sparcResetRegisterWord16, sparcResetPolarity, TRUE];
ControlBitWrite[sparcResetRegisterWord16, sparcResetPolarity, FALSE];
};
SparcCacheDisable: PUBLIC PROC ~ {
ControlBitWrite[sparcCacheEnableRegisterWord16, sparcCacheEnablePolarity, FALSE];
};
SparcCacheFlushAndEnable: PUBLIC PROC ~ {
ControlBitWrite[sparcCacheEnableRegisterWord16, sparcCacheEnablePolarity, FALSE];
ControlBitWrite[sparcCacheEnableRegisterWord16, sparcCacheEnablePolarity, TRUE];
};
DMAState: TYPE = SparcSoftcardOps.DMAState;
SetDMAState: PUBLIC PROC [dMAState: DMAState] ~ {
IF dMAState = active THEN
ControlBitWrite[dMAActiveRegisterWord16, dMAActivePolarity, TRUE]
ELSE
ControlBitWrite[dMAActiveRegisterWord16, dMAActivePolarity, FALSE];
};
DMAMode: TYPE = SparcSoftcardOps.DMAMode;
SetDMAMode: PUBLIC PROC [dMAMode: DMAMode]~ {
SELECT dMAMode FROM
= printer => {
ControlBitWrite[dMAMode0RegisterWord16, dMAMode0Polarity, FALSE];
ControlBitWrite[dMAMode1RegisterWord16, dMAMode1Polarity, FALSE];
};
= display => {
ControlBitWrite[dMAMode0RegisterWord16, dMAMode0Polarity, FALSE];
ControlBitWrite[dMAMode1RegisterWord16, dMAMode1Polarity, TRUE];
};
= versatecOneShot => {
ControlBitWrite[dMAMode0RegisterWord16, dMAMode0Polarity, TRUE];
ControlBitWrite[dMAMode1RegisterWord16, dMAMode1Polarity, FALSE];
};
= versatecStream => {
ControlBitWrite[dMAMode0RegisterWord16, dMAMode0Polarity, TRUE];
ControlBitWrite[dMAMode1RegisterWord16, dMAMode1Polarity, TRUE];
};
ENDCASE;
};
DMAAddressRegisterLoad: PUBLIC PROC [ byteAddress: CARD32 ] ~ {
address: CARD32 ← byteAddress /8;
DoveInputOutput.Poke[dMAAddressRegisterHighWord16, Basics.HighHalf[address]];
DoveInputOutput.Poke[dMAAddressRegisterLowWord16, Basics.LowHalf[address]];
};
PeekPokePeekRestore: PUBLIC PROC [ address0: CARD32, content: CARD16, address1: CARD32 ]
RETURNS [ lowByte: BYTE ] ~ {
word0: CARD16 ~ DoveInputOutput.Peek[address0];
DoveInputOutput.Poke[address0, content];
{
word1: CARD16 ~ DoveInputOutput.Peek[address1];
lowByte ← Basics.LowByte[word1];
};
DoveInputOutput.Poke[address0, word0];
};
SoftcardPresent: PUBLIC PROC RETURNS [ present: BOOL ] ~ {
value: BYTE ~ PeekPokePeekRestore[tRegisterWord16, magic, tRegisterAlternateWord16];
valueNot: BYTE ~ PeekPokePeekRestore[tRegisterAlternateWord16, magicNot, tRegisterWord16];
present ← SELECT TRUE FROM
( value # magic ) => FALSE,
( valueNot # magicNot ) => FALSE,
ENDCASE => TRUE;
};
InitializeCPandIOPMaps: PUBLIC PROC ~ {
startingPage: NAT ~ cedarMemoryExtensionBaseByte / softcardPageSizeByte;
start memory at 1.5 meg in Daybreak adress space
endingPage: NAT ~ cedarIOBaseByte / softcardPageSizeByte;
end memory at 3.5 meg in Daybreak adress space
pages: NAT ~ endingPage - startingPage;
Setting the IOP map entries
DoveInputOutput.Poke[mapWindowIndexRegisterWord16, iOPMapWindowIndex];
Initialize the window index register
FOR i: NAT IN [0..pages) DO
entryOffset: CARD16 ~ mapEntryWord16 * ( startingPage + i );
pageValue: NAT ~ mapEntryLowPattern + i;
Fill the High part of the entry
DoveInputOutput.Poke[iopMapHigh + entryOffset, mapEntryHighPattern];
Fill the Low part of the entry
DoveInputOutput.Poke[iopMapLow + entryOffset, pageValue];
ENDLOOP;
Setting the CP map entries
DoveInputOutput.Poke[mapWindowIndexRegisterWord16, cPMapWindowIndex];
Initialize the window index register
FOR i: NAT IN [0..pages) DO
entryOffset: CARD16 ~ mapEntryWord16 * ( startingPage + i );
pageValue: NAT ~ mapEntryLowPattern + i;
Fill the High part of the entry
DoveInputOutput.Poke[cpMapHigh + entryOffset, mapEntryHighPattern];
Fill the Low part of the entry
DoveInputOutput.Poke[cpMapLow + entryOffset, pageValue];
ENDLOOP;
};
InsertSoftcardPhyscialMemory: PUBLIC PROC [
reclaim: PROC [ PrincOps.RealPageNumber ] ] ~ {
startingPage: NAT ~ cedarMemoryExtensionBaseWord16 / PrincOps.wordsPerPage;
start memory at 1.5 meg in Daybreak adress space
endingPage: NAT ~ cedarIOBaseWord16 / PrincOps.wordsPerPage;
end memory at 3.5 meg in Daybreak adress space
FOR p: PrincOps.PageNumber IN [startingPage..endingPage) DO
reclaim[p];
ENDLOOP;
};
DummyReclaimPhysicalPage: PROC [ real: PrincOps.RealPageNumber ] ~ { NULL };
InitializeSoftcard: PUBLIC PROC [ reclaim: PROC [ real: PrincOps.RealPageNumber ] ] ~ {
IF ( NOT SoftcardPresent[] ) THEN RETURN;
InitializeCPandIOPMaps[];
InsertSoftcardPhyscialMemory[reclaim];
DoveInputOutput.Noop[];
};
ResetSoftcard: PUBLIC PROC ~ {
IF ( NOT SoftcardPresent[] ) THEN RETURN;
InitializeCPandIOPMaps[];
DoveInputOutput.Noop[];
};
SoftcardCommand: Commander.CommandProc ~ {
softcardHere: BOOL ~ SoftcardPresent[];
IO.PutF[cmd.out, "SPARC Softcard %g\n",
IO.rope[IF ( softcardHere ) THEN "present" ELSE "absent"]];
IF ( softcardHere ) THEN InitializeSoftcard[DummyReclaimPhysicalPage];
};
DoradoByteSwap: PROC [ value: CARD16 ] RETURNS [ swap: CARD16 ] ~ { ERROR };
DoradoLockMem: PROC [ operation: CARD16, address: CARD16, value: CARD16, mask: CARD16 ] RETURNS [ result: CARD16 ] ~ { ERROR };
DoradoNotifyIOP: PROC [ notifyMask: CARD16 ] ~ { ERROR };
DoradoSetWakeUpBits: PROC ~ { ERROR };
DoradoNoop: PROC ~ { ERROR };
DoradoPeek: PROC [ address: CARD32 ] RETURNS [ word: UNSPECIFIED ] ~ { ERROR };
DoradoPoke: PROC [ address: CARD32, word: UNSPECIFIED ] ~ { ERROR };
InitializeTrapHandlers: PROC ~ TRUSTED {
TrapSupport.opTrapTable.misc[DoveInputOutput.aBYTESWAP] ← LOOPHOLE[DoradoByteSwap];
TrapSupport.opTrapTable.misc[DoveInputOutput.aLOCKMEM] ← LOOPHOLE[DoradoLockMem];
TrapSupport.opTrapTable.misc[DoveInputOutput.aNOTIFYIOP] ← LOOPHOLE[DoradoNotifyIOP];
TrapSupport.opTrapTable.misc[DoveInputOutput.aSETWAKEUPBITS] ← LOOPHOLE[DoradoSetWakeUpBits];
TrapSupport.opTrapTable.misc[DoveInputOutput.aNOOP] ← LOOPHOLE[DoradoNoop];
TrapSupport.opTrapTable.misc[DoveInputOutput.aPEEK] ← LOOPHOLE[DoradoPeek];
TrapSupport.opTrapTable.misc[DoveInputOutput.aPOKE] ← LOOPHOLE[DoradoPoke];
};
InitializeTrapHandlers[];
Commander.Register[key: "Softcard?", proc: SoftcardCommand, doc: "Test for the presence of a Sparc softcard.\n"];
}.