How is data entered into the 5-bit array?
Like this:
1st Write == 1
00001 <-- LSB
or:
1st Write == 1
--> MSB 10000
Also is the LSB of the data written the actual value that goes into the array? Or is it if the data is equal to anything other than 0?
The first way. Least significant bit first. And only bits that matter are bit 0 (written to reg) and bit 7 (reset). The other bits should not be used at all.
Remember that all 5 writes must be completed before the 5-bit value actually gets moved to a register... and that only the address written to on the last (5th) write matters. Therefore:
Code:
LDA #$00
STA $8000
STA $8000
STA $8000
STA $8000
STA $E000
That's a perfectly valid way to write to the 4th MMC1 register ($E000). The contents of the first MMC1 reg ($8000) remain unchanged.
Thanks, just to confirm;
1st Write = 1
2nd Write = 1
3rd Write = 1
4th Write = 0
5th Write = 1
Would mean:
MSB-10111-LSB?
You see the trouble that I am having is on Zelda. It writes a 7 then a 5 to register 3. The first write is ok but on the second switch I get the illegal opcode error. Does Zelda require precise timing or anything?
Yes, your example is correct.
I haven't had problems with Zelda, so I don't really know what to tell you to look for. As far as I know it doesn't do anything tricky. Only thing out of the ordinary it does is write code to RAM at $6000-$7FFF and JMP/JSR to it.
Quote:
Yes, your example is correct.
Huh ? I'm sure it isn't.
Writing $1, $1, $1, $0, $1 will be the equivalent of writing %10111, so the exact opposite as you say. If you bankswitch bank $d instead of bank $7 you'll most probably have errors.
Remember that to load a value in a MMC1 register you will need to do :
lda #value
sta $ffff
lsr A
sta $fff
lsr A
....
So the LSB are written first.
It's not the opposite, his example was right.
If you write (in order) : 1, 1, 1, 0, 1 ... the first bit written is the LSB... and bits get more significant as written.. with the MSB last. So those writes will produce a 5-bit value: %...10111. Which is what his example portrayed.
A game will usually write this value with code like the following:
Code:
LDA #%00010111
STA $E000 ; lsb written (1)
LSR A ; A now %00001011
STA $E000 ; (1)
LSR A ; A=%00000101
STA $E000 ; (1)
LSR A ; A=%00000010
STA $E000 ; (0)
LSR A ; A=%00000001
STA $E000 ; (1)
Well.... doing it like this is a lot too much confusing scince I'm right now unable to say if I'm right or if you're right. Both sounds okay to me, but of course it's a nonsense.
Basically, just write the LSB of the written value to 5-bit serial buffer that will be shifted right on each writes, and that will be copied to MMC1 actual register when full. That should work perfectly.
I think we're just communicating poorly. You and I are both saying the same thing it looks like (your example was right too), we're just misreading or something.
So yeah. LSB first.
I still can't get this to work, and I am literally ripping out my hair over it.
Here is a sample of my code;
if( Register[0] & 0x08 )
memcpy( &CPU.Memory[0x8000 + (Register[0] & 0x04) * 0x1000], &File[0x10 + (Register[3] * 0x4000)], 0x4000 );
I have ANDed Register[3] with 0x0F but that has also had no effect.
Am I going wrong somewhere?
that snippit looks like it should work.
Do any other MMC1 games act up? Or is it just Zelda?
Are you changing the ROM data at that address? like if the game writes $07 to $E000, that should NOT change what the game reads from $E000 (ROM != RAM).
ALL MMC1 games are playing up.
Yes I am changing the ROM data (I was going to do all of the trapping later). Could that be what is effecting it?
Sorry guys problem solved, my fault;
if( Register[0] & 0x08 )
memcpy( &CPU.Memory[0xC000 - (Register[0] & 0x04) * 0x1000], &File[0x10 + (Register[3] * 0x4000)], 0x4000 );
not;
if( Register[0] & 0x08 )
memcpy( &CPU.Memory[0x8000 + (Register[0] & 0x04) * 0x1000], &File[0x10 + (Register[3] * 0x4000)], 0x4000 );
D'oh![/i]
whoops... that one slipped by me too ^^
glad you figured it out
Any reason for avoiding pointers? Take out those memcpy() man... -_-;;