OSDN Git Service

b0c9274e93ec6fc7c40873a4b1f5ba2fd17957e6
[proj16/16.git] / src / v2 / source / ENGINE / TIMER.C
1 /*\r
2 Copyright (C) 1998 BJ Eirich (aka vecna)\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7 This program is distributed in the hope that it will be useful,\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
10 See the GNU General Public Lic\r
11 See the GNU General Public License for more details.\r
12 You should have received a copy of the GNU General Public License\r
13 along with this program; if not, write to the Free Software\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
15 */\r
16 \r
17 #define TIMER_H\r
18 #include <go32.h>\r
19 #include <dpmi.h>\r
20 #include <crt0.h>\r
21 #include "verge.h"\r
22 \r
23 #define PIT0 0x40\r
24 #define PIT1 0x41\r
25 #define PIT2 0x42\r
26 #define PITMODE 0x43\r
27 #define PITCONST 1193180L\r
28 \r
29 #define OCR1    0x20\r
30 #define IMR1    0x21\r
31 \r
32 #define OCR2    0xA0\r
33 #define IMR2    0xA1\r
34 \r
35 // ================================= Data ====================================\r
36 \r
37 int _crt0_startup_flags = _CRT0_FLAG_NEARPTR;\r
38 typedef __dpmi_paddr *PVI;\r
39 static PVI oldhandler;\r
40 \r
41 unsigned int systemtime=0, timer_count=0;\r
42 int (*callback) (void);\r
43 \r
44 // ================================= Code ====================================\r
45 \r
46 PVI DJSetHandlerFunc(unsigned char irqno, void (*handler)(), int len)\r
47 {\r
48   PVI oldvect = (PVI) malloc(sizeof(__dpmi_paddr));\r
49   int vecno=(irqno>7) ? irqno+0x68 : irqno+0x8;\r
50   _go32_dpmi_seginfo wrapper;\r
51   __dpmi_paddr new;\r
52 \r
53   wrapper.pm_offset = (long int) handler;\r
54   wrapper.pm_selector = _my_cs();\r
55   _go32_dpmi_allocate_iret_wrapper(&wrapper);\r
56   new.offset32 = wrapper.pm_offset;\r
57   new.selector = wrapper.pm_selector;\r
58  __dpmi_get_and_disable_virtual_interrupt_state();\r
59  if (len) _go32_dpmi_lock_code(handler,len);\r
60  _go32_dpmi_lock_data(&wrapper,sizeof(_go32_dpmi_seginfo));\r
61  __dpmi_get_protected_mode_interrupt_vector(vecno,oldvect);\r
62  __dpmi_set_protected_mode_interrupt_vector(vecno,&new);\r
63  __dpmi_get_and_enable_virtual_interrupt_state();\r
64  return oldvect;\r
65 }\r
66 \r
67 void DJSetHandlerAddr(unsigned char irqno, PVI handler)\r
68 {\r
69   int vecno=(irqno>7) ? irqno+0x68 : irqno+0x8;\r
70   _go32_dpmi_seginfo wrapper;\r
71   __dpmi_paddr oldhandler;\r
72 \r
73   __dpmi_get_and_disable_virtual_interrupt_state();\r
74   __dpmi_get_protected_mode_interrupt_vector(vecno, &oldhandler);\r
75   wrapper.pm_offset = oldhandler.offset32;\r
76   wrapper.pm_selector = oldhandler.selector;\r
77   _go32_dpmi_free_iret_wrapper(&wrapper);\r
78   __dpmi_set_protected_mode_interrupt_vector(vecno,handler);\r
79   __dpmi_get_and_enable_virtual_interrupt_state();\r
80   free(handler);\r
81 }\r
82 \r
83 static void SendEOI (unsigned char irqno)\r
84 {\r
85   unsigned char ocr=(irqno>7) ? OCR2 : OCR1;\r
86   unsigned char eoi=0x60|(irqno&7);\r
87 \r
88   outportb(ocr,eoi);\r
89   if (irqno>7) outportb(OCR1,0x20);\r
90 }\r
91 \r
92 static void newhandler(void)\r
93 {\r
94   systemtime++;\r
95   timer_count++;\r
96   if (cpu_watch) CPUTick();\r
97   if (callback) callback();\r
98   CheckTileAnimation();\r
99   HookTimer();\r
100   MD_Update();\r
101   SendEOI(0);\r
102 }\r
103 \r
104 static void EndNewHandler() { }\r
105 \r
106 void sethz(unsigned int hz)\r
107 { unsigned int pit0_set, pit0_value;\r
108 \r
109   disable();\r
110 \r
111   outportb(PITMODE, 0x34);\r
112   pit0_value=PITCONST / hz;\r
113   pit0_set=(pit0_value & 0x00ff);\r
114   outportb(PIT0, pit0_set);\r
115   pit0_set=(pit0_value >> 8);\r
116   outportb(PIT0, pit0_set);\r
117 \r
118   enable();\r
119 }\r
120 \r
121 void restorehz()\r
122 {\r
123   disable();\r
124   outportb(PITMODE, 0x34);\r
125   outportb(PIT0, 0x00);\r
126   outportb(PIT0, 0x00);\r
127   enable();\r
128 }\r
129 \r
130 void InitTimer()\r
131 {\r
132    oldhandler = DJSetHandlerFunc(0, (void *) newhandler,\r
133                 ((int) EndNewHandler) - ((int) newhandler));\r
134    sethz(100);\r
135 }\r
136 \r
137 void ShutdownTimer()\r
138 {\r
139   DJSetHandlerAddr(0, oldhandler);\r
140   restorehz();\r
141 }\r