It is currently Sat Nov 17, 2018 10:29 pm

 All times are UTC - 7 hours

 Page 1 of 1 [ 11 posts ]
 Print view Previous topic | Next topic
Author Message
 Posted: Thu Oct 19, 2017 12:41 pm

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

 Posted: Thu Oct 19, 2017 12:45 pm

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20777
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

 Posted: Thu Oct 19, 2017 1:30 pm

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

 Posted: Thu Oct 19, 2017 2:00 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10974
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

 Posted: Thu Oct 19, 2017 2:19 pm

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

 Posted: Thu Oct 19, 2017 2:31 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10974
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

 Posted: Thu Oct 19, 2017 2:41 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10974
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!

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

Top

 Posted: Thu Oct 19, 2017 3:00 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10974
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

 Posted: Fri Oct 20, 2017 12:32 am

Joined: Tue Apr 11, 2006 4:08 am
Posts: 276
Location: Poland
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 34 times demo.nes [40.02 KiB] Downloaded 33 times
Top

 Posted: Fri Oct 20, 2017 1:30 am

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1251
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

 Posted: Fri Oct 20, 2017 9:30 am

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

 Attachments: demo8b.nes [40.02 KiB] Downloaded 32 times
Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 11 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: No registered users and 3 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki
Powered by phpBB® Forum Software © phpBB Group