I'm trying to set up my ca65/cc65 config and nes header for a BNROM mapper, using 4 32K banks. But it seems that once the game is loaded, and I switch to my first bank, it only loads the first half of the bank ($8000-$C000) and leaves the rest empty ($C000-$FFFA). I'm clearly doing something wrong in the configuration, but it's not obvious to me what that is. Maybe one of you more experienced folks could point me in the right direction?
My ca65 config looks like:
And my iNes header looks like:
When I inspect the file with a hex editor, it appears that all the data from my RODATA segment is in there. But when I start the game, and immediately write 0 to $8000 (to make sure I'm in the first bank), everything from $C000 to $F000 is empty. (my RODATA segment gets cut off halfway through, as it overlaps that point).
Is there something I'm doing wrong in the header or the bankswitching that's causing it to only load half my bank? Thanks, all.
My ca65 config looks like:
Code:
MEMORY {
ZP: start = $10, size = $f0, type = rw;
HEADER: start = 0, size = $0010, type = ro, file = %O, fill=yes, fillval=$00;
RAM: start = $0300, size = $0500, type = rw;
PRG0: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG1: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG2: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG3: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
}
SEGMENTS {
INESHDR: load = HEADER, type = ro, align = $10;
ZEROPAGE: load = ZP, type = zp;
VRAMBUFF: load = RAM, type = bss, define = yes, align = $100;
OAMSHADOW: load = RAM, type = bss, define = yes, align = $100;
BSS: load = RAM, type = bss, define = yes, align = $100;
INIT0: load = PRG0, type = ro, start = $8040;
STARTUP: load = PRG0, type = ro, align = $100;
LOWCODE: load = PRG0, type = ro, align = $100, optional = yes;
CODE: load = PRG0, type = ro, align = $100;
RODATA: load = PRG0, type = ro, align = $100;
VECTORS0: load = PRG0, type = ro, start = $FFFA;
INIT1: load = PRG1, type = ro, start = $8040;
CODE1: load = PRG1, type = ro, align = $100;
RODATA1: load = PRG1, type = ro, align = $100;
VECTORS1: load = PRG1, type = ro, start = $FFFA;
INIT2: load = PRG2, type = ro, start = $8040;
CODE2: load = PRG2, type = ro, align = $100;
RODATA2: load = PRG2, type = ro, align = $100;
VECTORS2: load = PRG2, type = ro, start = $FFFA;
INIT3: load = PRG3, type = ro, start = $8040;
CODE3: load = PRG3, type = ro, align = $100;
RODATA3: load = PRG3, type = ro, align = $100;
VECTORS3: load = PRG3, type = ro, start = $FFFA;
}
FILES {
%O: format = bin;
}
ZP: start = $10, size = $f0, type = rw;
HEADER: start = 0, size = $0010, type = ro, file = %O, fill=yes, fillval=$00;
RAM: start = $0300, size = $0500, type = rw;
PRG0: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG1: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG2: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
PRG3: start = $8000, size = $8000, type = ro, file = %O, fill=yes, fillval=$FF;
}
SEGMENTS {
INESHDR: load = HEADER, type = ro, align = $10;
ZEROPAGE: load = ZP, type = zp;
VRAMBUFF: load = RAM, type = bss, define = yes, align = $100;
OAMSHADOW: load = RAM, type = bss, define = yes, align = $100;
BSS: load = RAM, type = bss, define = yes, align = $100;
INIT0: load = PRG0, type = ro, start = $8040;
STARTUP: load = PRG0, type = ro, align = $100;
LOWCODE: load = PRG0, type = ro, align = $100, optional = yes;
CODE: load = PRG0, type = ro, align = $100;
RODATA: load = PRG0, type = ro, align = $100;
VECTORS0: load = PRG0, type = ro, start = $FFFA;
INIT1: load = PRG1, type = ro, start = $8040;
CODE1: load = PRG1, type = ro, align = $100;
RODATA1: load = PRG1, type = ro, align = $100;
VECTORS1: load = PRG1, type = ro, start = $FFFA;
INIT2: load = PRG2, type = ro, start = $8040;
CODE2: load = PRG2, type = ro, align = $100;
RODATA2: load = PRG2, type = ro, align = $100;
VECTORS2: load = PRG2, type = ro, start = $FFFA;
INIT3: load = PRG3, type = ro, start = $8040;
CODE3: load = PRG3, type = ro, align = $100;
RODATA3: load = PRG3, type = ro, align = $100;
VECTORS3: load = PRG3, type = ro, start = $FFFA;
}
FILES {
%O: format = bin;
}
And my iNes header looks like:
Code:
.segment "INESHDR"
.byt "NES",$1A ; magic signature
.byt 8 ; PRG ROM size in 16384 byte units
.byt 0 ; CHR ROM size in 8192 byte units
.byt $20 ; mirroring type and mapper number lower nibble
.byt $02 ; mapper number upper nibble
.byt "NES",$1A ; magic signature
.byt 8 ; PRG ROM size in 16384 byte units
.byt 0 ; CHR ROM size in 8192 byte units
.byt $20 ; mirroring type and mapper number lower nibble
.byt $02 ; mapper number upper nibble
When I inspect the file with a hex editor, it appears that all the data from my RODATA segment is in there. But when I start the game, and immediately write 0 to $8000 (to make sure I'm in the first bank), everything from $C000 to $F000 is empty. (my RODATA segment gets cut off halfway through, as it overlaps that point).
Code:
.segment "INIT0"
reset_handler:
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT1"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT2"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT3"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "VECTORS0"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS1"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS2"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS3"
.addr nmi_handler, reset_handler, irq_handler
reset_handler:
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT1"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT2"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "INIT3"
lda #0 ;jump to first bank
sta $8000
jmp start
.segment "VECTORS0"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS1"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS2"
.addr nmi_handler, reset_handler, irq_handler
.segment "VECTORS3"
.addr nmi_handler, reset_handler, irq_handler
Is there something I'm doing wrong in the header or the bankswitching that's causing it to only load half my bank? Thanks, all.