Skip to content

Upgrade to NES2.0 header #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ if (args.includes('-h')) {
-k Famicom Keyboard support
-w force WASM compiler
-c force PNG to CHR conversion
-i use iNES header instead of NES2.0
-o override autodetect mmc1 header with cnrom
-t run tests (requires cargo)
-h you are here
Expand Down Expand Up @@ -79,9 +80,15 @@ if (args.includes('-k')) {

if (args.includes('-s')) {
compileFlags.push('-D', 'SAVE_HIGHSCORES=0');
compileFlags.push('-D', 'HAS_SRAM=0');
console.log('highscore saving disabled');
}

if (args.includes('-i')) {
compileFlags.push('-D', 'INES_OVERRIDE=1');
console.log('iNES header override');
}

if (args.includes('-o')) {
compileFlags.push('-D', 'CNROM_OVERRIDE=1');
console.log('cnrom override for autodetect');
Expand Down
8 changes: 8 additions & 0 deletions src/constants.asm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ INES_MAPPER := 1000 ; 0 (NROM), 1 (MMC1), 3 (CNROM), 4 (MMC3), 5 (MMC5), and 100
SAVE_HIGHSCORES := 1
.endif

.ifndef HAS_SRAM
HAS_SRAM := 1
.endif

.ifndef AUTO_WIN
; faster aeppoz + press select to end game
AUTO_WIN := 0
Expand All @@ -15,6 +19,10 @@ AUTO_WIN := 0
KEYBOARD := 0
.endif

.ifndef INES_OVERRIDE
INES_OVERRIDE := 0
.endif

.ifndef CNROM_OVERRIDE
CNROM_OVERRIDE := 0
.endif
Expand Down
35 changes: 29 additions & 6 deletions src/header.asm
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
;
; iNES header
; NES2.0 header
; https://www.nesdev.org/wiki/NES_2.0
;

; This iNES header is from Brad Smith (rainwarrior)
; iNES header adapted from Brad Smith (rainwarrior)
; https://github.com/bbbradsmith/NES-ca65-example

.segment "HEADER"

.include "constants.asm" ; for INES_HEADER

INES_MIRROR = 0 ; 0 = horizontal mirroring, 1 = vertical mirroring (ignored in MMC1)
INES_SRAM = 1 ; 1 = battery backed SRAM at $6000-7FFF
INES_SRAM = HAS_SRAM ; 1 = battery backed SRAM at $6000-7FFF
NES2_SRAM_SHIFT = HAS_SRAM * 7 ; if SRAM present, set shift to 7 for (64 << 7) = 8KiB size
NES2_REGION = 2 ; 0 = NTSC, 1 = PAL, 2 = multi-region, 3 = UA6538 ("Dendy")
NES2_INPUT = 0 ; 0 = unspecified, 1 = standard NES/FC controllers, $23 = Family BASIC Keyboard

; Override INES_MAPPER for mode 1000 (auto detect)
.if INES_MAPPER = 1000
Expand All @@ -20,12 +24,31 @@ INES_SRAM = 1 ; 1 = battery backed SRAM at $6000-7FFF
_INES_MAPPER = 1 ; MMC1 for Emulator/Flashcart
.endif
.else
_INES_MAPPER = INES_MAPPER ; use actual INES_MAPPER otherwise
_INES_MAPPER = INES_MAPPER ; use actual INES_MAPPER otherwise
.endif

; Pick the appropriate NES2_SUBMAPPER
.if _INES_MAPPER = 1
NES2_SUBMAPPER = 5 ; MMC1 fixed PRG
.elseif _INES_MAPPER = 3
NES2_SUBMAPPER = 2 ; CNROM bus conflicts
.else
NES2_SUBMAPPER = 0 ; otherwise don't specify submapper
.endif

; Construct header
.byte 'N', 'E', 'S', $1A ; ID
.byte $02 ; 16k PRG chunk count
.byte $02 ; 8k CHR chunk count
.byte INES_MIRROR | (INES_SRAM << 1) | ((_INES_MAPPER & $f) << 4)
.byte (_INES_MAPPER & %11110000)
.byte $0, $0, $0, $0, $0, $0, $0, $0 ; padding

.if INES_OVERRIDE = 0
.byte (_INES_MAPPER & %11110000) | %00001000 ; NES2.0 header identifier
.byte ((NES2_SUBMAPPER & $f) << 4) | ((_INES_MAPPER & $f00) >> 8) ; submapper/mapper MSB
.byte $0, (NES2_SRAM_SHIFT << 4) ; PRG MSB, SRAM shift count
.byte $0, NES2_REGION, $0, $0, NES2_INPUT ; misc. fields, region, input device
.else
.byte (_INES_MAPPER & %11110000)
.byte $0, $0, $0, $0, $0, $0, $0, $0 ; padding
.endif