Trying to think of a need that can abuse this where you'd want interleaved writes to CIRAMDwedit wrote:STA (xx),Y adds a dummy read.They did it this way in case they needed to fix up the high byte before performing a write, because they figured that reads wouldn't have side effects like writes would.Code: Select all
1 PC R fetch opcode, increment PC 2 PC R fetch pointer address, increment PC 3 pointer R fetch effective address low 4 pointer+1 R fetch effective address high, add Y to low byte of effective address 5 address+Y* R read from effective address, fix high byte of effective address 6 address+Y W write to effective address
STA indirect indexed double-increments PPU address?
Moderator: Moderators
Re: STA indirect indexed double-increments PPU address?
Re: STA indirect indexed double-increments PPU address?
DMC will still screw with the read.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: STA indirect indexed double-increments PPU address?
As I remember, the behavior depended on the CPU-PPU clock alignment at power, that it wasn't reliably the same each time.exdeath wrote:Trying to think of a need that can abuse [extra read] where you'd want interleaved writes to CIRAM
Re: STA indirect indexed double-increments PPU address?
That's... pretty stupid, couldn't they have made it so that the bus was left unused in that 5th cycle? Pretty sure that reads with side-effects were already common when the 6502 was first designed =/Dwedit wrote:STA (xx),Y adds a dummy read.They did it this way in case they needed to fix up the high byte before performing a write, because they figured that reads wouldn't have side effects like writes would.Code: Select all
1 PC R fetch opcode, increment PC 2 PC R fetch pointer address, increment PC 3 pointer R fetch effective address low 4 pointer+1 R fetch effective address high, add Y to low byte of effective address 5 address+Y* R read from effective address, fix high byte of effective address 6 address+Y W write to effective address
Re: STA indirect indexed double-increments PPU address?
I'm sure they did everything they could to keep costs down when designing the 6502, so you can be certain that this decision was made to reduce the number of transistors.Sik wrote:couldn't they have made it so that the bus was left unused in that 5th cycle?
Yes, but they probably assumed that the more exotic addressing modes wouldn't be commonly used to access memory-mapped registers.Pretty sure that reads with side-effects were already common when the 6502 was first designed =/
Re: STA indirect indexed double-increments PPU address?
Or auto incrementing single address FIFOs. This is both the fault of the 6502 and the PPU combined, not just the 6502.tokumaru wrote:I'm sure they did everything they could to keep costs down when designing the 6502, so you can be certain that this decision was made to reduce the number of transistors.Sik wrote:couldn't they have made it so that the bus was left unused in that 5th cycle?
Yes, but they probably assumed that the more exotic addressing modes wouldn't be commonly used to access memory-mapped registers.Pretty sure that reads with side-effects were already common when the 6502 was first designed =/
This exact combination of CPU, addressing mode, and PPU port is like winning the lottery or something.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: STA indirect indexed double-increments PPU address?
Don't forget I also did it by discovering a compiler bug!exdeath wrote:This exact combination of CPU, addressing mode, and PPU port is like winning the lottery or something.
Re: STA indirect indexed double-increments PPU address?
It wasn't a bug, it's what you wrote
cc65 did exactly what you told it to.
Re: STA indirect indexed double-increments PPU address?
Subscripting in C is commutative. If the code that a compiler generates for a, b[a], and *(a+b) differs with optimization turned on, then either A. the compiler is Doing It Wrong with respect to efficiency of commutative operations in general or B. you are coding in C++ and have overloaded some operator.
Re: STA indirect indexed double-increments PPU address?
Or C, the optimizer is simplistic and takes advantage of the fact that most people write array[n] instead of n[array]. That is, it generates better code for most array expressions, and that's good enough. Handling it fully generally would be more work just for obscure cases.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: STA indirect indexed double-increments PPU address?
tepples wrote:Subscripting in C is commutative. If the code that a compiler generates for a, b[a], and *(a+b) differs with optimization turned on, then either A. the compiler is Doing It Wrong with respect to efficiency of commutative operations in general or B. you are coding in C++ and have overloaded some operator.
The problem here is there's a difference between array[7] and pointer[7]. One of them has a fixed address at compile/link time, and one of them needs to be resolved by extra code. cc65 normally correctly identifies these two types, and does generate different code for the array (absolute) and pointer variable (indirect indexed). This is neither incorrect, nor undesired, and does not require optimization to be turned on.
In the ((unsigned char*)0)[7] example, it is compiled as if this literal is cast to a pointer variable, rather than an array, and does all the things associated with such a thing. Yes, all arrays can be generically considered pointer variables, but that is a generalization which would generate a lot more (bigger/slower) code than necessary. This isn't really part of the optimization process; this is a problem further up the pipe. If the type is misidentified, you can't optimize away the indirection.
Anyhow, I'll report this to the cc65 mailing list, since someone on the project might be interested in fixing this problem. If not, we've covered a few ways to avoid it already. This was just a case of very poor code generation, which I do consider a bug, but I've no wish to argue the semantics of what should or should not be classified a bug. Yes the code is correct (when the extra read has no side-effect), but it's also slow as hell compared to what it could be.
Re: STA indirect indexed double-increments PPU address?
I just remembered this quirk of the 6502. More specifically:
Not to mention all the spurious accesses that can happen everywhere when crossing pages (lower byte is updated in a different cycle than the higher byte but the bus is still taken by the processor). Yeah, it's a mess. Looks like they literally assumed reads would never have side effects.
The standard doesn't require compilers to generate the most optimal code, only to ensure the final results are correct =P Though one could argue that the 6502 quirk here prevents it from being correct... (though we're starting to enter the realm of platform-specific hacks).
Code: Select all
When an NMI occurs, the processor jumps to Kernal code, which jumps to
($0318), which points to the following routine:
DD09 LSR $40 ; clear N flag
BPL $DD0A ; Note: $DD0A contains RTI.
Operational diagram of BPL $DD0A:
# data address R/W description
--- ---- ------- --- ---------------------------------
1 10 $DD0B R fetch opcode
2 11 $DD0C R fetch argument
3 xx $DD0D R fetch opcode, add argument to PCL
4 40 $DD0A R fetch opcode, (fix PCH)tepples wrote:Subscripting in C is commutative. If the code that a compiler generates for a, b[a], and *(a+b) differs with optimization turned on, then either A. the compiler is Doing It Wrong with respect to efficiency of commutative operations in general or B. you are coding in C++ and have overloaded some operator.
The standard doesn't require compilers to generate the most optimal code, only to ensure the final results are correct =P Though one could argue that the 6502 quirk here prevents it from being correct... (though we're starting to enter the realm of platform-specific hacks).