Skip to content

Instantly share code, notes, and snippets.

@robey
Last active December 15, 2015 04:29
Show Gist options
  • Save robey/5202420 to your computer and use it in GitHub Desktop.
Save robey/5202420 to your computer and use it in GitHub Desktop.
theoretical 16-bit CPU
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