Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/remko/uxn.wasm
WebAssembly implementation of the Uxn virtual machine
https://github.com/remko/uxn.wasm
emulators uxn virtual-machines webassembly
Last synced: 3 months ago
JSON representation
WebAssembly implementation of the Uxn virtual machine
- Host: GitHub
- URL: https://github.com/remko/uxn.wasm
- Owner: remko
- License: mit
- Created: 2023-10-26T20:07:36.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-03-19T18:58:35.000Z (8 months ago)
- Last Synced: 2024-07-16T12:53:22.510Z (4 months ago)
- Topics: emulators, uxn, virtual-machines, webassembly
- Language: WebAssembly
- Homepage:
- Size: 242 KB
- Stars: 33
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-uxn - UxnWasm - WebAssembly implementation of the Uxn core. (Emulators)
README
# Uxn implementation in WebAssembly
[![Build](https://github.com/remko/uxn.wasm/actions/workflows/build.yml/badge.svg)](https://github.com/remko/uxn.wasm/actions/workflows/build.yml)
This is an implementation of the [Uxn](https://100r.co/site/uxn.html) virtual
machine in WebAssembly. It provides a drop-in replacement for the
[uxn5](https://git.sr.ht/~rabbits/uxn5) vanilla JS core.The [WebAssembly
module](https://github.com/remko/uxn.wasm/blob/master/src/uxn.wat) is generated
by [a script](https://github.com/remko/uxn.wasm/blob/master/scripts/emuwasm.js) that generates WebAssembly for the various instruction variants, based on hand-written raw WebAssembly for the base instructions, and does some small local optimizations on the generated code.Goals of this implementation (in descending order of priority) are:
- **Compliance**: Follows the Uxn specification to the letter. This includes
support for circular stacks and memory, which comes at the cost of speed (and
simplicity). Compliance is [tested](https://github.com/remko/uxn.wasm/actions/workflows/upstream-tests.yml) against the [Uxn opcode test suite](https://git.sr.ht/~rabbits/uxn-utils/tree/main/item/cli/opctest).
- **Simplicity**: The implementation needs to be understandable and maintainable.
When speed optimizations would come at the cost of too much complexity, I
don’t do them.
- **Speed**: Try to be as fast as possible. If implementation of instructions are
changed, check the impact on performance of the benchmarks (and
microbenchmarks) to understand the impact on speed.See [this blog post](https://mko.re/blog/uxn-wasm/) for some context,
implementation details, and benchmarks.## Installation
Uxn.wasm is part of the uxn5 distribution.
If you want to install a different version:1. Download `uxn-wasm.js` from [the Releases page](https://github.com/remko/uxn.wasm/releases).
2. Put `uxn-wasm.js` in the `src/` dir of [uxn5](https://git.sr.ht/~rabbits/uxn5).
3. Open uxn5 `index.html`, and check your browser JavaScript console that it loaded the WebAssembly core.## Using Uxn.wasm in JavaScript
You can use the core outside of uxn5, as a standalone way to run Uxn programs.
This package ships with extra utilities under the `util` submodule to easily run Uxn
programs, including an Uxntal assembler (`asm`), and utility devices (e.g. a `LogConsole`
console device that logs output to `console`).### Example
The example below runs a Uxntal program to compute prime numbers below 65536, and writes
them to the console.```javascript
import { Uxn } from "uxn.wasm";
import { asm, mux, LogConsole } from "uxn.wasm/util";(async () => {
const uxn = new Uxn();// Initialize the system with 1 device: a console at device offset 0x10 that
// logs output using `console.log`.
await uxn.init(mux(uxn, { 0x10: new LogConsole() }));// Assemble the program written in Uxntal assembly language into a binary ROM
// using `asm`, and load it into the core.
uxn.load(
asm(`
( Source: https://git.sr.ht/~rabbits/uxn/tree/main/item/projects/examples/exercises )|0100 ( -> ) @reset
#0000 INC2k
&loop
DUP2 not-prime ?&skip
DUP2 print/short #2018 DEO
&skip
INC2 NEQ2k ?&loop
POP2 POP2
( flush ) #0a18 DEO
( halt ) #010f DEO
BRK@not-prime ( number* -- flag )
DUP2 ,&t STR2
( range ) #01 SFT2 #0002 LTH2k ?&fail
&loop
[ LIT2 &t $2 ] OVR2 ( mod2 ) DIV2k MUL2 SUB2 ORA ?&continue
&fail POP2 POP2 #01 JMP2r &continue
INC2 GTH2k ?&loop
POP2 POP2 #00
JMP2r@print ( short* -- )
&short ( short* -- ) SWP print/byte
&byte ( byte -- ) DUP #04 SFT print/char
&char ( char -- ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
JMP2r
`)
);// Start running at the default offset (0x100)
uxn.eval();
})();
```## Development
### Building
make
### Running the tests
make test
### Running the benchmarks
make bench
### Running the tests & benchmarks in a browser
make dev
The tests and benchmarks can now be run from .