# ALU and Instruction Set

A project log for Novasaur CP/M TTL Retrocomputer

Retrocomputer built from TTL logic running CP/M with no CPU or ALU

Alastair Hewitt 05/13/2019 at 15:190 Comments

Hardware testing is complete on all the jump and branch instructions. So that's the first 8 out of 256 instructions tested! The next 24 are loading operands. These should work fine since the jump/branch instructions are also loading operands in order to update the PC and Pg register. All the rest are ALU instructions, so it's time to work on the build script to generate the 96k of lookup tables.

First off is to define the functions. There's room for 8 full byte-wide, 4 half nibble-wide, and 64 unary functions. One of the unary functions has to be the identity (do nothing) so I don't count that in the total of 75 functions.

The 8 byte-wide functions are the classics:

3. SUB - Subtraction
4. DSB - BCD subtraction
5. AND - Logical AND
6. OR - Logical OR
7. XOR - Logical Exclusive-OR
8. CMP - Compare (returns 0 if equal, else -1)

The 4 nibble-wide functions are used for multiplication, division, and modulo. These would be used to multiply two nibbles to get a byte, or divide a byte by a nibble to get a nibble.

The 64 unary functions are contained in 4 sets of 16. One of these could contain math related functions consisting of the following:

1. SQRT - Square Root
2. POW2 - Square (x**2)
3. POW3 - Cube (x**3)
4. INV - 1/x
5. SIN - sin(x)
6. ASIN - arc sin(x)
7. COS - cos(x)
8. ACOS - arc cos(x)
9. TAN - tan(x)
10. ATAN - arc tan(x)
11. EXP - e**x
12. LN - natural log(x)
13. LOG - base 10 log(x)
14. LOG2 - base 2 log(x)
15. ABS - absolute (remove sign)
16. ?? - ran out of ideas :(

These math functions may look impressive, but they have a very limited dynamic range at only 8 bits wide. These can not be used directly to build a real floating-point library, but they can provide short cuts in making a real library faster. They could be used directly for demo-grade things like a Mandelbrot program, or to draw a circle on the screen. The circle should be clean if the radius is kept below 128, which is realistic in both the low and hires graphics modes.

The other sets would contain functions related to graphics, serial communication, keyboard scan codes, interpreter jump offsets etc. I have some ideas, but not worth finalizing at this point. The last set (FN3/FNH) are the most used and contain the typical unary functions you would see on other processors:

1. INC - Increment (x+1)
2. DEC - Decrement (x-1)
3. INC2 - Double Increment (x+2)
4. DEC2 - Double Increment (x-2)
5. 1COM - One's complement (invert bits)
6. 2COM - Two's complement (invert bits + 1)
7. ROR - Rotate Right
8. ROL - Rotate Left
9. LSR - Logical Shift Right
10. LSL - Logical Shift Left
11. ASR - Arithmetic Shift Right
12. ASR4 - Arithmetic Shift Right by 4 (move upper nibble to lower preserve sign)
13. SR4 - Shift Right by 4 (move upper nibble to lower)
14. SL4 - Shift Left by 4 (move lower nibble to upper)
15. SWAP - Swap nibbles
16. IDEN - Identity function (x = x)

The instruction set can now be derived based on the functions defined above. The following lists all 256 instructions:

```00: NOP
01: JMP D
02: BPZ D
03: BN D
04: PJ D
05: PJT D
06: PBPZ D
07: PBNT D
08: LD PC, D
09: LD V, D
0A: LD X, D
0B: LD Y, D
0C: LD HL, D
0D: LD E, D
0E: LD EX, D
0F: LD EY, D
10: LDZ PC, D, RAM1
11: LDZ V, D, RAM1
12: LDZ X, D, RAM1
13: LDZ Y, D, RAM1
14: LDZ HL, D, RAM1
15: LDZ E, D, RAM1
16: LDZ EX, D, RAM1
17: LDZ EY, D, RAM1
18: LDZ PC, D
19: LDZ V, D
1A: LDZ X, D
1B: LDZ Y, D
1C: LDZ HL, D
1D: LDZ E, D
1E: LDZ EX, D
1F: LDZ EY, D
22: SUB A, HL, RAM0
23: DSB A, HL, RAM0
24: AND A, HL, RAM0
25: OR A, HL, RAM0
26: XOR A, HL, RAM0
27: CMP A, HL, RAM0
2A: SUB RAM0, HL
2B: DSB RAM0, HL
2C: AND RAM0, HL
2D: OR RAM0, HL
2E: XOR RAM0, HL
2F: CMP RAM0, HL
32: SUB A, HL, RAM1
33: DSB A, HL, RAM1
34: AND A, HL, RAM1
35: OR A, HL, RAM1
36: XOR A, HL, RAM1
37: CMP A, HL, RAM1
3A: SUB A, HL
3B: DSB A, HL
3C: AND A, HL
3D: OR A, HL
3E: XOR A, HL
3F: CMP A, HL
40: FNH A, PC, RAM0
41: FNH A, V, RAM0
42: FNH A, X, RAM0
43: FNH A, Y, RAM0
44: FNH A, HL, RAM0
45: FNH A, E, RAM0
46: FNH A, EX, RAM0
47: FNH A, EY, RAM0
48: FNH RAM0, PC
49: FNH RAM0, V
4A: FNH RAM0, X
4B: FNH RAM0, Y
4C: FNH RAM0, HL
4D: FNH RAM0, E
4E: FNH RAM0, EX
4F: FNH RAM0, EY
50: FNH A, PC, RAM1
51: FNH A, V, RAM1
52: FNH A, X, RAM1
53: FNH A, Y, RAM1
54: FNH A, HL, RAM1
55: FNH A, E, RAM1
56: FNH A, EX, RAM1
57: FNH A, EY, RAM1
58: FNH A, PC
59: FNH A, V
5A: FNH A, X
5B: FNH A, Y
5C: FNH A, HL
5D: FNH A, E
5E: FNH A, EX
5F: FNH A, EY
60: FNH X, PC, RAM0
61: FNH X, V, RAM0
62: FNH X, X, RAM0
63: FNH X, Y, RAM0
64: FNH X, HL, RAM0
65: FNH X, E, RAM0
66: FNH X, EX, RAM0
67: FNH X, EY, RAM0
68: FNH X, PC
69: FNH X, V
6A: FNH X, X
6B: FNH X, Y
6C: FNH X, HL
6D: FNH X, E
6E: FNH X, EX
6F: FNH X, EY
70: FNH RAM1, PC, RAM1
71: FNH RAM1, V, RAM1
72: FNH RAM1, X, RAM1
73: FNH RAM1, Y, RAM1
74: FNH RAM1, HL, RAM1
75: FNH RAM1, E, RAM1
76: FNH RAM1, EX, RAM1
77: FNH RAM1, EY, RAM1
78: FNH E, PC
79: FNH E, V
7A: FNH E, X
7B: FNH E, Y
7C: FNH E, HL
7D: FNH E, E
7E: FNH E, EX
7F: FNH E, EY
82: SUB A, L, RAM0
83: DSB A, L, RAM0
84: AND A, L, RAM0
85: OR A, L, RAM0
86: XOR A, L, RAM0
87: CMP A, L, RAM0
8A: SUB RAM0, L
8B: DSB RAM0, L
8C: AND RAM0, L
8D: OR RAM0, L
8E: XOR RAM0, L
8F: CMP RAM0, L
92: SUB A, L, RAM1
93: DSB A, L, RAM1
94: AND A, L, RAM1
95: OR A, L, RAM1
96: XOR A, L, RAM1
97: CMP A, L, RAM1
9A: SUB A, L
9B: DSB A, L
9C: AND A, L
9D: OR A, L
9E: XOR A, L
9F: CMP A, L
A2: SUB X, L, RAM0
A3: DSB X, L, RAM0
A4: AND X, L, RAM0
A5: OR X, L, RAM0
A6: XOR X, L, RAM0
A7: CMP X, L, RAM0
AA: SUB X, L
AB: DSB X, L
AC: AND X, L
AE: XOR X, L
AF: CMP X, L
B2: SUB RAM1, L, RAM1
B3: DSB RAM1, L, RAM1
B4: AND RAM1, L, RAM1
B5: OR RAM1, L, RAM1
B6: XOR RAM1, L, RAM1
B7: CMP RAM1, L, RAM1
BA: SUB E, L
BB: DSB E, L
BC: AND E, L
BD: OR E, L
BE: XOR E, L
BF: CMP E, L
C0: MUL A, L, RAM0
C1: DML A, L, RAM0
C2: DIV A, L, RAM0
C3: MOD A, L, RAM0
C4: FN0 A, L, RAM0
C5: FN1 A, L, RAM0
C6: FN2 A, L, RAM0
C7: FN3 A, L, RAM0
C8: MUL RAM0, L
C9: DML RAM0, L
CA: DIV RAM0, L
CB: MOD RAM0, L
CC: FN0 RAM0, L
CD: FN1 RAM0, L
CE: FN2 RAM0, L
CF: FN3 RAM0, L
D0: MUL A, L, RAM1
D1: DML A, L, RAM1
D2: DIV A, L, RAM1
D3: MOD A, L, RAM1
D4: FN0 A, L, RAM1
D5: FN1 A, L, RAM1
D6: FN2 A, L, RAM1
D7: FN3 A, L, RAM1
D8: MUL A, L
D9: DML A, L
DA: DIV A, L
DB: MOD A, L
DC: FN0 A, L
DD: FN1 A, L
DE: FN2 A, L
DF: FN3 A, L
E0: MUL X, L, RAM0
E1: DML X, L, RAM0
E2: DIV X, L, RAM0
E3: MOD X, L, RAM0
E4: FN0 X, L, RAM0
E5: FN1 X, L, RAM0
E6: FN2 X, L, RAM0
E7: FN3 X, L, RAM0
E8: MUL X, L
E9: DML X, L
EA: DIV X, L
EB: MOD X, L
EC: FN0 X, L
ED: FN1 X, L
EE: FN2 X, L
EF: FN3 X, L
F0: MUL RAM1, L, RAM1
F1: DML RAM1, L, RAM1
F2: DIV RAM1, L, RAM1
F3: MOD RAM1, L, RAM1
F4: FN0 RAM1, L, RAM1
F5: FN1 RAM1, L, RAM1
F6: FN2 RAM1, L, RAM1
F7: FN3 RAM1, L, RAM1
F8: MUL E, L
F9: DML E, L
FA: DIV E, L
FB: MOD E, L
FC: FN0 E, L
FD: FN1 E, L
FE: FN2 E, L
FF: FN3 E, L
```