summaryrefslogtreecommitdiffstats
path: root/private/mvdm/v86/scaffold/i386/softpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/v86/scaffold/i386/softpc.c')
-rw-r--r--private/mvdm/v86/scaffold/i386/softpc.c442
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;
+}