A simple custom 8-bit cpu emulator.
I wanted to try out emulating a cpu and originally wanted to start with the 6502 CPU by MOS Technology. After discovering how complex such a task is i decided to try to emulate a very basic cpu first.
This cpu has a very basic, custom instruction set.
Since i did not use a build system you can just open the included Visual Studio 2022 Solution files in 8-bit CPU or 8-bit CPU asm
The repo is divided into two projects. 8-bit CPU includes the cpu emulation code and 8-bit CPU asm contains the assembler.
The root folder contains the compiled emulator and assembler (both are using a debug build).
There are two, 8-bit registers called A and B. All results from arithmetic operations are stored in register A. The cpu has 14 opcodes which are displayed below.
| Opcode | Hex | Description | Arg1 | Arg2 |
|---|---|---|---|---|
| LDA | 0x01 | Load a value into register A | Value | |
| LDB | 0x02 | Load a value into register B | Value | |
| ADD | 0x03 | Add registers A + B, store in A | ||
| SUB | 0x04 | Subtract B from A, store in A | ||
| OUTV | 0x05 | Output a value from memory | Memory adress | |
| STA | 0x06 | Store A into memory | Memory adress | |
| LDM | 0x07 | Load A from memory | Memory adress | |
| JEZ | 0x08 | Jump if zero flag is set | Memory adress to jump to | |
| JNZ | 0x09 | Jump if zero flag is not set | Memory adress to jump to | |
| MUL | 0x0A | Multiply A * B, store in A | ||
| DIV | 0x0B | Divide A / B, store in A | ||
| INP | 0x0C | Take input and store in memory | Memory adress | |
| LD | 0x0D | Load a register from memory | Register (0x01 = A, 0x02 = B) | Memory adress |
| HLT | 0xFF | Stop the CPU |
You have 256 Bytes of memory available (0x00-0xFF). Obviously memory adresses which contain the program should not be used.
To run a program you need the assembled .bin file that can be generated by the assembler (see below).
A program can be run by calling the 8-bit CPU.exe in the cmd using the -I flag to specify the input file.
For example 8-bit CPU.exe -I ./add_two_inputs.
The assembler can be run using 8-bit CPU asm.exe -I ./add_two_inputs.asm -O ./add_two_inputs.bin
where the -I flag is used for the input file and -O for the output file
It has support for creating and using labels. See label_test example Comments using semicolons (;) are also supported.
The following program takes two inputs and adds them together. Note that input1 + input2 > 9
is not handled in this example!
INP 0xF1
LD 0x01 0xF1
LDB 48
SUB
STA 0xF1
INP 0xF2
LD 0x01 0xF2
LDB 48
SUB
STA 0xF2
LD 0x01 0xF1
LD 0x02 0xF2
ADD
STA 0xF3
LD 0x01 0xF3
LDB 48
ADD
STA 0xF3
OUTV 0xF3
HLTAs you can see ASCII conversion has to be done manually.