A little of ternary theory - we will use "balanced" one where our 3 values are -1, 0 and +1 (NOT 0,1,2). Atomic bit of ternary information usually called trit. And lets call 3 trits a triad. 1 trit could be in 3 states, 2 trits could be in 9 states (3^2) and 3 trits could be in 27 states (3^3). Triad may represent a number from -13 (9*(-1)+3*(-1)+1*(-1)) to +13 (9*(+1)+3*(+1)+1*(+1)), but how we should write this numbers in ternary form? -1-1-1 and +1+1+1 are not practical. So we came up with alphabetical labels for ternary values: +1 is labeled P (positive), 0 is labeled O (it's letter O, but we call it "neutral") and -1 is labeled N (negative), So -1-1-1 (number -13) could be written as NNN and +1+1+1 (number +14) could be written as PPP. Obviously 000 (number 0) is OOO :)
Now about 3niti alpha architecture (mostly designed in 2004). It has 3-trit data (27 possible values from -13 to +13), 9-trit address (to access up to 19683 cells) and 9 registers (coded by 2 trits that could be represented by numbers from -4 to +4):
N (-4): triad from memory addressed by DPn;
O (-3): triad from memory addressed by DPo;
P (-2): triad from memory addressed by DPp;
F (-1): flag register: RSF (Result Sign Flag), DPF (Data Pointer Flag), BCF (Borrow Carry Flag);
A (0): accumulator register;
B (+1): auxiliary register;
L (+2): lower triad of current DP register;
M (+3): middle triad of current DP register;
H (+4): higher triad of current DP register.
There are THREE 9-trit DP (data pointer) registers - DPn, DPo, DPp that are available through registers L/M/H when flag DPF has corresponding value (N, O, P respectively). Also there is 9-trit register PC (program counter) and this architecture doesn't have a stack, so no register SP.
Instruction set is 27 opcodes ($ means one triad in instruction parameters):
Ternary | Decimal | Mnemonic | Description |
NNN | -13 | SAN | Save value from register A to N (memory cell with address DPn) |
NNO | -12 | SAO | Save value from register A to O (memory cell with address DPo) |
NNP | -11 | SAP | Save value from register A to P (memory cell with address DPp) |
NON | -10 | SAF | Save value from register A to F |
NOO | -9 | SPCD | Save value from PC (program counter) to current DP (data pointer) |
NOP | -8 | SAB | Save value from register A to B |
NPN | -7 | SAL | Save value from register A to L (lower triad of current data pointer) |
NPO | -6 | SAM | Save value from register A to M (middle triad of current data pointer) |
NPP | -5 | SAH | Save value from register A to H (higher triad of current data pointer) |
ONN | -4 | RLA | Rotate register A to the left through flag BCF |
ONO | -3 | ADD | Add register A with B and flag BCF, save result to A and BCF, modify sign flag RSF |
ONP | -2 | RRA | Rotate register A to the right through flag BCF |
OON | -1 | LAI $ | Load register A from immediate triad |
OOO | 0 | ADI $ | Add register A with immediate triad and flag BCF, save result to A and BCF, modify sign flag RSF |
OOP | 1 | OPA $ | Perform unary "tritwise" operation over A (function is defined by immediate triad), modify sign flag RSF |
OPN | 2 | LDI $ $ $ | Load current DP (data pointer) by immediate 3 triads (higher triad, middle triad, lower triad) |
OPO | 3 | JMP $ $ $ | Jump to address (copy to PC) set by immediate 3 triads (higher triad, middle triad, lower triad) |
OPP | 4 | OPB $ $ $ | Perform binary "tritwise" operation over A and B, save result to A (function is defined by immediate 3 triads), modify sign flag RSF |
PNN | 5 | LAN | Load register A by value from N (memory cell with address DPn) |
PNO | 6 | LAO | Load register A by value from O (memory cell with address DPo) |
PNP | 7 | LAP | Load register A by value from P (memory cell with address DPp) |
PON | 8 | LAF | Load register A by value from F |
POO | 9 | LPCD | Load PC (program counter) by value from current DP (data pointer) |
POP | 10 | LAB | Load register A by value from B |
PPN | 11 | LAL | Load register A by value from L (lower triad of current data pointer) |
PPO | 12 | LAM | Load register A by value from M (middle triad of current data pointer) |
PPP | 13 | LAH | Load register A by value from H (higher triad of current data pointer) |
Control panel for 3niti alpha (designed in 2008) consists of 2 rows:
Top horizontal row of 15 "ternary" red-green light indicators:
- Lights 1,2,3,4,5,6,7,8,9 (A8...A0) - value of PC register (address of current operation)
- Lights 10,11,12 (D2...D0) - 3-trit data (see below)
- Lights 13,14,15 (Register A) - current value of A register
Bottom horizontal row of 15 "ternary" slide switches:
- Switches 1,2,3,4,5,6,7,8,9 (A8...A0) - some 9-trit address entered by user
- Switches 10,11,12 (D2...D0) - some 3-trit data entered by user
- Switch 13 (W/R) - control input/output ternary switch:
P (top position) - using specified address write data to the memory (data lights display this 3-trit data)
O (neutral position) - ignore address and data switches (data lights display data from memory address PC)
N (bottom position) - ignore data switches and display data from specified address
- Switch 14 (I/M) - control subprogram ternary switch:
P (top position) - interrupt main program, save current PC and jump to specified address
O (neutral position) - do not disturb working program
N (bottom position) - stop subprogram and restore PC to return to main program
- Switch 15 (S/G) - control step/run ternary switch:
P (top position) - execute one step of the program
O (neutral position) - pause mode
N (bottom position) - run program from current position