-/*
-colcycle - color cycling image viewer
-Copyright (C) 2016 John Tsiombikas <nuclear@member.fsf.org>
-
-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 <http://www.gnu.org/licenses/>.
-*/
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#include <conio.h>
#include <dos.h>
+
+#ifdef __WATCOMC__
#include <i86.h>
+#endif
+
+#ifdef __DJGPP__
+#include <stdint.h>
+#include <dpmi.h>
+#include <go32.h>
+#include <pc.h>
+#endif
+
#include "pit8254.h"
#define PIT_TIMER_INTR 8
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;
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();
static void cleanup(void)
{
- if(!prev_timer_intr) {
+ if(!inum) {
return; /* init hasn't ran, there's nothing to cleanup */
}
}
/* 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();
}
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
_chain_intr(prev_timer_intr); /* XXX DOES NOT RETURN */
return; /* just for clarity */
}
+#endif
/* send EOI to the PIC */
outp(PIC1_CMD, OCW2_EOI);