Multi-discrete mapper

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

PRG ROM A13 out, if present on the CPLD, needs to match CPU A13 in. That's the only thing I can see that would allow $00 and $FF not to be in $FFF6 and $FFF7, where they are expected to be.
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: Multi-discrete mapper

Post by infiniteneslives »

tepples wrote:PRG ROM A13 out, if present on the CPLD, needs to match CPU A13 in. That's the only thing I can see that would allow $00 and $FF not to be in $FFF6 and $FFF7, where they are expected to be.
Oh man you're right... I guess I didn't put two and two together, your test rom even told me this. I've been ignoring PRG a13 the whole time... My boards have this line split for 8KB PRG banks (mmc3) and they lack a solder jumper to remind me of this. I'll get it fixed up in the code tonight, hopefully that'll be all it takes to get er up and running!
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: Multi-discrete mapper

Post by infiniteneslives »

Well that was it! It's up and running ;)

Not 100% sure what I'm supposed to see, but it looks right:

Code: Select all

INL-ROM Action 53 Mapper 
Interactive behavior test
copr 2012 Damian Yerrick

Mode $00  Outer bank $00

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00
01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01
And I guess your test rom answered/confirmed my reset question while giving me a good chuckle at the same time. ;)

I need to clean up my code a little bit then I'll post it up as is on the wiki.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

Top two rows are $8000-$BFFF, and the bottom two are $C000-$FFFF, for all sixteen values of reg $01. For mode $00 (1-screen mirroring, 32K bank mode, 32K outer bank size) and outer bank $00, the result is correct: bank 0 in $8000-$BFFF and bank 1 in $C000-$FFFF.

Now try the Control Pad and see how the bank numbers respond. Once this interactive test works, and someone gets an emulator to match my Python implementation of the bank formula, I'll work on the automated test.
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Re: Multi-discrete mapper

Post by cpow »

tepples wrote:Once this interactive test works, and someone gets an emulator to match my Python implementation of the bank formula, I'll work on the automated test.
I'm there...I just need to finish the CHR part [I don't have anything else that has 32K CHR-RAM so it's a first so it's a bit of an infrastructure change but not terribly hard] and do a build. Hopefully today.
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: Multi-discrete mapper

Post by infiniteneslives »

I cleaned everything up and updated the code on the wiki. One thing to note, I realized routing PRG R/W to WRAM /WE, and PRG_A13 to PRG-ROM_A13 costs 1 macrocell a peice. If we're looking to save logic in the future, these signals can be routed via wires/jumpers to make room for other logic. I don't have the jumpers on my PCBs so the CPLD is handling those signals right now for ease. That and we've got logic to spare, so not really a concern for now.
tepples wrote:Now try the Control Pad and see how the bank numbers respond. Once this interactive test works, and someone gets an emulator to match my Python implementation of the bank formula, I'll work on the automated test.
Both Mode and outer bank are able to be incremented/decremented from 0 to $3F and wrap around.

While in mode $00 outer bank increments ALL numbers by 2 for each outerbank.

Incrementing Mode while outer bank =$00 will increment the numbers by a few every but only for every few 4-8 values of mode. The pattern is a little irregular, but there is some sort of pattern going on.

If you've got a few specific values for me to check out and report back just let me know. Otherwise things look as 'proper' as I can imagine they should.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Re: Multi-discrete mapper

Post by cpow »

infiniteneslives wrote: If you've got a few specific values for me to check out and report back just let me know. Otherwise things look as 'proper' as I can imagine they should.
Tepples provided a python script that gives test cases and expected output...
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

These behaviors should tell you if you're close.

The lower nibble of mode:
0-7 AOROM/BNROM, banks increment by 2
8-B UNROM #180, bottom rows increment by 1, top rows fixed
C-F UNROM #2, top rows increment by 1, bottom rows fixed

The upper nibble of mode:
0 Bank numbers vary in bit 0
1 Bank numbers vary in bits 1-0
2 Bank numbers vary in bits 2-0
3 Bank numbers vary in bits 3-0
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: Multi-discrete mapper

Post by infiniteneslives »

Checked some of the script outputs and they were gunked up. The first was good though.

Code: Select all

mode $28, outer bank $00
$8000 banks: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
$C000 banks: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
This first one is good

Code: Select all

mode $28, outer bank $3c
$8000 banks: 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
$C000 banks: 78 79 7a 7b 7c 7d 7e 7f 78 79 7a 7b 7c 7d 7e 7f
ALL my first nibbles are 1's instead of 7's for this one...

So it seems something is wrong with my fixed bank of UNROM for both versions.

Mode $08 outerbank $00 looks like this:

Code: Select all

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00
00 01 00 01 00 01 00 01
00 01 00 01 00 01 00 01
Then when I increment outer bank ALL values increment by TWO. Instead of only bottom rows incrementing and top fixed.

Mode $0C outerbank $00 is pretty similar but looks like this:

Code: Select all

00 01 00 01 00 01 00 01
00 01 00 01 00 01 00 01
11 11 11 11 11 11 11 11 
11 11 11 11 11 11 11 11 
same story though, everything increments by two...

The upper nibble of mode seems to be proper.

I can't really see where I could be going wrong with my bankswitching logic in my verilog code... (FYI The code on the wiki is up to date) Am I missing something or mixed up somehow? Maybe you've got more insight as to what the pattern means I'm doing wrong exactly.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

infiniteneslives wrote:

Code: Select all

mode $28, outer bank $3c
$8000 banks: 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
$C000 banks: 78 79 7a 7b 7c 7d 7e 7f 78 79 7a 7b 7c 7d 7e 7f
ALL my first nibbles are 1's instead of 7's for this one...
As I wrote before, the effect of an AND with $1F is expected on a 512 KiB test ROM because the PRG ROM A20-A19 outputs don't go anywhere. Make one with 2 MiB for full $00-$7F range. You can change the size in bankdupe.py.
So it seems something is wrong with my fixed bank of UNROM for both versions.

Mode $08 outerbank $00 looks like this:

Code: Select all

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00
00 01 00 01 00 01 00 01
00 01 00 01 00 01 00 01
Then when I increment outer bank ALL values increment by TWO.
Mode $08 is 32K UNROM #180. When you change to a different 32K bank, all values will change, and they will change by two because outer bank is in 32K units (A15 lowest) and displayed banks are in 16K units (A14 lowest). It matches what the Python script says for those values, at least according to what I get when I add the following at the end:

Code: Select all

test_with_bank_mode_size(0x08, 0x00)
Instead of only bottom rows incrementing and top fixed.
Did you try $18, $28, or $38?
Mode $0C outerbank $00 is pretty similar but looks like this:

Code: Select all

00 01 00 01 00 01 00 01
00 01 00 01 00 01 00 01
11 11 11 11 11 11 11 11 
11 11 11 11 11 11 11 11 
Now that's a problem. The $C000 banks should be 01 to match the Python output:

Code: Select all

mode $0c, outer bank $00
$8000 banks: 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01
$C000 banks: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: Multi-discrete mapper

Post by infiniteneslives »

tepples wrote: Now that's a problem. The $C000 banks should be 01 to match the Python output:

Code: Select all

mode $0c, outer bank $00
$8000 banks: 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01
$C000 banks: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
I must have got things mixed up when coping from the screen to post because my output does match the python output there.

I made the change to the script for 512KB, sorry for missing this point in the discussion earlier... Here was the swaperoo I did:

Code: Select all

    outer_bank = (outer_bank << 1) & 0x1F #512KB
#2MB    outer_bank = outer_bank << 1
So the first two outputs match fine now, along with previous issues I've voiced. But here's what I'm seeing wrong elsewhere: (I'll try not to let my binary dyslexia shine through again...)

EDIT2: Unless you feel like reading what problems I had and how exactly I found/fixed them, save yourself the read and skip down to my EDITs...

My 'mode $28, outer bank $3f' output matches 'mode $28, outer bank $3c' when the script says they should differ.
So for 'mode $28, outer bank $3f' I see:

Code: Select all

$8000 banks: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18
$C000 banks: 18 19 1a 1b 1c 1d 1e 1f 18 19 1a 1b 1c 1d 1e 1f
instead of what the python script says:
mode $28, outer bank $3f
$8000 banks: 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e
$C000 banks: 18 19 1a 1b 1c 1d 1e 1f 18 19 1a 1b 1c 1d 1e 1f



Additionally the next output is wrong, for mode $2c, outer bank $00 I get:

Code: Select all

$8000 banks: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
$C000 banks: 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07

expecting based on script:
mode $2c, outer bank $00
$8000 banks: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
$C000 banks: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
The next one is correct though:

Code: Select all

mode $2c, outer bank $03
$8000 banks: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
$C000 banks: 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07
Did you try $18, $28, or $38?
Now that I think I'm starting to grasp what is going on here exactly they appear correct.

I think it's all coming together for me now... But when I look back at the differences above I don't understand why the script should be giving me this:

Code: Select all

mode $28, outer bank $3f
$8000 banks: 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e
$C000 banks: 18 19 1a 1b 1c 1d 1e 1f 18 19 1a 1b 1c 1d 1e 1f
lower mode nibble is 8 -> UNROM #180 with lower bank fixed to the 'first' bank right? So wouldn't that mean all $8000 banks should be 18???

Same here:

Code: Select all

mode $2c, outer bank $00
$8000 banks: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
$C000 banks: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
UNROM #2 with upper bank fixed to last bank, so shouldn't $C000 banks be 07???

My cart is behaving in the manner I'd personally expect ($8000->18 and $C000->07 from above). So either I messed up the script, there's and issue with the script, or my understanding of how the mapper is supposed to work is wrong. If I'm understanding the mapper behavior wrong then it should be an easy fix because it appears to be operating how I'd expect, I just need to fix my lack of understanding and the problem will present its self... ;)

EDIT: So it looks like cpow and I had/have some similar confusion looking back at the previous discussion:
With the outer bank set to $2A, the 16K banks used by 32K mode are $54 and $55, and the top half of this is $55. More commonly for a ROM of his size, the outer bank would be set to $2F, which produces the expected UOROM-alike last bank in the fixed slot.
I think I'm getting it now...

It kinda stems back to some previous private discussions we had Tepples. I think you've got it set up so that the fixed bank is the current bank, not necessarily the last or the first. My implementation assumes it's the last/first bank that it gets fixed to. Is it beneficial to fix to the current bank vice the last/first? As I remember it consumes more logic to fix the current bank. But for this mapper implementation we've got some logic to spare, so I can change it to fix to the current bank assuming that's what we want. So would this then allow for two smaller possibly non-power of 2 sized games to fit into one larger 'UNROM slot' then?

EDIT 2: I coded it up for the fixed to current outer_bank behavior and fixed up everything. Didn't cost any extra logic or anything either. Everything matches the output of the script now :) I also updated the wiki code. So everything should be good there now and fairly 'final'. Guess I was right about finding my misunderstanding of the behavior and revealing the problem.

Aside from the 32KB CHR RAM issues Tepples should be able to continue testing/development with NESICIDE. The 32KB CHR RAM isn't really planed to be made use of for the 'action15 bundle feat. Streemerz' right? Additionally thefox should be able to take my verilog and dump it into mapper #28 of power pak mappers to allow for additional testing. The one thing to keep in mind when he does that though is default/startup values my code doesn't actually cover that, it's a setting in the fitting properties of Xilinx webpack. Although I don't know how necessary all that is until the ROM is more finalized and we can be more sure that their won't be alterations of the mapper. Now that we've got this test up and running in an emu and hardware we should have most details ironed out in order to proceed with what we currently have.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

infiniteneslives wrote:I think you've got it set up so that the fixed bank is the current bank, not necessarily the last or the first. My implementation assumes it's the last/first bank that it gets fixed to. Is it beneficial to fix to the current bank vice the last/first? As I remember it consumes more logic to fix the current bank. But for this mapper implementation we've got some logic to spare, so I can change it to fix to the current bank assuming that's what we want. So would this then allow for two smaller possibly non-power of 2 sized games to fit into one larger 'UNROM slot' then?
Yeah, it'd be good for a 96K UNROM game that uses only banks 0, 1, 2, 3, 4, and the fixed bank. I seem to remember that Who's Cuter was this way before I improved its CHR compression to fit in 64K.
Aside from the 32KB CHR RAM issues Tepples should be able to continue testing/development with NESICIDE.
(tepples looks in Gitorious commit logs)
Apparently commit 82093e5 added this mapper. My Linux laptop isn't beefy enough to run NESICIDE, but I have access to a faster Windows machine. Are there any publicly available Windows binaries with this commit? Because once I have a working emulator, I can proceed to add an automated test that steps through all of the thousands of possible combinations of mode and outer bank.
The 32KB CHR RAM isn't really planed to be made use of for the 'action15 bundle feat. Streemerz' right?
Correct. It's not needed for NROM, AOROM, BNROM, or UNROM simulation, and all the games in the first volume are on NROM or UNROM.
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Re: Multi-discrete mapper

Post by cpow »

Tepples seems to have gone poof. Incase you missed it there, tepples, read last post in this thread. 8-)
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

Poof yes. Permanent poof no. I'be been getting ready for something IRL, and I just haven't yet had a chance to get on my winbox.

EDIT (Friday): I've got GNU Make, cc65 snapshot, and NESICIDE installed. I'm trying the test program in the NESICIDE emulator.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Multi-discrete mapper

Post by tepples »

I'm having a problem getting AOROM style 1-screen mirroring to work.

When mirroring is 1-screen (port $80 bit 1 is false), writes to bit 4 of port $00 and bit 4 of port $01 are supposed to change bit 0 of the mirroring mode. But for some reason, they're not appearing to take effect.

I made a new version of the test ROM with these changes:
  • If COMSPEC is present (that is, if running under Windows), the makefile adds Python 2.7 to the PATH. GNU Make (MSYS version) can't seem to find the installed .py handler otherwise.
  • I've started to add a fifth line of hex numbers. The first two bytes are related to whether the results match the assembly language version of calc_prg_bank, and the first should be 00 if PRG bank mode is working correctly (or 80 or C0 if it's screwed up). The third is the detected mirroring mode, as described below.
Mirroring modes are read back as follows:

Code: Select all

7654 3210
|||| |||+- Current bank $00, $2000
|||| ||+-- Current bank $10, $2000
|||| |+--- Current bank $00, $2400
|||| +---- Current bank $10, $2400
|||+------ Current bank $00, $2800
||+------- Current bank $10, $2800
|+-------- Current bank $00, $2C00
+--------- Current bank $10, $2C00
These five values are meaningful:
  • 00: 1-screen mirroring, page 0
  • FF: 1-screen mirroring, page 1
  • AA: 1-screen mirroring, page defined by bit 4
  • CC: Horizontal arrangement (vertical mirroring)
  • F0: Vertical arrangement (horizontal mirroring)
If the registers are written in the order $80 then $01, then increasing bank modes from 00 to 03 are supposed to return AA, AA, CC, F0. If the registers are written $01 then $80, then increasing bank modes from 00 to 03 are supposed to return 00, FF, CC, F0. I think my code is writing to $80 then $01, but NESICIDE appears to be ignoring the writes to bit 4 of $01 for some reason.

So I opened it up in NESICIDE, set a breakpoint for read_mode_x_bank_y (CPU executes at $0453), and went to work. I noticed that the nametable visualizer in NESICIDE reacts instantly when I press F8 to step to the next instruction. This is convenient; FCEUX's doesn't. The display of mirroring and internals in Debugger > Cartridge > Information is convenient as well. The write at $455 changes the mirroring to 1-screen (and changes the page as well); the write at $46B should change it to the first or second page, but it doesn't.

I don't know if it's a bug in NESICIDE or a bug in my test, but either way, it'd prevent Battletoads from running correctly.


EDIT: Quads get. By coincidence, the previous quads was the post where #28 was assigned.
Attachments
test28-0.02.zip
(32.91 KiB) Downloaded 608 times
Post Reply