25 February 2019, 11:56 | #1 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
Timing code using a CIA timer
I implemented a code timing snippet from this thread in Blitz Basic 2. It uses a CIA timer. To time a certain piece of code, you just call the StartTimer{} before the code you want to time, and then you call EndTimer{} after the code. Multiply the result of EndTimer{} with a time constant (explained in the code) to get the execution time in microseconds (µs). As a reference, one frame when running at 50fps spans about 20ms (20000µs).
You can't time code that takes longer than 92ms (milliseconds) to execute. There is a small overhead with calling the timer itself, but the result will be consistent nonetheless. There might exist something similar already in BB2 but I wanted to see if porting the assembly code would work. Code:
StartTimer{} ; The code you want to time go here time.q=EndTimer{}*time_constant Code:
; The two 16 bit timers on the 8520 chips each count down at 1/10 ; the CPU clock of a PAL A500 (~7MHz), more precisely .709379. That works out to 1.409684 ; microseconds per count (1/.709379) Under NTSC the countdown is slightly ; faster, .715909 Mhz. Faster Amigas use the same granularity for compatibility. ; Values for time_constant: ; ---------------------------- ; System Value ; PAL 1.410 ; NTSC 1.397 time_constant.q=1.410 ; Call this function to start the timer Statement StartTimer{} lea $bfd000,a0 moveq #-1,d0 move.b d0,$400(a0) move.b d0,$500(a0) move.b #%00011001,$e00(a0) ; force load, one-shot mode, start timer AsmExit End Statement ; Call this function to stop the timer ; The return value will be number of countdowns (each 1/10 CPU clock) ; Multiply this value with the 'time_constant' variable to get microseconds Function.w EndTimer{} lea $bfd000,a0 move.b #$00,$e00(a0) move.b $500(a0),d1 move.b $400(a0),d2 moveq #-1,d0 lsl.w #8,d1 move.b d2,d1 sub.w d1,d0 AsmExit End Function Last edited by MickGyver; 25 February 2019 at 14:17. Reason: Corrected the code according to the comment by ross |
25 February 2019, 13:01 | #2 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,481
|
Hi MickGyver, only a little correction.
On A1200 the CIA timer granularity is the same as A500. And is valid for any existing Amiga with CIAs on the motherboard |
25 February 2019, 13:05 | #3 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
|
25 February 2019, 13:16 | #4 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,481
|
|
25 February 2019, 13:20 | #5 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
|
06 March 2019, 14:48 | #6 |
Registered User
Join Date: Dec 2016
Location: Warsaw area
Posts: 153
|
this is really interesting in regard to a small project I work on right now.
Can I start few (sat 3-5) different timers/ counters with this routine? |
08 March 2019, 10:44 | #7 | |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
Quote:
EDIT1: If you don't super accurate timing you could also use VPos + VBL with the method I described (read values at start and end). One vertical blank is is 313 rasterlines for PAL, so the time for one rasterline (VPos oncreased by one) is (PAL) 1000000µs / 50fps = 20000µs. 20000µs / 313 ~ 63.9µs. For every frame you would add 20000µs to the timer. EDIT2: Use 20,0319ms instead of 20,000 for one frame like @ross explained below, with that, one rasterline "tick" is 63,9996us. Last edited by MickGyver; 08 March 2019 at 12:06. |
|
08 March 2019, 11:57 | #8 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,481
|
Some clarifications.
The timers within each CIA are 3. Some are normally used by the system so, if you do not take over the machine, you have to request for it politely. Timer A and B in each CIAs have the frequencies specified in previous messages. Timers can also be chained to make a longer delay (a underflow in TimerA can be used as a counter for TimerB). Every CIA contain also a TOD counter (the third timer). CIAA TOD counter is bond to V-Sync or PowerLine (depend on machine) so can be ~ 50 or 60 HZ CIAB TOD counter is bond to H-Sync. Anyway both V-Sync / H-Sync depends on a single master factor, that is the key in Amiga architecture: the CCK frequency that governs internal bus accesses and all timings (3546895 Hz on PAL and 3579545 on NTSC). Back to your example for H and V frequencies. In a standard 50Hz non interlaced PAL frame you have 227 CCKs/line and 313 lines. This gives you a tick of 1/3546895*227=63,9996us for CIAB-TOD and 63,9996*313=20,0319ms for CIAA-TOD. I hope this helped you |
08 March 2019, 12:07 | #9 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
|
09 March 2019, 11:05 | #10 |
Registered User
Join Date: Dec 2016
Location: Warsaw area
Posts: 153
|
MickGyver
Thanks for replies. Seam that it won't solve my problem. But maybe you could help me then. What I want to achieve is something like this: I want to: 1. spawn some objects of type A every second frame 2. spawn obj of type B every third frame 3. type every 4th frame for issue #1 I do normal differences like for double buffer counting: db = 1-db now I can figure out similar approach for #2 and #3. and I want to avoid simple db+1 and then additional if's. That woun't be nice IMO, but if there's no solution I'll have to do normal increment and ifs / thens. BTW: I use interrupt 5 by now to do the counting. so for varian 1 I do normal stuff as for |
10 March 2019, 09:56 | #11 | |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
Quote:
Code:
Select counter Case 0 ; Spawn A Case 1 ; Spawn B Case 3 ; Type Case 4 ; Do something else End Select counter+1 If counter>4 Then counter=0 Code:
counter+1 If counter MOD 4 = 0 ; Spawn A EndIf If counter MOD 4 = 1 ; Spawn B EndIf Code:
counter+1 If counter & 3 = 0 ; Same as counter MOD 4 = 0 ; Spawn A EndIf If counter & 3 = 1 ; Same as counter MOD 4 = 1 ; Spawn B EndIf Last edited by MickGyver; 10 March 2019 at 10:24. |
|
10 March 2019, 13:36 | #12 |
Registered User
Join Date: Dec 2016
Location: Warsaw area
Posts: 153
|
I haven't thought about "&" and Modulo.
My only concern is when "counter" overflows. I'm not sure how it will behave especially for the case like "counter MOD 3" but hey - thanks for a great hint. |
10 March 2019, 15:50 | #13 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
You just reset the counter to zero after it has reached a certain value (close to max positive value).
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Possible code bug/ inconsistency in cia.cpp? | rsn8887 | support.WinUAE | 2 | 22 April 2018 20:10 |
AHX CIA timing in Blitz2 | Anakirob | Coders. Language | 2 | 17 December 2017 10:21 |
example of a CIA timer interrupt in assembler using cia.resource | Apollo | Coders. Asm / Hardware | 3 | 05 July 2013 08:40 |
[WinUAE/A500] CIA A - Timer A INT2 problem | leoha | Coders. Asm / Hardware | 2 | 22 October 2012 10:18 |
CIA timer interrupt handler called twice during mod playback | absence | Coders. General | 5 | 16 March 2009 18:55 |
|
|