added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / x86_64-pc / timer / timer_init.c
blob391aff3e712ffdc33189131a3adfcf3d686f9042
1 /*
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
6 */
8 /****************************************************************************************/
10 #include <exec/types.h>
11 #include <exec/io.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>
26 #include <asm/io.h>
28 #include <aros/debug.h>
29 #undef kprintf
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)
40 );*/
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 */
72 outb(0x00, 0x42);
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);
87 /* VBlank EMU */
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);
97 return TRUE;
100 /****************************************************************************************/
102 static int GM_UNIQUENAME(Open)
104 LIBBASETYPEPTR LIBBASE,
105 struct timerequest *tr,
106 ULONG unitNum,
107 ULONG flags
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
116 this.
118 This fixes bug SF# 741580
121 switch(unitNum)
123 case UNIT_VBLANK:
124 case UNIT_WAITUNTIL:
125 case UNIT_MICROHZ:
126 case UNIT_ECLOCK:
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;
131 break;
133 default:
134 tr->tr_node.io_Error = IOERR_OPENFAIL;
137 return TRUE;
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);
146 return TRUE;
149 /****************************************************************************************/
151 ADD2INITLIB(GM_UNIQUENAME(Init), 0)
152 ADD2OPENDEV(GM_UNIQUENAME(Open), 0)
153 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge), 0)