3.4 KiB
Wipforth
Wipforth is a Forth implementation that runs in the WebAssembly virtual machine. The system is bootstrapped from source on page load: the only non-text file is the favicon :)
I/O is done via memory-mapped peripherals, which are emulated in JavaScript.
- For the Forth kernel, see wipforth.ws
- For the emulator, see emu.js
- For the assembler, see asm.js
- For the prelude (Forth code loaded right after the kernel boots), see prelude.f
- For a description of the peripherals, see the Peripherals section below.
Building and Running Locally
There's a Guile script in the repo you can use for this:
guile server.scm
You should then be able to open http://localhost:8080 in a browser and use the system from there.
However, since everything is bootstrapped on the client, basically any
HTTP server will do as long as it sets the appropriate response
headers for SharedArrayBuffer use:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
So, if you don't have Guile on your system you can use something else
like Python's http.server.
NOTE: You should definitely not use server.scm to serve the
application on the open internet or anything like that; I just hacked
it together for testing on localhost during development and it's
probably hilariously insecure.
End-to-End Tests
There's a (fairly minimal at the moment) end-to-end test suite defined in tests.scm. To run it you'll need:
- Guile again (no substitute this time, sorry)
- guile-json
- Firefox
I'm also pretty sure it won't work on a non-POSIX system, though I haven't tried it.
Given that's all sorted, you should be able to run:
guile tests.scm
It will print a JUnit XML report to standard out. You can
pretty-print it with xmllint if you have it installed:
guile tests.scm | xmllint --format -
Peripherals
Terminal
| Name | Address | Size / B | Access |
|---|---|---|---|
| TXBUF | 000h | 32 | write |
| RXBUF | 080h | 32 | read |
| TXHEAD | 100h | 4 | atomic read |
| TXTAIL | 104h | 4 | atomic write |
| RXHEAD | 108h | 4 | atomic write |
| RXTAIL | 10Ch | 4 | atomic read |
For both sending (TX) and receiving (RX), there are three
registers: xBUF, xHEAD and xTAIL:
xBUFregisters are 128-byte FIFO ring buffers used for data- The
xHEADandxTAILregisters specify the start and end of data in the ring buffer,xHEADbeing the offset of the first byte of data, andxTAILbeing the offset of the first byte after the data.
In order to be distinguishable from the empty state, the ring buffers must never be completely full -- there must always be at least one unoccupied byte between the tail and the head.
System status
| Name | Address | Size / B | Access |
|---|---|---|---|
| SYSREADY | 110h | 4 | atomic write |
| SYSINTER | 114h | 4 | atomic read |
The SYSREADY register is used to indicate when the system has booted
up and is ready for user input. SYSINTER is set (and notified on)
once the emulator has enabled user input and the system is
interactive.