119 lines
3.1 KiB
C
119 lines
3.1 KiB
C
/*
|
|
* DOS Virtual Machine
|
|
*
|
|
* Copyright 1998 Ove Kåven
|
|
*/
|
|
|
|
#ifdef linux
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include "windows.h"
|
|
#include "winbase.h"
|
|
#include "msdos.h"
|
|
#include "miscemu.h"
|
|
#include "debug.h"
|
|
#include "module.h"
|
|
#include "ldt.h"
|
|
#include "dosexe.h"
|
|
|
|
void DOSVM_Dump( LPDOSTASK lpDosTask)
|
|
{
|
|
unsigned iofs;
|
|
BYTE*inst;
|
|
int x;
|
|
|
|
switch (VM86_TYPE(lpDosTask->fn)) {
|
|
case VM86_SIGNAL:
|
|
printf("Trapped signal\n"); break;
|
|
case VM86_UNKNOWN:
|
|
printf("Trapped unhandled GPF\n"); break;
|
|
case VM86_INTx:
|
|
printf("Trapped INT %02x\n",VM86_ARG(lpDosTask->fn)); break;
|
|
case VM86_STI:
|
|
printf("Trapped STI\n"); break;
|
|
case VM86_PICRETURN:
|
|
printf("Trapped due to pending PIC request\n"); break;
|
|
case VM86_TRAP:
|
|
printf("Trapped debug request\n"); break;
|
|
}
|
|
#define REGS lpDosTask->VM86.regs
|
|
fprintf(stderr,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS.eax,REGS.ebx,REGS.ecx,REGS.edx);
|
|
fprintf(stderr,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS.esi,REGS.edi,REGS.esp,REGS.ebp);
|
|
fprintf(stderr,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS.cs,REGS.ds,REGS.es,REGS.ss);
|
|
|
|
iofs=((DWORD)REGS.cs<<4)+REGS.eip;
|
|
#undef REGS
|
|
inst=(BYTE*)lpDosTask->img+iofs;
|
|
printf("Opcodes:");
|
|
for (x=0; x<8; x++) printf(" %02x",inst[x]);
|
|
printf("\n");
|
|
|
|
exit(0);
|
|
}
|
|
|
|
int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context )
|
|
{
|
|
switch (vect) {
|
|
case 0x20:
|
|
return -1;
|
|
case 0x21:
|
|
if (AH_reg(context)==0x4c) return -1;
|
|
DOS3Call(context);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DOSVM_Process( LPDOSTASK lpDosTask )
|
|
{
|
|
CONTEXT context;
|
|
int ret=0;
|
|
|
|
#define REGS lpDosTask->VM86.regs
|
|
context.Eax=REGS.eax; context.Ecx=REGS.ecx; context.Edx=REGS.edx; context.Ebx=REGS.ebx;
|
|
context.Esi=REGS.esi; context.Edi=REGS.edi; context.Esp=REGS.esp; context.Ebp=REGS.ebp;
|
|
context.SegCs=REGS.cs; context.SegDs=REGS.ds; context.SegEs=REGS.es;
|
|
context.SegSs=REGS.ss; context.SegFs=REGS.fs; context.SegGs=REGS.gs;
|
|
context.Eip=REGS.eip; context.EFlags=REGS.eflags;
|
|
(void*)V86BASE(&context)=lpDosTask->img;
|
|
|
|
switch (VM86_TYPE(lpDosTask->fn)) {
|
|
case VM86_SIGNAL:
|
|
printf("Trapped signal\n");
|
|
ret=-1; break;
|
|
case VM86_UNKNOWN:
|
|
DOSVM_Dump(lpDosTask);
|
|
break;
|
|
case VM86_INTx:
|
|
TRACE(int,"DOS EXE calls INT %02x\n",VM86_ARG(lpDosTask->fn));
|
|
ret=DOSVM_Int(VM86_ARG(lpDosTask->fn),lpDosTask,&context); break;
|
|
case VM86_STI:
|
|
break;
|
|
case VM86_PICRETURN:
|
|
printf("Trapped due to pending PIC request\n"); break;
|
|
case VM86_TRAP:
|
|
printf("Trapped debug request\n"); break;
|
|
default:
|
|
DOSVM_Dump(lpDosTask);
|
|
}
|
|
|
|
lpDosTask->fn=VM86_ENTER;
|
|
REGS.eax=context.Eax; REGS.ecx=context.Ecx; REGS.edx=context.Edx; REGS.ebx=context.Ebx;
|
|
REGS.esi=context.Esi; REGS.edi=context.Edi; REGS.esp=context.Esp; REGS.ebp=context.Ebp;
|
|
REGS.cs=context.SegCs; REGS.ds=context.SegDs; REGS.es=context.SegEs;
|
|
REGS.ss=context.SegSs; REGS.fs=context.SegFs; REGS.gs=context.SegGs;
|
|
REGS.eip=context.Eip; REGS.eflags=context.EFlags;
|
|
#undef REGS
|
|
return ret;
|
|
}
|
|
|
|
#endif /* linux */
|