This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

About GNROM and bus conflicts

About GNROM and bus conflicts
by on (#157213)
I'm playing around with some GxROM-based mappers just to find the right one with the most features which fits my needs. Currently having success developing in C and using plain GNROM from emulators.

But I'm a bit concerned about bus conflicts in real hardware. Here's my lame bankswitching code which won't protect you against anything:

Code:
.segment "ROMJUMPER"
_change_rom:
   lda #0
   sta PPU_MASK
   sta PPU_CTRL
   lda $0300
   sta $8000
   jmp start


(This is copied along all PRG-ROMs so it works great).

I understand that, in order to prevent bus conflicts, you have to write to a ROM address with the same value. I know of this technique which I have used for CNROMs as it just needs a table with 4 values.
Code:
; A = bank to swap
tax
sta SwapTable, X
rts
SwapTable:
db $0, $1, $2, $3


Using the same technique for GxROMs would be kinda overkill, I would need a table with 256 values. Am I right? (I have 256 bytes to spare, but I was just wondering if there was a better way?)

And a related question: do GxROM-like mappers such as iNes #140 (Jaleco) which map the register to $6000 avoid such BUS conflicts?
Re: About GNROM and bus conflicts
by on (#157214)
Quote:
Using the same technique for GxROMs would be kinda overkill, I would need a table with 256 values. Am I right?

No, you are wrong. The GNROM board is based on a 74HC161 chip which can only latch 4 bits, and as such, there is at most 16 different values that can be used. The value for unused bits do not matter, so you should just use 0s for them (I mean you could set them to 1s but there's no point).

In the end your typical bankswitching code would look like that :
Code:
_bankswitching_lbl
     lda #something
     sta _bankswitching_lbl+1


The only issue is if you're going to bank switch from a variable. In this case you have no other choice to use a table. GNROM is a bit annoying because the 4 bits are not contigious, and you don't want to waste a lot of ROM because of that, so the best choice is to artificially make the 2 CHR select bits and the 2 PRG select bits contigious, and to dispatch them from a lookup table :

Code:
_bankswitching_lbl
     ldx bankswitching_var
     lda bus_conflict_tbl,X
     sta bus_conflict_tbl,X

bus_conflict_tbl
     .db $00, $01, $02, $03    ; 1st PRG Bank $00-$03
     .db $10, $11, $12, $13    ; 2nd PRG Bank $04-$07
     .db $20, $21, $22, $23    ; 3rd PRG Bank $08-$0b
     .db $30, $31, $32, $33    ; 4th PRG Bank $0c-$0f


If for some reason it is that much important that bankswitching_var reflects exactly what is written to the register, you could do the following :
Code:
[code]
_bankswitching_lbl
     lda bankswitching_var
     and #$03
     sta Temp
     lda bankswitching_var
     and #$30
     lsr A
     lsr A
     ora Temp
     tax
     lda bus_conflict_tbl,X
     sta bus_conflict_tbl,X

bus_conflict_tbl
     .db $00, $01, $02, $03    ; 1st PRG Bank $00-$03
     .db $10, $11, $12, $13    ; 2nd PRG Bank $04-$07
     .db $20, $21, $22, $23    ; 3rd PRG Bank $08-$0b
     .db $30, $31, $32, $33    ; 4th PRG Bank $0c-$0f


Quote:
And a related question: do GxROM-like mappers such as iNes #140 (Jaleco) which map the register to $6000 avoid such BUS conflicts?

As far as I know yes, since there is nothing else mapped to $6000 there cannot be any bus conflict.
Re: About GNROM and bus conflicts
by on (#157215)
As always, I get more than I was expecting from you, guys, this forum is awesome. Thanks for the code snippets, the first one you posted completely fits my needs as I can easily output the bits in the required format. Never thought of that, I think I have to practice my 6502 assembly a bit further.

In other order of things, iNes #140 is a tad more attractive than GNROM (16 CHR-ROM banks are just too sexy!) and it doesn't have bus conflicts, so I'd go for it.

Thanks again!
Re: About GNROM and bus conflicts
by on (#157236)
Oversize GNROM is the variant that would allow addressing 512 KiB of PRG, 128 KiB of CHR, and require a 256 byte table bus conflict prevention table in each 32 KiB PRG bank.

Also consider looking into the Color Dreams mapper, which is basically nybble-swapped oversize GNROM.

On hardware, it's trivial to disable bus conflicts. (At most, it's just an inverter, basically the same cost as the 74'20 you'd need for mapper 140. But even simpler, INL noticed that modern Flash 'PROMs go into hi-Z mode if both /OE and /WE are low, so you can also just tie the 'PROM's /OE line to ground and connect R/W to /WE.) The only tricky part is that some emulators don't allow you to opt out of bus conflicts.
Re: About GNROM and bus conflicts
by on (#157286)
Our hardware boy is studying the Jaleco mapper (iNes 140) and iNes 113. As both can contain a GNROM game and 113 can contain a 140 game we most likely will expand our game using 140 (4 PRG ROM, 16 CHR ROM, reg in $6000-$7FFF).
Re: About GNROM and bus conflicts
by on (#157301)
The real advantage of moving the mapper registers isn't avoiding the bus conflicts, but rather that you can use FlashROM and write to it.

The board I made here has the mapper register at $5000-$5FFF and $7000-$7FFF (it's the same register).
http://forums.nesdev.com/viewtopic.php?f=4&t=12716
Re: About GNROM and bus conflicts
by on (#157304)
Since you're comparing the set of GNROM-like mappers, I may as well point you at my summary of all of them.
Re: About GNROM and bus conflicts
by on (#157359)
Our hardware guy is designing the carts to use just discrete logic with off-the-shelf components.

Thanks for the suggestions. And very interesting chart! I will be looking at the UxROM variants very soon, as long as I learn how to make cc65 behave (I code in C) for such kind of mappers.