English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. Blitz Basic

 
 
Thread Tools
Old 25 February 2019, 11:56   #1
MickGyver
Registered User
 
MickGyver's Avatar
 
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
MickGyver is offline  
Old 25 February 2019, 13:01   #2
ross
Defendit numerus
 
ross's Avatar
 
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
ross is offline  
Old 25 February 2019, 13:05   #3
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by ross View Post
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
Aah, thanks, this means the time constant in my code only changes depending on PAL/NTSC?
MickGyver is offline  
Old 25 February 2019, 13:16   #4
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,481
Quote:
Originally Posted by MickGyver View Post
Aah, thanks, this means the time constant in my code only changes depending on PAL/NTSC?
Yes.
ross is offline  
Old 25 February 2019, 13:20   #5
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by ross View Post
Yes.
Cheers! I just read that also in another thread, I have corrected the code above.
MickGyver is offline  
Old 06 March 2019, 14:48   #6
carrion
Registered User
 
carrion's Avatar
 
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?
carrion is offline  
Old 08 March 2019, 10:44   #7
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by carrion View Post
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?
As far as I know, there are only two CIA timers available. In order to have more timers, you could read the value of a running timer to start a "virtual" timer, and then read the value of the same timer at the end. Then you would reduce the start time from the end time. There might be better ways, I'm by no means an expert on the subject.

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.
MickGyver is offline  
Old 08 March 2019, 11:57   #8
ross
Defendit numerus
 
ross's Avatar
 
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
ross is offline  
Old 08 March 2019, 12:07   #9
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by ross View Post
I hope this helped you
Cheers!
MickGyver is offline  
Old 09 March 2019, 11:05   #10
carrion
Registered User
 
carrion's Avatar
 
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
carrion is offline  
Old 10 March 2019, 09:56   #11
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by carrion View Post
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.
Incrementing a variable and checking if it has reached a certain value in this case should be very cpu friendly, you only need to do it once per frame. I don't know of a better way to do this. You can do with just one counter if you want to do certain things over a few frames.

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
You can also use MOD (modulo, remainder after integer division) with only one counter variable, but MOD is notoriously slow.

Code:
counter+1
If counter MOD 4 = 0 
  ; Spawn A
EndIf

If counter MOD 4 = 1 
  ; Spawn B
EndIf
A third option is to use bitwise & as a substitute for MOD (can be substituted for powers of two, at least for positive values) according to this formula: x MOD (2 inpower n) == x & (2 inpower n - 1). So x MOD 4 would be the same as x & 3 etc.

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.
MickGyver is offline  
Old 10 March 2019, 13:36   #12
carrion
Registered User
 
carrion's Avatar
 
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.
carrion is offline  
Old 10 March 2019, 15:50   #13
MickGyver
Registered User
 
MickGyver's Avatar
 
Join Date: Oct 2008
Location: Finland
Posts: 643
Quote:
Originally Posted by carrion View Post
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.
You just reset the counter to zero after it has reached a certain value (close to max positive value).
MickGyver is offline  
 


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 19:27.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.12432 seconds with 15 queries