|
Hello. I have some trouble designing a cycle-perfect PPU for my emu. This is what I've done so far:
*) Reads from PPU always return the current state of the PPU *) Writes to PPU during VBlank affect the PPU register immediately *) Writes to PPU during non-VBlank are stored in a 'stack', where every write to the PPU is performed AFTER the non-VBlank period has ended (pop stack event, perform event, draw pixels 'til next event, loop).
Now, this works perfectly fine visually but Nestress doesn't pass the basic write to VRAM/read from VRAM test. This is probably due to the PPU writes occuring during non-VBlank, and the READS are ALSO done during non-VBlank. I was under the impression that you are not allowed to read from 0x2007 during non-VBlank! This results in Nestress writing to the PPU (which is delayed) and directly reading from it. My PPU hasn't yet processed the 'write to PPU'-event (as this happens at the end of the frame when the bg is drawn), so the read will return an old PPU value. If Nestress had waited 'til VBlank before reading (as I thought was required), the PPU would've processed the events and updated the PPU registers.
Phew... so what I wonder is if reads from PPU (0x2007) are allowed during non-VBlank (ie, if writing to 0x2007 and reading from it directly afterwards should instantly return the new value)? Or maybe I've just missed something... I'd be really grateful if anyone could shed some light onto this.
(Also, what do you suggest if my fears are true and the value should be directly reflected in the PPU? I can't come up with anything else than to duplicate everything in the PPU and let the CPU read the original instantly changed values, while when drawing the bg do the write operations again for the PPU in the duplicate registers. Lots of cycles wasted).
Thank you very much in advance, Tommi Kiviniemi
|