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 +}