DIRECTORY Basics USING [ FWORD, Card16FromH, HFromCard16, DoubleShiftRight, LongDiv, LongMult ], DoveInputOutput USING [ Peek, Poke ], SparcSoftcard, SparcSoftcardMap; SparcSoftcardMapImpl: PROGRAM IMPORTS Basics, DoveInputOutput EXPORTS SparcSoftcardMap ~ { MapEntry: TYPE ~ SparcSoftcardMap.MapEntry; MapEntryConcrete: TYPE = MACHINE DEPENDENT RECORD [ dirty: BOOLEAN, referenced: BOOLEAN, readOnly: BOOLEAN, nonCachable: BOOLEAN, interrupt: BOOLEAN, task: BYTE, virtualPageHiHi: [0..7H], -- 3 bits, virtualPageHiLow: [0..3H], -- 2 bits, trash: BOOL, realPage: [0..1FFFH] -- 13 bits ]; PeekAtByteAd: PROC [byteAd: CARD32] RETURNS [content: CARD16] ~ { wordAd: CARD32 _ Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; -- /2 content _ DoveInputOutput.Peek[wordAd]; }; PokeAtByteAd: PROC [byteAd: CARD32, content: CARD16] ~ { wordAd: CARD32 _ Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; -- /2 DoveInputOutput.Poke[wordAd, content]; }; ReadMapEntry: PUBLIC PROC [ mapEntry: MapEntry ] RETURNS [ oldMapEntry: MapEntry ] ~ { windowNumber: CARD16; entryAddressHighByte, entryAddressLowByte: CARD32; oldMapEntryConcrete: Basics.FWORD; [windowNumber, entryAddressHighByte, entryAddressLowByte] _ ComputeEntryAddress[mapEntry]; PokeAtByteAd[SparcSoftcard.mapWindowIndexRegisterByte, windowNumber]; oldMapEntryConcrete.hi _ Basics.HFromCard16[PeekAtByteAd[entryAddressHighByte]]; oldMapEntryConcrete.lo _ Basics.HFromCard16[PeekAtByteAd[entryAddressLowByte]]; oldMapEntry _ EntryFromConcrete[oldMapEntryConcrete]; oldMapEntry.vMSpace.name _ mapEntry.vMSpace.name; oldMapEntry.virtualAddressByte _ mapEntry.virtualAddressByte; -- for now, see EntryFromConcrete }; WriteMapEntry: PUBLIC PROC [ mapEntry: SparcSoftcardMap.MapEntry ] ~ { windowNumber: CARD16; entryAddressHighByte, entryAddressLowByte: CARD32; mapEntryConcrete: Basics.FWORD; [windowNumber, entryAddressHighByte, entryAddressLowByte] _ ComputeEntryAddress[mapEntry]; mapEntryConcrete _ ConcreteFromEntry[mapEntry]; PokeAtByteAd[SparcSoftcard.mapWindowIndexRegisterByte, windowNumber]; PokeAtByteAd[entryAddressHighByte, Basics.Card16FromH[mapEntryConcrete.hi]]; PokeAtByteAd[entryAddressLowByte, Basics.Card16FromH[mapEntryConcrete.lo]]; }; ComputeEntryAddress: PROC [ mapEntry: SparcSoftcardMap.MapEntry ] RETURNS [windowNumber: CARD16, entryAddressHighByte, entryAddressLowByte: CARD32]~ { mapEntryNumber: CARD16; 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/SparcSoftcard.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 + Basics.LongDiv[mapEntry.virtualAddressByte, SparcSoftcard.softcardPageSizeByte]; windowNumber _ mapEntryNumber / SparcSoftcard.mapEntriesPerWindow; windowOffset _ mapEntryNumber MOD SparcSoftcard.mapEntriesPerWindow; entryAddressHighByte _ SparcSoftcard.mapWindowBaseByte + SparcSoftcard.mapEntryHighByteOffset + windowOffset * SparcSoftcard.mapEntrySizeByte; entryAddressLowByte _ SparcSoftcard.mapWindowBaseByte + SparcSoftcard.mapEntryLowByteOffset + windowOffset * SparcSoftcard.mapEntrySizeByte; }; ConcreteFromEntry: PROC [ mapEntry: SparcSoftcardMap.MapEntry ] RETURNS [mapEntryConcreteFW: Basics.FWORD] ~ { mapEntryConcrete: 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 _ Basics.LongDiv[mapEntry.realAddressByte, SparcSoftcard.softcardPageSizeByte]; mapEntryConcreteFW _ LOOPHOLE[mapEntryConcrete]; }; EntryFromConcrete: PROC [ mapEntryConcreteFW: Basics.FWORD ] RETURNS [mapEntry: SparcSoftcardMap.MapEntry] ~ { mapEntryConcrete: MapEntryConcrete _ LOOPHOLE[mapEntryConcreteFW]; mapEntry.flags.readOnly _ mapEntryConcrete.readOnly; mapEntry.flags.referenced _ mapEntryConcrete.referenced; mapEntry.flags.dirty _ mapEntryConcrete.dirty; mapEntry.flags.nonCachable _ mapEntryConcrete.nonCachable; mapEntry.flags.interrupt _ mapEntryConcrete.interrupt; IF mapEntryConcrete.task#0 THEN ERROR; -- Now only task 0 is implemented mapEntry.vMSpace.task _ mapEntryConcrete.task; IF mapEntryConcrete.virtualPageHiHi*4+mapEntryConcrete.virtualPageHiLow#0 THEN ERROR; --Now only 128 Meg of VM mapEntry.virtualAddressByte _ 0; mapEntry.realAddressByte _ Basics.LongMult[mapEntryConcrete.realPage, SparcSoftcard.softcardPageSizeByte] }; }. œSparcSoftcardMapImpl.Mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Christophe Cuenod, October 18, 1988 9:26:44 am PDT Bill Jackson (bj) April 19, 1988 3:34:37 am PDT Christian Le Cocq November 1, 1988 3:57:55 pm PST Daybreak range [1.5 thru 3.5 Mbytes] is mapped onto [0 thru 2.0 Mbytes] of the Sparc softcard. Types Exact layout of the bits inside a map entry: Utilities Map Access Store window number 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 *** ΚΆ˜code•Mark outsideHeaderšœ™Kšœ<™ !˜_K˜K˜—š‘ œœœ,˜FKšœœ˜Kšœ+œ˜2Kšœœ˜K˜KšœZ˜ZK˜Kšœ/˜/K˜šœE˜EK™—K˜šœL˜LK™—šœK˜KK™—K˜K˜—š ‘œœ*œœ-œ˜—K˜Kšœœ˜Kšœœ˜K˜K™&K™šœ˜!Kšœ™šœ ˜ Kšœ˜šœ)œœ˜6K™ —K˜—šœ ˜ Kšœ˜šœ)œœ˜6K™ —K˜—šœ ˜ šœF˜FKšœœœ™1—šœ(œœ˜5K™—K˜—šœ˜Kšœ˜šœ)œœ˜6K™K™JK™ K™—K˜—šœ˜Kšœ˜šœ)œœ˜6K™K™IK™ K™—K˜—šœ˜Kšœ˜šœ)œœ˜6K™2—K˜—šœ˜Kšœ˜šœ)œœ˜6K™2—K˜—Kšœœ˜—šœr˜rK™—KšœB˜BKšœœ#˜DK˜K™K˜KšœŽ˜ŽKšœŒ˜ŒK˜K˜—š‘œœ)œœ˜nKšœ#˜#Kšœ4˜4Kšœ8˜8Kšœ.˜.Kšœ:˜:Kšœ6˜6K˜šœ˜K™K™#K™—K˜Kšœ%˜%šœ&˜&K™Kšœ™K™—K˜Kšœi˜iKšœœ˜0K˜K˜—š‘œœœœ*˜nKšœ%œ˜BKšœ4˜4Kšœ8˜8Kšœ.˜.Kšœ:˜:Kšœ6˜6K˜Kšœœœ !˜HKšœ.˜.K˜KšœHœœ ˜nKšœ!˜!K˜Kšœi˜iK˜——K˜Kšœ˜K˜——…—Šά