<> <> <> <> <> <<>> DIRECTORY Basics USING [ LowByte, DoubleShiftRight ], DoveInputOutput USING [ Noop, Peek, Poke ], SparcSoftcardInit, PrincOps USING [ PageNumber, RealPageNumber, wordsPerPage ], SparcSoftcard, SparcSoftcardMap; SparcSoftcardInitImpl: PROGRAM IMPORTS Basics, DoveInputOutput, SparcSoftcardMap EXPORTS SparcSoftcardInit ~ { OPEN SparcSoftcard; <> PeekAtByteAd: PROC [byteAd: CARD32] RETURNS [content: CARD16] ~ { wordAd: CARD32 _ Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; content _ DoveInputOutput.Peek[wordAd]; }; PokeAtByteAd: PROC [byteAd: CARD32, content: CARD16] ~ { wordAd: CARD32 _ Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; DoveInputOutput.Poke[wordAd, content]; }; PeekPokePeekRestore: PROC [ byteAddress0: CARD32, content: CARD16, byteAddress1: CARD32 ] RETURNS [ lowByte: BYTE ] ~ { word0: CARD16 ~ PeekAtByteAd[byteAddress0]; PokeAtByteAd[byteAddress0, content]; { word1: CARD16 ~ PeekAtByteAd[byteAddress1]; lowByte _ Basics.LowByte[word1]; }; PokeAtByteAd[byteAddress0, word0]; }; <> SoftcardPresent: PUBLIC PROC RETURNS [ present: BOOL ] ~ { magic: BYTE ~ 05Ah; -- Arbitrary constant magicNot: BYTE ~ 0A5h; -- Another arbitrary constant value: BYTE ~ PeekPokePeekRestore[tRegisterByte, magic, tRegisterAlternateByte]; valueNot: BYTE ~ PeekPokePeekRestore[tRegisterAlternateByte, magicNot, tRegisterByte]; present _ (value=magic) AND (valueNot=magicNot); }; InitializeCPandIOPMaps: PUBLIC PROC ~ { iOPEntry, cPEntry: SparcSoftcardMap.MapEntry; iOPEntry.vMSpace.name _ iOP; cPEntry.vMSpace.name _ cP; iOPEntry.virtualAddressByte _ cedarMemoryExtensionBaseByte; iOPEntry.realAddressByte _ 0; cPEntry.virtualAddressByte _ cedarMemoryExtensionBaseByte; cPEntry.realAddressByte _ 0; FOR i: INT IN [0..cedarMemoryExtensionSizeByte/softcardPageSizeByte) DO SparcSoftcardMap.WriteMapEntry[iOPEntry]; iOPEntry.virtualAddressByte _ iOPEntry.virtualAddressByte + softcardPageSizeByte; iOPEntry.realAddressByte _ iOPEntry.realAddressByte+softcardPageSizeByte; SparcSoftcardMap.WriteMapEntry[cPEntry]; cPEntry.virtualAddressByte _ cPEntry.virtualAddressByte+softcardPageSizeByte; cPEntry.realAddressByte _ cPEntry.realAddressByte+softcardPageSizeByte; ENDLOOP; }; InsertSoftcardPhysicalMemory: PUBLIC PROC [ reclaim: PROC [ PrincOps.RealPageNumber ] ] ~ { startingPage: NAT ~ cedarMemoryExtensionBaseByte / (2*PrincOps.wordsPerPage); <> endingPage: NAT ~ (cedarMemoryExtensionBaseByte+cedarMemoryExtensionSizeByte) / (2*PrincOps.wordsPerPage); <> FOR p: PrincOps.PageNumber IN [startingPage..endingPage) DO reclaim[p]; ENDLOOP; }; InitializeSoftcard: PUBLIC PROC [ reclaim: PROC [ real: PrincOps.RealPageNumber ] ] ~ { IF ( NOT SoftcardPresent[] ) THEN RETURN; InitializeCPandIOPMaps[]; InsertSoftcardPhysicalMemory[reclaim]; DoveInputOutput.Noop[]; }; ResetSoftcard: PUBLIC PROC ~ { IF ( NOT SoftcardPresent[] ) THEN RETURN; InitializeCPandIOPMaps[]; DoveInputOutput.Noop[]; }; }.