BESM-6 Instruction Set

CPU resources visible to the user

(Traditionally, the bits in registers are numbered right to left, starting with 1.)

Instruction formats:

All instructions are 24 bit wide and are packed into words in pairs. The branches can be made to word boundaries only.

There are two formats:

Format 1
2421
20 19
1813
121
M 0 S OPCode1 offset
EA = ([M] + offset + S * 070000 + C) mod 0100000

Format 2
2421
20
1916
151
M 1 OPCode2 offset
EA = ([M] + offset + C) mod 0100000

Opcode descriptions

Traditionally, the opcodes in opcode lists are written in octal including bits 20 to 13 or 20 to 16 and assuming S = 0, therefore the opcode ranges are 000 to 077 for format 1 and 20 to 37 for format 2.

The following mnemonics are used in descriptions:

The opcode descriptions are too brief to be exact. The behavior of most arithmetic instructions depends on normalisation and rounding mode, and one of branch instructions depends on the value of ω. For instructions setting additive or multiplicative ω, A and X are considered floating point (unless said otherwise), for logical instructions - unsigned integers.

More precise descriptions will follow.

The way register Y is used, although seems bizarre at first, is to simplify the implementation of double precision arithmetic (the second word of a double precision value holds LSBs of mantissa and MSBs of exponent).

OpcodeMnemonicDescriptionFormulaω
000ATXStoreX = A;Kept
001STXPopX = A; A = mem[--M[017]]; Logical
002MODModify privileged registers (kernel)Log/Kept
003XTSPushmem[M[017]++] = A; A = X;Logical
004A+XAdd[A,Z] = A + X;Additive
005A-XSubtract[A,Z] = A - X;Additive
006X-AReverse subtract[A,Z] = X - A;Additive
007AMXSubtract absolute values[A,Z] = abs(A) - abs(X);Additive
010XTALoadA = X;Logical
011AAXBitwise ANDA = A & X; Y = 0;Logical
012AEXBitwise Exclusive ORY = A; A = Y ^ X;Logical
013ARXCyclical add(unsigned) A += (unsigned)X; if (carry) (unsigned)A++; Y = 0;Multipl.
014AVXNegateif (X < 0) A = -A; Y = 0;Additive
015AOXBitwise ORA = A | X; Y = 0;Logical
016A/XDivideA = A / X; Y undefined;Multipl.
017A*XMultiply[A,Z] = A * X;Multipl.
020APXPack bits in A masked by X. Did the inventors of INTERCAL know about this instruction?Logical
021AUXUnpack bits in A using mask XLogical
022ACXPopulation countA = popcount(A) + X; Y = 0;Logical
023ANXFind highest set bitA = high_1_and_rest(A) + XLogical
024E+XAdd exponentE += X[48:42] - 64; Y = 0;Multipl.
025E-XSubtract exponentE -= X[48:42] - 64; Y = 0;Multipl.
026ASXShiftY = 0; if (X[48:42] >= 64) [A,Y] >>= X[48:42]-64; else [Y,A] <<= 64-X[48:42];Logical
027XTRSet mode registerR = X[47:42];As set
030RTEGet mode registerE = R;Used
031YTAGet young bits registerA = yta (Y, ω);Used
032EXTAccess external I/O registers (kernel)Kept
033---
034E+NAdd exponent immediateE += N - 64; Y = 0;Multipl.
035E-NSubtract exponent immediateE -= N - 64; Y = 0;Multipl.
036ASNShift immediateY = 0; if (N >= 64) [A,Y] >>= N-64; else [Y,A] <<= 64-N;Logical
037NTRSet mode register immediateR = N[6:1];As set
040ATISet index registerI = A[15:1];Kept
041STIPop into index registerI = A[15:1], A = mem[--M[017]];Logical
042ITAGet index registerA = I;Logical
043ITSPush index registermem[M[017]++] = A, A = I;Logical
044MTJMove index registerJ = M;Kept
045J+MAdd index registersJ += M;Kept
046Unused, but identical to 044 and 045, respectively
047
050
.
.
.
077
*nnExtra-codes, used as system calls and math library functionsVaries or undefined
20
21
22UTCSet C register immediateC = U; ("UTC 0" == NOP)Kept
23WTCSet C registerC = X[15:1];
24VTMSet index register immediateM = V;
25UTMAdd to index register immediateM += V; (or M = U;)
26UZABranch if "Zero"Y = A; if (zero()) K = U;Used
27U1ABranch if not "Zero"Y = A; if (!zero()) K = U;
30UJUnconditional branchK = U;Kept
31VJMJump to subroutineM = K + 1; K = V;
32IJReturn from interrupt (kernel)
33STOPStop (unprivileged :-) )
34VZMBranch if index is zeroif (M == 0) K = V;
35V1MBranch is index is not zeroif (M != 0) K = V;
36Unused, but identical to 34
37VLMLoopif (M != 0) { M++; K = V; }Kept

All instructions except UTC and WTC reset C to 0 after execution.

If V of the current instruction is equal to 0 and the index register being used is 017, the following instructions are executed in stack mode:

that is, M++ is performed after ATX, and M-- is performed before all remaining instructions. To clarify things: the accumulator is the stack top, the stack grows toward bigger addresses, and the stack pointer points to the first available element of the stack.

(It is left to the reader to figure out the semantics of STX [017] and XTS [017].)


Finding the number of the highest 1 bit set

high_1_and_rest(word48 a) {
    int bit = 1;
    if (a == 0) {
	Y = 0;
	return 0;
    }
    while (!(a & 0x800000000000)) {
	bit++;
	a <<= 1;
    }
    Y = a << 1; /* the rest of A */
    return bit;
}

The original instruction set manual assumes a slightly simpler algorithm and says that A = 1 and A = 0 yield the same value 48, "which is somewhat unfortunate"; but in fact all the machines made (even the first one) had the instruction implemented the "correct" way.


Pack instruction illustration

A 0xB742 packed by 0x0F53 = 0x7A00
X
Result


Unpack instruction illustration

A 0xB742 unpacked by 0x0F53 = 0x0B13
X
Result


Semantics of conditional branches

For the UZA and U1A instructions, the "Zero" condition is calculated as follows:

switch (ω) {
	case additive: Zero = (A[41] == 0); /* A >= 0 */ break;
	case multiplicative: Zero = (A[48] == 1); /* abs(A) >= 0.5 */ break;
	case logical: Zero = (A[48:1] == 0); /* A == 0 */ break;
	case 0: Zero = FALSE;
}

YTA semantics

If the current ω is "logical", then A = Y; else A[40:1] = Z, A[41] = 0, E += N - 64;


© Leonid A. Broukhis, 1997

The BESM-6 pages have been accessed 9550 times.