• v1.3.1 a13eaea3a2

    SBC7 v1.3.1
    All checks were successful
    Release / build-rpm (push) Successful in 13m24s
    Release / build-deb (push) Successful in 14m31s
    Release / build-android (push) Successful in 18m5s
    Release / build-wasm (push) Successful in 3m58s
    Release / release (push) Successful in 1m51s
    Stable

    bcox released this 2026-04-05 05:53:54 +00:00 | 76 commits to main since this release

    Signed by bcox
    GPG key ID: 1C87BFF7FAC89089

    If v1.2.0 was the release where SBC7 escaped the simulator and landed on real silicon, v1.3.1 is the one where it learned to think bigger than 16 kilobytes. The headline: bank-switched memory turns the SBC7 into a machine that can address up to 128KB of RAM and 16KB of ROM without changing the instruction set. Everything that worked before still works -- the default configuration reproduces the flat 16KB layout -- but now there is room to stretch.

    Along the way the assembler learned real arithmetic, the ROM grew a syscall mechanism, and quite a few things that were slightly broken got fixed. Some of them were more than slightly broken.

    Memory Banking

    The SBC7 address space is now divided into 8 slots of 2KB each. Each slot has a bank register (I/O ports 0-7) that selects which physical bank of RAM or ROM appears in that region. With up to 64 banks per slot, the theoretical ceiling is 128KB of RAM plus 16KB of ROM -- roughly eight times "more than anyone could possibly need" by 1980s standards.

    The bank registers default to an identity mapping (slot N = bank N), so existing software that never touches the bank registers sees exactly the same 16KB flat memory it always did. No migration required; your old H7X files just work.

    RAM bank count is now configurable across every platform: the MiSTer OSD menu, the Android emulator dialog, the web emulator URL parameter, and the RTL ram_bank_mask parameter. Pick your own adventure between "period-accurate austerity" and "I have BlockRAM to burn."

    Multi-Bank ROM

    The boot ROM has been reorganized into three 2KB banks:

    • Bank 0 (slot 7 at reset): boot code, ISRs, console driver, UART/timer drivers, jump table, and the new FARCALL/EXTCALL dispatchers.
    • Bank 1: the interactive monitor (line editor, hex commands, H7X loader), mapped into slot 1 on demand.
    • Bank 2: extended syscall handlers, mapped into slot 2 by the EXTCALL dispatcher.

    Moving the monitor out of bank 0 freed approximately 660 bytes -- which in a 2KB ROM is practically a luxury apartment. Console output functions are bank-aware: they write to the VGA screen bank regardless of how the user has remapped slot 6, which means double-buffering is now possible without corrupting your terminal output.

    A bank-safe interrupt trampoline ensures that user code can remap slot 7 (the ROM slot) for its own purposes without breaking interrupt dispatch. The CPU still vectors into slot 7, but the trampoline restores the ROM bank, services the interrupt, and puts the user's bank back.

    FARCALL and EXTCALL

    Two new calling mechanisms for banked code:

    FARCALL is a reentrant bank-switching indirect call. Point a register pair at a far-address structure (target bank + address), invoke the CALLFAR macro, and the ROM handles the bank switch, the call, and the restore. It is fully reentrant, so interrupts and nested far-calls work correctly.

    EXTCALL (via RST 7) is a table-driven syscall dispatcher. The byte following the RST 7 instruction is the syscall number; the ROM maps bank 2 into slot 2, looks up the handler, calls it, and unmaps. Four initial syscalls ship in this release:

    Syscall Function
    PRT7DEC Print 7-bit value in decimal
    PRT7HEX Print 7-bit value in hex
    PRT14DEC Print 14-bit value in decimal
    PRT14HEX Print 14-bit value in hex

    The mechanism is extensible -- adding new syscalls is a matter of adding entries to the dispatch table in bank 2.

    Assembler Expression System

    The assembler's expression parser has been substantially overhauled. Where previously you had to pre-compute constants and scatter magic numbers through your source, you can now write full arithmetic expressions anywhere a value is expected: addition, subtraction, multiplication, division, modulo, shifts, bitwise operations, unary minus and complement, parentheses for grouping, and $ for the current program counter. Labels and numeric literals are fully interchangeable in expressions.

    New multi-bank directives (.bank, .slots, .entrypoint) let a single source file produce multi-bank H7X2 output. The assembler also now treats .inc files as implicitly pragma-once (no more include guards), and checks for reserved name conflicts at definition time instead of letting you discover them at link time or, worse, at runtime.

    H7X2 Object Format

    The H7X format gains a bank-aware successor. H7X2 files carry per-record bank tags so loaders know which physical bank each chunk belongs in. All loaders -- emu7, MiSTer, disasm7, and the ROM monitor -- have been updated to handle both H7X and H7X2 transparently.

    ROM Signature Block

    The top 8 bytes of ROM (&7F:78--&7F:7F) now contain a machine-readable signature: the ASCII string "SBC7", a three-part version number (major.minor.patch), and a feature-flags byte. Bit 0 of the flags byte indicates banking support. Software can probe this to determine ROM capabilities at runtime instead of guessing.

    Breaking Changes

    The ROM jump table has moved. All jump table entry addresses have changed in this release. If you have code that calls ROM routines by hardcoded address rather than by symbol, it will break. Reassemble against the new ROM symbols and you are fine. The assembler expression system makes this painless -- use the symbolic names, and the assembler will sort out the addresses for you.

    This is the cost of reorganizing the ROM for banking. We considered maintaining backward compatibility and decided it was not worth the contortion; better to break cleanly once than to accumulate thunks forever.

    Tooling

    • VS Code extension: The vsix package was missing its node_modules directory, which is the extension-packaging equivalent of shipping a car without an engine. Fixed. Also: a restart command, extensionKind: workspace for remote development, and TextMate grammar updates for doc comments and bank directives.
    • lsp7: Macro invocations now support hover and go-to-definition. The .bank, .slots, and .entrypoint directives have proper documentation. False errors on macro parameter references are gone (fixes #1).
    • dap7: Step-over now handles all opcodes correctly, and the debugger variables pane includes a bank register scope so you can see which banks are mapped where.
    • SBC7 font: The Panose classification now correctly identifies the font as monospaced, so VS Code will actually offer it in the font picker instead of hiding it behind a bushel.

    Emulator Performance

    Three changes that add up to noticeably smoother emulation on Linux:

    1. Batched UART stdout flush -- previously every byte was a separate syscall inside a mutex lock. Now they are batched per frame.
    2. Spin-yield throttling replaces thread::sleep(500us), which on Linux had 1--4ms actual granularity. The emulator now hits its target frame rate instead of overshooting by 2--8x.
    3. GUI snapshot takes a single mutex lock per frame instead of 3--4, and no lock is held during rendering.

    MiSTer FPGA Fixes

    • Quartus 17 Lite compatibility: An unpacked array port in bank_regs has been flattened to a packed bus. Quartus Lite does not support unpacked arrays on module ports, and it expresses its displeasure by refusing to synthesize.
    • OSD menu: CONF_STR updated to bracket notation; J/jn entries moved to end of string per MiSTer framework requirements.
    • Programmer's switch reliability: The interrupt pulse was 1 clock wide, and the CPU's clock-enable divider missed it roughly 44% of the time. Stretched to 8 clocks. The USER button is now wired to the programmer's switch as well, and the default gamepad binding has moved from A to left shoulder -- because "accidentally triggering the debugger mid-game" is only fun in stories you tell later.

    Signing and Verification

    Release artifacts (RPM, deb, tarballs) are now GPG-signed. Each release includes detached .asc signatures and a signed SHA256SUMS file. Verification instructions and the public key are in the repository. Closes #7.

    Documentation

    • H7X object file format specification.
    • MMIO range &60:00--&63:7F formally documented as reserved (fixes #14).
    • Doc comments (;;) added to every ROM label, so lsp7 can show you what a routine does when you hover over it.
    • Nine documentation inconsistencies across RTL and docs fixed.
    • All assembly sources formatted with fmt7.

    Bug Fixes

    • Boot sequence: UART0 initialization moved earlier in the boot path so serial output works before the banner prints. A trailing space in the banner text, stale-flags bugs in the decimal print routines, and a register corruption in the 14-bit subtract helper (which caused PRT14DEC to loop forever) are all fixed.
    • ROM alignment and init banner text corrections.
    Downloads