X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fdos%2Ftimer.c;h=f42fac695b075ad3d6da96994efccb1d08211dba;hp=dfadd25a74071e287e5c88cd6bb46fa5ec155b17;hb=0165ec15f868a16a70b56ada2d42db0cb69ea193;hpb=a1f76b7a26c675e16cb78fecc9b6a1c0fc9c05c3 diff --git a/src/dos/timer.c b/src/dos/timer.c index dfadd25..f42fac6 100644 --- a/src/dos/timer.c +++ b/src/dos/timer.c @@ -1,25 +1,20 @@ -/* -colcycle - color cycling image viewer -Copyright (C) 2016 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ #include #include +#include #include #include + +#ifdef __WATCOMC__ #include +#endif + +#ifdef __DJGPP__ +#include +#include +#include +#include +#endif + #include "pit8254.h" #define PIT_TIMER_INTR 8 @@ -31,10 +26,24 @@ along with this program. If not, see . static void set_timer_reload(int reload_val); static void cleanup(void); -static void __interrupt __far timer_irq(); -static void __interrupt __far dos_timer_intr(); -static void (__interrupt __far *prev_timer_intr)(); +#ifdef __WATCOMC__ +#define INTERRUPT __interrupt __far + +static void INTERRUPT dos_timer_intr(); + +static void (INTERRUPT *prev_timer_intr)(); +#endif + +#ifdef __DJGPP__ +#define INTERRUPT + +static _go32_dpmi_seginfo intr, prev_intr; + +#define outp(p, v) outportb(p, v) +#endif + +static void INTERRUPT timer_irq(); static unsigned long ticks; static unsigned long tick_interval, ticks_per_dos_intr; @@ -52,14 +61,28 @@ void init_timer(int res_hz) ticks_per_dos_intr = DIV_ROUND(65535L, reload_val); inum = PIT_TIMER_INTR; +#ifdef __WATCOMC__ prev_timer_intr = _dos_getvect(inum); _dos_setvect(inum, timer_irq); +#endif +#ifdef __DJGPP__ + _go32_dpmi_get_protected_mode_interrupt_vector(inum, &prev_intr); + intr.pm_offset = (intptr_t)timer_irq; + intr.pm_selector = _go32_my_cs(); + _go32_dpmi_allocate_iret_wrapper(&intr); + _go32_dpmi_set_protected_mode_interrupt_vector(inum, &intr); +#endif } else { tick_interval = 55; inum = DOS_TIMER_INTR; +#ifdef __WATCOMC__ prev_timer_intr = _dos_getvect(inum); _dos_setvect(inum, dos_timer_intr); +#endif +#ifdef __DJGPP__ + assert(0); +#endif } _enable(); @@ -68,7 +91,7 @@ void init_timer(int res_hz) static void cleanup(void) { - if(!prev_timer_intr) { + if(!inum) { return; /* init hasn't ran, there's nothing to cleanup */ } @@ -79,7 +102,14 @@ static void cleanup(void) } /* restore the original interrupt handler */ +#ifdef __WATCOMC__ _dos_setvect(inum, prev_timer_intr); +#endif +#ifdef __DJGPP__ + _go32_dpmi_set_protected_mode_interrupt_vector(inum, &prev_intr); + _go32_dpmi_free_iret_wrapper(&intr); +#endif + _enable(); } @@ -100,23 +130,26 @@ static void set_timer_reload(int reload_val) outp(PORT_DATA0, (reload_val >> 8) & 0xff); } -static void __interrupt __far dos_timer_intr() +#ifdef __WATCOMC__ +static void INTERRUPT dos_timer_intr() { ticks++; _chain_intr(prev_timer_intr); /* DOES NOT RETURN */ } +#endif /* first PIC command port */ #define PIC1_CMD 0x20 /* end of interrupt control word */ #define OCW2_EOI (1 << 5) -static void __interrupt __far timer_irq() +static void INTERRUPT timer_irq() { static unsigned long dos_ticks; ticks++; +#ifdef __WATCOMC__ if(++dos_ticks >= ticks_per_dos_intr) { /* I suppose the dos irq handler does the EOI so I shouldn't * do it if I am to call the previous function @@ -125,6 +158,7 @@ static void __interrupt __far timer_irq() _chain_intr(prev_timer_intr); /* XXX DOES NOT RETURN */ return; /* just for clarity */ } +#endif /* send EOI to the PIC */ outp(PIC1_CMD, OCW2_EOI);