comparing values in memory, which change very quickly

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
sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

comparing values in memory, which change very quickly

Post by sdm » Sun Dec 20, 2015 3:08 am

I guess this was already discussed in the forum, but I could not find.
Some time I wonder why comparing values in memory, which change very quickly is problematic.
The Annex is the code that is easier clearly shows what I mean.

I noticed that if faster-moving objects are comparable with the values that it can "miss" comparison.

My guess is that this is due, with a value greater than 1 is changed twice a NMI pause/time, and depending on what the value is in cell SPR2_X is skipped?

For example, giving a 3x INC time in SPR3_X values, the values in the memory cell "go" in the following order: 00,03,06,09 etc and if I make a comparison with the CMP 04 that such a comparison is not possible ??? I do not know if I understand correctly...

We would ask to explain and can describe how to do correctly, such a comparison with objects, whose memory cells are increased more than 1x during the NMI / LOOP.
Attachments
speed.zip
(40.61 KiB) Downloaded 155 times

User avatar
Memblers
Site Admin
Posts: 3890
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: comparing values in memory, which change very quickly

Post by Memblers » Sun Dec 20, 2015 3:41 am

Instead of CMP / BNE, you should use CMP / BCS for branch if greater than. Or in other cases, BCC for branch if less than. I've noticed that some assemblers use the aliases BLT and BGT for those instructions. For myself, I just remember which is which by thinking "S is greater than C". CMP works just like the SBC instruction but without modifying the accumulator, so as you can see now, it also affects the carry flag in the same way. Unlike SBC, I'm pretty sure it doesn't use the carry flag as part of the subtract operation though.

I like the games you've been posting, pretty cool stuff.

I know this demo doesn't, but in your games have you been using 8-bit values for the speed and sprite position, or have you tried using fixed-point fractional speeds yet? I noticed different things in the games moved at the same speeds, I didn't actually look at the code to see if that was by design or not. But using something like 8.8 fixed-point allows for much more variety. The sprite's position can be 16 bits, but only the upper 8 bits are written to OAM. For example, then you can add a value like $0180 every frame, to get 1.5 pixel per frame movement.

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: comparing values in memory, which change very quickly

Post by sdm » Sun Dec 20, 2015 3:53 am

Math is a tough thing for me, so assembly programming is a huge challenge. But slowly, slowly, a little bit better I understand it. :)

User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: comparing values in memory, which change very quickly

Post by Movax12 » Sun Dec 20, 2015 7:48 am

Memblers wrote:For myself, I just remember which is which by thinking "S is greater than C". CMP works just like the SBC instruction but without modifying the accumulator, so as you can see now, it also affects the carry flag in the same way. Unlike SBC, I'm pretty sure it doesn't use the carry flag as part of the subtract operation though.
CMP is just like a SEC / SBC without storing the result in the accumulator (other than cycle count). I always remember BCC is "less" by thinking that 'C' can also make an 'S' sound.. BCC, BSS, LBSS, LESS. BCS has two different letters and compares two different things: greater and equal.

tepples
Posts: 22160
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: comparing values in memory, which change very quickly

Post by tepples » Sun Dec 20, 2015 7:51 am

WDC had official synonyms for BCC and BCS in all its 65816 docs: BLT (branch less than) and BGE (branch greater or equal). In ca65, .MACPACK generic enables these as macros.

User avatar
Memblers
Site Admin
Posts: 3890
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: comparing values in memory, which change very quickly

Post by Memblers » Sun Dec 20, 2015 11:49 pm

Thanks for pointing that out, yeah BGE is what I was remembering wrong, the fact that equal is included in that compare is important.
sdm wrote:Math is a tough thing for me, so assembly programming is a huge challenge. But slowly, slowly, a little bit better I understand it. :)
Same for me with math, so I understand that struggle. I remember finding out that fixed-point math was simple in practice was a big eye-opener for me, so I tend to bring it up whenever I see the chance. Some of my older programs were doing terrible, ugly things to try and get speed variations.

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: comparing values in memory, which change very quickly

Post by sdm » Wed May 18, 2016 1:04 am

I'm going back, I stop, I go back over and over :)
After a break in the coding back to the forgotten problem.

I noticed that just any increase / decrease the value of the item object is driven separately to check:

My guess is that the method is ok, well, maybe the speed of code (it takes a lot of CPU time)?

Code: Select all

SPR3_loop:

	LDA SPR3_S
	AND #%00000100
	BNE SPR3_loop_Left

	LDA SPR3_X
	CMP #$E8
	beq SPR3_loop_chngDir

	INC SPR3_X
	INC SPR3_X
	INC SPR3_X

	RTS
 
SPR3_loop_Left:

	LDA SPR3_X
	CMP #$10
	BEQ SPR3_loop_chngDir

	DEC SPR3_X
	DEC SPR3_X
	DEC SPR3_X
 
	RTS

SPR3_loop_chngDir:
	
	JSR SND3
	LDA SPR3_S
	EOR #%01000100
	STA SPR3_S

SPR3_loop_end:

	RTS
i change to:

Code: Select all

SPR3_loop:

	LDA SPR3_S
	AND #%00000100
	BNE SPR3_loop_Left

	LDA SPR3_X
	CMP #$E8
	beq SPR3_loop_chngDir

	INC SPR3_X

	LDA SPR3_X
	CMP #$E8
	beq SPR3_loop_chngDir

	INC SPR3_X

	LDA SPR3_X
	CMP #$E8
	beq SPR3_loop_chngDir

	INC SPR3_X

	RTS
 
SPR3_loop_Left:

	LDA SPR3_X
	CMP #$10
	BEQ SPR3_loop_chngDir

	DEC SPR3_X

	LDA SPR3_X
	CMP #$10
	BEQ SPR3_loop_chngDir

	DEC SPR3_X

	LDA SPR3_X
	CMP #$10
	BEQ SPR3_loop_chngDir

	DEC SPR3_X
 
	RTS

SPR3_loop_chngDir:
	
	JSR SND3
	LDA SPR3_S
	EOR #%01000100
	STA SPR3_S

SPR3_loop_end:

	RTS
Attachments
speed2.zip
(40.49 KiB) Downloaded 137 times

User avatar
pubby
Posts: 557
Joined: Thu Mar 31, 2016 11:15 am

Re: comparing values in memory, which change very quickly

Post by pubby » Wed May 18, 2016 1:37 am

This is how you would do it using BCS/BCC:

Code: Select all

    lda spr3_x
    clc
    adc #3
    cmp #$E8
    bcc lessThanE8
    jsr SPR3_loop_chngDir
    lda #$E8
lessThanE8:
    sta spr3_x
Consider using variables for the speed. This would allow you to use reuse the same subroutine(s) for all 3 sprites:

Code: Select all

spr_loop:
    lda spr_x
    clc
    adc spr_xspeed  ; use a variable instead of #3
    cmp #$E8
    bcc lessThanE8
    jsr reverse_direction
    lda #$E8
lessThanE8:
    cmp #$10
    bcs greaterThan10
    jsr reverse_direction
    lda #$10
greaterThan10:
    sta spr_x
    rts

reverse_direction:
    ; This subroutine multiplies spr_xspeed by #-1
    lda #0
    sec
    sbc spr_xspeed
    sta spr_xspeed
    rts
The code above handles both directions.

Post Reply