<> <> 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