// SwatCommand.bcpl - Main Loop // Copyright Xerox Corporation 1980, 1982 // Last modified March 21, 1982 1:59 PM by Boggs get "Swat.decl" external [ // outgoing procedures SwatCommand; OpenCell // incoming procedures from Swat Exp SysIn; SysOut; TeleSwatServer; PrintError SetFailPt; ReportFail EffAddr; SymbolicInst StackSwapIn; MapStack; PrintFrame; Frame; GetRetPC MeasureSpy; DisplaySpy; StartSpy; StopSpy SetBreak; DelBreak; DelAllBreaks; PrintAllBreaks; BreakSwapOut; BreakSwapIn ResidentSwapOut; ResidentSwapIn; UserScreen; Go; Call; DisplayState SymSwapIn; AddrToSym; SymRead; SymPrint VMFetch; VMStore; VMSwap; VMSpace; VMPrint; VMCache ReadSwapOut; ReadSwapIn; ReadLine; ReadFromFile; ReadChar // incoming procedures from OS Ws; PutTemplate; Puts; Free; Gets; Resets // outgoing statics openCell // results of Exp's sucessful parse are: // char - the control character that ended the line NARGS // the number of arguments ARGS // a vector of arguments (ARG!1 is first) ALTFLG // true if an ESC immediately preceded char ALTFLG2 // true if two ESCs immediately preceded char // incoming statics sysZone; dsp; state; keys; vm; debugFlag ] static [ assignable = false // true iff open cell is assignable openCell // address of current open cell lastOpenCell // cell open just before this one openMode // type out mode (↑O, ↑D, ↑I, ↑N, or ↑S) char lastSearch // last arg to search command ] manifest [ CTRLA = 1B; CTRLB = 2B; CTRLC = 3B; CTRLD = 4B; CTRLE = 5B CTRLF = 6B; CTRLG = 7B; CTRLH = 10B; CTRLI = 11B; LF = 12B CTRLK = 13B; CTRLL = 14B; CR = 15B; CTRLN = 16B; CTRLO = 17B CTRLP = 20B; CTRLQ = 21B; CTRLR = 22B; CTRLS = 23B; CTRLT = 24B CTRLU = 25B; CTRLV = 26B; CTRLW = 27B; CTRLX = 30B; CTRLY = 31B CTRLZ = 32B; ESC = 33B ] //---------------------------------------------------------------------------- let SwatCommand() be //---------------------------------------------------------------------------- [ let lineMem = 0 Cloop: SetFailPt(Cloop) // errors go here if lineMem then [ Free(sysZone, lineMem); lineMem = 0 ] openMode = PrintO [SwapLoop // We'll be in this loop for months! (until he does another InstallSwat) let swapSignal = 0 while swapSignal eq 0 do [CommandLoop VMCache(vmFlush) // in case user boots out of Swat let TermChar(c) = (c ls 40b & c ne ESC) % (c eq $?) lineMem = ReadLine("#", TermChar) if lineMem!(lineMem!0) ne $*N then Puts(dsp, $*n) char = Exp(lineMem); Free(sysZone, lineMem); lineMem = 0 unless char eq $*n % char eq LF % char eq CTRLB % char eq CTRLW do assignable = false manifest [ // for switchon into commands noArgs = 1000b oneArg = 2000b moreArgs = 3000b vmIsCore = 4000b oneAlt = 10000b twoAlts = 20000b ] let command = char + (ALTFLG2? twoAlts, ALTFLG? oneAlt, 0) + (NARGS eq 0? noArgs, NARGS eq 1? oneArg, moreArgs) + (vm>>VM.type eq vmTypeCore & not debugFlag? vmIsCore, 0) switchon command into [ // 'loop' is normal exit from switch, 'endcase' for errors. case CTRLA+noArgs+vmIsCore: // ↑A [ OpenCell(VMFetch(openCell)) PrintOpenCell(0, 1) loop ] case CTRLB+noArgs: // ↑B [ if not assignable then ReportFail("Open cell not assignable") SetBreak(openCell) loop ] case CTRLB+noArgs+twoAlts: // $$↑B [ assignable = false PrintAllBreaks() loop ] case CTRLB+oneArg: // addr↑B [ assignable = false SetBreak(ARGS!1) loop ] case CTRLB+oneArg+oneAlt: // index$↑B [ assignable = false DelBreak(ARGS!1, true) loop ] case CTRLB+oneArg+twoAlts: // 0$$↑B [ assignable = false if ARGS!1 eq 0 then [ DelAllBreaks(); loop ] endcase ] case CTRLB+moreArgs: [ unless NARGS eq 2 endcase test ARGS!1 eq 0 ifso // 0$addr↑B [ assignable = false DelBreak(ARGS!2, false) ] ifnot SetBreak(ARGS!2, false, ARGS!1) // proceedCnt$addr↑B loop ] case CTRLC+oneArg: // proc↑C case CTRLC+moreArgs: // proc$n$...n$↑C [ swapSignal = Call(NARGS, ARGS+1) loop ] case CTRLD+oneArg+oneAlt+vmIsCore: // cnt$↑D case CTRLD+oneArg+vmIsCore: // addr↑D case CTRLD+noArgs+vmIsCore: // ↑D [ PrintOpenCell(PrintD) loop ] case CTRLE+noArgs+vmIsCore: // ↑E [ OpenCell(EffAddr(VMFetch(openCell), openCell)) PrintOpenCell(0, 1) loop ] case CTRLE+oneArg+vmIsCore: // addr↑E [ Search(ARGS!1, false) loop ] case CTRLF+oneArg+vmIsCore: // index↑F [ Frame(ARGS!1) loop ] case CTRLG+oneArg: // addr↑G [ swapSignal = Go(ARGS!1) loop ] case CTRLI+oneArg+oneAlt+vmIsCore: // cnt$↑I case CTRLI+oneArg+vmIsCore: // addr↑I case CTRLI+noArgs+vmIsCore: // ↑I [ PrintOpenCell(PrintI) loop ] case LF+oneArg+vmIsCore: // val↑J [ test assignable ifso VMStore(openCell, ARGS!1) ifnot ReportFail("No assignable cell") ] case LF+noArgs+vmIsCore: // ↑J [ OpenCell(openCell+1) PrintOpenCell(0, 1) loop ] case LF+noArgs+oneAlt+vmIsCore: // $↑J [ let t = openCell openCell = lastOpenCell+1 lastOpenCell = t PrintOpenCell(0, 1) loop ] case LF+moreArgs+vmIsCore: // byte$byte↑J [ if NARGS eq 2 then [ ARGS!1 = ARGS!1 lshift 8 + ARGS!2; docase LF+oneArg ] loop ] case CTRLK+noArgs: // ↑K [ let topStatics = VMFetch(176777b) StopSpy() DelAllBreaks() VMStore(userAC0, 1) // finish code = fcAbort swapSignal = Go(VMFetch(topStatics+21B)) // aka OsFinish loop ] case CTRLL+noArgs: // ↑L [ SysOut() loop ] case CR+oneArg+vmIsCore: // val↑M [ test assignable ifso VMStore(openCell, ARGS!1) ifnot ReportFail("No assignable cell") ] case CR+noArgs+vmIsCore: // ↑M [ assignable = false loop ] case CR+noArgs+oneAlt+vmIsCore: // $↑M [ let t = openCell openCell = lastOpenCell lastOpenCell = t PrintOpenCell(0, 1) loop ] case CR+moreArgs+vmIsCore: // byte$byte↑M [ if NARGS eq 2 then [ ARGS!1 = ARGS!1 lshift 8 + ARGS!2; docase CR+oneArg ] loop ] case CTRLN+oneArg+oneAlt+vmIsCore: // cnt$↑N case CTRLN+oneArg+vmIsCore: // addr↑N case CTRLN+noArgs+vmIsCore: // ↑N [ PrintOpenCell(PrintN) loop ] case CTRLO+oneArg+oneAlt+vmIsCore: // cnt$↑O case CTRLO+oneArg+vmIsCore: // addr↑O case CTRLO+noArgs+vmIsCore: // ↑O [ PrintOpenCell(PrintO) loop ] case CTRLP+oneArg+twoAlts: // addr$$↑P [ SetBreak(ARGS!1, true) swapSignal = Go(VMFetch(userPC)) loop ] case CTRLP+oneAlt+noArgs: // $↑P [ DelBreak(VMFetch(userPC), false) swapSignal = Go(VMFetch(userPC)) loop ] case CTRLP+oneAlt+oneArg: // index$↑P [ if ARGS!1 eq 0 endcase SetBreak(GetRetPC(ARGS!1)) ] case CTRLP+noArgs: // ↑P [ swapSignal = Go(VMFetch(userPC)) loop ] case CTRLQ+noArgs: // ↑Q [ SysIn() openCell = 0 lastOpenCell = 0 openMode = PrintO assignable = false loop ] case CTRLR+noArgs+vmIsCore: // ↑R case CTRLR+oneArg+vmIsCore: // rregno↑R [ PrintR() loop ] case CTRLS+oneArg+oneAlt+vmIsCore: // cnt$↑S case CTRLS+oneArg+vmIsCore: // addr↑S case CTRLS+noArgs+vmIsCore: // ↑S [ PrintOpenCell(PrintS) loop ] case CTRLT+noArgs+vmIsCore: // ↑T case CTRLT+oneArg+vmIsCore: // stackRoot↑T [ MapStack(77777B, PrintFrame, dsp, (NARGS eq 0? VMFetch(userAC2), ARGS!1)) loop ] case CTRLU+noArgs: // ↑U [ swapSignal = UserScreen() loop ] case CTRLV+noArgs+vmIsCore: // ↑V [ ARGS!1 = openCell ] case CTRLV+oneArg+vmIsCore: // val↑V [ PutTemplate(dsp, "$UOb = $D.*N", ARGS!1, ARGS!1) loop ] case CTRLW+oneArg+vmIsCore: // val↑W [ test assignable ifso VMStore(openCell, ARGS!1) ifnot ReportFail("No assignable cell") ] case CTRLW+noArgs+vmIsCore: // ↑W [ OpenCell(openCell-1) PrintOpenCell(0, 1) loop ] case CTRLW+noArgs+oneAlt+vmIsCore: // $↑W [ let t = openCell openCell = lastOpenCell-1 lastOpenCell = t PrintOpenCell(0, 1) loop ] case CTRLW+moreArgs+vmIsCore: // byte$byte↑W [ if NARGS eq 2 then [ ARGS!1 = ARGS!1 lshift 8 + ARGS!2; docase CTRLW+oneArg ] loop ] case CTRLX+noArgs: // ↑X [ MeasureSpy() loop ] case CTRLX+oneArg: // addr↑X [ StartSpy(ARGS!1) loop ] case CTRLX+noArgs+oneAlt: // $↑X [ DisplaySpy(true) loop ] case CTRLX+noArgs+twoAlts: // $$↑X [ DisplaySpy(false) loop ] case CTRLY+noArgs+vmIsCore: // ↑Y [ SymRead() loop ] case CTRLY+noArgs+oneAlt+vmIsCore: // $↑Y [ ReadFromFile() loop ] case CTRLY+noArgs+twoAlts+vmIsCore: // $$↑Y [ TeleSwatServer() loop ] case CTRLZ+noArgs+vmIsCore: // ↑Z [ VMSpace() loop ] case CTRLZ+noArgs+oneAlt+vmIsCore: // $↑Z [ PutTemplate(dsp, "$P*N$P*N", VMPrint, true, SymPrint, true) loop ] case CTRLZ+noArgs+twoAlts+vmIsCore: // $$↑Z [ ResidentSwapIn() loop ] case $*035+noArgs+vmIsCore: // ↑= case $*035+oneArg+vmIsCore: // n↑= case $*035+noArgs+oneAlt+vmIsCore: // $↑= case $*035+oneArg+oneAlt+vmIsCore: // n$↑= [ Search() loop ] case $?+noArgs+vmIsCore: // ? [ Ws("Help for command: ") char = ReadChar() Puts(dsp, char) Resets(state) PrintError(state, "Swat.help", HelpFetch) Gets(keys) DisplayState() loop ] default: test (command & vmIsCore) ne 0 ifso [ Ws("???*n"); loop ] ifnot [ command = command + vmIsCore; docase command ] ] ]CommandLoop // end of while loop ReadSwapOut() ResidentSwapOut(swapSignal) BreakSwapOut() VMSwap() // <------== This is it BreakSwapIn() SymSwapIn() StackSwapIn() ReadSwapIn(ResidentSwapIn()) ]SwapLoop repeat ] //---------------------------------------------------------------------------- and HelpFetch(nil) = char //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintOpenCell(routine, num; numargs na) be //---------------------------------------------------------------------------- [ if na ls 2 then num = 1 test routine eq 0 ifso routine = openMode ifnot if NARGS eq 1 test ALTFLG ne 0 & ALTFLG2 eq 0 ifso num = ARGS!1 ifnot OpenCell(ARGS!1) let done = 0 [ PutTemplate(dsp, "$P: ", AddrToSym, openCell+done) let todo = routine eq PrintN? 1, num-done for i = 1 to (todo gr 8? 8, todo) do [ routine(openCell+done) done = done +1 ] if done eq num break Puts(dsp, $*N) ] repeat if num ne 1 then OpenCell(openCell+num-1) openMode = routine assignable = true ] //---------------------------------------------------------------------------- and PrintN(cell) be SymbolicInst(VMFetch(cell), cell) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintO(cell) be PutTemplate(dsp, "$UO ", VMFetch(cell)) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintD(cell) be PutTemplate(dsp, "$D. ", VMFetch(cell)) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintI(cell) be //---------------------------------------------------------------------------- PutTemplate(dsp, "$O $O ", VMFetch(cell) rshift 8, VMFetch(cell) & 377B) //---------------------------------------------------------------------------- and PrintS(cell) be //---------------------------------------------------------------------------- PutTemplate(dsp, "$C $C ", VMFetch(cell) rshift 8, VMFetch(cell) & 377B) //---------------------------------------------------------------------------- and Search() be //---------------------------------------------------------------------------- // search from openCell+1 to end of memory (176777b). [ if NARGS ne 0 then lastSearch = ARGS!1 let loc = openCell +1 while loc ne 177000b do [ test ALTFLG ifnot if VMFetch(loc) eq lastSearch then [ openMode = PrintO; break ] ifso if EffAddr(VMFetch(loc), loc, true) eq lastSearch then [ openMode = PrintN; break ] loc = loc +1 ] test loc eq 177000b ifso Ws("Not found*N") ifnot [ OpenCell(loc) PrintOpenCell(0, 1) ] ] //---------------------------------------------------------------------------- and OpenCell(cell) be //---------------------------------------------------------------------------- [ if openCell+1 ne cell & openCell-1 ne cell then lastOpenCell = openCell openCell = cell ] //---------------------------------------------------------------------------- and PrintR() be //---------------------------------------------------------------------------- [ //Microcode routine should be: //1000 L← register, SWMODE; // [ BS=0(3 for S reg), RSELECT=reg, ALUF=0, LoadL, F1=10, NEXT=1001 ] //1001 AC0← L, :START; // [ BS=1, RSELECT=3, NEXT=20(start) ] structure MI: [ rselect bit 5 blank bit 4 bs bit 3 blank bit 4 ] manifest [ read = true; write = false ] //see if a ram is present by reading and writing in util area let save = vec 4; RWRam(read, save) let saveBar = vec 3; for i = 0 to 3 do saveBar!i = not save!i RWRam(write, saveBar) RWRam(read, saveBar) for i = 0 to 3 do if saveBar!i ne (not save!i) then ReportFail("You have no RAM.") let num = NARGS eq 1? 1, 100B let reg = NARGS eq 1? ARGS!1, 0 let JumpRam = table [ 61010B; 1401B ] let done = 0 [ // read and print loop PutTemplate(dsp, "*NR$2F0O: ", reg) for i = 1 to num-done gr 8? 8, num-done do [ if reg gr 77B then [ done = num; break ] let microInsts = table [ 0; 101001B; 14030B; 102020B ] microInsts>>MI.rselect = reg microInsts>>MI.bs = reg ge 40B? 3, 0 RWRam(write, microInsts) //Plop it down PutTemplate(dsp, "$U6O ", JumpRam(nil, 1000B)) done = done +1 reg = reg +1 ] ] repeatuntil done eq num RWRam(write, save) ] //---------------------------------------------------------------------------- and RWRam(read, tab) be //---------------------------------------------------------------------------- [ let ReadRam = table [ 61011B; 1401B ] let WriteRam = table [ 55001B; 35003B; 61012B; 35001B; 1401B ] for i = 0 to 1 do [ let j = i+i; let j1 = j+1 test read ifso [ tab!j = ReadRam(nil, 3000B+i) //High order tab!j1 = ReadRam(nil, 1000B+i) //Low order ] ifnot WriteRam(tab!j, 1000B+i, tab!j1) ] ]