Once I figure things out as best I can if someone wants to write a test rom to verify these things on other MMC1's while running on the NES etc I would think it's a good idea before considering any of this official. I'm just performing experiments to try and figure out how this thing is actually built. Once things have been verified, I'll release what my official design is of the MMC1 that is as accurate as I can tell. With all that said hopefully no body gets their panties in a wad...
To answer your question Bregalad. Like we discussed earlier if the double write ignore isn't intentional then they wouldn't have added extra logic to check for double (or more than double) consecutive writes and only acknowledge the first. So some optimization or 'don't care' would have had to be made use of if it was unintentional. There are only a few ways to do this. Here are some possibilities that I disproved in my experiments.
The biggest possibility I saw was the fact that PRG R/W stays low between sequential writes. It will only go high when a read is done. So maybe they are clocking something with PRG R/W (even though it sounds like a bad idea). With my tests I was able to actually pull PRG R/W high between the two writes without changing M2 or PRG /CE. Even if I did this, the follow on writes were ignored.
Another idea is some bad circuit or something that a capacitance or something that requires time to discharge so the second write is ignored. But since I can wait seconds between writes this is disproved because it didn't matter how much time I wait between writes (usually 50msec for my rig).
The real kicker for me was the question, "what if I perform 3, 4, 5 or more writes concecutively?" What I found, only the FIRST will be acknowledged. ALL follow on writes are ignored.
Then I asked, "what if I write to ROM (MMC1), then WRAM, then ROM? Even though it's impossible to do with the NES, It turns out only the first will still be acknowledged. Even if you write below where the MMC1 can see ($0000-$5FFF) for several cycles but then come back and write to ROM. It still only acknowledges the first write.
I then asked "Well if it isn't checking PRG R/W solely (based on my earlier statement.) How is it sensing the follow on writes?" I the only thing I could figure is that it uses M2 and only checks PRG R/W when clocked. But how to check this? Well what if we DON'T clock M2 but still do everything else normally. It turns out that consecutive writes WILL be acknowledged if we do this. Regardless if M2 is held high or low. This also further proves that PRG R/W can be held low between writes and still get each write acknowledged. This also means M2 is used for more than just WRAM CE. It's not used for clocking the Shift register, but is used for checking for consecutive writes.
And if they did this, then the MUST have ignored consecutive writes on purpose. Unless they somehow accidentally threw in an extra flipflop to create an 'enable write' signal by clocking PRG R/W each CPU clock cycle. Which I think everyone will agree isn't plausible.
One question I have yet to answer yet though is, "will blocked writes with D7=1 cause resets or not?" So really this could also be asked, "will DEC $00 cause a reset or cause a 0 to be loaded into the shift register with no reset." I'll get around to this at some point.
I also did some testing today to check into the details of how only the address of the last write matters as stated in Kevtris' docs. Turns out this is only true to a certain point. I found this out accidentally at first, but it turns out it's actually possible to write TWO Registers at ONCE. Well almost, You can write to one full register and bits 4-0 of a second. If one were to implement this the 5th bit of the second register appears to always be set to 1. Now the exact details of this I'm not 100% certain of yet but here's what it looks like to me.
So according to kevtris:
Code: Select all
LDA #[data to load]
STA 08000h ;It does not matter where these first 4 writes occur. only the last write matters.
LSR A
STA 08000h
LSR A
STA 08000h
LSR A
STA 08000h
LSR A
STA 0E000h ;NOTE: register 3 is what gets loaded!
I found this by only changing the address the last byte is written to, and keeping the address of the previous cycle's read the same as the previous writes. Implementing this on the NES the read that occurs the cycle before the write of a STA is from the address of the STA instruction. So wherever that read is performed from, the associated register gets partially written to. Looking at the opcodes this is only true for addressing modes that read from PC (+) before the write. Looks like you might get something funky for some addressing modes.
So it would seem this is somewhat of a bug and I wouldn't think it's intentional. But it gives hits as to how it's constructed. Looks like the copying from the Shift register to the other registers gets enabled a little early as a result of an optimization from not caring about this issue.
Well I thats all I've got for now, at this point I'm not sure how much I care to dig deeper. I should have enough info to get mine working atleast. It's been fun solving some of this puzzle but I don't think it's very fruitful to dig around much deeper. Most of this register stuff could be checked with ROM testing on the NES it just takes a lot longer to check each step compared to my set up. If someone wants something specific tested let me know. I can also burn eproms and test on the NES also.