correct window size in banked vbe, and added doublebuffered test
[vidsys] / cdpmi.c
1 #include <stdio.h>
2 #include <i86.h>
3 #include "cdpmi.h"
4
5 #define LOWBUF_SIZE             8192
6 #define RMSTACK_SIZE    4096
7
8 static char *lowbuf, *lowfree;
9 static uint16_t lowbuf_sel, lowbuf_seg;
10
11 int dpmi_init(void)
12 {
13         if(!(lowbuf_seg = dpmi_alloc(LOWBUF_SIZE >> 4, &lowbuf_sel))) {
14                 fprintf(stderr, "DPMI init failed to allocate low memory buffer\n");
15                 return -1;
16         }
17         lowbuf = (char*)((intptr_t)lowbuf_seg << 4);
18         lowfree = lowbuf + RMSTACK_SIZE;
19         return 0;
20 }
21
22 void dpmi_cleanup(void)
23 {
24         if(!lowbuf_sel) return;
25         dpmi_free(lowbuf_sel);
26         lowbuf = 0;
27         lowbuf_sel = 0;
28         lowbuf_seg = 0;
29 }
30
31 void *dpmi_lowbuf(void)
32 {
33         return lowfree;
34 }
35
36 uint16_t dpmi_alloc(unsigned int par, uint16_t *sel)
37 {
38         union REGS regs = {0};
39
40         regs.w.ax = 0x100;
41         regs.w.bx = par;
42         int386(0x31, &regs, &regs);
43         if(regs.w.cflag != 0) {
44                 return 0;
45         }
46         *sel = regs.w.dx;
47         return regs.w.ax;
48 }
49
50 void dpmi_free(uint16_t sel)
51 {
52         union REGS regs = {0};
53
54         regs.w.ax = 0x101;
55         regs.w.dx = sel;
56         int386(0x31, &regs, &regs);
57 }
58
59 int dpmi_rmint(int inum, struct dpmi_regs *dregs)
60 {
61         union REGS regs = {0};
62         struct SREGS sregs = {0};
63
64         regs.x.eax = 0x300;
65         regs.x.ebx = inum;
66         sregs.es = FP_SEG(dregs);
67         regs.x.edi = FP_OFF(dregs);
68         sregs.ss = lowbuf_seg;  /* 4k real mode stack */
69         int386x(0x31, &regs, &regs, &sregs);
70         if(regs.x.cflag != 0) {
71                 return -1;
72         }
73         return 0;
74 }
75
76 void *dpmi_mmap(uint32_t phys_addr, unsigned int size)
77 {
78         union REGS regs = {0};
79
80         regs.w.ax = 0x800;
81         regs.w.bx = phys_addr >> 16;
82         regs.w.cx = phys_addr & 0xffff;
83         regs.w.si = size >> 16;
84         regs.w.di = size & 0xffff;
85         int386(0x31, &regs, &regs);
86         if(regs.w.cflag != 0) {
87                 return 0;
88         }
89
90         return (void*)(((intptr_t)regs.w.bx << 16) | (intptr_t)regs.w.cx);
91 }
92
93 void dpmi_munmap(void *ptr)
94 {
95         union REGS regs = {0};
96         intptr_t addr = (intptr_t)ptr;
97
98         regs.w.ax = 0x801;
99         regs.w.bx = addr >> 16;
100         regs.w.cx = addr & 0xffff;
101         int386(0x31, &regs, &regs);
102 }