sola

Crates.iosola
lib.rssola
version0.1.0
sourcesrc
created_at2023-11-10 15:44:31.926508
updated_at2023-11-10 15:44:31.926508
descriptionA 16-bit stack machine and forth language
homepage
repository
max_upload_size
id1031279
size29,702
Louis Merlin (louismerlin)

documentation

README

sola

sola means 16 in Indo-Aryan languages.

So-la means perpetually in Solresol.

sola is a virtual stack machine inspired by Uxn. It uses an instruction format similar to the WISC CPU/16, with 16-bit addressing and 258 instructions (32 standard opcodes, 3 modes) as well as two circular stacks.

It is meant to be a personnal one-day computer in the idea of Chifir, a one-page, one-afternoon virtual machine.

Opcodes, Instructions and Modes

Literal values can be represented in decimal form (42, 1000, 51966), hexadecimal form (0x2A, 0x3e8, 0xcafe) or binary form (0b101010, 0b1111101000, 0b1100101011111110).

There are 25 opcodes, represented in the sola language by 25 different ASCII characters.

| Opcode   | Char | Instruction     | Definition               |
|----------|------|-----------------|--------------------------|
| `0xff00` | `#`  | Literal         | `( -- )`                 |
| `0xff01` | `+`  | Add             | `( a b -- a+b )`         |
| `0xff02` | `-`  | Subtract        | `( a b -- a-b )`         |
| `0xff03` | `*`  | Multiply        | `( a b -- a*b )`         |
| `0xff04` | `/`  | Divide          | `( a b -- a/b )`         |
| `0xff05` | `%`  | Modulo          | `( a b -- a%b )`         |
| `0xff06` | `^`  | Increment       | `( a -- a+1 )`           |
| `0xff07` | `=`  | Equal           | `( a b -- a==b )`        |
| `0xff08` | `~`  | NotEqual        | `( a b -- a!=b )`        |
| `0xff09` | `>`  | GreaterThan     | `( a b -- a>b )`         |
| `0xff0a` | `<`  | LessThan        | `( a b -- a<b )`         |
| `0xff0b` | `&`  | And             | `( a b -- a&&b )`        |
| `0xff0c` | `|`  | InclusiveOr     | `( a b -- a\|\|b )`      |
| `0xff0d` | `,`  | Shift           | `( a b -- a>>b8l<<b8h )` |
| `0xff0e` | `$`  | Jump            | `( addr -- )`            |
| `0xff0f` | `?`  | JumpConditional | `( addr bool -- )`       |
| `0xff10` | `\`  | Break           | `( -- )`                 |
| `0xff11` | `'`  | Pop             | `( a -- )`               |
| `0xff12` | `{`  | Swap            | `( a b -- b a )`         |
| `0xff13` | `}`  | Rotate          | `( a b c -- b c a )`     |
| `0xff14` | `"`  | Duplicate       | `( a -- a a )`           |
| `0xff15` | `_`  | Stash           | `( a -- )`               |
| `0xff16` | `.`  | Print           | `( a -- )`               |
| `0xff17` | `@`  | Get             | `( a -- ram[a] )`        |
| `0xff18` | `!`  | Set             | `( a b -- ram[b]=a )`    |
| `0xff19` | TBD  | TBD             | `( -- )`                 |
| `0xff1a` | TBD  | TBD             | `( -- )`                 |
| `0xff1b` | TBD  | TBD             | `( -- )`                 |
| `0xff1c` | TBD  | TBD             | `( -- )`                 |
| `0xff1d` | TBD  | TBD             | `( -- )`                 |
| `0xff1e` | TBD  | TBD             | `( -- )`                 |
| `0xff1f` | TBD  | TBD             | `( -- )`                 |

The undefined opcodes will probably be defined in the future as combinations of other opcodes often used together.

There are three modes, represented by the three highest bits of the opcode byte.

| Flag     | Prefix | Mode      | Effect                                                     |
|----------|--------|-----------|------------------------------------------------------------|
| `0xff20` | `#`    | Immediate | Uses the next value in RAM as the address or main argument |
| `0xff40` | `_`    | Return    | Uses the return stack instead of the work stack            |
| `0xff80` | `"`    | Keep      | Keeps the input values on the stack                        |

For example, #? my_word is an immediate conditional jump, popping a boolean from the work stack and conditionally jumping to the address immediately next in RAM, here the address of the definition of my_word.

Future additions to the language

sola lacks string literals. Strings will be surounded by `quotes` and null-byte terminated.

sola also lacks a way to write data directly to a rom, that is not intertwined with Literal opcodes. Raw data will be surounded by [ and ].

I/O

Gets (@) and sets (!) on values addressed [0; 255] will directly interact with the system sola is running on.

Right now, programs can set ASCII codes at address 5 to output an ASCII character into the terminal.

Future I/O interfaces will include setting event loops to interact with keyboard inputs, handing file i/o and stdin/stdout/stderr data.

Installing

Check out the binaries in the releases page.

Otherwise, if you have cargo, you can cargo install sola.

Building

Install Rust via any means you prefer.

Then, you can install or run this project using cargo.

cargo install --path .

If you're debugging the machine, there is a debug build flag configuration that you might find useful.

RUSTFLAGS="--cfg=debug" cargo run -r -- r software/10PRINT.rom

Run Hello World

sola assemble software/hello_world.sola
sola run software/hello_world.rom
Commit count: 0

cargo fmt