News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: NES ASM Question - How do I read a location without reading the actual address?  (Read 1494 times)

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
I think I might have a hard time putting this in words, but I'll try.  I want to be able to put in my pointer, the address of data that I want to be read.  But I'm using an assembler for my code.  So naturally, you wouldn't know the exact address of your code until it was assembled.  So, I want to change the table so that it reads the location of my data instead of the address.

For instance:

Code: [Select]
table: $C0, $40, $D1, $50

lda #<table
sta pointer
lda #>table
sta pointer + 1


$C040    (Data1)

Data to be read here at $C040


$D150    (Data2)

Data to be read here are $D150


So instead of that, I want it to be:


Code: [Select]
table: Data1, Data2

lda #<table
sta pointer
lda #>table
sta pointer + 1


Data1:

Data to be read here


Data2:

Data to be read here

I just don't know if I'm doing the table line right.  I don't care about the address obviously, since I just want the data that is located at the label.  I want to read the address AT the label, without actually reading the address itself, since obviously the address changes the more you program and add things.

I hope that made sense.

Thanks.

Disch

  • Hero Member
  • *****
  • Posts: 2725
  • NES Junkie
    • View Profile
First thing to know is that just about everything is a number.  Your labels get translated into a number based on what the PC is at the time of assembly.

Example:
Code: [Select]
; ... at $C000
foo:

; ... somewhere else
lda foo  ;<- gets assembled to lda $C000 because foo=$C000

With that in mind, assemblers let you embed raw numbers into your code.  Typically with a .word or .dw directive:

Code: [Select]
.word foo  ; assembles to ".word $C000" -- which will be '00 C0' in the final binary
  ; might be ".dw foo" depending on your assembler


So to do what you want:

Code: [Select]
table:
.word Data1, Data2

LDA table
STA pointer
LDA table+1
STA pointer+1  ; pointer points to Data1

LDY #0
LDA (pointer),Y  ; reads first byte from Data1

Or, if you want to index your table:

Code: [Select]
table:
.word Data1, Data2


; assume A is the index for above table.  IE, A=0 means you want to read from Data1
;   but A=1 means you want to read from Data2

ASL A  ; double it (2 bytes per pointer)
TAX
LDA table,X
STA pointer
LDA table+1,X
STA pointer+1

LDY #0
LDA (pointer),Y

Or alternatively:

Code: [Select]
table_low:
.byte <Data1, <Data2

table_high:
.byte >Data1, >Data2

; no need to double A, since there's only 1 byte in each table instead of 2 bytes
TAX
LDA table_low,X
STA pointer
LDA table_high,X
STA pointer+1

...

That last approach is probably the best since it allows for a full 256 entries without having to deal with any carry, plus it saves a few cycles/bytes because you don't need the ASL.

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Cool Disch.  Thank you.  Does .word work because it represents 16 bits (2 bytes)?

Disch

  • Hero Member
  • *****
  • Posts: 2725
  • NES Junkie
    • View Profile
Cool Disch.  Thank you.  Does .word work because it represents 16 bits (2 bytes)?

Yes.  ".word" / ".dw" will output a raw 2-byte value.   ".byte" / ".db" will output a single byte

Code: [Select]
.word 1, 2, 3    ; outputs the following to the binary:  01 00 02 00 03 00
.byte 1, 2, 3    ; outputs the following to the binary:  01 02 03

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Thanks Disch for clearing that up.  It's something that's been puzzling me for a little while.  I want to read some graphics tiles from a table, but to save space I wanted to be able to read the pointer locations from a table.  Thank you! :)