home *** CD-ROM | disk | FTP | other *** search
- /*
-
- 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 <i86.h>
- #endif
-
- #include <dos.h>
- #include <stdio.h>
- #include <string.h>
-
- 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 */
-