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 ]; 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[]; }. RobotHardwareImpl.mesa Created Saturday, June 9, 1984 10:52 pm PDT Last edited by Eric Nickell, July 12, 1985 0:01:38 am PDT Interpret immediate tags in range [-128 .. 127]. Here, we need to dereference the instruction Since #tag^ useless, it is re-interpreted as a stack reference... Now, perform the operation using these references [robot[ac], robot[ind], robot[pc], addr, cont, regs] _ RobotOpCodes.ProcessOpCode[ op: instruction.opNum, lAc: robot[ac], lInd: robot[ind], lPc: robot[pc], lAddr: addr, lCont: cont ]; Identify which locations have been modified IF regs.pc THEN addressWritten[pc] _ TRUE; IF regs.ac THEN addressWritten[ac] _ TRUE; IF regs.stk THEN addressWritten[Loc2Mem[stk]] _ TRUE; IF regs.ind THEN addressWritten[ind] _ TRUE; Tickle the up and down counters Κ<˜šœ™Jšœ+™+J™9J™—šΟk ˜ Icodešœ œ˜+KšœœL˜`Jšœ˜Kšœ œ ˜Kšœœœ˜J˜—šœœ˜ Jšœ˜$Jšœ˜Jšœ˜Jšœ˜J˜Jšœœœ˜J˜Jšœœœ˜'šœœT˜]Jšœœœœ˜'J˜—Jšœœ˜%Jšœœ˜%Jšœœ˜%Jšœœ˜%Jšœœ˜)Jšœœ˜)Jšœœ˜-Jšœœ˜)šœœ˜+J˜—š Οn œœœ œ œ ˜Ušžœœ œœ˜8Kšœ-œ ˜@K˜—š žœœœœœ˜:Kšœœœœ˜+K˜—Kšœ œ˜(Kšœ#˜#Kšœ œœ ˜8K˜KšœΟc#˜6KšœŸ&˜9Kšœœ Ÿ˜8Kš œœœ œœ ˜HšœŸ˜1K™0Kšœœ œ˜?—Kšœ Ÿ"˜/K™K™,šœœœœ˜QK™AK˜!K˜K˜K˜ Kšœ˜—šœ˜šœœ˜Kšœ˜K˜Kšœ˜—šœœ˜Kšœ˜K˜ Kšœ˜—šœœ˜ Kšœ˜K˜Kšœ˜—K˜—K˜K™1šœ'˜'K˜K˜ K˜ K˜Kšœ˜—šœR™RK™K™K™K™K™ K™ K™K™—K™+Kšœ œœ™*Kšœ œœ™*Kšœ œ œ™5Kšœ œœ™,K˜K™šœœ œœ˜FK˜Kšœ˜—šœœ œœ˜HK˜Kšœ˜—K˜K˜K˜—šž œ œœ œ ˜JKšœ œ˜š œœ œœ˜DKšœŸ˜*Kš˜—Kšœœ Ÿ%˜QKšœ"Ÿ˜>Kšœ$Ÿ˜BKšœŸ˜2KšœŸ˜4K˜K˜—šžœœœ$˜Gšžœœœ˜(Jšœ˜KšœV˜VK˜—J˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—J˜šžœœ œœ˜9Kšœœœ œ˜1K˜K˜—šžœœœ˜K˜K˜—K˜J˜——…—Β