DIRECTORY RobotDefs USING [MemoryMap, MemoryMapRep], RobotHardware USING [direct, fire, speed], RobotOpCodes, Rope USING [Equal, Fetch, Length, ROPE]; RobotOpCodesImpl: CEDAR PROGRAM IMPORTS RobotHardware, Rope EXPORTS RobotOpCodes ~ { OPEN RobotOpCodes; MemoryMap: TYPE ~ RobotDefs.MemoryMap; OpCodeEntry: TYPE ~ RECORD [ text: Rope.ROPE, --The actual name hash: INT, --A quick comparison proc: OpProc --The execution proc ]; OpProc: TYPE ~ PRIVATE PROC [addr, cont: INTEGER, m: REF Memory, mw: MemoryMap]; MaxOpCodes: INT ~ 32; opCodeTable: ARRAY [0..MaxOpCodes) OF OpCodeEntry; opCodesInTable: INTEGER _ 0; IsOpCode: PUBLIC PROC [r: Rope.ROPE] RETURNS [BOOLEAN] ~ { RETURN [OpCode[r]^>=0]; --OpCode returns -1 if not an opcode }; OpCode: PUBLIC PROC [r: Rope.ROPE] RETURNS [REF INTEGER] ~ { hash: INT _ HashRope[r]; IF opCodesInTable=0 THEN RETURN [NEW[INTEGER _ -1]]; --Implies not there FOR i:INT IN [0..opCodesInTable) DO IF hash=opCodeTable[i].hash AND Rope.Equal[r,opCodeTable[i].text] THEN RETURN[NEW[INTEGER _ i]]; ENDLOOP; RETURN [NEW[INTEGER _ -1]]; --Implies not there }; DoOpCode: PUBLIC PROC [op: INT, addr, cont: INTEGER, m: REF Memory] RETURNS [mw: MemoryMap] ~ { mw _ NEW[RobotDefs.MemoryMapRep _ ALL[FALSE]]; IF opCodeTable[op].proc=NIL THEN RETURN; opCodeTable[op].proc[addr, cont, m, mw]; IF ~mw[pc] THEN m[pc] _ m[pc]+1; --If nobody else modified it }; HashRope: PRIVATE PROC [r: Rope.ROPE] RETURNS [INT] ~ { len: INTEGER _ Rope.Length[r]; RETURN [len + CharToInt[Rope.Fetch[r,0]] + CharToInt[Rope.Fetch[r,len-1]]]; }; CharToInt: PRIVATE PROC [c: CHAR] RETURNS [i: INT] ~ { RETURN [ORD[c]]; }; Install: PRIVATE PROC [r: Rope.ROPE, proc: OpProc] ~ { opCode: OpCodeEntry _ [ text: r, hash: HashRope[r], proc: proc ]; IF opCodesInTable >= MaxOpCodes THEN ERROR; opCodeTable[opCodesInTable] _ opCode; opCodesInTable _ opCodesInTable + 1; }; ShiftLeft: PRIVATE PROC [shiftee, shifter: INTEGER] RETURNS [shifted: INTEGER] ~ { shifted _ shiftee; SELECT TRUE FROM shifter >=16 => RETURN [0]; shifter IN [0..16) => { THROUGH [1..shifter] DO shifted _ shifted*2 ENDLOOP; RETURN[shifted]; }; shifter=0 => RETURN[shiftee]; shifter IN (-16..0) => { THROUGH [shifter..-1] DO shifted _ shifted/2 ENDLOOP; RETURN[shifted]; }; shifter <=-16 => RETURN[0]; ENDCASE => ERROR; }; Set: PROC [mem: REF Memory, memWrit: MemoryMap, loc: MemoryIndex, val: INTEGER] ~ { mem[loc] _ val; memWrit[loc] _ TRUE; }; ac: INTEGER ~ 0; i: INTEGER ~ 1; stk: INTEGER ~ 2; pc: INTEGER ~ 3; fire: INTEGER ~ RobotHardware.fire; direct: INTEGER ~ RobotHardware.direct; speed: INTEGER ~ RobotHardware.speed; LDAProc: OpProc ~ {Set[m,mw,ac,cont]}; STAProc: OpProc ~ {Set[m,mw,addr,m[ac]]}; BAZProc: OpProc ~ {IF m[ac]=0 THEN Set[m,mw,pc,cont]}; BALProc: OpProc ~ {IF m[ac]<0 THEN Set[m,mw,pc,cont]}; BAGProc: OpProc ~ {IF m[ac]>0 THEN Set[m,mw,pc,cont]}; BANProc: OpProc ~ {IF m[ac]#0 THEN Set[m,mw,pc,cont]}; LDIProc: OpProc ~ {Set[m,mw,i,cont]}; STIProc: OpProc ~ {Set[m,mw,addr,m[i]]}; BIZProc: OpProc ~ {IF m[i]=0 THEN Set[m,mw,pc,cont]}; BILProc: OpProc ~ {IF m[i]<0 THEN Set[m,mw,pc,cont]}; BIGProc: OpProc ~ {IF m[i]>0 THEN Set[m,mw,pc,cont]}; BINProc: OpProc ~ {IF m[i]#0 THEN Set[m,mw,pc,cont]}; JMPProc: OpProc ~ {Set[m,mw,pc,cont]}; LUPProc: OpProc ~ {Set[m,mw,i,m[i]-1]; IF m[i]>=0 THEN Set[m,mw,pc,cont]}; ADDProc: OpProc ~ {Set[m,mw,ac,m[ac]+cont]}; SUBProc: OpProc ~ {Set[m,mw,ac,m[ac]-cont]}; MULProc: OpProc ~ {Set[m,mw,ac,m[ac]*cont]}; SHFProc: OpProc ~ {Set[m,mw,ac,ShiftLeft[m[ac],cont]]}; FRMProc: OpProc ~ {Set[m,mw,ac,cont-m[ac]]}; FIRProc: OpProc ~ {Set[m,mw,fire,cont]}; TRNProc: OpProc ~ {Set[m,mw,direct,cont]}; SPDProc: OpProc ~ {Set[m,mw,speed,cont]}; Install ["LDA", LDAProc]; Install ["STA", STAProc]; Install ["BAZ", BAZProc]; Install ["BAL", BALProc]; Install ["BAG", BAGProc]; Install ["BAN", BANProc]; Install ["LDI", LDIProc]; Install ["STI", STIProc]; Install ["BIZ", BIZProc]; Install ["BIL", BILProc]; Install ["BIG", BIGProc]; Install ["BIN", BINProc]; Install ["JMP", JMPProc]; Install ["LUP", LUPProc]; Install ["ADD", ADDProc]; Install ["SUB", SUBProc]; Install ["MUL", MULProc]; Install ["SHF", SHFProc]; Install ["FRM", FRMProc]; Install ["FIR", FIRProc]; Install ["TRN", TRNProc]; Install ["SPD", SPDProc]; }. ดRobotOpCodesImpl.mesa Created Monday, May 21, 1984 10:38 pm PDT Last edited by Eric Nickell, July 6, 1985 11:21:02 am PDT Last Edited by: Rumph, November 7, 1984 3:37:19 pm PST Given a rope, return the opcode #, or -1 if the opcode doesn't exist Check for for illegal op => a noop OK, call the proc for this opcode to get the work done... RUN THIS SECTION ON START-UP Define the opcode procedures Install the opcode procedures ส˜šœ™Jšœ)™)J™9—J™6J™šฯk ˜ Icodešœ œ˜*Jšœœ˜*J˜ Jšœœœ˜(J˜—šœœ˜Jšœ˜Jšœ ˜Jšœ˜Jšœ˜J˜Jšœ œ˜&J˜šœ œœ˜Jšœ œฯc˜%Jšœœž˜"Jšœž˜%J˜J˜—Jš œœœœœœ˜PJšœ œ˜Jšœ œœ ˜2šœœ˜J˜—š ฯnœœœ œœœ˜:Jšœ8˜>Jšœ˜J˜—J™DšŸœœœ œœœœ˜K˜K˜—š Ÿœœœ œœœ˜7Jšœœ˜JšœE˜KJ˜J˜—š Ÿ œœœœœœ˜6Jšœœ˜J˜J˜—šŸœœœ œ˜6˜J˜J˜Jšœ ˜ J˜—Jšœœœ˜+Jšœ%˜%Jšœ$˜$J˜J˜—š Ÿ œœœœœ œ˜RJ˜šœœ˜Jšœœ˜šœœ ˜Jšœœœ˜4Jšœ ˜J˜—Jšœ œ ˜šœœ˜Jšœœœ˜5Jšœ ˜J˜—Jšœœ˜Jšœœ˜—J˜—šŸœœœ4œ˜SK˜Kšœœ˜K˜˜J˜———J™Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜#Kšœœ˜'Kšœœ˜%title™Kšœ&˜&Kšœ)˜)Kšœœœ˜6Kšœœœ˜6Kšœœœ˜6Kšœœœ˜6Kšœ%˜%Kšœ(˜(Kšœœœ˜5Kšœœœ˜5Kšœœœ˜5Kšœœœ˜5Kšœ&˜&Kšœ'œœ˜JKšœ,˜,Kšœ,˜,Kšœ,˜,Kšœ7˜7Kšœ,˜,Kšœ(˜(Kšœ*˜*Kšœ)˜)—K˜™Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—J˜—…—ฎu