RobotHardwareImpl.mesa
Created Saturday, June 9, 1984 10:52 pm PDT
Last edited by Eric Nickell, July 12, 1985 0:01:38 am PDT
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
Interpret immediate tags in range [-128 .. 127].
IF instruction.immediate AND cont > 127 THEN cont ← cont - 256;
addr ← -1;   --And writes here do screwy things
Here, we need to dereference the instruction
IF instruction.indirect AND instruction.immediate AND ~instruction.indexed THEN {
Since #tag^ useless, it is re-interpreted as a stack reference...
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];
};
};
Now, perform the operation using these references
addressWritten ← RobotOpCodes.DoOpCode[
op: instruction.opNum,
addr: addr,
cont: cont,
m: robot
];
[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
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[];
}.