The loop which sets various bits at a certain time/frames.
Moderator: Moderators
The loop which sets various bits at a certain time/frames.
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.
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.
Re: The loop which sets various bits at a certain time/frame
For what purpose will you be using the bitset value that this code would produce?
(Or is it a homework assignment?)
(Or is it a homework assignment?)
Re: The loop which sets various bits at a certain time/frame
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 subroutine.
"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.
"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
Re: The loop which sets various bits at a certain time/frame
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.
Re: The loop which sets various bits at a certain time/frame
Thanks, i try it.
I've tried to do something before (using one byte) :
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.
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
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.
Re: The loop which sets various bits at a certain time/frame
Err... You can get a sequence like that (each higher bit is twice slower) with a single instruction: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,...
(...)
Code: Select all
inc bits
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
(...)
Re: The loop which sets various bits at a certain time/frame
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!
EDIT: BTW, you didn't answer tepples' question... What is this for?
EDIT: BTW, you didn't answer tepples' question... What is this for?
Re: The loop which sets various bits at a certain time/frame
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):
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.
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
Re: The loop which sets various bits at a certain time/frame
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.
Re: The loop which sets various bits at a certain time/frame
Why not just use 16bit math? The low byte for every object is a fractional position, the high byte is its pixel position.
Granted you can't get exactly 1 pixel per 3 frames, but I think it's close enough for most practical purposes.
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
Re: The loop which sets various bits at a certain time/frame
ok thanks, everything works just as I wanted.
 Attachments

 demo8b.nes
 (40.02 KiB) Downloaded 157 times