<> <> <> <> <<>> DIRECTORY Basics USING [ BITAND, LowByte, HighHalf, LowHalf ], DoveInputOutput USING [ Noop, Peek, Poke ], Rope USING [ ], PrincOps USING [ PageNumber, RealPageNumber, wordsPerPage ], SparcSoftcard, SparcSoftcardOps; <> << 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; <> endingPage: NAT ~ cedarIOBaseByte / softcardPageSizeByte; <> pages: NAT ~ endingPage - startingPage; <> DoveInputOutput.Poke[mapWindowIndexRegisterWord16, iOPMapWindowIndex]; <> FOR i: NAT IN [0..pages) DO entryOffset: CARD16 ~ mapEntryWord16 * ( startingPage + i ); pageValue: NAT ~ mapEntryLowPattern + i; <> DoveInputOutput.Poke[iopMapHigh + entryOffset, mapEntryHighPattern]; <> DoveInputOutput.Poke[iopMapLow + entryOffset, pageValue]; ENDLOOP; <> DoveInputOutput.Poke[mapWindowIndexRegisterWord16, cPMapWindowIndex]; <> FOR i: NAT IN [0..pages) DO entryOffset: CARD16 ~ mapEntryWord16 * ( startingPage + i ); pageValue: NAT ~ mapEntryLowPattern + i; <> DoveInputOutput.Poke[cpMapHigh + entryOffset, mapEntryHighPattern]; <> DoveInputOutput.Poke[cpMapLow + entryOffset, pageValue]; ENDLOOP; }; InsertSoftcardPhyscialMemory: PUBLIC PROC [ reclaim: PROC [ PrincOps.RealPageNumber ] ] ~ { startingPage: NAT ~ cedarMemoryExtensionBaseWord16 / PrincOps.wordsPerPage; <> endingPage: NAT ~ cedarIOBaseWord16 / PrincOps.wordsPerPage; <> 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[]; }; <> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <<};>> <<>> <> <> }.