Tested and debugged ToolTypes.
[AROS.git] / rom / kernel / kernel_timer.c
blob15f9b55cd97a901b20efc007dcd80a01a5223079
1 /*
2 * Generic support code for software emulated system timer.
4 * The main idea is: we have a single timer or arbitrary frequence (eclock),
5 * which is used for generating timer interrupts. Its frequency can be higher
6 * than reasonable VBlank frequency, so we emulate VBlank by dividing EClock
7 * frequency by some integer factor.
9 * This code uses two variables in ExecBase, which describe the way in which the machine
10 * measures time:
12 * VBlankFrequency - this is the frequency with which exec VBlank handler is called.
13 * Task scheduler's Quantum is measured in these intervals.
14 * ex_EClockFrequency - this is the machine's master clock frequency. It specifies
15 * how many EClock units is in one second. This value is provided
16 * here to be used by generic software implementation of timer.device,
17 * which simply counts ticks of our system timer. Real hardware
18 * implementations of timer.device are expected to update ex_EClockFrequency
19 * to the unit in which machine's hardware measures time.
21 * On native ports this file will likely be replaced by hardware-probing code.
24 #include <aros/symbolsets.h>
25 #include <exec/execbase.h>
26 #include <hardware/intbits.h>
27 #include <proto/arossupport.h>
28 #include <proto/exec.h>
30 #include <kernel_base.h>
31 #include <kernel_intr.h>
33 #include <stdlib.h>
34 #include <string.h>
36 /* This definition can come from machine-specific files */
37 #ifndef NO_VBLANK_EMU
39 static int Timer_Init(struct KernelBase *KernelBase)
41 char *args;
44 * This will make EClock frequency to be equal to VBlank by default.
45 * Reasonable Amiga(tm)-compatible VBlank is already provided by exec.library.
47 SysBase->ex_EClockFrequency = 0;
50 * Since we are software-driven, we can just ask the user which
51 * frequencies he wishes to use.
53 args = (char *)LibGetTagData(KRN_CmdLine, 0, BootMsg);
54 if (args)
56 char *s;
58 /* Set VBlank and EClock frequencies if specified */
59 s = strstr(args, "vblank=");
60 if (s)
61 SysBase->VBlankFrequency = atoi(&s[7]);
63 s = strstr(args, "eclock=");
64 if (s)
65 SysBase->ex_EClockFrequency = atoi(&s[7]);
68 /* By default we enable VBlank emulation */
69 KernelBase->kb_VBlankEnable = 1;
72 * Calculate number of timer ticks per VBlank and ensure that it is nonzero.
73 * Note that if eclock= argument was not supplied this will set ticks
74 * number to 1 (because ex_EClockFrequency is 0 by default).
76 KernelBase->kb_VBlankTicks = SysBase->ex_EClockFrequency / SysBase->VBlankFrequency;
77 if (!KernelBase->kb_VBlankTicks)
78 KernelBase->kb_VBlankTicks = 1;
81 * Calculate fixed up value of timer frequency. We need to set ex_EClockFrequency
82 * in order to provide correct information to the software.
83 * If timer.device provides better clock, it should update ex_EClockFrequency with
84 * the value which reflects its time granularity.
86 SysBase->ex_EClockFrequency = SysBase->VBlankFrequency * KernelBase->kb_VBlankTicks;
88 return TRUE;
91 ADD2INITLIB(Timer_Init, 0)
93 /* Handle periodic timer and drive exec VBlank */
94 void core_TimerTick()
96 if (KernelBase->kb_VBlankEnable)
98 KernelBase->kb_TimerCount++;
99 if (KernelBase->kb_TimerCount == KernelBase->kb_VBlankTicks)
101 core_Cause(INTB_VERTB, 1L << INTB_VERTB);
102 KernelBase->kb_TimerCount = 0;
107 #endif