Last active
December 15, 2015 04:29
-
-
Save robey/5202420 to your computer and use it in GitHub Desktop.
theoretical 16-bit CPU
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 registers: | |
/ / / / / / E F <- value registers (r0 - r5) | |
/ / / / / / S P <- index registers (a0 - a5) | |
E = extended (carry/rollover) result | |
F = flags: | |
set on result of each binary operation, or load into register | |
x x x x x x x x / Q x x x M N C Z | |
(Q) interrupts are queueing | |
(M) masked: in comparisons, left & right != 0 | |
(N) high bit (negative) was set (for comparisons: left < right) | |
(C) add carried out, or subtract didn't borrow | |
(Z) result was zero (for comparisons: left == right) | |
S = stack pointer | |
P = program counter | |
(for 24 bit addresses: P bank, S bank, data bank?) | |
(IV = interrupt vector) | |
indexed operations (computing the address through a register) may only use | |
an index register (a0 - a5, stack pointer, or program counter). | |
three-register math operations (operations with a 32-bit result) may only | |
use a value register (r0 - r5, extended result, or flags). | |
any other operation may use any of the 16 registers. | |
## indexed binary operation | |
o = operation: | |
0: load | |
1: store | |
2: compare | |
3: add w/carry | |
4: subtract w/borrow | |
5: or | |
6: and | |
7: xor | |
d = destination register | |
s = source (index) register | |
t = -1 to 30 | |
- binop Rd, [Rs + tiny] | |
1 ooo ttttt sss dddd | |
- binop Rd, (Rs) | |
0001 ooo mm sss dddd | |
m = mode: | |
0: ? | |
1: [Rs + imm] | |
2: [Rs++] | |
3: [--Rs] | |
## binary operation | |
o = operation: | |
0: load | |
1: store | |
2: compare | |
3: add w/carry | |
4: subtract w/borrow | |
5: or | |
6: and | |
7: xor | |
8: shift left into (zeroed) E | |
9: shift right into (zeroed) E | |
A: shift right (with/sign) into E | |
d = destination register | |
s = source register | |
t = -1 to 30 | |
- binop Rd, Rs | |
0010 oooo ssss dddd | |
- binop Rd, (tiny) | |
01 oooo m ttttt dddd | |
m = mode: | |
0: tiny | |
1: [tiny] | |
- binop Rd, (imm) | |
0000 011 oooo m dddd | |
m = mode: | |
0: imm | |
1: [imm] | |
## 3-register math | |
o = operation: | |
0: add | |
1: subtract | |
2: unsigned multiply | |
3: signed multiply | |
4: unsigned divide (h = quotient, l = remainder) | |
5: signed divide | |
h = destination high (overflow) value register | |
d = source/destination low value register | |
s = source value register | |
- mathop Rh, Rd, Rs | |
0011 ooo hhh ddd sss | |
## flags | |
o = operation: | |
0: clear | |
1: set | |
2: if-clear | |
3: if-set | |
f = flag (0-15) | |
- flagop f | |
0000 0100 01 oo ffff | |
## unary calls | |
o = operation: | |
0: jsr | |
1: int | |
2: hwi(?) | |
3: | |
r = register | |
- op (R) | |
0000 0100 1 m oo rrrr | |
m = mode: | |
0: R | |
1: [R+imm] | |
- op [R + tiny] | |
0000 1 oo ttttt rrrr | |
- op (tiny) | |
0000 0101 m oo ttttt | |
m = mode: | |
0: tiny | |
1: [tiny] | |
- op (imm) | |
0000 0100 0011 1 m oo | |
m = mode: | |
0: imm | |
1: [imm] | |
## nullary calls | |
- op | |
0000 0100 0011 0ooo | |
o = operation: | |
0: rfi | |
1: hlt | |
2: | |
3: | |
used up: | |
0000 00x - | |
0000 0100 000x - | |
0000 0100 0010 x - | |
0000 0100 0011 0x - op nullary | |
0000 0100 0011 1x - op (imm) unary | |
0000 0100 01x - flagop | |
0000 0100 1x - op (R) unary | |
0000 0101 x - op (tiny) unary | |
0000 011x - binop Rd, (imm) | |
0000 1x - op [R + tiny] unary | |
0001 x - binop Rd, (Rs) | |
0010 x - binop Rd, Rs | |
0011 x - mathop Rh, Rd, Rs | |
01x - binop Rd, (tiny) | |
1x - binop Rd, [Rs + tiny] | |
free: | |
00xx 01xx 02xx 03xx | |
040x 041x 042x | |
(4/256) + (3/4096) = 1.6% unused | |
asm: | |
get r0, [a1 + 3] | |
put r4, [a0++] | |
cmp | |
add | |
sub | |
bor | |
and | |
xor | |
shl r5, 5 | |
shr r5, 5 | |
asr r5, 5 | |
add r5, r0, r1 | |
sub r5, r0, r1 | |
mul r5, r0, r1 | |
div r5, r0, r1 | |
sml r5, r0, r1 | |
sdv r5, r0, r1 | |
set q | |
clr q | |
ifq / ifi (q) | |
ifm / ifu (m) | |
ifn / ifp (n) -- if <, if > | |
ifc / ifb (c) | |
ifz / ifd (z) -- if =, if != | |
jsr | |
int | |
rfi | |
hlt | |
waste: | |
- (get r1, r2) == (put r2, r1) | |
- get r1, r1: 16 wasted combos (32 if you count put) | |
tricks: | |
- (load r1, [r2]) == (load r1, [r2 + 0]) == 100 00000 ssss dddd | |
- (jmp nnnn) == (load p, nnnn) | |
- (bra nnnn) == (add/sub p, nnnn) | |
- (ret) == (load p, [s++]) | |
to-do: | |
- query hardware somehow? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment