Skip to content

Commit ae4b44c

Browse files
committed
autodetect mmc1 or cnrom
1 parent da4fd29 commit ae4b44c

File tree

11 files changed

+346
-166
lines changed

11 files changed

+346
-166
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,4 @@ This project descends from the TAUS disassembly of NES Tetris and has been heavi
451451

452452
* [https://github.com/ejona86/taus](https://github.com/ejona86/taus)
453453
* [https://github.com/CelestialAmber/TetrisNESDisasm](https://github.com/CelestialAmber/TetrisNESDisasm)
454+
* [https://github.com/pinobatch/holy-mapperel](https://github.com/pinobatch/holy-mapperel)

build.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,22 @@ const { spawnSync } = require('child_process');
66
console.log('TetrisGYM buildscript');
77
console.time('build');
88

9-
const mappers = [1, 3, 4, 5];
9+
const mappers = [0, 1, 3, 4, 5];
1010

1111
// options handling
1212

1313
const args = process.argv.slice(2);
1414

1515
if (args.includes('-h')) {
16-
console.log(`usage: node build.js [-h] [-v] [-m<${mappers.join('|')}>] [-a] [-s] [-k] [-w]
16+
console.log(`usage: node build.js [-h] [-v] [-m<${mappers.join('|')}>] [-a] [-s] [-k] [-w] [-c] [-o]
1717
1818
-m mapper
1919
-a faster aeppoz + press select to end game
2020
-s disable highscores/SRAM
2121
-k Famicom Keyboard support
2222
-w force WASM compiler
2323
-c force PNG to CHR conversion
24+
-o override autodetect mmc1 header with cnrom
2425
-h you are here
2526
`);
2627
process.exit(0);
@@ -42,7 +43,7 @@ console.log(`using ${nativeCC65 ? 'system' : 'wasm'} ca65/ld65`);
4243

4344
// mapper options
4445

45-
const mapper = args.find((d) => d.startsWith('-m'))?.slice(2) ?? 1;
46+
const mapper = args.find((d) => d.startsWith('-m'))?.slice(2) ?? 0;
4647

4748
if (!mappers.includes(+mapper)) {
4849
console.error(
@@ -74,6 +75,11 @@ if (args.includes('-s')) {
7475
console.log('highscore saving disabled');
7576
}
7677

78+
if (args.includes('-o')) {
79+
compileFlags.push('-D', 'CNROM_OVERRIDE=1');
80+
console.log('cnrom override for autodetect');
81+
}
82+
7783
console.log();
7884

7985
// build / compress nametables

src/boot.asm

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
1-
ldy #$06
2-
sty tmp2
3-
ldy #$00
4-
sty tmp1
5-
lda #$00
6-
@zeroOutPages:
7-
sta (tmp1),y
8-
dey
9-
bne @zeroOutPages
10-
dec tmp2
11-
bpl @zeroOutPages
1+
; $0000 through $06FF cleared during vblank wait
122
lda initMagic
133
cmp #$54
144
bne @coldBoot

src/constants.asm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.ifndef INES_MAPPER ; is set via ca65 flags
2-
INES_MAPPER := 1 ; supports 1, 3 and 4 (MMC1 / CNROM / MMC3)
2+
INES_MAPPER := 0 ; supports 0 (autodetect 1/3), 1, 3, 4 and 5 (MMC1 / CNROM / MMC3 / MMC5)
33
.endif
44

55
HAS_MMC = INES_MAPPER = 1 || INES_MAPPER = 4 || INES_MAPPER = 5
@@ -17,6 +17,10 @@ AUTO_WIN := 0
1717
KEYBOARD := 0
1818
.endif
1919

20+
.ifndef CNROM_OVERRIDE
21+
CNROM_OVERRIDE := 0
22+
.endif
23+
2024
NO_MUSIC := 1
2125

2226
; dev flags

src/header.asm

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,20 @@
1212
INES_MIRROR = 0 ; 0 = horizontal mirroring, 1 = vertical mirroring (ignored in MMC1)
1313
INES_SRAM = 1 ; 1 = battery backed SRAM at $6000-7FFF
1414

15+
; Override INES_MAPPER for mode 0 (auto detect)
16+
.if INES_MAPPER = 0
17+
.if CNROM_OVERRIDE
18+
_INES_MAPPER = 3 ; Test CNROM on Emulator/Flashcart
19+
.else
20+
_INES_MAPPER = 1 ; MMC1 for Emulator/Flashcart
21+
.endif
22+
.else
23+
_INES_MAPPER = INES_MAPPER ; use actual INES_MAPPER otherwise
24+
.endif
25+
1526
.byte 'N', 'E', 'S', $1A ; ID
1627
.byte $02 ; 16k PRG chunk count
1728
.byte $02 ; 8k CHR chunk count
18-
.byte INES_MIRROR | (INES_SRAM << 1) | ((INES_MAPPER & $f) << 4)
19-
.byte (INES_MAPPER & %11110000)
29+
.byte INES_MIRROR | (INES_SRAM << 1) | ((_INES_MAPPER & $f) << 4)
30+
.byte (_INES_MAPPER & %11110000)
2031
.byte $0, $0, $0, $0, $0, $0, $0, $0 ; padding

src/main.asm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ mainLoop:
5454
.include "util/math.asm"
5555
.include "util/menuthrottle.asm"
5656
.include "util/modetext.asm"
57+
.include "util/mapper.asm"
58+
.if INES_MAPPER = 0
59+
.include "util/autodetect.asm"
60+
.endif
5761

5862
.include "sprites/loadsprite.asm"
5963
.include "sprites/drawrect.asm"

src/ram.asm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ dasOnlyShiftDisabled: .res 1 ; $63A
210210

211211
invisibleFlag: .res 1 ; $63B ; 0 for normal mode, non-zero for Invisible playfield rendering. Reset on game init and game over.
212212

213-
.res $39
213+
mapperId: .res 1 ; $63C ; For INES_MAPPER 0 (autodetect). 0 = CNROM. 1 = MMC1.
214+
215+
.res $38
214216

215217
.if KEYBOARD
216218
newlyPressedKeys: .res 1 ; $0675

src/reset.asm

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,60 @@ reset: cld
44
ldx #$00
55
stx PPUCTRL
66
stx PPUMASK
7+
8+
; init code from https://www.nesdev.org/wiki/Init_code
9+
bit PPUSTATUS
710
@vsyncWait1:
8-
lda PPUSTATUS
11+
bit PPUSTATUS
912
bpl @vsyncWait1
13+
14+
; zero out pages 0 through 6 while waiting
15+
txa
16+
@clrmem:
17+
sta $0000,x
18+
sta $0100,x
19+
sta $0200,x
20+
sta $0300,x
21+
sta $0400,x
22+
sta $0500,x
23+
sta $0600,x
24+
inx
25+
bne @clrmem
26+
27+
bit PPUSTATUS
1028
@vsyncWait2:
11-
lda PPUSTATUS
29+
bit PPUSTATUS
1230
bpl @vsyncWait2
13-
dex
31+
32+
dex ; $FF for stack pointer
1433
txs
15-
.if INES_MAPPER = 1
16-
RESET_MMC1
17-
.elseif INES_MAPPER = 4
18-
jsr mmc3Init
19-
.elseif INES_MAPPER = 5
20-
jsr mmc5Init
21-
.endif
34+
jsr changePRGBank ; 0 in accumulator
35+
jsr mapperInit
2236
jsr setVerticalMirroring
2337
lda #CHRBankSet0
2438
jsr changeCHRBanks
25-
lda #$00
26-
jsr changePRGBank
2739
jmp initRam
2840

29-
.if INES_MAPPER = 4
41+
mapperInit:
42+
; autodetect
43+
.if INES_MAPPER = 0
44+
jsr testHorizontalMirroring
45+
bne not_mmc1
46+
jsr testVerticalMirroring
47+
bne not_mmc1
48+
inc mapperId ; 1 for MMC1, otherwise 0 for CNROM
49+
not_mmc1:
50+
51+
; MMC1
52+
.elseif INES_MAPPER = 1
53+
RESET_MMC1
54+
55+
; CNROM (no init)
56+
.elseif INES_MAPPER = 3
57+
58+
; MMC3
59+
.elseif INES_MAPPER = 4
3060
; https://www.nesdev.org/wiki/MMC3
31-
mmc3Init:
3261
; 110: R6: Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF)
3362
ldx #$06
3463
ldy #$00
@@ -43,18 +72,19 @@ mmc3Init:
4372
lda #$80 ; enable PRG RAM
4473
sta MMC3_PRG_RAM
4574
rts
75+
76+
; MMC5
4677
.elseif INES_MAPPER = 5
4778
; https://www.nesdev.org/wiki/MMC5
48-
mmc5Init:
4979
ldx #$00
5080
stx MMC5_PRG_MODE ; 0: 1 32Kb bank
5181
inx
5282
stx MMC5_CHR_MODE ; 1: 4kb CHR pages
5383
stx MMC5_RAM_PROTECT2 ; 1: enable PRG RAM
5484
inx
5585
stx MMC5_RAM_PROTECT1 ; 2: enable PRG RAM
56-
rts
5786
.endif
87+
rts
5888

5989

6090
MMC1_PRG:

src/util/autodetect.asm

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; Mapper detect code by pinobatch. Only relevant code has been copied and has been modified.
2+
; Original code: https://github.com/pinobatch/holy-mapperel/blob/60ea5c0d97dedca1522525b054012b7c8526f1e1/src/mapper_detect.s
3+
4+
; Original notice:
5+
6+
; Mapper detection for Holy Mapperel
7+
;
8+
; Copyright 2013-2017 Damian Yerrick
9+
;
10+
; This software is provided 'as-is', without any express or implied
11+
; warranty. In no event will the authors be held liable for any damages
12+
; arising from the use of this software.
13+
;
14+
; Permission is granted to anyone to use this software for any purpose,
15+
; including commercial applications, and to alter it and redistribute it
16+
; freely, subject to the following restrictions:
17+
;
18+
; 1. The origin of this software must not be misrepresented; you must not
19+
; claim that you wrote the original software. If you use this software
20+
; in a product, an acknowledgment in the product documentation would be
21+
; appreciated but is not required.
22+
; 2. Altered source versions must be plainly marked as such, and must not be
23+
; misrepresented as being the original software.
24+
; 3. This notice may not be removed or altered from any source distribution.
25+
;
26+
27+
MIRRPROBE_V = %0101
28+
MIRRPROBE_H = %0011
29+
30+
testHorizontalMirroring:
31+
inc mapperId
32+
jsr setHorizontalMirroring
33+
dec mapperId
34+
jsr testMirroring
35+
cmp #MIRRPROBE_H
36+
rts
37+
38+
testVerticalMirroring:
39+
inc mapperId
40+
jsr setVerticalMirroring
41+
dec mapperId
42+
jsr testMirroring
43+
cmp #MIRRPROBE_V
44+
rts
45+
46+
testMirroring:
47+
; write_mirror_probe_vals
48+
ldx #$20
49+
ldy #$00
50+
stx PPUADDR
51+
sty PPUADDR
52+
sty PPUDATA
53+
ldx #$2C
54+
stx PPUADDR
55+
sty PPUADDR
56+
iny
57+
sty PPUDATA
58+
59+
; read_mirror_probe_vals
60+
ldx #$20 ; src address high
61+
ldy #$00 ; src address low
62+
lda #$10 ; ring counter loop: finish once the 1 gets rotated out
63+
readloop:
64+
pha
65+
stx PPUADDR
66+
inx
67+
sty PPUADDR
68+
inx
69+
bit PPUDATA
70+
inx
71+
lda PPUDATA
72+
inx
73+
lsr a
74+
pla
75+
rol a
76+
bcc readloop
77+
rts

0 commit comments

Comments
 (0)