Update Sphinx docs with v0.15.0 Hardware I/O Simulator, bump version

This commit is contained in:
Eremey Valetov
2026-03-28 18:30:04 -04:00
parent e100290dd3
commit d69c46330c
6 changed files with 66 additions and 38 deletions
+4 -3
View File
@@ -49,15 +49,16 @@ HAL writes straight to stdout.
| INPUT/LINE INPUT | `input.c` | BINTRP.ASM |
| Sound engine | `sound.c` | — |
| Virtual memory (PEEK/POKE) | `virmem.c` | — |
| Hardware I/O ports | `portio.c` | — |
| Platform abstraction | `hal_posix.c` | OEM*.ASM |
## Source Layout
```
src/ — core interpreter (21 files)
include/ — headers (13 files)
src/ — core interpreter (22 files)
include/ — headers (14 files)
platform/ — HAL backends (1 file)
tests/ — 66 automated test programs, 4 classic interactive programs, compat harness
tests/ — 70 automated test programs, 4 classic interactive programs, compat harness
docs/ — Sphinx documentation
```
+6 -5
View File
@@ -18,10 +18,11 @@
| 0.12.0 | | BSAVE/BLOAD, TUI ANSI 16-color rendering, CGA graphics framebuffer PEEK/POKE, keyboard shift flags |
| 0.13.0 | | VIEW/WINDOW/PALETTE graphics, PMAP function, MBF float format for CVS/CVD/MKS$/MKD$ |
| 0.14.0 | | MBF binary file compatibility (IEEE↔MBF at save/load boundary), fix binary loader null-byte truncation, fix DRAW M/S/A bugs, add TA/=var;/X substring |
| 0.15.0 | | Hardware I/O simulator: OUT/INP/WAIT/MOTOR statements, port emulation (8253 PIT, PPI speaker, CGA mode/color, COM1, game port), continuous tone via PulseAudio |
## Tests
68 test programs in `tests/programs/`, plus 4 classic interactive programs in
70 test programs in `tests/programs/`, plus 4 classic interactive programs in
`tests/classic/` (Hamurabi, Lunar Lander, Gunner, Diamond from David Ahl's
*BASIC Computer Games*).
@@ -31,10 +32,10 @@ Run the full automated suite:
bash tests/run_tests.sh
```
Each test has a 5-second timeout. 62 tests have `.expected` golden files
for output regression detection. Three timing-dependent tests (datetime,
on_timer, timer_stop) and one visual test (color_test) run without golden
comparison.
Each test has a 5-second timeout. 65 tests have `.expected` golden files
for output regression detection. Tests without golden comparison: datetime,
on_timer, timer_stop (timing-dependent), color_test (visual), play_music
(audio duration).
### Compatibility Testing
+5 -2
View File
@@ -19,12 +19,15 @@ version is structured as modular C suitable for new feature development.
- **INKEY$ extended keys** — arrow keys, F-keys, and navigation keys return proper
`CHR$(0)` + scan code two-byte sequences
- **Sixel graphics** — `SCREEN 1`/`SCREEN 2` rendering in compatible terminals
- **Sound** — `SOUND`, `BEEP`, `PLAY` (MML) via PulseAudio
- **Sound** — `SOUND`, `BEEP`, `PLAY` (MML) via PulseAudio, plus continuous tone
via `OUT` (8253 PIT / PPI speaker emulation)
- **Hardware I/O** — `OUT`, `INP`, `WAIT` port emulation (PIT, PPI, CGA, COM1,
game port) for classic programs that drive hardware directly
- **Full file I/O** — sequential, random-access, SAVE/LOAD/MERGE/CHAIN/COMMON
- **Printer output** — `LPRINT`/`LLIST` to file or real hardware via `--lpt`
- **Classic programs** — Hamurabi, Lunar Lander, Gunner, and Diamond from
David Ahl's *BASIC Computer Games* (1978) run out of the box
- **66 test programs** with golden-file regression testing and DOSBox-X
- **70 test programs** with golden-file regression testing and DOSBox-X
compatibility testing against real GWBASIC.EXE
- **MIT License**
+37
View File
@@ -60,6 +60,7 @@ type suffixes (`%`, `!`, `#`)
| Graphics | `PSET`, `PRESET`, `LINE`, `CIRCLE`, `DRAW`, `PAINT`, `GET`, `PUT`, `VIEW`, `WINDOW`, `PALETTE`, `PMAP` |
| Sound | `SOUND`, `BEEP`, `PLAY` (MML parser, PulseAudio backend) |
| Memory | `DEF SEG`, `PEEK`, `POKE`, `BSAVE`, `BLOAD` |
| Hardware I/O | `OUT`, `INP`, `WAIT`, `MOTOR`, `STICK`, `STRIG` |
| Misc | `KEY`, `TRON`/`TROFF`, `OPTION BASE`, `MID$` assignment |
| System | `SYSTEM` |
@@ -222,6 +223,42 @@ The file format is compatible with the original GW-BASIC: byte 0 = `0xFD`,
bytes 1-2 = segment (LE), bytes 3-4 = offset (LE), bytes 5-6 = length (LE),
followed by the raw data bytes.
## Hardware I/O (OUT / INP / WAIT)
`OUT`, `INP`, and `WAIT` provide access to emulated IBM PC I/O ports, enabling
classic programs that drive hardware directly — speaker tones via the 8253 PIT,
CGA palette tricks, and serial port polling.
```
OUT &H43, &HB6 ' PIT channel 2: lobyte/hibyte, mode 3
OUT &H42, &HD3 : OUT &H42, &H04 ' set frequency divisor (1235 → 966 Hz)
OUT &H61, INP(&H61) OR 3 ' speaker on
OUT &H61, INP(&H61) AND &HFC ' speaker off
```
### Emulated Ports
| Port | Device | Behavior |
|------|--------|----------|
| `&H42``&H43` | 8253 PIT channel 2 | Speaker frequency divisor (1193180 / divisor Hz) |
| `&H61` | PPI Port B | Bits 01 control speaker; both set = tone on, either clear = off |
| `&H3D8` | CGA mode control | Mode register; writes with changed mode bits trigger `SCREEN` changes |
| `&H3D9` | CGA color select | Background color (bits 03) and palette select (bit 5) |
| `&H201` | Game port | Returns `&HF0` (no joystick connected) |
| `&H3F8``&H3FE` | COM1 serial | Minimal stub; LSR (`&H3FD`) returns `&H60` (transmitter ready) |
| Default | — | Reads return `&HFF` (floating bus), writes silently discarded |
### Related Functions
- `INP(port)` — read a byte from an I/O port
- `STICK(n)` — joystick axis position (returns 128 = center, n = 03)
- `STRIG(n)` — joystick button state (returns 0 = not pressed)
- `WAIT port, mask [, xor_mask]` — busy-wait until `(INP(port) XOR xor_mask) AND mask` is nonzero; Ctrl+C breaks out
- `MOTOR [n]` — accepted and silently ignored (cassette motor control)
When the PPI speaker bits are set, the PIT frequency divisor is used to
generate a continuous tone via PulseAudio (same backend as `SOUND` / `PLAY`).
## Sound
- `SOUND frequency, duration` — play a tone (frequency in Hz, duration in clock ticks)
+13 -27
View File
@@ -8,35 +8,21 @@
But we've come this far, so why not? Likely approach: translate the token
stream to C and lean on GCC/Clang for the heavy lifting.
## Completed
### Hardware I/O Simulator (v0.15.0)
Implemented in `portio.c` / `portio.h` following the `virmem.c` dispatch
pattern. Emulates 8253 PIT channel 2 (speaker frequency), PPI port B
(speaker on/off with continuous tone via PulseAudio), CGA mode/color
registers, game port (joystick stub), and COM1 serial (transmitter-ready
stub). Default: reads return 0xFF (floating bus), writes discarded.
Statements: `OUT`, `WAIT`, `MOTOR`. Functions: `INP()`, `STICK()`, `STRIG()`.
## Next Up
### Hardware I/O Simulator
An optional emulation layer for `OUT`, `INP`, `WAIT`, `MOTOR`, and friends,
following the established `virmem.c` dispatch-by-address pattern.
**New module:** `portio.c` / `portio.h` with `portio_inp(port)` /
`portio_out(port, value)` dispatch.
**Priority ports:**
| Port | Device | Emulation |
|------|--------|-----------|
| 0x420x43 | 8253 PIT channel 2 | Speaker frequency divisor (1193180 / divisor Hz) |
| 0x61 | PPI Port B | Speaker on/off (bits 01), routes to `snd_start_continuous()` / `snd_stop_continuous()` |
| 0x3D8 | CGA mode control | Mode register storage, feeds `gfx_init()` |
| 0x3D9 | CGA color select | Palette/background bits, feeds `gfx_palette_set()` |
| 0x201 | Game port | Joystick stub (returns 0xF0 = no buttons) |
| 0x3F80x3FE | COM1 serial | Minimal stub (LSR reports transmitter ready to prevent spin loops) |
| Default | — | Reads return 0xFF (floating bus), writes silently discarded |
**Statement/function changes:**
- `OUT port, value``portio_out(port, value)`
- `WAIT port, mask [, xor_mask]` → busy loop with `portio_inp()`, break check, timeout
- `MOTOR` → accept and silently ignore
- `INP(port)``portio_inp(port)` (currently returns 0)
- `STICK(n)` / `STRIG(n)` → joystick state from port 0x201
*(Looking for the next major feature — see IDE and Notebook Integration below.)*
## IDE and Notebook Integration
+1 -1
View File
@@ -10,7 +10,7 @@
#include "gw_math.h"
#include "strings.h"
#define GW_VERSION "0.14.0"
#define GW_VERSION "0.15.0"
#define GW_BANNER "GW-BASIC " GW_VERSION
/* Tokenizer */