#include #include #include #include "dpmi.h" static uint16_t vbeDOSBufferDPMISelector = 0; /** * This is memory accessible to real-mode x86, so that * interrupts can access the data. */ void *dpmiAllocateDOSMemory(int size) { union REGS regs; // a paragraph is 16 bytes because why not unsigned short sizeParagraphs = (size + 15) >> 4UL; regs.w.ax = 0x0100; regs.w.bx = sizeParagraphs; int386(0x31, ®s, ®s); vbeDOSBufferDPMISelector = regs.w.dx; return (void *)(((unsigned long)regs.w.ax) << 4UL); } void dpmiDeallocateDOSMemory() { union REGS regs; regs.w.ax = 0x0101; regs.w.dx = vbeDOSBufferDPMISelector; int386(0x31, ®s, ®s); } /** * You only need to use this if you're passing a DPMI-allocated * memory struture to an interrupt via ES:DI. Otherwise, a * regular int386 call is sufficient. */ void dpmiInt(int interruptNo, struct dpmiRealModeRegs *rc) { union REGS regs; // call the DPMI real mode interrupt handler regs.w.ax = 0x0300; regs.w.bx = interruptNo; // real mode interrupt regs.w.cx = 0; // don't mess with our stack regs.x.edi = (unsigned int)rc; int386(0x31, ®s, ®s); }