builds with djgpp but crashes
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 6 Feb 2018 03:42:44 +0000 (05:42 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 6 Feb 2018 03:42:44 +0000 (05:42 +0200)
22 files changed:
Makefile
Makefile.dj [new file with mode: 0644]
libs/imago/Makefile.dj [new file with mode: 0644]
libs/oldmik/Makefile.dj [new file with mode: 0644]
libs/oldmik/src/virtch.c
src/cfgopt.c
src/cfgopt.h
src/dos/cdpmi.h [new file with mode: 0644]
src/dos/djdpmi.c [new file with mode: 0644]
src/dos/dpmi.c [deleted file]
src/dos/dpmi.h [deleted file]
src/dos/gfx.c
src/dos/gfx.h
src/dos/keyb.c
src/dos/main.c
src/dos/mouse.c
src/dos/sball.c
src/dos/timer.c
src/dos/vbe.c
src/dos/vbe.h
src/dos/watdpmi.c [new file with mode: 0644]
src/polyfill.c

index e724f75..2f593c2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ demoobj = main.obj demo.obj screen.obj cfgopt.obj music.obj gfxutil.obj &
 3dgfx.obj polyfill.obj polyclip.obj metasurf.obj dynarr.obj
 scrobj = tunnel.obj fract.obj grise.obj polytest.obj plasma.obj bump.obj &
 thunder.obj metaball.obj
-sysobj = gfx.obj vbe.obj dpmi.obj timer.obj keyb.obj mouse.obj sball.obj &
+sysobj = gfx.obj vbe.obj watdpmi.obj timer.obj keyb.obj mouse.obj sball.obj &
 logger.obj tinyfps.obj
 obj = $(baseobj) $(demoobj) $(sysobj) $(scrobj)
 bin = demo.exe
diff --git a/Makefile.dj b/Makefile.dj
new file mode 100644 (file)
index 0000000..600403a
--- /dev/null
@@ -0,0 +1,61 @@
+src = $(wildcard src/*.c) $(wildcard src/dos/*.c)
+obj = $(src:.c=.o)
+dep = $(obj:.o=.d)
+bin = demo.exe
+
+ifeq ($(findstring COMMAND.COM, $(SHELL)), COMMAND.COM)
+       hostsys = dos
+else
+       hostsys = unix
+       TOOLPREFIX = i586-pc-msdosdjgpp-
+endif
+
+inc = -Isrc -Isrc/dos -Ilibs/imago/src -Ilibs/oldmik/src
+opt = -O3 -ffast-math
+dbg = -g
+
+CC = $(TOOLPREFIX)gcc
+AR = $(TOOLPREFIX)ar
+CFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc)
+LDFLAGS = libs/imago/imago.a libs/oldmik/mikmod.a
+
+$(bin): $(obj) imago mikmod
+       $(CC) -o $@ -Wl,-Map=ld.map $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%.d: %.c
+       @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+.PHONY: imago
+imago:
+       $(MAKE) -C libs/imago -f Makefile.dj
+
+.PHONY: mikmod
+mikmod:
+       $(MAKE) -C libs/oldmik -f Makefile.dj
+
+.PHONY: cleanlibs
+cleanlibs:
+       $(MAKE) -C libs/imago -f Makefile.dj clean
+       $(MAKE) -C libs/oldmik -f Makefile.dj clean
+
+.PHONY: clean
+.PHONY: cleandep
+
+ifeq ($(hostsys), dos)
+clean:
+       del src\*.o
+       del src\dos\*.o
+       del $(bin)
+
+cleandep:
+       del src\*.d
+       del src\dos\*.d
+else
+clean:
+       rm -f $(obj) $(bin)
+
+cleandep:
+       rm -f $(dep)
+endif
diff --git a/libs/imago/Makefile.dj b/libs/imago/Makefile.dj
new file mode 100644 (file)
index 0000000..2d1ead6
--- /dev/null
@@ -0,0 +1,33 @@
+src = $(wildcard src/*.c) \
+         $(wildcard zlib/*.c) \
+         $(wildcard libpng/*.c) \
+         $(wildcard jpeglib/*.c)
+obj = $(src:.c=.o)
+alib = imago.a
+
+ifeq ($(findstring COMMAND.COM, $(SHELL)), COMMAND.COM)
+       hostsys = dos
+else
+       hostsys = unix
+       TOOLPREFIX = i586-pc-msdosdjgpp-
+endif
+
+CC = $(TOOLPREFIX)gcc
+AR = $(TOOLPREFIX)ar
+CFLAGS = -pedantic -Wall -Wno-main -g -O3 -ffast-math -Izlib -Ilibpng -Ijpeglib
+
+$(alib): $(obj)
+       $(AR) rcs $@ $(obj)
+
+.PHONY: clean
+ifeq ($(hostsys), dos)
+clean:
+       del src\*.o
+       del zlib\*.o
+       del libpng\*.o
+       del jpeglib\*.o
+       del $(alib)
+else
+clean:
+       rm -f $(obj) $(alib)
+endif
diff --git a/libs/oldmik/Makefile.dj b/libs/oldmik/Makefile.dj
new file mode 100644 (file)
index 0000000..3d890f2
--- /dev/null
@@ -0,0 +1,31 @@
+csrc = $(wildcard src/*.c)
+obj = $(csrc:.c=.o)
+
+alib = mikmod.a
+
+opt = -O3 -ffast-math
+#dbg = -g
+
+ifeq ($(findstring COMMAND.COM, $(SHELL)), COMMAND.COM)
+       hostsys = dos
+else
+       hostsys = unix
+       TOOLPREFIX = i586-pc-msdosdjgpp-
+endif
+
+CC = $(TOOLPREFIX)gcc
+AR = $(TOOLPREFIX)ar
+CFLAGS = $(opt) $(dbg) -Isrc
+
+$(alib): $(obj)
+       $(AR) rcs $@ $(obj)
+
+.PHONY: clean
+ifeq ($(hostsys), dos)
+clean:
+       del src\*.o
+       del $(alib)
+else
+clean:
+       rm -f $(obj) $(alib)
+endif
index a414e4a..6a05cac 100644 (file)
@@ -185,10 +185,10 @@ static SLONG lvolmul,rvolmul;
 static void VC_Sample32To8Copy(SLONG *srce,SBYTE *dest,ULONG count,UBYTE shift)\r
 {\r
        SLONG c;\r
-       int shift=(24-ampshift);\r
+       int fooshift=(24-ampshift);\r
 \r
        while(count--){\r
-               c=*srce >> shift;\r
+               c=*srce >> fooshift;\r
                if(c>127) c=127;\r
                else if(c<-128) c=-128;\r
                *dest++=c+128;\r
@@ -200,10 +200,10 @@ static void VC_Sample32To8Copy(SLONG *srce,SBYTE *dest,ULONG count,UBYTE shift)
 static void VC_Sample32To16Copy(SLONG *srce,SWORD *dest,ULONG count,UBYTE shift)\r
 {\r
        SLONG c;\r
-       int shift=(16-ampshift);\r
+       int fooshift=(16-ampshift);\r
 \r
        while(count--){\r
-               c=*srce >> shift;\r
+               c=*srce >> fooshift;\r
                if(c>32767) c=32767;\r
                else if(c<-32768) c=-32768;\r
                *dest++=c;\r
index 71065e4..ef16167 100644 (file)
@@ -4,7 +4,12 @@
 #include <ctype.h>
 #include "cfgopt.h"
 
-struct options opt;
+struct options opt = {
+       0,      /* start_scr */
+       0,      /* music */
+       0,      /* sball */
+       1       /* vsync */
+};
 
 int parse_args(int argc, char **argv)
 {
@@ -21,6 +26,10 @@ int parse_args(int argc, char **argv)
                                scrname = argv[++i];
                        } else if(strcmp(argv[i], "-sball") == 0) {
                                opt.sball = !opt.sball;
+                       } else if(strcmp(argv[i], "-vsync") == 0) {
+                               opt.vsync = 1;
+                       } else if(strcmp(argv[i], "-novsync") == 0) {
+                               opt.vsync = 0;
                        } else {
                                fprintf(stderr, "invalid option: %s\n", argv[i]);
                                return -1;
@@ -105,6 +114,8 @@ int load_config(const char *fname)
                        opt.start_scr = strdup(value);
                } else if(strcmp(line, "sball") == 0) {
                        opt.sball = bool_value(value);
+               } else if(strcmp(line, "vsync") == 0) {
+                       opt.vsync = bool_value(value);
                } else {
                        fprintf(stderr, "%s:%d invalid option: %s\n", fname, nline, line);
                        return -1;
index 68a8e9d..57c41f6 100644 (file)
@@ -5,6 +5,7 @@ struct options {
        const char *start_scr;
        int music;
        int sball;
+       int vsync;
 };
 
 extern struct options opt;
diff --git a/src/dos/cdpmi.h b/src/dos/cdpmi.h
new file mode 100644 (file)
index 0000000..9ce64e1
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef DPMI_H_
+#define DPMI_H_
+
+#ifdef __DJGPP__
+#include <dpmi.h>
+#endif
+
+#include "inttypes.h"
+
+struct dpmi_real_regs {
+       uint32_t edi, esi, ebp;
+       uint32_t reserved;
+       uint32_t ebx, edx, ecx, eax;
+       uint16_t flags;
+       uint16_t es, ds, fs, gs;
+       uint16_t ip, cs, sp, ss;
+};
+
+uint16_t dpmi_alloc(unsigned int par, uint16_t *sel);
+void dpmi_free(uint16_t sel);
+
+#ifdef __WATCOMC__
+#pragma aux dpmi_alloc = \
+               "mov eax, 0x100" \
+               "int 0x31" \
+               "mov [edi], dx" \
+               value[ax] parm[ebx][edi];
+
+#pragma aux dpmi_free = \
+               "mov eax, 0x101" \
+               "int 0x31" \
+               parm[dx];
+
+void dpmi_real_int(int inum, struct dpmi_real_regs *regs);
+#endif /* __WATCOMC__ */
+
+#ifdef __DJGPP__
+#define dpmi_real_int(inum, regs) __dpmi_int((inum), (__dpmi_regs*)(regs))
+#endif
+
+void *dpmi_mmap(uint32_t phys_addr, unsigned int size);
+void dpmi_munmap(void *addr);
+
+#endif /* DPMI_H_ */
diff --git a/src/dos/djdpmi.c b/src/dos/djdpmi.c
new file mode 100644 (file)
index 0000000..69e7b56
--- /dev/null
@@ -0,0 +1,35 @@
+#ifdef __DJGPP__
+#include <dpmi.h>
+#include <sys/nearptr.h>
+#include "cdpmi.h"
+#include "inttypes.h"
+
+uint16_t dpmi_alloc(unsigned int par, uint16_t *sel)
+{
+       int tmp;
+       uint16_t seg = __dpmi_allocate_dos_memory(par, &tmp);
+       *sel = tmp;
+       return tmp;
+}
+
+void dpmi_free(uint16_t sel)
+{
+       __dpmi_free_dos_memory(sel);
+}
+
+void *dpmi_mmap(uint32_t phys_addr, unsigned int size)
+{
+       __dpmi_meminfo mem;
+       mem.address = phys_addr;
+       mem.size = size;
+       __dpmi_physical_address_mapping(&mem);
+       return (void*)(mem.address - __djgpp_base_address);
+}
+
+void dpmi_munmap(void *addr)
+{
+       __dpmi_meminfo mem;
+       mem.address = (uint32_t)addr + __djgpp_base_address;
+       __dpmi_free_physical_address_mapping(&mem);
+}
+#endif /* __DJGPP__ */
diff --git a/src/dos/dpmi.c b/src/dos/dpmi.c
deleted file mode 100644 (file)
index 4f7a794..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-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 "dpmi.h"
-
-void dpmi_real_int(int inum, struct dpmi_real_regs *regs)
-{
-       unsigned char int_num = (unsigned char)inum;
-       __asm {
-               mov eax, 0x300
-               mov edi, regs
-               mov bl, int_num
-               mov bh, 0
-               xor ecx, ecx
-               int 0x31
-       }
-}
-
-void *dpmi_mmap(uint32_t phys_addr, unsigned int size)
-{
-       uint16_t mem_high, mem_low;
-       uint16_t phys_high = phys_addr >> 16;
-       uint16_t phys_low = phys_addr & 0xffff;
-       uint16_t size_high = size >> 16;
-       uint16_t size_low = size & 0xffff;
-       unsigned int err, res = 0;
-
-       __asm {
-               mov eax, 0x800
-               mov bx, phys_high
-               mov cx, phys_low
-               mov si, size_high
-               mov di, size_low
-               int 0x31
-               add res, 1
-               mov err, eax
-               mov mem_high, bx
-               mov mem_low, cx
-       }
-
-       if(res == 2) {
-               return 0;
-       }
-       return (void*)(((uint32_t)mem_high << 16) | ((uint32_t)mem_low));
-}
-
-void dpmi_munmap(void *addr)
-{
-       uint16_t mem_high = (uint32_t)addr >> 16;
-       uint16_t mem_low = (uint16_t)addr;
-
-       __asm {
-               mov eax, 0x801
-               mov bx, mem_high
-               mov cx, mem_low
-               int 0x31
-       }
-}
diff --git a/src/dos/dpmi.h b/src/dos/dpmi.h
deleted file mode 100644 (file)
index 352b9c1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef DPMI_H_
-#define DPMI_H_
-
-#include "inttypes.h"
-
-struct dpmi_real_regs {
-       uint32_t edi, esi, ebp;
-       uint32_t reserved;
-       uint32_t ebx, edx, ecx, eax;
-       uint16_t flags;
-       uint16_t es, ds, fs, gs;
-       uint16_t ip, cs, sp, ss;
-};
-
-unsigned short dpmi_alloc(unsigned int par);
-#pragma aux dpmi_alloc = \
-               "mov eax, 0x100" \
-               "int 0x31" \
-               value[ax] parm[ebx];
-
-void dpmi_real_int(int inum, struct dpmi_real_regs *regs);
-
-void *dpmi_mmap(uint32_t phys_addr, unsigned int size);
-void dpmi_munmap(void *addr);
-
-#endif /* DPMI_H_ */
index a07d77a..46cec31 100644 (file)
@@ -6,15 +6,23 @@
 #include <string.h>
 #include <limits.h>
 #include "vbe.h"
-#include "dpmi.h"
+#include "cdpmi.h"
 
+#ifdef __DJGPP__
+#include <sys/nearptr.h>
+
+#define REALPTR(s, o)  (void*)(((uint32_t)(s) << 4) - __djgpp_base_address + (uint32_t)(o))
+#else
 #define REALPTR(s, o)  (void*)(((uint32_t)(s) << 4) + (uint32_t)(o))
+#endif
+
 #define VBEPTR(x)              REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff)
 #define VBEPTR_SEG(x)  (((x) & 0xffff0000) >> 16)
 #define VBEPTR_OFF(x)  ((x) & 0xffff)
 
 #define SAME_BPP(a, b) \
-       ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32)
+       ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \
+        ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32))
 
 static unsigned int make_mask(int sz, int pos);
 
@@ -25,9 +33,14 @@ static int pal_bits = 6;
 void *set_video_mode(int xsz, int ysz, int bpp)
 {
        int i;
-       uint16_t *modes, best = 0;
+       static uint16_t *modes;
+       uint16_t best = 0;
        unsigned int fbsize;
 
+#ifdef __DJGPP__
+       __djgpp_nearptr_enable();
+#endif
+
        /* check for VBE2 support and output some info */
        if(!vbe_info) {
                if(!(vbe_info = vbe_get_info())) {
@@ -41,8 +54,8 @@ void *set_video_mode(int xsz, int ysz, int bpp)
                        return 0;
                }
 
-               printf("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr),
-                               VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr));
+               printf("Graphics adapter: %s, %s (%s)\n", (char*)VBEPTR(vbe_info->oem_vendor_name_ptr),
+                               (char*)VBEPTR(vbe_info->oem_product_name_ptr), (char*)VBEPTR(vbe_info->oem_product_rev_ptr));
                printf("Video memory: %dkb\n", vbe_info->total_mem << 6);
 
                modes = VBEPTR(vbe_info->vid_mode_ptr);
@@ -141,20 +154,42 @@ void set_palette(int idx, int r, int g, int b)
        vbe_set_palette(idx, col, 1, pal_bits);
 }
 
+#ifdef __WATCOMC__
+void wait_vsync_asm(void);
+#pragma aux wait_vsync_asm = \
+       "mov dx, 0x3da" \
+       "l1:" \
+       "in al, dx" \
+       "and al, 0x8" \
+       "jnz l1" \
+       "l2:" \
+       "in al, dx" \
+       "and al, 0x8" \
+       "jz l2" \
+       modify[al dx];
+
 void wait_vsync(void)
 {
-       __asm {
-               mov dx, 0x3da
-       l1:
-               in al, dx
-               and al, 0x8
-               jnz l1
-       l2:
-               in al, dx
-               and al, 0x8
-               jz l2
-       }
+       wait_vsync_asm();
+}
+#endif
+
+#ifdef __DJGPP__
+void wait_vsync(void)
+{
+       asm volatile (
+               "mov $0x3da, %%dx\n\t"
+               "0:\n\t"
+               "in %%dx, %%al\n\t"
+               "and $8, %%al\n\t"
+               "jnz 0b\n\t"
+               "0:\n\t"
+               "in %%dx, %%al\n\t"
+               "and $8, %%al\n\t"
+               "jz 0b\n\t"
+               :::"%eax","%edx");
 }
+#endif
 
 static unsigned int make_mask(int sz, int pos)
 {
index 941f05c..b19c992 100644 (file)
@@ -1,20 +1,3 @@
-/*
-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/>.
-*/
 #ifndef GFX_H_
 #define GFX_H_
 
index 9ec20a9..98a1f3d 100644 (file)
@@ -22,7 +22,17 @@ along with the program. If not, see <http://www.gnu.org/licenses/>
 #include <string.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 "keyb.h"
 #include "scancode.h"
 
@@ -32,11 +42,24 @@ along with the program. If not, see <http://www.gnu.org/licenses/>
 #define PIC1_CMD_PORT  0x20
 #define OCW2_EOI               (1 << 5)
 
+#ifdef __WATCOMC__
+#define INTERRUPT __interrupt __far
+
 #define DONE_INIT      (prev_handler)
+static void (INTERRUPT *prev_handler)();
+#endif
+
+#ifdef __DJGPP__
+#define INTERRUPT
 
-static void __interrupt __far kbintr();
+#define DONE_INIT prev_intr.pm_offset
+static _go32_dpmi_seginfo intr, prev_intr;
 
-static void (__interrupt __far *prev_handler)();
+#define outp(p, v)     outportb(p, v)
+#define inp(p) inportb(p)
+#endif
+
+static void INTERRUPT kbintr();
 
 static int *buffer;
 static int buffer_size, buf_ridx, buf_widx;
@@ -67,8 +90,17 @@ int kb_init(int bufsz)
 
        /* set our interrupt handler */
        _disable();
+#ifdef __WATCOMC__
        prev_handler = _dos_getvect(KB_INTR);
        _dos_setvect(KB_INTR, kbintr);
+#endif
+#ifdef __DJGPP__
+       _go32_dpmi_get_protected_mode_interrupt_vector(KB_INTR, &prev_intr);
+       intr.pm_offset = (intptr_t)kbintr;
+       intr.pm_selector = _go32_my_cs();
+       _go32_dpmi_allocate_iret_wrapper(&intr);
+       _go32_dpmi_set_protected_mode_interrupt_vector(KB_INTR, &intr);
+#endif
        _enable();
 
        return 0;
@@ -82,7 +114,13 @@ void kb_shutdown(void)
 
        /* restore the original interrupt handler */
        _disable();
+#ifdef __WATCOMC__
        _dos_setvect(KB_INTR, prev_handler);
+#endif
+#ifdef __DJGPP__
+       _go32_dpmi_set_protected_mode_interrupt_vector(KB_INTR, &prev_intr);
+       _go32_dpmi_free_iret_wrapper(&intr);
+#endif
        _enable();
 
        free(buffer);
@@ -103,6 +141,17 @@ int kb_isdown(int key)
        return keystate[key];
 }
 
+#ifdef __WATCOMC__
+void halt(void);
+#pragma aux halt = \
+       "sti" \
+       "hlt";
+#endif
+
+#ifdef __DJGPP__
+#define halt() asm volatile("sti\n\thlt\n\t")
+#endif
+
 void kb_wait(void)
 {
        int key;
@@ -110,10 +159,7 @@ void kb_wait(void)
                /* put the processor to sleep while waiting for keypresses, but first
                 * make sure interrupts are enabled, or we'll sleep forever
                 */
-               __asm {
-                       sti
-                       hlt
-               }
+               halt();
        }
        kb_putback(key);
 }
@@ -157,7 +203,7 @@ void kb_putback(int key)
        }
 }
 
-static void __interrupt __far kbintr()
+static void INTERRUPT kbintr()
 {
        unsigned char code;
        int key, press;
index 7564be3..3917e03 100644 (file)
@@ -3,6 +3,7 @@
 #include <math.h>
 #include <string.h>
 #include <limits.h>
+#include <conio.h>
 #include "demo.h"
 #include "keyb.h"
 #include "mouse.h"
@@ -12,6 +13,9 @@
 #include "sball.h"
 #include "cfgopt.h"
 #include "logger.h"
+#include "tinyfps.h"
+
+#define NOKEYB
 
 static int handle_sball_event(sball_event *ev);
 static void recalc_sball_matrix(float *xform);
@@ -31,7 +35,9 @@ int main(int argc, char **argv)
        init_logger("demo.log");
 
        init_timer(100);
+#ifndef NOKEYB
        kb_init(32);
+#endif
 
        if((use_mouse = have_mouse())) {
                set_mouse_limits(0, 0, fb_width, fb_height);
@@ -61,10 +67,16 @@ int main(int argc, char **argv)
        reset_timer();
 
        while(!quit) {
+#ifndef NOKEYB
                int key;
                while((key = kb_getkey()) != -1) {
                        demo_keyboard(key, 1);
                }
+#else
+               if(kbhit()) {
+                       demo_keyboard(getch(), 1);
+               }
+#endif
                if(quit) goto break_evloop;
 
                if(use_mouse) {
@@ -86,7 +98,9 @@ int main(int argc, char **argv)
 break_evloop:
        set_text_mode();
        demo_cleanup();
+#ifndef NOKEYB
        kb_shutdown();
+#endif
        if(use_sball) {
                sball_shutdown();
        }
@@ -102,11 +116,17 @@ void swap_buffers(void *pixels)
 {
        /* TODO implement page flipping */
        if(pixels) {
-               /*wait_vsync();*/
+               if(opt.vsync) {
+                       wait_vsync();
+               }
                drawFps(pixels);
                memcpy(vmem_front, pixels, fbsize);
        } else {
                drawFps(vmem_back);
+
+               if(opt.vsync) {
+                       wait_vsync();
+               }
        }
 }
 
index e2779c9..0033130 100644 (file)
@@ -17,26 +17,31 @@ typedef unsigned short uint16_t;
 int have_mouse(void)
 {
        uint16_t res = 0;
+#ifdef __WATCOMC__
        _asm {
                mov eax, QUERY
                int INTR
                mov res, ax
        }
+#endif
        return res;
 }
 
 void show_mouse(int show)
 {
        uint16_t cmd = show ? SHOW : HIDE;
+#ifdef __WATCOMC__
        _asm {
                mov ax, cmd
                int INTR
        }
+#endif
 }
 
 int read_mouse(int *xp, int *yp)
 {
        uint16_t x, y, state;
+#ifdef __WATCOMC__
        _asm {
                mov eax, READ
                int INTR
@@ -44,6 +49,10 @@ int read_mouse(int *xp, int *yp)
                mov x, cx
                mov y, dx
        }
+#endif
+#ifdef __DJGPP__
+       x = y = state = 0;
+#endif
 
        if(xp) *xp = x;
        if(yp) *yp = y;
@@ -52,16 +61,19 @@ int read_mouse(int *xp, int *yp)
 
 void set_mouse(int x, int y)
 {
+#ifdef __WATCOMC__
        _asm {
                mov eax, WRITE
                mov ecx, x
                mov edx, y
                int INTR
        }
+#endif
 }
 
 void set_mouse_limits(int xmin, int ymin, int xmax, int ymax)
 {
+#ifdef __WATCOMC__
        _asm {
                mov eax, XLIM
                mov ecx, xmin
@@ -72,16 +84,19 @@ void set_mouse_limits(int xmin, int ymin, int xmax, int ymax)
                mov edx, ymax
                int INTR
        }
+#endif
 }
 
 void set_mouse_rate(int xrate, int yrate)
 {
+#ifdef __WATCOMC__
        _asm {
                mov ax, PIXRATE
                mov ecx, xrate
                mov edx, yrate
                int INTR
        }
+#endif
 }
 
 void set_mouse_mode(enum mouse_mode mode)
index a8fbebc..9b9238a 100644 (file)
@@ -1,7 +1,20 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <dos.h>
 #include <conio.h>
+
+#ifdef __WATCOMC__
 #include <i86.h>
+#endif
+
+#ifdef __DJGPP__
+#include <stdint.h>
+#include <dpmi.h>
+#include <go32.h>
+#include <pc.h>
+#endif
+
 #include "sball.h"
 
 struct motion {
@@ -96,6 +109,11 @@ struct motion {
 #define PIC2_DATA_PORT 0xa1
 #define OCW2_EOI               0x20
 
+struct packet {
+       int id;
+       char data[80];
+};
+
 static int init_smouse(void);
 static void read_motion(int *m, const char *s);
 static void read_keystate(unsigned int *stptr, const char *s);
@@ -105,6 +123,7 @@ static void enqueue_event(sball_event *ev);
 #define COM_FMT_8N1            LCTL_8N1
 #define COM_FMT_8N2            LCTL_8N2
 static void com_setup(int port, int baud, unsigned int fmt);
+static void com_close(void);
 
 static void com_putc(char c);
 static void com_puts(const char *s);
@@ -114,15 +133,25 @@ static char *com_gets(char *buf, int sz);
 static int com_have_recv(void);
 static int com_can_send(void);
 
-static void __interrupt __far recv_intr(void);
+#ifdef __WATCOMC__
+#define INTERRUPT      __interrupt __far
+static void (INTERRUPT *prev_recv_intr)(void);
+#endif
+
+#ifdef __DJGPP__
+#define INTERRUPT
+
+static _go32_dpmi_seginfo intr, prev_intr;
+
+#define outp(port, val)        outportb(port, val)
+#define inp(port) inportb(port)
+#endif
+
+static void INTERRUPT recv_intr(void);
 
 static int uart_base, uart_intr_num;
-static void (__interrupt __far *prev_recv_intr)(void);
 
-static struct packet {
-       int id;
-       char data[80];
-} pktbuf[16];
+static struct packet pktbuf[16];
 static int pktbuf_ridx, pktbuf_widx;
 #define BNEXT(x)       (((x) + 1) & 0xf)
 #define BEMPTY(b)      (b##_ridx == b##_widx)
@@ -260,8 +289,17 @@ static void com_setup(int port, int baud, unsigned int fmt)
        uart_intr_num = irq[port] | 8;
 
        _disable();
+#ifdef __WATCOMC__
        prev_recv_intr = _dos_getvect(uart_intr_num);
        _dos_setvect(uart_intr_num, recv_intr);
+#endif
+#ifdef __DJGPP__
+       _go32_dpmi_get_protected_mode_interrupt_vector(uart_intr_num, &prev_intr);
+       intr.pm_offset = (intptr_t)recv_intr;
+       intr.pm_selector = _go32_my_cs();
+       _go32_dpmi_allocate_iret_wrapper(&intr);
+       _go32_dpmi_set_protected_mode_interrupt_vector(uart_intr_num, &intr);
+#endif
        /* unmask the appropriate interrupt */
        outp(PIC1_DATA_PORT, inp(PIC1_DATA_PORT) & ~(1 << irq[port]));
 
@@ -281,7 +319,13 @@ static void com_close(void)
        _disable();
        outp(uart_base + UART_INTR, 0);
        outp(uart_base + UART_MCTL, 0);
+#ifdef __WATCOMC__
        _dos_setvect(uart_intr_num, prev_recv_intr);
+#endif
+#ifdef __DJGPP__
+       _go32_dpmi_set_protected_mode_interrupt_vector(uart_intr_num, &prev_intr);
+       _go32_dpmi_free_iret_wrapper(&intr);
+#endif
        _enable();
 }
 
@@ -340,7 +384,7 @@ static int com_can_send(void)
        return inp(uart_base + UART_LSTAT) & LST_TREG_EMPTY;
 }
 
-static void __interrupt __far recv_intr()
+static void INTERRUPT recv_intr()
 {
        static char buf[128];
        static char *bptr = buf;
index dfadd25..f42fac6 100644 (file)
@@ -1,25 +1,20 @@
-/*
-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
@@ -31,10 +26,24 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 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);
index 5182e0a..009d5ca 100644 (file)
@@ -1,7 +1,20 @@
 #include <stdio.h>
 #include <string.h>
+#include <conio.h>
 #include "vbe.h"
-#include "dpmi.h"
+#include "cdpmi.h"
+#include "inttypes.h"
+
+#ifdef __DJGPP__
+#include <pc.h>
+#include <sys/nearptr.h>
+
+#define SEG_ADDR(s)    (((uint32_t)(s) << 4) - __djgpp_base_address)
+
+#define outp(p, v)     outportb(p, v)
+#else
+#define SEG_ADDR(s)    ((uint32_t)(s) << 4)
+#endif
 
 /* VGA DAC registers used for palette setting in 8bpp modes */
 #define VGA_DAC_STATE          0x3c7
 
 struct vbe_info *vbe_get_info(void)
 {
-       static unsigned short info_block_seg;
+       static uint16_t info_block_seg, info_block_selector;
        static struct vbe_info *info;
        struct dpmi_real_regs regs;
 
        if(!info) {
                /* allocate 32 paragraphs (512 bytes) */
-               info_block_seg = dpmi_alloc(32);
-               info = (struct vbe_info*)(info_block_seg << 4);
+               info_block_seg = dpmi_alloc(32, &info_block_selector);
+               info = (struct vbe_info*)SEG_ADDR(info_block_seg);
        }
 
        memcpy(info->sig, "VBE2", 4);
@@ -37,14 +50,14 @@ struct vbe_info *vbe_get_info(void)
 
 struct vbe_mode_info *vbe_get_mode_info(int mode)
 {
-       static unsigned short mode_info_seg;
+       static uint16_t mode_info_seg, mode_info_selector;
        static struct vbe_mode_info *mi;
        struct dpmi_real_regs regs;
 
        if(!mi) {
                /* allocate 16 paragraphs (256 bytes) */
-               mode_info_seg = dpmi_alloc(16);
-               mi = (struct vbe_mode_info*)(mode_info_seg << 4);
+               mode_info_seg = dpmi_alloc(16, &mode_info_selector);
+               mi = (struct vbe_mode_info*)SEG_ADDR(mode_info_seg);
        }
 
        memset(&regs, 0, sizeof regs);
@@ -85,7 +98,7 @@ int vbe_set_palette_bits(int bits)
        regs.ebx = bits << 8;   /* bits in bh */
        dpmi_real_int(0x10, &regs);
 
-       if((regs.eax >> 8) & 0xff == 3) {
+       if(((regs.eax >> 8) & 0xff) == 3) {
                return -1;
        }
        return regs.ebx >> 8 & 0xff;    /* new color bits in bh */
@@ -98,11 +111,7 @@ void vbe_set_palette(int idx, int *col, int count, int bits)
 {
        int i, shift = 8 - bits;
 
-       __asm {
-               mov dx, VGA_DAC_ADDR_WR
-               mov eax, idx
-               out dx, al
-       }
+       outp(VGA_DAC_ADDR_WR, idx);
 
        for(i=0; i<count; i++) {
                unsigned char r = *col++;
@@ -115,15 +124,9 @@ void vbe_set_palette(int idx, int *col, int count, int bits)
                        b >>= shift;
                }
 
-               __asm {
-                       mov dx, VGA_DAC_DATA
-                       mov al, r
-                       out dx, al
-                       mov al, g
-                       out dx, al
-                       mov al, b
-                       out dx, al
-               }
+               outp(VGA_DAC_DATA, r);
+               outp(VGA_DAC_DATA, g);
+               outp(VGA_DAC_DATA, b);
        }
 }
 
@@ -149,5 +152,5 @@ void print_mode_info(FILE *fp, struct vbe_mode_info *mi)
        fprintf(fp, "red bits: %d (mask: %x)\n", (int)mi->rmask_size, get_mask(mi->rmask_size, mi->rpos));
        fprintf(fp, "green bits: %d (mask: %x)\n", (int)mi->gmask_size, get_mask(mi->gmask_size, mi->gpos));
        fprintf(fp, "blue bits: %d (mask: %x)\n", (int)mi->bmask_size, get_mask(mi->bmask_size, mi->bpos));
-       fprintf(fp, "framebuffer address: %x\n", mi->fb_addr);
+       fprintf(fp, "framebuffer address: %x\n", (unsigned int)mi->fb_addr);
 }
index 17b2439..5854d5e 100644 (file)
@@ -3,6 +3,12 @@
 
 #include "inttypes.h"
 
+#ifdef __GNUC__
+#define PACKED __attribute__((packed))
+#else
+#define PACKED
+#endif
+
 #define VBE_ATTR_LFB   (1 << 7)
 #define VBE_MODE_LFB   (1 << 14)
 
@@ -20,7 +26,7 @@ struct vbe_info {
        uint32_t oem_product_rev_ptr;
        uint8_t reserved[222];
        uint8_t oem_data[256];
-};
+} PACKED;
 
 struct vbe_mode_info {
        uint16_t mode_attr;
@@ -54,7 +60,7 @@ struct vbe_mode_info {
        uint16_t reserved3;
 
        uint8_t reserved4[206];
-};
+} PACKED;
 #pragma pack (pop)
 
 struct vbe_info *vbe_get_info(void);
diff --git a/src/dos/watdpmi.c b/src/dos/watdpmi.c
new file mode 100644 (file)
index 0000000..12dcfde
--- /dev/null
@@ -0,0 +1,57 @@
+#ifdef __WATCOMC__
+#include "cdpmi.h"
+
+void dpmi_real_int(int inum, struct dpmi_real_regs *regs)
+{
+       unsigned char int_num = (unsigned char)inum;
+       __asm {
+               mov eax, 0x300
+               mov edi, regs
+               mov bl, int_num
+               mov bh, 0
+               xor ecx, ecx
+               int 0x31
+       }
+}
+
+void *dpmi_mmap(uint32_t phys_addr, unsigned int size)
+{
+       uint16_t mem_high, mem_low;
+       uint16_t phys_high = phys_addr >> 16;
+       uint16_t phys_low = phys_addr & 0xffff;
+       uint16_t size_high = size >> 16;
+       uint16_t size_low = size & 0xffff;
+       unsigned int err, res = 0;
+
+       __asm {
+               mov eax, 0x800
+               mov bx, phys_high
+               mov cx, phys_low
+               mov si, size_high
+               mov di, size_low
+               int 0x31
+               add res, 1
+               mov err, eax
+               mov mem_high, bx
+               mov mem_low, cx
+       }
+
+       if(res == 2) {
+               return 0;
+       }
+       return (void*)(((uint32_t)mem_high << 16) | ((uint32_t)mem_low));
+}
+
+void dpmi_munmap(void *addr)
+{
+       uint16_t mem_high = (uint32_t)addr >> 16;
+       uint16_t mem_low = (uint16_t)addr;
+
+       __asm {
+               mov eax, 0x801
+               mov bx, mem_high
+               mov cx, mem_low
+               int 0x31
+       }
+}
+#endif /* __WATCOM__ */
index e94de2f..8f6dbd2 100644 (file)
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#if defined(__WATCOMC__) || defined(_MSC_VER)
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__)
 #include <malloc.h>
 #else
 #include <alloca.h>