It is currently Mon Aug 21, 2017 6:56 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Sun Aug 13, 2017 10:21 pm 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 182
Location: Central Illinois, USA
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:
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;
}



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


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





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 games: http://www.bitethechili.com


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 10:37 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9905
Location: Rio de Janeiro - Brazil
One thing to keep in mind is that BNROM suffers from bus conflicts, so depending on the value at $8000 (it should be $00 if you're trying to switch to bank $00), a bank other than the one you want could be selected. Not sure if this could have something to do with your problem.


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 10:49 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9905
Location: Rio de Janeiro - Brazil
Oh crap, your header is wrong. The upper nibble of the mapper number is in the wrong position, so this is probably being interpreted as mapper #2, which uses 16KB banks.


Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 4:38 am 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 182
Location: Central Illinois, USA
tokumaru wrote:
Oh crap, your header is wrong. The upper nibble of the mapper number is in the wrong position, so this is probably being interpreted as mapper #2, which uses 16KB banks.


Ah, yup. Thank you, I somehow kept missing that. (I even compared the hex dump of the header with a known good BNROM header and somehow missed it there also)

Which makes sense, as I went to sleep stewing over this issue, I got convinced that it was switching in 16k chunks.

_________________
My games: http://www.bitethechili.com


Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 8:16 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2924
Location: Tampere, Finland
gauauu wrote:
tokumaru wrote:
Oh crap, your header is wrong. The upper nibble of the mapper number is in the wrong position, so this is probably being interpreted as mapper #2, which uses 16KB banks.


Ah, yup. Thank you, I somehow kept missing that. (I even compared the hex dump of the header with a known good BNROM header and somehow missed it there also)

Which makes sense, as I went to sleep stewing over this issue, I got convinced that it was switching in 16k chunks.

Protip: To avoid such errors in the future, replace your header with something like this:
Code:
INES_NUM_16K_PRG_BANKS = 8
INES_NUM_8K_CHR_BANKS = 0
INES_MAPPER_NUMBER = 34
INES_MIRRORING = 0

.segment "HEADER"
    .byte "NES", $1A
    .byte INES_NUM_16K_PRG_BANKS
    .byte INES_NUM_8K_CHR_BANKS
    .byte ( INES_MAPPER_NUMBER & $F ) << 4 | INES_MIRRORING
    .byte INES_MAPPER_NUMBER & $F0

Might as well take advantage of the assembler's expression evaluation abilities.

There's also this: https://wiki.nesdev.com/w/index.php/NES ... r_for_ca65 (instead of the examples there, personally, I would replace 131072 with 128*1024, 524288 with 512*1024, and so on to make it easier to read).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 8:47 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9905
Location: Rio de Janeiro - Brazil
Yeah, best let the assembler shuffle all the bits around for you than doing it in your head each time. I use macros to create my headers.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group