A strange little 16bit ISA/Architecture.
Run git clone https://github.com/l3gacyb3ta/super16.git && cd super16
, then run whatever command you like! Examples are bellow in the example commands section.
As I have not yet learned how to build an actual sim in logisim or similar software (so many sim-s!), I have implemented this ISA in python. After running assembler.py
with a valid asembly file as an argument, a pickle file named rom.pic will appear. In order to run it, simply execute cpu.py
for normal use, and slowpu.py
for debugging.
In order to compile to a binary that would run on a theoretical S16 cpu, simply invoke binaryassembler.py
with the asembley file as a parameter.
A set of example programs are provided in the tests/
directory. This is a great place to begin programming for S16. I have also included a script test.sh
to run a test file. To do that, simply run test.sh
and type the name (without .asm) of the file you want to run, and it should run.
- Running an assembly file:
$ python assembler.py tests/scrn.asm
$ python cpu.py
- Compiling to a binary:
$ python binaryassembler.py tests/scrn.asm
One instruction is composed of 32 bits, making up 3 catagories; Opcode, Register and data. The opcode is two hexadecimal digits, the register is another two, and the data is a 4-digit hexadecimal number split into two two-digit numbers. Here is an example instruction loading 0xf988
into r5
:
Opcode | Register | Data 1 | Data 2 |
---|---|---|---|
0x20 | 0x05 | 0xf9 | 0x88 |
The full list of opcodes, as well as an example, the instruction & explaination are as follows:
Opcode | Instruction | |
---|---|---|
0x10 | store | store reg reg2 |
Copy value from one reg to another | ||
0x20 | load | load reg val |
Load a value into a reg | ||
0x30 | add | add reg val |
Add value to reg | ||
0x31 | addr | addr reg reg2 |
Adds reg2 to reg | ||
0x40 | sub | sub reg val |
Subtracts val from reg | ||
0x41 | subr | subr reg reg2 |
Subtracts reg2 from reg | ||
0x50 | mul | mul reg val |
Multipy register by value | ||
0x51 | mulr | mul reg reg2 |
Multiply reg by reg 2 | ||
0x60 | div | div reg val |
Intiger divides the register by the value | ||
0x61 | divr | div reg reg2 |
Initger devides reg by rg2 | ||
0xff | prt | prt 0x0000 0x0000 |
Print ascii value in p0 reg | ||
0x0f | scrn | scrn 0x0000 val |
Set pixel in x8 and y9 regs to the value (0: black) (1: white) | ||
0xdd | drw | drw 0x0000 0x0000 |
Draw screen buffer | ||
0xf0 | cmp | cmp reg reg2 |
Set cm reg to 0x0001 if bigger, 0x0000 if smaller, and 0xffff if their equal | ||
0xb0 | branch | branch val label |
Branch to loop if cm is val | ||
0xb1 | nbranch | nbranch val label |
Branch to loop if cm is not val | ||
0xbb | jump | jump 0x0000 label |
Jump to label | ||
0x00 | noop | noop 0x000 0x000 |
Literally does nothing | ||
0xfe | halt | halt 0x0000 0x0000 |
Halts the cpu |