Gamma-corrected color, bug fixes, and CI improvements #21

Merged
bcox merged 20 commits from version-1.3.5 into main 2026-04-11 16:55:35 +00:00
Owner

Summary

The big headline here is per-channel gamma-corrected color expansion for the VGA palette. Instead of treating all three channels the same (which makes everything look a bit washed-out on real monitors), each channel now gets its own gamma curve: R=1.6, G=1.5, B=1.4. The default palette and logo example have been updated to match, and there is a brand-new palette.s example program that displays all 64 colors so you can admire the results yourself.

Beyond the eye candy:

  • Interrupt vector race condition fixed. The CPU could read a stale vector address if an interrupt landed at just the wrong moment. It no longer does.
  • S7FS multi-cluster file read bug fixed. Files spanning more than one cluster on the filesystem could read garbage past the first cluster boundary. That is the sort of bug that hides until you ship a slightly larger program on the factory disk -- which is, of course, exactly what happened.
  • Release workflow split into three stages: bump-version, make-release, and publish-release. The old monolithic script was getting unwieldy; now each phase can be run (and re-run) independently. Claude Code skills were added so the agents know how to drive these.
  • just test recipe added, running the full Rust test suite across all crates. A matching CI job now runs on every pull request, so we will catch stale tests before merge instead of after. (Four lsp7 tests with outdated macro-param-replacement expectations were fixed as part of this work.)
  • Version consistency: s7fs was still claiming to be 1.3.4 while everyone else had moved on. It has been brought into line.
  • Palette and logo examples added to the factory disk image, MiSTer distribution, and release packages.

Test plan

  • just test passes all Rust crate tests (including the four previously-broken lsp7 tests).
  • just run launches the emulator; default palette colors are visibly richer and more saturated than before, without banding artifacts.
  • Load palette.h7x from the factory disk in the emulator and confirm all 64 colors display in an orderly grid.
  • Load logo.h7x and confirm the logo renders with the updated palette (no washed-out channels).
  • Load a multi-cluster file from the filesystem and verify the contents are correct past the first cluster boundary.
  • Verify that interrupt-driven I/O (keyboard input during ROM monitor operation, for instance) does not glitch or hang.
  • PR workflow in Forgejo triggers the new test job automatically.
## Summary The big headline here is **per-channel gamma-corrected color expansion** for the VGA palette. Instead of treating all three channels the same (which makes everything look a bit washed-out on real monitors), each channel now gets its own gamma curve: R=1.6, G=1.5, B=1.4. The default palette and logo example have been updated to match, and there is a brand-new `palette.s` example program that displays all 64 colors so you can admire the results yourself. Beyond the eye candy: - **Interrupt vector race condition fixed.** The CPU could read a stale vector address if an interrupt landed at just the wrong moment. It no longer does. - **S7FS multi-cluster file read bug fixed.** Files spanning more than one cluster on the filesystem could read garbage past the first cluster boundary. That is the sort of bug that hides until you ship a slightly larger program on the factory disk -- which is, of course, exactly what happened. - **Release workflow split into three stages:** `bump-version`, `make-release`, and `publish-release`. The old monolithic script was getting unwieldy; now each phase can be run (and re-run) independently. Claude Code skills were added so the agents know how to drive these. - **`just test` recipe added**, running the full Rust test suite across all crates. A matching CI job now runs on every pull request, so we will catch stale tests before merge instead of after. (Four lsp7 tests with outdated macro-param-replacement expectations were fixed as part of this work.) - **Version consistency:** s7fs was still claiming to be 1.3.4 while everyone else had moved on. It has been brought into line. - **Palette and logo examples** added to the factory disk image, MiSTer distribution, and release packages. ## Test plan - `just test` passes all Rust crate tests (including the four previously-broken lsp7 tests). - `just run` launches the emulator; default palette colors are visibly richer and more saturated than before, without banding artifacts. - Load `palette.h7x` from the factory disk in the emulator and confirm all 64 colors display in an orderly grid. - Load `logo.h7x` and confirm the logo renders with the updated palette (no washed-out channels). - Load a multi-cluster file from the filesystem and verify the contents are correct past the first cluster boundary. - Verify that interrupt-driven I/O (keyboard input during ROM monitor operation, for instance) does not glitch or hang. - PR workflow in Forgejo triggers the new test job automatically.
bcox added 12 commits 2026-04-08 00:22:06 +00:00
Replace linear color expansion with gamma-corrected lookup tables for
more perceptually uniform brightness steps. Per-channel gamma values
darken midtones and reduce perceived blue dominance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adjust 5 palette entries (Blue, Brown, Dark Grey, Light Grey, Light
Cyan) that looked wrong under the new per-channel gamma curves.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Retune the custom 16-color palette to better match the SVG logo under
the new per-channel gamma curves.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Draws all 16 palette colors as 6x4 paint chips in two rows of 8,
with hex digit labels underneath each chip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- bump-version: updates all version strings across the project
- make-release: RPM changelog, build, commit, tag, push
- publish-release: create Forgejo release and upload MiSTer zip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three bugs prevented the ROM monitor's LD/X commands from loading
multi-cluster H7X files (logo, language interpreters) from disk:

1. Interrupt vector race condition (cpu.sv, lib.rs): INT_ACK read
   int_vec from the pin on the cycle after FETCH detected the
   interrupt. If the source deasserted in between (e.g. VGA vblank's
   4-tick hold expired), int_vec was 0, dispatching to RST 0 (monitor
   reset) instead of the correct vector. Fix: latch int_vec when
   transitioning to INT_ACK.

2. E register clobbered by nested EXTCALL (rom_bank3.s): In the FAT
   chain follow path of _fs_read_impl, E held a FAT offset value
   across a nested RST 7 (SYS_DSK_READ), but EXTCALL clobbers E.
   Fix: PUSH/POP A around the RST 7 to preserve E.

3. Missing end-of-chain check (rom_bank3.s): After the last valid
   cluster, the FAT entry is EOC ($3FFF). Without checking, the code
   tried to compute an LBA from the EOC value, reading garbage.
   Fix: check cluster == FAT_EOC before LBA computation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
administrivia
Some checks failed
PR Check / test (pull_request) Failing after 4m0s
PR Check / build-rpm (pull_request) Has been cancelled
2ee8909842
Add nodejs to CI test job for actions/checkout
Some checks failed
PR Check / test (pull_request) Failing after 11m55s
PR Check / build-rpm (pull_request) Has been cancelled
65693fa4da
The Forgejo runner needs node to execute actions/checkout@v4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
add the rom dep to test
All checks were successful
PR Check / test (pull_request) Successful in 15m8s
PR Check / build-rpm (pull_request) Successful in 22m44s
7fe7ebfd29
console_init now resets CHAR_BANK to ROM bank 7 ($47) so custom
character sets loaded by a previous program don't persist across
reinitialization.

The charset example now displays the version string in dark grey
(palette index 8) at the lower-left corner. The bump-version script
is updated to include charset.s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add bank_regs, disk, gamepad, and rtc modules to the MiSTer QIP file.
Extract VGA bank mask expressions into intermediate wires to work around
Quartus 17.0 Lite not supporting bit-select on compound expressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BUFRD (_bufrd) now sets the Z flag before returning: AND A,A ensures
Z=1 for empty/overflow returns (A=0) and Z=0 for successful reads.
Previously LD A,#0 and POP A left Z stale, so callers testing JR NZ
after BUFRD could miss data or spin forever.

New example: sinewave.s draws three animated sine waves in an
oscilloscope style display with custom 1-pixel-wide glyphs, per-wave
phase counters driven by vblank frame counting, and border color
cycling on keypress.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
make sure everything is there
All checks were successful
PR Check / test (pull_request) Successful in 9m43s
PR Check / build-rpm (pull_request) Successful in 23m35s
960fbc66d9
- Fix sd_ack width mismatch: hps_io outputs per-drive sd_ack[1:0] with
  VDNUM(2), but the chain declared it as 1-bit scalar. Drive 1 I/O hung
  forever in S_WAIT_ACK. Widen to [3:0] and index by disk_sel throughout.

- Fix disk presence lost on reset: disk_present was cleared by rst_n,
  but MiSTer framework sends RESET after OSD file selection, racing with
  img_mounted and wiping the mount state. Move disk_present tracking to
  a reset-independent always_ff block.

- Fix VGA 1-pixel color bleed: cell_fg/bg_color were registered, causing
  the first pixel of each new character cell to render with the previous
  cell's colors. Make palette lookup combinational so color tracks
  latched_color_attr without a pipeline delay.

- Add LD_ENT default initialization in boot code: after OSD H7X loading,
  the CPU reboots but LD_ENT_G/H was never initialized, so G with no
  argument jumped to garbage. Now boot code writes default &01:00.

- Add descriptive monitor error messages: mount failures print "No disk",
  file-open failures print "Not found", unknown commands still print "?".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix disk BPTR auto-increment; add mister-clean recipe and examples to zip
All checks were successful
PR Check / test (pull_request) Successful in 11m30s
PR Check / build-rpm (pull_request) Successful in 18m4s
b35a83b24c
- Fix disk.sv BPTR over-increment on FPGA: the CPU holds io_req high for
  multiple clk_sys cycles per I/O instruction (14 MHz clock-enable on
  25 MHz system clock). BPTR was incrementing on every cycle, reading
  every 3rd byte. Add io_req edge detection: register writes fire on
  rising edge, BPTR auto-increment fires on falling edge (after the CPU
  has sampled io_din).

- Use |sd_ack instead of sd_ack[disk_sel] for backend buffer write gate,
  matching standard MiSTer core pattern.

- Add mister-clean recipe: cleans Quartus cache and does full rebuild.

- Include .bas and .lsp example files in MiSTer distribution zip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bcox merged commit d649821111 into main 2026-04-11 16:55:35 +00:00
bcox deleted branch version-1.3.5 2026-04-11 16:55:36 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bcox/sbc7!21
No description provided.