| Crates.io | e8bit_emulator |
| lib.rs | e8bit_emulator |
| version | 0.3.6 |
| created_at | 2025-05-07 01:18:39.538763+00 |
| updated_at | 2025-05-21 17:14:31.977324+00 |
| description | 8-bit emulator written in Rust. |
| homepage | |
| repository | https://github.com/mi66mc/e8bit_emulator |
| max_upload_size | |
| id | 1663280 |
| size | 69,012 |
This project is a simple 8-bit virtual machine (VM) emulator written in Rust. It simulates a basic CPU with registers, memory, and a set of instructions for performing arithmetic, memory operations, and control flow.
ADD, SUB, MUL, DIV, MOD, MULHMOV, STORE[0], [A], [B], etc.JMP, JZ, JNZ, LOOPINPUT, PRINT, PRINTCHHALTDRAW, CLS, RENDERCMPRANDfalse (non-zero) or true (zero), enabling conditional logic.//) and instruction separation via ; or by lines.MOV A 'p'. Characters are internally treated as their ASCII numeric values and must fit within 8 bits (0–255), just like any other number.80 by 25 virtual screen and rendering it to the console.JMP, JZ, JNZ, LOOP) instead of numeric instruction indices.You can define a label by writing it at the start of a line followed by a colon, e.g. LOOP_START:.
You can then use the label name as the target for JMP, JZ, JNZ, or LOOP instructions:
MOV A 0
MOV B 10
LOOP_START:
ADD A 1
PRINT A
CMP A B
JNZ LOOP_START
HALT
This is equivalent to using numeric indices, but is easier to read and maintain.
The files game.e8, game2.e8, example.e8, example2.e8, example3.e8, example4.e8, example5.e8, example6.e8, example7.e8, and others contain example programs that demonstrate the use of registers, arithmetic operations, memory storage, loops, and conditional logic.
Even or Odd Example:
// EVEN OR ODD
INPUT A // get number from user input
MOD A 2 // get remainder of A divided by 2
CMP A 0 // compare A with 0, if true, zero flag set to true
JZ EVEN // EVEN (jump to label EVEN if zero)
MOV C 'O' // ODD
PRINTCH C -N
MOV C 'D'
PRINTCH C -N
PRINTCH C -N
JMP END
EVEN:
MOV C 'E' // EVEN
PRINTCH C -N
MOV C 'V'
PRINTCH C -N
MOV C 'E'
PRINTCH C -N
MOV C 'N'
PRINTCH C -N
END:
HALT // end program
Factorial Example (example.e8):
// FACTORIAL SCRIPT
// registers
MOV A 1; // A = 1 (result)
MOV B 5; // B = 5 (number to get factorial)
LOOP_START:
MUL A B; // A *= B
SUB B 1; // B -= 1
LOOP LOOP_START B; // if B != 0 go to LOOP_START
// END
PRINT A; // shows result
HALT;
Install Rust: Ensure you have Rust installed. You can download it from rust-lang.org.
Compile the Program:
cargo build --release
Run the Emulator:
cargo run example.e8 -d
Replace example.e8 with the path to your program file.
If no file is specified, it will run in IDLE mode, where you can enter instructions directly.
The -d flag is optional and enables debug mode, which provides additional output for debugging purposes.
Programs for the emulator are written in a custom assembly-like language. Each instruction is written on a new line or separated by a semicolon and can include comments starting with //. Refer to the example programs above for syntax.
| Instruction | Description |
|---|---|
MOV A 10 |
Move value 10 into register A |
MOV A 'p' |
Move character literal 'p' into register A (ASCII value) |
MOV A [0] |
Move value from memory address 0 into A |
MOV A [B] |
Move value from memory at index stored in B |
ADD A B |
A = A + B |
SUB A 1 |
A = A - 1 |
MUL A 2 |
A = A * 2 |
DIV A 2 |
A = A / 2 |
MOD A 2 |
A = A % 2 (remainder after division) |
MULH A B C |
A = high byte of (B * C) |
STORE A [0] |
Store A into memory[0] |
STORE A [B] |
Store A into memory at index in B |
INPUT A |
Read input (u8 or char) into register A |
INKEY A |
Reads a single key press (non-blocking), stores ASCII code of the key in register A, or 0 if no key was pressed. Only character keys are returned. |
JMP 10 / JMP LABEL |
Jump to instruction index 10 or to label LABEL |
JZ 5 / JZ LABEL |
Jump to index 5 or label if last result was 0 (zero flag set) |
JNZ 8 / JNZ LABEL |
Jump if last result was not zero (zero flag not set) |
LOOP 3 C / LOOP LABEL C |
Jump to index 3 or label while C != 0 |
PRINT A |
Print value of A with newline |
PRINT A -N |
Print value of A without newline |
PRINTCH A |
Print character represented by value in A |
PRINTCH A -N |
Print character without newline |
DRAW X Y C |
Draw character C at screen position (X, Y) |
CLS |
Clear the screen |
CTS |
Clear the terminal screen |
RENDER |
Render the screen to the console (80x25) |
SLP 1000 |
Pause execution for 1 second (1000 ms) |
HALT |
Stops program execution |
CMP A 10 |
Compare register A with value 10. Sets the zero flag if equal. |
RAND A |
Set register A to a random value between 0–255 |
| Type | Example | Description |
|---|---|---|
| Register | A, B, C, D, E |
One of the five registers |
| Immediate Value | 42, 'p' |
A literal number or character between 0–255 |
| Memory Address | [0] |
Direct access to memory index 0 |
| Memory via Reg | [A] |
Access memory using value in register A |
Note: Square brackets (
[]) are used to specify memory addresses. For example:
MOV A [0]loads the value from memory address 0 into register A.STORE A [0]stores the value of register A into memory address 0.
| Instruction | Arg 1 Type | Arg 2 Type | Arg 3 Type |
|---|---|---|---|
MOV |
Register | Immediate Value, Register, or Memory Address ([0], [A], etc.) |
- |
ADD |
Register | Immediate Value, Register, or Memory Address | - |
SUB |
Register | Immediate Value, Register, or Memory Address | - |
MUL |
Register | Immediate Value, Register, or Memory Address | - |
DIV |
Register | Immediate Value, Register, or Memory Address | - |
MOD |
Register | Immediate Value, Register, or Memory Address | - |
MULH |
Register | Register | Register |
STORE |
Register | Memory Address ([0], [B], etc.) |
- |
JMP |
Immediate Value | - | - |
JZ |
Immediate Value | - | - |
JNZ |
Immediate Value | - | - |
LOOP |
Immediate Value (Instruction Index) | Register | - |
PRINT |
Register | Optional: -N to suppress newline |
- |
PRINTCH |
Register | Optional: -N to suppress newline |
- |
INPUT |
Register | - | - |
DRAW |
Immediate Value, Register, or Memory Address | Immediate Value, Register, or Memory Address | Immediate Value, Register, or Memory Address |
CLS |
- | - | - |
CTS |
- | - | - |
RENDER |
- | - | - |
SLP |
Milliseconds | - | - |
HALT |
- | - | - |
CMP |
Register | Immediate Value, Register, or Memory Address | - |
RAND |
Register | - | - |
CTS instruction to clear the terminal screen and CLS to clear virtual screen.MOD instruction to easily check for even/odd numbers or perform modular arithmetic.CMP instruction is useful for conditional branching with JZ and JNZ.PRINTCH for ASCII output and PRINT for numeric output.DRAW, CLS, and RENDER for simple graphics.This project is open-source and available under the MIT License.
INKEYINKEY A reads a single key press (non-blocking) and stores the ASCII code of the pressed key in register A.A is set to 0.A == 0).