Another noob question about address and label!

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Another noob question about address and label!
by on (#242932)
Hello!
I'm working on a "level switch room", I just load my background in this way:

Code:
  level_0_room_0:
  .db $30,$31,$30,$31,$30,$31,$30,$31,$30,$31,$30,$31,$30,$31,$30,$31
  ......
  .db $40,$41,$40,$41,$40,$41,$40,$41,$40,$41,$40,$41,$40,$41,$40,$41

  level_0_room_1:
  .db $D0,$D1,$D0,$D1,$D0,$D1,$D0,$00,$01,$D1,$D0,$D1,$D0,$D1,$D0,$D1
  ......
  .db $D0,$D1,$D0,$D1,$D0,$D1,$D0,$00,$01,$D1,$D0,$D1,$D0,$D1,$D0,$D1

  lda #low( level_0_room_0 )
  sta MATRIX_LVL_ROOM_ADDR + 0
  lda #high( level_0_room_0 )
  sta MATRIX_LVL_ROOM_ADDR + 1


everything works ok if I change the addressing from level_0_room_0 to level_0_room_1, but I need to do that dynamically but I don't know how. I tried to put "level_0_room_1" on an address but it seems it doesn't work.

Code:
  lda #low( level_0_room_0 )
  sta ROOM_TO_LOAD + 0
  lda #high( level_0_room_0 )
  sta ROOM_TO_LOAD + 1

  ....

  lda #low( ROOM_TO_LOAD )
  sta MATRIX_LVL_ROOM_ADDR + 0
  lda #high( ROOM_TO_LOAD )
  sta MATRIX_LVL_ROOM_ADDR + 1



So, what's the best way to put the address of a label "level_0_room_X" in a variable so I can load dynamically at run time?

Thanks! :)
Re: Another noob question about address and label!
by on (#242933)
There are other ways, but here's one of the simpler ways to select from a list of addresses (allows up to 128 of them):

Code:
address_table:
.dw level_0_room_0
.dw level_0_room_1

lda #1 ; change this to load other rooms
asl
tax
lda address_table,x
sta MATRIX_LVL_ROOM_ADDR + 0
lda address_table+1,x
sta MATRIX_LVL_ROOM_ADDR + 1


On your second code block, the first time you use low() and high() is correct. On the next part though it does low( ROOM_TO_LOAD ), which seems to be a variable. In that case, the data (address of level_0_room_0) isn't used, but instead you're getting the address of the ROOM_TO_LOAD variable.

edit:
fixed version of 2nd code block
Code:
  lda #low( level_0_room_0 )
  sta ROOM_TO_LOAD + 0
  lda #high( level_0_room_0 )
  sta ROOM_TO_LOAD + 1

  ....

  lda ROOM_TO_LOAD + 0
  sta MATRIX_LVL_ROOM_ADDR + 0
  lda ROOM_TO_LOAD + 1
  sta MATRIX_LVL_ROOM_ADDR + 1
Re: Another noob question about address and label!
by on (#242934)
Ok thanks! I will try as soon as I can!
Re: Another noob question about address and label!
by on (#242962)
Memblers wrote:
There are other ways, but here's one of the simpler ways to select from a list of addresses (allows up to 128 of them):

Code:
address_table:
.dw level_0_room_0
.dw level_0_room_1

lda #1 ; change this to load other rooms
asl
tax
lda address_table,x
sta MATRIX_LVL_ROOM_ADDR + 0
lda address_table+1,x
sta MATRIX_LVL_ROOM_ADDR + 1


On your second code block, the first time you use low() and high() is correct. On the next part though it does low( ROOM_TO_LOAD ), which seems to be a variable. In that case, the data (address of level_0_room_0) isn't used, but instead you're getting the address of the ROOM_TO_LOAD variable.

edit:
fixed version of 2nd code block
Code:
  lda #low( level_0_room_0 )
  sta ROOM_TO_LOAD + 0
  lda #high( level_0_room_0 )
  sta ROOM_TO_LOAD + 1

  ....

  lda ROOM_TO_LOAD + 0
  sta MATRIX_LVL_ROOM_ADDR + 0
  lda ROOM_TO_LOAD + 1
  sta MATRIX_LVL_ROOM_ADDR + 1


Ok, the second block works withou problem but now I need to iterate on a list of Rooms:

Code:
level_0_rooms:
  .dw level_0_room_0
  .dw level_0_room_1
  .dw level_0_room_2

   lda #1 ; change this to load other rooms
   asl a
   tax
   lda level_0_rooms, x
   sta MATRIX_LVL_ROOM_ADDR + 0
   lda level_0_rooms + 1, x
   sta MATRIX_LVL_ROOM_ADDR + 1


But the background start to glitch badly. Now I need to understand if I do something like this:

Code:
  ldx #$00
  lda level_0_rooms, x


I'm putting in A the first address in level_0_rooms, so level_0_room_0? Right? And it's the same of:

Code:
  lda #low( level_0_room_0 )
  sta MATRIX_LVL_ROOM_ADDR + 0
  lda #high( level_0_room_0 )
  sta MATRIX_LVL_ROOM_ADDR + 1


In your example ASL multiply by 2 the "index" to increase it because the address are 16 bit long right?

Thanks! :)
Re: Another noob question about address and label!
by on (#242965)
kikutano wrote:
[
Code:
level_0_rooms:
  .dw level_0_room_0
  .dw level_0_room_1
  .dw level_0_room_2

   lda #1 ; change this to load other rooms
   asl a
   tax
   lda level_0_rooms, x
   sta MATRIX_LVL_ROOM_ADDR + 0
   lda level_0_rooms + 1, x
   sta MATRIX_LVL_ROOM_ADDR + 1


But the background start to glitch badly.

This code looks correct. When exactly is it starting to glitch?

Quote:
Code:
  ldx #$00
  lda level_0_rooms, x


I'm putting in A the first address in level_0_rooms, so level_0_room_0? Right?

Your list of addresses contains 16-bit elements, you can't read from it using 8-bit addressing (X indexes bytes) and an 8-bit register (A). The 6502 only does 8-bit operations, so you absolutely must double the index, so it indexes words instead of bytes, and read the 2 bytes separately, because A can only hold 8-bit values.

There is an alternative, which is to have two 8-bit lists instead of a single 16-bit one, so that you can access them without having to double the index.

Code:
ListOfAddressesLow:
  .db low(Address0)
  .db low(Address1)
  .db low(Address1)

ListOfAddressesHigh:
  .db high(Address0)
  .db high(Address1)
  .db high(Address1)

But you still have to load the two bytes separately and copy them to RAM before you can use them as a full 16-bit address.