DIRECTORY Ascii USING [BS, CR, LF], Basics USING [BITAND, LowHalf], CommandTool USING [ArgumentVector], Convert USING [CardFromRope, Error], IO, LarkControl USING [BootReason, Breakpoint, BreakpointObject, DisplayEvent, DisplayState, FetchState, LarkData, LoadProgram, LocalGo, RepairBreakpoint, SetState, SetValue, VerifyInternal], LarkPrograms USING [AddOrReplaceProgram, FetchProgram, FindVariable, Monitor, PatchFromFile, PatchItem, ProcedureEnclosing, Program, ReadProgramFromDisk, STObject], LarkWork USING [LarkWorkProc, RegisterLarkWorkProc], Process USING [MsecToTicks, Pause], ProcessExtras USING [CheckForAbort], Rope USING [Concat, Equal, ROPE], TeleLoad USING [AddressSpace, CoreAddress, CoreBlock, CoreBlockObject, EventRecordObject, Failed, Fetch, FlushWrites, GetEventData, GoToDebugger, Handle, locMaxByte, Read, ReadWord, Registers8086, ResetCache, SetCacheSize, SingleStep, State8086Object, Store, Write, WriteWord]; LarkWorkCommandsA: CEDAR PROGRAM IMPORTS Basics, Convert, IO, LarkControl, LarkPrograms, LarkWork, Process, ProcessExtras, Rope, TeleLoad = BEGIN BadCommRope: Rope.ROPE = "Communications Failure\n"; BadArgsRope: Rope.ROPE = "Bad Arguments\n"; SetCurrentProgram: LarkWork.LarkWorkProc = { IF argv.argc < 2 THEN RETURN["Requires programName as argument\n"]; IF NOT capital THEN { -- main CPU lark.program _ LarkPrograms.FetchProgram[argv[1]]; IF lark.program = NIL THEN RETURN[Rope.Concat[argv[1], " not found\n"]]; } ELSE { -- slave cpu lark.slaveProgram _ LarkPrograms.FetchProgram[argv[1]]; IF lark.slaveProgram = NIL THEN RETURN[Rope.Concat[argv[1], " not found\n"]]; }; }; Go: LarkWork.LarkWorkProc = { LarkControl.LocalGo[lark]; }; SingleStep: LarkWork.LarkWorkProc = { ENABLE { TeleLoad.Failed => GOTO BadComm; }; found: BOOL _ FALSE; breakpoint: LarkControl.Breakpoint; FOR l: LIST OF LarkControl.Breakpoint _ lark.breakList, l.rest WHILE l # NIL DO IF l.first.address = lark.state.Regs[IP] THEN { found _ TRUE; breakpoint _ l.first; EXIT; }; ENDLOOP; IF found THEN { LarkControl.RepairBreakpoint[h: lark.h, breakpoint: breakpoint]; [] _ LarkControl.SetState[h: lark.h, state: lark.state, tp: TeleLoad.SingleStep, print: TRUE]; Process.Pause[Process.MsecToTicks[50]]; TeleLoad.SetCacheSize[lark.h, 1]; TeleLoad.Write[lark.h, breakpoint.address, 0CCH]; TeleLoad.FlushWrites[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; } ELSE [] _ LarkControl.SetState[h: lark.h, state: lark.state, tp: TeleLoad.SingleStep, print: TRUE]; EXITS BadComm => RETURN[BadCommRope]; }; GetState: LarkWork.LarkWorkProc = { localState: TeleLoad.State8086Object; ok: BOOL; lark.h.log.PutRope["State\n"]; IF capital THEN { [ok, localState] _ LarkControl.FetchState[h: lark.h]; IF ok THEN lark.state _ localState; }; LarkControl.DisplayState[lark.h.log, lark.state]; }; AlterVariable: LarkWork.LarkWorkProc = { ENABLE Convert.Error => GOTO BadArgs; variableName: Rope.ROPE; offset: NAT _ 0; value: CARDINAL; IF argv.argc > 1 THEN variableName _ argv[1] ELSE RETURN; SELECT argv.argc FROM 3 => value _ Basics.LowHalf[Convert.CardFromRope[argv[2], 16]]; ENDCASE => { value _ Basics.LowHalf[Convert.CardFromRope[argv[3], 16]]; offset _ Basics.LowHalf[Convert.CardFromRope[argv[2], 16]]; }; [] _ LarkControl.SetValue[lark: lark, name: variableName, value: value, offset: offset]; EXITS BadArgs => RETURN["Bad arguments\n"]; }; AlterVariablesFromFile: LarkWork.LarkWorkProc = { ENABLE TeleLoad.Failed => GOTO BadComm; pl: LIST OF LarkPrograms.PatchItem; IF argv.argc # 2 THEN RETURN; pl _ LarkPrograms.PatchFromFile[program: lark.program, fileName: argv[1], log: lark.h.log]; TeleLoad.SetCacheSize[h: lark.h, bytes: 2]; WHILE pl # NIL DO TeleLoad.WriteWord[h: lark.h, addr: pl.first.address, value: pl.first.wordValue]; lark.h.log.PutChar['p]; pl _ pl.rest; ENDLOOP; TeleLoad.FlushWrites[lark.h]; TeleLoad.SetCacheSize[h: lark.h, bytes: 0]; lark.h.log.PutChar['\n]; EXITS BadComm => RETURN[BadCommRope]; }; SetBlock: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; destination: TeleLoad.CoreAddress; addr: TeleLoad.CoreAddress; count: LONG CARDINAL; value: CARDINAL; IF argv.argc NOT IN [4..5] THEN GOTO BadArgs; destination _ Convert.CardFromRope[argv[1], 16]; count _ Convert.CardFromRope[argv[2], 16]; value _ Basics.LowHalf[Convert.CardFromRope[argv[3], 16]]; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; addr _ destination; WHILE addr < (destination+count) DO TeleLoad.WriteWord[h: lark.h, addr: addr, value: value]; addr _ addr + 2; ENDLOOP; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; CheckSetBlock: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; destination: TeleLoad.CoreAddress; addr: TeleLoad.CoreAddress; count: LONG CARDINAL; value, found: CARDINAL; IF argv.argc # 4 THEN GOTO BadArgs; destination _ Convert.CardFromRope[argv[1], 16]; count _ Convert.CardFromRope[argv[2], 16]; value _ Basics.LowHalf[Convert.CardFromRope[argv[3], 16]]; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; addr _ destination; WHILE addr < (destination+count) DO found _ TeleLoad.ReadWord[h: lark.h, addr: addr]; IF found # value THEN { lark.h.log.PutF["%04x is %04x\n", IO.card[addr], IO.card[found]]; ProcessExtras.CheckForAbort[]; }; addr _ addr + 2; ENDLOOP; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; FillWithAddress: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; destination: TeleLoad.CoreAddress; addr: TeleLoad.CoreAddress; count: LONG CARDINAL; bytes: BOOL _ capital; IF argv.argc # 3 THEN RETURN; destination _ Convert.CardFromRope[argv[1], 16]; count _ Convert.CardFromRope[argv[2], 16]; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; addr _ destination; WHILE addr < (destination+count) DO IF bytes THEN { TeleLoad.Write[h: lark.h, addr: addr, value: Basics.BITAND[Basics.LowHalf[addr], 0377B]]; addr _ addr + 1; } ELSE { TeleLoad.WriteWord[h: lark.h, addr: addr, value: Basics.LowHalf[addr]]; addr _ addr + 2; }; ENDLOOP; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; CheckAddressFill: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; destination: TeleLoad.CoreAddress; addr: TeleLoad.CoreAddress; count: LONG CARDINAL; bytes: BOOL _ capital; found: CARDINAL; IF argv.argc # 3 THEN RETURN; destination _ Convert.CardFromRope[argv[1], 16]; count _ Convert.CardFromRope[argv[2], 16]; TeleLoad.FlushWrites[lark.h]; TeleLoad.ResetCache[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; addr _ destination; WHILE addr < (destination+count) DO IF bytes THEN { found _ TeleLoad.Read[h: lark.h, addr: addr]; IF found # LOOPHOLE[Basics.BITAND[Basics.LowHalf[addr], 0377B], CARDINAL] THEN { lark.h.log.PutF["%04x is %02x\n", IO.card[addr], IO.card[found]]; ProcessExtras.CheckForAbort[]; }; addr _ addr + 1; } ELSE { found _ TeleLoad.ReadWord[h: lark.h, addr: addr]; IF found # LOOPHOLE[Basics.LowHalf[addr], CARDINAL] THEN { lark.h.log.PutF["%04x is %04x\n", IO.card[addr], IO.card[found]]; ProcessExtras.CheckForAbort[]; }; addr _ addr + 2; }; ENDLOOP; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; Blit: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; source, destination: TeleLoad.CoreAddress; count: LONG CARDINAL; IF argv.argc # 4 THEN RETURN; source _ Convert.CardFromRope[argv[1], 16]; destination _ Convert.CardFromRope[argv[2], 16]; count _ Convert.CardFromRope[argv[3], 10]; BlitInternal[h: lark.h, source: source, destination: destination, count: count]; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; BlitInternal: PROC [h: TeleLoad.Handle, source, destination: TeleLoad.CoreAddress, count: LONG CARDINAL] = { cb: TeleLoad.CoreBlock; highAddr: TeleLoad.CoreAddress; TeleLoad.FlushWrites[h]; TeleLoad.ResetCache[h]; TeleLoad.SetCacheSize[h, 0]; cb _ NEW[TeleLoad.CoreBlockObject[TeleLoad.locMaxByte]]; highAddr _ source+count-1; DO IF source+TeleLoad.locMaxByte > highAddr THEN { count _ highAddr-source; cb _ NEW[TeleLoad.CoreBlockObject[count]]; } ELSE count _ TeleLoad.locMaxByte; cb.address _ source; cb.advice _ [FALSE, FALSE, 0]; IF NOT TeleLoad.Fetch[h, cb].ok THEN { h.log.PutF["\ncannot fetch %d bytes from address %04xH\n", IO.card[count], IO.card[source]]; EXIT; }; cb.address _ destination; cb.advice _ [FALSE, FALSE, 0]; IF NOT TeleLoad.Store[h, cb].ok THEN { h.log.PutF["\ncannot restore %d bytes at address %04xH\n", IO.card[count], IO.card[destination]]; EXIT; }; h.log.PutChar['.]; destination _ destination + TeleLoad.locMaxByte; source _ source + TeleLoad.locMaxByte; IF source > highAddr THEN EXIT; ENDLOOP; h.log.PutChar['\n]; }; LocalLoad: LarkWork.LarkWorkProc = { IF NOT capital AND lark.program = NIL THEN RETURN["No program selected\n"]; IF capital AND lark.slaveProgram = NIL THEN RETURN["No program selected\n"]; IF NOT capital AND lark.breakList # NIL THEN { lark.h.log.PutRope["Clearing breakpoints\n"]; lark.breakList _ NIL; }; LarkControl.LoadProgram[lark: lark, go: FALSE, main: NOT capital]; }; MemoryTest: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; out: IO.STREAM _ lark.h.log; h: TeleLoad.Handle _ lark.h; saved, cb: TeleLoad.CoreBlock; lowAddr, highAddr, addr: TeleLoad.CoreAddress; count: CARDINAL; TestLump: PROC [testValue: CARDINAL] RETURNS [BOOL] = { cb.address _ addr; cb.advice _ [FALSE, FALSE, 0]; FOR i: CARDINAL IN [0..count) DO cb.data[i] _ testValue; ENDLOOP; IF NOT TeleLoad.Store[h, cb].ok THEN { cb.advice _ [FALSE, FALSE, 0]; IF NOT TeleLoad.Fetch[h, cb].ok THEN out.PutRope["contact lost\n"]; FOR i: CARDINAL IN [0..count) DO IF cb.data[i] # testValue THEN { out.PutF["loc %4x is %02x, should be %02x\r", IO.card[addr+i], IO.card[cb.data[i]], IO.card[testValue]]; EXIT; }; ENDLOOP; out.PutF["test of %d bytes of %02x at address %04xH failed\r", IO.card[count], IO.card[testValue], IO.card[addr]]; RETURN [FALSE]; }; RETURN[TRUE]; }; TeleLoad.ResetCache[h]; IF argv.argc # 3 THEN RETURN; lowAddr _ Convert.CardFromRope[argv[1], 16]; highAddr _ Convert.CardFromRope[argv[2], 16]; saved _ NEW[TeleLoad.CoreBlockObject[TeleLoad.locMaxByte]]; cb _ NEW[TeleLoad.CoreBlockObject[TeleLoad.locMaxByte]]; addr _ lowAddr; DO IF addr+TeleLoad.locMaxByte > highAddr THEN { count _ Basics.LowHalf[highAddr-addr]; cb _ NEW[TeleLoad.CoreBlockObject[count]]; saved _ NEW[TeleLoad.CoreBlockObject[count]]; } ELSE count _ TeleLoad.locMaxByte; saved.address _ addr; saved.advice _ [FALSE, FALSE, 0]; IF NOT TeleLoad.Fetch[h, saved].ok THEN { out.PutF["cannot fetch %d bytes from address %04xH\r", IO.card[count], IO.card[addr]]; EXIT; }; IF NOT TestLump[0377B] THEN EXIT; IF NOT TestLump[0B] THEN EXIT; IF NOT TestLump[0252B] THEN EXIT; IF NOT TestLump[0125B] THEN EXIT; saved.advice _ [FALSE, FALSE, 0]; IF NOT TeleLoad.Store[h, saved].ok THEN { out.PutF["cannot restore %d bytes at address %04xH\r", IO.card[count], IO.card[addr]]; EXIT; }; addr _ addr + TeleLoad.locMaxByte; IF addr > highAddr THEN EXIT; ENDLOOP; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; ChangeRegister: LarkWork.LarkWorkProc = { value: CARDINAL; IfCmd: PROC [r: Rope.ROPE] RETURNS [BOOL] = { RETURN [Rope.Equal[argv[1], r, FALSE]]; }; IF argv.argc # 3 THEN GOTO BadArgs; value _ Basics.LowHalf[Convert.CardFromRope[argv[2], 16 ! Convert.Error => GOTO BadArgs]]; IF IfCmd["AX"] THEN lark.state.Regs[AX] _ value; IF IfCmd["BX"] THEN lark.state.Regs[BX] _ value; IF IfCmd["CX"] THEN lark.state.Regs[CX] _ value; IF IfCmd["DX"] THEN lark.state.Regs[DX] _ value; IF IfCmd["SP"] THEN lark.state.Regs[SP] _ value; IF IfCmd["BP"] THEN lark.state.Regs[BP] _ value; IF IfCmd["SI"] THEN lark.state.Regs[SI] _ value; IF IfCmd["DI"] THEN lark.state.Regs[DI] _ value; IF IfCmd["IP"] THEN lark.state.Regs[IP] _ value; IF IfCmd["FL"] THEN lark.state.Regs[FL] _ value; IF IfCmd["CS"] THEN lark.state.Regs[CS] _ value; IF IfCmd["DS"] THEN lark.state.Regs[DS] _ value; IF IfCmd["SS"] THEN lark.state.Regs[SS] _ value; IF IfCmd["ES"] THEN lark.state.Regs[ES] _ value; IF IfCmd["SR"] THEN StartRegisters[lark]; IF IfCmd["ZR"] THEN ZeroRegisters[lark]; IF IfCmd["RR"] THEN RemoteRegisters[lark]; IF IfCmd["ER"] THEN EventRegisters[lark]; IF IfCmd["?"] THEN RETURN["8088 register name or: SR => program start state, ZR => zero registers, ER => last event registers, RR => remote registers\n"]; LarkControl.DisplayState[lark.h.log, lark.state]; EXITS BadArgs => RETURN[BadArgsRope]; }; ZeroRegisters: PROC [lark: LarkControl.LarkData] = { FOR i: TeleLoad.Registers8086 IN [AX..FL] DO lark.state.Regs[i] _ 0; ENDLOOP; lark.state.Regs[IP] _ 1024; -- 00400H lark.state.Regs[SP] _ 54256; -- 0D3F0H }; StartRegisters: PROC [lark: LarkControl.LarkData] = { IF lark.program # NIL THEN lark.state _ lark.program.startState ELSE lark.h.log.PutRope[" . . .No program specified\n"]; }; RemoteRegisters: PROC [lark: LarkControl.LarkData] = { localState: TeleLoad.State8086Object; ok: BOOL; [ok, localState] _ LarkControl.FetchState[h: lark.h]; IF ok THEN lark.state _ localState; }; EventRegisters: PROC [lark: LarkControl.LarkData] = { lark.state _ lark.event.regs; }; InteractiveDebug: LarkWork.LarkWorkProc = { ENABLE TeleLoad.Failed => GOTO BadComm; out: IO.STREAM _ lark.h.log; in: IO.STREAM _ lark.eval.in.backingStream; -- not edited h: TeleLoad.Handle _ lark.h; address: INT; value: CARDINAL; variableRope: Rope.ROPE; found: BOOL; sym: LarkPrograms.STObject; c: CHAR; addressSpace: TeleLoad.AddressSpace _ main; words: BOOL _ TRUE; PrintVarAddress: PROC = { sym _ LarkPrograms.ProcedureEnclosing[lark.program, address]; out.PutF["\n%04xH (%g", IO.card[address], IO.rope[sym.id]]; IF sym.addr # address THEN out.PutF[" + %04xH): ", IO.card[address - sym.addr]] ELSE out.PutF["): "]; }; TeleLoad.ResetCache[h]; TeleLoad.SetCacheSize[h, 2]; IF argv.argc > 1 THEN variableRope _ argv[1] ELSE variableRope _ lark.eval.in.GetTokenRope[].token; [item: sym, found: found] _ LarkPrograms.FindVariable[lark.program, variableRope]; IF found THEN address _ sym.addr ELSE address _ Convert.CardFromRope[variableRope, 16 ! Convert.Error => { out.PutRope["???\n"]; GOTO Quit; }]; PrintVarAddress[]; DO value _ IF words THEN TeleLoad.ReadWord[h: h, addr: address, addressSpace: addressSpace] ELSE TeleLoad.Read[h: h, addr: address, addressSpace: addressSpace]; IF words THEN out.PutF["%04xH (%6d) ", IO.card[value], IO.card[value]] ELSE out.PutF["%02xH (%3d) ", IO.card[value], IO.card[value]]; c _ in.GetChar[]; SELECT c FROM Ascii.LF, 'n => { address _ IF words THEN address + 2 ELSE address + 1; PrintVarAddress[]; }; Ascii.BS, 'p => { address _ IF words THEN address - 2 ELSE address - 1; PrintVarAddress[]; }; Ascii.CR => EXIT; 'w, 'W => { words _ TRUE; TeleLoad.SetCacheSize[h, 2]; PrintVarAddress[]; }; 'b, 'B => { words _ FALSE; TeleLoad.SetCacheSize[h, 1]; PrintVarAddress[]; }; 's, 'S => { addressSpace _ main; PrintVarAddress[]; }; 'm, 'M => { addressSpace _ slave; PrintVarAddress[]; }; 't, 'T => { address _ value; PrintVarAddress[]; }; '? => { out.PutF["LF, n => next word, BS, p => previous, CR => exit, m => main, s=> slave, w => words, b=> bytes, _ => new hex value, t => trace\n"]; PrintVarAddress[]; }; '_ => { out.PutF[" _ "]; value _ Basics.LowHalf[Convert.CardFromRope[lark.eval.in.GetTokenRope[].token, 16 ! Convert.Error => GOTO Quit]]; IF words THEN TeleLoad.WriteWord[h, address, value, addressSpace] ELSE TeleLoad.Write[h, address, value, addressSpace]; TeleLoad.FlushWrites[h]; address _ IF words THEN address + 2 ELSE address + 1; PrintVarAddress[]; lark.eval.in.Reset[]; }; ENDCASE => { out.PutF["LF, n => next word, BS, p => previous, CR => exit, m => main, s=> slave, w => words, b=> bytes, _ => new hex value\n"]; PrintVarAddress[]; lark.eval.in.Reset[]; }; ENDLOOP; out.PutChar['\n]; TeleLoad.ResetCache[h]; TeleLoad.SetCacheSize[h, 0]; EXITS Quit => NULL; BadComm => RETURN[BadCommRope]; }; SetBreak: LarkWork.LarkWorkProc = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; out: IO.STREAM _ lark.h.log; sym: LarkPrograms.STObject; address, offset: TeleLoad.CoreAddress; breakpoint: LarkControl.Breakpoint; found: BOOL; set: BOOL _ NOT capital; IF argv.argc # 2 AND argv.argc # 3 THEN RETURN; [item: sym, found: found] _ LarkPrograms.FindVariable[lark.program, argv[1]]; IF found THEN address _ sym.addr ELSE { address _ Convert.CardFromRope[argv[1], 16 ! Convert.Error => { out.PutF["%g not found\n", IO.rope[argv[1]]]; GOTO Quit; }]; }; IF argv.argc = 3 THEN offset _ Convert.CardFromRope[argv[2], 16 ! Convert.Error => { out.PutF["%g bad offset\n", IO.rope[argv[2]]]; GOTO Quit; }] ELSE offset _ 0; found _ FALSE; FOR l: LIST OF LarkControl.Breakpoint _ lark.breakList, l.rest WHILE l # NIL DO IF offset + address = l.first.address THEN { found _ TRUE; EXIT; }; ENDLOOP; IF set THEN { IF found THEN out.PutRope["Breakpoint already exists.\n"] ELSE { breakpoint _ NEW[LarkControl.BreakpointObject]; breakpoint.address _ address + offset; TeleLoad.SetCacheSize[lark.h, 1]; breakpoint.codeByte _ TeleLoad.Read[lark.h, breakpoint.address]; lark.breakList _ CONS[breakpoint, lark.breakList]; TeleLoad.Write[lark.h, breakpoint.address, 0CCH]; TeleLoad.FlushWrites[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; }; } ELSE { IF found THEN { l: LIST OF LarkControl.Breakpoint _ lark.breakList; lark.breakList _ NIL; WHILE l # NIL DO IF l.first.address # offset + address THEN lark.breakList _ CONS[l.first, lark.breakList] ELSE breakpoint _ l.first; l _ l.rest; ENDLOOP; TeleLoad.SetCacheSize[lark.h, 1]; TeleLoad.Write[lark.h, breakpoint.address, breakpoint.codeByte]; TeleLoad.FlushWrites[lark.h]; TeleLoad.SetCacheSize[lark.h, 0]; } ELSE out.PutRope["Breakpoint doesn't exist.\n"]; }; EXITS Quit => NULL; BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; WorkVerify: LarkWork.LarkWorkProc = { program: LarkPrograms.Program; IF lark = NIL THEN RETURN["NIL Lark!"]; program _ IF capital THEN lark.slaveProgram ELSE lark.program; IF program = NIL THEN RETURN["No program!"]; IF capital THEN lark.h.log.PutRope["Verify Slave program\n"] ELSE lark.h.log.PutRope["Verify Main program\n"]; RETURN[VerifyCommon[lark, argv, program]] }; MonitorVerify: LarkWork.LarkWorkProc = { program: LarkPrograms.Program _ LarkPrograms.Monitor[log: lark.h.log, addressSpace: IF capital THEN slave ELSE main]; IF lark = NIL THEN RETURN["NIL Lark!"]; IF program = NIL THEN RETURN["No monitor!"]; IF capital THEN lark.h.log.PutRope["Verify Slave Monitor\n"] ELSE lark.h.log.PutRope["Verify Main Monitor\n"]; RETURN[VerifyCommon[lark, argv, program]] }; VerifyCommon: PROC [lark: LarkControl.LarkData, argv: CommandTool.ArgumentVector, program: LarkPrograms.Program] RETURNS [Rope.ROPE] = { ENABLE { Convert.Error => GOTO BadArgs; TeleLoad.Failed => GOTO BadComm; }; startAddress, stopAddress: TeleLoad.CoreAddress; log: IO.STREAM _ lark.h.log; IF argv.argc = 3 THEN { startAddress _ Convert.CardFromRope[argv[1], 16]; stopAddress _ Convert.CardFromRope[argv[2], 16]; } ELSE { startAddress _ 0; stopAddress _ 0; }; LarkControl.VerifyInternal[lark: lark, program: program, startAddress: startAddress, stopAddress: stopAddress]; RETURN[NIL]; EXITS BadArgs => RETURN[BadArgsRope]; BadComm => RETURN[BadCommRope]; }; Zap: LarkWork.LarkWorkProc = { [] _ LarkControl.SetState[h: lark.h, state: lark.state, tp: TeleLoad.GoToDebugger, print: FALSE]; }; ParseProgram: LarkWork.LarkWorkProc = { program: LarkPrograms.Program _ LarkPrograms.ReadProgramFromDisk[objectFileName: argv[1], log: lark.h.log, addressSpace: IF capital THEN slave ELSE main]; IF argv.argc # 2 THEN RETURN; IF program # NIL THEN LarkPrograms.AddOrReplaceProgram[program]; }; ShowEvent: LarkWork.LarkWorkProc = { IF NOT capital THEN { ok: BOOL; event: TeleLoad.EventRecordObject; [event: event, ok: ok] _ TeleLoad.GetEventData[lark.h, FALSE]; IF ok THEN lark.event _ event ELSE lark.h.log.PutRope["GetEventData failed\n"]; }; LarkControl.DisplayEvent[lark: lark, event: lark.event, out: lark.h.log, reasonRope: LarkControl.BootReason[lark.event.reason, lark.event.regs.Regs[BX]], preRope: "Event "]; }; LarkWork.RegisterLarkWorkProc[proc: SetCurrentProgram, key: "CurrentProgram", caseMatters: FALSE, doc: "Set program which Lark should use", usage: "[c/C]urrentProgram programName, c => main, C => slave"]; LarkWork.RegisterLarkWorkProc[proc: Go, key: "Go", caseMatters: FALSE, doc: "Start full speed execution"]; LarkWork.RegisterLarkWorkProc[proc: SingleStep, key: "Next", caseMatters: FALSE, doc: "Single step"]; LarkWork.RegisterLarkWorkProc[proc: GetState, key: "X", caseMatters: FALSE, doc: "Print Lark State", usage: "x: print local state, X print remote state and copy to local state"]; LarkWork.RegisterLarkWorkProc[proc: AlterVariable, key: "AlterVariable", caseMatters: FALSE, doc: "Change a variable in Lark", usage: "AlterVariable variableName {offset} value"]; LarkWork.RegisterLarkWorkProc[proc: AlterVariablesFromFile, key: "FilePatch", caseMatters: FALSE, doc: "Patch Lark from a File", usage: "FilePatch patchFileName"]; LarkWork.RegisterLarkWorkProc[proc: SetBlock, key: "SetBlock", caseMatters: FALSE, doc: "Set a block of memory to a value", usage: "SetBlock addr count value, count and value are in words"]; LarkWork.RegisterLarkWorkProc[proc: CheckSetBlock, key: "CheckSetBlock", caseMatters: FALSE, doc: "Check that a block of memory is set to a value", usage: "CheckSetBlock addr count value, count and value are in words"]; LarkWork.RegisterLarkWorkProc[proc: FillWithAddress, key: "FillWithAddress", caseMatters: FALSE, doc: "Fill a block of memory with its address", usage: "FillWithAddress addr count {b}, b => count is in bytes"]; LarkWork.RegisterLarkWorkProc[proc: CheckAddressFill, key: "CheckFillWithAddress", caseMatters: FALSE, doc: "Check that a block of memory is filled with its address", usage: "CheckFillWithAddress addr count {b}, b => count is in bytes"]; LarkWork.RegisterLarkWorkProc[proc: Blit, key: "Move", caseMatters: FALSE, doc: "BLT in Lark", usage: "Move from to count"]; LarkWork.RegisterLarkWorkProc[proc: LocalLoad, key: "Load", caseMatters: FALSE, doc: "Load current program", usage: "[l/L]oad, l => load main, L => load slave"]; LarkWork.RegisterLarkWorkProc[proc: MemoryTest, key: "TestMemory", caseMatters: FALSE, doc: "Test Lark Memory", usage: "TestMemory lowAddress highAddress"]; LarkWork.RegisterLarkWorkProc[proc: ChangeRegister, key: "Register", caseMatters: FALSE, doc: "Change a register value", usage: "Register registerName newValue"]; LarkWork.RegisterLarkWorkProc[proc: InteractiveDebug, key: "Fiddle", caseMatters: FALSE, doc: "Enter interactive debugger", usage: "Fiddle {Variable}"]; LarkWork.RegisterLarkWorkProc[proc: SetBreak, key: "Break", caseMatters: FALSE, doc: "Set and clear breakpoints", usage: "[b/B]reak {variableOrAddress} {offset}. break => set, Beak => clear, no argument => all breaks"]; LarkWork.RegisterLarkWorkProc[proc: WorkVerify, key: "Verify", caseMatters: FALSE, doc: "Check Lark Code space", usage: "[v/V]erify {lowAddress highAddress}, v => main program, V => slave program"]; LarkWork.RegisterLarkWorkProc[proc: MonitorVerify, key: "MonVerify", caseMatters: FALSE, doc: "Check Lark monitor", usage: "[m/M]onVerify {lowAddress highAddress}, m => main monitor, M => slave monitor"]; LarkWork.RegisterLarkWorkProc[proc: Zap, key: "Zap", caseMatters: FALSE, doc: "Force Lark into debugger"]; LarkWork.RegisterLarkWorkProc[proc: ParseProgram, key: "Parse", caseMatters: FALSE, doc: "Read a program from disk", usage: "[p/P]arse programName, p => main CPU, P => slave CPU"]; LarkWork.RegisterLarkWorkProc[proc: ShowEvent, key: "Event", caseMatters: FALSE, doc: "Display last event", usage: "[e/E]vent. e => fetch event and print, E => print local event"]; END. April 27, 1983 2:14 pm, LCS, created from LarkWorkImpl December 22, 1983 2:43 pm, LCS, Cedar 5 ¬LarkWorkCommandsA.mesa L. Stewart, December 22, 1983 2:43 pm Fetch old contents Store old contents Fetch old contents Store old contents Register all the commands �ÊZ˜Jšœ™Jšœ%™%J˜šÏk ˜ Jš œ�œ�œ�œ�œ˜Jšœ�œ�œ ˜Jšœ �œ˜#Jšœ�œ˜$Jš�œ˜Jšœ �œª˜»Jšœ �œ’˜¤Jšœ �œ&˜4Jšœ�œ˜#Jšœ�œ˜$Jšœ�œ�œ˜!Jšœ �œ‡˜•—J˜Jšœ�œ�˜ Jš�œ�œO˜jJš�˜Jšœ�œ˜4Jšœ�œ˜+J˜šœ,˜,Jš�œ�œ�œ'˜Cš�œ�œ �œÏc ˜!Jšœ2˜2Jš�œ�œ�œ�œ'˜HJ˜—š�œž ˜Jšœ7˜7Jš�œ�œ�œ�œ'˜MJ˜—J˜—J˜šœ˜J˜J˜—J˜šœ%˜%š�œ˜Jšœ�œ ˜ J˜—Jšœ�œ�œ˜J˜#š �œ�œ�œ1�œ�œ�˜Oš�œ#�œ�œ˜/Jšœ�œ˜ Jšœ˜Jš�œ˜J˜—Jš�œ˜—š�œ�œ˜Jšœ@˜@JšœX�œ˜^J˜'Jšœ!˜!Jšœ1˜1Jšœ˜Jšœ!˜!J˜—Jš�œY�œ˜cJš�˜Jšœ �œ˜J˜—J˜šœ#˜#J˜%Jšœ�œ˜ Jšœ˜š�œ �œ˜Jšœ5˜5Jš�œ�œ˜#J˜—Jšœ1˜1J˜—J˜šœ(˜(Jš�œ�œ ˜%Jšœ�œ˜Jšœ�œ˜Jšœ�œ˜Jš�œ�œ˜,Jš�œ�œ˜ š�œ �˜Jšœ?˜?š�œ˜ Jšœ:˜:Jšœ;˜;J˜——JšœX˜XJš�˜Jšœ �œ˜%J˜J˜—šœ1˜1Jš�œ�œ ˜'Jšœ�œ�œ˜#Jš�œ�œ�œ˜Jšœ[˜[J˜+š�œ�œ�˜J˜QJšœ˜J˜ Jš�œ˜—J˜J˜+Jšœ˜Jš�˜Jšœ �œ˜J˜J˜—šœ#˜#š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—J˜"J˜Jšœ�œ�œ˜Jšœ�œ˜Jš �œ �œ�œ�œ�œ ˜-Jšœ0˜0Jšœ*˜*Jšœ:˜:Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜š�œ�˜#Jšœ8˜8J˜Jš�œ˜—Jšœ˜Jšœ˜Jš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šœ(˜(š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—J˜"J˜Jšœ�œ�œ˜Jšœ�œ˜Jš�œ�œ�œ ˜#Jšœ0˜0Jšœ*˜*Jšœ:˜:Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜š�œ�˜#Jšœ1˜1š�œ�œ˜Jšœ"�œ �œ˜AJšœ˜J˜—J˜Jš�œ˜—Jšœ˜Jšœ˜Jš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šœ*˜*š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—J˜"J˜Jšœ�œ�œ˜Jšœ�œ ˜Jš�œ�œ�œ˜Jšœ0˜0Jšœ*˜*Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜š�œ�˜#š�œ�œ˜Jšœ4�œ˜YJ˜J˜—š�œ˜JšœG˜GJ˜J˜—Jš�œ˜—Jšœ˜Jšœ˜Jš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šœ+˜+š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—J˜"J˜Jšœ�œ�œ˜Jšœ�œ ˜Jšœ�œ˜Jš�œ�œ�œ˜Jšœ0˜0Jšœ*˜*Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜š�œ�˜#š�œ�œ˜Jšœ-˜-š �œ �œ�œ�œ�œ˜PJšœ"�œ �œ˜AJšœ˜J˜—J˜J˜—š�œ˜Jšœ1˜1š�œ �œ�œ�œ˜:Jšœ"�œ �œ˜AJšœ˜J˜—J˜J˜—Jš�œ˜—Jš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šœ˜š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—J˜*Jšœ�œ�œ˜Jš�œ�œ�œ˜Jšœ+˜+Jšœ0˜0Jšœ*˜*J˜PJš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šÏn œ�œH�œ�œ˜lJ˜J˜Jšœ˜Jšœ˜Jšœ˜Jšœ�œ0˜8J˜š�˜š�œ'�œ˜/J˜Jšœ�œ"˜*J˜—Jš�œ˜!Jšœ™J˜Jšœ �œ�œ˜š�œ�œ�œ˜&Jšœ;�œ�œ˜\Jš�œ˜J˜—Jšœ™J˜Jšœ �œ�œ˜š�œ�œ�œ˜&Jšœ;�œ�œ˜aJš�œ˜J˜—Jšœ˜J˜0J˜&Jš�œ�œ�œ˜Jš�œ˜—Jšœ˜J˜—J˜šœ$˜$Jš �œ�œ �œ�œ�œ�œ˜KJš �œ �œ�œ�œ�œ˜Lš �œ�œ �œ�œ�œ˜.Jšœ-˜-Jšœ�œ˜J˜—Jšœ(�œ�œ ˜BJ˜—J˜šœ%˜%š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—Jšœ�œ�œ˜J˜J˜J˜.Jšœ�œ˜š Ÿœ�œ �œ�œ�œ˜7J˜Jšœ �œ�œ˜Jš �œ�œ�œ �œ�œ˜Aš�œ�œ�œ˜&Jšœ �œ�œ˜Jš�œ�œ�œ˜Cš�œ�œ�œ �˜ š�œ�œ˜ Jšœ.�œ�œ�œ˜hJš�œ˜J˜—Jš�œ˜—Jšœ?�œ�œ�œ ˜rJš�œ�œ˜J˜—Jš�œ�œ˜ J˜—Jšœ˜Jš�œ�œ�œ˜Jšœ,˜,Jšœ-˜-Jšœ�œ0˜;Jšœ�œ0˜8J˜š�˜š�œ%�œ˜-J˜&Jšœ�œ"˜*Jšœ�œ"˜-J˜—Jš�œ˜!Jšœ™J˜Jšœ�œ�œ˜!š�œ�œ�œ˜)Jšœ7�œ�œ ˜VJš�œ˜J˜—Jš�œ�œ�œ�œ˜!Jš�œ�œ�œ�œ˜Jš�œ�œ�œ�œ˜!Jš�œ�œ�œ�œ˜!Jšœ™Jšœ�œ�œ˜!š�œ�œ�œ˜)Jšœ7�œ�œ ˜VJš�œ˜J˜—J˜"Jš�œ�œ�œ˜Jš�œ˜—Jš�˜Jšœ �œ˜Jšœ �œ˜J˜J˜—šœ)˜)Jšœ�œ˜š Ÿœ�œ �œ�œ�œ˜-Jš�œ�œ˜'J˜—Jš�œ�œ�œ ˜#JšœK�œ ˜ZJš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ�œ ˜0Jš�œ �œ˜)Jš�œ �œ˜(Jš�œ �œ˜*Jš�œ �œ˜)Jš�œ �œ�œ�˜šJšœ1˜1Jš�˜Jšœ �œ˜J˜J˜—šŸ œ�œ!˜4Jš �œ�œ�œ�œ�œ�œ˜MJšœ�œ ž ˜%Jšœ�œ ž ˜&J˜—J˜šŸœ�œ!˜5Jš�œ�œ�œ%˜?Jš�œ4˜8J˜—J˜šŸœ�œ!˜6J˜%Jšœ�œ˜ Jšœ5˜5Jš�œ�œ˜#J˜—J˜šŸœ�œ!˜5Jšœ˜J˜—J˜šœ+˜+Jš�œ�œ ˜'Jšœ�œ�œ˜Jšœ�œ�œž ˜9Jšœ˜Jšœ �œ˜ Jšœ�œ˜Jšœ�œ˜Jšœ�œ˜ J˜Jšœ�œ˜Jšœ+˜+Jšœ�œ�œ˜šŸœ�œ˜J˜=Jšœ�œ�œ˜;Jš�œ�œ�œ˜OJš�œ˜J˜—Jšœ˜Jšœ˜Jš�œ�œ˜,Jš�œ2˜6J˜RJš�œ�œ˜ š�œE˜IJšœ˜Jš�œ˜ Jšœ˜—J˜š�˜Jšœ�œ�œD�œ@˜�Jš�œ�œ�œ�œ ˜FJš�œ�œ�œ˜>J˜š�œ�˜ šœ�œ ˜Jšœ �œ�œ �œ ˜5J˜J˜—šœ�œ ˜Jšœ �œ�œ �œ ˜5J˜J˜—Jšœ�œ�œ˜˜ Jšœ�œ˜ J˜J˜J˜—˜ Jšœ�œ˜J˜J˜J˜—˜ Jšœ˜J˜J˜—˜ Jšœ˜J˜J˜—˜ Jšœ˜J˜J˜—˜J˜�J˜J˜—˜J˜Jšœe�œ˜qJš�œ�œ5�œ1˜wJšœ˜Jšœ �œ�œ �œ ˜5J˜Jšœ˜J˜—š�œ˜ J˜�J˜Jšœ˜J˜——Jš�œ˜—Jšœ˜Jšœ˜Jšœ˜Jš�˜Jšœ�œ˜ Jšœ �œ˜J˜—J˜šœ#˜#š�œ˜Jšœ�œ ˜Jšœ�œ ˜ J˜—Jšœ�œ�œ˜J˜J˜&J˜#Jšœ�œ˜ Jšœ�œ�œ ˜Jš�œ�œ�œ�œ˜/J˜MJš�œ�œ˜ š�œ˜˜?Jšœ�œ˜-Jš�œ˜ J˜—J˜—š�œ�œ?˜TJšœ�œ˜.Jš�œ˜ J˜—Jš�œ ˜Jšœ�œ˜š �œ�œ�œ1�œ�œ�˜Oš�œ$�œ˜,Jšœ�œ˜ Jš�œ˜J˜—Jš�œ˜—š�œ�œ˜ Jš�œ�œ,˜9š�œ˜Jšœ �œ˜/J˜&J˜!J˜@Jšœ�œ˜2J˜1J˜J˜!J˜—J˜—š�œ˜š�œ�œ˜Jšœ�œ�œ)˜3Jšœ�œ˜š�œ�œ�˜Jš�œ$�œ�œ˜YJš�œ˜J˜ Jš�œ˜—J˜!J˜@J˜J˜!J˜—Jš�œ,˜0J˜—Jš�˜Jšœ�œ˜ Jšœ �œ˜Jšœ �œ˜J˜—J˜šœ%˜%Jšœ˜Jš�œ�œ�œ�œ˜'Jšœ �œ �œ�œ˜>Jš�œ �œ�œ�œ˜,Jš�œ �œ-˜