This is a 16-bit instruction set that operates on an "emulated" 32bit cpu, along with an assembler for a custom assembly language.
There are several included demo programs in the programs folder.
This is what an implementation of Collatz looks like in the assembly:
# Collatz Function .main mov r10 Enter an Integer:\0 pln r10 ini r0 mov r11 \0 mov r1 1 pln r11 parity_test: out r0 pln r11 cmp r0 r1 je finish_collatz mov r6 r0 mov r7 0 mod r6 2 cmp r6 r7 jg odd jmp even even: div r0 2 jmp parity_test odd: mul r0 3 add r0 1 jmp parity_test finish_collatz: #we done now boys mov r0 10 psh r0And this is what the 'machine code' looks like:
<<<===Main===>>> 0xff00 0xe30a Enter an Integer:\0 0xf40a 0xe200 0xe30b \0 0xe001 0x0001 0xf40b # Label: parity_test 0xdf00 0x0001 0xf000 0xf40b 0xd101 0xd200 0x0002 0xe160 0xe007 0x0000 0xa806 0x0002 0xd167 0xd400 0x0003 0xd000 0x0004 # Label: even 0xdf00 0x0004 0xa900 0x0002 0xd000 0x0001 # Label: odd 0xdf00 0x0003 0xa700 0x0003 0xa500 0x0001 0xd000 0x0001 # Label: finish_collatz 0xdf00 0x0002 0xe000 0x000a 0xeb00 Note: Anything prepended with # is a comment and is ignored when loading the program, and strings such as 'Enter an Integer:\0' and parsed into their constituent bytes when the program is loaded.
To build the program to you can run the build script, or run these commands:
mkdir bin g++ -std=c++17 -O3 src/cpu_main.cpp src/instr.cpp -o bin/cpu g++ -std=c++17 -O3 src/assembler_main.cpp src/assembler.cpp -o bin/assemblerTo run (assemble and execute) a test program:
bin/run programs/filename To run the sandbox assembly shell:
bin/ish To assemble one of the test programs:
bin/assembler programs/filename To run the compiled test programs:
bin/cpu programs/filename.inst Arithmetic:
0xA... /* r[C] += r[D] 0xA0.. */ /* add reg, int or reg */ /* r[C] -= r[D] 0xA1.. */ /* sub reg, int or reg */ /* r[C] *= r[D] 0xA2.. */ /* mul reg, int or reg */ /* r[C] %= r[D] 0xA3.. */ /* mod reg, int or reg */ /* r[C] += int 0xA4.. */ /* r[C] -= int 0xA5.. */ /* r[C] *= int 0xA6.. */ /* r[C] %= int 0xA7.. */ Bitwise:
0xC... /* r[C] &= r[D] 0xB0.. */ /* r[C] |= r[D] 0xB1.. */ /* r[C] << r[D] 0xB2.. */ /* r[C] >> r[D] 0xB3.. */ /* r[C] &= int 0xB4.. */ /* r[C] |= int 0xB5.. */ /* r[C] << int 0xB6.. */ /* r[C] >> int 0xB7.. */ Jumping:
Lable 0x1... 0xD... /* jmp 0xD000 */ /* cmp 0xD1.. */ /* jl 0xD300 */ /* jg 0xD400 */ /* jle 0xD500 */ /* jge 0xD600 */ Output:
OxF... /* cout r[D] 0xF00. */ /* mem dump 0xF100 */ /* reg dump 0xF200 */ /* cout@ptr 0xF30. */ /* cout@ptr\n 0xF40. */ /* cout@mem 0xF50. */ /* new line 0xF600 */ Input:
0xE... /* mov r[D],int 0xE0.. */ /* mov r[D],int 0xE1.. */ /* cin r[D],int 0xE20. */ /* mov r[D],str* 0xE30. */ /* mov r[D],mem 0xE4.. */ /* mov mem,r[C] 0xE5.. */ /* mov mem,r[D] 0xE6.. */ /* mov mem,int 0xE7.. */ /* cin r[D],str* 0xE80. */ /* mov r[D],*int[] 0xE90. */ Labels:
0x0 - 0x9 are labels for now Registers:
regs[0x0]->regs[0xF]