An emulator for the RX82 fantasy retro computer system, including the R8 8-bit CPU.
ADRIC: What do these numbers and letters mean?
DOCTOR: It's an early version. Instructions have to be punched in by machine code.
ADRIC: Oh, how boring.
DOCTOR: Boring?
—Doctor Who, Logopolis
cargo install rx82This is an emulator for the RX82 architecture, an imagined home computer system similar to those of the early 1980s, such as the Sinclair ZX81 and Spectrum, the BBC Micro, or the Commodore 64.
The RX82's design is intended not only to evoke fond memories in those of a certain age, but also to help teach the fundamentals of computer systems architecture and computer engineering. It's simpler than historic systems such as the ZX81, because no cost or design compromises are required, but also realistic enough to be useful for learning purposes.
Its central processor is the R8, a fan-fiction CPU design comparable to the Zilog Z80 or the MOS 6502, but again, somewhat simplified for educational purposes.
This crate provides a reference implementation of the RX82 and R8 architectures, and an assembler / disassembler for use with R8 assembly language programs. However, it is intended to be modular, so that you can pick and choose components to build your own systems.
For example, you could use the R8 CPU as part of your own emulator that replaces the RX82 system with something else. Equally, you could use the RX82 system components but replace the CPU with a design of your own, or an emulated real machine such as a 6502.
Prepare your program in a text file (see R8 Assembly Language below), and run:
rx82 asm my_prog.asmIf the program assembles correctly, this will produce a my_prog.bin file you can run with the monitor.
To assemble with verbose debugging (probably only of interest to RX82 developers), use the --debug switch:
rx82 asm --debug my_prog.asmTo start the monitor in debug (single-step) mode:
rx82 monYou can also optionally load and run a binary file (such as one produced by the assembler, for example):
rx82 mon my_prog.binThe monitor displays the current CPU registers and the next instruction in memory, then prompts for a command. Type H for help:
RMON v1.0 (C) 1977 Solid State Technologies, Inc.
PC SP A B C D E F G H ZC | NEXT
C022 BFFF 02 00 BF FF 00 00 00 00 00 | halt
> h
Commands:
G [<address>] = Go (run till halted)
H = Help
M [<address>] = Memory dump
S [<address>] = Single step
Q = Quit
Enter = Repeat last command
>To dump memory, use the M command. This will print a block of memory starting at the current value of PC:
> m
0000: 10 06 19 FF FF 49 B2 FD 40 B2 F7 00 00 00 00 00
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...Press Enter to dump the next block:
>
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...To dump memory from a specific address, enter the address in hex:
> m fff0
FFF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0
0000: 10 06 19 FF FF 49 B2 FD 40 B2 F7 00 00 00 00 00
...Run:
rx82 dis my_prog.binThis will print the disassembled listing.
The RX82 is a single-board computer with one R8 CPU clocked at 4Mhz, 64KiB of static RAM, an 8-bit data bus, and a 16-bit address bus.
| Address | Contents |
|---|---|
| 0x0000 | Trap/interrupt table |
| 0x0080 | System data area |
| 0x0100 | User RAM |
| 0xC000 | ROM |
| 0xFF00 | System I/O area |
| 0xFFFE | Reset vector |
At power on, the CPU loads the reset vector at 0xFFFE, which in the RX82 system holds the ROM entry point, 0xC000. Execution begins here and a simple RAM test is performed to find the highest writable address in memory. The stack pointer is initialised to this address.
Finally, the interactive monitor is invoked.
The R8 is a little-endian CPU with an 8-bit data bus, a 16-bit address bus, and a 16-bit ALU.
The CPU has eight 8-bit registers: A, B, C, D, E, F, G, and H. As with the Z80, these can also be addressed as 16-bit register pairs: AB, CD, EF, and GH.
The 16-bit address bus allows the R8 to address up to 64KiB of memory, and the program counter register PC holds the 16-bit address of the next memory location to fetch from.
The processor status register PS contains the following flags:
- Carry (bit 0) — After addition, this is the carry result. After subtraction or comparison, this flag is set if no borrow occurred (that is, for X - Y, if X >= Y). Increment and decrement instructions do not affect the carry flag.
- Zero (bit 1) — After instructions with a value result, this flag is set if the result is zero, or cleared otherwise.
The hardware stack is governed by the stack pointer register SP, which should be initialised to a suitable address in RAM. The stack grows downwards unboundedly. SP always points to the next location where a value will be pushed: that is, an address one byte lower than the address of the current top-of-stack value.
16-bit registers and return addresses are pushed in little-endian order: that is, the low byte is pushed first, followed by the high byte.
On reset, all registers and flags are zeroed and cleared, and PC is initialised from the little-endian reset vector at 0xFFFE.
The input format recognised by the R8 assembler is very similar to that of most Z80 or 6502 assemblers. Here's a simple example program:
; RAM test
ld cd, 0xFFFD ; top of possible RAM
ld a, 0x02
RAM_FILL:
ld (cd), a ; write 0x02 to each location
dec cd
cmp cd, 0x00FF ; reached bottom of user memory?
bne RAM_FILL ; if not, keep going
RAM_READ:
inc cd ; pointer to next test address
cmp cd, 0xFFFE ; past top?
beq DONE ; if so, all memory is present and OK
dec (cd) ; 0x02 goes to 0x01
beq DONE ; but if zero, RAM is faulty
inc (0x0000) ; anti-aliasing tripwire
dec (cd) ; 0x01 goes to 0x00
beq RAM_READ ; if zero, RAM OK: test next location
DONE:
dec cd ; cd points to the highest usable addressWhitespace is ignored, and only 0x-prefixed hexadecimal numbers are recognised as literals.
- 0.4.0 — beq, bne, inc, dec, and cmp instructions; zero and carry flags; backward labels, comments
- 0.3.0 — all registers, load immediate and store direct instructions
- 0.2.0 — monitor improvements, add
haltinstruction, add assembler - 0.1.0 — first release
