It is currently Mon May 20, 2019 8:48 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 6:20 pm 
Offline

Joined: Mon Feb 18, 2019 3:08 pm
Posts: 7
Hey guys,

I'm currently experimenting with emulating per cycle, instead of per instruction.
I'm using nestest, and found a bug with my handling of sta.

Why does STA Indexed Indirect "ignore" page boundaries? It takes exactly 6 cycles (no +1).
(as per http://www.obelisk.me.uk/6502/reference.html#STA)

Btw, if there are better tests for (cpu) cycle accuracy let me know.

Thanks!


Top
 Profile  
 
 Post subject: Re: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 6:47 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3678
Location: Indianapolis
LDA has the optional +1 cycle when crossing page boundaries, STA always takes +1.

Reason is, the extra cycle is needed to update the address whenever a page boundary is crossed. But the 6502 still always does a read or write on every cycle. If you do LDX #1 / LDA $2FF,X, 6502 will read $2FF, then $300. If writes were done the same way, LDX #1 / STA $2FF,X the CPU would WRITE to $2FF, then $300. Clearly, a stray write would be much more consequential than a stray read. Basically, reads are able to take a shortcut that the writes can't. Instead, STA $2FF,X in that example it would read $2FF, then write $300.

You'll see the read and write instructions listed separately here, with the steps taken on each cycle:
http://nesdev.com/6502_cpu.txt


Top
 Profile  
 
 Post subject: Re: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 7:17 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 4071
Location: A world gone mad
This thread is already confusing, as ABSOLUTE INDEXED has been described by Memblers: I'm going to reference documentation for that addressing mode just to make it crystal clear: https://github.com/eteran/pretendo/blob ... .txt#L1092 -- pay very close attention to lines 1145/1146 and the paragraph at 1151-1154.

What you're wanting to comprehend, I believe, are called "T-states" (timing states), where you can understand what the CPU is doing during each cycle of opcode execution. This document outlines most of those pretty well, but you need to be careful and read it very slowly as it's easy to mistake where you are in the document or what you're reading about. They are not just copy-pastes of the same thing over and over!

Now let's focus entirely on indexed indirect, e.g. ($c0,x), like you asked: https://github.com/eteran/pretendo/blob ... .txt#L1183

Both reads and writes with indexed indirect, e.g. lda ($c0,x) and sta ($c0,x), take 6 cycles. Indexed indirect "ignores" page boundaries (thus the potential +1 cycle penalty) because the effective address calculated is always within zero page, i.e. ldx #$80 / lda ($c0,x) will not load from $140 but from $40. The same applies to sta ($c0,x).

Indirect indexed, e.g. ($c0),y is different, but only on reads (e.g. lda), where there can be a +1 cycle penalty if there's a page wrap (thus 6 cycles instead of 5). On writes (e.g. sta), the cycle count is always 6.

Be prepared for lots of fun when dealing with RMW instructions, e.g. inc.

If you're asking "why" in the sense of "why was the 6502 designed this way" or "why does this addressing mode differ in behaviour than the other", then you should redirect your question to Bill Mench, one of the creators of the 6502; you can ask him here.


Top
 Profile  
 
 Post subject: Re: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 7:37 pm 
Offline

Joined: Mon Feb 18, 2019 3:08 pm
Posts: 7
Thank you Memblers and Koitsu!

Effectively, I got it backwards, my interpretation was that "LDA may take 6 cycles", but the reality is that it may take 5.
As Memblers pointed out a read or write *has* to happen, as such LDA may have read an incorrect value, and it may have to re-read it after fixing the address.

STA only cares about the address, not its contents, as such it takes exactly 6 cycles and not 6+.

I think it clicked, did I get it right?


Top
 Profile  
 
 Post subject: Re: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 8:06 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 4071
Location: A world gone mad
Rather than say yes/no, I'll clarify with actual opcode + addressing mode descriptions:

Code:
lda abs -- 4 cycles
lda zp -- 3 cycles
lda zp-indexed-- 4 cycles
lda abs-indexed -- 4 cycles, 5 if there's a page wrap
lda zp-indexed-indirect -- 6 cycles
lda zp-indirect-indexed -- 5 cycles, 6 if there's a page wrap

sta abs -- 4 cycles
sta zp -- 3 cycles
sta zp-indexed -- 4 cycles; also does a read
sta abs-indexed -- 5 cycles; also does a read
sta zp-indexed-indirect -- 6 cycles
sta zp-indirect-indexed -- 6 cycles

RMW opcodes, ex. asl/lsr/rol/ror/inc/dec, are not covered in the above.


Top
 Profile  
 
 Post subject: Re: STA Indexed Indirect
PostPosted: Thu Feb 21, 2019 8:15 pm 
Offline

Joined: Mon Feb 18, 2019 3:08 pm
Posts: 7
Yeah, I know it's a bit convoluted. It's 3am here, so I think it's best if I re-read 6502_cpu.txt tomorrow and see if it still makes sense.

This came up because my addressing mode handling and actual instruction execution are decoupled, so when I'm processing a mode I don't care what instruction it applies to. It's clear to me now that this can be faulty, I need to pay attention to r/w/rmw semantics.

Thanks for the help!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group