Skip to content

Commit 147fe58

Browse files
committed
fix(zig): some changes
snes improvements - megablast port - snes-pad added - fastrom support - dynamic headers - drop any build redundancies/useless
1 parent 483e779 commit 147fe58

14 files changed

Lines changed: 1415 additions & 704 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
run: zig build neo6502-graphics --summary all
8989

9090
- name: Build SNES examples
91-
run: zig build snes-hello snes-color-cycle snes-zig-logo snes-pi-test snes-hirom-hello --summary all
91+
run: zig build snes-hello snes-color-cycle snes-zig-logo snes-pi-test snes-pi-fastrom snes-hirom-hello snes-megablast snes-pads --summary all
9292

9393
- name: Build Apple IIe example
9494
run: zig build apple2-hello --summary all
@@ -113,7 +113,7 @@ jobs:
113113
pce-color-cycle.pce pce-color-cycle-banked.pce \
114114
mega65-hello.prg viciv.prg \
115115
graphics.neo \
116-
snes-hello.sfc snes-color-cycle.sfc snes-zig-logo.sfc snes-pi-test.sfc snes-hirom-hello.sfc \
116+
snes-hello.sfc snes-color-cycle.sfc snes-zig-logo.sfc snes-pi-test.sfc snes-pi-fastrom.sfc snes-hirom-hello.sfc snes-megablast.sfc snes-pads.sfc \
117117
hello.sys \
118118
sim-hello mos-sim; do
119119
test -f "zig-out/bin/$f" && echo "OK: $f" || echo "MISSING: $f"
@@ -172,8 +172,8 @@ jobs:
172172
for f in pce-color-cycle.pce pce-color-cycle-banked.pce; do
173173
smoke "$f"
174174
done
175-
# SNES (LoROM + HiROM — mednafen detects map mode from header byte $FFD5)
176-
for f in snes-hello.sfc snes-color-cycle.sfc snes-zig-logo.sfc snes-pi-test.sfc snes-hirom-hello.sfc; do
175+
# SNES (LoROM + FastROM + HiROM — mednafen detects map mode from header byte $FFD5)
176+
for f in snes-hello.sfc snes-color-cycle.sfc snes-zig-logo.sfc snes-pi-test.sfc snes-pi-fastrom.sfc snes-hirom-hello.sfc snes-megablast.sfc snes-pads.sfc; do
177177
smoke "$f"
178178
done
179179
# Note: Atari 2600 (.a26) is NOT tested here — apt mednafen lacks the vcs module.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ zig build snes-hello
7474
zig build snes-color-cycle
7575
zig build snes-zig-logo
7676
zig build snes-pi-test
77+
zig build snes-pi-fastrom
7778
zig build snes-hirom-hello
79+
zig build snes-megablast
80+
zig build snes-pads
7881

7982
# mos-sim (6502 simulator)
8083
zig build sim-hello
@@ -125,10 +128,14 @@ Output files land in `zig-out/bin/`.
125128

126129
| Example | Preview |
127130
|---------|---------|
131+
| `snes-hello` — LoROM backdrop hello | |
128132
| `snes-zig-logo` — Zig mark logo on BG1 with shimmer palette animation | ![](.github/snes-zig-logo.gif) |
129133
| `snes-color-cycle` — backdrop hue rotation (192-step colour wheel) | |
130134
| `snes-pi-test`~900 digits of π via Spigot algorithm, BG1 text (port of pi_snes by Sirmacho) | |
135+
| `snes-pi-fastrom` — same π demo built as FastROM (map mode $30, MEMSEL=1) | |
131136
| `snes-hirom-hello` — HiROM backdrop hello (map mode $21) | |
137+
| `snes-megablast` — full-game port [no sound] of NES Megablast (CH13), Mode 1 BG+OBJ | |
138+
| `snes-pads` — joypad demo: LEFT/RIGHT cycles backdrop color, A+B resets; exercises `buttonMask`, `held`, `pressed` | |
132139

133140
### Other platforms
134141

@@ -176,7 +183,10 @@ Output files land in `zig-out/bin/`.
176183
| `snes-color-cycle` | SNES LoROM | mosw65816 | `.sfc` |
177184
| `snes-zig-logo` | SNES LoROM | mosw65816 | `.sfc` |
178185
| `snes-pi-test` | SNES LoROM | mosw65816 | `.sfc` |
186+
| `snes-pi-fastrom` | SNES FastROM | mosw65816 | `.sfc` |
179187
| `snes-hirom-hello` | SNES HiROM | mosw65816 | `.sfc` |
188+
| `snes-megablast` | SNES LoROM | mosw65816 | `.sfc` |
189+
| `snes-pads` | SNES LoROM | mosw65816 | `.sfc` |
180190
| `sim-hello` | mos-sim (6502 simulator) | mos6502 | binary |
181191
| `mega65-hello`, `mega65-plasma` | MEGA65 | mos45gs02 | `.prg` |
182192
| `mega65-viciv` | MEGA65 VICIV | mos45gs02 | `.prg` |

build.zig

Lines changed: 277 additions & 615 deletions
Large diffs are not rendered by default.

snes/crt0.s

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@
1818
lda #0x00 ; explicit DB=0: safe for both LoROM (bank $00) and HiROM (bank $C0+)
1919
pha
2020
plb
21+
lda #__snes_memsel ; 0=SlowROM (lorom.ld/hirom.ld), 1=FastROM (fastrom.ld)
22+
sta 0x420d ; MEMSEL: set ROM access speed before any ROM-intensive code runs
2123

24+
.extern __snes_memsel
2225
.extern vblank_flag
26+
.extern pad_keys
27+
.extern pad_keysold
28+
.extern pad_keysdown
2329
.section .text.nmi_handler,"ax",@progbits
2430
.global nmi_handler
2531
nmi_handler:
@@ -35,9 +41,25 @@ nmi_handler:
3541
plb ; DB = 0
3642
lda #0x01
3743
sta vblank_flag ; signal VBlank to wait_vblank()
38-
pld ; restore direct page
39-
plb ; restore data bank
40-
rep #0x30 ; 16-bit for restoring A/X/Y
44+
; --- joypad auto-read (uses only abs operands — no lda #imm after rep) ---
45+
rep #0x30 ; 16-bit A for 16-bit joypad reads
46+
lda pad_keys ; save pad1 previous state
47+
sta pad_keysold
48+
lda 0x4218 ; read JOY1L/H (16-bit auto-read result)
49+
sta pad_keys
50+
eor pad_keysold ; new XOR previous
51+
and pad_keys ; (new XOR previous) AND new = 0→1 transitions
52+
sta pad_keysdown
53+
lda pad_keys+2 ; pad2: save previous state
54+
sta pad_keysold+2
55+
lda 0x421a ; read JOY2L/H
56+
sta pad_keys+2
57+
eor pad_keysold+2
58+
and pad_keys+2
59+
sta pad_keysdown+2
60+
; --- restore (M=0/X=0 from rep above — pld/plb are M-independent) ---
61+
pld ; restore direct page (always 16-bit)
62+
plb ; restore data bank (always 8-bit)
4163
ply
4264
plx
4365
pla

snes/fastrom.ld

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* Copyright (c) 2024 Matheus C. França */
2+
/* SPDX-License-Identifier: Apache-2.0 */
3+
/* */
4+
/* SNES FastROM LoROM — single 32 KiB PRG bank ($80:8000–$80:FFFF). */
5+
/* */
6+
/* ROM is placed in bank $80 so instruction fetches run at */
7+
/* 3.58 MHz (FastROM speed) after $420D is set to 1 in crt0. */
8+
/* WRAM and I/O remain at the same addresses as LoROM. */
9+
/* */
10+
/* Memory map (bank $80): */
11+
/* $0000–$00FF Direct page / ZP (WRAM mirror, first 256 B) */
12+
/* $0100–$01FF Hardware stack (WRAM mirror) */
13+
/* $0200–$1FFF WRAM (data / BSS / soft stack) */
14+
/* $2000–$5FFF Hardware I/O registers (not addressable here) */
15+
/* $8000–$FFFF ROM bank $80 (32 KiB) */
16+
17+
/* Imaginary (zero-page / direct-page) registers __rc0–__rc31. */
18+
__rc0 = 0x0000;
19+
INCLUDE imag-regs.ld
20+
ASSERT(__rc31 == 0x001f, "Inconsistent zero page map.")
21+
22+
/* ROM access speed for MEMSEL ($420D): 0=SlowROM, 1=FastROM. */
23+
/* crt0.s reads this symbol as an immediate and writes $420D. */
24+
__snes_memsel = 1;
25+
26+
MEMORY {
27+
/* Direct page: bytes after imaginary regs, up to end of page */
28+
zp (rw) : ORIGIN = __rc31 + 1, LENGTH = 0x100 - (__rc31 + 1)
29+
/* WRAM: $0200–$1FFF (stack page $0100–$01FF reserved for hardware stack) */
30+
ram (rw) : ORIGIN = 0x0200, LENGTH = 0x1e00
31+
/* ROM bank $80: FastROM window — same physical data as bank $00 mirror */
32+
rom (rx) : ORIGIN = 0x808000, LENGTH = 0x8000
33+
}
34+
35+
REGION_ALIAS("c_readonly", rom)
36+
REGION_ALIAS("c_writeable", ram)
37+
38+
/* Soft stack grows down from the top of WRAM. */
39+
__stack = 0x2000;
40+
41+
SECTIONS {
42+
INCLUDE c.ld
43+
44+
/* SNES internal ROM header: 32 bytes at $80:FFC0–$80:FFDF. */
45+
.snes_header 0x80ffc0 : { KEEP(*(.snes_header)) } >rom
46+
47+
/* Interrupt vector table: 28 bytes at $80:FFE4–$80:FFFF. */
48+
.vectors 0x80ffe4 : { KEEP(*(.vectors)) } >rom
49+
}
50+
51+
OUTPUT_FORMAT {
52+
FULL(rom)
53+
}

snes/header.zig

Lines changed: 0 additions & 38 deletions
This file was deleted.

snes/hirom.ld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ __rc0 = 0x0000;
2121
INCLUDE imag-regs.ld
2222
ASSERT(__rc31 == 0x001f, "Inconsistent zero page map.")
2323

24+
/* ROM access speed for MEMSEL ($420D): 0=SlowROM, 1=FastROM. */
25+
__snes_memsel = 0;
26+
2427
MEMORY {
2528
/* Direct page: bytes after imaginary regs, up to end of page */
2629
zp (rw) : ORIGIN = __rc31 + 1, LENGTH = 0x100 - (__rc31 + 1)

snes/hirom_header.zig

Lines changed: 0 additions & 40 deletions
This file was deleted.

snes/lorom.ld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ __rc0 = 0x0000;
1515
INCLUDE imag-regs.ld
1616
ASSERT(__rc31 == 0x001f, "Inconsistent zero page map.")
1717

18+
/* ROM access speed for MEMSEL ($420D): 0=SlowROM, 1=FastROM. */
19+
__snes_memsel = 0;
20+
1821
MEMORY {
1922
/* Direct page: bytes after imaginary regs, up to end of page */
2023
zp (rw) : ORIGIN = __rc31 + 1, LENGTH = 0x100 - (__rc31 + 1)

snes/megablast/megablast.chr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../nesdoug/megablast/megablast.chr

0 commit comments

Comments
 (0)