diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-05-01 13:50:52 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-05-01 13:58:09 +0100 |
commit | 8998bd04c94da08dc49ab62007da5604d53895c3 (patch) | |
tree | 43a588f7a372ce17d035536a56fd71691fa6a73f /README.md | |
download | tr8vm-8998bd04c94da08dc49ab62007da5604d53895c3.tar.gz tr8vm-8998bd04c94da08dc49ab62007da5604d53895c3.zip |
Initial import
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c35301 --- /dev/null +++ b/README.md @@ -0,0 +1,389 @@ +# TR-8 + +**Important**: this is a work in progress with pre-alpha quality. Not all the information in this document is final, complete or even accurate. + +8-bit fantasy console inspired by MIPS, Z80 and 6502 real world CPUs. + +## Specs + +``` +Display: 128 x 128 pixels 16 colors (from palette of 32) +Memory: 64K +CPU: TR-8, 8M VM instr/sec +Sound: TBD +``` + +Other features: + +* programable in ASM +* TR-8 CPU + - 16-bit registers: stack pointer (SP) and program counter (PC) + - 8-bit registers: 4 general purpose registers (a, b, x, y), flags refister (F) +* frame interrupt (60Hz) and external IO interrupt +* port based IO + +Memory map: + +``` +0x0000 + program (48896 bytes) +0xbf00 + frame buffer (16K) +0xff00 + frame interrupt vector +0xff02 + IO interrupt vector +0xff04 + stack (251 bytes) +0xffff +``` + +## How to build + +It requires SDL2 and SDL_Mixer. + +On Linux install a C compiler and the development packages for the requirements. + +Example on Debian/Ubuntu using `sudo`: + + sudo apt install build-essential libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev + +Then run `make`. + +This will result in two binaries: + + - *tr8as*: the TR8 assembler + - *tr8vm*: the TR8 VM that can run `tr8` files + +You can then compile and run the example with `make example`. + +## Detailed specs + +### Ports + +| Port | Type | Result | +| --- | --- | --- | +| 0xe0 to 0xef | write | Color select | +| 0xf0 | read | Status of the controller 1 | +| 0xf1 | read | Status of the controller 2 | + +### Controller + +The controller support d-pad with 4 directions, 2 action buttons, select and start. + +Read the port `0xf0` for the 8 1-bit flags reporting the state of the controller 1, and `0xf1` for controller 2. + +``` +76543210 +|||||||\ a (fire 1) +||||||\ b (fire 2) +|||||\ d-pad up +||||\ d-pad down +|||\ d-pad left +||\ d-pad right +|\ select +\ start +``` + +### Palette + +Ports from `0xe0` to `0xef` can be used to select the colors to use in the 16 color palette from the 32 available. + +TODO: palette colours + +### Instructions + +All the instructions are 16-bit, with the exception of `JMP addr` and `CALL +addr` that use an extra 16-bit parameter for "addr". All the instructions take +the same time to run, and being 8 MIPS it can fit `133333` instructions in a +frame (at 60Hz). + +There are no 16-bit registers, but they can be implemented with 2 registers, +and that is supported in some addressing modes with `[r1:r2]`. + +For example: + +```asm + ; fill with color 15 + ld a, 15 + push a + call fill + pop a + + ; halt the CPU + sif + halt + + ; + ; void fill(uint8_t color) + ; + ; fill frame-buffer with a color + ; +fill: + ; grab the color from the stack + ld b, [sp + 2] + ; 64 * 256 is 16K + ld y, 64 + ; a:x is our 16-bit register + ld a, 0xbf + ld x, 0 +fill_loop: + ld [a : x], b + inc x + bno + jmp fill_loop + ; x overfows, so we increment a + ; and decrement y (one 256 block done) + inc a + dec y + bnz + jmp fill_loop + ret +``` + +Arithmetic operations on the "16-bit" can be performed easily using branching +instructions: + +```asm + ; inc a:x + inc x + ; if x overflows we need to increase a + bo + inc a +``` + +#### Directives + +.org addr +Set the address to that value. By default the starting address is `0x0000`. + +.db imm [, imm] +Literal byte. Label can be used with `<` prefix for the low byte of the address and `>`for the high byte. + +.dw imm [, imm] +Literal word. + +#### Load and Store + +LD r1, r2 +Load the value of r2 in r1. + +LD r1, imm +Load the immediate value in r1. + +LD [r1:r2], r3 +Load the value of r3 in the memory address provided by r1:r2. + +LD r3, [r1:r2] +Load into r3 the value in the memory address provided by r1:r2. + +LD [SP + imm], r1 +Load r1 into the stack on top address plus the immediate value. + +LD r1, [SP + imm] +Load into r1 the stack value on top address plus the immediate value. + +#### Stack + +PUSH r1 +Save the value of r1 on the top of the stack. + +POP r1 +Restore the value of r1 by popping it from the top of the stack. + +PUSH F +Save the flags in the stack. + +POP F +Restore the flags from the top of the stack. + +XSP r1 +Exchange the high byte of the stack pointer by the value in r1. + +#### Logical + +AND r1, r2 +Logical AND between r1 and r2, storing the result in r1. +Affected flags: ZF, SF + +AND r1, imm +Logical AND between r1 and immediate value, storing the result in r1. +Affected flags: ZF, SF + +OR r1, r2 +Logical OR between r1 and r2, storing the result in r1. +Affected flags: ZF, SF + +OR r1, imm +Logical OR between r1 and immediate value, storing the result in r1. +Affected flags: ZF, SF + +XOR r1, r2 +Logical exclusive OR between r1 and r2, storing the result in r1. +Affected flags: ZF, SF + +XOR r1, imm +Logical exclusive OR between r1 and immediate value, storing the result in r1. +Affected flags: ZF, SF + +#### Arithmetic + +INC r1 +Incremet r1. +Affected flags: ZF, CF, OF, SF + +DEC r1 +Decrement r1. +Affected flags: ZF, CF, OF, SF + +ADD r1, r2 +Add r1 and r2, storing the result in r1. +Affected flags: ZF, CF, OF, SF + +ADD r1, imm +Add r1 and the immediate value, storing the result in r1. +Affected flags: ZF, CF, OF, SF + +SUB r1, r2 +Subtract r2 to r1, storing the result in r1. +Affected flags: ZF, CF, OF, SF + +SUB r1, imm +Subtract the immediate value to r1, storing the result in r1. +Affected flags: ZF, CF, OF, SF + +CMP r1, r2 +Perform a SUB of r1 minus r2, without storing the result and only updating the flags. +Affected flags: ZF, CF, OF, SF + +CMP r1, imm +Perform a SUB of r1 minus the immediate value without storing the result and only updating the flags. +Affected flags: ZF, CF, OF, SF + +#### Bit Operations + +SHL r1, n +Shift r1 n bits to the left (0 to 7), storing the result in r1. +Affected flags: ZF, CF, SF + +SHR r1, n +Shift r1 n bits to the right (0 to 7), storing the result in r1. +Affected flags: ZF, CF, SF + +ROL r1, n +Rotate r1 n bits to the left (0 to 7), storing the result in r1. +Affected flags: ZF, CF, SF + +ROR r1, n +Rotate r1 n bits to the right (0 to 7), storing the result in r1. +Affected flags: ZF, CF, SF + +BIT r1, n +Test bit n (0 to 7) or r1, setting ZF if it is set or clearing it otherwise. +Affected flags: ZF + +#### Jump and Call + +JMP addr +Set the PC to the 16-bit address. + +CALL addr +Store the next PC in the stack (16-bit address) and sets te PC to the 16-bit address. + +CALL [r1:r2] +Store the next PC in the stack (16-bit address) and sets te PC to the 16-bit address provided by r1:r2. + +RET +Return from a call by setting PC to the top 16-bit value popped from the stack. + +#### Branching + +BZ inst +Branch if Zero, will skip the next instruction if ZF is not set. +Affected flags: BF + +BNZ inst +Branch if not Zero, will skip the next instruction if ZF flag is set. +Affected flags: BF + +BC inst +Branch if Carry, will skip the next instruction if CF flag is not set. +Affected flags: BF + +BNC inst +Branch if not Carry, will skip the next instruction if CF flag is set. +Affected flags: BF + +BO inst +Branch if Overflow, will skip the next instruction if OF flag is not set. +Affected flags: BF + +BNO inst +Branch if not Overflow, will skip the next instruction if OF flag is set. +Affected flags: BF + +BS inst +Branch if Sign, will skip the next instruction if SF flag is not set. +Affected flags: BF + +BNS inst +Branch if not Sign, will skip the next instruction if SF flag is set. +Affected flags: BF + +BI inst +Branch if Interrupt, will skip the next instruction if IF flag is not set. +Affected flags: BF + +BNI inst +Branch if not Interrupt, will skip the next instruction if IF flag is set. +Affected flags: BF + +#### IO, flags and Misc + +HALT +Stop the execution until there is frame interrupt. If the interruption flag is set, this will hang the CPU. + +PORT r1, r2 +Write the value of r2 in the port number provided by r1. If there is an output, the value will be stored in r1. + +NOP +No instruction has no effect. + +SIF +Set IF, disabling the interrupt. +Affected flags: IF + +CIF +Clear IF, enabling the interrupt. If called in an interrupt handler, it won't have effect. Use IRET instead to return from the interrupt to unset IF. +Affected flags: IF + +CCF +Clear carry flag. +Affected flags: CF + +SCF +Set carry flag. +Affected flags: CF + +COF +Clear overflow flag. +Affected flags: OF + +IRET +Return from an interupt handler by setting PC to the top 16-bit value popped from the stack. It enables interrupts by clearing the interrupt flag. +Affected flags: IF + +### TR8 file format + +It is a binary file to be run on the TR-8. + +It doesn't have a header and it will be loaded at `0x0000` address. The execution will start on that address with interruptions disabled (interruption flag set). + +See the memory map for further information. + +## Author and Licence + +This was made by [Juan J. Martinez](https://www.usebox.net/jjm/about/me/). + +The code is MIT licensed. + |