It is currently Thu Apr 26, 2018 10:37 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Mon Jan 22, 2018 7:44 am 
Offline

Joined: Sun Jun 30, 2013 7:59 am
Posts: 17
Sorry for the rather muddled title, couldn't think of what to put exactly :?

In the nerdy nights tutorials, there is a comment on the 6th tutorial (http://nintendoage.com/forum/messagevie ... eadid=8172) in which someone (Zzap) loads the attribute and name tables in one loop. I'm having trouble understanding what's going on. Full code is here https://pastebin.com/f12cef2c1
Here's the part I'm having difficulties with:

Code:
LDA #low(background)
  STA AddrLow
  LDA #high(background)
  STA AddrHigh
 
  LDX #$04              ; Loop X 4 times
  LDY #$00              ; Loop Y 256 times
LoadBackgroundsLoop:
  LDA [AddrLow],y
  STA $2007
  INY
  BNE LoadBackgroundsLoop
; Outer loop
  INC AddrHigh           ; increment high byte of address backg to next 256 byte chunk
  DEX                    ; one chunk done so X = X - 1.
  BNE LoadBackgroundsLoop   ; if X isn't zero, do again


I'm unsure of what value AddrLow and AddrHigh actually hold, because I don't understand what is being loaded into them.
LDA #low(background)
LDA #high(background)
What does this mean? there is no value set to low anywhere in the code. I've also never seen () used before. I understand the looping and branching in the rest of the code well enough, but those parts are baffling me. The label background precedes the tile data in bytes, I know that much. I've just never seen anything like this before so having trouble understanding what #low(background) means, especially when low hasn't been set to any value prior.

Sorry for being so inept. I'm making progress slowly after a long hiatus, really appreciate any help you guys can offer. Thank you :)


Top
 Profile  
 
PostPosted: Mon Jan 22, 2018 8:20 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2040
Location: DIGDUG
Are you familiar with pointers in other programming languages?

AddrLow and AddrHigh are 2 zero page RAM addresses. You put the address of the data here, and then you can 'indirectly' load from the data using the (INDIRECT), Y mode.

So let's say the data is at address 9000. You load the pointer with values 90 and 00, then you are basically saying, load from 9000, when you do LDA (AddrLow), y assuming y is zero.

6502 is little endian, so the small byte of the address is first, the high byte is next.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Mon Jan 22, 2018 1:32 pm 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 291
'background' is an address to the level data that's being copied. It could be defined in the source like this:

Code:
background:
.byt 50
.byt 34
.byt 130
.byt 200
; continue for 1024 bytes


An address is 16 bits. The built-in functions 'low' and 'high' take 16 bit constant values and split them up into two 8 bit values: a low byte and a high byte.

'AddrLow' is being used for indirect indexed addressing, as Dougeff mentioned. Basically, this allows you to write a subroutine and reuse the code for different data (e.g. reuse it for different levels).

You could write the code like this:

Code:
  LDX #$04              ; Loop X 4 times
  LDY #$00              ; Loop Y 256 times
LoadBackgroundsLoop:
  LDA background, y    ; look here!
  STA $2007
  INY
  BNE LoadBackgroundsLoop
; Outer loop
  INC AddrHigh           ; increment high byte of address backg to next 256 byte chunk
  DEX                    ; one chunk done so X = X - 1.
  BNE LoadBackgroundsLoop   ; if X isn't zero, do again


By replacing 'LDA [AddrLow],y' with 'LDA background,y', the data being copied becomes hard coded. If you wanted to write a more generic routine that could copy different data from different locations you'd use indexed indirect addressing.


Top
 Profile  
 
PostPosted: Mon Jan 22, 2018 2:26 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 859
Location: cypress, texas
Sorry, dougeff's example used indirect indexed addressing so you'd need zero-page variables, like he said; but, hope this post is helpful, otherwise. : )

To make dougeff's example have less of a chance of causing head hurt:

AddrHigh would be loaded with 90 and AddrLow would be loaded with 00. Like (in asm6):
Code:
AddrHigh .equ $90
AddrLow .equ $00


---
But, like pubby said, since the code I put up there is a hardcoded address, a faster instruction, taking one byte more (3 bytes), is:
Code:
;at some valid address below $8FFE:
lda background, y

;and then have something like:

.pad $9000 ;<sets background's (starting) address to $9000
background:
.db 50, 34, 130, 200, ...etc. ; <could also be .db $32, $22, $82, $C8, ...etc.

 ;or even .db 50, $22, $82, 200, ...etc.


edit.


Top
 Profile  
 
PostPosted: Wed Mar 28, 2018 4:22 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 859
Location: cypress, texas
unregistered wrote:
Sorry, dougeff's example used indirect indexed addressing so you'd need zero-page variables, like he said; but, hope this post is helpful, otherwise. : )
indirect indexed addressing is lda (Oper), y

learned that from MOS Technology Family Programming Manual

A long time ago I printed out all of that manual's appendices. Just print pages 198 and 234 in landscape so it flips the pages.

MOS Technology created the 6502. The NES uses an alternate version called the 2A03; it lacks Decimal mode (the d flag is useless). It is really cool for me to have the creator's manual's appendices printed out; have used them so much. Appendix A and B are so nicely laid out! :)

Note: I've written lda (Oper), y next to Appendix E.9 to remind me of what indirect indexed addressing is. And I've added a small XOR truth table next to Appendix B's EOR. Writing small notes is really helpful for me. :)

edit:
wikipedia wrote:
The 6502 used in the NES was a second source version by Ricoh, a partial system-on-a-chip, that lacked the binary-coded decimal mode but added 22 memory-mapped registers (and on-die hardware) for sound generation, joypad reading, and sprite list DMA. Called 2A03 in NTSC consoles and 2A07 in PAL consoles...
Noticed that I must have printed out an earlier version of the manual because my Appendix B is left justified, I like that better than the centered version in the first and second editions for some reason, but below the branches in my Appendix B it says
Quote:
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to same page.
and so that was quite confusing. I failed at finding the earlier manual for you, but found that wikipedia quote and want to share it. :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group