SolarOS

Native extensions

SolarOS Modules

Native modules extend SolarOS with applications, background jobs, hardware drivers, and reusable libraries. Browse the catalog below, or connect your device to Wi-Fi and open the package manager:

pkg

Native modules require an ESP32-S3 device with PSRAM and native-module support enabled in its firmware. Each module can have additional requirements, shown in its catalog entry.

Install and manage modules

Use these shell commands to check your system, list packages, and manage installed modules. Replace MODULE-ID with the ID shown in the module details:

pkg system
pkg available
pkg installed
pkg install MODULE-ID
pkg remove MODULE-ID

pkg checks the signed catalog against the device's exact SolarOS version, ESP target, and native ABI. It verifies each package's size and SHA-256 before installation. A module listed here may not yet have a published package for your firmware; use pkg available to see what you can install on your device.

Run a module

Installed applications run by module ID from the shell. Background jobs use the job commands, and driver modules register expansion drivers. Libraries load when a consumer acquires their API. Open a module's details for its controls, required assets, and usage.

See the native module guide, native media interfaces, and foreground app guide for the supported interfaces.

Official module catalog

Explore the modules.

6 modules in 2 categories. Select a module to read its requirements and usage.

Applications

Libraries

Application · Version 0.2.0 · ESP32-S3 · Requires PSRAM, graphics

Apple II Plus foreground app

External SolarOS foreground app based on Reinette II Plus. Upstream snapshot: b272efd (2023-09-10). MIT notices and the license are retained under main/vendor. Apple II Plus and Disk II firmware ROMs are embedded in the module; see ROM provenance. Disk images are supplied separately.

The module emulates an Apple II Plus with 64 KiB RAM including the language card, 40-column text, lores/hires and mixed graphics, two Disk II drives, paddles and the speaker. It supports NIB disk images. Undocumented CPU opcodes act as NOPs. The font is derived from upstream assets/font-normal.bmp.

Build with ESP-IDF 5.5 for ESP32-S3:

idf.py set-target esp32s3
idf.py build
cmake --build build --target typed_elf

The manifest declares a resumable GUI app, a 16 KiB worker stack and priority 1. Launch admission checks its internal-memory and PSRAM requirements.

Artifact: build/solaros_native_apple2.app.elf. Copy it to storage and run:

load /sdcard/solaros_native_apple2.app.elf /sdcard/apple2/dos33.nib

Use pkg install apple2 to install from the module catalog, or copy the artifact to /sdcard/modules/apps/apple2.elf. Start BASIC or boot one or two disks:

apple2
apple2 dos33.nib
apple2 dos33.nib data.nib
session create apple2 display0 /sdcard/apple2/dos33.nib

No separate ROM files are needed. NIB images must be exactly 232960 bytes. Disk paths are relative to the launching shell's current directory, or absolute. The existing apple2 <disk-directory> [drive1.nib] [drive2.nib] form also works; relative disk names then use that directory. Files opens .nib images with the installed module. The firmware must provide resolve_path.

F1 saves drive 1; Alt+F1 saves drive 2. F2 shows status, F3 toggles disk acceleration, F4 mutes, F10 pauses, F11 resets the guest, and F12 shows help. Ctrl+Alt+Del or Ctrl+] exits to the SolarOS shell. Exit discards unsaved disk changes. The module requires firmware providing the foreground stop_requested callback. See the Apple II Plus user guide and native app reference.

Alt+Tab or Alt+Right switches to the next SolarOS session; Alt+Left switches to the previous session. Resume with these shortcuts or session fg ID. Switching pauses the guest and releases display, keyboard and audio resources; CPU, RAM and disk state, including unsaved changes, remain allocated. F10 pause is retained across session switches. The firmware must provide enable_suspend, suspend_requested and suspend.

The module uses the SolarOS foreground app service for display, keyboard, storage, timing and optional audio. Text and overlays follow terminal colors on color displays and use black on white on monochrome displays. Graphics retain their Apple II palettes. Native color displays use black aspect-ratio bars. The firmware must provide text_colors and video_open_ex. Changed frames are submitted asynchronously at up to 25 Hz. F2 includes guest speed, interpreter throughput and frame-rendering time.

Package commands

Module ID: apple2.

pkg available
pkg install apple2

Application · Version 0.1.0 · ESP32-S3 · Requires PSRAM, graphics

DOOM foreground app

External SolarOS ESP32-S3 app based on Espressif's esp32-doom revision 085f21b630f11adb69a3894db5a1efa39a7aa31a (PrBoom 2.5.0). The engine, tables, authors and GPL license are retained in main/vendor. The SolarOS adapter is GPL-2.0-or-later. No game WAD is bundled.

Build and launch

Build with ESP-IDF 5.5 for ESP32-S3, from this directory:

idf.py set-target esp32s3
cmake --build build --target typed_elf

Copy build/solaros_native_doom.app.elf to /sdcard/modules/apps/doom.elf, and supply a DOOM or DOOM II IWAD:

doom /sdcard/doom/doom1.wad
load /sdcard/solaros_native_doom.app.elf /sdcard/doom/doom1.wad
session create doom display0 /sdcard/doom/doom1.wad

Only one IWAD argument is accepted. PWAD overlays, DeHackEd patches, networking, music, savegames and persistent configuration are unsupported. The WAD remains on storage; keep it mounted and unchanged while the app is running or suspended. The game uses a 320x240 indexed frame, fitted by the host presenter. Palette flashes are converted to a fixed RGB332 palette. Monochrome output uses the host's display conversion. Missing PrBoom color tables use identity mappings; missing alternate HUD artwork uses the IWAD's original font. Vanilla IWADs use the standard engine switch and animation definitions when the Boom SWITCHES and ANIMATED tables are absent.

Sampled sound effects use the selected SolarOS audio output and global speaker level. The module mixes the engine's sound channels into stereo PCM, with resampling, distance attenuation and stereo positioning. The game's sound volume controls its mixer gain. An unavailable or busy audio output leaves the game usable silently. The IWAD must contain DS* digital sound lumps; Espressif's doom1-cut.wad omits them. Use an uncut shareware or owned full-game IWAD for sound effects. Music remains disabled.

Controls: arrow keys move/turn, Ctrl fires, Space uses doors/switches, Shift runs, Alt strafes, comma/period strafe left/right, 1–7 select weapons, Tab opens the map, Escape opens the menu, and Enter selects. Use a keyboard that supplies key releases for held actions. Text-only key sources provide taps.

SolarOS session shortcuts suspend the game. Resume retains game state, clears held keys, excludes suspension time from the game clock, and redraws the frame. Ctrl+] or session close ID closes it and releases all module allocations.

If a replacement ELF changes the app's resource declaration, reboot SolarOS before launching it. App discovery retains that declaration until restart.

The manifest declares a resumable GUI app, a 24 KiB worker stack, priority 1, 8 KiB free internal memory and 4 MiB free PSRAM minimum. These are launch admission checks, not reserved memory or a guarantee that every IWAD fits. The adapter uses only versioned SolarOS services and initializes no peripherals. Its PCM callback runs on the host audio worker and is joined before suspension or unload. Resume reopens the selected output and continues retained samples.

Source and validation

main/vendor/prboom and main/vendor/tables come from the revision above. i_main.c retains upstream platform startup; i_sound.c supplies the SolarOS sampled-effects backend. Local engine changes replace raw zone allocation, preserve integer booleans with SolarOS headers, remove hardware/IRAM headers, and supply fallbacks for optional PrBoom artwork and colormap markers, standard switch and animation tables, and cooperative checks during translucency-map generation. The table defaults reproduce the engine definitions in upstream's cut WAD. The adapter supplies tracked PSRAM, bounded read-only WAD access with an unlocked-lump cache, fixed-palette video, keyboard events, time, cooperative lifecycle checks and trapped engine exits. The DeHackEd translation unit supplies engine string defaults; patch processing is rejected by the adapter. Process-wide stdio and configuration access are disabled. Pure string helpers and libm are linked into the module.

Run the host tests from the SolarOS repository root:

python3 -m unittest discover -s tests -p test_doom_module.py
SOLAR_OS_DOOM_TEST_WAD=/path/to/doom1.wad python3 -m unittest discover -s tests -p test_doom_module.py

The optional IWAD fixture must contain Episode 1 and standard DOOM menus; digital sound lumps enable the audio integration cases. The host checks exercise gameplay, keyboard input, suspend/resume, close, sample mixing, resampling, malformed samples and directories, short reads, allocation failures and cleanup. Hardware frame rate, display behavior and memory availability depend on the selected device.

Package commands

Module ID: doom.

pkg available
pkg install doom

Library · Version 3.3.13 · ESP32-S3 · Requires PSRAM

ESP-DL inference library

The espdl resident library supplies the ESP32-S3 inference engine for firmware that enables service.inference without backend.inference-espdl. It uses ESP-DL 3.3.13 with the configured SDK operator registry, including single, auto, and dual-core execution. It accepts validated, unencrypted, single-model EDL1/EDL2 buffers. File access, bundle validation, input adapters, model admission, and scripting APIs belong to the firmware frontend.

Usage

Mount storage and install from the signed catalog for your firmware version:

pkg install espdl
model backend
model load /sdcard/model.espdl

The library loads when the frontend first loads a model. Each model holds a lease until it closes and its workers finish. After closing all models, pkg unload espdl releases library code and runtime allocations without removing the installed file. pkg remove espdl also removes the file. Built-in firmware always uses its built-in engine. See Model inference for Python, Lua, native clients, bundles, and execution modes.

Build and catalog

Use the project's ESP-IDF 5.5 toolchain with GCC 14.2.0 and PlatformIO installed:

python3 modules/espdl/build.py

Outputs are .pio/modules/espdl/espdl.library.elf, arithmetic and vision probes, a debug ELF, and build.json with artifact hashes. The builder configures a separate SDK under .pio/espdl-sdk/build/<environment> using a generated copy of full with inference_backend enabled, then builds the ESP-DL and schema archives. It creates the compile commands automatically and refreshes the SDK on later runs. It does not compile or flash a firmware image or edit the checked-in flavor files.

--environment selects an ESP32-S3 PlatformIO environment; --output selects a folder. SOLAROS_PIO can select the PlatformIO executable. To reuse an already prepared SDK instead, pass --sdk-build-dir /path/to/build/<environment>; it must contain both archives and ESP-DL compile commands from a build with the backend enabled. The standard full flavor uses downloadable inference and does not supply these prerequisites by itself. CMake's typed_elf target wraps the same builder. CID's module deployment pipeline accepts this module's module.toml, validates imports and ELF structure, and signs the catalog. SOLAROS_ESPDL_ENVIRONMENT selects the SDK environment during deployment.

The builder makes private archive copies, replaces only the worker dispatcher, binds C++ symbols within the library, and verifies the final stripped ELF's imports and mapped relocations. Its only imports are the library host and memcpy, memmove, memset, memcmp, and strlen. The firmware ownership patch must be present in the SDK archives; the builder rejects unpatched sources.

The private runtime manages constructors, finalizers, exception frames, tracked allocations, and exception TLS. Dual workers use versioned host synchronization and joined internal stacks. Exceptions stay inside the provider; copied output buffers belong to the host and may outlive the model and library. Unavailable file/partition/crypto paths cannot be used by this buffer-only interface. Toolchain upgrades require review of exception-frame relocation and runtime layout.

The frontend transfers its aligned model-file allocation to providers that support load_owned_buffer, avoiding a second file-sized allocation during load.

Model weights and tensor descriptors remain loaded between calls. Activation workspace is acquired for each inference and released after its outputs are copied, including cancellation and error paths. Image decoding and other idle work can use that space between calls. Loaded-model memory estimates exclude the released workspace; execution still needs a contiguous workspace block. The original borrowed-buffer operation still copies its input. Both paths free the owned model source when the model closes, including failed construction.

Hardware checks

The arithmetic probe checks scalar int8, float32, SIMD int8, all execution modes, cancellation, oversized workspace rejection, leases, copied-output lifetime, and 15 complete library/model cycles:

python3 tests/hil/espdl_library.py --telnet DEVICE_ADDRESS \
  --artifacts .pio/modules/espdl --output .pio/espdl-arithmetic-check

Upload mode requires FTP, refuses an existing espdl install, uses unsigned maintainer ELFs, and removes only its own uploads. --installed --probe PATH uses staged files and leaves them in place.

For real-model parity, supply compatible vision models explicitly:

python3 tests/hil/inference_backends.py --telnet DEVICE_ADDRESS \
  --probe .pio/modules/espdl/espdl-vision-check.app.elf \
  --model /path/to/face-model.espdl --model /path/to/classifier.espdl \
  --output .pio/espdl-baseline --keep-fixtures

After changing to firmware without a built-in engine and installing the signed library, repeat with --installed .pio/espdl-baseline/fixtures.json and --expected .pio/espdl-baseline/results.json. The probe exercises typed inputs, all execution modes, cancellation/recovery, output parity, and worker teardown. Use --cleanup --installed PATH to remove retained fixtures. Firmware flashing and catalog hosting are separate maintainer actions.

Measured inference timing includes cooperative layer delays. Compare equivalent frontend workloads; these probes do not establish camera throughput or detector accuracy on images. Model files, workspace, copied outputs and loaded code all consume PSRAM; externalization saves firmware flash, not active inference RAM.

Package commands

Module ID: espdl.

pkg available
pkg install espdl

Application · Version 0.1.0 · ESP32-S3 · Requires PSRAM, graphics

Game Boy foreground app

External SolarOS app using the vendored Peanut-GB CPU core, ROM validator, packed video conversion and MiniGB APU. The original licenses are in main/vendor/peanut_gb. No ROM images are bundled.

Build with ESP-IDF 5.5 for ESP32-S3:

idf.py set-target esp32s3
idf.py build
cmake --build build --target typed_elf

Artifact: build/solaros_native_gameboy.app.elf. Install from a compatible catalog with pkg install gameboy, or copy the artifact to /sdcard/modules/apps/gameboy.elf. Launch from a display shell:

gameboy /sdcard/roms/game.gb

You can also use session create gameboy display0 /sdcard/roms/game.gb or load /sdcard/gameboy.app.elf /sdcard/roms/game.gb.

Files opens .gb ROMs through the installed app's file association.

Arrow keys control the directional pad. The physical US-Z key position and X are A and B; the US-Z key is labeled Y on German QWERTZ keyboards. Enter is Start, and Backspace/Delete is Select. Character-only input pulses buttons for 140 ms. P pauses, R resets, and Q, Escape or Ctrl+] exits. On boards with a buttons input source, Enter is A, Space is B, the app-exit button is Start and Escape is Select; pressing Start and Select together exits.

Session switching retains guest CPU, RAM, cartridge RAM, pause state and APU state. Display and audio are released for the other foreground app. Resume clears held inputs and rebases frame timing. Closing writes modified cartridge RAM to a .sav file alongside the ROM using atomic replacement. Existing saves are loaded on launch; a size mismatch is reported. Reset preserves cartridge RAM.

The module accepts original Game Boy ROMs up to 4 MiB. Color-only ROMs and unsupported cartridge controllers are rejected. Video uses packed INDEX2 frames at up to 25 presented frames/s. The guest frame period is 16743 microseconds, with at most three catch-up frames. Audio uses MiniGB at 16 kHz stereo with gain 4 through the host synth service; unavailable audio leaves emulation running.

The foreground manifest declares an 8 KiB worker, priority 2, 16 KiB of internal memory and 256 KiB of PSRAM for admission. ROM and cartridge allocations are checked at launch. Hot core/APU state prefers internal RAM and can fall back to PSRAM. Two optional 16 KiB internal ROM caches preserve the OS reserve. See the foreground app contract. The Game Boy user guide covers installation, controls, and save files.

Package commands

Module ID: gameboy.

pkg available
pkg install gameboy

Application · Version 0.1.0 · ESP32-S3 · Requires PSRAM, graphics

Macintosh Plus foreground app

External ESP32-S3 SolarOS app based on epatel/esp32_mac, revision eaffb010eee2267672f1f766fcc4c5eb80cb5baa. The Musashi 68000 core, VIA, SCC, RTC, mouse and SCSI controller run in the SolarOS foreground worker. No Arduino, BLE server, board driver, SD mount, flash partition or separate emulator task is initialized by this module.

The guest has 4 MiB RAM, a monochrome screen matching the selected display, keyboard, keyboard-controlled mouse, and one optional SCSI disk or floppy. Audio and LocalTalk are not implemented. The IWM remains a stub; floppy access uses the replacement Sony driver described below. Physical touch and pointer devices are not exposed by the current foreground input ABI.

Build and install

Build with ESP-IDF 5.5 for ESP32-S3:

idf.py set-target esp32s3
cmake --build build --target typed_elf

Copy build/solaros_native_mac.app.elf to modules/apps/mac.elf on the preferred storage volume. The firmware must provide the foreground service through disk_close. This module uses lifecycle ABI 2, a 16 KiB worker stack and priority 1. Launch admission requires 8 KiB free internal RAM and 5 MiB free PSRAM after loading the ELF. Guest RAM needs a contiguous 4 MiB block; 8 MiB PSRAM boards can fail admission or allocation if other apps retain large buffers or memory is fragmented. Allocation failure returns to the shell.

mac /sdcard/mac/macplus.rom
mac /sdcard/mac/macplus.rom /sdcard/mac/hd.img
mac /sdcard/mac/macplus.rom --floppy /sdcard/mac/system.img
session create mac display0 /sdcard/mac/macplus.rom --floppy /sdcard/mac/system.img
mac --self-test

ROM and guest disks are user-supplied and are not included. ROM loading checks the complete 128 KiB prefix against the Mac Plus v1, v2 or v3 checksum and reset vector. Extra trailing dump data is ignored. SCSI disks need 512-byte sectors and a guest bootable Apple partition map and driver. A raw HFS floppy is not a SCSI hard disk. The controller rejects transfers larger than its 32 KiB buffer and accesses past the image end.

Verified Plus v3 ROMs skip the long power-on RAM test in the in-memory copy. The host allocates and clears guest RAM before startup. Native display sizes other than 512×342 require Plus v3. Plus v1/v2 retain their original screen and require a 512×342 host surface.

--floppy accepts one raw 400 or 800 KiB image and requires a verified Plus v3 ROM (4d1f8172). It patches only the in-memory ROM copy with the open source Sony driver. The original ROM file is unchanged. Disk Copy containers and GCR/nibble images are not accepted. Floppy and SCSI attachments are mutually exclusive in this version.

Images are exclusively claimed through the SolarOS disk service. Guest writes update and sync the image immediately; use copies to preserve original disks. The image remains claimed while the app is suspended. Close the guest before mounting its image elsewhere or removing storage. PRAM is stored in a 32-byte .pram sidecar beside the ROM, on suspend and close. Serial-port settings start in offline asynchronous mode; LocalTalk is disabled when loading saved PRAM.

Display, controls and sessions

The app queries the selected display dimensions and patches the in-memory Plus v3 ROM so the guest uses that resolution. Each guest pixel maps to one display pixel: there is no scaling, cropping or letterboxing. Both dimensions must be 64..1024 pixels; larger surfaces may exceed the available PSRAM. Rows are word-aligned even when the visible width is not a multiple of 16 pixels. The app checks for screen changes at up to 25 Hz and submits only changed frames, with a complete redraw after resume. Precomputed source rows, byte offsets and bit masks expand the packed guest pixels to display palette indices. Software that assumes the original Mac screen size may have windows or dialogs that do not fit smaller displays.

  • Letters, punctuation and modifiers use Macintosh keyboard scan codes.
  • Keypad 4/6/8/2 move the mouse; hold keypad 5 to hold its button.
  • F8 toggles mouse mode: arrows move and Space holds the mouse button.
  • F2 saves the guest framebuffer as a .pbm sidecar beside the ROM.
  • F10 toggles pause.
  • Ctrl+] closes the app. SolarOS session shortcuts retain their normal use.

On character-only input sources, each arrow event moves six pixels and Space toggles the button because those sources do not supply key-release events.

Suspend retains CPU, RAM, peripheral state, pause state and image claims. It releases display and input ownership. Resume clears held inputs and submits a complete frame. The guest has no callbacks or workers that survive module unload. CPU batches are bounded and yield to the host scheduler.

--self-test runs an original diagnostic ROM that fills the guest framebuffer with stripes and increments a RAM counter. It needs no Apple files and does not boot Macintosh software.

Source and licenses

The original Beer-Ware notices and Musashi MIT permission text are retained under main/vendor. SolarOS changes provide checked memory accesses, bounded execution, deferred device interrupts, recoverable failures, controller bounds, input translation and foreground lifecycle handling.

The replacement Sony driver comes from umac, revision b62d3c6e725ca2ac2224e710b3cee765dbc35e45, and its Basilisk II driver code by Christian Bauer. Its GPL notices, Matt Evans's notices, corresponding assembly source and generated bytes are retained under main/vendor/sony; see COPYING. SolarOS changes bound guest-memory spans, disk offsets, drive-queue traversal and transfer chunks, and update actual transfer counts. Plus v3 installs this driver even without a floppy image. Native-resolution patches in main/video.c derive from umac's MIT-licensed rom.c and Mini vMac's GPL-2.0 SCRNHACK.h by Paul C. Pratt; their notices are retained in that file.

To regenerate the bundled Sony stub with GNU m68k binutils:

cpp main/vendor/sony/sonydrv.S | m68k-linux-gnu-as -o /tmp/sonydrv.o
m68k-linux-gnu-ld /tmp/sonydrv.o -o /tmp/sonydrv.elf -Ttext=0
m68k-linux-gnu-objcopy /tmp/sonydrv.elf -O binary --only-section=.text /tmp/sonydrv.bin
xxd -i < /tmp/sonydrv.bin > main/vendor/sony/sonydrv.h

No Apple firmware, operating system, or disk image is part of these sources.

Package commands

Module ID: mac.

pkg available
pkg install mac

Application · Version 0.2.0 · ESP32-S3 · Requires PSRAM, graphics

Tiny386 foreground app

External ESP32-S3 SolarOS app using tiny386 at 9ed786b4dd9698306dccdb7595858dee10949994. BSD-3-Clause and upstream MIT notices are retained in main/vendor. The port uses SolarOS memory, timing, display, input and file services; it initializes no board peripherals.

The app emulates a 386 PC with 2 MiB RAM, 256 KiB VGA RAM, PS/2 keyboard, timer, RTC, floppy drive and IDE hard drive. The app queries the foreground display dimensions and submits a matching indexed frame. Text cells use the guest's VGA font and palette, with coverage sampling to retain thin strokes at smaller cell sizes. Graphics use a 640x400 VGA buffer and an aspect-preserving fit. This version has no guest networking, mouse or audio. Guest RTC starts at 2000-01-01. It supports 720 KiB, 1.2 MiB, 1.44 MiB and 2.88 MiB raw floppy images and one raw IDE image with 512-byte sectors, smaller than 2 GiB. Images are read and written directly through the host's disk-image service; writes sync before returning. Keep a copy of images whose original contents must be preserved. Unmount an image from SolarOS before starting the guest, and close the guest before mounting it to edit its files.

Build and launch

Build with ESP-IDF 5.5 for ESP32-S3:

idf.py set-target esp32s3
idf.py build
cmake --build build --target typed_elf

The BIOS and VGA BIOS are embedded in the ELF; no separate ROM files are required. The firmware must provide the appended foreground video_dimensions method and the appended disk-image methods through disk_close. Copy build/solaros_native_tiny386.app.elf to storage and run:

load /sdcard/solaros_native_tiny386.app.elf /sdcard/tiny386/dos.img

For installed app discovery, copy the artifact to /sdcard/modules/apps/tiny386.elf, then run:

tiny386 /sdcard/tiny386/dos.img
tiny386 /sdcard/tiny386/dos.img --hdd /sdcard/tiny386/harddisk.img
tiny386 --hdd /sdcard/tiny386/bootable-harddisk.img

The manifest declares a resumable GUI app, a 16 KiB worker stack, priority 1, 8 KiB free internal-memory minimum and 5 MiB free PSRAM minimum. These are admission checks; allocation failures return an error and release guest state.

Keyboard events go to the guest PS/2 keyboard. SolarOS session shortcuts switch away normally. Suspend retains the CPU, RAM and unsaved floppy changes, pauses guest timers, and releases foreground resources. Resume clears held keys and redraws the guest screen. Ctrl+] or session close ID closes the app and saves floppy changes before releasing allocations.

See the Tiny386 application manual.

BIOS source and licenses

The bundled ROMs use SeaBIOS revision 81ec9ec0bcf45df11fb7f98339ec9036b546fca0, tiny386's BIOS patches and the configuration under bios/. bios/seabios-source.tar.xz contains the corresponding unmodified source; bios/tiny386.patch contains the changes. SeaBIOS license texts are included as bios/COPYING and bios/COPYING.LESSER. Distribute these sources, patches, configuration and notices with the ROMs.

SolarOS changes to the vendored core provide bounded stepping, service-backed allocation, files and timing, trapped failures, and a VGA text-frame snapshot for rendering at the selected display's resolution. VGA retrace advances with CPU/device stepping independently of the host's 15 fps rendering limit. Text rendering caches guest glyphs and unchanged cells; a resumed session still submits a complete frame. CPU execution yields after bounded 8 ms batches. Register decrement/branch pairs retain the instruction budget and code-page checks. REP moves use bulk copies for separate RAM ranges; overlaps and device memory retain element-by-element access. Guest fonts remain in VGA RAM; no replacement font or guest disk image is bundled.

Rebuild the ROMs with a native x86 GCC/binutils toolchain, Python 3 and make:

python3 -B scripts/build_bios.py

The build uses a fixed version string. The resulting ROM bytes depend on the compiler and binutils versions. scripts/embed_bios.py converts the bundled ROMs into C data during the module build. No DOS, Windows or other guest disk image is bundled.

Package commands

Module ID: tiny386.

pkg available
pkg install tiny386