It is currently Sat Oct 20, 2018 4:41 pm

 All times are UTC - 7 hours

 Page 1 of 1 [ 9 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: It may be smaller by \$100Posted: Tue Aug 08, 2017 10:13 pm

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
6502_cpu.txt says for Absolute indexed:

Quote:
Absolute indexed addressing

Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
LAX, LAE, SHS, NOP)

# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+I* R read from effective address,
fix the high byte of effective address
5+ address+I R re-read from effective address

Notes: I denotes either index register (X or Y).

* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by \$100.

+ This cycle will be executed only if the effective address
was invalid during cycle #4, i.e. page boundary was crossed.

I know that "crossing pages" takes 1 more cc, but i don't understand the:

Quote:
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by \$100.

can someone explain me??

_________________
ANes

Top

 Post subject: Re: It may be smaller by \$100Posted: Tue Aug 08, 2017 10:32 pm

Joined: Sun Dec 12, 2010 10:27 pm
Posts: 323
Location: Hong Kong
That means if page crossing happens, the address read in the 4th cycle is incorrect, say if you do:
LDA \$02FF, X
where 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.

Top

 Post subject: Re: It may be smaller by \$100Posted: Tue Aug 08, 2017 10:55 pm

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6897
Location: Canada
Gilbert wrote:
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.

Top

 Post subject: Re: It may be smaller by \$100Posted: Tue Aug 08, 2017 11:59 pm

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7675
Location: Seattle
Certainly tepples's console/controller identification ROM relies on being able to "precharge" the data bus with the value from \$2007 (\$3F17) before the intended read from \$4017 ...

Top

 Post subject: Re: It may be smaller by \$100Posted: Wed Aug 09, 2017 6:27 am

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20679
Location: NE Indiana, USA (NTSC)
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.

Top

 Post subject: Re: It may be smaller by \$100Posted: Wed Aug 09, 2017 8:02 am

Joined: Sun Dec 12, 2010 10:27 pm
Posts: 323
Location: Hong Kong
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)?

Top

 Post subject: Re: It may be smaller by \$100Posted: Wed Aug 09, 2017 11:15 am

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7675
Location: Seattle
In practice, only if there are peripherals that care only that a read happened. In the NES/FC, that includes \$2002, \$2007, \$4016, and \$4017, but not much else.

In the 2600, only the bankswitching registers count. I guess that means you could deliberately trigger a bankswitch that would then fall over into a read from the RAM portion of the RIOT?

I don't think the C64 or VIC-20 do anything in response to just a read... It looks like some of the Apple 2 I/O registers do.

Top

 Post subject: Re: It may be smaller by \$100Posted: Wed Aug 09, 2017 11:51 am

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6897
Location: Canada
Gilbert wrote:
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.

I've heard that Bill and Ted bizarrely relies on the MMC1 filtering out writes on consecutive cycles from an INC.

Top

 Post subject: Re: It may be smaller by \$100Posted: Wed Aug 09, 2017 1:36 pm

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7548
Location: Chexbres, VD, Switzerland
Gilbert wrote:
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.

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 9 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: No registered users and 6 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

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki
Powered by phpBB® Forum Software © phpBB Group