DIRECTORY Basics USING [ BITAND, HighHalf, LowHalf ], DoveInputOutput USING [ Peek, Poke ], Rope USING [ ], SparcSoftcard, SparcSoftcardOps; 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; }; = sparcUserProgram => { mapEntryNumber _ 4000H; IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR; }; = 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; mapEntryConcrete.virtualPageHiHi _ 0; mapEntryConcrete.virtualPageHiLow _ 0; mapEntryConcrete.realPage _ mapEntry.realAddressByte/softcardPageSizeByte; mapEntryConcreteCard _ LOOPHOLE[mapEntryConcrete]; }; }. ΤSparcSoftcardOpsImpl.Mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Christophe Cuenod, September 12, 1988 9:35:03 am PDT Bill Jackson (bj) April 19, 1988 3:34:37 am PDT 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. If error here the address for the control bit is false. If error here the address for the control bit is false. SparcCacheFlushAndEnable: PUBLIC PROC ~ { ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, FALSE]; ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, TRUE]; }; Store window number Store high part of the entry Store low part of the entry Computes the entry number into the map Sets the base of mapEntryNumber Address range limited to 64 Meg. Address range limited to 16 Meg. CP is in the same VM than IOP but 16 Meg farther. Address range limited to 4 Meg. *** *** In this first implementation the address range is limited to 128 Meg. *** Only task 0 is implemented. *** *** *** In this first implementation the address range is limited to 128 Meg. *** Only task 0 is implemented. *** The supervisor address range is limited to 64 Meg. The supervisor address range is limited to 64 Meg. Adds the offset. Computes addresses *** *** Now only task 0 is implemented *** *** *** Now only 128 Meg of VM *** *** *** Now only 128 Meg of VM *** Κτ˜code•Mark outsideHeaderšœ™Kšœ<™K˜K˜—šœ˜Kšœ8œ˜>Kšœ8œ˜?K˜K˜—šœ˜Kšœ8œ˜>Kšœ8œ˜>K˜—Kšœ˜—˜K˜—K˜—šžœœœœ˜?Kšœ œ˜!KšœM˜MKšœK˜KK˜K˜—šž œœœ,˜FJšœœ˜Jšœ+œ˜2Jšœœ˜J˜JšœZ˜ZK˜Kšœ/˜/K˜šœA˜AK™—K˜šœO˜OK™—šœO˜OK™—K˜K˜—š žœœ*œœ-œ˜—J˜Jšœœ˜Jšœœ˜J˜J™&J™šœ˜!Jšœ™šœ ˜ Jšœ˜šœ)œœ˜6J™ —J˜—šœ ˜ Jšœ˜šœ)œœ˜6J™ —J˜—šœ ˜ šœ8˜8Jšœœœ™1—šœ(œœ˜5J™—J˜—šœ˜Jšœ˜šœ)œœ˜6J™J™JJ™ J™—J˜—šœ˜Jšœ˜šœ)œœ˜6J™J™IJ™ J™—J˜—šœ˜Jšœ˜šœ)œœ˜6J™2—J˜—šœ˜Jšœ˜šœ)œœ˜6J™2—J˜—Jšœœ˜—šœS˜SJ™—Jšœ4˜4Jšœœ˜6J˜J™J˜Jšœd˜dJšœb˜bK˜K˜—šžœœ)œœ˜jKšœ4˜4Kšœ4˜4Kšœ8˜8Kšœ.˜.Kšœ:˜:Kšœ6˜6K˜šœ˜K™K™#K™—K˜šœ%˜%K™Kšœ™K™—K˜šœ&˜&K™Kšœ™K™—K˜KšœJ˜JKšœœ˜2K˜—K˜Kšœ˜K˜——…—π"Έ