Skip to content

Releases: rh1tech/frank-snes

Version 1.11

Choose a tag to compare

@rh1tech rh1tech released this 02 May 19:50
  • Fixed black-screen-with-audio on Cybernator (USA) and Assault Suits Valken; HDMI palette is now pushed when the game raises brightness instead of at end-of-frame
  • Fixed long ROM filenames like "Assault Suits Valken (Japan) [T-En by Aeon Genesis v1.1].sfc" not launching from the carousel
  • Added a third MOUSE PORT value "OFF" to hide the SNES mouse from games that lock up when one is detected (e.g. King Arthur & The Knights of Justice); PS/2 and USB mice still work in menus
  • Suppressed the once-per-second mouse-pipeline heartbeat log when no mouse is attached

Version 1.10

Choose a tag to compare

@rh1tech rh1tech released this 01 May 20:25
  • Added USB XInput (Xbox 360) gamepad support alongside existing HID pads
  • Added per-device USB gamepad button maps keyed on VID/PID, regenerated from captures in gamepads/
  • Added first-connect menu A/B calibration wizard for unknown USB pads; learned bits are saved to snes/gamepads/gamepad_VVVV_PPPP.txt on SD and reused on later boots
  • Added a hid_rip HID descriptor fallback parser so arcade sticks, composites, and cheap clones the stock TinyUSB parser trips on now enumerate their buttons
  • Auto-detect NES vs SNES pad type per port; NES pads map A and B correctly, SNES pads get A/B/X/Y/L/R without manual configuration
  • Changed gamepad settings hotkey from Select+Start to Select+Start+A; bare Select+Start now toggles the ROM carousel / file browser
  • Tab on a PS/2 or USB keyboard also toggles the carousel / file browser
  • File browser: A opens directories and launches ROMs; Start is reserved for combos
  • Settings launched from the ROM selector shows "BACK TO ROMS" instead of "BACK"
  • Added Settings → Button Mapping → Clean USB Cache to wipe learned USB pad layouts and re-arm the wizard
  • Replaced SNES Mouse on/off toggle with Mouse Port: Gamepad 1/2; entry is hidden when no mouse is connected, and emulation engages automatically whenever a PS/2 or USB mouse is detected
  • Show a visible NO SD CARD DETECTED screen at boot when the SD card is missing instead of a silent LED-blink loop
  • release.sh: added -t/--test flag for preview builds that skip version.txt rewrite and postfix output with _test
  • release.sh: strip leading zeros from version.txt so minor=09 is no longer parsed as octal

Version 1.09

Choose a tag to compare

@rh1tech rh1tech released this 29 Apr 11:50
  • Fix PS/2 mouse init on USB_HID=1 release builds (BAT succeeded but SET_SAMPLE_RATE returned 0xFC). Workaround: skip IntelliMouse magic knock, NVIC-mask host-to-device frames, 50 ms inter-byte gap, wait for bus idle before SIO→PIO handoff.
  • Fix HDMI resync glitch when a PS/2 mouse is plugged in on M2 boards. PS/2 bit-bang on GPIO 0/1 was perturbing HDMI TMDS pairs on GPIO 12–19. PS/2 keyboard and mouse now init before graphics_init().
  • Bump mouse init retry loop from 3 attempts to 10, with 500 ms between attempts. Bail out immediately if no device responds to RESET.
  • Restore full mouse init path on USB_HID=0 builds (IntelliMouse probe, sample rate 200, resolution 3, scaling 1:1). USB_HID=1 keeps the skip-magic-knock workaround.
  • Log now distinguishes Mouse: No device on bus, giving up from Mouse: Init FAILED after 10 retries.

Version 1.08

Choose a tag to compare

@rh1tech rh1tech released this 28 Apr 15:33

Focus: PS/2 mouse support now works with a much wider range of devices, including cheap and older mice that previously failed to initialize.

Fixes

  • Handle the device's 0xFE (RESEND) reply. A single corrupt host-to-device byte no longer fails the whole init; the driver retries the byte as the spec requires.
  • Handle the device's 0xFC (ERROR) reply the same way. The spec says 0xFC is BAT-only, but many real-world mice send it post-BAT as a soft "please resend". The driver now treats it as a retry request instead of a fatal error.
  • Wait for the bus to be idle (CLK and DATA both high) before every host-to-device transmit. Slower mice that hold the lines a little longer no longer cause a request-to-send collision.
  • Add a 50 ms settling delay after BAT completes, plus a drain of any stragglers in the PIO RX FIFO, before the first configuration byte. Mice that were still finishing internal init no longer get commands thrown at them too early.
  • Flush the RX FIFO before every command. A leftover response from a previously failed command can no longer be misread as the answer to the current one.
  • Replace the old 4-try / 5 ms retry loop with 2 tries at 30 ms. The faster loop was flooding some mice into a locked state that even a fresh reset couldn't recover from.
  • Add a communication-inhibit bus recovery step between init attempts: CLK held low for 20 ms, both lines released for 30 ms, then the PIO state machine is restarted. Retry attempts now start from a clean bus instead of a wedged one.
  • Fall back gracefully when the IntelliMouse magic knock fails. Previously the driver gave up; now it continues in plain 3-button mode.

Diagnostics

  • Command timeouts log timed out waiting for ACK instead of 0xFFFFFFFF.

Assets

  • frank-snes_m1_1_08.uf2 — firmware for M1 board variant
  • frank-snes_m2_1_08.uf2 — firmware for M2 board variant
  • metadata.zip — sdcard ROM metadata bundle

Version 1.07

Choose a tag to compare

@rh1tech rh1tech released this 27 Apr 18:59

SNES mouse support

  • Added SNES mouse support. PS/2 and USB mice both work as a SNES mouse on controller port 2. Enables Cannon Fodder, Mario Paint, Lemmings, and other mouse titles.
  • Replaced the PS/2 keyboard driver with a unified PS/2 driver that handles keyboard and mouse on separate PIO instances. Keyboard moved to PIO2; mouse lives on PIO1 next to audio, matching the proven frank-wolf layout.
  • Fixed the snes9x 0x4017 serial read path. The original port truncated to 16 bits; mice need the full 32-bit packet, so dx/dy bytes now reach the game instead of being read as 1s.
  • Added a SNES MOUSE toggle on the main Settings page, directly under Button Mapping. Default is on. Saved to /snes/settings.ini.
  • USB mouse fixes ported from frank-wolf: accept short HID reports via a zero-padded copy, detect mouse via HID_USAGE_DESKTOP_MOUSE in the descriptor for protocol=NONE devices, route generic reports through the descriptor dispatcher so generic-HID mice are not swallowed by the gamepad path.
  • Axes normalized for the on-board mouse orientation. Raw dy maps to screen -x; raw dx maps to screen +y. Same transform applied to USB and PS/2 so both feel identical.
  • Free-running mouse accumulator. The pointer no longer clamps at [0..255, 0..223], so motion after reaching a screen edge still registers (fixes "can't move left after hitting the left edge").

SuperFX / DOOM fixes

  • Fixed the cold-boot regression from 1.05 where DOOM (and other SuperFX games needing a 6 MB ROM buffer) rendered a single garbage scanline on first launch and only worked after a selector round-trip. Root cause: the 57 KB sub-screen transparency buffer was allocated inside the permanent PSRAM arena after psram_mark_session, which pushed S9xInitGFX's 22 KB LocalState allocation past the ceiling and silently returned NULL. GFX.OBJLines then stayed NULL and the PPU dereferenced it from frame one. The buffer is now parked at a fixed offset inside the 512 KB scratch region, which is outside the session lifecycle, so it survives across ROM launches and never competes with ROM data. S9xInitGFX's return value is now checked and fatal-logged.
  • Fixed SuperFX rendering for DOOM and other non-Star-Fox SuperFX titles. Three bugs were conspiring: VRAM/RAM/SRAM/FillRAM were malloc'd instead of calloc'd, so DOOM's tilemap referenced never-DMA'd tile indexes and rendered PSRAM garbage as a red/blue houndstooth over the viewport. FxEmulate was hard-capped to 350/700 cycles per HBlank (a Star Fox-specific hack); DOOM needs the GSU to run to STOP within the frame, so this is now FxEmulate(~0) matching snes9x2005. NO_WINDOW_CLIPPING skipped ComputeClipWindows entirely, which SuperFX games rely on to mask the 3D viewport borders — the optimization is now conditional on !Settings.SuperFX. GSU opcode handlers also moved to .time_critical SRAM.

Performance

  • Moved the hot emulation code out of XIP-cached flash into .time_critical SRAM sections. XIP cache misses during opcode dispatch were the dominant overhead. Tagged: all 478 65816 opcode handlers and the five 256-entry dispatch tables in cpuops.c, the SPC700 APUExecute switch (called every HBlank), S9xGet/SetPPU and S9xGet/SetCPU (hit on every $21xx/$42xx/$43xx access), S9xDoDMA, S9xSetAPUDSP, S9xMixSamplesMono, S9xUpdateScreen, and S9xDoHBlankProcessing.
  • Moved the 96 KB SPC700 echo buffer from static .bss to PSRAM via snes_malloc, freeing SRAM for the hot sections above. Echo is read/written at most once per sample and only when enabled, so PSRAM latency is not measurable.
  • DOOM gameplay measurements: emulation throughput 27.6 → 30.3 fps, skip-frame 28.0 → 26.0 ms, render-frame 60.2 → 55.2 ms.

Dev / build

  • Dev-build USB CDC wait: block until the host terminal opens the port, then pause 3 seconds before the first LOG(...). Full boot log now lands in the console.
  • build.sh accepts USB_HID_ENABLED as an environment override (USB_HID_ENABLED=ON ./build.sh M2).

Downloads

  • frank-snes_m1_1_07.uf2 — M1 board variant
  • frank-snes_m2_1_07.uf2 — M2 board variant
  • metadata.zip — SD-card metadata bundle (drop into / of your SD card)

Version 1.06

Choose a tag to compare

@rh1tech rh1tech released this 26 Apr 22:21

A small but targeted release. Two fixes on top of 1.05, one visible, one you only hit if you'd been poking at the video settings.

What's new

HUD chrome reappears in games that use OBJ palette 7

Several SNES titles store their HUD colors in the top slice of CGRAM — OBJ palette 7, which lives at indices 240–255. Our HDMI driver reserves indices 251–254 for sync-control codes, and when the framebuffer contains one of those values the assembly scanline copy substitutes it with the nearest visible color from the rest of the palette.

That substitution table was only computed once, before the game had uploaded its real palette, and never refreshed. So the first time a game wrote silver/white chrome colors to CGRAM 252/253/254, those pixels showed up on screen as sync-black instead.

Addams Family Values surfaced this first — the skull life counter and its silver frame looked like an empty black pill. The fix is small: the substitute table now updates incrementally on every palette write. Cost is O(4) in the common case, a full rescan only when one of the reserved targets itself moves. All of it stays on Core 0, so the HDMI VBlank ISR is untouched.

As a bonus while I was in there, the fast-mode per-scanline sprite cap went from 16 back up to 32 (SNES hardware max). Some HUDs assemble their chrome from a lot of small sprites and the cap was silently dropping the late ones.

Warning at boot when video settings could hide game content

If you've been debugging something and left BG1 off, or turned transparency off to check what it was doing, it's easy to forget. The next day you fire up a game and wonder why it looks broken.

After the welcome screen, you now get a yellow warning page listing every game-affecting video setting you have turned off — BG1–4, sprites, transparency, HDMA — with a nudge to open the settings menu (Start+Select in-game) if that wasn't intentional. The screen is skipped entirely when everything is at defaults, so you'll only see it when it's telling you something useful. CRT overscan is excluded because it doesn't affect game content.

Press any button or wait eight seconds to continue.

Firmware

  • frank-snes_m1_1_06.uf2 — Board variant M1
  • frank-snes_m2_1_06.uf2 — Board variant M2
  • metadata.zip — SNES cover art and game info for the ROM selector (copy to your SD card, same as before)

Version 1.05

Choose a tag to compare

@rh1tech rh1tech released this 26 Apr 19:05

This release is focused on the UX around the ROM selector and a handful of in-game hotkeys. The emulator core is unchanged; if a game ran on 1.04 it runs on 1.05.

What's new

File browser

There's a second way to pick a ROM now. From the carousel press Select+Start and you land in a directory listing rooted at /snes, with .. for up-navigation, a size column, and folders sorted before files. Only .smc, .sfc, and .fig files are shown.

  • Up/Down wraps (top ⇄ bottom)
  • Left/Right pages by 20 entries
  • Scrollbar when the list overflows
  • Auto-repeat on held D-pad
  • Your current directory and last-launched filename are saved, so a cold boot returns you exactly where you left off

B / ESC / F12 or another Select+Start returns to the carousel.

No-ROMs flow

When /snes is missing or empty, 1.04 sat at a blank loading screen. Now you see an explanatory screen telling you what to copy, then it drops you into the file browser so you can load a ROM from anywhere on the SD card.

Search

Select+A in the carousel or file browser opens a search dialog. Gamepad users can pick letters from an on-screen keyboard. If you have a PS/2 or USB keyboard plugged in, just type — the query updates live and shows the top five matches by title. Picking a result takes you straight back to the carousel at that ROM.

Settings behaviour

  • Settings no longer opens from the ROM selector. Start+Select on the carousel now opens the file browser instead. Settings are only available while a ROM is running.
  • New RESTART GAME entry at the bottom of the in-game Settings menu — same effect as hitting the Reset button on a real SNES: the ROM stays loaded, state is cleared, the title screen comes back.
  • The Settings menu now shows a scrollbar when the list overflows.

New video option

  • CRT OVERSCAN toggle in Video Settings. Blanks the edge columns of the frame to hide scroll artifacts that appear at the left/right edges in games using per-tile offset scrolling (Axelay and other Mode 5/6 titles). In 1.04 this blanking was applied unconditionally; it's a switch now.

New in-game hotkeys

  • F11 → back to ROM selector. Skips the menu entirely.
  • Ctrl+Alt+Del → soft-reset the current ROM, same effect as the Restart Game menu entry. Edge-triggered so one press fires exactly one reset.

Both work on PS/2 and USB keyboards.

ROM selector quality of life

  • ROMs are sorted alphabetically (case-insensitive) after the scan.
  • CRC indexing and metadata loading now show a progress bar instead of a blank screen.
  • Held buttons no longer leak between screens — you won't auto-select a ROM just because you were still holding A when the selector appeared.

Firmware

  • frank-snes_m1_1_05.uf2 — Board variant M1
  • frank-snes_m2_1_05.uf2 — Board variant M2

SD card metadata

metadata.zip contains cover art and game info indexed by CRC32. Extract the metadata/ directory into /snes/ on your SD card. The selector shows filenames when metadata is missing, so this is optional.

Version 1.04

Choose a tag to compare

@rh1tech rh1tech released this 26 Mar 12:37

Changes

  • Fix scroll edge artifacts (CRT overscan simulation for offset-per-tile modes)
  • Implement SuperFX (GSU) chip emulation - work in progress
  • Fix version display (1.03 was showing as 1.3)

Firmware

  • frank-snes_m1_1_04.uf2 — Board variant M1
  • frank-snes_m2_1_04.uf2 — Board variant M2

Version 1.03

Choose a tag to compare

@rh1tech rh1tech released this 22 Mar 22:18

What's New

  • Button mapping settings: New Settings > Button Mapping submenu for remapping A/B/X/Y/L/R/Start/Select per input device (keyboard, NES/SNES gamepad, USB gamepad)
  • Scan-based mapping: press A to scan, then press any button on the target device to assign it
  • Mappings saved to settings.ini and take effect in-game immediately
  • D-pad remains fixed (not remappable)

Version 1.02

Choose a tag to compare

@rh1tech rh1tech released this 22 Mar 20:15

Fix crash on games using SNES hi-res modes (Mode 5/6)

Games that use SNES hi-res rendering (512px wide) — such as Axelay — would crash shortly after switching to Mode 5 or Mode 6. The 512px rendering overflowed the 256px framebuffer, corrupting emulator state.

Fix: Hi-res modes now render at half horizontal resolution (256px), preventing the buffer overflow. Visual quality in hi-res scenes is slightly reduced but gameplay works correctly.