Hey everyone,
My coolboy carts will be arriving in the next few days and I'll build up a prototype cart programmer. It is only intended to support these coolboy carts, both varieties with and without the battery back SRAM. Once I'm happy with the hardware I'll get a short run of boards made up for a more robust professional solution.
The carts in their current form cannot be flashed, you'll need to lift the WE pin on the flash and route it to an unused cart edge pin. Once this is done flashing will be done the same way as with a GB cart in my Joey-Squinson.
These carts have their limitations (mappers etc) though for the price ($5) they are too cheap not to be repurposed!!!
So I'm just interested if anyone wants one of these? I'm still in the design phase but things will progress very quickly once my carts arrive.
I've found 60 pin connectors for $4, I'm still deciding on the MCU solution. Looking at around $25-$30 for the assembled writer with 3d printed enclosure.
Let me know you thoughts!
Great job.
You can try to support with kazzo to flash this cart,but maybe this cart has autoreset circuit.
Auto reset? Do you have more information?
I've just built the hardware to interface with the cart and successfully dumped the menu ROM. Steep learning curve from the GB stuff i'm familiar with.
The question is do I build a cart flasher or do I integrate a MCU into the 72pin shell as a daughter board to convert it to a full, no fuss usb flash cart? This seems like the best solution. No connect/disconnect the rd/wr pins. MCU board would be priced around $10-15 making this a full USB NES flash Cartridge for under $20
What are your thoughts?
The no-solder solution would be for the best.
Will you have software for building multicart ROMs?
There will always be a requirement to solder the two pins, though if it was built into the cart it would only have to happen once.
Yes, I can program a menu builder based around the original Menu ROM. It will replace the ROM names, Location, and Mapper settings to the ROM's header values that you add to the list. This seems like the quickest and easiest option.
That'd be a good first step. The second might be a replacement of the actual menu (the part before the actual program-launching code) with the Action 53 menu so we can get screenshots and quick start manuals right in the ROM.
I'll have to read up on the Action 53 menu. What advantages does it have over the stock menu?
Attached is the Menu ROM's from both the 400in1 and 198in1. I'll take a look today how the menu stores the ROM data in lookup tables and write a bit of python to read and write to the menu list.
BennVenn wrote:
I'll have to read up on the Action 53 menu. What advantages does it have over the stock menu?
Tepples put a lot of effort into polishing it, so it looks a lot less like a generic pirate multicart.
Unlike typical multicart menus, Action 53 menu
- Collects games into tabbed groups, such as "Multiplayer" or "Compo 2011" or "Shmups" or "Toys"
- Shows a screenshot of each game as you page through them
- Shows the author, release year, number of players, and up to 16 lines of instructional text
- Supports a mouse in port 1 or a Zapper in port 2, in case a game also supports one of those
It's currently designed for oversize BNROM and the Action 53 mapper (which has modes simulating CNROM, BNROM, UOROM, and AOROM), but the source code is available to let it be ported to other mappers.


Good looking Ben. Gotta love wire-hell.

My Adsl router died yesterday... what a pain. Wonder if a recap would fix it?
I was trying to dump the whole 32m rom and I was getting weird mirroring throughout the dump. I ended up soldering 25 wires to each address line so I'd have led indicators of address activity.
Many hours later and I have a good rom dump. There are some issues with the wiki coolboy mapper regs. Ill post them when I get my internet back up. Also, A24 is inverted. Something to keep an eye on when issuing flash commands and building rom compilations.
Action 53 looks awesome. Is there a menu generator program too or is it all done manually?
I think ill stick with the stock menu until im more comfortable with nes asm. Unless someone wants to help me?
Ill cad up the schematic and board layout tonight. Hopefully get a batch made up before the new year. Ill do a run of 10. PM me if you want to secure one for yourself.
Nice rats nest jazz

BennVenn wrote:
There are some issues with the wiki coolboy mapper regs. Ill post them when I get my internet back up. Also, A24 is inverted.
I'm not surprised

BennVenn wrote:
Action 53 looks awesome.
Just wait till you
see it in action (no pun intended).
Quote:
Is there a menu generator program too or is it all done manually?
The source code for the menu generator is
here. It reads an .ini file that contains descriptions, .nes filenames (the games), .png filenames (the screenshots), and unused byte ranges in of .nes files (for stashing reset patches, screenshots, and compressed CHR data). It would need to be tweaked to work with the Coolboy mapper instead of BNROM and A53 mappers though.
I've just about got the original menu ROM all mapped out. Here is what I have so far (198in1 cart)
9Bytes per game entry -
0-2 are Jump instructions as found in the original ROM reset vector
3 is cart paramaters. PRG+CHR ROM Size, MMC type etc... This value is used to populate most of the CHR RAM xfer values
4 -PRG ROM Location
5 -PRG ROM Location
6 -CHR ROM Location
7 -CHR ROM Location
8 - Mirroring -H or V
The games menu itself is not mapped in a sequential order. I believe this is to make use of the mappers granularity so small ROMs are positioned lower down, then larger ROM's are further up in multiples of 128k or 256k etc...
Once I find the lookup table to map the Game Name to the game entry table, I'll build my python script to dump and edit the ROM list, re-flash and see how it goes!
I really want to use the Action53 ROM menu. Once I'm all over the Chr Ram xfer routines I'll look into porting it to A53.
one more thing, PCB's. Gold plating the board is essential for long contact life but it is expensive!!! The other options are to de-solder the 60pin socket from the 72pin adapter, point to point solder the daughter board to the 72pin adapter and re-use the 60pin adapter for the daughter board. No gold plating required, cheaper for the end user but does require a bit of soldering.
Or, make the stand alone programmer, where you simply plug your modded FC coolboy cart in and re-flash. This looks like the best option. Maybe I'll do both, or all 3!
I've spent the last few hours building ROM lists using the existing menu - with varying success.
So far, I'm able to extract any ROM on the list, add a .NES header and have it boot in an emulator. I'm able to build my own ROM list using these extracted ROM's, place them anywhere on the flash IC and point the menu to them. This all works fine.
All ROM's I've dumped so far are of Mapper# 0,3 or 4. I've been unable to get a Mapper(1) ROM to boot on the cart using any of the included 'Initialization Routines'
These routines are part of the 9 byte ROM information block and can be one of the following byte values:
$02 - Unknown
$11 - Unknown
$12 - Mapper #4 - 128K/128K - (Double Dragon 3)
$44 - Mapper #3 - 32k/32k - (Aladin 3)
$54 - Unknown
$64 - Mapper #4 - 128k/128k -(Double Dragon 1+2) - Not sure the difference between $12, but they are not compatible
$73 - Mapper #0 - 16k/8k - (Excite bike)
$92 - Unknown
$94 - Unknown
$99 - Unknown
$A9 - Unknown
The menu code checks these values and jumps to a routine which copies a particular amount of CHR ROM to RAM then sets some mapper registers on the cart, then jumps to the reset vector address.
I've had some success adding simple ROM's to the list, like variants of Mario bros. No such luck with more complex ROM's, even ones of the same PRG/CHR ROM sizes and Mappers. I'm not sure why!!!
I'm waiting on my Rockman cart to arrive, these ROM's use all kinds of mappers and contain as much as 512k PRG ROM - which I have been unable to boot on the cart using the above initialization values. It would be good to see how the mapper registers are set up to play these ROM's.
Does anyone have the Rockman coolboy cart?
Are there any ASM guru's here that could look over some code? Progress is slow when you have to reference various documents to see what random register writes are doing!
My hardware has been pretty thoroughly tested. A 1mbyte ROM can be written in under a minute. Pretty happy with it so far!
It seems pretty easy to trap the relevant outer bank writes in FCEUX/Nintendulator's debuggers?
Anyway, you'd said you noticed some issues with the wiki document?
Yes, the only mode I could get a successful dump from the flash was:
#$6000 ABCC DEEE 0, 1, A24, A23 0, A19, A18, A17
#$6001 GHIJ KKLx 0, 1, 0, A20, A22, A21, 1, 0
#$6002 xxxx MMMM 0, 0, 0, 0, 0, 0, 0, 0
#$6003 NPxP QQRx 0, 0, 0, 1, A16, A15, A14, 0
Not a huge problem, I'll need to dig around a bit more to work out the masking. If the last bank of a ROM is mapped to the fixed ROM region, how is it assigned via the mapper? So far only 128k PRG ROM's work, and this is why. Must be due to masking??
I've got the Programmers up for sale on my store, they are being made now and should be shipped over here in the next few days.
Theoretically:
Code:
: 128KiB PRG MMC3:
#$6000 ABCC DEEE z, 1, A24, A23, z, A19, A18, A17
#$6001 GHIJ KKLx 1, 0, 0, A20, A22, A21, dc, dc
#$6002 dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
: 256KiB PRG MMC3:
#$6000 ABCC DEEE z, 0, A24, A23, z, A19, A18, dc
#$6001 GHIJ KKLx 1, 0, 0, A20, A22, A21, dc, dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
: 512KiB PRG MMC3:
#$6000 ABCC DEEE z, 0, A24, A23, z, A19, dc, dc
#$6001 GHIJ KKLx 0, 0, 0, A20, A22, A21, dc, dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
(where "z" is a function of whether 128 KiB or 256 KiB of CHR-RAM is desired)
But I bet you already tried that.
EDIT: correct previous misinterpretation of G H and I bits
I hadn't tried that, I have tried various combinations (while having a logic scope on the address bus) to see the effect. It makes sense now that having MMC3 in control of A17/A18 will allow the correct re-mapping of the fixed bank. Thanks!!!
Unfortunately all my stuff is at my new place which I wont be able to get to until early next week... I might try code a ROM to set a specific mode and bootstrap a 256k PRG ROM.
I'll have to write the ASM, shift it into RAM, execute the register set code, then jump to reset vector of the ROM? (I'll start with a 256K/0K MMC3 ROM)
BennVenn wrote:
I'll have to write the ASM, [copy] it into RAM, execute the register set code, then jump to reset vector of the ROM?
Sounds correct to me.
Do i need to clear RAM, set the stack, set the PPU to a defined state etc? Or can I let the game ROM sort all that out? I'm not calling any subroutines or pushing data so stack shouldn't be required.
I'm thinking this will be enough?
Code:
;----------------------------------------------------------------
; constants
;----------------------------------------------------------------
PRG_COUNT = 2 ;1 = 16KB, 2 = 32KB
MIRRORING = %0001 ;%0000 = horizontal, %0001 = vertical, %1000 = four-screen
;----------------------------------------------------------------
; variables
;----------------------------------------------------------------
.enum $0000
.ende
;----------------------------------------------------------------
; iNES header
;----------------------------------------------------------------
.db "NES", $1a ;identification of the iNES header
.db PRG_COUNT ;number of 16KB PRG-ROM pages
.db $01 ;number of 8KB CHR-ROM pages
.db $00|MIRRORING ;mapper 0 and mirroring
.dsb 9, $00 ;clear the remaining bytes
;----------------------------------------------------------------
; program bank(s)
;----------------------------------------------------------------
.org $8000
Reset:
sei
cld
Copy2Ram:
ldx #$00
C2R:
lda #Program , x
sta #$0100 , x
inx
bne C2R
jmp #$0100
NMI:
IRQ:
Program:
stuff goes here...
;----------------------------------------------------------------
; interrupt vectors
;----------------------------------------------------------------
.org $fffa
.dw NMI
.dw Reset
.dw IRQ
I'll have the MMC registers set up under the Program: Routine, then a jump to the reset vector of the target game ROM?
Anything I'm missing?
The game probably has its own initialization intact, but you won't go wrong doing all the initialization yourself.
Also, if you want to do anything other than just switch immediately to a game (or make an audio-only menu), you'll need to initialize the PPU anyway.
I don't think I'm up to coding a menu just yet, baby steps!
I'll initialise just to be sure.
Thanks
There must be something obvious I'm missing...
I've written my 512kbyte bootstrap program which copies some code to $0100 then executes it. The code sets the Mapper to point to Megaman 4 (512k/0k chr), then jumps to $FE00 which is taken from Megaman4 reset vector.
On the real hardware, I get a black screen.
I've simulated the same writes I've done in the bootstrap program using my writer to the coolboy cart, the mapping seems correct. 0x8000 reflects the first bank of the ROM while 0xC000 reflects the fixed bank (The last bank of the mm4 rom including reset vector etc...) This indicates the 512k ROM is mapped correctly.
Should I be re-enabling interrupts or something prior to jumping to the ROM?
I am assuming the MM4 iNes header of 512k/0k means only the internal NES ram is used? Or is the ROM expecting CHR RAM? Either way, wouldn't I still get sound/game play but with corrupted/no graphics?
HELP!!!
0kB CHR means it expect CHR-RAM, but yeah more than likely with bad CHR it would run, but with corrupt graphics.
In case you have the wrong bank mapped in somehow, instead of JMP $FE00 you should try a JMP ($FFFC). That will do an indirect jump using the actual reset vector, that would more than likely should do something, even if the wrong bank was mapped in. As long as it has a reset vector present, and the mapper is ready to accept the game's mapper writes. Games typically have a reset vector in every bank that can be mapped there (because there's no predicting when the player will hit the reset button).
You should have NMIs disabled, but I doubt you had them enabled to begin with. The game's reset code should take care of initializing everything. Note that all that I'm saying is under the assumption that the ROMs intended for the cartridge weren't hacked in any way.
This MegaMan4 ROM is a Direct rip from a PAL cart, runs fine in an emulator.
Tried jumping indirectly via $FFFC, and also threw in a bunch of NOP's incase it was a timing issue. Still no luck.
Below is an extract from the coolboy menu where the mapper mode is set and what appears to be a zeroing of the bank registers? Also looks like it is populating the CHR RAM. If anyone has a clue what this code is actually doing, please share.
Code:
:0200:AD 14 01 LDA $0114 = #$E0 -Temp storage of ROM location
:0203:8D 00 60 STA $6000 = #$E0
:0206:AD 15 01 LDA $0115 = #$84 -Temp storage of ROM location
:0209:8D 01 60 STA $6001 = #$84
:020C:AD 16 01 LDA $0116 = #$00 -Temp storage of ROM location
:020F:8D 02 60 STA $6002 = #$00
:0212:AD 17 01 LDA $0117 = #$00 -Temp storage of ROM location
:0215:8D 03 60 STA $6003 = #$00
:0218:A9 00 LDA #$00
:021A:8D 11 01 STA $0111 = #$00
:021D:A9 06 LDA #$06
:021F:8D 00 80 STA $8000 = #$00
:0222:AD 1C 01 LDA $011C = #$00
:0225:18 CLC
:0226:6D 11 01 ADC $0111 = #$00
:0229:8D 01 80 STA $8001 = #$01
:022C:AD 11 01 LDA $0111 = #$00
:022F:0A ASL
:0230:0A ASL
:0231:0A ASL
:0232:AA TAX
:0233:A0 00 LDY #$00
:0235:8C 00 80 STY $8000 = #$00
:0238:8E 01 80 STX $8001 = #$01
:023B:E8 INX
:023C:E8 INX
:023D:C8 INY
:023E:8C 00 80 STY $8000 = #$00
:0241:8E 01 80 STX $8001 = #$01
:0244:E8 INX
:0245:E8 INX
:0246:C8 INY
:0247:8C 00 80 STY $8000 = #$00
:024A:8E 01 80 STX $8001 = #$01
:024D:E8 INX
:024E:C8 INY
:024F:8C 00 80 STY $8000 = #$00
:0252:8E 01 80 STX $8001 = #$01
:0255:E8 INX
:0256:C8 INY
:0257:8C 00 80 STY $8000 = #$00
:025A:8E 01 80 STX $8001 = #$01
:025D:E8 INX
:025E:C8 INY
:025F:8C 00 80 STY $8000 = #$00
:0262:8E 01 80 STX $8001 = #$01
:0265:A9 00 LDA #$00
:0267:8D 06 20 STA $2006 = #$01
:026A:8D 06 20 STA $2006 = #$01
:026D:85 C3 STA $00C3 = #$00
:026F:A9 80 LDA #$80
:0271:85 C4 STA $00C4 = #$80
:0273:A2 20 LDX #$20
:0275:A0 00 LDY #$00
:0277:B1 C3 LDA ($C3),Y @ $8001 = #$01
:0279:8D 07 20 STA $2007 = #$00
:027C:C8 INY
:027D:D0 F8 BNE $0277
:027F:E6 C4 INC $00C4 = #$80
:0281:CA DEX
:0282:D0 F3 BNE $0277
:0284:EE 11 01 INC $0111 = #$00
:0287:AD 11 01 LDA $0111 = #$00
:028A:CD 1D 01 CMP $011D = #$10
:028D:90 8E BCC $021D
:028F:A9 00 LDA #$00
:0291:8D 06 20 STA $2006 = #$01
:0294:8D 06 20 STA $2006 = #$01
:0297:78 SEI
:0298:D8 CLD
:0299:A9 C0 LDA #$C0
:029B:8D 17 40 STA $4017 = #$FF
:029E:A2 08 LDX #$08
:02A0:2C 02 20 BIT $2002 = #$00
:02A3:10 FB BPL $02A0
:02A5:2C 02 20 BIT $2002 = #$00
:02A8:30 FB BMI $02A5
:02AA:CA DEX
:02AB:10 F3 BPL $02A0
:02AD:9A TXS
:02AE:A2 06 LDX #$06
:02B0:A0 0C LDY #$0C
:02B2:8E 00 80 STX $8000 = #$00
:02B5:8C 01 80 STY $8001 = #$01
:02B8:E8 INX
:02B9:C8 INY
:02BA:8E 00 80 STX $8000 = #$00
:02BD:8C 01 80 STY $8001 = #$01
:02C0:AD 18 01 LDA $0118 = #$C3
:02C3:8D 00 60 STA $6000 = #$E0
:02C6:AD 19 01 LDA $0119 = #$90
:02C9:8D 01 60 STA $6001 = #$84
:02CC:AD 1A 01 LDA $011A = #$00
:02CF:8D 02 60 STA $6002 = #$00
:02D2:AD 1B 01 LDA $011B = #$80
:02D5:8D 03 60 STA $6003 = #$00
:02D8:4C 00 01 JMP $0100
From what I can tell, CHR ROM is selected in the Flash, it is copied to the CHR RAM, PRG ROM is then mapped in and then a jump to $100 is made, which contains a jump to the reset vector of the target game. What I haven't done is locked the mapper before the jump by writing $80 > $6003. I'll try that now.
Success!
Needs the Mapper locked with $80 > $6003 before it boots.
Merry Xmas!
lidnariq wrote:
Theoretically:
Code:
: 128KiB PRG MMC3:
#$6000 ABCC DEEE z, 1, A24, A23, z, A19, A18, A17
#$6001 GHIJ KKLx 0, 1, 0, A20, A22, A21, dc, dc
#$6002 dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
: 256KiB PRG MMC3:
#$6000 ABCC DEEE z, 0, A24, A23, z, A19, A18, dc
#$6001 GHIJ KKLx 0, 1, 0, A20, A22, A21, dc, dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
: 512KiB PRG MMC3:
#$6000 ABCC DEEE z, 0, A24, A23, z, A19, dc, dc
#$6001 GHIJ KKLx 0, 0, 0, A20, A22, A21, dc, dc
#$6003 NPxP QQRx 0, 0, dc, 0, dc, dc, dc, dc
(where "z" is a function of whether 128 KiB or 256 KiB of CHR-RAM is desired)
But I bet you already tried that.
I'm having a hard time trying to get my head around exactly HOW the mapper fixes the last bank to the one memory region while letting others be swapped in and out. I get that simple logic gates can logically AND address lines to test for a particular memory region access. What I don't understand is how a MMC3 mapper can be configured for 128k, 256k or 512k ROMs.
From the above 3 samples, only the 512Kib mode works, the others fail to map the last bank in the expected memory location. I've tried combination upon combination to try map a 256k ROM, and bank0 appears at 0x8000 and a write to the mmc3 can swap in any bank into that location, however 0xFFFC is incorrect and always points to the last bank of a 512k ROM instead of the reset vector of the last bank of the 128k ROM.
I've logged a few of the original coolboy mapper writes when selecting a 128k ROM, the only common bit from all 4 registers is bit7 of $6001 always being a 1. This only ever changes when selecting a 256k or 32k ROM.
I suppose I could mirror 128k ROM's to pad out to 512k but that would be a waste and the original multicart clearly doesn't do this.
Any ideas where I should be looking? I've got pages of notes in front of me trying to piece together what the original menu ROM is trying to do and I've got most of it nailed, except for this!
I've decided to go about this a little different. I've created a 512kbyte file, filled with $00. I've inserted keywords like 512, 256, 128, 64, 32 thought the ROM at what should be 0xFFF0 of a ROM of a particular size. When I get the mapper to map the ROM in, if all is well, and i read 0xFFF0 I'll get one of the keywords I've inserted, depending on how it has been mapped.
By default, reset power on etc, I read 0xFFF0 and get
Code:
array('B', [5, 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Indicating the full 512k is mapped correctly.
I then send $00>$6000 $80>6001 $00>6002 $00>6003 and get
Code:
array('B', [2, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
This doesn't align with my interpretation of the mapper registers.
I've tried various other values to the registers but cant trigger any of my other keywords. I'll write some code to brute force it...
Does this make sense to anyone?
Edit:
Brute Force Results for 128k mapping:
First byte is $6000, second is $6001
Code:
Match 0x40 0x80
Match 0x48 0x80
Match 0xc0 0x80
Match 0xc8 0x80
Match 0x40 0x81
Match 0x48 0x81
Match 0xc0 0x81
Match 0xc8 0x81
Match 0x40 0x82
Match 0x48 0x82
Match 0xc0 0x82
Match 0xc8 0x82
Match 0x40 0x83
Match 0x48 0x83
Match 0xc0 0x83
Match 0xc8 0x83
bits 0&1 of $6001 are 'dont care' which leaves us with:
Code:
Match 0x40 0x80
Match 0x48 0x80
Match 0xc0 0x80
Match 0xc8 0x80
bit 3&7 of $6000 is also dont care so we get:
Code:
Match 0x40 0x80
Looks like the interpretation of GHI is wrong, given the numbers you found.
It's totally possible I made a mistake when I was reinterpreting FCEUX's source ... unless you're already testing that too.
That makes sense, GHI never really worked the way it was documented when dumping the carts contents.
If I could get FCEUX booting my ROM's that would be great! I'm not sure how to build the correct header to get it to boot, or how to compile the source for the one or two versions that have the coolboy mapper added.
I might just reverse engineer the whole thing from scratch. I'll write a 2mbyte ROM to the cart with keywords scattered in all the important places, 128k boundaries, 8kbyte boundaries, 1kbyte boundaries then brute all the mapping combinations that I think are important.
I think there is more going on inside this chip than FCEUX's source lets on. There must be a way to tell the mapper the ROM size. I can't think how MMC3 would work otherwise for more than 1 ROM size.
I haven't understood a lot of the preceding discussion about how a particular cart arranges the bits that control each particular address line. But here's the general outline of how
any multicart would select game size.
- 128K: A17 and above come from the outer mapper, and A16 and below come from the MMC3
- 256K: A18 and above come from the outer mapper, and A17 and below come from the MMC3
- 512K: A19 and above come from the outer mapper, and A18 and below come from the MMC3
This might be implemented several ways:
- A pair of muxes controls the A17 and A18 select lines, choosing between A18-A17 from the MMC3 and the corresponding bits in the outer mapper
- The bits from the MMC3 are ANDed with the select bits, and then the corresponding bits in the outer mapper is ORed onto it
- The bits from the MMC3 are ORed with the select bits, and then the corresponding bits in the outer mapper is ANDed onto it
- The bits from the MMC3 are ANDed with the select bits, and then the corresponding bits in the outer mapper is XORed onto it
- The bits from the MMC3 are ORed with the select bits, and then the corresponding bits in the outer mapper is XORed onto it
The "game size" bits in the Action 53 mapper behave similarly to option a above, where bits 5-4 of register $80-$81 control how many of A15 through A17 are replaced with outer bank bits 0 through 2 when the CPU is reading outside the game's fixed bank.
Thanks for the info Tepples, I think the coolboy mapper is also similar to a) on your list.
Here is what I have found, this confirms the information on the wiki is incorrect.
Cool($6000,$6001,$6002,$6003)
Code:
Cool(0x00,0x00,0,0)
Maps 512kbyte ROM
Cool(0x00,0x80,0,0)
Maps 256kbyte ROM
Cool(0x40,0x80,0,0)
Maps 128kbyte ROM
128kbyte mapping
Cool(0x41,0x80,0,0)
Maps second 128kbyte ROM, Offset A17 in bit0 of $6000
Cool(0x42,0x80,0,0)
Maps third 128kbyte ROM, Offset A17 in bit0, A18 in bit1 of $6000
Cool(0x43,0x80,0,0)
Maps fourth 128kbyte ROM, Offset A17 in bit0, A18 in bit1 of $6000
256kbyte mapping
Cool(0x01,0x80,0,0)
Maps 256kbyte ROM. Bit0 (A17) in $6000 not responsive
Cool(0x02,0x80,0,0)
Maps second 256kbyte ROM. Bit0 (A17) in $6000 not responsive, Bit1=A18
Cool(0x04,0x80,0,0)
Maps Third 256kbyte ROM. Bit0 (A17) in $6000 not responsive, Bit1=A18, bit2=A19
512kbyte mapping
Cool(0x04,0x00,0,0)
Maps second 512kbyte ROM. Bit0&1 not responsive, Bit 2=A19
The remainder of the upper address bytes seem to be valid as seen on the Flash IC's address bus. The exception is the most significant bit A24 is inverted but that really doesn't make any difference as it doesn't affect flash commands so we can leave it alone.
This should be enough to get a majority of the ROM's working on this cart. This doesn't explain how I could boot mario (32k) using mm3 without padding the ROM to 128k using 32k mirrors. I'll need to look into GNROM mode for 32k ROM's. I'm dumping and flashing these carts in GNROM mode, just need to work out the fixed address mapping.
Also interesting to note is the wiki states the mmc3 can address up to 2mbyte ROM's. So far I've been unable to move the fixed bank up past 512kbytes.
BennVenn wrote:
If I could get FCEUX booting my ROM's that would be great! I'm not sure how to build the correct header to get it to boot
The simplest way I can think of to do this is to use a program that will pack/unpack UNIF files ... like this program I created a while ago:
Attachment:
unif_packer_unpacker.7z [32.18 KiB]
Downloaded 124 times
You should only need a MAPR chunk and a PRG0 chunk, I think.
There is a russian gaming site that has dumped almost all the coolboy carts and included a UNIF header to boot them in an emulator. Problem is I get the 'mapper not supported' error as the coolboy mapper needs to be included at build time?
COOLBOY support only began as of January this year, but 2.2.2 dates to September 2013. You'll need a build from svn.
Found 2.2.3 and it works fine with coolboy ROM's.
Now i've found I'm having trouble booting 128k ROM's. The PRG data is fine, but the CHR data is a bit screwed up.
It must be in my CHR RAM copying routine, or maybe mapping... I've taken the chr routine from the coolboy cart so I don't think its that.
Anyone care to take a look to see if there is anything obvious?
I have been stepping through in fceux and sometimes a mapper write to $06>$8000 and say, $02>$8001 shows $8001 as $07????
Code:
;----------------------------------------------------------------
; constants
;----------------------------------------------------------------
PRG_COUNT = 32 ;1 = 16KB, 2 = 32KB
MIRRORING = %0001 ;%0000 = horizontal, %0001 = vertical, %1000 = four-screen
;----------------------------------------------------------------
; variables
;----------------------------------------------------------------
.enum $0000
.ende
;----------------------------------------------------------------
; iNES header
;----------------------------------------------------------------
.db "NES", $1a ;identification of the iNES header
.db PRG_COUNT ;number of 16KB PRG-ROM pages
.db $00 ;number of 8KB CHR-ROM pages
.db $00|MIRRORING ;mapper 0 and mirroring
.dsb 9, $00 ;clear the remaining bytes
;----------------------------------------------------------------
; program bank(s)
;----------------------------------------------------------------
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $8000
;Bank Data here:
ORG $C000
BASE $C000
Reset:
sei
cld
lda $2000
and #$FB
sta $2000 ;set up auto incrment vram
;SET UP CHR RAM, LOCATION $A0000
LDA #$45
STA $0114
LDA #$80
STA $0115
LDA #%00000000
STA $0116
LDA #%00000000
STA $0117
;SET UP PRG ROM, LOCATION $80000
LDA #$44
STA $0118
LDA #$80
STA $0119
LDA #%00000000
STA $011A
LDA #%10000000
STA $011B
LDA #$10
STA $011D ;NUMBER OF 8KBYTE BLOCKS TO COPY
LDA #$00
STA $011C ;BANK OFFSET OF CHR ROM
Copy2Ram:
ldx #$00
C2R:
lda #Program , x
sta #$0200 , x
inx
bne C2R
jmp #$0200
Program:
LDA $0114 ;CHR ROM LOCATION IN FLASH
STA $6000
LDA $0115
STA $6001
LDA $0116
STA $6002
LDA $0117
STA $6003
LDA #$00
STA $0111 ; COUNTER OF 8K CHR BLOCKS TO COPY TO RAM
LOOP0:
LDA #$06
STA $8000
LDA $011C ;WHASSS SSSISSSSS?
CLC
ADC $0111
STA $8001
LDA $0111
ASL
ASL
ASL
TAX
LDY #$00
STY $8000
STX $8001
INX
INX
INY
STY $8000
STX $8001
INX
INX
INY
STY $8000
STX $8001
INX
INY
STY $8000
STX $8001
INX
INY
STY $8000
STX $8001
INX
INY
STY $8000
STX $8001
LDA #$00
STA $2006 ;SET VRAM ADDRESS TO $0000
STA $2006
STA $00C3
LDA #$80
STA $00C4
LDX #$20
LDY #$00
LOOP1:
LDA ($C3),Y
STA $2007
INY
BNE LOOP1
INC $00C4
DEX
BNE LOOP1
INC $0111
LDA $0111
CMP $011D
BCC LOOP0
LDA #$00
STA $2006
STA $2006
SEI
CLD
LDA #$C0
STA $4017
LDX #$08
LOOP2:
BIT $2002
BPL LOOP2
LOOP3:
BIT $2002
BMI LOOP3
DEX
BPL LOOP2
TXS
LDX #$06
LDY #$0C
STX $8000
STY $8001
INX
INY
STX $8000
STY $8001
LDA $0118
STA $6000
LDA $0119
STA $6001
LDA $011A
STA $6002
LDA $011b
STA $6003
JMP ($FFFC)
NMI:
IRQ:
.org $fffa
.dw NMI
.dw Reset
.dw IRQ
Any chance that the default menu uses a different order of 8KiB slices, or 256-byte pages within an 8KiB slice, than the original CHR-ROMs?
I've pulled Contra 2 out of the coolboy cart and it matches byte for byte with a downloaded version so I don't think that is it.
I read somewhere the PPU takes 80,000clk cycles to initialise? Do you think that is why?
Also, I'm having the same issue with Mario2, except this time I can partially re-create the issue in the emulator if I don't specify mirroring in the Unif header. If I specify then it boots and plays fine in the emulator.
I've tried setting the mmc to vertical or horizontal before jumping to its reset vector address but it didn't make a change.
Very confused...
The front-loader's PPU takes a full field of video (262 scanlines NTSC, 312 scanlines PAL) before it accepts writes to $2006, but that should only cause a subset of the game's CHR to be lost, if that's what's to blame.
Waiting for the PPU to warm up is really easy, though:
nesdevwiki:PPU power up state
Tried this:
Code:
LDX #$08
LOOP12:
BIT $2002
BPL LOOP12
LOOP13:
BIT $2002
BMI LOOP13
DEX
BPL LOOP12
This was taken from the cart's menu.
Still not working....
With Bugs Bunny's Birthday Blowout, all the CHR is fine up until the game begins where it is a mess. This hints at a partial transfer?
BennVenn wrote:
There is a russian gaming site that has dumped almost all the coolboy carts and included a UNIF header to boot them in an emulator. Problem is I get the 'mapper not supported' error as the coolboy mapper needs to be included at build time?
Why not ask more informations from
Cluster ?
He's the owner of the «russian gaming site».
I'll do that.
I've also started coding a test program to confirm the data read back from cHr ram is the data written. this should help identify the problem
I think I need some graphical feedback. Is there a reference to the minimum needed setup to display a limited ascii set?
From the GB world, I'd copy a bunch of tiles, set up a pallete, then set the OAM to draw up some sprites. Is it as simple as that on the NES?
Edit: I've just found Dwedit's HelloWorld.asm I've relocated the Font table to bank0, and modified the code. Looks good. I'll set up different font tables in each bank then have them cycled through one at a time to see if I can catch out something going wrong.
If I don't see anything I'll do a full CHR RAM copy and read back the checksums to find any corruption.
At least I'm learning some NES ASM!
That's basically it. Wait for the PPU to be ready, write a palette (to PPU $3F00-$3F1F instead of GBCPU's 0xFF47,8,9), write some tiles (to PPU $0000-$1FFF instead of GBCPU's 0x8000-0x97FF), write a nametable (to PPU $2000-$2FFF instead of GBCPU 0x9800-0x9FFF), and enable video (via writes to CPU $2000,1 instead of GBCPU $FF40)
Yes.
First wait for the PPU to warm up:
Code:
lda #0
sta $2000 ; disable NMI and set video memory increment to +1
sta $2001 ; disable rendering
bit $2002 ; clear in case reset was pressed during vblank
vwait1:
bit $2002
bpl vwait1
; At this point you have about 30,000 cycles to burn for
; other mapper initialization if necessary
vwait2:
bit $2002
bpl vwait2
Then load a palette into CGRAM $3F00-$3F1F, load a font into CHR RAM $0000-$07FF, load some text into the nametable at $2000-$23FF or DMA a sprite display list to OAM, set the scroll position, and turn on rendering.
Thanks guys.
I've placed nametable data in each bank though something fishy is going on with bank switching.
It is as though LSbit of 8001 doesn't do anything. Ill re read the wiki. I might not have set up the mapper correctly.
The 2KiB CHR banks on the MMC3 ignore its LSB, if that's what you're encountering. (i.e. the number you write is always an offset in 1024-byte units, not a direct bank #)
Its with the prg banks. $06> $8000
All good, just my interpretation of the mapper. 8Kib mapped blocks. No problem.
OK, bootstrap program swaps out the 512kbyte ROM and executes it. It displays the contents of all 64 mapped banks, no problems there.
Next up is CHR Ram verification.
Is there a way to detect mirroring? Am I just looking for mirrored address space in the PPU's address space?
Write $00 at $2000 and $01 at $2C00, then read back from $2400. It'll be $00 for horizontal mirroring (AABB) or $01 for vertical mirroring (ABAB), just like bit 0 of iNES flags 6. Untested code follows:
Code:
.proc detect_mirroring
lda #$20
ldx #$00
sta PPUADDR
stx PPUADDR
stx PPUDATA ; vram[$2000] = $00
lda #$2C
sta PPUADDR
stx PPUADDR
lda #$01
sta PPUDATA ; vram[$2C00] = $01
lda #$24
sta PPUADDR
stx PPUADDR
bit PPUDATA ; prepare read from vram[$2400]
lda PPUDATA ; complete the read
rts
.endproc
But MMC3 itself has unspecified mirroring at power-on. This means a game that has been properly mapper-hacked or otherwise developed for MMC3 will set the mirroring at least in its init code. Something developed for mapper 206 (Namco 108/Tengen MIMIC-1), such as
Karnov or
RBI Baseball series, might need mirroring to be set up in advance because these games assume hardwired mirroring.
OK,
My code fills all 128K CHR RAM with data from bank 0-16, then reads back and compares byte for byte the data in CHR RAM. 100% match.
So why doesn't Bugs Bunny birthday blowout or Mario2 work on this cart?
megaman 3+4 works fine. MM4 doesn't rely on CHR RAM on the cart, and MM3 is 128k/128k, H mirroring and is more or less identical to Mario2/bugs...
I'm thinking mario/bugs could be writing to a different address to swap banks? That could explain what is going wrong on these games and not others. Or it could be a mirroring thing? Forcing bad mirroring in fcuex can simulate some of the artifacts I'm seeing on the real NES which makes me think it could be related.
The NES ALU is pretty cool though, comparing a value from an indirect memory location using an 8bit pointer, with an offset.
Code:
cmp ($C3),Y
All without modifying the accumulator. Very cool.
Edit:
I had a look at the mapper access of SMB2, it sets A12 inversion for all its writes. This could be the cause. I then looked into Bugs, there is absolutely nothing odd with any of its mapper access. All standard addresses, Mirroring is set to 1, 3 times throughout the startup into the game. Pretty lost in all this!
I changed all mirror writes from 1 to 0 to see the effect in the emulator. It changed the starting location of bugs in his crazy world, but otherwise completely playable.
I got in touch with Cluster,
He has a ROM compilation generator online, super easy to use! I just built a ROM list including the trouble ROM's and get the same problem on the NES. Its satisfying to know its not my coding that is bugging out!
It must be the carts compatibility with the original front loading PAL NES. I remember reading somewhere online that there is a mod you must do, bridge one of the CHR bus lines across the 60-72 pin adaptor. I can't find it though. Does anyone know where I could find that info?
Just waiting back on cluster to test smb2 and bugs on his console to verify it is a system issue, not a ROM issue.
Finally my 150in1 Rockman Coolboy cart (with Battery and WRAM) arrived. I noticed Mario2 worked on this cart. I thought it could have been patched so I dumped the full 32mb and re-flashed to the non-save coolboy cart.
Same fault when running on the non-save cart.
I've tried breaking and bridging all the possible jumpers on the cart with no change in the fault.
I'm going to try narrow down exactly what is going wrong with Mario2. It could be an accidental mapper CHR page swap that isn't there, or a rogue write to a register (But this doesn't occur with the save-cart). Interesting...
Otherwise, the 150-in-1 with battery save is the cart you want!
Edit: OR!!! it could be that the 150in1 has an onboard 3.3v regulator?!?!?! OR Bus collision forcing an mapper reset?
All the COOLBOY carts have to have some kind of 3V regulator; the FLASH 'PROM will rapidly die if its Vcc is above 4V.
The 400-in-1 doesn't. It has a single diode with a fwd voltage drop of .55volts inline with VCC however there is a pad next to it which shorts it effectively passing VCC to all the IC's. I'm pretty sure these carts are designed for Pocket NES/FC systems which are 3.3v native.
I'm just adding 3 signal diodes to drop it to about 3.5volts and a cap to help with transients.
Edit: No Change. I'm thinking more bus collision/bad mapper switch
Why do you think 'ZELDA' is written into the ROM next to the interrupt vectors?
I'd bet
Doki Doki Panic was the next game that Nintendo ported from FDS to cartridge after
Zelda no Densetsu. Because somebody at Nintendo forgot to change the PRG ROM footer, every authentic Game Pak of
Super Mario Bros. 2: Mario Madness contains the string "ZELDA".
See
The Cutting Room Floor,
previous post,
previous post, and
previous post.
SMB2 needs WRAM, does the other cart have it?
Quote:
SMB2 needs WRAM, does the other cart have it?
Whaaaaat! Is it really that simple? I can't believe I overlook that!
Is that in the iNes header or something?
Ahhhh I just trapped all writes to A001 and 6000-7FFF and yeah, Bugs uses WRAM too. So simple its frustrating!
Nope, the original iNES header only shows if the WRAM is battery-backed or not, emulators just had to assume WRAM is there. The later NES 2.0 standard does specify if WRAM is present.
http://wiki.nesdev.com/w/index.php/NES_2.0Best way to be sure what's on the cart is to look at it, thankfully there is an excellent resource for that:
http://bootgod.dyndns.org:7777/
Sorta.
If the "battery backed" flag is set, then the cart definitely has PRG RAM. If it's not ... well ... what Memblers said.
Thanks heaps guys!
Same with Bugs, WRAM. Works fine on the WRAM Cart
Would it be possible to use this mapper to create a program which utilizes a massively oversized CHR-ROM?
Is it possible to instantly switch which section of ROM is available as you would switching a bank?
No, COOLBOY is still restricted to 128/256 KiB CHR RAM (depending on the specific hardware)
You could fake it by disabling rendering, copying all the data over (which is going to be SLOW, btw), and re-enabling the game, but ... if you're writing new software, you should just use the RAM as RAM rather than lousy ROM.
PRG ROM can be banked dynamically, but the location of the banking registers means that you can't really use PRG RAM in a game that needs access to the COOLBOY outer bank registers.
Okay, so all CHR is RAM, but you can bank the RAM, right? Like a VRC7, except that VRC7 is not readily available in any form.
So, could you, in theory, decompress all of the graphics for a level onto the 256KB of CHR-RAM and then bankswap them during gameplay for faster frame transitions?
Furthermore, would it be possible to store the graphics on a different section of the PRG outer bank, switch over during a break in gameplay, copy, then swap back to the program?
I'm finding that the animations that I'm designing are not going to fit in a 256KB CHR-ROM. Looking for an option to expand that.
Yes, it has the ordinary MMC3 CHR banking registers ... just applied to CHR RAM.
And yes, pre-loading the CHR RAM is how the original pirate multicarts work.
Would using a multi cart like this and preloading graphics on a per-level basis be a reasonable solution for creating a game that exceeds normal CHR limits?
It looks like activating the lockout is a one-way trip. After the lockout is set, $6003 will be treated as WRAM, right? Meaning that I couldn't use WRAM and flip between outer banks, but the PRG-ROM size is 2 MiB anyway though, so that's plenty.
Sorry for so many questions!
There's the notable loophole that WRAM addresses which are A%4=2 correspond exclusively to GNROM mode CHR bank #, and so you could use those 2 KiB of PRG RAM safely if awkwardly.
Soldering 30 solid core wire wrap wires was frustrating! Definitely using hookup wire next time. Below is the ARM STM32 board fitted to the 72pin 256k coolboy cart.
All I/O is High-Z input until USB enumeration is complete where it takes over the bus. You should NEVER have USB connected while the cart is in the console. The STM32 is a 3.3v part with 5v tolerant IO. The NES can source/sink far more current than the STM could and will instantly destroy its IO drivers. I've put the USB port on the side of the cart for that reason but some consoles will still allow an accident to occur.
My Version 2.0 PCB will fit between the 60 and 72 pin boards and remove the need for the 30 point to point wires. I was even thinking of making an integrated 72pin adapter board with the STM on there, though this would require gold plating which will drive the price up a bit.
If there is enough demand I'll make a small run, otherwise I have the 60pin socketed PCB's ready or just the bare STM board as in my 72pin cart below.
$12 for the STM board, programmed and shipped (No tracking, insurance etc....) Firmware updates via USB, PC side software coded in Python 3.4 and also compiled into an executable binary for windows. The python can be ported to any OS if you know what you are doing. TKinter is buggy on OSX.
Add $4 if you want the 60Pin Coolboy Programmer PCB (Bare, no 60pin socket etc...)
OR if time is money, I can sell you a pre-made flash cart. PM me.
I'll add WRAM reading/writing in the next firmware version.
I'm going to get one of these, and I've been brainstorming on what might be possible with them.
First, I've heard that the Wiki may be wrong and that the ROM size may be limited to 512KiB with MMC3 mode. Has anyone successfully used a 2 MiB ROM in MMC3 mode?
Okay, so you can't use WRAM while adjusting the outerbank, but is that the only limitation? With 32 MiB of PRG storage, it wouldn't be hard to write a program that doesn't need WRAM. If you wanted to save progress, you could even wait to lockout when somebody selects "save and quit", then lockout, save, and reset to title menu, right?
Can you LDA from WRAM while registers are not locked out? That would make it easier to read save data without doing a reset trick.
I'm guessing it's not, but I just want to go ahead and ask if the CHR-RAM is dual ported, meaning that you could start a copy to it without turning off rendering? Like I said, I'm guessing this isn't the case, because people said dual ported RAM is pretty expensive.
darryl.revok wrote:
First, I've heard that the Wiki may be wrong and that the ROM size may be limited to 512KiB with MMC3 mode. Has anyone successfully used a 2 MiB ROM in MMC3 mode?
The wiki notes are just my interpretation of FCEUX's source, where ClusteR wrote in a comment "Regular MMC3 mode, internal ROM size can be up to 2048kb!"
There's something that looks like a bug in FCEUX's source, where all the MMC3 derivatives call GenMMC3_Init with parameters in terms of maximum supported kibibytes, but GenMMC3_Init then generates a mask from that number that expects it to be give a parameter as a pure number of bytes ... but that should in practice have net no effect. (because (512 >> 13)-1 == -1 == uint32_max)
Quote:
If you wanted to save progress, you could even wait to lockout when somebody selects "save and quit", then lockout, save, and reset to title menu, right?
It has to be a hard reset (person hits reset button ... or maybe even power button, depending), not simply the program starting over from scratch.
Quote:
Can you LDA from WRAM while registers are not locked out?
ClusteR's implementation only attaches to FCEUX's write handlers in the $6000-$7FFF region, so according to that, you should be able to. But I have no idea whether that's accurate.
Quote:
I'm guessing it's not, but I just want to go ahead and ask if the CHR-RAM is dual ported, meaning that you could start a copy to it without turning off rendering?
No.
Not only is dual-ported RAM expensive, but there's no interface defined for such a dual-ported interface here; the PPU's RAM interface is definitely busy during rendering.
In regards to the mmc3 limitations, I've brute forced all 4 registers to see what mapping options there are. I've flashed a 2megabyte ROM to the cart with identification strings in what should be the interrupt vectors for a 32k, 64k, 128k, 256k, 512k, 1024k and 2048k ROM. I've only managed to get the cart to map 128k, 256k and 512k ROM's in MMC3 mode (Reset vector in the correct place)
I have not tried to swap banks beyond the 512k ROM, that is switch to bank 255 on a 512k ROM. This could map up to 2048kbytes in the bank mapping regions if the mapper supported it. I'll try later tonight and report back. I know GNROM mode will allow it so it is very likely it can be done.
For the Mapper reset - My STM32 is held in a loop waiting for the 'Set Configuration' command from the USB host. There is no reason why I could't monitor the CPU bus and catch a reset command sequence (i.e. write &AA,$55,$AA to $6000) then act on that. It'll need some simple logic, an NPN + resistor to clamp the PHI signal to force a cart reset but it could be easily done. (Or just a resistor come to think of it)
The MCU runs at 72mhz and has very powerful interrupt hardware so will be fine catching writes from the comparatively slow CPU Bus. It could even do some more advanced trickery, I'm not sure exactly what as NES hardware is relatively new to me, I'm sure others could offer a few suggestions. Maybe a game genie or something? Serial Port?
I'll check out that mmc3 stuff and report back.
Initial testing shows mapping up to bank 63 works, past that there seems to be some odd masking going on. Bank 253 is mapped to bank 61 (indicating masking of %00111111). Bank 255 is mapped somewhere I haven't yet identified, well past the 2mbyte mark. I'll need to hook the logic analyser up to the ROM IC to see exactly what is going on.
This confirms my suspicions that accessing past 512kbytes could be tricky in mmc3 mode once the registers are locked out. There is still the hybrid GNROM/MMC3 mode to investigate.
For carts without WRAM, I had a look in my junkbox and found a couple of N64 Save Packs. Inside is a 32kbyte SRAM IC. I probed around the Coolboy cart's WRAM footprint and all the traces seemed like they were in the correct place. The upper Address bit was tied to VCC but the rest were controlled via the Bus/Mapper. This could mean 16kbytes is mappable.
Anyway, moving the SRAM IC from the N64 save pack to the cheapest coolboy cart seems to have worked. I can now boot ROM's that require WRAM including SMB2 and Bugs.
It seems more likely to me that that is the
MMC3's PRG RAM +CE output instead of
A13...
I think you're right in that the board was intended to control 8kbytes of SRAM, not 32. Still, a 32k IC is a direct drop in replacement which is handy.
The 72 pin coolboy games are no longer 60 pin with adaptors. A whole new board. Luckily the gold fingers are longer than they need to be so I could solder onto those.
Interesting the date stamp on the mmc is 18nov2015.
You know, for a chinese multicart board that looks really well assembled...
What kind of CPLD is on there for the mapper? Looks like an Altera something-something.
Yeah, gold plated and even washed of all flux after soldering. They've really improved from the dodgey nickle plated version 1 boards.
The mapper is a custom ASIC. 'SMD132' I've not found any data on this chip except for the reverse engineering attemps by clusterr and myself.
That's interesting, I wonder exactly what finish they've used on their different edge connectors. If the gold on the edge pins looks the same as the IC pads, then I'd think it'd be immersion gold (ENIG). That costs almost nothing compared to electrolytic gold (hard gold), I wonder how well it would hold up with repeated use in a tight connector though. IPC specs say ENIG on a connector is rated for something like 5 insertion cycles, maybe not so bad in a front-loader since it takes less lower force. Hm, I might have to buy one of these and run it through a Game Genie a bunch of times and see what happens. Would be nice if I could bring down the price of the boards I've been making without making it too crappy.
There is no sign of electroplating (small traces running off the fingers to ensure uniform potential when in the bath) so I'd say its ENIG.
No bevel on the edge either unlike their earlier boards. So they cut costs there
I get the idea from the use of the word "early" in the
Wikipedia article that ENIG processes have improved. Is that the case? There's also ENEPIG that puts palladium between the nickel and gold. Is that any better?
I have been very curious about ENEPIG, unfortunately the only source I've seen for the IPC-4556 doc is like $300 for a paper copy.. that's a bit much for my hobbyist curiosity, heheh. I wouldn't suppose anyone reading this thread has access to that, but I'd love to know just what it says for it's durability as a connector finish. I've seen articles mention that it's suitable for low-insertion-force and ZIF connections, but no details beyond that. I suppose I can ask my board manufacturer, I don't think the one I use offers that finish but it's probably worth asking around.
I read a thread over at eevblog that in the last year or two there have been big changes to what chemicals can be used for the gold depositing process in China. Because of this, prices in general have increased especially with plated boards.
I can confirm the nickle plating on the 60pin boards is incredibly tough and a pain to solder to! It took a lot of effort to cut a pad. Far more sturdy than gold plating. Is the difficulty to solder the only reason it isn't more common?
Hello BennVenn,
I like your cheap Famicom cart mod, any rough schematics you can share here?
I can get these carts cheap from Taobao there, and I will do the rest of the programmming.
If I'm not mistaken - you only connect the cart's CPU data and the address lines (and the Write line on the flash chip) to the microcontroller board?
That's right. Schematics are nothing special, standard data and address bus type stuff. Prg bus only
Any cpu will do the interfacing to the PC though I'm keeping my source/bin private. You could very easily connect it to an arduino for example.
Google the flash ic and you'll get the datasheet and flash instructions.
Last piece of the puzzle is the mmc but thats pretty well documented too.
BennVenn wrote:
That's right. Schematics are nothing special, standard data and address bus type stuff. Prg bus only
Any cpu will do the interfacing to the PC though I'm keeping my source/bin private. You could very easily connect it to an arduino for example.
Google the flash ic and you'll get the datasheet and flash instructions.
Last piece of the puzzle is the mmc but thats pretty well documented too.
Thanks BennVenn for the info. I'll check the datasheet for that particular flash chip. Since I'm in SE Asia, it's mostly Famicom, so the cart fits on a Famiclone.
I can do the flash programming by myself there - I have these tools. And of course, I assume it's possible for me to put one (1) game inside for a quick test?

Edit: Is your cart looking like this?
http://www.aliexpress.com/item/No-repeat-real-8-bit-60Pins-Game-Cartridge-classical-game-card-198-in-1-PCBA/32492028523.html?spm=2114.40010508.4.206.2ihLJX
You could use that cart though it doesnt have wram or very large chr ram. Get the kirby cart.
You will need to write a bootloader if your rom uses chr rom.
I have a few I built for generic roms. 32/32k 32k/128k etc.. ill post them here
BennVenn wrote:
You could use that cart though it doesnt have wram or very large chr ram. Get the kirby cart.
You will need to write a bootloader if your rom uses chr rom.
I have a few I built for generic roms. 32/32k 32k/128k etc.. ill post them here
Thanks for the info. I wanted to write my own FC game and play it on a Famiclone, but Everdrive N8 is too expensive for me. I'll try to use the another version of the cart with the battery (you mentioned the Kirby, probably it's the one).

Also, I guess that you already have a memory map of these cart laid out, or still in progress? I'll test my game in the emulator first, then I'll get the actual hardware once I'm done with them.