That means if page crossing happens, the address read in the 4th cycle is incorrect, say if you do:LDA $02FF, Xwhere X = 4, at the 4th cycle the CPU actually reads from $0203(low byte $(FF + 4) = $03 with carry, but at this point the high byte is not "fixed" by adding the carry yet, so the high byte is still $02), instead of the correct $0303. That's why it needs an extra 5th cycle to re-read from the correct address $0303.

That's just how the CPU works internally. I think for accurate CPU emulation it doesn't really matter as long as the cycles are correct and yields the expected output.

That's just how the CPU works internally. I think for accurate CPU emulation it doesn't really matter as long as the cycles are correct and yields the expected output.

Occasionally the extra read or write cycles have side effects.

For example, using STA (indirect), Y on $2007 can end up writing two bytes to the PPU.

Most of the time an extra read doesn't have a consequence, but there are some effects that are read-triggered (e.g. $2002). I don't know if there's any games out there that rely on the dummy read, though.

Lidnariq is referring to this test ROM that distinguishes among Control Deck variants (Famicom, front-loading NES, or top-loading NES) by exploiting the open bus behavior when the CPU reads $3F16 then $4016 in quick succession without an intervening instruction. In case you lack time to read the other topic, I'll summarize:

An "open bus" is a data bus that is read while nothing is connected. For example, if you LDA $4021 on an ordinary NES with an ordinary cartridge, the PRG ROM drives $AD, $21, and $40 in succession onto the data bus. But because no circuit responds to reading $4021, capacitance of the data bus holds the value $40 in place momentarily to be read by the CPU. One might think of this value as "riding" the open bus, boarding at the PRG ROM and debarking at $4021.

In normal operation, when the CPU reads $4016 (the first joystick port), the PRG ROM puts $40 on the data bus, and then the joystick circuit replaces but some but not all of these bits with joystick bits. Bits 7-5 are always unconnected (NC) except on Vs. System, bits 1 and 0 are always driven, and bits 4-2 are either driven or NC depending on which port (1 vs. 2) and which Control Deck variant. Because bits 7-5 are NC, those bits from the $40 value remain, and the port normally returns $41 for a pressed button or $40 for one not pressed. But the program can't tell an NC bit from a bit always driven to 0 because all driven bits are already precharged to 0.

The PPU has a video memory address port at $2006 and a video memory data port at $2007. These ports are mirrored every eight bytes up through $3FFE and $3FFF, including $3F16 and $3F17. Though $2006 is nominally write-only, the PPU's I/O has its own internal data bus, and reading a write-only PPU port will return the last byte written to any PPU port. The test program puts $BF into this internal PPU latch and then uses an indexed read (LDX #$20 LDA $3FF6,X) to cause the PPU to read $3F16, which puts $BF on the data bus, and $4016, which replaces some bits. Comparing the value when the PPU loads $BF to the value when the PRG ROM loads $40 lets a program tell which joystick bits aren't connected to the data bus.

Never thought of that. So, does it mean that it is possible that in any 6502 systems (MOST 6502 systems I suppose) with memory ports mapped to other devices, there could be potentially hard to track bugs because of the (discarded) read/write when a page crossing occurs in index mode(however rare this could happen)?

Never thought of that. So, does it mean that it is possible that in any 6502 systems (MOST 6502 systems I suppose) with memory ports mapped to other devices, there could be potentially hard to track bugs because of the (discarded) read/write when a page crossing occurs in index mode(however rare this could happen)?

A bunch of things have to align for it to matter.

Using an indexed instruction to write such a register while also crossing a page is a but of an unusual occurrence in itself.

The most common places I've seen indexed writes to memory mapped registers on the NES is in initialization code (e.g. write 0 to all registers in a loop), and sometimes in audio code. A page crossing wouldn't normally happen in these cases, since the base address is going to be $2000 (PPU) or $4000 (APU). A doubled write might matter in some cases, but probably not during an initialization blanking.

Never thought of that. So, does it mean that it is possible that in any 6502 systems (MOST 6502 systems I suppose) with memory ports mapped to other devices, there could be potentially hard to track bugs because of the (discarded) read/write when a page crossing occurs in index mode(however rare this could happen)?

It is possible, but the memory mapped I/Os are typically adressed through direct adressing only. The only exeption in NES' case would be the APU registers which are commonly accessed as indexed adressing because they're basically an array of registers - but there will never be an overflow so it doesn't matter. I even adressed them using indirect adressing in one of my engines (the pointer would decide which of the 4 sound register is written to, and the Y register which sound channel is written to), but even that doesn't cause problems as there is no page crossing.

Who is online

Users browsing this forum: No registered users and 9 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum