<> <> <> <> <<>> DIRECTORY Basics USING [ BITNOT ], Commander USING [ CommandProc, Register ], DoveInputOutput USING [ Peek, Poke ], Process USING [ CheckForAbort, Yield ], SparcSoftcard USING [ softcardMemoryBackDoorStartingPage, softcardMemoryBackDoorWord16Address, activeLineLengthByte, activeLineNumber, bitMapLineLengthByte, bitMapLineNumber, leftBorderLengthByte, topBorderLineNumber ], SparcSoftcardOps USING [ DMAAddressRegisterLoad, SetDMAMode, SetDMAState, SparcCacheDisable, SparcCacheFlushAndEnable, SparcReset, SparcResetAndStart ], SparcSoftcardVM USING [ AllocateRealMemory, GetCPPageValue, SegmentType, SetCPPageValue, SetPageValue, SparcPageValue ]; TestSparcSoftcardVM: CEDAR MONITOR IMPORTS Basics, Commander, DoveInputOutput, Process, SparcSoftcardOps, SparcSoftcardVM ~ { OPEN SparcSoftcardVM, SparcSoftcard; MyPeek: PROC [ address: CARD32 ] RETURNS [ word: CARD16 ] ~ INLINE { word _ DoveInputOutput.Peek[address] }; MyPoke: PROC [ address: CARD32, word: CARD16 ] ~ INLINE { DoveInputOutput.Poke[address, word] }; cpbackdoor: CARD32 ~ softcardMemoryBackDoorWord16Address; backdoorPage: NAT ~ softcardMemoryBackDoorStartingPage; <> somePage: CARD32 _ SparcSoftcardVM.AllocateRealMemory[1].firstPage; -- probably page: 2MB nMapWindowEntries: CARD16 ~ 800H; -- 8k byte pages / BYTES[MapEntryConcrete] MapBackdoor: PROC ~ { entry: SparcPageValue ~ [clean, FALSE, FALSE, 0, somePage]; SparcSoftcardVM.SetCPPageValue[backdoorPage, entry]; <> }; SetupSillyMap: PROC ~ { SetOneWindow: PROC [ s: SegmentType, i: NAT ] ~ { sillyEntry: SparcPageValue ~ [clean, FALSE, FALSE, 0, somePage]; <> FOR j: NAT IN [0..nMapWindowEntries) DO fullVirtual: CARD32 ~ ( i * nMapWindowEntries ) + j; SparcSoftcardVM.SetPageValue[s, fullVirtual, sillyEntry]; ENDLOOP; }; FOR i: NAT IN [0H..4H) DO SetOneWindow[$userData, i]; ENDLOOP; -- user d FOR i: NAT IN [4H..8H) DO SetOneWindow[$userDataAlt, i]; ENDLOOP; -- user d (Alt) FOR i: NAT IN [8H..0CH) DO SetOneWindow[$userText, i]; ENDLOOP; -- user i FOR i: NAT IN [0CH..10H) DO SetOneWindow[$userTextAlt, i]; ENDLOOP; -- user i (Alt) FOR i: NAT IN [10H..14H) DO SetOneWindow[$superData, i]; ENDLOOP; -- super d <> <> FOR i: NAT IN [18H..1CH) DO SetOneWindow[$superText, i]; ENDLOOP; -- super i <> }; InitializeSupervisor: PROC ~ { entry: SparcPageValue ~ [clean, FALSE, FALSE, 0, somePage]; <> SparcSoftcardVM.SetPageValue[$superText, 0, entry]; <> SparcSoftcardVM.SetPageValue[$superData, 0, entry]; }; LoadTestProgram1: PROC ~ { nextWord16: CARD32 _ cpbackdoor; PutWord16: PROC [ instruction: CARD32 ] ~ { MyPoke[nextWord16, instruction]; nextWord16 _ nextWord16.SUCC; }; PutWord16[0c200h]; PutWord16[02040h]; PutWord16[08200h]; PutWord16[06001h]; PutWord16[0c220h]; PutWord16[02040h]; PutWord16[010bfh]; PutWord16[0fffdh]; PutWord16[00100h]; PutWord16[00000h]; }; LoadTestProgram2: PROC ~ { nextWord16: CARD32 _ cpbackdoor; PutWord16: PROC [ instruction: CARD32 ] ~ { MyPoke[nextWord16, instruction]; nextWord16 _ nextWord16.SUCC; }; <> <> <> <> <> <> <> <> <> <> }; <> bitmapWords16: CARD32 ~ ( bitMapLineNumber * bitMapLineLengthByte ) / 2; wordsPerLine: NAT ~ activeLineLengthByte / 2; linesPerScan: NAT ~ activeLineNumber; LineOffset: PROC [ line: CARD32 ] RETURNS [ wordOffset: CARD32 ] ~ { visibleLine: CARD32 ~ line + topBorderLineNumber; byteOffset: CARD32 ~ leftBorderLengthByte + ( visibleLine * bitMapLineLengthByte ); wordOffset _ byteOffset / 2; }; grey: CARD16 ~ 0AAAAH; stripe: CARD16 ~ 0CACAH; pinstripe: CARD16 ~ 0AA55H; quarterMeg: NAT ~ 32; sparcRamStartingPage: NAT ~ 200H; -- first 0.25 MB DMA VM at physical 4.0 MB SetBackDoorPages: PROC ~ { FOR i: CARD32 IN [0..quarterMeg) DO page: CARD32 ~ sparcRamStartingPage + i; entry: SparcPageValue ~ [clean, FALSE, FALSE, 0, page]; SparcSoftcardVM.SetCPPageValue[backdoorPage + i, entry]; ENDLOOP; }; SetDMAPages: PROC ~ { FOR virtual: CARD32 IN [0..quarterMeg) DO page: CARD32 ~ sparcRamStartingPage + virtual; entry: SparcPageValue ~ [clean, FALSE, FALSE, 0, page]; SparcSoftcardVM.SetPageValue[$dma, virtual, entry]; ENDLOOP; }; GreyBackground: PROC ~ { FOR word: CARD32 IN [0..bitmapWords16) DO address: CARD32 ~ cpbackdoor + word; MyPoke[address, grey]; ENDLOOP; }; StrippedBackground: PROC ~ { FOR word: CARD32 IN [0..bitmapWords16) DO address: CARD32 ~ cpbackdoor + word; MyPoke[address, stripe]; ENDLOOP; }; PinStripeBackground: PROC ~ { FOR word: CARD32 IN [0..bitmapWords16) DO address: CARD32 ~ cpbackdoor + word; MyPoke[address, pinstripe]; ENDLOOP; }; JazzBackground: PROC ~ { chunks: NAT ~ bitMapLineLengthByte / 8; -- poke 4 words FOR line: CARD32 IN [0..bitMapLineNumber) DO linebase: CARD32 ~ cpbackdoor + line * wordsPerLine; pattern: CARD16 _ 0; FOR word: NAT IN [0..chunks) DO address: CARD32 ~ linebase + ( word * 4 ); MyPoke[address + 0, pattern]; MyPoke[address + 1, pattern]; MyPoke[address + 2, pattern]; MyPoke[address + 3, pattern]; pattern _ Basics.BITNOT[pattern]; ENDLOOP; ENDLOOP; }; CopyScreen: PROC ~ { origin, destination: CARD32; FOR line: CARD32 IN [0..linesPerScan) DO origin _ line * wordsPerLine; destination _ cpbackdoor + LineOffset[line]; FOR word: NAT IN [0..wordsPerLine) DO notbits: CARD16 ~ Basics.BITNOT[MyPeek[origin + word]]; MyPoke[destination + word, notbits]; ENDLOOP; Process.Yield[]; Process.CheckForAbort[]; ENDLOOP; }; <> LoadAndGo: Commander.CommandProc ~ { MapBackdoor[]; SetupSillyMap[]; InitializeSupervisor[]; SparcSoftcardOps.SparcReset[]; SparcSoftcardOps.SparcCacheDisable[]; LoadTestProgram1[]; LoadTestProgram2[]; SparcSoftcardOps.SparcCacheFlushAndEnable[]; SparcSoftcardOps.SparcResetAndStart[]; }; UpdateDisplay: Commander.CommandProc ~ { SparcSoftcardOps.SetDMAState[$inactive]; SparcSoftcardOps.SetDMAMode[$display]; SparcSoftcardOps.DMAAddressRegisterLoad[0]; SetBackDoorPages[]; GreyBackground[]; SetDMAPages[]; SparcSoftcardOps.SetDMAState[$active]; DO CopyScreen[]; Process.Yield[]; Process.CheckForAbort[]; ENDLOOP; }; StressDisplay: Commander.CommandProc ~ { SparcSoftcardOps.SetDMAState[$inactive]; SparcSoftcardOps.SetDMAMode[$display]; SparcSoftcardOps.DMAAddressRegisterLoad[0]; SetBackDoorPages[]; GreyBackground[]; SetDMAPages[]; SparcSoftcardOps.SetDMAState[$active]; DO GreyBackground[]; JazzBackground[]; Process.Yield[]; Process.CheckForAbort[]; ENDLOOP; }; Halt: Commander.CommandProc ~ { SparcSoftcardOps.SparcReset[]; }; CertifyCPMap: Commander.CommandProc ~ { FOR i: CARD32 IN [0..256) DO -- 2MB worth! value: SparcPageValue _ SparcSoftcardVM.GetCPPageValue[i + 0C0H]; IF ( value.realPage # i ) THEN ERROR; ENDLOOP; }; Commander.Register["RunSparc", LoadAndGo, "Try the first Sparc program.\n"]; Commander.Register["HaltSparc", Halt, "Stop the Sparc dead in its tracks.\n"]; Commander.Register["CertifyCPMap", CertifyCPMap, "Check the pages under our feet.\n"]; Commander.Register["DisplayScreen", UpdateDisplay, "Copy the screen bitmap into the Softcard for display via the DMA port.\n"]; Commander.Register["StressDisplay", StressDisplay, "Display a *painful* image.\n"]; }.