/* DPMICALL.C Verschiedene DPMI Aufrufe Achtung: 16-Bit: LARGE 32-Bit: SMALL (linear executable) (c) 1996 Oliver Kraus kraus@lrs.e-technik.uni-erlangen.de */ #include "dpmicall.h" #ifdef C_DPMI #ifdef __WATCOMC__ #include #endif #include #include #include void DPMI_FAR *dpmi_get_dos_ptr(short selector) { #ifdef C_DPMI386 return MK_FP(selector,0); #else return (void DPMI_FAR *)(((unsigned long)selector)<<16); #endif } void dpmi_copy_to_dos(short selector, void *ptr, size_t len) { void DPMI_FAR *dest_ptr; dest_ptr = dpmi_get_dos_ptr(selector); #ifdef C_DPMI386 _fmemcpy(dest_ptr, ptr, len); #else memcpy(dest_ptr, ptr, len); #endif } void dpmi_copy_from_dos(short selector, void *ptr, size_t len) { void DPMI_FAR *src_ptr; src_ptr = dpmi_get_dos_ptr(selector); #ifdef C_DPMI386 _fmemcpy(ptr, src_ptr, len); #else memcpy(ptr, src_ptr, len); #endif } int dpmi_alloc_dos_memory(int size, short *selector, short *segment ) { #ifdef C_DPMI386 union REGS regs; struct SREGS sregs; memset(&sregs,0,sizeof(sregs)); regs.w.ax=0x0100; regs.w.bx=(unsigned short)((size+15)/16); int386x( 0x031, ®s, ®s, &sregs); if ( segment != NULL ) *segment=regs.w.ax; if ( selector != NULL ) *selector=regs.w.dx; return 1; #else union REGS regs; regs.x.ax=0x04800; regs.x.bx=(unsigned)((size+15)/16); int86( 0x021, ®s, ®s); if ( segment != NULL ) *segment=(short)(unsigned short)regs.x.ax; if ( selector != NULL ) *selector=(short)(unsigned short)regs.x.ax; return 1; #endif } int dpmi_free_dos_memory(short selector) { #ifdef C_DPMI386 union REGS regs; struct SREGS sregs; segread(&sregs); regs.w.ax=0x0101; regs.w.dx=(unsigned short)(selector); int386x( 0x031, ®s, ®s, &sregs); return 1; #else union REGS regs; struct SREGS sregs; segread(&sregs); regs.x.ax=0x04900; sregs.es=selector; int86x( 0x021, ®s, ®s, &sregs); return 1; #endif } unsigned dpmi_simulate_rmi(int int_no, rminfo_struct *rmi) { #ifdef C_DPMI386 union REGS regs; struct SREGS sregs; /* stack soll vom host bereitgestellt werden */ rmi->sp = 0; rmi->ss = 0; rmi->ip = 0; rmi->cs = 0; segread(&sregs); regs.w.ax = 0x0300; regs.h.bl = int_no; regs.h.bh = 0; regs.w.cx = 0; sregs.es = FP_SEG(rmi); regs.x.edi = FP_OFF(rmi); int386x( 0x31, ®s, ®s, &sregs ); return rmi->flags & 1; #else union REGS regs; struct SREGS sregs; segread(&sregs); regs.x.ax = (unsigned)rmi->eax; regs.x.bx = (unsigned)rmi->ebx; regs.x.cx = (unsigned)rmi->ecx; regs.x.dx = (unsigned)rmi->edx; regs.x.di = (unsigned)rmi->edi; regs.x.si = (unsigned)rmi->esi; sregs.es = rmi->es; sregs.ds = rmi->ds; int86x( int_no, ®s, ®s, &sregs ); rmi->es = (short)(unsigned short)sregs.es; rmi->ds = (short)(unsigned short)sregs.ds; rmi->eax = (long)(unsigned long)regs.x.ax; rmi->ebx = (long)(unsigned long)regs.x.bx; rmi->ecx = (long)(unsigned long)regs.x.cx; rmi->edx = (long)(unsigned long)regs.x.dx; rmi->edi = (long)(unsigned long)regs.x.di; rmi->esi = (long)(unsigned long)regs.x.si; return regs.x.cflag & 1; #endif } #ifdef dpmicall_main void main(void) { char *s = "Hello DPMI!$"; rminfo_struct rmi; short selector, segment; dpmi_alloc_dos_memory(strlen(s)+1, &selector, &segment ); dpmi_copy_to_dos(selector, s, strlen(s)+1); rmi.eax = 0x0900; rmi.ds = segment; rmi.edx = 0; dpmi_simulate_rmi(0x021, &rmi); dpmi_free_dos_memory(selector ); rmi.eax = 0x03000; dpmi_simulate_rmi(0x021, &rmi); printf("\nDOS Version: %d.%d\n", (int)(rmi.eax&255), (int)((rmi.eax>>8)&255)); } #endif #endif /* C_DPMI */