Need help with addressing in my monster data reading code.

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
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Need help with addressing in my monster data reading code.

Post by Eisetley »

Hi. Here's code that loads monster data (type, x y pos, etc.).

Code: Select all

LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDY #$08
  LDX #$00
LoadEnemiesLoop:
  LDA spawn_test0 - 1, y
  STA Mob8Id - 1, y
  
  LDA spawn_test0 + 7, y
  STA Mob8Hp - 1, y

  LDA spawn_test0 + 15, y
  STA EnemyRam + 3, x

  LDA spawn_test0 + 23, y
  STA EnemyRam, x

  LDA spawn_test0 + 31, y
  STA Mob8Direction - 1, y

  TXA
  CLC
  ADC #$10
  TAX

  DEY
  BNE LoadEnemiesLoop
  INC MobLoadingStatus
  RTS
and sample spawndata:

Code: Select all

spawn_test0:

;mob ids
.db #oak, #oak, #oak, #oak, #oak, #oak, #oak, #oak

;hp
.db $05, $05, $05, $05, $05, $05, $05, $05

;x pos
.db $20, $20, $20, $20, $90, $85, $50, $C0

;y pos
.db $20, $40, $60, $80, $40, $30, $60, $90

;direction
.db #Mob_Dir_West, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West
The thing is that I don't know how to make it read from anything else than spawn_test0. I don't want to copy and paste that subroutine as many times as there are rooms in my game of course. I want it to be something like this:

Code: Select all

LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDY #$08
  LDX #$00
LoadEnemiesLoop:
  LDA CurrentSpawn - 1, y
  STA Mob8Id - 1, y
  
  LDA CurrentSpawn + 7, y
  STA Mob8Hp - 1, y

  LDA CurrentSpawn + 15, y
  STA EnemyRam + 3, x

  LDA CurrentSpawn + 23, y
  STA EnemyRam, x

  LDA CurrentSpawn + 31, y
  STA Mob8Direction - 1, y

  TXA
  CLC
  ADC #$10
  TAX

  DEY
  BNE LoadEnemiesLoop
  INC MobLoadingStatus
  RTS
I want to be able to set what CurrentSpawn means before calling LoadEnemies subroutine.
CurrentSpawn = spawn_test0
JSR LoadEnemies
CurrentSpawn = spawn_test1
JSR LoadEnemies
etc.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need help with addressing in my monster data reading cod

Post by dougeff »

The thing is that I don't know how to make it read from anything else than spawn_test0
I would solve this by having 2 pointers (indirect), y. One source (points to data set) and one destination (which mob object). You then adjust each pointer itself rather than adjusting y. Keep y at #0.

You can use a temporary variable as a loop counter.
LDA #count
STA temp
...
DEC temp
BNE @loop


EDIT, now that I think about it, it would be more efficient to still use y as the index and the loop counter. So you would INY and CPY.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Re: Need help with addressing in my monster data reading cod

Post by Eisetley »

Wouldn't it require dumping all the spawn data into the ram?
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Need help with addressing in my monster data reading cod

Post by unregistered »

Eisetley wrote:Wouldn't it require dumping all the spawn data into the ram?
No, put all of your spawn data into ROM. :) We have limited RAM: $0000 through $07FF. You have lots and lots of ROM though (an abundant amount of ROM if you use a mapper, like MMC1).

Putting spawn data into RAM would just enable you to change it at will; however, changing all of that data would take many cycles and would take up ROM space as well (for all the instructions doing the changing).

---
Eisetley wrote:

Code: Select all

  LDY #$08
  LDX #$00

...

 LDA spawn_test0 + 15, y
 STA EnemyRam + 3, x
If I'm remembering what tokumaru told me correctly, it isn't possible to add and subtract from memory locations when using the Zero Page Indexed by X, Absolute Indexed by X, and Absolute Indexed by Y addressing modes. (Zero Page Indexed by Y doesn't allow that either.)

Advice:
  • Change Y instead of trying to change the memory address.
  • or follow dougeff's advice and use a pointer
  • Since your X is constantly at 0, just remove the , x and

Code: Select all

 STA EnemyRam + 3
would work just fine. :)

Done editing this post now. : ) Edited once more: added "use" infront of "a mapper" and fixed my misspellings of "advice" : )
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Need help with addressing in my monster data reading cod

Post by unregistered »

Eisetley wrote: I want to be able to set what CurrentSpawn means before calling LoadEnemies subroutine.
CurrentSpawn = spawn_test0
JSR LoadEnemies
CurrentSpawn = spawn_test1
JSR LoadEnemies
My, untested, pointer advice/example, from what I've learned so far: code is for Loopy's asm6

Code: Select all

.enum $000
 CurrentSpawn .dsb 2  ;<the pointer
.ende

;then, somewhere in ROM
 ldx #00 ;or: ldx #01 ;anything higher than #01, in this example, will load incorrectly...
 ; because spawns_l and spawns_h only have 2 bytes each :)
 lda spawns_l, x
 sta CurrentSpawn+0
 lda spawns_h, x
 sta CurrentSpawn+1

;then inside LoadEnemies
;set y to whatever byte you want to read from the spawn_test loaded
 lda (CurrentSpawn), y

;then somewhere else in ROM
spawns_l:  .dl spawn_test0, spawn_test1 ;.db <spawn_test0, <spawn_test1
spawns_h:  .dh spawn_test0, spawn_test1 ;.db >spawn_test0, >spawn_test1
You could probably make your LoadEnemies faster than just calling lda (CurrentSpawn), y a bunch, I have to go, hopefully this example will help you or others to get started with pointers. :)

edit: Switched the order of spawns_h and spawns_l because, from my experience, it is less stressful for a NES game if you order the memory locations to mimic the order in which you use them. Since the low byte always comes first in a pointer, it makes sense, in my opinion, to order the bytes accordingly.


final edit: Am so very blessed to have discovered using Absolute Indexed by X for accessing the different groups of bytes in my sister's NES game. I wanted a really quick way of using pointers; I prayed about it and He helped me to solve that problem!! :mrgreen: :)
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Re: Need help with addressing in my monster data reading cod

Post by Eisetley »

Thanks for help, that's what I came up with at this point:

Code: Select all

LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDX CurrentSpawnId
  LDA spawns_lo, x
  STA CurrentSpawn
  LDA spawns_hi, x
  STA CurrentSpawn + 1
  DEC CurrentSpawn

  LDY #$19 ;; copy first 25 bytes to ram
LoadEnemiesLoop1:
  LDA (CurrentSpawn), y
  STA MobAmount - 1, y
  DEY
  BNE LoadEnemiesLoop1

  LDY #$29 ;loop for 8 mobs, every loop stores 2 values -->cpy#$19
  LDX #$00
LoadEnemiesLoop2: ;;load last 16 bytes
  LDA (CurrentSpawn), y
  STA EnemyRam, x
  DEY

  LDA (CurrentSpawn), y
  STA EnemyRam + 3, x

  DEY
  CPY #$19
  BEQ +
  TXA
  CLC
  ADC #$10
  TAX
  JMP LoadEnemiesLoop2
  +
  INC MobLoadingStatus
  RTS

Code: Select all

;;;;;TEST ROOM 0 - SPAWN;;;;;
;;room size =  41 bytes
spawn_test0:
;active mob amount
.db $08
;mob ids
.db #nettle, #nettle, #nettle, #nettle, #nettle, #nettle, #nettle, #nettle

;hp
.db $05, $05, $05, $05, $05, $05, $05, $05

;direction
.db #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_East, #Mob_Dir_North, #Mob_Dir_West

    ;x   ;y
.db $20, $20    ;mob8
.db $30, $30    ;mob7
.db $40, $40    ;mob6
.db $50, $50    ;mob5
.db $60, $60    ;mob4
.db $70, $70    ;mob3
.db $80, $80    ;mob2
.db $90, $90    ;mob1
https://www.youtube.com/watch?v=3RzfjRgBO18

The only thing that bothers me is that I've had a really rough time loading the first value into the right place (;active mob amount .db $08). I've had to DEC the low byte to make it work.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need help with addressing in my monster data reading cod

Post by dougeff »

Array begins at zero.

see every programming joke written for reference. ;)

EDIT.
It seems you are exiting each loop before loading the 0th element.
nesdoug.com -- blog/tutorial on programming for the NES
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Need help with addressing in my monster data reading cod

Post by Oziphantom »

Make sure you data is page aligned it XX00. Then make each array page aligned. Say you put the data at $9000 for example

Code: Select all

* = $9000
Mob_IDs .db #oak, #oak, #oak, #oak, #oak, #oak, #oak, #oak, start screen 2 here...
align $100 ; not sure how do this in your assembler
Mob_HP .db $05, $05, $05, $05, $05, $05, $05, $05, start screen 2 here...
align $100
Mob_X .db $20, $20, $20, $20, $90, $85, $50, $C0, start screen 2 here...
align $100
Mob_Dir .db #Mob_Dir_West, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, start screen 2 here...
Then you have 4 words in ZP ptrIDs,ptrHP,ptrX,ptrDir initilially you will load them as follows, but at some point you will get beyond 256 arrays being able to hold all spawn points

Code: Select all

lda #0
sta ptrIDs
sta ptrHP
sta ptrX
sta ptrDir
ldx #>Mob_IDs
stx ptrIDs+1
inx
stx ptrHP
inx
stx ptrX
inx
stx ptrDir
Then you have a table of start and end index per screen

Code: Select all

EnemySpawn_start .db 0,8
EnemySpawn_end .db 8,somevalue
to read the data you then do

Code: Select all

ldx Screen 
ldy EnemySpawn_start,x
lda EnemySpawn_end,x
sta ZPTemp
Loop
lda (ptrIds),y
; do something with it
lda (ptrHP),y
; do something with it
lda (ptrX),y
; do something with it
lda (ptrDir),y
; do something with it
iny
cpy ZPTEmp
bne Loop
Post Reply