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"];
}.