Dot matrix arcade
Debugger
r00
r10
r20
r30
ip0
sp0
zero0
carry0
Code
Manual
The dot matrix arcade is an 8-bit machine running at 2 MHz, because any faster would render it unusable. It has 256 bytes of memory and that's for code and data combined. That's not enough to do anything useful, but it's plenty to do something interesting.
Display
The 8-bit output port is connected to a 16 by 16 dot matrix display. What it lacks in resolution, it makes up for in pixel size. You can toggle a dots on or off by sending a byte to the output port where the lower four bits contain the x-coordinate and the upper for bits contain the y-coordinate.
Buttons
The 8-bit output port is connected to eight buttons. Four of the buttons are invisible, though; that may or may not be considered a feature. You can get the state of the buttons by reading a byte from the input port. Each bit in that byte represents the state of a button: 1 means the button is down, 0 means the button is up.
Registers
There are four general purpose registers, called r0, r1, r2, and r3. They can be used to store values and perform arithmetic as needed.
There are two special purpose registers.
- instruction pointer
- Contains the memory address of the next instruction the processor will execute.
- stack pointer
- Contains the memory address of the top of the stack. The top of the stack is where the next value will be stored, so it doesn't contain a value yet. The stack pointer increases every time a value is pushed and decreases every time a value is popped.
Flags
A flags is a single bit that tells you something about the result of the last executed instruction.
- zero
- If the result of the last instruction was zero, this flag will be 1. Compare-instructions set this flag to 1 if two values are equal.
- carry
- If the result of the last instruction produced a carry—for example because an addition was greater than 255 or a subtraction was smaller than 0—then this flag will be 1. Compare-instructions set this flag to 1 if the left value was smaller than the right value.
Flags are only set by specific instructions. Check the instruction set for more information.
Instruction set
These are all the instructions the dot matrix machine supports. Some instructions are available for all general purpose registers. In that case, the manual uses the notation rd for destination register and rs for source register. For example, set_rd_rs means that there's an instruction for set_r0_r1, set_r0_r2, set_r0_r3, set_r1_r0, etc.
If an instruction updates a flag, it's noted in the description.
- add_rd_rs
- Calculate
rd + rsand store the result in register d. Set the zero flag if the result is 0; clear it if not. Set the carry flag if the result is greater than 255; clear it if not. - and_rd_rs
- Calculate
rd bitwise-and rsand store the result in register d. Set the zero flag if the result is 0; clear it if not. - call address
- Push the address of the next instruction onto the stack and jump to the instruction at address.
- clear_carry
- Set the carry flag to 0.
- clear_zero
- Set the zero flag to 0.
- compare_rs value
- Set the zero flag if register s is equal to value; clear it if not. Set the carry flag if register d is smaller than value; clear it if not.
- compare_rd_rs
- Set the zero flag if register d is equal to register s; clear it if not. Set the carry flag if register d is smaller than register s; clear it if not.
- decrement_rd
- Calculate
rd - 1and store the result in register d. Set the zero flag if the result is 0; clear it if not. Set the carry flag if the result is 255; clear it if not. - divide
- Calculate
r0 / r1and store the result in r0, and calculater0 module r1and store the result in r1. Set the zero flag if the result is 0; clear it if not. Set the carry flag if r1 is 0 before the calculation; clear it if not. - in_rd
- Read the device connected to the input port and store the result in register d.
- increment_rd
- Calculate
rd + 1and store the result in register d. Set the zero flag if the result is 0; clear it if not. Set the carry flag if the result is 0; clear it if not. - jump address
- Jump to the instruction at address.
- jump_if_equal address
- Jump to the instruction at address if the zero flag is not set. Same as jump_if_zero.
- jump_if_not_carry address
- Jump to the instruction at address if the carry flag is not set.
- jump_if_not_equal address
- Jump to the instruction at address if the zero flag is set. Same as jump_if_not_zero.
- jump_if_not_zero address
- Jump to the instruction at address if the zero flag is not set. Same as jump_if_not_equal.
- jump_if_carry address
- Jump to the instruction at address if the carry flag is set.
- jump_if_greater_or_equal address
- Jump to the instruction at address if the carry flag is set and the zero flag is set.
- jump_if_greater_than address
- Jump to the instruction at address if the carry flag is set and the zero flag is not set.
- jump_if_smaller_or_equal address
- Jump to the instruction at address if the carry flag is set and the zero flag is not set.
- jump_if_smaller_than address
- Jump to the instruction at address if the carry flag is not set and the zero flag is not set.
- jump_if_zero address
- Jump to the instruction at address if the zero flag is set. Same as jump_if_equal.
- multiply
- Calculate
r0 * r1and store the lower eight bits of the result in r0 and the upper eight bits of the result in r1. Set the zero flag if the result 0; clear it if not. Set the carry flag if the result is greater than 255; clear it if not. - negate_rd
- Calculate the two's complement of register d—i.e. flipping its sign—and store the result in register d. Set the zero flag if the result is 0; clear it if not.
- nop
- Do nothing.
- not_rd
- Calculate
bitwise-not rdand store the result in register d. Set the zero flag if the result is 0; clear it if not. - or_rd_rs
- Calculate
rd bitwise-or rsand store the result in register d. Set the zero flag if the result is 0; clear it if not. - out_rs
- Send the value stored in register s to the device connected to the output port.
- pop_all
- Pop four values of the stack and store them in the general purpose registers in the order r3, r2, r1, r0.
- push_all
- Push the contents of all general purpose registers onto the stack in the order r0, r1, r2, r3.
- push_instruction_pointer
- Push the contents of the instruction pointer onto the stack.
- push_rs
- Push the contents of register s onto the stack.
- push_stack_pointer
- Push the contents of the stack pointer onto the stack.
- read_by_pointer_rd_rs
- Read the value in memory that's stored at the address in register s and store it in register d.
- read_rd address
- Read the value in memory that's stored at address an store it in register d.
- return
- Pop an address of the stack and jump to the instruction at that address.
- set_carry
- Set the carry flag to 1.
- set_rd value
- Store value in register d.
- set_rd_rs
- Copy the contents of register d to register s.
- set_stack_pointer address
- Move the stack pointer to address.
- set_zero
- Set the zero flag to 1.
- shift_left_rd value
- Shift the bits in register d value places to the left, filling in zeros as needed. Set the zero flag if the result is 0; clear it if not. Set the carry flag to the last bit shifted out.
- shift_right_rd value
- Shift the bits in register d value places to the right, filling in zeros as needed. Set the zero flag if the result is 0; clear it if not. Set the carry flag to the last bit shifted out.
- subtract_rd_rs
- Calculate
rd - rsand store the result in register d. Set the zero flag if the result is 0; clear it if not. Set the carry flag if the result is smaller than 0; clear it if not. - write_by_pointer_rd_rs
- Write the value in register s to memory at the address stored in register d.
- write_rs address
- Write the value in register s to memory at address.
- xor_rd_rs
- Calculate
rd bitwise-xor rsand store the result in register d. Set the zero flag if the result is 0; clear it if not.