4 * Copyright 1998 Ove Kåven
6 * This code hasn't been completely cleaned up yet.
16 #include <sys/types.h>
35 static void DOSVM_Dump( LPDOSTASK lpDosTask
, int fn
,
36 struct vm86plus_struct
*VM86
)
42 switch (VM86_TYPE(fn
)) {
44 printf("Trapped signal\n"); break;
46 printf("Trapped unhandled GPF\n"); break;
48 printf("Trapped INT %02x\n",VM86_ARG(fn
)); break;
50 printf("Trapped STI\n"); break;
52 printf("Trapped due to pending PIC request\n"); break;
54 printf("Trapped debug request\n"); break;
56 #define REGS VM86->regs
57 fprintf(stderr
,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS
.eax
,REGS
.ebx
,REGS
.ecx
,REGS
.edx
);
58 fprintf(stderr
,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS
.esi
,REGS
.edi
,REGS
.esp
,REGS
.ebp
);
59 fprintf(stderr
,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS
.cs
,REGS
.ds
,REGS
.es
,REGS
.ss
);
60 fprintf(stderr
,"EIP=%04lX EFLAGS=%08lX\n",REGS
.eip
,REGS
.eflags
);
62 iofs
=((DWORD
)REGS
.cs
<<4)+REGS
.eip
;
64 inst
=(BYTE
*)lpDosTask
->img
+iofs
;
66 for (x
=0; x
<8; x
++) printf(" %02x",inst
[x
]);
72 static int DOSVM_Int(int vect
, PCONTEXT context
)
74 /* moved to INT_RealModeInterrupt in msdos/interrupts.c */
75 INT_RealModeInterrupt(vect
,context
);
79 #define CV CP(eax,Eax); CP(ecx,Ecx); CP(edx,Edx); CP(ebx,Ebx); \
80 CP(esi,Esi); CP(edi,Edi); CP(esp,Esp); CP(ebp,Ebp); \
81 CP(cs,SegCs); CP(ds,SegDs); CP(es,SegEs); \
82 CP(ss,SegSs); CP(fs,SegFs); CP(gs,SegGs); \
83 CP(eip,Eip); CP(eflags,EFlags)
85 static int DOSVM_Process( LPDOSTASK lpDosTask
, int fn
,
86 struct vm86plus_struct
*VM86
)
91 #define CP(x,y) context.y = VM86->regs.x
94 (void*)V86BASE(&context
)=lpDosTask
->img
;
96 switch (VM86_TYPE(fn
)) {
98 printf("Trapped signal\n");
100 case VM86_UNKNOWN
: /* unhandled GPF */
101 DOSVM_Dump(lpDosTask
,fn
,VM86
);
102 ctx_debug(SIGSEGV
,&context
);
105 TRACE(int,"DOS EXE calls INT %02x with AX=%04lx\n",VM86_ARG(fn
),context
.Eax
);
106 ret
=DOSVM_Int(VM86_ARG(fn
),&context
); break;
110 printf("Trapped due to pending PIC request\n"); break;
112 ctx_debug(SIGTRAP
,&context
);
115 DOSVM_Dump(lpDosTask
,fn
,VM86
);
118 #define CP(x,y) VM86->regs.x = context.y
124 int DOSVM_Enter( PCONTEXT context
)
126 TDB
*pTask
= (TDB
*)GlobalLock16( GetCurrentTask() );
127 NE_MODULE
*pModule
= NE_GetPtr( pTask
->hModule
);
129 struct vm86plus_struct VM86
;
132 GlobalUnlock16( GetCurrentTask() );
134 ERR(module
,"No task is currently active!\n");
137 if (!pModule
->lpDosTask
) {
138 /* no VM86 (dosmod) task is currently running, start one */
139 if ((lpDosTask
= calloc(1, sizeof(DOSTASK
))) == NULL
)
141 lpDosTask
->hModule
=pModule
->self
;
142 stat
=MZ_InitMemory(lpDosTask
,pModule
);
143 if (stat
>=32) stat
=MZ_InitTask(lpDosTask
);
148 pModule
->lpDosTask
= lpDosTask
;
149 pModule
->dos_image
= lpDosTask
->img
;
150 /* Note: we're leaving it running after this, in case we need it again,
151 as this minimizes the overhead of starting it up every time...
152 it will be killed automatically when the current task terminates */
153 } else lpDosTask
=pModule
->lpDosTask
;
156 #define CP(x,y) VM86.regs.x = context->y
161 memset(&VM86
,0,sizeof(VM86
));
162 VM86
.regs
.cs
=lpDosTask
->init_cs
;
163 VM86
.regs
.eip
=lpDosTask
->init_ip
;
164 VM86
.regs
.ss
=lpDosTask
->init_ss
;
165 VM86
.regs
.esp
=lpDosTask
->init_sp
;
166 VM86
.regs
.ds
=lpDosTask
->psp_seg
;
167 VM86
.regs
.es
=lpDosTask
->psp_seg
;
168 /* hmm, what else do we need? */
171 /* main exchange loop */
174 /* transmit VM86 structure to dosmod task */
175 if (write(lpDosTask
->write_pipe
,&stat
,sizeof(stat
))!=sizeof(stat
))
177 if (write(lpDosTask
->write_pipe
,&VM86
,sizeof(VM86
))!=sizeof(VM86
))
179 /* wait for response */
181 if (read(lpDosTask
->read_pipe
,&stat
,sizeof(stat
))!=sizeof(stat
)) {
182 if ((errno
==EINTR
)||(errno
==EAGAIN
)) continue;
187 if (read(lpDosTask
->read_pipe
,&VM86
,sizeof(VM86
))!=sizeof(VM86
)) {
188 if ((errno
==EINTR
)||(errno
==EAGAIN
)) continue;
193 } while (DOSVM_Process(lpDosTask
,stat
,&VM86
)>=0);
196 #define CP(x,y) context->y = VM86.regs.x
203 #else /* !MZ_SUPPORTED */
205 int DOSVM_Enter( PCONTEXT context
)
207 ERR(module
,"DOS realmode not supported on this architecture!\n");