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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
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
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
#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)
{
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;
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;
const char *start_scr;
int music;
int sball;
+ int vsync;
};
extern struct options opt;
--- /dev/null
+#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_ */
--- /dev/null
+#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__ */
+++ /dev/null
-/*
-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
- }
-}
+++ /dev/null
-#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_ */
#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);
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())) {
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);
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)
{
-/*
-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_
#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"
#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;
/* 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;
/* 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);
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;
/* 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);
}
}
}
-static void __interrupt __far kbintr()
+static void INTERRUPT kbintr()
{
unsigned char code;
int key, press;
#include <math.h>
#include <string.h>
#include <limits.h>
+#include <conio.h>
#include "demo.h"
#include "keyb.h"
#include "mouse.h"
#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);
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);
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) {
break_evloop:
set_text_mode();
demo_cleanup();
+#ifndef NOKEYB
kb_shutdown();
+#endif
if(use_sball) {
sball_shutdown();
}
{
/* 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();
+ }
}
}
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
mov x, cx
mov y, dx
}
+#endif
+#ifdef __DJGPP__
+ x = y = state = 0;
+#endif
if(xp) *xp = x;
if(yp) *yp = y;
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
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)
#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 {
#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);
#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);
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)
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]));
_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();
}
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;
-/*
-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);
#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);
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);
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 */
{
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++;
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);
}
}
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);
}
#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)
uint32_t oem_product_rev_ptr;
uint8_t reserved[222];
uint8_t oem_data[256];
-};
+} PACKED;
struct vbe_mode_info {
uint16_t mode_attr;
uint16_t reserved3;
uint8_t reserved4[206];
-};
+} PACKED;
#pragma pack (pop)
struct vbe_info *vbe_get_info(void);
--- /dev/null
+#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__ */
#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>