<> <> <> <> <<>> DIRECTORY Basics USING [ BITAND, HighHalf, LowHalf ], DoveInputOutput USING [ Peek, Poke ], Rope USING [ ], 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 [ byteAddress: CARD32, polarity: Polarity, value: BOOL ] ~ { address : CARD32 ~ byteAddress / 2; IF ((byteAddress MOD 8) # 7) THEN ERROR; <> 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 [ byteAddress: CARD32, polarity: Polarity ] RETURNS [ value: BOOL ] ~ { address : CARD32 ~ byteAddress / 2; read: CARD16 ~ Basics.BITAND[commandBitMask, DoveInputOutput.Peek[address]]; IF ((byteAddress MOD 8) # 7) THEN ERROR; <> 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[sparcResetRegisterByte, sparcResetPolarity, TRUE]; }; SparcResetAndStart: PUBLIC PROC ~ { ControlBitWrite[sparcResetRegisterByte, sparcResetPolarity, TRUE]; ControlBitWrite[sparcResetRegisterByte, sparcResetPolarity, FALSE]; }; SparcCacheDisable: PUBLIC PROC ~ { ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, FALSE]; }; <> <> <> <<};>> <<>> DMAState: TYPE = SparcSoftcardOps.DMAState; SetDMAState: PUBLIC PROC [dMAState: DMAState] ~ { IF dMAState = active THEN ControlBitWrite[dMAActiveRegisterByte, dMAActivePolarity, TRUE] ELSE ControlBitWrite[dMAActiveRegisterByte, dMAActivePolarity, FALSE]; }; DMAMode: TYPE = SparcSoftcardOps.DMAMode; SetDMAMode: PUBLIC PROC [dMAMode: DMAMode]~ { SELECT dMAMode FROM = printer => { ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, FALSE]; ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, FALSE]; }; = display => { ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, FALSE]; ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, TRUE]; }; = versatecOneShot => { ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, TRUE]; ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, FALSE]; }; = versatecStream => { ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, TRUE]; ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, TRUE]; }; ENDCASE; }; DMAAddressRegisterLoad: PUBLIC PROC [ byteAddress: CARD32 ] ~ { address: CARD32 _ byteAddress /8; DoveInputOutput.Poke[dMAAddressRegisterHighByte/2, Basics.HighHalf[address]]; DoveInputOutput.Poke[dMAAddressRegisterLowByte/2, Basics.LowHalf[address]]; }; WriteMapEntry: PUBLIC PROC [ mapEntry: SparcSoftcardOps.MapEntry ] ~ { windowNumber: CARD16; entryAddressHighByte, entryAddressLowByte: CARD32; mapEntryConcrete: CARD32; [windowNumber, entryAddressHighByte, entryAddressLowByte] _ ComputeEntryAddress[mapEntry]; mapEntryConcrete _ ConcreteFromEntry[mapEntry]; DoveInputOutput.Poke[mapWindowIndexRegisterByte/2, windowNumber]; <> DoveInputOutput.Poke[entryAddressHighByte/2, Basics.LowHalf[mapEntryConcrete]]; <> DoveInputOutput.Poke[entryAddressLowByte/2, Basics.HighHalf[mapEntryConcrete]]; <> }; ComputeEntryAddress: PROC [ mapEntry: SparcSoftcardOps.MapEntry ] RETURNS [windowNumber: CARD16, entryAddressHighByte, entryAddressLowByte: CARD32]~ { mapEntryNumber: CARD32; windowOffset: CARD16; <> <<>> SELECT mapEntry.vMSpace.name FROM <> = dMA => { mapEntryNumber _ 0E000H; IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR; <
> }; = iOP => { mapEntryNumber _ 0A000H; IF mapEntry.virtualAddressByte >= 1000000H THEN ERROR; <
> }; = cP => { mapEntryNumber _ 0A000H + 1000000H/softcardPageSizeByte; <> IF mapEntry.virtualAddressByte >= 400000H THEN ERROR; <
> }; = sparcUserData => { mapEntryNumber _ 0; IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR; <<***>> <<*** In this first implementation the address range is limited to 128 Meg. >> <<*** Only task 0 is implemented. >> <<***>> }; = sparcUserProgram => { mapEntryNumber _ 4000H; IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR; <<***>> <<*** In this first implementation the address range is limited to 128 Meg.>> <<*** Only task 0 is implemented. >> <<***>> }; = sparcSuperData => { mapEntryNumber _ 8000H; IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR; <> }; = sparcSuperProgram => { mapEntryNumber _ 0C000H; IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR; <> }; ENDCASE => ERROR; mapEntryNumber _ mapEntryNumber + mapEntry.virtualAddressByte/softcardPageSizeByte; <> windowNumber _ mapEntryNumber / mapEntriesPerWindow; windowOffset _ mapEntryNumber MOD mapEntriesPerWindow; <> entryAddressHighByte _ mapWindowBaseByte + mapEntryHighByteOffset + windowOffset * mapEntrySizeByte; entryAddressLowByte _ mapWindowBaseByte + mapEntryLowByteOffset + windowOffset * mapEntrySizeByte; }; ConcreteFromEntry: PROC [ mapEntry: SparcSoftcardOps.MapEntry ] RETURNS [mapEntryConcreteCard: CARD32] ~ { mapEntryConcrete: SparcSoftcardOps.MapEntryConcrete; mapEntryConcrete.readOnly _ mapEntry.flags.readOnly; mapEntryConcrete.referenced _ mapEntry.flags.referenced; mapEntryConcrete.dirty _ mapEntry.flags.dirty; mapEntryConcrete.nonCachable _ mapEntry.flags.nonCachable; mapEntryConcrete.interrupt _ mapEntry.flags.interrupt; mapEntryConcrete.task _ 0; <<***>> <<*** Now only task 0 is implemented>> <<***>> mapEntryConcrete.virtualPageHiHi _ 0; <<***>> <<*** Now only 128 Meg of VM>> <<***>> mapEntryConcrete.virtualPageHiLow _ 0; <<***>> <<*** Now only 128 Meg of VM>> <<***>> mapEntryConcrete.realPage _ mapEntry.realAddressByte/softcardPageSizeByte; mapEntryConcreteCard _ LOOPHOLE[mapEntryConcrete]; }; }.