<> <> <> <<>> DIRECTORY RobotDefs USING [Instruction, MemoryIndex], RobotEvaluator USING [AssignValueToSymbol, NewValueFromInteger, RopeToSymbolIndex, SymbolTable], RobotHardware, RobotOpCodes USING [DoOpCode], Rope USING [ROPE]; RobotHardwareImpl: CEDAR PROGRAM IMPORTS RobotEvaluator, RobotOpCodes EXPORTS RobotHardware ~ { OPEN RobotHardware; ROPE: TYPE ~ Rope.ROPE; nIndex: CARDINAL ~ LAST[MemoryIndex]+1; Loc: TYPE ~ {ac, i, stk, pc, hx, mx, hy, my, hdmg, mdmg, ctx, down, up, direct, fire, speed}; offset: INTEGER ~ LOOPHOLE[FIRST[Loc]]; hx: PUBLIC MemoryIndex _ Loc2Mem[hx]; mx: PUBLIC MemoryIndex _ Loc2Mem[mx]; hy: PUBLIC MemoryIndex _ Loc2Mem[hy]; my: PUBLIC MemoryIndex _ Loc2Mem[my]; hdmg: PUBLIC MemoryIndex _ Loc2Mem[hdmg]; mdmg: PUBLIC MemoryIndex _ Loc2Mem[mdmg]; direct: PUBLIC MemoryIndex _ Loc2Mem[direct]; fire: PUBLIC MemoryIndex _ Loc2Mem[fire]; speed: PUBLIC MemoryIndex _ Loc2Mem[speed]; ProcessRobot: PUBLIC PROC [robot: REF Memory] RETURNS [addressWritten: MemoryMap] ~ { CtxLoc: PROC [loc: Loc] RETURNS [MemoryIndex] ~ INLINE { RETURN [(contextBase + Loc2Mem[loc] - Loc2Mem[ac]) MOD (nIndex)] }; Addr: PROC [val: INTEGER] RETURNS [MemoryIndex] ~ INLINE { RETURN [LOOPHOLE[val, CARDINAL] MOD nIndex] }; ac, ind, pc, addr, cont, value: INTEGER; instruction: RobotDefs.Instruction; contextBase: INTEGER _ robot[Loc2Mem[ctx]] MOD (nIndex); ac _ CtxLoc[ac]; --Ac pointed to by context register ind _ CtxLoc[i]; --Index pointed to by context register pc _ Loc2Mem[pc] MOD nIndex; --Get the next instruction instruction _ LOOPHOLE[robot[LOOPHOLE[robot[pc], CARDINAL] MOD nIndex]]; cont _ instruction.tag; --Start by assuming #tag <> IF instruction.immediate AND cont > 127 THEN cont _ cont - 256; addr _ -1; --And writes here do screwy things <<>> <> IF instruction.indirect AND instruction.immediate AND ~instruction.indexed THEN { <> stkptr: MemoryIndex _ Addr[cont]; addr _ Addr[robot[stkptr]]; cont _ robot[addr]; robot[stkptr] _ robot[stkptr]+1; } ELSE { IF instruction.indirect THEN { addr _ Addr[cont]; cont _ robot[addr]; }; IF instruction.indexed THEN { cont _ cont + robot[Addr[ind]]; addr _ -1; }; IF ~instruction.immediate THEN { addr _ Addr[cont]; cont _ robot[addr]; }; }; <> addressWritten _ RobotOpCodes.DoOpCode[ op: instruction.opNum, addr: addr, cont: cont, m: robot ]; <<[robot[ac], robot[ind], robot[pc], addr, cont, regs] _ RobotOpCodes.ProcessOpCode[>> <> <> <> <> <> <> <<];>> <<>> <> <> <> <> <> <> IF (value_robot[Loc2Mem[up]]) IN MemoryIndex AND robot[value]#0 THEN { robot[value] _ robot[value]+1; }; IF (value_robot[Loc2Mem[down]]) IN MemoryIndex AND robot[value]#0 THEN { robot[value] _ robot[value]-1; }; }; InitialMemory: PUBLIC PROC [code: Memory] RETURNS [memory: REF Memory] ~ { memory _ NEW[Memory _ code]; FOR i: MemoryIndex IN [Loc2Mem[FIRST[Loc]] .. Loc2Mem[LAST[Loc]]] DO memory[i] _ 0; --Zero register locations ENDLOOP; memory[Loc2Mem[pc]] _ Loc2Mem[LAST[Loc]]+1; --Start execution after last register memory[Loc2Mem[stk]] _ nIndex-1; --Put stack at end of memory memory[Loc2Mem[ctx]] _ Loc2Mem[ac]; --Start with accumulator at ac memory[Loc2Mem[up]] _ -1; --No counters initially memory[Loc2Mem[down]] _ -1; --No counters initially }; InstallStandardSymbols: PUBLIC PROC [s: RobotEvaluator.SymbolTable] ~ { Install: PROC [loc: Loc, name: ROPE] ~ { OPEN RobotEvaluator; AssignValueToSymbol[NewValueFromInteger[Loc2Mem[loc]], RopeToSymbolIndex[name, s], s]; }; Install[ac, "AC"]; Install[i, "I"]; Install[stk, "STK"]; Install[pc, "PC"]; Install[hx, "HX"]; Install[mx, "MX"]; Install[hy, "HY"]; Install[my, "MY"]; Install[hdmg, "HDMG"]; Install[mdmg, "MDMG"]; Install[ctx, "CONTEXT"]; Install[down, "DOWN"]; Install[up, "UP"]; Install[direct, "DIRECT"]; Install[fire, "FIRE"]; Install[speed, "SPEED"]; }; Loc2Mem: PROC [loc: Loc] RETURNS [MemoryIndex] ~ INLINE { RETURN [LOOPHOLE[loc, INTEGER]-offset MOD nIndex] }; Init: PROC ~ TRUSTED { }; Init[]; }.