00001

This is an emulator for Dick, my 16-bit one instruction set computer.

Δt: ++ + 50ms (20fps) - -- | Pause | Tick

Load State

Assemble Programme

Assembly language

A line of an assembly programme is either a label, a value, or an instruction.

Labels end in ':'s, and mark the name preceding the ':' as referring to that location in memory.

A value is either an integer literal like 413, 0x98ab, etc. or a label name. The latter can optionally be preceded by a '-' to indicate that it should be the value of that label minus one (which is useful for setting the PC).

Instructions are all MOV A B, since it's an OISC. A and B are both 8-bit addresses, and can optionally be values (as long as those values fit in 8 bits). Nicknames for words can also be used (e.g. OPA instead of W01).

';' starts a comment.

Example Programmes

Hello world

This one only works if you run it on the actual computer, not this emulator, and then look at the display upside-down.

  MOV HELLO OUTPUT
LOOP:
  MOV LOOP_PTR PC

LOOP_PTR:
-LOOP
HELLO:
7734

Square numbers

START:
  MOV SQUARE W0B
  MOV SIDES W01
  MOV TWO W02
  MOV W00 SIDES
  MOV SIDES W01
  MOV SQUARE W02
  MOV W00 SQUARE
  MOV STARTPTR W00

SIDES:
1
SQUARE:
1
TWO:
2

STARTPTR:
-START

Prime numbers

This uses bit-shifts to test divisors quickly. It also only tests divisors up to the square root of the candidate prime. You can make it much faster, at the expense of reducing how long it lasts before getting inaccurate, by removing some of the "MOV SLA SLA" lines.

  ; TEST PRIME P
TEST_PRIME:
  MOV THREE Q
  MOV NINE QSQUARED
TEST_DIVISOR:
  MOV Q SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SLA
  MOV SLA SRA ; SRA = Q << 8
  MOV MINUS_P DIVACC
DIVLOOP:
  MOV DIVACC OPB
  MOV SRA OPA
  MOV SUB_PTR CARA
  MOV DONTSUB_PTR CARB
  MOV CARB PC
SUB:
  MOV ABSUM DIVACC
  MOV NEXTSHIFT_PTR PC
DONTSUB: ; IF OPB + SRA == 0, P IS COMPOSITE
  MOV ABSUM OPB
  MOV ZERO OPA
  MOV NEXTP_PTR EQUA ; DIVISOR FOUND
  MOV NEXTSHIFT_PTR EQUB
  MOV EQUB PC
NEXTSHIFT:
  MOV SRA OPA
  MOV Q OPB
  MOV SRA SRA
  MOV NEXTQ_PTR EQUA
  MOV DIVLOOP_PTR EQUB
  MOV EQUB PC
NEXTQ:
  MOV Q OPA
  MOV TWO OPB
  MOV ABSUM Q
  MOV OPA SLA
  MOV SLA SLA
  MOV SLA OPA
  MOV THREE OPB
  MOV ABSUM OPA
  MOV QSQUARED OPB
  MOV ABSUM OPA
  MOV OPA CARA ; CARA STORES Q SQUARED MINUS ONE
  ; CARA IS USED AS A TEMP VARIABLE HERE
  MOV ONE OPB
  MOV ABSUM QSQUARED
  ; Q AND QSQUARED HAVE NOW PROGRESSED
  ; IF Q**2 - P > 0 GOTO NEXTP
  ; IF (Q**2 - 1) - P >= 0 GOTO NEXTP
  MOV CARA OPA
  MOV MINUS_P OPB
  MOV TEST_DIVISOR_PTR CARA
  MOV PRIME_FOUND_PTR CARB
  MOV CARB PC
PRIME_FOUND:
  MOV P OUTPUT
NEXTP:
  MOV P OPA
  MOV TWO OPB
  MOV ABSUM P
  MOV MINUS_P OPA
  MOV MINUS_TWO OPB
  MOV ABSUM MINUS_P
  MOV TEST_PRIME_PTR PC

Q:
0
QSQUARED:
0
P:
9
MINUS_P:
0XFFF7 ; -9
ONE:
1
TWO:
2
MINUS_TWO:
0XFFFE
THREE:
3
NINE:
9
ZERO:
0
DIVACC:
0

; POINTERS

TEST_PRIME_PTR:
-TEST_PRIME
TEST_DIVISOR_PTR:
-TEST_DIVISOR
DIVLOOP_PTR:
-DIVLOOP
SUB_PTR:
-SUB
DONTSUB_PTR:
-DONTSUB
NEXTSHIFT_PTR:
-NEXTSHIFT
NEXTQ_PTR:
-NEXTQ
PRIME_FOUND_PTR:
-PRIME_FOUND
NEXTP_PTR:
-NEXTP