It is currently Tue Dec 18, 2018 11:13 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Count over 255.
PostPosted: Mon Jul 16, 2018 1:00 am 
Offline

Joined: Sat May 26, 2018 6:14 am
Posts: 57
Location: Italy
Hello again,
thanks for all of your suggests, I'm learning a lot of things in this forum, but the ASM for Nes always give me new challenges. I will try to explain my problem. In my Arkanoid clone I copied all the tiles on RAM to check the collision detection, everything works great, the collision works, the VRAM is updated correctly so I can see the change on the background... Until the tile 255! :D I know that NES can store only 8 bit value and the best way to work is using 16 addressing, I have no problem to use low and high byte to use the 16 addressing and access to all address on VRAM or on RAM. BUT. I can't really understand how to compute a tile greater than 255. I do something like this:

Code:
  LDA #$00
  STA BALL_POS_X_ON_TILE
  STA BALL_POS_Y_ON_TILE

  LDA BALL_POS_X
  LSR A
  LSR A
  LSR A                    ; Divide by 8
  STA BALL_POS_X_ON_TILE

  LDA BALL_POS_Y         

  LSR A
  LSR A
  LSR A                   ; Divide by 8
  STA BALL_POS_Y_ON_TILE

...

  LDX #$00
ComputeXYOnTile:
  LDA BALL_POS_X_ON_TILE
  CLC
  ADC #$20
  STA BALL_POS_X_ON_TILE
  INX
  CPX BALL_POS_Y_ON_TILE
  BNE ComputeXYOnTile

....

PerformBallColWithBrickLeft:
  LDX BALL_POS_X_ON_TILE
  LDA $0400, x ( $400 is where the ram map begin )
  CMP #$2D
  BEQ PerformBallCollisionWithBrick

...


I know BALL_POS_X_ON_TILE is always between 0-255 because it's a value stored on a single location, but I can't understand how to store or use a tile that is greater than 255, with addressing it's not a problem, but in this case? How can I do that? Could you please give me an example to learn?

Thanks a lot, this is the last big "problem" to solve to finish my first demo! :P


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Mon Jul 16, 2018 1:19 am 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 448
I don't fully understand what you're asking, but computing a nametable address would look something like this:

Code:
lda #0
sta ADDR+1

lda BALL_POS_Y
and #%11111000
asl
rol ADDR+1
asl
rol ADDR+1
sta ADDR+0

lda BALL_POS_X
lsr
lsr
lsr
clc
adc ADDR+0
sta ADDR+0
lda #$20 ; high byte of address
adc ADDR+1
sta ADDR+1


(haven't tested but it should work)

If you wanted to test ram, just use indirect addressing with a Y of 0 after computing the address:

Code:
ldy #0
lda (ADDR), y


So accessing RAM and VRAM is really done the same way.


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Mon Jul 16, 2018 1:57 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3731
Location: A world gone mad
There are only 256 tiles available on the NES (values $00 to $FF) at any one time. That's all the pattern table provides space for, and all you can natively address in a single nametable. Period. If you think I'm kidding, I'm not (read: "The pattern table is divided into two 256-tile sections ...").

If you need more than that, then you need to look into using either:

a) a mapper with CHR-RAM (and thus write your own graphics to the pattern table (CHR) yourself using 6502 code), or,
b) a mapper with CHR-ROM (which lets you swap out all of, or portions of, the pattern table (CHR) immediately using 6502 code).

A good example of (a) is mapper 1 or UNROM. The wiki has a demonstration of how to do this.

A good example of (b) is mapper 3 or CNROM which lets you swap in/out the entire 8KByte CHR, or you can use something more complex like MMC1 (mapper 1) (swap 4KByte portions of CHR) or MMC3 (mapper 4) (swap 2KByte or 1KByte portions of CHR).

If you need help implementing these, or don't understand the difference between the two, read this.

If I've misunderstood what your problem is, then sorry, all of the above is wasted effort on my part.


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Mon Jul 16, 2018 4:53 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2355
Location: DIGDUG
It sounds like he has an array for collisions in the RAM that is larger than 256.

If that were the case, I would use (indirect), y and adjust the high byte of the indirect address if it rolls past 255.

The collision array I used for Jammin Honey is a bit bigger than 256. So, it's not uncommon.

However, you seem to be using a fairly slow method to calculate the address of the collision byte.

...if its a 16x8 sized breakable tile like Arkanoid. Then it would be 16 elements wide and (??) 18 elements high. Your array should fit in a 288 byte array. So this should work...

LDA #4 ;address 400
STA pointerHigh
LDA x position
LSR a
LSR a
LSR a
LSR a ;divide by 16
Sta pointerLow
LDA y position
;divide 8, then multiply 16 = multiply 2
ASL a ;times 2
BCC +
INC pointerHigh
+
AND #$f0
CLC
ADC pointerLow
STA pointerLow
LDY #0
LDA (pointerLow), y

;where pointerLow and pointerHigh are 2 consecutive zeropage addresses.

Edit.
AND #$f0
CLC
ADC pointerLow

Could have been

AND #$f0
ORA pointerLow

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


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Mon Jul 16, 2018 5:20 am 
Offline

Joined: Sat May 26, 2018 6:14 am
Posts: 57
Location: Italy
Yes, I've 960 tiles on RAM ( 32 * 30 ) and when I translate the x, y point on tile it will be greater than 255. I will read your answers and I will respond as soon as I can! Thanks! :)


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 12:21 am 
Offline

Joined: Sat May 26, 2018 6:14 am
Posts: 57
Location: Italy
dougeff wrote:

BCC +
INC pointerHigh
+


What's mean that "+" simbol? I can't compile it, it's just a label? Something like:

Code:
  BCC label
  INC pointerHigh
label:
  ...


thanks! :)


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 12:26 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11015
Location: Rio de Janeiro - Brazil
Yeah, it's an anonymous label, ASM6 style, and yes, you can rewrite it like you did.


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 12:27 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2131
Location: Fukuoka, Japan
Yes, those are unnamed labels. '+' one's are for jumping forward and '-' ones backward. Not all compiler support that paradigm. I know that ca65 uses them but don't know about other ones.

You can use any name in that case to make it work in your compiler.

edit:

Tokumaru pressed the send button faster than me :lol:


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 12:29 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3731
Location: A world gone mad
It's a label that means "the next occurrence of label +", and only works forwards (i.e. "the label is somewhere past/later on/in front of the current line"). The opposite/reverse is -. However, these are re-usable labels, and can be nested (ex. +, ++, +++, etc.). This is an assembler-specific syntax, so it may not be available in the assembler you're using. You can use normal labels and accomplish the same thing.


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 9:42 am 
Offline

Joined: Sat May 26, 2018 6:14 am
Posts: 57
Location: Italy
dougeff wrote:
ASL a ;times 2
BCC label
INC pointerHigh

label:
AND #$f0
ORA pointerLow



I really don't understand how the BCC is working in this code. I know that BCC is used to branch and compare like this:

Code:
CMP  $20     ;Accumulator less than location $20?
        BCC  THERE
HERE                 ;No, continue execution here.
        .
        .
        .
THERE                ;Execute this if Accumulator is less than location $20.
        .
        .
        .


But in this case what BCC is comparing? The value in the accumulator? Could you please explain me? Why the #04 is stored on High Byte and not on Low Byte considering the fact that the collision map start at address $0400 on RAM?

Sorry for my dumps questions but I'm still learning ASM :oops: and everything is new for me. Thanks!


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 10:00 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7026
Location: Canada
There is a thing called "flags" which contain the last result of an operation.

CMP in particular updates the C (carry) flag, which is what BCC uses. (Branch if C is Clear)

Many instructions affect the flags, but they only change what is related to the operation. An instruction like LDA won't affect carry, but does update the Z (zero) flag, for instance, so a LDA can set the flags for a BEQ/BNE (branch if equal, branch if not equal) on whether the loaded value was zero.

Instruction reference will tell you which flags each instruction affects:
http://www.obelisk.me.uk/6502/reference.html

Info about registers and flags. Z (zero) and C (carry) are the most important ones.
http://www.obelisk.me.uk/6502/registers.html


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 10:06 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3731
Location: A world gone mad
kikutano wrote:
I really don't understand how the BCC is working in this code. I know that BCC is used to branch and compare like this:

Code:
CMP  $20     ;Accumulator less than location $20?
        BCC  THERE
HERE                 ;No, continue execution here.
        .
THERE                ;Execute this if Accumulator is less than location $20.
        .


You may want cmp #$20, not cmp $20. Your comment says "than location $20", so I can't tell if you mean "the value in/at memory location $20", or "literal value $20".

cmp $20 would be comparing the accumulator against the value in memory location $20, while cmp #$20 would be comparing the accumulator against literal value $20.

As for branches: there are two commonly-used "aliases" for branch opcodes that might help you, depending on context:

BCC is sometimes written as BLT (branch if less than)
BCS is sometimes written as BGE (branch if greater than or equal to)


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Tue Jul 17, 2018 10:44 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2355
Location: DIGDUG
I'm not comparing. I'm indexing an array > 256.

ASL a ;times 2
BCC +
INC pointerHigh
+

the "ASL a" shifts all the bits left, and puts the high order bit in the Carry Flag.

If that bit was a zero, the Carry Flag will be zero (clear), and it will skip the next line.

If that bit was 1, the Carry Flag will be 1 (set), so it will increase the high byte of the array address (pointerHigh).

.

Your array is 960 bytes large, so this code won't work. Instead, you will need to shift the y value right until it is 0-3, then add that to #4 to get the high byte of the address.

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


Top
 Profile  
 
 Post subject: Re: Count over 255.
PostPosted: Wed Jul 18, 2018 12:26 am 
Offline

Joined: Sat May 26, 2018 6:14 am
Posts: 57
Location: Italy
Ok thanks! I will take my time to study and try your suggests :).


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Nicole and 3 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