From 0165ec15f868a16a70b56ada2d42db0cb69ea193 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 6 Feb 2018 05:42:44 +0200 Subject: [PATCH] builds with djgpp but crashes --- Makefile | 2 +- Makefile.dj | 61 +++++++++++++++++++++++++++++++++++ libs/imago/Makefile.dj | 33 +++++++++++++++++++ libs/oldmik/Makefile.dj | 31 ++++++++++++++++++ libs/oldmik/src/virtch.c | 8 ++--- src/cfgopt.c | 13 +++++++- src/cfgopt.h | 1 + src/dos/cdpmi.h | 44 +++++++++++++++++++++++++ src/dos/djdpmi.c | 35 ++++++++++++++++++++ src/dos/dpmi.c | 72 ----------------------------------------- src/dos/dpmi.h | 26 --------------- src/dos/gfx.c | 67 ++++++++++++++++++++++++++++---------- src/dos/gfx.h | 17 ---------- src/dos/keyb.c | 60 ++++++++++++++++++++++++++++++---- src/dos/main.c | 22 ++++++++++++- src/dos/mouse.c | 15 +++++++++ src/dos/sball.c | 58 +++++++++++++++++++++++++++++---- src/dos/timer.c | 80 +++++++++++++++++++++++++++++++++------------- src/dos/vbe.c | 49 +++++++++++++++------------- src/dos/vbe.h | 10 ++++-- src/dos/watdpmi.c | 57 +++++++++++++++++++++++++++++++++ src/polyfill.c | 2 +- 22 files changed, 562 insertions(+), 201 deletions(-) create mode 100644 Makefile.dj create mode 100644 libs/imago/Makefile.dj create mode 100644 libs/oldmik/Makefile.dj create mode 100644 src/dos/cdpmi.h create mode 100644 src/dos/djdpmi.c delete mode 100644 src/dos/dpmi.c delete mode 100644 src/dos/dpmi.h create mode 100644 src/dos/watdpmi.c diff --git a/Makefile b/Makefile index e724f75..2f593c2 100644 --- 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 index 0000000..600403a --- /dev/null +++ b/Makefile.dj @@ -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 index 0000000..2d1ead6 --- /dev/null +++ b/libs/imago/Makefile.dj @@ -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 index 0000000..3d890f2 --- /dev/null +++ b/libs/oldmik/Makefile.dj @@ -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 diff --git a/libs/oldmik/src/virtch.c b/libs/oldmik/src/virtch.c index a414e4a..6a05cac 100644 --- a/libs/oldmik/src/virtch.c +++ b/libs/oldmik/src/virtch.c @@ -185,10 +185,10 @@ static SLONG lvolmul,rvolmul; static void VC_Sample32To8Copy(SLONG *srce,SBYTE *dest,ULONG count,UBYTE shift) { SLONG c; - int shift=(24-ampshift); + int fooshift=(24-ampshift); while(count--){ - c=*srce >> shift; + c=*srce >> fooshift; if(c>127) c=127; else if(c<-128) c=-128; *dest++=c+128; @@ -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) { SLONG c; - int shift=(16-ampshift); + int fooshift=(16-ampshift); while(count--){ - c=*srce >> shift; + c=*srce >> fooshift; if(c>32767) c=32767; else if(c<-32768) c=-32768; *dest++=c; diff --git a/src/cfgopt.c b/src/cfgopt.c index 71065e4..ef16167 100644 --- a/src/cfgopt.c +++ b/src/cfgopt.c @@ -4,7 +4,12 @@ #include #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; diff --git a/src/cfgopt.h b/src/cfgopt.h index 68a8e9d..57c41f6 100644 --- a/src/cfgopt.h +++ b/src/cfgopt.h @@ -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 index 0000000..9ce64e1 --- /dev/null +++ b/src/dos/cdpmi.h @@ -0,0 +1,44 @@ +#ifndef DPMI_H_ +#define DPMI_H_ + +#ifdef __DJGPP__ +#include +#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 index 0000000..69e7b56 --- /dev/null +++ b/src/dos/djdpmi.c @@ -0,0 +1,35 @@ +#ifdef __DJGPP__ +#include +#include +#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 index 4f7a794..0000000 --- a/src/dos/dpmi.c +++ /dev/null @@ -1,72 +0,0 @@ -/* -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 "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 index 352b9c1..0000000 --- a/src/dos/dpmi.h +++ /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_ */ diff --git a/src/dos/gfx.c b/src/dos/gfx.c index a07d77a..46cec31 100644 --- a/src/dos/gfx.c +++ b/src/dos/gfx.c @@ -6,15 +6,23 @@ #include #include #include "vbe.h" -#include "dpmi.h" +#include "cdpmi.h" +#ifdef __DJGPP__ +#include + +#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) { diff --git a/src/dos/gfx.h b/src/dos/gfx.h index 941f05c..b19c992 100644 --- a/src/dos/gfx.h +++ b/src/dos/gfx.h @@ -1,20 +1,3 @@ -/* -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 . -*/ #ifndef GFX_H_ #define GFX_H_ diff --git a/src/dos/keyb.c b/src/dos/keyb.c index 9ec20a9..98a1f3d 100644 --- a/src/dos/keyb.c +++ b/src/dos/keyb.c @@ -22,7 +22,17 @@ along with the program. If not, see #include #include #include + +#ifdef __WATCOMC__ #include +#endif +#ifdef __DJGPP__ +#include +#include +#include +#include +#endif + #include "keyb.h" #include "scancode.h" @@ -32,11 +42,24 @@ along with the program. If not, see #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; diff --git a/src/dos/main.c b/src/dos/main.c index 7564be3..3917e03 100644 --- a/src/dos/main.c +++ b/src/dos/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #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(); + } } } diff --git a/src/dos/mouse.c b/src/dos/mouse.c index e2779c9..0033130 100644 --- a/src/dos/mouse.c +++ b/src/dos/mouse.c @@ -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) diff --git a/src/dos/sball.c b/src/dos/sball.c index a8fbebc..9b9238a 100644 --- a/src/dos/sball.c +++ b/src/dos/sball.c @@ -1,7 +1,20 @@ #include +#include +#include #include #include + +#ifdef __WATCOMC__ #include +#endif + +#ifdef __DJGPP__ +#include +#include +#include +#include +#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; 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); diff --git a/src/dos/vbe.c b/src/dos/vbe.c index 5182e0a..009d5ca 100644 --- a/src/dos/vbe.c +++ b/src/dos/vbe.c @@ -1,7 +1,20 @@ #include #include +#include #include "vbe.h" -#include "dpmi.h" +#include "cdpmi.h" +#include "inttypes.h" + +#ifdef __DJGPP__ +#include +#include + +#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 @@ -14,14 +27,14 @@ 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(®s, 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, ®s); - 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>= 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); } diff --git a/src/dos/vbe.h b/src/dos/vbe.h index 17b2439..5854d5e 100644 --- a/src/dos/vbe.h +++ b/src/dos/vbe.h @@ -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 index 0000000..12dcfde --- /dev/null +++ b/src/dos/watdpmi.c @@ -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__ */ diff --git a/src/polyfill.c b/src/polyfill.c index e94de2f..8f6dbd2 100644 --- a/src/polyfill.c +++ b/src/polyfill.c @@ -2,7 +2,7 @@ #include #include #include -#if defined(__WATCOMC__) || defined(_MSC_VER) +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__) #include #else #include -- 1.7.10.4