It is currently Fri Nov 17, 2017 7:58 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Thu Oct 19, 2017 12:41 pm 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 248
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.


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 12:45 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19221
Location: NE Indiana, USA (NTSC)
For what purpose will you be using the bit-set value that this code would produce?

(Or is it a homework assignment?)


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 1:30 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1823
Location: DIGDUG
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


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 2:00 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
Untested (ca65 notation):

Code:
counters: .res 8 ;8 bytes in RAM


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


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


Code:
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.

Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 2:19 pm 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 248
Thanks, i try it.


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


Code:
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.


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 2:31 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
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:
inc bits

Look:

Code:
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?


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 2:41 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
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?


Top
 Profile  
 
PostPosted: Thu Oct 19, 2017 3:00 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
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:
   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.


Top
 Profile  
 
PostPosted: Fri Oct 20, 2017 12:32 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 248
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 8 times
demo.nes [40.02 KiB]
Downloaded 7 times
Top
 Profile  
 
PostPosted: Fri Oct 20, 2017 1:30 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1035
Why not just use 16bit math? The low byte for every object is a fractional position, the high byte is its pixel position.
Code:
;moves one pixel every two frames
lda lowbyte
clc
adc #128
sta lowbyte

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

Code:
;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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Fri Oct 20, 2017 9:30 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 248
ok thanks, everything works just as I wanted.


Attachments:
demo8b.nes [40.02 KiB]
Downloaded 6 times
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 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