// 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)
]
]