2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id: timer_init.c 26645 2007-09-15 20:24:05Z schulz $
5 Desc: Timer startup and device commands
8 /****************************************************************************************/
10 #include <exec/types.h>
12 #include <exec/errors.h>
13 #include <exec/devices.h>
14 #include <exec/alerts.h>
15 #include <exec/initializers.h>
16 #include <devices/timer.h>
17 #include <hidd/timer.h>
18 #include <hardware/intbits.h>
20 #include <proto/exec.h>
21 #include <proto/timer.h>
22 #include <proto/kernel.h>
24 #include <aros/symbolsets.h>
28 #include <aros/debug.h>
30 #include <proto/arossupport.h>
32 //#include "timer_intern.h"
33 #include LC_LIBDEFS_FILE
35 /*AROS_UFP4(ULONG, VBlankInt,
36 AROS_UFPA(ULONG, dummy, A0),
37 AROS_UFPA(struct TimerBase *, TimerBase, A1),
38 AROS_UFPA(ULONG, dummy2, A5),
39 AROS_UFPA(struct ExecBase *, SysBase, A6)
41 void VBlankInt(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
);
43 /****************************************************************************************/
45 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
47 void *KernelBase
= TLS_GET(KernelBase
);
48 /* Setup the timer.device data */
49 LIBBASE
->tb_CurrentTime
.tv_secs
= 0;
50 LIBBASE
->tb_CurrentTime
.tv_micro
= 0;
51 LIBBASE
->tb_VBlankTime
.tv_secs
= 0;
52 LIBBASE
->tb_VBlankTime
.tv_micro
= 1000000 / (SysBase
->VBlankFrequency
* SysBase
->PowerSupplyFrequency
);
53 LIBBASE
->tb_Elapsed
.tv_secs
= 0;
54 LIBBASE
->tb_Elapsed
.tv_micro
= 0;
56 D(kprintf("Timer period: %ld secs, %ld micros\n",
57 LIBBASE
->tb_VBlankTime
.tv_secs
, LIBBASE
->tb_VBlankTime
.tv_micro
));
59 LIBBASE
->tb_MiscFlags
= TF_GO
;
61 /* Initialise the lists */
62 NEWLIST( &LIBBASE
->tb_Lists
[0] );
63 NEWLIST( &LIBBASE
->tb_Lists
[1] );
64 NEWLIST( &LIBBASE
->tb_Lists
[2] );
65 NEWLIST( &LIBBASE
->tb_Lists
[3] );
66 NEWLIST( &LIBBASE
->tb_Lists
[4] );
68 /* Start the timer2 */
69 outb((inb(0x61) & 0xfd) | 1, 0x61); /* Enable the timer (set GATE on) */
70 outb(0xb4, 0x43); /* Binary mode on Timer2, count mode 2 */
71 outb(0x00, 0x42); /* We're counting whole range */
74 LIBBASE
->tb_prev_tick
= 0xffff;
76 /* Start up the interrupt server. This is shared between us and the
77 HIDD that deals with the vblank */
78 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Pri
= 0;
79 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
80 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Name
= (STRPTR
)MOD_NAME_STRING
;
81 LIBBASE
->tb_VBlankInt
.is_Code
= (APTR
)&VBlankInt
;
82 LIBBASE
->tb_VBlankInt
.is_Data
= LIBBASE
;
84 // AddIntServer(INTB_TIMERTICK, &LIBBASE->tb_VBlankInt);
85 KrnAddIRQHandler(0x20, VBlankInt
, LIBBASE
, SysBase
);
89 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Command
= TR_ADDREQUEST
;
90 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Device
= (struct Device
*)TimerBase
;
91 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Unit
= (struct Unit
*)UNIT_MICROHZ
;
92 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_secs
= 0;
93 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
95 SendIO(&LIBBASE
->tb_vblank_timerequest
.tr_node
);
100 /****************************************************************************************/
102 static int GM_UNIQUENAME(Open
)
104 LIBBASETYPEPTR LIBBASE
,
105 struct timerequest
*tr
,
110 outb((inb(0x61) & 0xfd) | 1, 0x61); /* Enable the timer (set GATE on) */
113 Normally, we should check the length of the message and other
114 such things, however the RKM documents an example where the
115 length of the timerrequest isn't set, so we must not check
118 This fixes bug SF# 741580
127 case UNIT_WAITECLOCK
:
128 tr
->tr_node
.io_Error
= 0;
129 tr
->tr_node
.io_Unit
= (struct Unit
*)unitNum
;
130 tr
->tr_node
.io_Device
= (struct Device
*)LIBBASE
;
134 tr
->tr_node
.io_Error
= IOERR_OPENFAIL
;
140 /****************************************************************************************/
142 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
)
144 outb((inb(0x61) & 0xfd) | 1, 0x61); /* Enable the timer (set GATE on) */
145 RemIntServer(INTB_VERTB
, &LIBBASE
->tb_VBlankInt
);
149 /****************************************************************************************/
151 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
152 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
153 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)