2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
9 #include <asm/mpc5200b.h>
12 #include <aros/asmcall.h>
13 #include <hardware/intbits.h>
14 #include <exec/execbase.h>
17 #include <proto/exec.h>
18 #include <proto/timer.h>
22 uint32_t tbc_expected
;
23 uint32_t tbc_achieved
;
26 volatile slt_t
*slice_timer
;
28 This is a slightly faster version of AddTime() that we use here. It
29 also saves the function call overhead...
31 #define FastAddTime(d, s)\
32 (d)->tv_micro += (s)->tv_micro;\
33 (d)->tv_secs += (s)->tv_secs;\
34 if((d)->tv_micro > 999999) {\
36 (d)->tv_micro -= 1000000;\
39 BOOL
timer_addToWaitList(struct TimerBase
*, struct MinList
*, struct timerequest
*);
41 void SliceHandler(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
)
43 uint32_t startup_time
= mftbl();
45 if (inl(&slice_timer
->slt_ts
) & SLT_TS_ST
)
47 struct timerequest
*tr
, *next
;
49 /* Clear interrupt request. */
50 outl(SLT_TS_ST
, &slice_timer
->slt_ts
);
53 outl(0, &slice_timer
->slt_cf
);
54 // outl(SLT_CF_RUNWAIT | SLT_CF_INTRENA | SLT_CF_ENABLE, &slice_timer->slt_cf);
56 // D(bug("[timer] SliceHandler on %08x%08x slt->cv=%08x\n", (uint32_t)(mftb() >> 32),mftbl(),inl(&slice_timer->slt_cv)));
58 EClockUpdate(TimerBase
);
60 tbc_achieved
= startup_time
;
62 /* Timer errors bigger than approx 15 microseconds shouldn't be taken into account */
63 //if (tbc_achieved > tbc_expected) // && (tbc_achieved - tbc_expected) < 1000)
65 corr
= ((int32_t)(tbc_achieved
- tbc_expected
))-1;
70 Go through the "wait for x seconds" list and return requests
71 that have completed. A completed request is one whose time
72 is less than that of the elapsed time.
74 ForeachNodeSafe(&TimerBase
->tb_Lists
[TL_VBLANK
], tr
, next
)
76 if(CmpTime(&TimerBase
->tb_Elapsed
, &tr
->tr_time
) <= 0)
78 if (tr
== &TimerBase
->tb_vblank_timerequest
)
80 struct IntVector
*iv
= &SysBase
->IntVects
[INTB_VERTB
];
86 AROS_INTC1(iv
->iv_Code
, iv
->iv_Data
);
88 /* Automatically requeue/reactivate request */
90 Remove((struct Node
*)tr
);
91 tr
->tr_node
.io_Command
= TR_ADDREQUEST
;
92 tr
->tr_time
.tv_secs
= 0;
93 tr
->tr_time
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
94 AddTime(&tr
->tr_time
, &TimerBase
->tb_Elapsed
);
96 timer_addToWaitList(TimerBase
, &TimerBase
->tb_Lists
[TL_VBLANK
], tr
);
100 /* This request has finished */
101 Remove((struct Node
*)tr
);
102 tr
->tr_time
.tv_secs
= tr
->tr_time
.tv_micro
= 0;
103 tr
->tr_node
.io_Error
= 0;
104 ReplyMsg((struct Message
*)tr
);
110 The first request hasn't finished, as all requests are in
111 order, we don't bother searching through the remaining
118 The other this is the "wait until a specified time". Here a request
119 is complete if the time we are waiting for is before the current time.
121 ForeachNodeSafe(&TimerBase
->tb_Lists
[TL_WAITVBL
], tr
, next
)
123 if(CmpTime(&TimerBase
->tb_CurrentTime
, &tr
->tr_time
) <= 0)
125 /* This request has finished */
126 Remove((struct Node
*)tr
);
127 tr
->tr_time
.tv_secs
= tr
->tr_time
.tv_micro
= 0;
128 tr
->tr_node
.io_Error
= 0;
129 ReplyMsg((struct Message
*)tr
);
134 The first request hasn't finished, as all requests are in
135 order, we don't bother searching through the remaining
140 TimerSetup(TimerBase
, startup_time
);