nesasm low/high confusion with indirect indexing

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
djcouchycouch
Posts: 97
Joined: Sat May 28, 2011 10:30 am

nesasm low/high confusion with indirect indexing

Post by djcouchycouch »

I've been trying to wrap my head around how to use the low/high macros.

Let's say I've got something like:

Code: Select all

.rsset $0000
currentSpriteDefinition .rs 2    

; sprite definition data store somewhere.
sprite_mario_definition:
  ; sprite 1
  .db 0 ; y offset
  .db $32; sprite index
  .db %00000000
  .db 0 ; x offset 
  ; sprite 2
  .db 0 ; y offset
  .db 33; sprite index
  .db %00000000
  .db 8 ; x offset
  ; sprite 3  
  .db 8 ; y offset
  .db 34; sprite index
  .db %00000000
  .db 0 ; x offset
  ; sprite 4
  .db 8 ; y offset
  .db 35; sprite index
  .db %00000000
  .db 8 ; x offset  

And sometime during the code, currentSpriteDefinition will point to the memory at sprite_mario_definition.

But what I'm confused on is how the Low and High macros work with both currentSpriteDefinition and sprite_mario_definition. It's all been blind trial and error so far to make it work. I don't know what value to expect when doing:

Code: Select all

LDA LOW(currentSpriteDefinition) 
LDA #LOW(currentSpriteDefinition)
LDA LOW(sprite_mario_defintion)
LDA #LOW(sprite_mario_definition)

STA LOW(currentSpriteDefinition)

Can someone clear this up for me?

Thanks!
Shawn
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Are you trying to use currentSpriteDefinition as a pointer to sprite_mario_definition? If so, I think you're looking for this:

Code: Select all

	lda #low(sprite_mario_definition)
	sta currentSpriteDefinition+0
	lda #high(sprite_mario_definition)
	sta currentSpriteDefinition+1
You obviously don't need the "+0", but I like to use it just to make it clear that the address is part of a multi-byte variable. Also, you might have to use "<" in the store commands if you want to use ZP addressing, but that's not required.
djcouchycouch
Posts: 97
Joined: Sat May 28, 2011 10:30 am

Post by djcouchycouch »

My specific problem is after currentSpriteDefinition is set to the location of sprite_mario_defintion, I'm not sure how to move the currentSpriteDefinition along the data. I'd be working with it four bytes at a time.

Code: Select all

; defined earlier
SUB_SPRITE_SIZE = 4

...
...
...
; move the currentSpriteDefinition down one sprite. four bytes.
  LDA LOW(currentSpriteDefinition)
  CLC
  ADC SUB_SPRITE_SIZE
  STA LOW(currentSpriteDefinition)
  LDA HIGH(currentSpriteDefinition)
  ADC #0
  STA HIGH(currentSpriteDefinition)

I think that's right, but not sure.


But generally, I'd also like to figure out what exactly the different calls would do.

Code: Select all


; example

; currentSpritesDefinition's location is at $0300. Two bytes reserved.
; currentSpriteDefinition's value is $1234
; sprite_mario_definition's location is at $8000
; sprite_mario_defnition's value is $55

LDA LOW(currentSpriteDefinition)      ; loads $34 into A? 
LDA #LOW(currentSpriteDefinition)    ; ???
LDA LOW(sprite_mario_defintion)      ; loads $00 into A? 
LDA #LOW(sprite_mario_definition)   ; ???

STA LOW(currentSpriteDefinition)      ; stores ??? into A? 
Thanks!
Shawn
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

shawnleblanc wrote:My specific problem is after currentSpriteDefinition is set to the location of sprite_mario_defintion, I'm not sure how to move the currentSpriteDefinition along the data. I'd be working with it four bytes at a time.

Code: Select all

; defined earlier
SUB_SPRITE_SIZE = 4

...
...
...
; move the currentSpriteDefinition down one sprite. four bytes.
  LDA LOW(currentSpriteDefinition)
  CLC
  ADC SUB_SPRITE_SIZE
  STA LOW(currentSpriteDefinition)
  LDA HIGH(currentSpriteDefinition)
  ADC #0
  STA HIGH(currentSpriteDefinition)
I'm pretty sure that "LOW(currentSpriteDefinition)" will return the low byte of the address where "currentSpriteDefinition" is (somewhere in ZP), not the low byte of its contents. Since you want to modify the address it points to, you want to modify its contents. Try this:

Code: Select all

	clc
	lda currentSpriteDefinition+0
	adc #SUB_SPRITE_SIZE ;the "#" is important here!
	sta currentSpriteDefinition+0
	lda currentSpriteDefinition+1
	adc #$00
	sta currentSpriteDefinition+1
Again, "+0" is entirely optional and is there only for clarity.
But generally, I'd also like to figure out what exactly the different calls would do.
Let's see...

Code: Select all

; currentSpritesDefinition's location is at $0300. Two bytes reserved.
; currentSpriteDefinition's value is $1234
; sprite_mario_definition's location is at $8000
; sprite_mario_defnition's value is $55
I'm not sure I understand the terminology here. You haven't told me where in RAM currentSpriteDefinition is, but I'll consider it to be at $0000 because of your previous post. Also, I don't get what you mean by "sprite_mario_defnition's value is $55". "sprite_mario_definition" is a label in ROM, and if this label is at address $8000, its "value" should be the contents of address $8000, which from your last post appears to be 0 (the Y offset of the first sprite). I guess we're not on the same page here.

Code: Select all

LDA LOW(currentSpriteDefinition)      ; loads $34 into A?
Loads the contents of memory location $00 (the low byte of $0000) into A. In this case it's be the same as "LDA currentSpriteDefinition", because "currentSpriteDefinition" is in ZP. If "currentSpriteDefinition" is pointing to $1234, the value loaded would be $34. Please note that "LDA HIGH(currentSpriteDefinition)" will also result in $34 being loaded into A, because because the high byte of the address where "currentSpriteDefinition" is is also $00.

Code: Select all

LDA #LOW(currentSpriteDefinition)    ; ???
Loads $00 (the low byte of $0000) into A.

Code: Select all

LDA LOW(sprite_mario_defintion)      ; loads $00 into A?
Loads the contents of memory location $00 (the low byte of $8000) into A.

Code: Select all

LDA #LOW(sprite_mario_definition)   ; ???
Loads $00 (the low byte of $8000) into A.

Code: Select all

STA LOW(currentSpriteDefinition)      ; stores ??? into A?
Stores whatever is in A into memory location $00 (the low byte of $0000).

To sum it up:

There's no reason to ever use LOW() and HIGH() with a store command, it only makes sense to use them with load commands. You only need LOW() and HIGH() if you need the address of a variable/label, never its contents. To access the contents of different bytes of a multi-byte variable you should use "+1", "+2", etc. after their names.
djcouchycouch
Posts: 97
Joined: Sat May 28, 2011 10:30 am

Post by djcouchycouch »

Thanks for clearing that up. I've got my stuff working now.
Post Reply