/* * VxD emulation * * Copyright 1995 Anand Kumria */ #include "windows.h" #include "msdos.h" #include "miscemu.h" #include "debug.h" #define VXD_BARF(context,name) \ DUMP( "vxd %s: unknown/not implemented parameters:\n" \ "vxd %s: AX %04x, BX %04x, CX %04x, DX %04x, " \ "SI %04x, DI %04x, DS %04x, ES %04x\n", \ (name), (name), AX_reg(context), BX_reg(context), \ CX_reg(context), DX_reg(context), SI_reg(context), \ DI_reg(context), (WORD)DS_reg(context), (WORD)ES_reg(context) ) static WORD VXD_WinVersion(void) { WORD version = LOWORD(GetVersion16()); return (version >> 8) | (version << 8); } /*********************************************************************** * VXD_PageFile */ void WINAPI VXD_PageFile( CONTEXT *context ) { unsigned service = AX_reg(context); /* taken from Ralf Brown's Interrupt List */ TRACE(vxd,"[%04x] PageFile\n", (UINT16)service ); switch(service) { case 0x00: /* get version, is this windows version? */ TRACE(vxd,"returning version\n"); AX_reg(context) = VXD_WinVersion(); RESET_CFLAG(context); break; case 0x01: /* get swap file info */ TRACE(vxd,"VxD PageFile: returning swap file info\n"); AX_reg(context) = 0x00; /* paging disabled */ ECX_reg(context) = 0; /* maximum size of paging file */ /* FIXME: do I touch DS:SI or DS:DI? */ RESET_CFLAG(context); break; case 0x02: /* delete permanent swap on exit */ TRACE(vxd,"VxD PageFile: supposed to delete swap\n"); RESET_CFLAG(context); break; case 0x03: /* current temporary swap file size */ TRACE(vxd,"VxD PageFile: what is current temp. swap size\n"); RESET_CFLAG(context); break; case 0x04: /* read or write?? INTERRUP.D */ case 0x05: /* cancel?? INTERRUP.D */ case 0x06: /* test I/O valid INTERRUP.D */ default: VXD_BARF( context, "pagefile" ); break; } } /*********************************************************************** * VXD_Shell */ void WINAPI VXD_Shell( CONTEXT *context ) { unsigned service = DX_reg(context); TRACE(vxd,"[%04x] Shell\n", (UINT16)service); switch (service) /* Ralf Brown says EDX, but I use DX instead */ { case 0x0000: TRACE(vxd,"returning version\n"); AX_reg(context) = VXD_WinVersion(); EBX_reg(context) = 1; /* system VM Handle */ break; case 0x0001: case 0x0002: case 0x0003: case 0x0004: case 0x0005: TRACE(vxd,"VxD Shell: EDX = %08lx\n",EDX_reg(context)); VXD_BARF( context, "shell" ); break; case 0x0006: /* SHELL_Get_VM_State */ TRACE(vxd,"VxD Shell: returning VM state\n"); /* Actually we don't, not yet. We have to return a structure * and I am not to sure how to set it up and return it yet, * so for now let's do nothing. I can (hopefully) get this * by the next release */ /* RESET_CFLAG(context); */ break; case 0x0007: case 0x0008: case 0x0009: case 0x000A: case 0x000B: case 0x000C: case 0x000D: case 0x000E: case 0x000F: case 0x0010: case 0x0011: case 0x0012: case 0x0013: case 0x0014: case 0x0015: case 0x0016: default: TRACE(vxd,"VxD Shell: EDX = %08lx\n",EDX_reg(context)); VXD_BARF( context, "shell"); break; } } /*********************************************************************** * VXD_Comm */ void WINAPI VXD_Comm( CONTEXT *context ) { unsigned service = AX_reg(context); TRACE(vxd,"[%04x] Comm\n", (UINT16)service); switch (service) { case 0x0000: /* get version */ TRACE(vxd,"returning version\n"); AX_reg(context) = VXD_WinVersion(); RESET_CFLAG(context); break; case 0x0001: /* set port global */ case 0x0002: /* get focus */ case 0x0003: /* virtualise port */ default: VXD_BARF( context, "comm" ); } } /*********************************************************************** * VXD_Timer */ void VXD_Timer( CONTEXT *context ) { unsigned service = AX_reg(context); TRACE(vxd,"[%04x] Virtual Timer\n", (UINT16)service); switch(service) { case 0x0000: /* version */ AX_reg(context) = VXD_WinVersion(); RESET_CFLAG(context); break; case 0x0100: /* clock tick time, in 840nsecs */ EAX_reg(context) = GetTickCount(); EDX_reg(context) = EAX_reg(context) >> 22; EAX_reg(context) <<= 10; /* not very precise */ break; case 0x0101: /* current Windows time, msecs */ case 0x0102: /* current VM time, msecs */ EAX_reg(context) = GetTickCount(); break; default: VXD_BARF( context, "VTD" ); } }