forked from PlaneteCasio/Casio_asm
127 lines
5.7 KiB
Markdown
127 lines
5.7 KiB
Markdown
|
# CASIO ASM
|
||
|
|
||
|
## What is this?
|
||
|
|
||
|
This is a language, assembler and interpreter designed to run on the CASIO calculators and computer alike.
|
||
|
This language is meant to be assembled, not compiled, and can be assembled on the computer or the calculator.
|
||
|
|
||
|
## Does it work?
|
||
|
|
||
|
Yes! Even though not everything works, it compiles and runs successfully with a few missing features.
|
||
|
|
||
|
Things that work:
|
||
|
* cross-platform support
|
||
|
* the assembler
|
||
|
* basic arithmetic operation
|
||
|
* the docs, I hope
|
||
|
|
||
|
Things that partially work:
|
||
|
* the file support
|
||
|
..* some problems with files opened RW
|
||
|
* the keyboard
|
||
|
..* on calculator, it is working, except the AC key
|
||
|
..* on PC, only EXE, EXIT and the arrow keys work
|
||
|
* the graphical library
|
||
|
..* lines and rectangles work
|
||
|
..* circles are glitchy if you use XOR mode
|
||
|
..* structural changes are to come
|
||
|
* the interpreter
|
||
|
..* crashes after three program runs on calculator, but you can exit and re-open the addin
|
||
|
..* missing some instructions
|
||
|
|
||
|
Things to rework:
|
||
|
* the licence, I'd like to put it under MIT or GPL, but for now, no licence
|
||
|
..* and if anyone has a better idea, tell me
|
||
|
* this file, README.md
|
||
|
..* may not be up to date, like at all
|
||
|
* the interrupt system
|
||
|
..* getting an interrupt while in the interrupt handler sometimes crashes
|
||
|
* the build system
|
||
|
..* seriously, make clean all the time to make it work?
|
||
|
* the addin icon
|
||
|
* the addin loader
|
||
|
..* and the linker script
|
||
|
..* because I can't declare a `char[3]` without crashing
|
||
|
..* nor can I use `static int i=3`, as it will be set to `0x55555555` instead
|
||
|
* the code, in general
|
||
|
..* no, seriously, I wanted it to run, and now it's a mess
|
||
|
|
||
|
Things that don't work at all:
|
||
|
* timers
|
||
|
* Gint support
|
||
|
..* but it will be so much cleaner when I get it to work!
|
||
|
* Windows support
|
||
|
..* missing file lib, so no programs to load, much less execute
|
||
|
..* but probably works on Cygwin and WSL
|
||
|
|
||
|
## The syntax
|
||
|
|
||
|
A program is a list of instructions separated by a newline, and the file **MUST** end with a newline.
|
||
|
Whitespace characters are omitted between instructions.
|
||
|
An instruction can be either:
|
||
|
1. A mnemonic
|
||
|
2. A mnemonic and arguments
|
||
|
3. A label
|
||
|
4. A comment
|
||
|
|
||
|
Labels start with a dot and may not be longer than 20 characters. They may contain alphanumeric characters and underscores, but may not start with a number.
|
||
|
Mnemonics are listed in `data/opcode.list` along with their description.
|
||
|
Comments start with a quote (single or double) or a pipe, and are ignored entirely.
|
||
|
Mnemonics and arguments are to be separated by comas or semicolons.
|
||
|
|
||
|
## The processor
|
||
|
|
||
|
The interpreter acts like a 32-bit big-endian processor capable of handling integral values `int` and decimal values `float`.
|
||
|
This processor has 256 32-bit registers, #00 to #ff which can hold either a float or an int.
|
||
|
Care must be taken by the user not to operate on the wrong data type, as the processor itself doesn't know what type of data is stored in the registers.
|
||
|
This emulated processor stores its program counter `PC` in register #00, which should not be written directly.
|
||
|
|
||
|
## The stack
|
||
|
|
||
|
This processor is attached to a stack which is where arguments are taken when not directly supplied, and where the return values are pushed.
|
||
|
This stack can contain up to 256 values, and will silently ignore illegal push or pop operations.
|
||
|
This stack follows the last in first out principle `LIFO`, and handles a few basic operations:
|
||
|
1. Push which adds a value on top of the stack
|
||
|
2. Pop which removes and returns the value currently on top of the stack
|
||
|
3. Top which returns the number of values currently in the stack
|
||
|
|
||
|
## The MMU
|
||
|
|
||
|
This processor is attached to a memory management unit `MMU` which handles virtual memory, which can be manipulated with `ext` instructions or set at startup time.
|
||
|
Virtual memory types include:
|
||
|
1. The ROM, which is just the assembled program
|
||
|
2. RAM segments
|
||
|
3. The stack
|
||
|
4. Files, either RO or RW
|
||
|
5. The VRAM
|
||
|
6. Basically anything permitted by the `ext` instruction
|
||
|
|
||
|
## Interrupts
|
||
|
|
||
|
The emulated processor supports interrupts, which can be triggered by hardware, the interpreter itself or by the program.
|
||
|
When an interrupt is triggered, the processor will push the `PC` on the stack, followed by the interrupt data and the interrupt code. The processor will then jump to the interrupt handler.
|
||
|
Hardware interrupts may include:
|
||
|
1. Key press
|
||
|
2. Timers
|
||
|
|
||
|
Interpreter interrupts include:
|
||
|
1. Illegal operation
|
||
|
2. Segmentation error
|
||
|
|
||
|
Hardware interrupts may be subscribed or not, and by default are ignored. Interpreter interrupts will always be triggered when their conditions are met.
|
||
|
The interrupt handler **MUST** be set using the `inth` instruction and point to executable memory, otherwise any interrupt will crash the program.
|
||
|
The program may raise a software interrupt with the `int` instruction.
|
||
|
|
||
|
## Instructions
|
||
|
|
||
|
Instructions are variable-length instructions, and can be anywhere between 8-bit and 32-bit long.
|
||
|
Instructions fall in two categories, regular and extended instructions:
|
||
|
1. Regular instructions consist of 2 bits describing the arguments type, 6 bits representing the opcode, and up to two bytes of arguments
|
||
|
2. Extended instructions are like regular instructions, but the 6-bit opcode is set to all ones, and there's a 8-bit opcode as the second byte, followed by up to two bytes of arguments
|
||
|
|
||
|
Instructions may use the following argument types:
|
||
|
1. None: all required arguments are popped from the stack
|
||
|
2. One: One argument is taken from a register, the others are popped from the stack
|
||
|
3. Two: Two arguments are taken from registers, and the others are popped from the stack
|
||
|
4. Immediate: One argument is read as a 16-bit immediate value, the others are popped from the stack
|