diff options
Diffstat (limited to 'private/mvdm/v86/scaffold/i386/softpc.c')
-rw-r--r-- | private/mvdm/v86/scaffold/i386/softpc.c | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/private/mvdm/v86/scaffold/i386/softpc.c b/private/mvdm/v86/scaffold/i386/softpc.c new file mode 100644 index 000000000..b97ee53a9 --- /dev/null +++ b/private/mvdm/v86/scaffold/i386/softpc.c @@ -0,0 +1,442 @@ +#include <windows.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <malloc.h> +#include <ctype.h> +#include "demexp.h" +#include "softpc.h" +#include <cmdsvc.h> +#include <xmssvc.h> +#include <dbgexp.h> +#include "xwincon.h" +#include "fun.h" +#include <conapi.h> + +#define VDM_VIRTUAL_INTERRUPTS 0x00000200L +extern CONTEXT IntelRegisters; + +VOID DumpIntelRegs(); +VOID ParseSwitches( int, char**); +VOID usage(); +BOOL ConInit (VOID); +extern VOID VDMCtrlCHandler(ULONG); + +INT flOptions; + +HANDLE OutputHandle; +HANDLE InputHandle; +HANDLE SCSCreateEvent; +char *EmDirectory; +BOOL scaffMin = FALSE; +BOOL scaffWow = FALSE; +BOOL VDMForWOW = FALSE; +CHAR BootLetter; + + +void main (argc, argv) +int argc; +char *argv[]; +{ + + PSZ psz,pszNULL; + HANDLE hfile; + DWORD BytesRead; + int i; + PCHAR FileAddress; + BOOL IsFirst; + int temp_argc = argc; + char **temp_argv = argv; + +// DebugBreak(); + + if(SetConsoleCtrlHandler((PHANDLER_ROUTINE)VDMCtrlCHandler,TRUE) + == FALSE) { + VDprint( + VDP_LEVEL_INFO, + ("CtrlC Handler Could'nt be installed\n") + ); + } + + // Tell the console that we want the last event (i.e when the + // window is just to be destroyed. + SetLastConsoleEventActive(); + + // Check if the VDM Is for WOW + while (--temp_argc > 0) { + psz = *++temp_argv; + if (*psz == '-' || *psz == '/') { + psz++; + if(tolower(*psz) == 'w'){ + VDMForWOW = TRUE; + break; + } + } + } + + // This following API is required for recovery purposes. This + // tells the basesrv that VDM has hooked ctrlc event. After + // this it will always get the termination notification. If + // the window is killed before we hook ctrl-c then basesrv + // will know that data structures for this VDM has to be + // freed. This should be the first call to base.dll. + + VDMOperationStarted (VDMForWOW); + + EmDirectory = NULL; + + // Hide the cmd window of WOWVDM + if(VDMForWOW) + VDMConsoleOperation((DWORD)VDM_HIDE_WINDOW); + + ParseSwitches( argc, argv ); + + IsFirst = GetNextVDMCommand(NULL); + + for (i = 0; i < argc; i++) { + VDprint( + VDP_LEVEL_INFO, + ("%s\n", argv[i]) + ); + } + + VDbreak(VDB_LEVEL_INFO); + + if (EmDirectory == NULL) { + usage(); + TerminateVDM(); + } + + // Sudeepb 26-Dec-1991 Temporary code to make + // the life easy for WOW's internal users such that they dont have + // to change the config.sys as per their setup. + + FixConfigFile (EmDirectory,IsFirst); + + pszNULL = strchr(EmDirectory,'\0'); + psz = EmDirectory; + while(*psz == ' ' || *psz == '\t') + psz++; + + BootLetter = *psz; + + host_cpu_init(); + sas_init(1024L * 1024L + 64L * 1024L); + + // Initialize ROM support + + BiosInit(argc, argv); + + // Initialize console support + + if (!ConInit()) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: error initializing console\n") + ); + TerminateVDM(); + } + + // Initialize WOW + + + CMDInit (argc,argv); + + // Initialize DOSEm + + if(!DemInit (argc,argv,EmDirectory)) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: error initializing DOSEm\n") + ); + TerminateVDM(); + } + + // Initialize XMS + + if(!XMSInit (argc,argv)) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: error initializing XMS\n") + ); + TerminateVDM(); + } + + // Initialize DBG + + if(!DBGInit (argc,argv)) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: error initializing DBG\n") + ); + TerminateVDM(); + } + + // Prepare to load ntio.sys + strcat (EmDirectory,"\\ntio.sys"); + hfile = CreateFile(EmDirectory, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if (hfile == (HANDLE)0xffffffff) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: could not open file %s. Error %d\n", + EmDirectory, + GetLastError()) + ); + TerminateVDM(); + } + + FileAddress = (PCHAR)0x700; + BytesRead = 1; + while (BytesRead) { + if (!ReadFile(hfile, FileAddress, 16384, &BytesRead, NULL)) { + VDprint( + VDP_LEVEL_ERROR, + ("SoftPC: read failure on file %s. Error %d\n", + EmDirectory, + GetLastError()) + ); + TerminateVDM(); + } + + VDprint(VDP_LEVEL_INFO, + ("SoftPC: read a block of file %s\n", + EmDirectory) + ); + FileAddress = (PCHAR)FileAddress + BytesRead; + } + + VDprint(VDP_LEVEL_WARNING, + ("SoftPC: using Emulation file %s\n", + EmDirectory) + ); + + VDbreak(VDB_LEVEL_INFO); + + CloseHandle (hfile); + + // restore the emulation directory + *pszNULL = 0; + + + IntelRegisters.Eip = 0x0; + IntelRegisters.SegCs = 0x70; + IntelRegisters.EFlags = VDM_VIRTUAL_INTERRUPTS; + + host_simulate(); + + if (IntelRegisters.EFlags & VDM_VIRTUAL_INTERRUPTS) { + VDprint(VDP_LEVEL_INFO, ("Virtual ints enabled\n")); + } else { + VDprint(VDP_LEVEL_INFO, ("Virtual ints disabled\n")); + } + + DumpIntelRegs(); +} + +#define MAX_CONFIG_SIZE 1024 + +VOID FixConfigFile (pszBin86Dir,IsFirstVDM) +PSZ pszBin86Dir; +BOOL IsFirstVDM; +{ + + // Temporary code. To be thrown out once we have full configuration + // and installation. + +CHAR ConfigFile[]="?:\\config.vdm"; +CHAR Buffer [MAX_CONFIG_SIZE]; +DWORD len,i; +DWORD BytesRead,BytesWritten; +HANDLE hfile; + + if (IsFirstVDM == FALSE) + return; + + ConfigFile[0] = *pszBin86Dir; + hfile = CreateFile( ConfigFile, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + if (hfile == (HANDLE)0xffffffff) { + DbgPrint ("config.vdm is'nt found on the root drive of yout NT trre\n"); + return; + } + + + if (!ReadFile(hfile, Buffer, MAX_CONFIG_SIZE, &BytesRead, NULL)){ + DbgPrint ("config.vdm could'nt be read\n, %x\n",GetLastError ()); + CloseHandle (hfile); + return; + } + + if (BytesRead == MAX_CONFIG_SIZE) { + DbgPrint ("config.vdm is too big, could'nt perform macro substitution\n"); + CloseHandle (hfile); + return; + } + + SetFilePointer (hfile, + 0, + NULL, + FILE_BEGIN); + + len = strlen (pszBin86Dir); + + for (i=0; i < BytesRead; i++) { + if (Buffer [i] != '@'){ + WriteFile (hfile, + &Buffer[i], + 1, + &BytesWritten, + NULL); + } + else { + WriteFile (hfile, + pszBin86Dir, + len, + &BytesWritten, + NULL); + } + } + + CloseHandle (hfile); + return; +} + +VOID DumpIntelRegs() +{ + + VDprint(VDP_LEVEL_ERROR,("EAX = %lx\n",IntelRegisters.Eax)); + VDprint(VDP_LEVEL_ERROR,("Ebx = %lx\n",IntelRegisters.Ebx)); + VDprint(VDP_LEVEL_ERROR,("Ecx = %lx\n",IntelRegisters.Ecx)); + VDprint(VDP_LEVEL_ERROR,("Edx = %lx\n",IntelRegisters.Edx)); + VDprint(VDP_LEVEL_ERROR,("Esi = %lx\n",IntelRegisters.Esi)); + VDprint(VDP_LEVEL_ERROR,("Edi = %lx\n",IntelRegisters.Edi)); + VDprint(VDP_LEVEL_ERROR,("Ebp = %lx\n",IntelRegisters.Ebp)); + VDprint(VDP_LEVEL_ERROR,("SegDs = %lx\n",IntelRegisters.SegDs)); + VDprint(VDP_LEVEL_ERROR,("SegEs = %lx\n",IntelRegisters.SegEs)); + VDprint(VDP_LEVEL_ERROR,("SegFs = %lx\n",IntelRegisters.SegFs)); + VDprint(VDP_LEVEL_ERROR,("SegGs = %lx\n",IntelRegisters.SegGs)); + VDprint(VDP_LEVEL_ERROR,("EFlags = %lx\n",IntelRegisters.EFlags)); + VDprint(VDP_LEVEL_ERROR,("SS:Esp = %lx:",IntelRegisters.SegSs)); + VDprint(VDP_LEVEL_ERROR,("%lx\n",IntelRegisters.Esp)); + VDprint(VDP_LEVEL_ERROR,("CS:Eip = %lx:",IntelRegisters.SegCs)); + VDprint(VDP_LEVEL_ERROR,("%lx\n",IntelRegisters.Eip)); +} + +VOID ParseSwitches( + int argc, + char **argv + ) +{ + int i; + + for (i = 1; i < argc; i++){ + if ((argv[i][0] == '-') || (argv[i][0] == '/')) { + + switch (argv[i][1]) { + + case 's' : + case 'S' : + sscanf(&argv[i][2], "%x", &VdmDebugLevel); + VDprint( + VDP_LEVEL_WARNING, + ("VdmDebugLevel = %x\n", + VdmDebugLevel) + ); + break; + + case 'f' : + case 'F' : + // Note this memory is freed by DEM. + if((EmDirectory = (PCHAR)malloc (strlen (&argv[i][2]) + + 1 + + sizeof("\\ntdos.sys") + + 1 + )) == NULL){ + DbgPrint("SoftPC: Not Enough Memory \n"); + TerminateVDM(); + } + strcpy(EmDirectory,&argv[i][2]); + break; + + case 't' : + case 'T' : + flOptions |= OPT_TERMINAL; + break; + case 'm' : + case 'M' : + scaffMin = TRUE; + break; + case 'w' : + case 'W' : + scaffWow = TRUE; + } + } else { + break; + } + } +} + +VOID usage() +{ + DbgPrint("SoftPC Usage: softpc -F<emulation file> [-D#] [<drive>:=<virtual disk>] [dos command line]\n"); +} + + +VOID TerminateVDM(void) +{ + + if(VDMForWOW) + // Kill everything for WOW VDM + ExitVDM(VDMForWOW,(ULONG)-1); + else + ExitVDM(FALSE,0); + ExitProcess (0); +} + + +DWORD SCSConsoleThread(LPVOID lp) +{ + + + SetEvent(SCSCreateEvent); + BiosKbdReadLoop(); + return TRUE; +} + + +BOOL ConInit (VOID) +{ + DWORD SCSThreadId; + HANDLE InputThread; + OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + InputHandle = GetStdHandle(STD_INPUT_HANDLE); + + SCSCreateEvent = CreateEvent( NULL, TRUE, FALSE,NULL ); + + InputThread = CreateThread( + (LPSECURITY_ATTRIBUTES)0, + 8192, + (LPTHREAD_START_ROUTINE)SCSConsoleThread, + (LPVOID)0, + STANDARD_RIGHTS_REQUIRED, + &SCSThreadId + ); + + WaitForSingleObject(SCSCreateEvent, -1); + + CloseHandle(SCSCreateEvent); + + return TRUE; +} |