Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > 64tass: arrays, for loop, labels (timer/sync code)
2016-05-14 18:49
Rudi
Account closed

Registered: May 2010
Posts: 125
64tass: arrays, for loop, labels (timer/sync code)

ive developed some macros for a demotimer.
it jumps to specific parts, that is labels.
the two-way jump is of course due to the branch "jumping-length" restrictions.

timer code:
	lda TIME1
	#CmpAccBranchEq #000, j_p00
	#CmpAccBranchEq #011, j_x00
	#CmpAccBranchEq #013, j_p01
	#CmpAccBranchEq #024, j_x00
	#CmpAccBranchEq #026, j_p02
	#CmpAccBranchEq #037, j_x00
	#CmpAccBranchEq #039, j_p03
	#CmpAccBranchEq #050, j_x00
	#CmpAccBranchEq #052, j_p04
	#CmpAccBranchEq #053, j_p05
	#CmpAccBranchEq #054, j_p06
	#CmpAccBranchEq #059, j_p07
etc..
	jmp updatesites

	;jump table
	j_x00: jmp blkpart
	j_p00: jmp part0
	j_p01: jmp part1
	j_p02: jmp part2
	j_p03: jmp part3
	j_p04: jmp part4
	j_p05: jmp part4b
	j_p06: jmp part4c
	j_p07: jmp part4d
	etc..

	jmp sync_time


I wanted to make this shorter, because it looks ugly like this. Im not sure if one can change label-names on compile-time. I wanted to use array-elements for the time-values and label(memory address of the part).
Im in the very early stages of figuring out if any of this is possible.

short explanation of the #CmpAccBranchEq macro:
first operand is a timer-value (compared to a timer)
second operand is a label (part to jump to).
my idea is to make a simple .for loop and have just one CmpAccBranchEq and all the other stuff in an array, if this is indeed possible.
2016-05-15 05:48
Krill

Registered: Apr 2002
Posts: 2980
Yes, it is possible to put label addresses into arrays (.word label, .byte <label and .byte >label), and this is indeed what you should do. The code doesn't seem to be timing-critical, and can be simpler, shorter and more elegant.

And you do not want to check timer values (i.e., frame counts) for equality. Unexpected delays may happen when loading something (or for other reasons), and it's better to perform a larger-than-or-equal check to pick the first matching entry in an ascendingly-sorted list.
2016-05-15 06:30
Oswald

Registered: Apr 2002
Posts: 5094
- 64tass doesnt require : after label name.
- you are overcomplicating it

- this is about as short and clean as the array you want (you have to write out the array similarly like this anyway), but without the for loop.

replace #CmpAccBranchEq, with something more readable for even more clarity. fex #OnFrameGoto

	lda TIME1
	#CmpAccBranchEq #000, blkpart
	#CmpAccBranchEq #011, part0
	#CmpAccBranchEq #013, part1
	#CmpAccBranchEq #024, part2
	#CmpAccBranchEq #026, part3
	#CmpAccBranchEq #037, part4
	#CmpAccBranchEq #039, part4b
	#CmpAccBranchEq #050, part4c
	#CmpAccBranchEq #052, part4d


"And you do not want to check timer values (i.e., frame counts) for equality. "

+1, doing this resulted in some of my demos waiting for an additional 65536 frames. because the timing was too tight and on some machine the loading wasnt fast enought.
2016-05-15 08:14
iAN CooG

Registered: May 2002
Posts: 3193
how about
ldx TIME1
    lda tbll,x
    sta patchjmp+1
    lda tblh,x
    sta patchjmp+2
patchjmp
    jmp $ffff

tbll
    byte <blkpart    ;0
    byte 0,0,0,0,0,0,0,0,0,0 ; 1-10
    byte <part0      ;11
    byte 0           ;12
    byte <part1      ;13
    byte 0
    byte <part2
    byte <part3
    byte <part4
    byte <part4b
    byte <part4c
    byte <part4d
tblh
    byte >blkpart    ;0
    byte 0,0,0,0,0,0,0,0,0,0 ; 1-10
    byte >part0      ;11
    byte 0           ;12
    byte >part1      ;13
    byte 0
    byte >part2
    byte >part3
    byte >part4
    byte >part4b
    byte >part4c
    byte >part4d


just fill the tables with empty values where TIME1 is not used.
2016-05-15 08:33
soci

Registered: Sep 2003
Posts: 480
Put pairs of timings and addresses in a list. Then convert this into 3 byte arrays for time, low and high bytes. A simple routine can take care of calling the next one in case the time has come.
							*=$1000
=$2					time1	= $2

=[0,$1023,10,$1029,20,$102f]		timings	:= [0, part1, 10, part2, 20, part3]
=[0,$1023,10,$1029,20,$102f,30,$1035]	timings	..= [30, part4]

.1000	 a5 02		lda $02		call	lda time1
.1002	 ae 16 10	ldx $1016		ldx index
.1005	 dd 17 10	cmp $1017,x		cmp times,x
.1008	 90 0b		bcc $1015		bcc +		;are we there yet?
.100a	 ee 16 10	inc $1016		inc index	;next
.100d	 bd 1f 10	lda $101f,x		lda highs,x
.1010	 48		pha			pha
.1011	 bd 1b 10	lda $101b,x		lda lows,x
.1014	 48		pha			pha		;jump
.1015	 60		rts		+	rts

>1016	 00				index	.byte 0
>1017	 00 0a 14 1e			times	.byte timings[0::2] ;slice it
>101b	 22 28 2e 34			lows	.byte <(timings[1::2]-1)
>101f	 10 10 10 10			highs	.byte >(timings[1::2]-1)

.1023	 a9 01		lda #$01	part1	lda #1
.1025	 8d 20 d0	sta $d020		sta $d020
.1028	 60		rts			rts
.1029	 a9 02		lda #$02	part2	lda #2
.102b	 8d 20 d0	sta $d020		sta $d020
.102e	 60		rts			rts
.102f	 a9 03		lda #$03	part3	lda #3
.1031	 8d 20 d0	sta $d020		sta $d020
.1034	 60		rts			rts
.1035	 a9 04		lda #$04	part4	lda #4
.1037	 8d 20 d0	sta $d020		sta $d020
.103a	 60		rts			rts
2016-05-15 13:25
Rudi
Account closed

Registered: May 2010
Posts: 125
Thanks for the replies.

Krill: not sure what you mean by frame? the timer is "cycle" dependant (and on every compare the cycle-count is different). doing a bpl instead of beq will cause unexpected behavior (i.e. run all the parts at the same time). i will find out if my code is a silly way of doing things later, but its all that i got right now.

Oswald: if that happens at the very beginning (hence after the loading) and stuff that i dont know about, then i would have to look at it. maybe use a one second delay at the very beginning? or i have missed something.

a frame according to my time-code would be when it jumps back to the beginning of the loop and compares again. and as said above the cycle-count is different every time this happens. its not dependant on the raster.

i need a more detailed explanation of the unexpected delays, because i didnt understand it fully, sorry. like what exactly does the loading have to do with the timer etc.

ian_coog: ahh, why didnt i think of that. i guess patchjmp is the one jump address that needs to be changed on every update.

soci: will have to take a closer look at that code.
2016-05-15 13:47
Oswald

Registered: Apr 2002
Posts: 5094
unexpected delay will happen if you are doing a trackmo because of different drive types, meachnics load at slightly different speed. if your stuff doesnt load between parts then you can use beq. no timing uncertainty then.

frame is used in the meaning of 50fps. typically demos time visual stuff (length of part displayed etc) on a frame basis, using a self coded 16bit frame counter. (inc per retrace) CIA timer is usually used for more critical stuff like cycle exact timing (stable raster) etc.

so misunderstanding is because there are some unspoken rules of demo making here :)
2016-05-15 16:12
Rudi
Account closed

Registered: May 2010
Posts: 125
That was a very good explanation, thank you Oswald. And no, i am not loading between parts actually. my first demo will fit on a .prg or so.

I have a 24-bit counter, because the counter is running quite fast i needed that. My timer is cycle exact, but its not critical for me to know the exact cycles on each part since i use the 24-bit counter for that instead. And the timer is not running per retrace.
2016-05-17 08:04
Krill

Registered: Apr 2002
Posts: 2980
I wonder why you need a 24-bit cycle counter. Usually people count in video frames, then rasterlines, then cycles. That is, one 16-bit frame counter plus a CIA timer counting the 63 cycles within a PAL rasterline. With this setup, you can address any cycle in the demo, and sync to it, easily.

Quoting Rudi
doing a bpl instead of beq will cause unexpected behavior (i.e. run all the parts at the same time)
I didn't propose to check for the sign (which would indeed not be very sensible), but do a >= comparison rather than ==. This means something like
lda seekcyclelo
cmp cyclecountlo
lda seekcyclemid
sbc cyclecountmid
lda seekcyclehi
sbc cyclecounthi
bcs wait
This is also required because you cannot wait for a single cycle with a check for equality, as all operations take at least 2 cycles, and the cycle you want to find may happen anytime during execution of the sync code. Syncing to cycle counters also requires some thought about atomicity. Make sure the 3 bytes of your 24-bit counter are properly latched etc., so you'll always read consistent values (and not have overflows from $00 to $ff after reading the first but before reading the last byte).
2016-05-17 10:24
Skate

Registered: Jul 2003
Posts: 494
I second Krill and Oswald. All you need is a frame counter. When you reach the frame which you need to switch to the next routine, you can still wait for an exact cycle in this frame if this is really mandatory.
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Sychamis
Isildur/Samar
Bitbreaker/Performers
csabanw
Holy Moses/Role
Steffan/BOOM!
AArt1256/MoonShine
rambo/Therapy/ Resou..
E$G/HF ⭐ 7
Didi/Laxity
Linus/MSL
Firelord/Excess
Guests online: 127
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 No Listen  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top NTSC-Fixers
1 Pudwerx  (10)
2 Booze  (9.7)
3 Stormbringer  (9.7)
4 Fungus  (9.6)
5 Grim Reaper  (9.3)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.05 sec.