revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-mingw32 / timer / timer_init.c
blobabe7b7a2f81487e65bcd02b269af693092019a4b
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * Windows-hosted timer driver.
9 * In Windows kernel we have two statically allocated timers.
10 * Timer 0 is used by kernel for VBlank interrupts, timer 1 is our one.
12 * Our VBlank unit is driven by exec interrupt.
14 * TODO: Rewrite this implementation to use variable time intervals.
17 #include <aros/bootloader.h>
18 #include <aros/debug.h>
19 #include <aros/symbolsets.h>
20 #include <exec/execbase.h>
21 #include <exec/interrupts.h>
22 #include <hardware/intbits.h>
23 #include <proto/arossupport.h>
24 #include <proto/bootloader.h>
25 #include <proto/exec.h>
26 #include <proto/hostlib.h>
27 #include <proto/kernel.h>
29 #include "timer_intern.h"
30 #include "timer_macros.h"
31 #include "timervblank.h"
33 #include <stdlib.h>
34 #include <string.h>
36 /* Timer 1 (EClock) interrupt handler */
37 static void TimerTick(struct TimerBase *TimerBase, struct ExecBase *SysBase)
39 /* Increment EClock value and process microhz requests */
40 ADDTIME(&TimerBase->tb_CurrentTime, &TimerBase->tb_Platform.tb_VBlankTime);
41 ADDTIME(&TimerBase->tb_Elapsed, &TimerBase->tb_Platform.tb_VBlankTime);
42 TimerBase->tb_ticks_total++;
44 handleMicroHZ(TimerBase, SysBase);
47 /****************************************************************************************/
49 #define KernelBase TimerBase->tb_KernelBase
51 static int Timer_Init(struct TimerBase *TimerBase)
53 APTR BootLoaderBase;
54 int ret;
56 HostLibBase = OpenResource("hostlib.resource");
57 if (!HostLibBase)
58 return FALSE;
60 TimerBase->tb_Platform.kernelHandle = HostLib_Open("Libs\\Host\\kernel.dll", NULL);
61 if (!TimerBase->tb_Platform.kernelHandle)
62 return FALSE;
64 TimerBase->tb_Platform.StartClock = HostLib_GetPointer(TimerBase->tb_Platform.kernelHandle, "StartClock", NULL);
65 if (!TimerBase->tb_Platform.StartClock)
66 return FALSE;
68 /* Install timer IRQ handler */
69 TimerBase->tb_TimerIRQHandle = KrnAddIRQHandler(1, TimerTick, TimerBase, SysBase);
70 if (!TimerBase->tb_TimerIRQHandle)
71 return FALSE;
73 /* Set up VBlank handler */
74 vblank_Init(TimerBase);
76 /* By default we want 100 Hz EClock */
77 TimerBase->tb_eclock_rate = 100;
80 * Since we are software-driven, we can just ask the user which
81 * frequencies he wishes to use.
83 BootLoaderBase = OpenResource("bootloader.resource");
84 if (BootLoaderBase)
86 struct List *args = GetBootInfo(BL_Args);
88 if (args)
90 struct Node *node;
92 for (node = args->lh_Head; node->ln_Succ; node = node->ln_Succ)
94 if (strncasecmp(node->ln_Name, "eclock=", 7) == 0)
96 TimerBase->tb_eclock_rate = atoi(&node->ln_Name[7]);
97 break;
103 /* Set ExecBase public field. */
104 SysBase->ex_EClockFrequency = TimerBase->tb_eclock_rate;
105 D(bug("[Timer_Init] Timer frequency is %d\n", TimerBase->tb_eclock_rate));
107 /* Calculate timer period in us */
108 TimerBase->tb_Platform.tb_VBlankTime.tv_secs = 0;
109 TimerBase->tb_Platform.tb_VBlankTime.tv_micro = 1000000 / TimerBase->tb_eclock_rate;
111 /* Start up timer 1 */
112 Forbid();
113 ret = TimerBase->tb_Platform.StartClock(1, TimerBase->tb_eclock_rate);
114 Permit();
116 D(bug("[Timer_Init] StartClock() returned %d\n", ret));
117 return ret;
120 static int Timer_Expunge(struct TimerBase *TimerBase)
122 if (!HostLibBase)
123 return TRUE;
125 if (TimerBase->tb_TimerIRQHandle)
126 KrnRemIRQHandler(TimerBase->tb_TimerIRQHandle);
128 if (TimerBase->tb_Platform.kernelHandle)
129 HostLib_Close(TimerBase->tb_Platform.kernelHandle, NULL);
131 return TRUE;
134 ADD2INITLIB(Timer_Init, 0)
135 ADD2EXPUNGELIB(Timer_Expunge, 0)