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

41 


Exponent  Sign (pos=0, neg=1)  Mantissa (2complement) 
6 

2  1  
Suppress FPE  ω (omega)  Suppress rounding  Suppress normalisation 
ω could have the following values:
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  


20  19 



M  0  S  OPCode1  offset 
Format 2  


20 



M  1  OPCode2  offset 
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).
Opcode  Mnemonic  Description  Formula  ω 

000  ATX  Store  X = A;  Kept 
001  STX  Pop  X = A; A = mem[M[017]];  Logical 
002  MOD  Modify privileged registers (kernel)  Log/Kept  
003  XTS  Push  mem[M[017]++] = A; A = X;  Logical 
004  A+X  Add  [A,Z] = A + X;  Additive 
005  AX  Subtract  [A,Z] = A  X;  Additive 
006  XA  Reverse subtract  [A,Z] = X  A;  Additive 
007  AMX  Subtract absolute values  [A,Z] = abs(A)  abs(X);  Additive 
010  XTA  Load  A = X;  Logical 
011  AAX  Bitwise AND  A = A & X; Y = 0;  Logical 
012  AEX  Bitwise Exclusive OR  Y = A; A = Y ^ X;  Logical 
013  ARX  Cyclical add  (unsigned) A += (unsigned)X; if (carry) (unsigned)A++; Y = 0;  Multipl. 
014  AVX  Negate  if (X < 0) A = A; Y = 0;  Additive 
015  AOX  Bitwise OR  A = A  X; Y = 0;  Logical 
016  A/X  Divide  A = A / X; Y undefined;  Multipl. 
017  A*X  Multiply  [A,Z] = A * X;  Multipl. 
020  APX  Pack bits in A masked by X. Did the inventors of INTERCAL know about this instruction?  Logical  
021  AUX  Unpack bits in A using mask X  Logical  
022  ACX  Population count  A = popcount(A) + X; Y = 0;  Logical 
023  ANX  Find highest set bit  A = high_1_and_rest(A) + X  Logical 
024  E+X  Add exponent  E += X[48:42]  64; Y = 0;  Multipl. 
025  EX  Subtract exponent  E = X[48:42]  64; Y = 0;  Multipl. 
026  ASX  Shift  Y = 0; if (X[48:42] >= 64) [A,Y] >>= X[48:42]64; else [Y,A] <<= 64X[48:42];  Logical 
027  XTR  Set mode register  R = X[47:42];  As set 
030  RTE  Get mode register  E = R;  Used 
031  YTA  Get young bits register  A = yta (Y, ω);  Used 
032  EXT  Access external I/O registers (kernel)  Kept  
033    
034  E+N  Add exponent immediate  E += N  64; Y = 0;  Multipl. 
035  EN  Subtract exponent immediate  E = N  64; Y = 0;  Multipl. 
036  ASN  Shift immediate  Y = 0; if (N >= 64) [A,Y] >>= N64; else [Y,A] <<= 64N;  Logical 
037  NTR  Set mode register immediate  R = N[6:1];  As set 
040  ATI  Set index register  I = A[15:1];  Kept 
041  STI  Pop into index register  I = A[15:1], A = mem[M[017]];  Logical 
042  ITA  Get index register  A = I;  Logical 
043  ITS  Push index register  mem[M[017]++] = A, A = I;  Logical 
044  MTJ  Move index register  J = M;  Kept 
045  J+M  Add index registers  J += M;  Kept 
046  Unused, but identical to 044 and 045, respectively  
047  
050 . . . 077  *nn  Extracodes, used as system calls and math library functions  Varies or undefined  
20  
21  
22  UTC  Set C register immediate  C = U; ("UTC 0" == NOP)  Kept 
23  WTC  Set C register  C = X[15:1];  
24  VTM  Set index register immediate  M = V;  
25  UTM  Add to index register immediate  M += V; (or M = U;)  
26  UZA  Branch if "Zero"  Y = A; if (zero()) K = U;  Used 
27  U1A  Branch if not "Zero"  Y = A; if (!zero()) K = U;  
30  UJ  Unconditional branch  K = U;  Kept 
31  VJM  Jump to subroutine  M = K + 1; K = V;  
32  IJ  Return from interrupt (kernel)  
33  STOP  Stop (unprivileged :) )  
34  VZM  Branch if index is zero  if (M == 0) K = V;  
35  V1M  Branch is index is not zero  if (M != 0) K = V;  
36  Unused, but identical to 34  
37  VLM  Loop  if (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:
(It is left to the reader to figure out the semantics
of STX [017]
and XTS [017]
.)
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.
A  

X  
Result 
A  

X  
Result 
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; }
If the current ω is "logical", then A = Y; else A[40:1] = Z, A[41] = 0, E += N  64;
The BESM6 pages have been accessed 6427 times.