Coolboy cart programmer

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

Moderators: B00daW, Moderators

lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Coolboy cart programmer

Post by lidnariq »

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?
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Coolboy cart programmer

Post by lidnariq »

Theoretically:

Code: Select all

: 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
Last edited by lidnariq on Tue Dec 29, 2015 3:12 pm, edited 1 time in total.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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)
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Coolboy cart programmer

Post by lidnariq »

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.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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: Select all

;----------------------------------------------------------------
; 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?
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Coolboy cart programmer

Post by lidnariq »

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.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

I don't think I'm up to coding a menu just yet, baby steps!

I'll initialise just to be sure.

Thanks
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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!!!
User avatar
Memblers
Site Admin
Posts: 3901
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Coolboy cart programmer

Post by Memblers »

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.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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: Select all

   :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.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

Success!

Needs the Mapper locked with $80 > $6003 before it boots.

Merry Xmas!
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

lidnariq wrote:Theoretically:

Code: Select all

: 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!
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: Coolboy cart programmer

Post by BennVenn »

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: Select all

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: Select all

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: Select all

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: Select all

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: Select all

Match 0x40 0x80
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Coolboy cart programmer

Post by lidnariq »

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.
Post Reply