cardiograph-computer/readme.md

130 lines
3.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Cardiograph Mark I — simulator for a paper computer
## Dependencies
- Node.js
- readline-sync
## Run
### Assemble
Hex output:
```./run-assembler run source_code.asm```
Binary output:
```./run-assembler runbin source_code.asm```
Verbose debugging output (hex):
```./run-assembler debug source_code.asm```
### Assemble and run
With animated display of screen memory:
```./run-cpu run source_code.asm```
With verbose debugging output:
```./run-cpu debug source_code.asm```
With single stepping + pretty-printed display:
```./run-cpu step source_code.asm```
With single stepping + verbose debugging output:
```./run-cpu stepdebug source_code.asm```
## Instruction set
00 END
01 STO lit# ; store ... mem[lit#] <- A
02 STO addr ; store ... mem[mem[addr]] <- A
03 LDA lit# ; load ... A <- lit#
04 LDA addr ; load ... A <- mem[addr]
05 ADD lit# ; add ... A <- A + lit# ... and un/set carry flag
06 ADD addr ; add ... A <- A + mem[addr] ... and un/set carry flag
07 SUB lit# ; sub ... A <- A - lit# ... and un/set carry flag
08 SUB addr ; sub ... A <- A - mem[addr] ... and un/set carry flag
09 HOP lit# ; hop ... skip next instruction if A == lit# ... when true: IP <- PC + 4
0A HOP addr ; hop ... skip next instruction if A == addr ... when true: IP <- PC + 4
0B JMP lit# ; jump ... IP <- lit#
0C JMP addr ; jump ... IP <- addr
0D FTG lit# ; toggle flag by number (see details below)
0E FHP lit# ; flag hop ... skip next instruction if flag is set ... when true: IP <- PC + 4
0F NOP ———— ; no operation
- Instructions are two bytes long:
one byte for the opcode, one for the operand
## Registers and Flags
- `A` - accumulator
- `IP` - instruction pointer (aka program counter)
- `FLAGS` - flags: **N**egative, **Z**ero, **O**verflow, **C**arry
- in machine language, each flag is given a number:
- N = 3
Z = 2
O = 1
C = 0
- (bitwise, `0000 = NZOC`)
## Memory map / Peripherals
- `00-0F` - display (4x4)
- `10-19` - reserved for future use
- `20 ` - keypad - value of the most recent keypress
- `21 ` - pointer to display memory
- `22 ` - pointer to keypad memory
- `23-2F` - reserved for future use / variable storage
- `30 ` - initial value for IP
- `30-FF` - free
### Keypad
The value of the latest keypress on a hex keypad is stored at `$20`.
(The keypad can also be relocated by changing the value of the pointer-to-keypad at `$22`.)
The keypad uses the same layout as the COSMAC VIP (and CHIP-8):
```
1 2 3 C
4 5 6 D
7 8 9 E
A 0 B F
```
The CPU simulator maps the following Qwerty keys onto those values:
```
1 2 3 4
Q W E R
A S D F
Z X C V
```
## Assembly language
ADD $01 ; comments follow a `;`
ADD $FF ; this is direct addressing
ADD ($CC) ; this is indirect addressing
END ; END and NOP don't require operands
; (the assembler will fill in a default value of 0)
@subroutine ; create a label
ADD $01 ; (it must be on the line before the code it names)
ADD $02
JMP @subroutine ; use a label as operand
; the label will be replaced with
; the address of the label
#foo $FF ; define a constant
; (must be defined before it is referenced)
ADD #foo ; use a constant as an operand
LDA *ADDR ; `*ADDR` is a magic value referencing the memory address
; that the current line will store at after assembly
- Hexadecimal numbers are preceded by a `$`
- Whitespace is ignored