rayzor
diff src/timer.c @ 1:a826bf0fb169
fixed line endings
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 05 Apr 2014 09:05:26 +0300 |
parents | 2a5340a6eee4 |
children | 5380ff64e83f |
line diff
1.1 --- a/src/timer.c Sat Apr 05 08:46:27 2014 +0300 1.2 +++ b/src/timer.c Sat Apr 05 09:05:26 2014 +0300 1.3 @@ -1,131 +1,131 @@ 1.4 -/* 1.5 -256-color 3D graphics hack for real-mode DOS. 1.6 -Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 - 1.8 -This program is free software: you can redistribute it and/or modify 1.9 -it under the terms of the GNU General Public License as published by 1.10 -the Free Software Foundation, either version 3 of the License, or 1.11 -(at your option) any later version. 1.12 - 1.13 -This program is distributed in the hope that it will be useful, 1.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 -GNU General Public License for more details. 1.17 - 1.18 -You should have received a copy of the GNU General Public License 1.19 -along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 -*/ 1.21 -#include <stdio.h> 1.22 -#include <stdlib.h> 1.23 -#include <conio.h> 1.24 -#include <dos.h> 1.25 -#include <i86.h> 1.26 -#include "pit8254.h" 1.27 - 1.28 -#define PIT_TIMER_INTR 8 1.29 -#define DOS_TIMER_INTR 0x1c 1.30 - 1.31 -/* macro to divide and round to the nearest integer */ 1.32 -#define DIV_ROUND(a, b) \ 1.33 - ((a) / (b) + ((a) % (b)) / ((b) / 2)) 1.34 - 1.35 -static void set_timer_reload(int reload_val); 1.36 -static void cleanup(void); 1.37 -static void __interrupt __far timer_irq(); 1.38 -static void __interrupt __far dos_timer_intr(); 1.39 - 1.40 -static void (__interrupt __far *prev_timer_intr)(); 1.41 - 1.42 -static unsigned long ticks; 1.43 -static unsigned long tick_interval, ticks_per_dos_intr; 1.44 -static int inum; 1.45 - 1.46 -void init_timer(int res_hz) 1.47 -{ 1.48 - _disable(); 1.49 - 1.50 - if(res_hz > 0) { 1.51 - int reload_val = DIV_ROUND(OSC_FREQ_HZ, res_hz); 1.52 - set_timer_reload(reload_val); 1.53 - 1.54 - tick_interval = DIV_ROUND(1000, res_hz); 1.55 - ticks_per_dos_intr = DIV_ROUND(65535L, reload_val); 1.56 - 1.57 - inum = PIT_TIMER_INTR; 1.58 - prev_timer_intr = _dos_getvect(inum); 1.59 - _dos_setvect(inum, timer_irq); 1.60 - } else { 1.61 - tick_interval = 55; 1.62 - 1.63 - inum = DOS_TIMER_INTR; 1.64 - prev_timer_intr = _dos_getvect(inum); 1.65 - _dos_setvect(inum, dos_timer_intr); 1.66 - } 1.67 - _enable(); 1.68 - 1.69 - atexit(cleanup); 1.70 -} 1.71 - 1.72 -static void cleanup(void) 1.73 -{ 1.74 - if(!prev_timer_intr) { 1.75 - return; /* init hasn't ran, there's nothing to cleanup */ 1.76 - } 1.77 - 1.78 - _disable(); 1.79 - if(inum == PIT_TIMER_INTR) { 1.80 - /* restore the original timer frequency */ 1.81 - set_timer_reload(65535); 1.82 - } 1.83 - 1.84 - /* restore the original interrupt handler */ 1.85 - _dos_setvect(inum, prev_timer_intr); 1.86 - _enable(); 1.87 -} 1.88 - 1.89 -void reset_timer(void) 1.90 -{ 1.91 - ticks = 0; 1.92 -} 1.93 - 1.94 -unsigned long get_msec(void) 1.95 -{ 1.96 - return ticks * tick_interval; 1.97 -} 1.98 - 1.99 -static void set_timer_reload(int reload_val) 1.100 -{ 1.101 - outp(PORT_CMD, CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE); 1.102 - outp(PORT_DATA0, reload_val & 0xff); 1.103 - outp(PORT_DATA0, (reload_val >> 8) & 0xff); 1.104 -} 1.105 - 1.106 -static void __interrupt __far dos_timer_intr() 1.107 -{ 1.108 - ticks++; 1.109 - _chain_intr(prev_timer_intr); /* DOES NOT RETURN */ 1.110 -} 1.111 - 1.112 -/* first PIC command port */ 1.113 -#define PIC1_CMD 0x20 1.114 -/* end of interrupt control word */ 1.115 -#define OCW2_EOI (1 << 5) 1.116 - 1.117 -static void __interrupt __far timer_irq() 1.118 -{ 1.119 - static unsigned long dos_ticks; 1.120 - 1.121 - ticks++; 1.122 - 1.123 - if(++dos_ticks >= ticks_per_dos_intr) { 1.124 - /* I suppose the dos irq handler does the EOI so I shouldn't 1.125 - * do it if I am to call the previous function 1.126 - */ 1.127 - dos_ticks = 0; 1.128 - _chain_intr(prev_timer_intr); /* XXX DOES NOT RETURN */ 1.129 - return; /* just for clarity */ 1.130 - } 1.131 - 1.132 - /* send EOI to the PIC */ 1.133 - outp(PIC1_CMD, OCW2_EOI); 1.134 -} 1.135 +/* 1.136 +256-color 3D graphics hack for real-mode DOS. 1.137 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.138 + 1.139 +This program is free software: you can redistribute it and/or modify 1.140 +it under the terms of the GNU General Public License as published by 1.141 +the Free Software Foundation, either version 3 of the License, or 1.142 +(at your option) any later version. 1.143 + 1.144 +This program is distributed in the hope that it will be useful, 1.145 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.146 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.147 +GNU General Public License for more details. 1.148 + 1.149 +You should have received a copy of the GNU General Public License 1.150 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.151 +*/ 1.152 +#include <stdio.h> 1.153 +#include <stdlib.h> 1.154 +#include <conio.h> 1.155 +#include <dos.h> 1.156 +#include <i86.h> 1.157 +#include "pit8254.h" 1.158 + 1.159 +#define PIT_TIMER_INTR 8 1.160 +#define DOS_TIMER_INTR 0x1c 1.161 + 1.162 +/* macro to divide and round to the nearest integer */ 1.163 +#define DIV_ROUND(a, b) \ 1.164 + ((a) / (b) + ((a) % (b)) / ((b) / 2)) 1.165 + 1.166 +static void set_timer_reload(int reload_val); 1.167 +static void cleanup(void); 1.168 +static void __interrupt __far timer_irq(); 1.169 +static void __interrupt __far dos_timer_intr(); 1.170 + 1.171 +static void (__interrupt __far *prev_timer_intr)(); 1.172 + 1.173 +static unsigned long ticks; 1.174 +static unsigned long tick_interval, ticks_per_dos_intr; 1.175 +static int inum; 1.176 + 1.177 +void init_timer(int res_hz) 1.178 +{ 1.179 + _disable(); 1.180 + 1.181 + if(res_hz > 0) { 1.182 + int reload_val = DIV_ROUND(OSC_FREQ_HZ, res_hz); 1.183 + set_timer_reload(reload_val); 1.184 + 1.185 + tick_interval = DIV_ROUND(1000, res_hz); 1.186 + ticks_per_dos_intr = DIV_ROUND(65535L, reload_val); 1.187 + 1.188 + inum = PIT_TIMER_INTR; 1.189 + prev_timer_intr = _dos_getvect(inum); 1.190 + _dos_setvect(inum, timer_irq); 1.191 + } else { 1.192 + tick_interval = 55; 1.193 + 1.194 + inum = DOS_TIMER_INTR; 1.195 + prev_timer_intr = _dos_getvect(inum); 1.196 + _dos_setvect(inum, dos_timer_intr); 1.197 + } 1.198 + _enable(); 1.199 + 1.200 + atexit(cleanup); 1.201 +} 1.202 + 1.203 +static void cleanup(void) 1.204 +{ 1.205 + if(!prev_timer_intr) { 1.206 + return; /* init hasn't ran, there's nothing to cleanup */ 1.207 + } 1.208 + 1.209 + _disable(); 1.210 + if(inum == PIT_TIMER_INTR) { 1.211 + /* restore the original timer frequency */ 1.212 + set_timer_reload(65535); 1.213 + } 1.214 + 1.215 + /* restore the original interrupt handler */ 1.216 + _dos_setvect(inum, prev_timer_intr); 1.217 + _enable(); 1.218 +} 1.219 + 1.220 +void reset_timer(void) 1.221 +{ 1.222 + ticks = 0; 1.223 +} 1.224 + 1.225 +unsigned long get_msec(void) 1.226 +{ 1.227 + return ticks * tick_interval; 1.228 +} 1.229 + 1.230 +static void set_timer_reload(int reload_val) 1.231 +{ 1.232 + outp(PORT_CMD, CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE); 1.233 + outp(PORT_DATA0, reload_val & 0xff); 1.234 + outp(PORT_DATA0, (reload_val >> 8) & 0xff); 1.235 +} 1.236 + 1.237 +static void __interrupt __far dos_timer_intr() 1.238 +{ 1.239 + ticks++; 1.240 + _chain_intr(prev_timer_intr); /* DOES NOT RETURN */ 1.241 +} 1.242 + 1.243 +/* first PIC command port */ 1.244 +#define PIC1_CMD 0x20 1.245 +/* end of interrupt control word */ 1.246 +#define OCW2_EOI (1 << 5) 1.247 + 1.248 +static void __interrupt __far timer_irq() 1.249 +{ 1.250 + static unsigned long dos_ticks; 1.251 + 1.252 + ticks++; 1.253 + 1.254 + if(++dos_ticks >= ticks_per_dos_intr) { 1.255 + /* I suppose the dos irq handler does the EOI so I shouldn't 1.256 + * do it if I am to call the previous function 1.257 + */ 1.258 + dos_ticks = 0; 1.259 + _chain_intr(prev_timer_intr); /* XXX DOES NOT RETURN */ 1.260 + return; /* just for clarity */ 1.261 + } 1.262 + 1.263 + /* send EOI to the PIC */ 1.264 + outp(PIC1_CMD, OCW2_EOI); 1.265 +}