The instruction set of the MIX computer is described below. The instructions are grouped by function. In describing the instructions, the following notation is used:
A | the A register |
X | the X register |
AX | the 10-byte double-length register composed of the A and X register, with the A register being the upper 5 bytes and the X register being the lower 5 bytes. |
I1,I2,I3,I4,I5,I6 | the 6 index registers |
J | the J register |
MEMORY[q] | the memory word whose address is q (0 ≤ q < 4000) |
REG[*] | the *th register, where REG[0] is A, REG[1] is I1, REG[2] is I2, REG[3] is I3, …, REG[6] is I6, and REG[7] is X |
q → r | the contents of register or memory word q, or the value of the expression q, is copied to the register or memory word r. |
q(L:R) | the L:R bytes of memory word or register q |
m | the effective address of the instruction being executed |
P | the program counter |
I | the instruction register; holds the instruction while it is being executed |
The instruction execution cycle for the MIX computer is:
The effect of execute(I) depends upon bytes 5 and 4 of the instruction register I as follows. (All numbers are octal.)
For each instruction, the assembler mnemonic, octal numeric opcode and field specifications are given, along with a short description of the instruction. When the same instruction applies to the eight registers, A, X, I1, I2, I3, I4, I5, and I6 in the same way, the symbol "*" is used to stand for the register to be used. For mnemonics, the * should be replaced by A, 1, 2, 3, 4, 5, 6, X; for opcodes by 0, 1, 2, 3, 4, 5, 6, 7, as appropriate.
LD* | 10+* | L:R | MEMORY[m](L:R) → REG[*] |
LD*N | 20+* | L:R | -MEMORY[m](L:R) → REG[*] |
ST* | 30+* | L:R | if L=0, then REG[*](0:0) → MEMORY[m](0:0) and REG[*](6-R:5) → MEMORY[m](1:R); if L > 0, then REG[*](5-R+L:5) → MEMORY[m](L:R) |
STJ | 40 | L:R | if L=0, then "+" → MEMORY[m](0:0) and J(6-R:5) → MEMORY[m](1:R); if L > 0, then J(5-R+L:5) → MEMORY[m](L:R) |
STZ | 41 | L:R | +0 → MEMORY[m](L:R) |
ADD | 01 | L:R | A + MEMORY[m](L:R) → A; if the magnitude of this sum is too large, "ON" → Overflow toggle |
SUB | 02 | L:R | A - MEMORY[m](L:R) → A; if the magnitude of this difference is too large, "ON" → Overflow toggle |
MUL | 03 | L:R | A × MEMORY[m](L:R) → AX |
DIV | 04 | L:R | the quotient of AX / MEMORY[m](L:R) → A; the remainder → X; if the magnitude of the quotient is too large, or MEMORY[m](L:R) = 0, then "ON" → Overflow toggle |
INC* | 60+* | 00 | REG[*] + m → REG[*] |
DEC* | 60+* | 01 | REG[*] - m → REG[*] |
ENT* | 60+* | 02 | m → REG[*] |
ENN* | 60+* | 03 | -m → REG[*] |
CMP* | 70+* | L:R | if REG[*](L:R) < MEMORY[m](L:R), then "LESS" → Comparison indicator; if REG[*](L:R) = MEMORY[m](L:R), then "EQUAL" → Comparison indicator; if REG[*](L:R) > MEMORY[m](L:R), then "GREATER" → Comparison indicator |
JMP | 47 | 00 | P → J and m → P |
JSJ | 47 | 01 | m → P |
JOV | 47 | 02 | if Overflow toggle = "ON", then "OFF" Overflow toggle and P → J and m → P |
JNOV | 47 | 03 | if Overflow toggle = "OFF", then P → J and m → P; |
JL | 47 | 04 | if Comparison indicator = "LESS", then P → J and m → P |
JE | 47 | 05 | if Comparison indicator = "EQUAL", then P → J and m → P |
JG | 47 | 06 | if Comparison indicator = "GREATER", then P → J and m → P |
JGE | 47 | 07 | if Comparison indicator = "GREATER" or Comparison indicator = "EQUAL", then P → J and m → P |
JNE | 47 | 10 | if Comparison indicator = "GREATER" or Comparison indicator = "LESS", then P → J and m → P |
JLE | 47 | 11 | if Comparison indicator = "LESS" or Comparison indicator = "EQUAL", then P → J and m → P |
J*N | 50+* | 00 | if REG[*] < 0, then P → J and m → P |
J*Z | 50+* | 01 | if REG[*] = 0, then P → J and m → P |
J*P | 50+* | 02 | if REG[*] > 0, then P → J and m → P |
J*NN | 50+* | 03 | if REG[*] ≥ 0, then P → J and m → P |
J*NZ | 50+* | 04 | if REG[*] ≠ 0, then P → J and m → P |
J*NP | 50+* | 05 | if REG[*] ≤ 0, then P → J and m → P |
JBUS | 42 | N | if unit N is busy, then P → J and m → P |
JRED | 46 | N | if unit N is not busy, then P → J and m → P |
IN | 44 | N | if unit N is busy, then wait until it is not busy; then issue an input command to unit N with memory address m. |
OUT | 45 | N | if unit N is busy, then wait until it is not busy; then issue an output command to unit N with memory address m. |
IOC | 43 | N | if unit N is busy, then wait until it is not busy; then issue a control command to Unit N with parameter m. |
SLA | 06 | 00 | shift A left m bytes, end-off, zero fill |
SRA | 06 | 01 | shift A right m bytes, end-off, zero fill |
SLAX | 06 | 02 | shift AX left m bytes, end-off, zero fill |
SRAX | 06 | 03 | shift AX right m bytes, end-off, zero fill |
SLC | 06 | 04 | shift AX left m bytes, circular |
SRC | 06 | 05 | shift AX right m bytes, circular |
NUM | 05 | 00 | convert from decimal character code in AX to binary numeric in A |
CHAR | 05 | 01 | convert from binary numeric in A to decimal character code in AX |
HLT | 05 | 02 | halt the computer |
NOP | 00 | 00 | do nothing, simply continue with the next instruction |
MOVE | 07 | N | copy the N words at m, m+1, m+2, …, m+N-1 to I1, I1+1, I1+2, …, I1+N-1, one at a time, leaving I1 + N → I1 |
FADD | 01 | 06 | A + MEMORY[m] → A |
FSUB | 02 | 06 | A - MEMORY[m] → A |
FMUL | 03 | 06 | A × MEMORY[m] → A |
FDIV | 04 | 06 | A / MEMORY[m] → A |
FCMP | 70 | 06 | if A < MEMORY[m] then "LESS" → Comparison indicator; if A = MEMORY[m], then "EQUAL" → Comparison indicator; if A > MEMORY[m], then "GREATER" → Comparison indicator |
FLOT | 05 | 06 | convert the integer number in A to a floating point number of the same value, and leave the floating point representation in A |
AND | 05 | 03 | A and MEMORY[m] → A |
ORR | 05 | 04 | A or MEMORY[m] → A |
XOR | 05 | 05 | A xor MEMORY[m] → A |
SLB | 06 | 06 | shift AX left m bits |
SRB | 06 | 07 | shift AX right m bits |
JAE | 50 | 06 | if A is even, then P → J and m → P |
JAO | 50 | 07 | if A is odd, then P → J and m → P |
JXE | 57 | 06 | if X is even, then P → J and m → P |
JXO | 57 | 07 | if X is odd, then P → J and m → P |