DIRECTORY Basics USING [HighHalf, LowHalf, UnsafeBlock], Commander USING [CommandProc, Register], DoveInputOutput USING [ Peek, Poke ], FS USING [ StreamOpen ], IO USING [ CharClass, EndOfStream, GetTokenRope, RIS, STREAM, UnsafeGetBlock], Rope USING [ROPE], SparcSoftcardOps, SparcSoftcard; SparcSoftcardLoader: CEDAR PROGRAM IMPORTS Basics, Commander, DoveInputOutput, FS, IO, SparcSoftcardOps ~ BEGIN ROPE: TYPE ~ Rope.ROPE; aDotOutIdentificationByte: CARD16 ~ 0; aDotOutEntryPointByte: CARD16 ~ 14H; aDotOutBssSizeByte: CARD16 ~ 0CH; aDotOutHeaderSizeByte: CARD16 ~ 20H; aDotOutIdentificationValue: CARD32 ~ 0103010BH; MyPeek: PROC [address: CARD32] RETURNS [word: UNSPECIFIED] ~ { word _ DoveInputOutput.Peek[address]; }; MyPoke: PROC [address: CARD32, word: UNSPECIFIED] ~ { DoveInputOutput.Poke[address, word]; }; InsertResetPointer: PUBLIC PROC [resetVector: CARD32] ~ { instruction: CARD32 _ 10800000H; -- ba 0 IF resetVector >= 1000000H THEN ERROR; -- verify max offest instruction _ instruction + resetVector/4; -- add offsett DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2, Basics.HighHalf[instruction]]; DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2 + 1, Basics.LowHalf[instruction]]; instruction _ 01000000H; -- nop DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2 + 2, Basics.HighHalf[instruction]]; DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2 + 3, Basics.LowHalf[instruction]]; }; CmdTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = { rope _ NIL; rope _ stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token; }; SparcSoftcardLoaderProc: Commander.CommandProc ~ { GetLong: PROC [byteAddress: CARD16] RETURNS [result: CARD32] = { IF (byteAddress MOD 4) # 0 THEN ERROR; result _ buffer[byteAddress/2] * 65536 + buffer[byteAddress/2 + 1]; }; SetOneMoreMapPage: PROC ~ { backdoorEntry.virtualAddressByte _ SparcSoftcard.cedarBackDoorBaseByte; superTextEntry.virtualAddressByte _ loadAddress; superDataEntry.virtualAddressByte _ loadAddress; backdoorEntry.realAddressByte _ loadAddress + SparcSoftcard.cedarMemoryExtensionSizeByte; superTextEntry.realAddressByte _ loadAddress + SparcSoftcard.cedarMemoryExtensionSizeByte; superDataEntry.realAddressByte _ loadAddress + SparcSoftcard.cedarMemoryExtensionSizeByte; SparcSoftcardOps.WriteMapEntry[backdoorEntry]; SparcSoftcardOps.WriteMapEntry[superTextEntry]; SparcSoftcardOps.WriteMapEntry[superDataEntry]; }; in: IO.STREAM _ IO.RIS[cmd.commandLine]; fileName: ROPE _ GetCmdToken[in]; inputFile: IO.STREAM _ FS.StreamOpen[fileName: fileName, accessOptions: $read]; startAddress, loadAddress: CARD32; bssSize: INT32; backdoorEntry, superTextEntry, superDataEntry: SparcSoftcardOps.MapEntry; backdoorPointerWord16: CARD32; bufSize: NAT = 1000H; buffer: ARRAY [0..bufSize/2) OF CARD16; block: Basics.UnsafeBlock; readSize: CARD16; TRUSTED { block _ [base: @buffer, count: bufSize]; readSize _ IO.UnsafeGetBlock[inputFile, block]; }; IF readSize # bufSize THEN ERROR; IF GetLong[aDotOutIdentificationByte] # aDotOutIdentificationValue THEN ERROR; startAddress _ GetLong[aDotOutEntryPointByte]; IF (startAddress MOD SparcSoftcard.softcardPageSizeByte) # aDotOutHeaderSizeByte THEN ERROR; loadAddress _ startAddress - aDotOutHeaderSizeByte; bssSize _ GetLong[aDotOutBssSizeByte]; SparcSoftcardOps.SparcReset[]; SparcSoftcardOps.SparcCacheDisable[]; backdoorEntry.vMSpace.name _ cP; superTextEntry.vMSpace.name _ sparcSuperProgram; superDataEntry.vMSpace.name _ sparcSuperData; backdoorEntry.virtualAddressByte _ SparcSoftcard.cedarBackDoorBaseByte; backdoorEntry.realAddressByte _ SparcSoftcard.cedarMemoryExtensionSizeByte; SparcSoftcardOps.WriteMapEntry[backdoorEntry]; superTextEntry.virtualAddressByte _ 0; superTextEntry.realAddressByte _ SparcSoftcard.cedarMemoryExtensionSizeByte; SparcSoftcardOps.WriteMapEntry[superTextEntry]; superDataEntry.virtualAddressByte _ 0; superDataEntry.realAddressByte _ SparcSoftcard.cedarMemoryExtensionSizeByte; SparcSoftcardOps.WriteMapEntry[superDataEntry]; InsertResetPointer[startAddress]; WHILE readSize = bufSize DO IF (loadAddress MOD SparcSoftcard.softcardPageSizeByte) = 0 THEN { SetOneMoreMapPage[]; backdoorPointerWord16 _ SparcSoftcard.cedarBackDoorBaseByte/2; }; FOR i: NAT IN [0..bufSize/2) DO DoveInputOutput.Poke[backdoorPointerWord16, buffer[i]]; backdoorPointerWord16 _ backdoorPointerWord16 + 1; ENDLOOP; TRUSTED { readSize _ IO.UnsafeGetBlock[inputFile, block]; }; loadAddress _ loadAddress + bufSize; ENDLOOP; IF readSize # 0 THEN ERROR; WHILE bssSize > 0 DO IF (loadAddress MOD SparcSoftcard.softcardPageSizeByte) = 0 THEN { SetOneMoreMapPage[]; backdoorPointerWord16 _ SparcSoftcard.cedarBackDoorBaseByte/2; }; FOR i: NAT IN [0..bufSize/2) DO DoveInputOutput.Poke[backdoorPointerWord16, 0]; backdoorPointerWord16 _ backdoorPointerWord16 + 1; ENDLOOP; loadAddress _ loadAddress + bufSize; bssSize _ bssSize - bufSize; ENDLOOP; backdoorEntry.virtualAddressByte _ SparcSoftcard.cedarBackDoorBaseByte; backdoorEntry.realAddressByte _ SparcSoftcard.cedarMemoryExtensionSizeByte; SparcSoftcardOps.WriteMapEntry[backdoorEntry]; backdoorEntry.virtualAddressByte _ SparcSoftcard.cedarBackDoorBaseByte + SparcSoftcard.softcardPageSizeByte; backdoorEntry.realAddressByte _ SparcSoftcard.cedarMemoryExtensionSizeByte + SparcSoftcard.softcardPageSizeByte; SparcSoftcardOps.WriteMapEntry[backdoorEntry]; SparcSoftcardOps.SparcResetAndStart[]; }; Commander.Register[ key: "SparcSoftcardLoader", proc: SparcSoftcardLoaderProc, doc: "Loads a a.out file into the SparcSoftcard memory"]; END. SparcSoftcardLoader.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. First created by Christophe Cuenod, September 12, 1988 3:48:32 pm PDT Loads a single a.out file into the SparcSoftcard Basics USING [BITAND, BITNOT, HighHalf, LowHalf, UnsafeBlock], Insert by hand the instruction ba resetVector followed by nop IndicateVMSize: PUBLIC PROC [sparcVMSize: CARD32] ~ { Insert by hand the size of the VM at address 8 (byte address) DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2 + 4, Basics.HighHalf[sparcVMSize]]; DoveInputOutput.Poke[SparcSoftcard.cedarBackDoorBaseByte/2 + 5, Basics.LowHalf[sparcVMSize]]; }; Always on the same backdoor page Maximum size allowed by the compiler Reads first the beginning of the file to check the header and find out the loading address File way too small Bad magic number or tool version Probably bad linking. The entry point has to be the first effective instruction. Reset the Sparc and the cache Set the first map pages The first page of backdoor points to the begining of free memory The first page of sparcSuperProgram points to the begining of free memory The first page of sparcSuperData points to the begining of free memory Insert the reset pointer Transfert the data and set additional map pages if needed Set one more map page. the file has an odd length (ie non multiple of softcardPageSizeByte) Zero bss. Should be done by the sparc. Set one more map page. For debug replace pages 0 and 1 of backdoor to the begining of Sparc memory. Start the sparc Registration ΚV˜code•Mark outsideHeaderšœ™Kšœ<™Kšœœ"˜.Kšœ œ˜(Kšœœ˜%Kšœœ˜Kšœœ)œœ˜NKšœœœ˜Kšœ˜Kšœ˜—K˜KšΟnœœ˜"Kšœ%œœ˜DK˜šœ˜K˜Kšœœœ˜K˜Kšœœ˜&Kšœœ˜$Kšœœ˜!K˜Kšœœ˜$Kšœœ ˜/K˜K˜š žœœ œœ œ˜>Kšœ%˜%K˜—K˜šžœœ œ œ˜5Kšœ$˜$K˜—K˜šžœœœœ˜9Kšœ=™=Kšœ œΟc˜(KšœœœŸ˜K– "cedar" stylešœœ˜ K– "cedar" stylešœ+œœ˜MKšœ˜—K– "cedar" style˜šžœ˜2K˜– "cedar" styleš žœœœœ œ˜@Jšœœœœ˜&JšœC˜CKšœ˜—K˜šžœœ˜šœG˜GJ™ —Jšœ0˜0Jšœ0˜0JšœY˜YJšœZ˜ZJšœZ˜ZJšœ.˜.Jšœ/˜/Jšœ/˜/K˜—K˜Kš œœœœœ˜(Kšœ œ˜!Jšœ œœœ6˜OJšœœ˜"Jšœ œ˜JšœI˜IJšœœ˜šœ œ ˜J™$—Jšœœœœ˜'Jšœ˜Jšœ œ˜J˜J™ZJ˜šœ˜ Jšœ(˜(Kšœ œ"˜/K˜—šœœœ˜!K™—šœAœœ˜NJ™ —Jšœ.˜.šœœ=œœ˜\J™P—Jšœ3˜3Jšœ&˜&K˜™K˜Kšœ˜Kšœ%˜%K˜—™K˜Jšœ ˜ Jšœ0˜0Jšœ-˜-J˜JšœG˜GJšœK˜Kšœ.˜.J™A—K˜Jšœ&˜&JšœL˜Lšœ/˜/JšœJ™J—K˜Jšœ&˜&JšœL˜Lšœ/˜/JšœG™G—K˜—™J™Jšœ!˜!—J™J™™9J˜šœ˜šœœ)œ˜BJ™Kšœ˜Jšœ>˜>J˜—šœœœ˜Jšœ7˜7Jšœ2˜2Jšœ˜—šœ˜ Jšœ œ"˜/J˜—Jšœ$˜$Jšœ˜—J˜šœœœ˜JšœD™D——J˜J˜˜K™—™&K™šœ ˜šœœ)œ˜BJ™Kšœ˜Jšœ>˜>J˜—šœœœ˜Jšœ/˜/Jšœ2˜2Jšœ˜—Jšœ$˜$Jšœ˜Jšœ˜—J˜—™LK™JšœG˜GJšœK˜KJšœ.˜.Jšœl˜lJšœp˜pJšœ.˜.—K™™K™Jšœ&˜&—šœ˜K™K™———head™ šœ˜Jšœt˜tK™K™——K˜Kšœ˜J˜—…—¬$