# Paper computer simulator experiment ## To do ### Misc - [ ] Play with JSDoc ### Testing/using - [ ] Write some more complex test programs - [ ] Display (hex) numbers - [ ] Think about automated testing ### Features - [ ] Assembler: - [x] Always add an END at the end - [ ] Pad up to 256 bytes - [x] Add constants to assembler - [ ] Keypad - [ ] Add single-stepping - [x] Make $0F a NOP - [ ] In assembler.js: validateLabel() - [ ] In assemble.js: print better output to stdout - [x] Add a function for logging just a specific range of memory ### Under-the-hood improvements - [ ] Do a proper binary version... (or lose the typed arrays?) - [ ] Extract debugging to its own module ## Run the assembler/simulator Assemble source code: ```npm run asm source_code.asm``` Assemble source code, with debug output: ```npm run asmdebug source_code.asm``` Assemble and run, with animated display of screen memory: ```npm run rundisplay source_code.asm``` Assemble and run, with debug output: ```npm run rundebug 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 + 2 0A HOP addr ; hop ... skip next instruction if A == addr ... when true: IP <- PC + 2 0B JMP lit# ; jump ... IP <- lit# 0C JMP addr ; jump ... IP <- addr 0D CCF ———— ; clear Carry Flag ... CF = 0 0E CHP ———— ; carry hop ... skip next instruction if Carry Flag is set ... when true: IP <- PC + 2 0F NOP ———— ; no operation - Instructions are two bytes long: one byte for the opcode, one for the argument ### Nice features that didn't fit - Hop `IF<` and hop `IF>` - `MUL` and `DIV` - Rotates and shifts ## Registers and Flags - `A` - accumulator - `IP` - instruction pointer (aka program counter) - `CF` - carry flag ## Memory map / Peripherals - `00-0F` - display (4x4) - `10-1F` - keypad? (details TBD) - `20 ` - pointer to display memory - `21 ` - pointer to keypad memory - `22-2F` - reserved for future use / variable storage - `30 ` - initial value for IP - `30-FF` - free ### Maybe someday - Timer (for a version in software/electronic-hardware) ## Assembly language ADD $01 ; comments follow a `;` ADD $FF ; this is direct addressing ADD ($CC) ; this is indirect addressing END ; END, CFC, and CHP don't require arguments ; (a default value of 0 will be used as their operand) @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 an argument ; 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 - Hexadecimal numbers are preceded by a `$` - Whitespace is ignored