Tiny4CPU is a lightweight and educational 4-bit CPU emulator designed for simplicity. This project provides a hands-on exploration into the fundamentals of computer architecture, offering a platform to experiment with assembly language programming in a compact environment.
Dive into the world of microprocessors with Tiny4CPU and witness the power of 4 bits in action.
Code for the upper example:
; Usage of instruction OUT
; Init Register X to 0
Init:
LDX #0
; Main Loop
Loop:
ADX #1
OUT #0
JMP Loop- 4-bit architecture with its own assembler and disassembler
- 16-instruction set for data manipulation and control flow
- 2 general-purpose registers and memory space of 8 bytes
- Ability to adjust CPU clock cycles for synchronization in milliseconds
- Assembly language support
- Modular and extensible design
- Comprehensive documentation
- Examples for each instruction
Tiny4CPU programs are written in T4C Assembly and saved as *.t4c files.
Use the Tiny4CPU Assembler to assembly your program to a *.bin file.
After that, load your ROM *.bin file using the Tiny4CPU executable, including
the file path and the clock time in milliseconds.
The recommended clock time is 1000 milliseconds.
Example:
./assembler .../examples/output.t4c
./tiny4cpu .../examples/output.bin 1000Tiny4CPU has 16 opcodes (operation code, OP or instruction machine code),
which are all one byte long and stored big-endian. Big-endian means that
the most-significant-byte is saved in memory first (i.e. the lower memory address).
Currently only 10 of potentially 16 opcodes are defined.
| Mnemonic | Instruction | Description |
|---|---|---|
| LDX | 0000 kkkk | Load Register X with immediate nibble value k |
| LDY | 0001 kkkk | Load Register Y with immediate nibble value k |
| ADX | 0010 kkkk | Add immediate nibble value k to Register X |
| ADY | 0011 kkkk | Add immediate nibble value k to Register Y |
| SUX | 0100 kkkk | Subtract immediate nibble value k from Register X |
| SUY | 0101 kkkk | Subtract immediate nibble value k from Register Y |
| OUT | 0110 kkkk | Set output to nibble value from register (1) |
| JXZ | 0111 kkkk | Jump to memory address k if Register X is zero |
| JYZ | 1000 kkkk | Jump to memory address k if Register Y is zero |
| JMP | 1001 kkkk | Unconditional jump to memory address k |
| --- | 1010 | Unused |
| --- | 1011 | Unused |
| --- | 1100 | Unused |
| --- | 1101 | Unused |
| --- | 1110 | Unused |
| --- | 1111 | Unused |
(1) Use value #0 for Register X or value #1 for Register Y
| Register | Size (bits) | Description |
|---|---|---|
| PC | 4 | Program Counter |
| IR | 8 | Instruction Register |
| IAR | 8 | Instruction Address Register |
| ACC | 4 | Accumulator |
| MAR | 4 | Memory Address Register |
| RX | 4 | General-purpose register X |
| RY | 4 | General-purpose register Y |
- Mono-directional 4-bit address-bus from the microprocessor unit (MPU) to memory
- The memory layout consists of one Memory Address Register (MAR). The MAR is connected to two 2x4 decoder, enabling addressing of up to 16 memory locations
- Each memory location holds 4 bits of data, resulting in a total memory size of 8 bytes
