Help understanding indirect Y

Building your first 6502-based project? We'll help you get started here.
Post Reply
gluesniffing
Posts: 2
Joined: 02 May 2024

Help understanding indirect Y

Post by gluesniffing »

Hello all. I'm just sinking my teeth into 6502 and I thought a good idea for a simple starter program was to write one that could fill a screen. My various attempts failed because I'm an idiot and didn't know how to properly reference 16 bit addresses. So, I found a program that does what I was trying to do so I could try to reverse engineer it a bit, but it just left me with more questions. Here's the code I found:

Code: Select all

lda #1
ldx #$02

fill_screen:
stx $01

draw_segment:
sta ($00),Y
iny
bne draw_segment

inx
cpx #$06
bne fill_screen
As I understand it, the X register being stored at $01 represents the first half of the 16 bit address being referenced, which is then combined(?) with the increasing Y value. Starting at $0200 and increasing with each loop until reaching the end of the vram at $05FF. However, I don't understand how this works. The indirect indexed reference

Code: Select all

sta ($00),Y
is referencing $00, which stores nothing. Shouldn't it be

Code: Select all

sta ($01),Y
? And in draw_segment, there is a branch not equal instruction with no compare instruction before it? What is the branching condition?

All of this is probably very simple to anyone versed in machine languages, but that's why I'm in the newbies board. Try and go easy on me.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Help understanding indirect Y

Post by 8BIT »

Code: Select all

sta ($00),Y
Will take the 16 bit address stored at $00 & $01 ($00 low byte, $01 high byte) and add the value of Y to that. The value in the Accumulator "A" register is then stored to memory at the resulting address.

The

Code: Select all

INY
opcode will affect the Zero Flag in the status register so once Y goes from $FF to $00, the flag is set and the branch is not taken.

I think they are assuming the value of $00 to be $0 and storing $02 at $01 to make the effective start address $0200 + Y. The innner loop then fills all locations from $0200 to $02FF then increments $01 and repeats until it reaches $05FF.

Hope this helps!

Daryl
Please visit my website -> https://sbc.rictor.org/
gluesniffing
Posts: 2
Joined: 02 May 2024

Re: Help understanding indirect Y

Post by gluesniffing »

Ohh, that makes a lot more sense now, thank you! The syntax is just a bit confusing. Does it just use the next location in memory as the high byte and the referenced byte as the low one? If I were to shift addresses by one, and store the high byte in $02 and use

Code: Select all

sta ($01),Y
would it have the same effect?

edit: also, yeah, documentation told me that branching runs on the Z flag, so it makes sense now that I know it's triggered by an overflow
Paganini
Posts: 516
Joined: 18 Mar 2022

Re: Help understanding indirect Y

Post by Paganini »

gluesniffing wrote:
...in draw_segment, there is a branch not equal instruction with no compare instruction before it? What is the branching condition?
This is an excellent newbie question. Many 6502 instructions set status flags automatically so you can test them without needing any compare instructions. In this common looping pattern:

Code: Select all

    ldy     #0
loop:
    ;   do some stuff here
    iny
    bne     loop
When .Y contains $FF, adding 1 to it will cause it to "wrap around" to 0. The iny instruction automatically sets the Z flag when this happens. So, this loop will do some stuff 256 times (.Y = 0 through 255). A good instruction set reference will tell you what flags an instruction affects.
"The key is not to let the hardware sense any fear." - Radical Brad
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Help understanding indirect Y

Post by GARTHWILSON »

An automatic compare-to-zero instruction is built into the following 65c02 instructions:  LDA, LDX, LDY, INC, INX, INY, DEC, DEX, DEY, INA, DEA, AND, ORA, EOR, ASL, LSR, ROL, ROR, PLA, PLX, PLY, SBC, ADC, TAX, TXA, TAY, TYA, and TSX.  (This is from the middle of the programming-tips page of the 6502 primer, at http://wilsonminesco.com/6502primer/PgmTips.html .)
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Help understanding indirect Y

Post by BigDumbDinosaur »

GARTHWILSON wrote:
An automatic compare-to-zero instruction is built into the following 65c02 instructions...
The fact that the 6502 family handles instructions in this fashion is one of the reasons it produces good throughput at relatively sedate clock speeds.  Not having to do an explicit comparison each time a register or memory value is incremented/decremented can eliminate a lot of clock cycles out of a loop.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
6502inside
Posts: 101
Joined: 03 Jan 2007
Location: Sunny So Cal
Contact:

Re: Help understanding indirect Y

Post by 6502inside »

gluesniffing wrote:
Ohh, that makes a lot more sense now, thank you! The syntax is just a bit confusing. Does it just use the next location in memory as the high byte and the referenced byte as the low one? If I were to shift addresses by one, and store the high byte in $02 and use

Code: Select all

sta ($01),Y
would it have the same effect?
Yes. Your address pair is now in $01/$02.
Post Reply