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