
This project implements a simplified 8-bit CPU architecture in C, along with an assembler, emulator, and a TUI-based visualization tool. It serves as an educational tool for understanding computer architecture, instruction sets, and low-level programming.
Clone the project by:
git clone https://github.com/empitrix/amethyst
cd ./amethyst
To build the project using gnu make
run:
make
After that you will have ./cpu
.
Note
currently this project is for unix-like operating systems only.
For example to use the project run:
./cpu -p ./examples/pattern.bin
Which executes the file pattern.asm
that generated by Assembler.
Or if you wish to see the instructions step by step use -s
flag:
./cpu -p ./examples/pattern.bin -s
In stepping mode if you press q
the program will end.
And to see how console works use -c
flag and hello.bin
program in examples/
which is running hello.asm
:
./cpu -p ./examples/hello.bin -c
- 16 bytes of RAM (Addresses
0x10
to0x1F
) - 256 words of ROM (Addresses
0x00
to0xFF
)
- 10 special-purpose registers (Addresses
0x00
to0x09
)- Register
0x06
: GPIO (General Purpose Input/Output)
- Register
BSF f, b
Description | Set bit (b ) at address (f ) to 1 |
Encoding | 0101 bbbf ffff |
Example | BSF GPIO, 0 |
BCF f, b
Description | Set bit (b ) at address (f ) to 0 |
Encoding | 0100 bbbf ffff |
Example | BCF GPIO, 0 |
GOTO k
Description | Goto given lable |
Encoding | 101k kkkk kkkk |
Example | GOTO start |
NOP
Description | No operation |
Encoding | 0000 0000 0000 |
Example | NOP |
MOVLW K
Description | Loads a literal (immediate) value into the W register. |
Encoding | 1100 KKKK KKKK (where KKKKKKKK is the 8-bit literal value) |
Example | MOVLW 03H |
MOVWF f
Description | Moves the contents of the W register to a specified register or memory location. |
Encoding | 0000 001F FFFF (where FFFFF is the 5-bit address) |
Example | MOVWF 06H |
CLRF f
Description | Clears (sets to 0) a specified register or memory location. |
Encoding | 0000 011F FFFF |
Example | CLRF 06H |
CLRW
Description | Clears the W register. |
Encoding | 0000 0100 0000 |
Example | CLRW |
SLEEP
Description | Puts the CPU into a standby mode. |
Encoding | 0000 0000 0011 |
Example | SLEEP |
DECF f, d
Description | Decrement register f and store the result back in f only if (d ) destination is 1 otherwise store the resutl into register W . |
Encoding | 0000 11dF FFFF |
Example | DECF 0x01, 1 |
DECFSZ f, d
Description | Decrement the contents of register f. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . If the result is 0 , skip the next instruction (which is already fetched) and execute a NOP instead. |
Encoding | 0010 11dF FFFF |
Example | DECFSZ 0x02, 1 |
INCF f, d
Description | Increment the contents of register f . If d is 0 , store the result in the W register. If d is 1 , store the result back in register f . |
Encoding | 0010 10dF FFFF |
Example | INCF 0x03, 1 |
INCFSZ f, d
Description | Increment the contents of register f. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . If the result is 0 , skip the next instruction and execute a NOP instead. |
Encoding | 0011 11dF FFFF |
Example | INCFSZ 0x04, 1 |
BTFSS f, b
Description | Test the bit b in register f . If bit b is 1 , skip the next instruction (which is already fetched) and execute a NOP instead. |
Encoding | 0110 bbbF FFFF |
Example | BTFSC 0x06, 2 |
BTFSC f, b
Description | Test the bit b in register f . If bit b is 0 , skip the next instruction (which is already fetched) and execute a NOP instead. |
Encoding | 0111 bbbF FFFF |
Example | BTFSC 0x06, 2 |
ADDWF f, d
Description | Add the value in W register to the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0001 11df ffff |
Example | ADDWF 0x06, 1 |
ANDWF f, d
Description | AND the value in W register with the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0001 01df ffff |
Example | ANDWF 0x06, 1 |
COMF f, d
Description | Complement the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0010 01df ffff |
Example | COMF 0x06, 1 |
IORWF f, d
Description | Inclusive OR the value in W register with the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0001 00df ffff |
Example | IORWF 0x06, 1 |
MOVF f, d
Description | Move content of the specified register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0010 00df ffff |
Example | MOVF 0x06, 0 |
RLF f, d
Description | Rotate the specified file register left through the Carry flag. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0011 01df ffff |
Example | RLF 0x06, 0 |
RRF f, d
Description | Rotate the specified file register right through the Carry flag. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0011 00df ffff |
Example | RRF 0x06, 0 |
SUBWF f, d
Description | Subtract the value in W register from the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0000 10df ffff |
Example | SUBWF 0x06, 0 |
SWAPF f, d
Description | Swap the upper and lower nibbles of the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0011 10df ffff |
Example | SWAPF 0x06, 0 |
XORWF f, d
Description | Exclusive OR the value in W register with the specified file register. If d is 0 , place the result in the W register. If d is 1 , place the result back in register f . |
Encoding | 0001 10df ffff |
Example | XORWF 0x06, 0 |
ANDLW k
Description | AND a literal value with the W register |
Encoding | 1110 kkkk kkkk |
Example | ANDLW 0b00000110 |
CALL k
Description | Call a subroutine. |
Encoding | 1001 kkkk kkkk |
Example | CALL start |
CLRWDT
Description | Clear the Watchdog Timer. |
Encoding | 0000 0000 0100 |
Example | CLRWDT |
IORLW k
Description | Inclusive OR a literal value with the W register. |
Encoding | 1101 kkkk kkkk |
Example | IORLW 05H |
OPTION
Description | Load the OPTION register. |
Encoding | 0000 0000 0010 |
Example | OPTION |
RETLW k
Description | Return from a subroutine and place a literal value in the W register. |
Encoding | 1000 kkkk kkkk |
Example | RETLW 07H |
TRIS f
Description | Load the TRIS register. |
Encoding | 0000 0000 0fff (0000 0000 0110 or 0000 0000 0111 ) |
Example | TRIS 07H or TRIS 06H |
XORLW k
Description | Exclusive OR a literal value with the W register. |
Encoding | 1111 kkkk kkkk |
Example | XORLW 12H |
Flag | Name | Description |
---|---|---|
-s |
Stepping Mode | Clock pulse with keyboard keys |
-f <num> |
Frequency | Clock frequency from 1 to 1000000 |
-p <path> |
Program | Path to .bin file from assembler |
-l <path> |
Load CPU state | Path to a .txt file that contains CPU's state |
-c |
Console | Enables the console and allows loggin for register 0x06 (GPIO) |
-i <num> |
CI Mode | Save CPU state at given position |
- If CPU state is loaded with
-l
don't need to use-p
to load a program to CPU, but make sure that the program is exists for CPU to load it.
This section displays ASCII characters directly from the CPU's GPIO port. To print a character, write its 7-bit ASCII code to the port and set the eighth bit (bit 7) to 1. The corresponding ASCII character will appear on the console.
MOVLW 'A' ; Load the ASCII code for 'A' into register W
MOVWF GPIO ; Write the value from register W to the GPIO port
BSF GPIO, 7 ; Set the eighth bit (bit 7) of the GPIO port to 1
- Press
s
to save the cpu's state to acpu_state.txt
file! - Press
<space>
to move to the next step instepping mode
. - Press
<space>
to pause/unpause CPU inauto mode
. - Press
r
to reset the cpu while CPU is inSLEEP
.
- Possible
seg fult
forupdate_console
in./src/emulator.c
when changing terminal size with high frequency so fast...