The loop which sets various bits at a certain time/frames.

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

The loop which sets various bits at a certain time/frames.

Post by sdm » Thu Oct 19, 2017 12:41 pm

I would need a code, which will be set and clear different bits (one byte=eight bits) in different time intervals (frames).

For example:

00000001 - This bit is set every second frame (frame1 = 1(set), frame2 = 0(clear), frame3 = 1,frame4 = 0, etc etc)
00000010 - This bit is set every third frame (frame1 = 1, frame2 = 0, frame3 = 0, frame4 = 1, frame5 = 0, etc etc)
00000100 - every fourth frame (1,0,0,0,1,0,0,0,1,etc etc)
00001000 - every fifth frame (1,0,0,0,0,1,0,0,0,0,1,etc etc)
00010000 - every sixth frame (1,0,0,0,0,0,1,0,0,0,0,0,1,etc etc
00100000 - every seventh frame
01000000 - every eighth
10000000 - every nine

It's very easy to do it with the first bit (every second frame - 0,1,0,1,0,1 etc), because you just need to loop in:

LDA byte
EOR #%00000001
STA byte

Unfortunately I have a problem how to do it with the next bits.

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

Re: The loop which sets various bits at a certain time/frame

Post by tepples » Thu Oct 19, 2017 12:45 pm

For what purpose will you be using the bit-set value that this code would produce?

(Or is it a homework assignment?)

User avatar
dougeff
Posts: 2795
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: The loop which sets various bits at a certain time/frame

Post by dougeff » Thu Oct 19, 2017 1:30 pm

Brute force. Use 8 counter variables, and handle each separately. Increment each every frame, check if equal to frame rate, reset to zero if true, JSR a bit changer sub-routine.

"The proof is trivial, and left as an exercise for the reader" (is a common phrase in books where the author is too lazy to provide a complete answer).

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

User avatar
tokumaru
Posts: 11942
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: The loop which sets various bits at a certain time/frame

Post by tokumaru » Thu Oct 19, 2017 2:00 pm

Untested (ca65 notation):

Code: Select all

counters: .res 8 ;8 bytes in RAM

Code: Select all

limits: ;data table in ROM
	.byte 2, 3, 4, 5, 6, 7, 8, 9

Code: Select all

Initialize:
	ldx #7
	lda #0
@Loop:
	sta counter, x
	dex
	bpl Loop

Code: Select all

Update:
	ldx #7 ;start from the last counter
@Loop:
	lda counters, x ;get the counter
	clc
	adc #1 ;increment it
	cmp limits, x ;check if it hit the limit
	bcc :+ ;skip if not
	lda #0 ;reset the counter
:	sta counters, x ;save the new value
	rol result ;shift 1 or 0 into the result
	dex ;go to the next counter
	bpl Loop ;do another counter if the index is still positive
Last edited by tokumaru on Thu Oct 19, 2017 2:19 pm, edited 1 time in total.

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

Re: The loop which sets various bits at a certain time/frame

Post by sdm » Thu Oct 19, 2017 2:19 pm

Thanks, i try it.


I've tried to do something before (using one byte) :

Code: Select all

TEST:
	LDA bits
	EOR #%00000001
	STA bits

	LDA bits
	AND #%00000001
	BNE n1
	RTS
n1:
	LDA bits
	EOR #%00000010
	STA bits

	LDA bits
	AND #%00000010
	BNE n2
	RTS
n2:
	LDA bits
	EOR #%00000100
	STA bits

	LDA bits
	AND #%00000100
	BNE n3
	RTS
n3:
	LDA bits
	EOR #%00001000
	STA bits

	LDA bits
	AND #%00001000
	BNE n4
	RTS
n4:
	LDA bits
	EOR #%00010000
	STA bits
;(...)
	RTS
Finally the bits are set like this:

bit0=1,0,1,0,1,0,1,0...
bit1=1,1,0,0,1,1,0,0...
bit2=1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0.....
bit3=1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0...
(...)

Generally it would be enough for me (each higher bit is twice slower). But it is not the way I want, that is, I want the bit to be set only once per few frames.

User avatar
tokumaru
Posts: 11942
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: The loop which sets various bits at a certain time/frame

Post by tokumaru » Thu Oct 19, 2017 2:31 pm

sdm wrote:bit / frame
bit0=1,0,1,0,1,0,1...
bit1=1,1,0,0,1,1,0,0...
bit2=1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0.....
bit3=1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,...
(...)
Err... You can get a sequence like that (each higher bit is twice slower) with a single instruction:

Code: Select all

inc bits
Look:

Code: Select all

value $00 $01 $02 $03 $04 $05 $06 $07 (...)
bit 0  0   1   0   1   0   1   0   1
bit 1  0   0   1   1   0   0   1   1
bit 2  0   0   0   0   1   1   1   1
bit 3  0   0   0   0   0   0   0   0
(...)
See?

User avatar
tokumaru
Posts: 11942
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: The loop which sets various bits at a certain time/frame

Post by tokumaru » Thu Oct 19, 2017 2:41 pm

You're using arbitrary update rates here, so I don't think you can calculate the upper bits in function of the lower ones. It's either 8 separate counters or dividing a global counter by the 8 different rates and using the remainders to decide whether to set or clear bits. I'd rather just use 8 counters! :wink:

EDIT: BTW, you didn't answer tepples' question... What is this for?

User avatar
tokumaru
Posts: 11942
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: The loop which sets various bits at a certain time/frame

Post by tokumaru » Thu Oct 19, 2017 3:00 pm

Triple posting! Here's an idea:

If each higher bit being twice as slow is OK, and the only thing you don't want is for bits to remain set for more than one frame, you can try this (needs only 2 variables):

Code: Select all

	lda counter ;get old state
	inc counter ;advance to the next state
	eor #$ff ;invert the old state so that bits that were not set before become 1
	and counter ;and with the new state causing only bits that were clear before but are set now to become 1
	sta bits ;save the result
The trick here is the same used to detect when controller buttons change from not pressed to pressed, it returns 0 for all transitions except 0 -> 1, so you'll only get a 1 when a bit in the counter changes from 0 to 1, if it was already set the result will be 0.

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

Re: The loop which sets various bits at a certain time/frame

Post by sdm » Fri Oct 20, 2017 12:32 am

To this variable (bits) I will refer to when I want to slow down the movement of objects on the screen. Their movement will be dependent on the need to run the given bit (set 1 = on, set 0- =off movement). Something like that.
Attachments
demo2.nes
(40.02 KiB) Downloaded 160 times
demo.nes
(40.02 KiB) Downloaded 157 times

User avatar
Kasumi
Posts: 1292
Joined: Wed Apr 02, 2008 2:09 pm

Re: The loop which sets various bits at a certain time/frame

Post by Kasumi » Fri Oct 20, 2017 1:30 am

Why not just use 16bit math? The low byte for every object is a fractional position, the high byte is its pixel position.

Code: Select all

;moves one pixel every two frames
lda lowbyte
clc
adc #128
sta lowbyte

lda highbyte
adc #0
sta highbyte
;;;
lda highbyte
sta OAMX

Code: Select all

;moves one pixel every three frames (roughly)
lda lowbyte
clc
adc #85
sta lowbyte

lda highbyte
adc #0
sta highbyte
;;;
lda highbyte
sta OAMX
Granted you can't get exactly 1 pixel per 3 frames, but I think it's close enough for most practical purposes.

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

Re: The loop which sets various bits at a certain time/frame

Post by sdm » Fri Oct 20, 2017 9:30 am

ok thanks, everything works just as I wanted.
Attachments
demo8b.nes
(40.02 KiB) Downloaded 157 times

Post Reply