Another noob question about address and label!

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
kikutano
Posts: 115
Joined: Sat May 26, 2018 6:14 am
Location: Italy

Another noob question about address and label!

Post by kikutano »

Hello!
I'm working on a "level switch room", I just load my background in this way:

Code: Select all

  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: Select all

  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! :)
User avatar
Memblers
Posts: 4100
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Another noob question about address and label!

Post by Memblers »

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: Select all

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: Select all

  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
User avatar
kikutano
Posts: 115
Joined: Sat May 26, 2018 6:14 am
Location: Italy

Re: Another noob question about address and label!

Post by kikutano »

Ok thanks! I will try as soon as I can!
User avatar
kikutano
Posts: 115
Joined: Sat May 26, 2018 6:14 am
Location: Italy

Re: Another noob question about address and label!

Post by kikutano »

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: Select all

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: Select all

  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: Select all

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: Select all

  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: Select all

  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! :)
User avatar
tokumaru
Posts: 12535
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Another noob question about address and label!

Post by tokumaru »

kikutano wrote:[

Code: Select all

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?

Code: Select all

  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: Select all

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.
Post Reply