// SwatInsAnal.bcpl - Routines for analyzing Alto instructions // Copyright Xerox Corporation 1979, 1981, 1982 // Last modified March 21, 1982 2:10 PM by Boggs // All you have to do is...07/25/73 (alb) get "Swat.decl" external [ // outgoing procedures SymbolicInst; EffAddr; BuildSI // incoming procedures VMFetch; ReportFail; AddrToSym Ws; PutTemplate; Puts; Zero // incoming statics dsp; xmFlag ] structure OP: // instruction fields [ [ alu bit 1 acSrc bit 2 acDest bit 2 aluFn bit 3 shift bit 2 carry bit 2 noLoad bit 1 skip bit 3 ] = [ f1 bit 3 f2 bit 2 = ac bit 2 indir bit 1 index bit 2 disp bit 8 ] ] structure SI: // Simulated Instruction [ instr word // simulating instruction doItRtn word // 0: default, 1: jmp, 2: bri simRtn word // simulation routine dispatch (small integer) disp word // sign extended displacement eaReg word // 0, or -> trapAdd, trapAC2, or AC3 indir word // number of times to indirect (0-2) ] compileif size SI/16 ne 6 then [ Error("Change lenSI declaration in Swat.decl") ] manifest [ // SI.sim values -- *** known to SwatResident.asm *** simMRIALU = 0 // Memory Reference and Arithmetic Logical instrs simJmp = 1 simJsr = 2 simDirs = 3 simBRI = 4 // SI.doIt values -- *** known to SwatResident.asm *** doItDefault = 0 doItJmp = 1 doItBRI = 2 ] //---------------------------------------------------------------------------- let EffAddr(instr, addr, returnIfNoEA; numargs na) = valof //---------------------------------------------------------------------------- [ let disp = Displacement(instr) test (instr & 177400B) eq 64400B //JSRII ifso resultis VMFetch(VMFetch(disp+addr)) ifnot test (instr & 177400B) eq 65000B //JSRIS ifso resultis VMFetch(VMFetch(disp+VMFetch(userAC2))) ifnot [ if instr<<OP.f1 gr 2 test na ge 3 & returnIfNoEA ifso resultis -1 ifnot ReportFail("Instruction has no effective address") let ea = disp + selecton instr<<OP.index into [ case 0: 0 case 1: addr case 2: VMFetch(userAC2) case 3: VMFetch(userAC3) ] if instr<<OP.indir eq 1 then ea = VMFetch(ea) resultis ea ] ] //---------------------------------------------------------------------------- and BuildSI(si, instr) be //---------------------------------------------------------------------------- // Builds an SI structure at si to simulate the execution of instr [ Zero(si, lenSI) si>>SI.instr = 401b //jmp .+1 si>>SI.doItRtn = doItDefault si>>SI.disp = Displacement(instr) si>>SI.eaReg = selecton instr<<OP.index into [ case 0: 0 case 1: userPC case 2: userAC2 case 3: userAC3 ] switchon instr<<OP.f1 into [ case 0: // jmp, jsr, isz, dsz [ switchon instr<<OP.f2 into [ case 0: // jmp [ si>>SI.simRtn = simJmp endcase ] case 1: // jsr [ si>>SI.simRtn = simJsr endcase ] case 2: // isz case 3: // dsz [ si>>SI.simRtn = simMRIALU si>>SI.instr = (instr & 74000b) + 2405b //op @.+5 endcase ] ] si>>SI.indir = instr<<OP.indir endcase ] case 1: // lda case 2: // sta [ si>>SI.simRtn = simMRIALU si>>SI.instr = (instr & 74000b) + 2405b //op @.+5 si>>SI.indir = instr<<OP.indir endcase ] case 4 to 7: // alu [ si>>SI.simRtn = simMRIALU si>>SI.instr = instr endcase ] // BuildSI (cont'd) case 3: // special Alto instructions [ let i = instr & 77400b test i eq 64400b % i eq 65000b // jsrii, jsris ifso [ si>>SI.simRtn = simJsr si>>SI.indir = 2 ] ifnot switchon instr into [ case 61000b: // dir [ si>>SI.doItRtn = doItJmp endcase ] case 61001b: // eir [ si>>SI.doItRtn = doItBRI endcase ] case 61002b: // bri [ si>>SI.simRtn = simBRI si>>SI.doItRtn = doItBRI endcase ] case 61013b: // dirs [ si>>SI.simRtn = simDirs si>>SI.doItRtn = doItJmp endcase ] default: // simMRIALU works for the rest of them [ si>>SI.simRtn = simMRIALU // don't re-execute traps unless i eq 77400b do si>>SI.instr = instr if xmFlag & ((instr & xJmpInstMask) eq xJmp0) then ReportFail("I Can't simulate xJmp instructions") endcase ] ] endcase ] ] ] //---------------------------------------------------------------------------- and SymbolicInst(instr, addr) be //---------------------------------------------------------------------------- // Print instr as an Alto instruction assuming it resides at addr. [ PutTemplate(dsp, "$6UO ", instr) test instr<<OP.alu eq 1 ifso [ Ws(selecton instr<<OP.aluFn into [ case 0:"com" case 1:"neg" case 2:"mov" case 3:"inc" case 4:"adc" case 5:"sub" case 6:"add" case 7:"and" ]) Ws(selecton instr<<OP.carry into [ case 0:"" case 1:"z" case 2:"o" case 3:"c" ]) Ws(selecton instr<<OP.shift into [ case 0:"" case 1:"l" case 2:"r" case 3:"s" ]) if instr<<OP.noLoad ne 0 then Puts(dsp, $#) PutTemplate(dsp, " $O $O ", instr<<OP.acSrc, instr<<OP.acDest) Ws(selecton instr<<OP.skip into [ case 0:"" case 1:"skp" case 2:"szc" case 3:"snc" case 4:"szr" case 5:"snr" case 6:"sez" case 7:"sbn" ]) // SymbolicInst (Cont'd) test instr<<OP.skip eq 0 ifso if instr<<OP.acSrc eq instr<<OP.acDest then PutTemplate(dsp, selecton instr & 103777b into //ignore ACs [ case 102520b: "; AC$O ← 1" case 102000b: "; AC$O ← -1" case 102400b: "; AC$O ← 0" default: "" ], instr<<OP.acSrc) ifnot PutTemplate(dsp, selecton instr & 103767b into //ignore ACs,nl [ case 102023b: "$S$O uls AC$O" case 102423b: "$S$O ule AC$O" case 102422b: "$S$O ugr AC$O" case 102022b: "$S$O uge AC$O" case 102102b: case 102122b: "$S$O ls AC$O" case 102502b: case 102522b: "$S$O le AC$O" case 102503b: case 102523b: "$S$O gr AC$O" case 102103b: case 102123b: "$S$O ge AC$O" case 102405b: "$S$O ne AC$O" case 102404b: "$S$O eq AC$O" case 101103b: "$S$O ls 0" case 100502b: "$S$O le 0" case 100503b: "$S$O gr 0" case 101102b: "$S$O ge 0" case 101005b: "$S$O ne 0" case 101004b: "$S$O eq 0" case 100005b: "$S$O ne -1" case 100004b: "$S$O eq -1" case 101202b: "$S$O even" case 101203b: "$S$O odd" default: "" ], "; Skip if AC", instr<<OP.acSrc, instr<<OP.acDest) ] // SymbolicInst (Cont'd) ifnot switchon instr<<OP.f1 into [ case 0: [ Ws(selecton instr<<OP.f2 into [ case 0:"jmp " case 1:"jsr " case 2:"isz " case 3:"dsz " ]) PrintAddress(instr, addr) endcase ] case 1: [ PutTemplate(dsp, "lda $O ", instr<<OP.ac) PrintAddress(instr, addr) endcase ] case 2: [ PutTemplate(dsp, "sta $O ", instr<<OP.ac) PrintAddress(instr, addr) endcase ] case 3: [ Ws(selecton instr into [ case 61000b: "dir" case 61001b: "eir" case 61002b: "bri" case 61003b: "rclk" case 61004b: "sio" case 61005b: "blt" case 61006b: "blks" case 61007b: "sit" case 61010b: "jmpram" case 61011b: "rdram" case 61012b: "wrtram" case 61013b: "dirs" case 61014b: "vers" case 61015b: "dread" case 61016b: "dwrite" case 61017b: "dexch" case 61020b: "mul" case 61021b: "div" case 61022b: "diagnose1" case 61023b: "diagnose2" case 61024b: "bitblt" case 61025b: "xmlda" case 61026b: "xmsta" case 61037b: "setdefaultdisk" case 61040b: "doradoin" case 61041b: "doradoout" case 61042b: "doradohalt" case 61043b: "setpchist" case 64034b: "xjmp0" case 64035b: "xjmp1" case 64036b: "xjmp2" case 64037b: "xjmp3" default: "" ]) switchon instr & 77400b into [ case 60000b: [ PutTemplate(dsp, "cycle $O", instr&17B); endcase ] case 64400b: [ Ws("jsrii"); PrintAddress(instr, addr); endcase ] case 65000b: [ Ws("jsris"); PrintAddress(instr, addr); endcase ] case 67000b: [ PutTemplate(dsp, "convert $P", SignedDisp, instr) ] ] endcase ] ] ] //---------------------------------------------------------------------------- and PrintAddress(instr, addr) be //---------------------------------------------------------------------------- // Prints jump and memory reference addresses [ if instr<<OP.indir eq 1 then Puts(dsp, $@) switchon instr<<OP.index into [ case 0: // page zero [ PutTemplate(dsp, "$O", instr<<OP.disp) endcase ] case 1: // pc relative [ PutTemplate(dsp, ".$P", SignedDisp, instr) endcase ] case 2: // ac2 relative case 3: // ac3 relative [ PutTemplate(dsp, "$O,$O", Displacement(instr), instr<<OP.index) endcase ] ] let effAdd = EffAddr(instr, addr) PutTemplate(dsp, " -> $P: $UO", AddrToSym, effAdd, VMFetch(effAdd)) ] //---------------------------------------------------------------------------- and Displacement(instr) = (instr<<OP.index eq 0? instr<<OP.disp, (instr<<OP.disp + (instr<<OP.disp ge 200b? 177400b, 0))) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and SignedDisp(stream, instr) be //---------------------------------------------------------------------------- [ let disp = Displacement(instr) PutTemplate(stream, "$S$O", (disp ge 0? "+", ""), disp) ]