DIRECTORY AMBridge USING [SomeRefFromTV, TVForReferent], AMTypes USING [TV], Basics USING [BITAND, BITSHIFT, LongNumber, ShortNumber], Buttons USING [Create, ReLabel], Convert USING [CardFromRope], DebuggerDefs -- using lots -- , DragOpsCross USING [StackedStatusWord], DragOpsCrossUtils USING [CardToWord], FS USING [Error, FileInfo, StreamOpen], Interpreter USING [Evaluate], IO, Labels USING [Create, Set], List USING [CompareProc, Sort], Process USING [Detach, Milliseconds, PauseMsec], Rope, SoftcardOps, SoftcardPrivate USING [SCBaseAddr], SoftcardToolPrivate, SymTab USING [Create, Ref, Store], ViewerTools USING [GetContents, MakeNewTextViewer, SetSelection]; SoftcardToolQuadIOImpl: CEDAR MONITOR IMPORTS AMBridge, Interpreter, Basics, Buttons, Convert, DragOpsCrossUtils, FS, IO, Labels, List, Process, Rope, SymTab, ViewerTools, SoftcardOps, SoftcardToolPrivate, DD: DebuggerDefs EXPORTS SoftcardToolPrivate = BEGIN OPEN SoftcardToolPrivate; Word: TYPE = CARD32; STREAM: TYPE = IO.STREAM; ROPE: TYPE = Rope.ROPE; Memory: TYPE = REF MemoryRec; MemoryRec: TYPE = RECORD [ sym: SymTab.Ref, wds: REF MemWords, sortedSyms: REF SortedSyms, lowestAddr: Word _ 0, highestAddr: Word _ 0]; MemWords: TYPE = RECORD [SEQUENCE size: CARDINAL OF MemWord]; MemWord: TYPE = RECORD [addr, value: Word]; SortedSyms: TYPE = RECORD [SEQUENCE size: CARDINAL OF SymbolAddr]; SymbolAddr: TYPE = REF SymbolAddrRec; SymbolAddrRec: TYPE = RECORD [sym: ROPE, addr: Word]; quadMemory: Memory; quadFileNameText: Viewer; interpretWhatText, showInterpretResult: Viewer; debuggerWatcherButton, autoDumpDebuggerButton, autoRestartDebuggerButton: Viewer; watcherWait: Process.Milliseconds _ 100; watchingDebugger: BOOL _ FALSE; autoDumpDebuggerState: BOOL _ FALSE; autoRestartDebugger: BOOL _ FALSE; debuggerWatchAddr: CARD32 = DD.debugBase + DD.debuggerProceed; dumpBaseAddr: CARD32 = DD.debugBase; numToDump: CARD16 = DD.ifuRegBase + 2*DD.IFUStackSize; debuggerWatchSCAddr: CARD32 = SoftcardToolPrivate.DragonToSoftcardAddr[debuggerWatchAddr]; dumpBaseSCAddr: CARD32 = SoftcardToolPrivate.DragonToSoftcardAddr[dumpBaseAddr]; debuggerState: SoftcardOps.SeqLong; BuildQuadIOButtons: PUBLIC PROC[topViewer, sibx: Viewer] RETURNS[sib: Viewer] = { sib _ sibx; sib _ Buttons.Create[ info: [ name: " LoadQuadFile ", parent: topViewer, wx: leftEdge, wy: sib.wy+sib.wh+betweenHeight, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: LoadQuadFileProc ]; sib _ Buttons.Create[ info: [ name: " fileName: ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: FALSE, scrollable: FALSE], font: selectFont, proc: QuadFileNameProc ]; sib _ quadFileNameText _ ViewerTools.MakeNewTextViewer[ info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge+6, wy: sib.wy, ww: 300, wh: entryHeight, border: FALSE, scrollable: FALSE]]; watchingDebugger _ FALSE; sib _ Labels.Create[ info: [ name: " Debugger ", parent: topViewer, wx: leftEdge, wy: sib.wy+sib.wh+betweenHeight, wh: entryHeight, border: FALSE, scrollable: FALSE], font: labelFont ]; sib _ debuggerWatcherButton _ Buttons.Create[ info: [ name: " WatcherOff ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: selectFont, proc: DebuggerWatcherProc ]; autoDumpDebuggerState _ FALSE; sib _ autoDumpDebuggerButton _ Buttons.Create[ info: [ name: " AutoDumpOff ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: selectFont, proc: AutoDumpDebuggerProc ]; autoRestartDebugger _ FALSE; sib _ autoRestartDebuggerButton _ Buttons.Create[ info: [ name: " AutoRestartOff ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: selectFont, proc: AutoRestartDebuggerProc ]; sib _ Buttons.Create[ info: [ name: " DumpAllState ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: DumpAllDebuggerStateProc ]; sib _ Buttons.Create[ info: [ name: " Restart ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: RestartDebuggerProc ]; sib _ Buttons.Create[ info: [ name: " ShowMinState ", parent: topViewer, wx: leftEdge+40, wy: sib.wy+sib.wh+betweenHeight, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: MinStateProc ]; sib _ Buttons.Create[ info: [ name: " EUStack ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: EUStackProc ]; sib _ Buttons.Create[ info: [ name: " IFUStack ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: IFUStackProc ]; sib _ Buttons.Create[ info: [ name: " EUAuxRegs ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: EUAuxRegsProc ]; sib _ Buttons.Create[ info: [ name: " EUConstRegs ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: EUConstRegsProc ]; sib _ Buttons.Create[ info: [ name: " InterpSym ", parent: topViewer, wx: leftEdge, wy: sib.wy+sib.wh+betweenHeight, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: InterpSymbolProc ]; sib _ Buttons.Create[ info: [ name: " InterpAddr ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: TRUE, scrollable: FALSE], font: activeFont, proc: InterpAddrProc ]; sib _ Buttons.Create[ info: [ name: " what: ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: FALSE, scrollable: FALSE], font: selectFont, proc: InterpretWhatProc ]; sib _ interpretWhatText _ ViewerTools.MakeNewTextViewer[ info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, ww: 400, wh: entryHeight, border: FALSE, scrollable: FALSE]]; sib _ Labels.Create[ info: [ name: " result: ", parent: topViewer, wx: leftEdge+40, wy: sib.wy+sib.wh+betweenHeight, wh: entryHeight, border: FALSE, scrollable: FALSE], font: labelFont ]; sib _ showInterpretResult _ Labels.Create[ info: [ name: " ", parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, border: FALSE, scrollable: FALSE] ]; RETURN[sib]; }; wordsPerCall: CARD16 _ 1024; LoadQuadFileProc: ClickProc = { fName: ROPE _ ViewerTools.GetContents[quadFileNameText]; fullName: ROPE; numLeft: CARD16 _ 0; indexThisRound, pushIndex: CARD16 _ 0; PushAddrVal: PROC RETURNS[addr: SoftcardOps.Addr, value: CARD32] = { addr _ ByteAddrToSoftcardAddr[quadMemory.wds[pushIndex].addr]; value _ quadMemory.wds[pushIndex].value; pushIndex _ pushIndex + 1; }; IF fName.Length[] = 0 THEN { TSOutPutRope["\n**** Please fill in the name of a quad file\n"]; RETURN }; IF fName.Find["."] < 0 THEN fName _ fName.Concat[".quad"]; fullName _ FS.FileInfo[name: fName, remoteCheck: FALSE, wDir: regDir ! FS.Error => { TSOutPutRope[error.explanation]; TSOutPutChar['\n]; GOTO nogood } ].fullFName; quadMemory _ ReadQuadFile[fullName]; IF quadMemory = NIL THEN RETURN; -- some error, already reported numLeft _ quadMemory.wds.size; WHILE numLeft > wordsPerCall DO SoftcardOps.WriteMultipleLong[wordsPerCall, PushAddrVal]; numLeft _ numLeft - wordsPerCall; ENDLOOP; IF numLeft > 0 THEN SoftcardOps.WriteMultipleLong[numLeft, PushAddrVal]; TSOutPutF["\n\tQuadFile %g (%g instructions) has been loaded\n\n", [rope[fullName]], [cardinal[quadMemory.wds.size]] ]; EXITS nogood => NULL; }; QuadFileNameProc: ClickProc = { ViewerTools.SetSelection[quadFileNameText, NIL] }; DebuggerWatcherProc: ClickProc = { IF DebuggerWatching[changeState: TRUE] THEN Buttons.ReLabel[debuggerWatcherButton, " WatcherOff "] ELSE Buttons.ReLabel[debuggerWatcherButton, " WatcherOn "] }; DebuggerWatching: ENTRY PROC[changeState: BOOL] RETURNS[BOOL] = { IF ~changeState THEN RETURN[watchingDebugger]; watchingDebugger _ ~watchingDebugger; RETURN[~watchingDebugger]; -- if changeState return previous value }; AutoDumpDebuggerProc: ClickProc = { IF AutoDumpDebuggerState[changeState: TRUE] THEN Buttons.ReLabel[autoDumpDebuggerButton, " AutoDumpOff "] ELSE Buttons.ReLabel[autoDumpDebuggerButton, " AutoDumpOn "] }; AutoDumpDebuggerState: ENTRY PROC[changeState: BOOL] RETURNS[BOOL] = { IF ~changeState THEN RETURN[autoDumpDebuggerState]; autoDumpDebuggerState _ ~autoDumpDebuggerState; RETURN[~autoDumpDebuggerState]; -- if changeState still return previous value }; AutoRestartDebuggerProc: ClickProc = { IF AutoRestart[changeState: TRUE] THEN Buttons.ReLabel[autoRestartDebuggerButton, " AutoRestartOff "] ELSE Buttons.ReLabel[autoRestartDebuggerButton, " AutoRestartOn "] }; AutoRestart: ENTRY PROC[changeState: BOOL] RETURNS[BOOL] = { IF ~changeState THEN RETURN[autoRestartDebugger]; autoRestartDebugger _ ~autoRestartDebugger; RETURN[~autoRestartDebugger]; -- if changeState still return previous value }; TheWatcherProc: PROC = { alreadyReported: BOOL _ FALSE; DO BEGIN ENABLE SoftcardOps.SCError => GOTO scError; IF ~DebuggerWatching[changeState: FALSE] THEN { alreadyReported _ FALSE; Process.PauseMsec[watcherWait]; LOOP; }; IF SoftcardOps.ReadLong[debuggerWatchSCAddr] = 0 THEN { alreadyReported _ FALSE; Process.PauseMsec[watcherWait]; LOOP; }; IF ~alreadyReported THEN { TSOutPutRope["\n\n***** Debugger is in wait loop\n"]; alreadyReported _ TRUE; debuggerState _ SoftcardOps.DumpLong[dumpBaseSCAddr, numToDump]; IF AutoDumpDebuggerState[changeState: FALSE] THEN DumpMinState[]; IF AutoRestart[changeState: FALSE] THEN RestartDebugger[] ELSE { ShowDebuggerWaiting[]; alreadyReported _ FALSE; UNTIL IsDebuggerRestarted[] DO Process.PauseMsec[watcherWait]; ENDLOOP; LOOP; }; }; Process.PauseMsec[watcherWait]; EXITS scError => Process.PauseMsec[10*watcherWait]; END; ENDLOOP; }; debuggerIsRestarted: BOOL _ FALSE; RestartDebugger: ENTRY PROC = { ENABLE UNWIND => NULL; SoftcardOps.WriteLong[debuggerWatchSCAddr, 0]; debuggerIsRestarted _ TRUE; }; ShowDebuggerWaiting: ENTRY PROC = { debuggerIsRestarted _ FALSE }; IsDebuggerRestarted: ENTRY PROC RETURNS[BOOL] = { RETURN[debuggerIsRestarted] }; DumpAllDebuggerStateProc: ClickProc = { DumpAllDebuggerState[] }; RestartDebuggerProc: ClickProc = { RestartDebugger[]; TSOutPutRope["\tRestarted the debugger\n"]; }; DumpAllDebuggerState: PROC = { IF debuggerState = NIL THEN { TSOutPutRope[noState]; RETURN }; TSOutPutRope["Dumping the entire debugger state\n"]; ShowEUState[]; DumpIFUStack[]; DumpWords["EUStack:", DD.euRegBase, 126]; DumpWords["EUConstRegs:", DD.euRegBase+euConst, DD.EUConstants]; DumpWords["EUAuxRegs:", DD.euRegBase+euAux, DD.EUAuxRegs]; }; noState: ROPE = "\n**** No debugger state to dump\n"; euMar: CARD16 = 130; euField: CARD16 = 131; euConst: CARD16 = 132; euAux: CARD16 = 144; MinStateProc: ClickProc = { DumpMinState[] }; DumpMinState: PROC = { youngest: CARD16 _ debuggerState[DD.debuggerFrame]; -- youngest is debugger call IF debuggerState = NIL THEN { TSOutPutRope[noState]; RETURN }; ShowEUState[]; TSOutPutRope["\nThe top few stack entries:\n"]; TSOutPutF["\t[s]: %xH, [s-1]: %xH, [s-2]: %xH, [s-3]: %xH, [s-4]: %xH\n", [cardinal[debuggerState[DD.euRegBase+126]]], [cardinal[debuggerState[DD.euRegBase+125]]], [cardinal[debuggerState[DD.euRegBase+124]]], [cardinal[debuggerState[DD.euRegBase+123]]], [cardinal[debuggerState[DD.euRegBase+122]]] ]; OneIFUStackEntry["\nYoungestIFU:", youngest]; }; ShowEUState: PROC = { field: SoftcardOps.FieldDesc = LOOPHOLE[debuggerState[DD.euRegBase+euField]]; TSOutPutRope["\nDumping minimum EU state\n"]; TSOutPutF["\topCode: %xH, alphaBeta: %xH, s: %xH, carry: %xH\n", [cardinal[debuggerState[DD.debuggerOpcode]]], [cardinal[debuggerState[DD.debuggerAlphaBeta]]], [cardinal[debuggerState[DD.debuggerS]]], [cardinal[debuggerState[DD.debuggerCarry]]] ]; TSOutPutF["\teuMAR: %xH, euField: [insert: %g, mask: %g, shift: %g]\n", [cardinal[debuggerState[DD.euRegBase+euMar]]], [cardinal[field.insert]], [cardinal[field.mask]], [cardinal[field.shift]] ]; }; IFUStackProc: ClickProc = { DumpIFUStack[] }; DumpIFUStack: PROC = { nFrames: CARD32 = debuggerState[DD.debuggerFrame]; IF debuggerState = NIL THEN { TSOutPutRope[noState]; RETURN }; TSOutPutF["\nDumping %g frames in the IFU stack\n", [cardinal[nFrames]] ]; FOR i: CARD32 IN [0..nFrames] DO OneIFUStackEntry[IO.PutFR[" [%g]:", [cardinal[i+1]] ], i]; ENDLOOP; }; OneIFUStackEntry: PROC[rp: ROPE, i: CARD32] = { statusWord: DragOpsCross.StackedStatusWord = LOOPHOLE[DragOpsCrossUtils.CardToWord[debuggerState[DD.ifuRegBase+2*i]] ]; pc: CARD32 = debuggerState[DD.ifuRegBase+2*i+1]; sym: ROPE; ok: BOOL; [ok, sym] _ InterpretAddrAsSym[pc, quadMemory, FALSE]; TSOutPutF["%g status[userMode: %g, trapsEnabled: %g, lBase: %xH]\n", [rope[rp]], [boolean[statusWord.userMode]], [boolean[statusWord.trapsEnabled]], [cardinal[statusWord.lBase]] ]; TSOutPutF["\t\tpc: %xH", [cardinal[pc]] ]; IF ok THEN TSOutPutF[" (%g)", [rope[sym]] ]; TSOutPutChar['\n]; }; EUStackProc: ClickProc = { DumpWords["EUStack:", DD.euRegBase, 126] }; DumpWords: PROC[rp: ROPE, first: CARD32, num: CARD16] = { seq: SoftcardOps.SeqLong = debuggerState; addr: CARD32 _ 0; count: CARD16 _ num; index: CARD16 _ first; format: ROPE = " %04x"; TSOutPutF["\nDumping %g words of %g\n", [cardinal[num]], [rope[rp]] ]; WHILE count >= 8 DO TSOutPutF["%xH:", [cardinal[addr+index-first]] ]; FOR i: CARD16 IN [0..8) DO TSOutPutF[format, [cardinal[seq[index+i]]] ]; ENDLOOP; TSOutPutChar['\n]; index _ index + 8; count _ count - 8; ENDLOOP; IF count # 0 THEN { TSOutPutF["%xH:", [cardinal[addr+index-first]] ]; FOR i: CARD16 IN [0..count) DO TSOutPutF[format, [cardinal[seq[index+i]]] ]; ENDLOOP; TSOutPutChar['\n]; }; }; EUAuxRegsProc: ClickProc = { DumpWords["EUAuxRegs:", DD.euRegBase+euAux, DD.EUAuxRegs] }; EUConstRegsProc: ClickProc = { DumpWords["EUConstRegs:", DD.euRegBase+euConst, DD.EUConstants] }; InterpSymbolProc: ClickProc = { what: ROPE = ViewerTools.GetContents[interpretWhatText]; rp: ROPE; addr: CARD32; ok: BOOL; IF what.Length[] = 0 THEN { TSOutPutRope["\n Please fill in the Interpret \"what\" field\n"]; RETURN }; [ok, addr] _ InterpretSymAsAddr[what, quadMemory]; IF ok = FALSE THEN { Labels.Set[showInterpretResult, " ??? "]; RETURN; }; Labels.Set[showInterpretResult, rp _ IO.PutFR["0%xH", [cardinal[addr]]] ]; TSOutPutF["Expression \"%g\" has dragon byte address %g\n", [rope[what]], [rope[rp]] ]; }; InterpAddrProc: ClickProc = { what: ROPE = ViewerTools.GetContents[interpretWhatText]; ok: BOOL; rp: ROPE; addr: CARD32; [ok, addr] _ CheckedGetAsCard[interpretWhatText, "Interpret \"what\"", LAST[CARD32]]; IF ~ok THEN RETURN; [ok, rp] _ InterpretAddrAsSym[addr, quadMemory, TRUE]; Labels.Set[showInterpretResult, rp]; IF ok THEN TSOutPutF["The symbol for dragon byte address \"%g\" is : %g\n", [rope[what]], [rope[rp]] ]; }; InterpretWhatProc: ClickProc = { ViewerTools.SetSelection[interpretWhatText, NIL] }; ReadQuadFile: PROC[fileName: ROPE] RETURNS[mem: Memory] = { quadFile: STREAM _ FS.StreamOpen[fileName]; count: INT _ 0; list: LIST OF MemWord _ NIL; symList: LIST OF SymbolAddr _ NIL; numSyms: CARD16 _ 0; previousAddr: Word _ 0; --***JCC mem _ NEW[MemoryRec _ [sym: SymTab.Create[]]]; DO Skip: PROC [source: STREAM, c: CHAR] RETURNS[BOOL] ~ { ch: CHAR; [] _ source.SkipWhitespace[]; IF (ch _ source.GetChar[]) # c THEN { TSOutPutF[" Bad char %g (expected %g) at pos %g in quadFile %g - quitting\n", [character[c]], [character[ch]], [integer[source.GetIndex[]]], [rope[fileName]] ]; RETURN[FALSE]; }; RETURN[TRUE]; }; tokenKind: IO.TokenKind; token: ROPE; addr: Word; value: Basics.LongNumber; [tokenKind, token] _ quadFile.GetCedarTokenRope[! IO.EndOfStream => EXIT]; SELECT tokenKind FROM tokenDECIMAL, tokenOCTAL, tokenHEX => { addr _ Convert.CardFromRope[token]; IF ~Skip[quadFile, '/] THEN { quadFile.Close[]; RETURN[NIL]; }; value.hh _ GetHexByte[quadFile]; value.hl _ GetHexByte[quadFile]; value.lh _ GetHexByte[quadFile]; value.ll _ GetHexByte[quadFile]; IF (addr # (previousAddr+4)) THEN { list _ CONS[[previousAddr+4, 0], list]; count _ count+1; }; previousAddr _ addr; list _ CONS[[addr, value.lc], list]; count _ count+1 }; tokenID => { IF ~Skip[quadFile, '=] THEN { quadFile.Close[]; RETURN[NIL]; }; addr _ quadFile.GetCard[]; symList _ CONS[NEW[SymbolAddrRec _ [token, addr]], symList]; numSyms _ numSyms + 1; [] _ SymTab.Store[mem.sym, token, TVFromRef[NEW[Word _ addr]]] }; tokenEOF => EXIT; ENDCASE => { TSOutPutF["\n****Unknown tokenKind in quadFile %g at pos %g - quitting\n", [rope[fileName]], [integer[quadFile.GetIndex[]]] ]; quadFile.Close[]; RETURN[NIL]; }; ENDLOOP; quadFile.Close[]; mem.wds _ NEW[MemWords[count]]; FOR i: INT DECREASING IN [0..count) DO mem.wds[i] _ list.first; list _ list.rest ENDLOOP; mem.lowestAddr _ mem.wds[0].addr; mem.highestAddr _ mem.wds[count-1].addr; IF numSyms # 0 THEN { MySort: List.CompareProc = { sa1: SymbolAddr = NARROW[ref1]; sa2: SymbolAddr = NARROW[ref2]; IF sa1.addr < sa2.addr THEN RETURN[less]; IF sa1.addr = sa2.addr THEN RETURN[equal]; RETURN[greater]; }; TRUSTED { symList _ LOOPHOLE[List.Sort[LOOPHOLE[symList], MySort] ] }; mem.sortedSyms _ NEW[SortedSyms[numSyms]]; FOR i: CARD16 IN [0..numSyms) DO mem.sortedSyms[i] _ symList.first; symList _ symList.rest; ENDLOOP; }; }; GetHexByte: PROC[strm: STREAM] RETURNS[BYTE] = { sn: WORD; ch: CHAR; DO SELECT ch _ strm.GetChar[] FROM IN ['0..'9] => sn _ Basics.BITSHIFT[sn, 4] + ch - '0; IN ['A..'F] => sn _ Basics.BITSHIFT[sn, 4] + ch - 'A + 10; IN ['a..'f] => sn _ Basics.BITSHIFT[sn, 4] + ch - 'a + 10; 'h, 'H => RETURN[LOOPHOLE[sn, Basics.ShortNumber].lo]; ENDCASE => NULL; ENDLOOP; }; InterpretSymAsAddr: PROC[rp: ROPE, mem: Memory] RETURNS[ok: BOOL, addr: Word] = { result: AMTypes.TV; errorRope: ROPE; noResult: BOOL; refCard: REF; [result, errorRope, noResult] _ Interpreter.Evaluate[rp, NIL, LIST[mem.sym]]; IF noResult THEN { addr _ 0; TSOutPutF["\n*****Could not interpret \"%g\" - quitting\n", [rope[rp]] ]; RETURN[FALSE, addr]}; refCard _ RefFromTV[result]; WITH refCard SELECT FROM word: REF Word => {RETURN[TRUE, word^]}; card: REF LONG CARDINAL => {RETURN[TRUE, card^]}; int: REF INT => { IF int^ < 0 THEN RETURN[FALSE, 0]; RETURN[TRUE, int^] }; ENDCASE => { TSOutPutF["\n*****Unknown variant for \"%g\" - quitting\n", [rope[rp]] ]; RETURN[FALSE, 0]; }; }; InterpretAddrAsSym: PROC[addr: CARD32, mem: Memory, verbose: BOOL] RETURNS[ok: BOOL, rp: ROPE] = { sortedSyms: REF SortedSyms; num: CARD16; ok _ FALSE; rp _ " ??? "; IF mem = NIL THEN RETURN; sortedSyms _ mem.sortedSyms; num _ IF sortedSyms = NIL THEN 0 ELSE sortedSyms.size; IF addr < mem.lowestAddr THEN { IF verbose THEN TSOutPutF["***%xH is smaller than any address (%xH)\n", [cardinal[addr]], [cardinal[mem.lowestAddr]] ]; RETURN }; IF addr > mem.highestAddr THEN { IF verbose THEN TSOutPutF["***%xH is larger than any address (%xH)\n", [cardinal[addr]], [cardinal[mem.highestAddr]] ]; RETURN }; IF sortedSyms = NIL THEN { IF verbose THEN TSOutPutRope["\t*****Loaded file had no symbols\n"]; RETURN; }; IF addr < sortedSyms[0].addr THEN { diff: CARD32 = sortedSyms[0].addr - addr; RETURN[TRUE, IO.PutFR["%g-%xH", [rope[sortedSyms[0].sym]], [cardinal[diff]]] ]; }; IF addr > sortedSyms[num-1].addr THEN { diff: CARD32 = addr - sortedSyms[num-1].addr; RETURN[TRUE, IO.PutFR["%g+%xH", [rope[sortedSyms[num-1].sym]], [cardinal[diff]]] ]; }; FOR i: CARD16 IN [0..num) DO diff: CARD32; IF addr > sortedSyms[i].addr THEN LOOP; IF addr = sortedSyms[i].addr THEN RETURN[TRUE, sortedSyms[i].sym]; diff _ addr - sortedSyms[i-1].addr; RETURN[TRUE, IO.PutFR["%g+%xH", [rope[sortedSyms[i-1].sym]], [cardinal[diff]]] ]; ENDLOOP; }; TVFromRef: PROC [ref: REF] RETURNS [AMTypes.TV] = TRUSTED { RETURN [AMBridge.TVForReferent[ref]] }; RefFromTV: PROC [tv: REF] RETURNS [REF] = { IF tv = NIL THEN RETURN [NIL]; IF ~ISTYPE [tv, AMTypes.TV] THEN ERROR; TRUSTED {RETURN [AMBridge.SomeRefFromTV[tv]]} }; ByteAddrToSoftcardAddr: PUBLIC PROC[addr: CARD32] RETURNS[softAddr: CARD32] = { IF Basics.BITAND[LOOPHOLE[addr, Basics.LongNumber].hi, 8000H] # 0 THEN softAddr _ SoftcardPrivate.SCBaseAddr + (addr MOD 80000H)/2 ELSE softAddr _ 100000H+(addr MOD 100000H)/2; }; TRUSTED { Process.Detach[FORK TheWatcherProc] }; END. lSoftcardToolQuadIOImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Don Curry, March 16, 1987 5:11:02 pm PST Willie-Sue, April 13, 1987 2:33:53 pm PDT Christophe Cuenod April 15, 1987 9:14:24 am PDT Load Quad file (dragon code) DebuggerWatcher for dragon code DebuggerState for dragon code Interpret symbol for dragon code THROUGH [0..4) DO value _ value*100H + quadFile.GetCard[] ENDLOOP; ***JCC ***JCC special for quad files - know that there is a Hex byte next in the file if the high order address bit is set, map the address into the IO space of the softcard start code Κ<˜šœ™Jšœ<™Kšœœœ ˜$Kšœ œœœ˜6šœœ˜Kšœ=˜=—Kšœœ:˜Pšœ#˜#J˜—šŸœœœœ˜QJšœ ˜ ™šœ˜šœ2˜2Jšœ@˜@Jšœ œœ˜"—Jšœ+˜+J™—šœ˜šœ/˜/Jšœ7˜7Jšœ œœ˜#—Jšœ+˜+J™—šœ7˜7JšœA˜AJšœ#œœ˜>—J˜—™Jšœœ˜šœ˜šœ.˜.Jšœ@˜@Jšœ œœ˜#—Jšœ˜J™—šœ-˜-šœ0˜0Jšœ7˜7Jšœ œœ˜"—Jšœ.˜.J™—Jšœœ˜šœ.˜.šœ1˜1Jšœ7˜7Jšœ œœ˜"—Jšœ/˜/J™—Jšœœ˜šœ1˜1šœ4˜4Jšœ7˜7Jšœ œœ˜"—Jšœ2˜2J™—šœ˜šœ2˜2Jšœ7˜7Jšœ œœ˜"—Jšœ3˜3J™—šœ˜šœ-˜-Jšœ7˜7Jšœ œœ˜"—Jšœ.˜.J™—J˜—™šœ˜šœ2˜2JšœC˜CJšœ œœ˜"—Jšœ'˜'J™—šœ˜šœ-˜-Jšœ7˜7Jšœ œœ˜"—Jšœ&˜&J™—šœ˜šœ.˜.Jšœ7˜7Jšœ œœ˜"—Jšœ'˜'J™—šœ˜šœ/˜/Jšœ7˜7Jšœ œœ˜"—Jšœ(˜(J™—šœ˜šœ1˜1Jšœ7˜7Jšœ œœ˜"—Jšœ*˜*J™——™ šœ˜šœ/˜/Jšœ@˜@Jšœ œœ˜"—Jšœ+˜+J™—šœ˜šœ0˜0Jšœ7˜7Jšœ œœ˜"—Jšœ)˜)J™—šœ˜šœ+˜+Jšœ7˜7Jšœ œœ˜#—Jšœ,˜,J™—šœ8˜8Jšœ?˜?Jšœ#œœ˜>J˜—šœ˜šœ-˜-JšœC˜CJšœ œœ˜#—Jšœ˜J˜—šœ*˜*šœX˜XJšœ˜Jšœ7˜7Jšœ œœ˜"—Jšœ˜—J˜—Jšœ˜ J˜J˜—Jšœœ˜šŸœ˜Jšœœ-˜8Jšœ œ˜Jšœ œ˜Jšœœ˜&šŸ œœœ œ˜DKšœ>˜>Kšœ(˜(K˜K˜—šœœ˜J˜@Jš˜J˜—Jšœœ˜:šœ œ$œ˜Dšœœ ˜Jšœ ˜ Jšœ˜Jšœ˜——Kšœ$˜$Kš œœœœž˜AK˜Kšœ˜šœ˜Kšœ9˜9Kšœ!˜!Kšœ˜—šœ œ5˜HJ˜—˜BJšœ4˜4—š˜Jšœ œ˜—J˜J˜—šŸœ ˜Jšœ-œ˜4J˜—šŸœ˜"šœœ˜+Jšœ6˜6Jšœ6˜:—J˜J˜—š Ÿœœœœœœ˜AJšœœœ˜.Jšœ%˜%Jšœž'˜BJ˜J˜—šŸœ˜#šœ$œ˜0Jšœ8˜8Jšœ8˜<—J˜J˜—š Ÿœœœœœœ˜FJšœœœ˜3Jšœ/˜/Jšœž-˜MJ˜J˜—šŸœ˜&šœœ˜&Jšœ>˜>Jšœ>˜B—J˜J˜—š Ÿ œœœœœœ˜J˜4Jšœ˜Jšœ˜Jšœœ˜)Jšœœ$˜@Jšœœœ ˜:J˜J˜—Jšœ œ(˜5Jšœœ˜Jšœ œ˜Jšœ œ˜šœœ˜J˜—šŸ œ!˜-J˜—šŸ œœ˜Jšœ  œœž˜QJšœœœœ˜>J˜J˜J˜J˜0˜IJšœœ˜,Jšœœ˜,Jšœœ˜,Jšœœ˜,Jšœœ˜+Jšœ˜—Jšœ-˜-Jšœ˜J˜—šŸ œœ˜Jšœœœ˜MJ˜-˜@Jšœœ˜-Jšœœ˜0Jšœœ˜(Jšœœ˜+Jšœ˜—šœG˜GJšœœ˜.Jšœ˜Jšœ˜Jšœ˜J˜—J˜J˜—šŸ œ!˜-J˜—šŸ œœ˜Jšœ œœ˜2Jšœœœœ˜>JšœJ˜Jšœœœ˜ Jšœœ(˜;Jšœ˜—J˜J˜—šŸœœœœ˜/šœ,˜,Jšœœ,œ˜K—Jšœœœ˜0Jšœœ˜ Jšœœ˜ Jšœ/œ˜6šœD˜DJšœP˜PJšœ˜—Jšœ*˜*Jšœœ"˜,Jšœ˜J˜J˜—šŸ œ&œ˜FJ˜—š Ÿ œœœ œœ˜:Jšœ*˜*Jšœœ˜Jšœœ˜Jšœœ ˜Jšœœ ˜JšœF˜Fšœ ˜Jšœ1˜1šœœœ˜Jšœ-˜-Jšœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ˜—šœ œ˜Jšœ1˜1šœœœ ˜Jšœ-˜-Jšœ˜—Jšœ˜J˜—J˜J˜—šŸ œ ˜Jšœœœ˜>J˜—šŸœ ˜Jšœœ&˜DJ˜—šŸœ˜Jšœœ.˜8Jšœœ˜ Jšœœ˜ Jšœœ˜ šœœ˜JšœA˜AJš˜J˜—Jšœ2˜2šœœœ˜Jšœ)˜)Jšœ˜J˜—Jšœ%œ#˜J˜;Jšœ˜—J˜J˜—šŸœ˜Jšœœ.˜8Jšœœ˜ Jšœœ˜ Jšœœ˜ JšœGœœ˜UJšœœœ˜Jšœ0œ˜6Jšœ$˜$šœ˜ šœ@˜@Jšœ˜——J˜J˜—šŸœ ˜Jšœ.œ˜5J˜—šŸ œœ œœ˜;Jšœ œœ˜+Jšœœ˜Jšœœœ œ˜Jšœ œœœ˜"Jšœ œ˜Jšœž˜!Jšœœ%˜.šœ˜š Ÿœœ œœœœ˜6Jšœœ˜ Jšœ˜šœœ˜%˜MJšœR˜R—Jšœœ˜J˜—Jšœœ˜ Jšœ˜—Jšœ œ ˜Jšœœ˜ Jšœ ˜ Jšœ˜Jšœ2œœ˜Jšœ ˜Jšœ ˜ Jšœ ˜ šœ ˜ Jšœ#˜#šœœ˜Jšœ˜Jšœœ˜ J˜—Jšœœ)œ™BJšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ J™Jšœ™šœœ˜#Jšœœ˜'Jšœ˜J˜—Jšœ˜Jšœ™Jšœœ˜$Jšœ˜Jšœ˜—šœ ˜ šœœ˜Jšœ˜Jšœœ˜ J˜—Jšœ˜Jšœ œœ*˜Jšœ˜—Jšœ œ˜šœ˜ šœJ˜JJšœ3˜3—Jšœ˜Jšœœ˜ J˜——Jšœ˜—Jšœ˜Jšœ œ˜š œœ œœ ˜&Jšœ˜Jšœ˜Jšœ˜—Jšœ!˜!Jšœ(˜(šœ œ˜šŸœ˜Jšœœ˜Jšœœ˜Jšœœœ˜)Jšœœœ˜*Jšœ ˜J˜—Jšœ œ œ˜FJšœœ˜*šœœœ˜ Jšœ"˜"Jšœ˜Jšœ˜—J˜—Jšœ˜J˜—š Ÿ œœœœœ˜0J™GJšœœ˜ Jšœ˜ š˜šœ˜Jšœœ˜5Jšœœ˜:Jšœœ˜:Jšœ œœ˜6Jšœœ˜—Jšœ˜—J˜J˜—š Ÿœœœœœ˜QJšœœ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜ Jšœ9œœ ˜Mšœ œ˜Jšœ ˜ JšœI˜IJšœœ ˜—Jšœ˜šœ œ˜Jšœœ œœ ˜(Jš œœœœœœ ˜1šœœœ˜Jšœ œœœ˜"Jšœœ˜Jšœ˜—šœ˜ JšœI˜IJšœœ˜J˜—Jšœ˜J˜——šŸœœœœ˜BJšœœœœ˜ Jšœ œ ˜Jšœœ˜ Jšœœ˜ Jšœ ˜ Jšœœœœ˜Jšœ˜Jš œœœœœ˜6šœœ˜šœ œ8˜GJšœ/˜/—Jš˜J˜—šœœ˜ šœ œ7˜FJšœ0˜0—Jš˜J˜—šœœœ˜Jšœ œ5˜DJšœ˜J˜—šœœ˜#Jšœœ˜)Jšœœœ@˜OJ˜—šœœ˜'Jšœœ!˜-JšœœœD˜SJ˜—J˜šœœœ ˜Jšœœ˜ Jšœœœ˜'Jšœœœœ˜BJšœ#˜#JšœœœB˜QJšœ˜—J˜——˜š Ÿ œœœœ œœ˜:Kšœœ!˜)K˜—š Ÿ œœœœœ˜+Kš œœœœœ˜Kš œœœœœ˜(Kšœœ˜-Kšœ˜K˜—š Ÿœœœœœ œ˜OKšœ?œ™Wšœœœ)˜FKšœ.œ ˜;Kšœœ ˜-—J˜K˜—Kšœ ™ K™Kšœœ˜0—J˜Jšœ˜—…—Oςkš