Coolboy cart programmer
Moderators: B00daW, Moderators
Re: Coolboy cart programmer
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?
Anyway, you'd said you noticed some issues with the wiki document?
Re: Coolboy cart programmer
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.
#$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.
Re: Coolboy cart programmer
Theoretically:
(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
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
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.
Re: Coolboy cart programmer
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)
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)
Re: Coolboy cart programmer
Sounds correct to me.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?
Re: Coolboy cart programmer
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?
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?
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
Anything I'm missing?
Re: Coolboy cart programmer
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.
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.
Re: Coolboy cart programmer
I don't think I'm up to coding a menu just yet, baby steps!
I'll initialise just to be sure.
Thanks
I'll initialise just to be sure.
Thanks
Re: Coolboy cart programmer
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!!!
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!!!
Re: Coolboy cart programmer
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.
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.
Re: Coolboy cart programmer
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.
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.
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
Re: Coolboy cart programmer
Success!
Needs the Mapper locked with $80 > $6003 before it boots.
Merry Xmas!
Needs the Mapper locked with $80 > $6003 before it boots.
Merry Xmas!
Re: Coolboy cart programmer
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.lidnariq wrote:Theoretically:(where "z" is a function of whether 128 KiB or 256 KiB of CHR-RAM is desired)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
But I bet you already tried that.
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!
Re: Coolboy cart programmer
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
Indicating the full 512k is mapped correctly.
I then send $00>$6000 $80>6001 $00>6002 $00>6003 and get
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
bits 0&1 of $6001 are 'dont care' which leaves us with:
bit 3&7 of $6000 is also dont care so we get:
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])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])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
Code: Select all
Match 0x40 0x80
Match 0x48 0x80
Match 0xc0 0x80
Match 0xc8 0x80
Code: Select all
Match 0x40 0x80
Re: Coolboy cart programmer
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.
It's totally possible I made a mistake when I was reinterpreting FCEUX's source ... unless you're already testing that too.