Make a global asm helper function to handle 32-bit RMCB calls, so we
don't need those complex constraints either.
This commit is contained in:
parent
a5bb5ea2c3
commit
3939b6d9dd
89
msdos/dpmi.c
89
msdos/dpmi.c
|
@ -183,6 +183,66 @@ static void INT_SetRealModeContext( REALMODECALL *call, CONTEXT86 *context )
|
|||
call->ss = SS_reg(context);
|
||||
}
|
||||
|
||||
void DPMI_CallRMCB32(RMCB *rmcb, UINT16 ss, DWORD esp, UINT16*es, DWORD*edi)
|
||||
#if 0 /* original code, which early gccs puke on */
|
||||
{
|
||||
int _clobber;
|
||||
__asm__ __volatile__(
|
||||
"pushl %%ebp\n"
|
||||
"pushl %%ebx\n"
|
||||
"pushl %%es\n"
|
||||
"pushl %%ds\n"
|
||||
"pushfl\n"
|
||||
"mov %7,%%es\n"
|
||||
"mov %5,%%ds\n"
|
||||
".byte 0x36, 0xff, 0x18\n" /* lcall *%ss:(%eax) */
|
||||
"popl %%ds\n"
|
||||
"mov %%es,%0\n"
|
||||
"popl %%es\n"
|
||||
"popl %%ebx\n"
|
||||
"popl %%ebp\n"
|
||||
: "=d" (*es), "=D" (*edi), "=S" (_clobber), "=a" (_clobber), "=c" (_clobber)
|
||||
: "0" (ss), "2" (esp),
|
||||
"4" (rmcb->regs_sel), "1" (rmcb->regs_ofs),
|
||||
"3" (&rmcb->proc_ofs) );
|
||||
}
|
||||
#else /* code generated by a gcc new enough */
|
||||
;
|
||||
__ASM_GLOBAL_FUNC(DPMI_CallRMCB32,
|
||||
"pushl %ebp\n\t"
|
||||
"movl %esp,%ebp\n\t"
|
||||
"subl $0x10,%esp\n\t"
|
||||
"pushl %edi\n\t"
|
||||
"pushl %esi\n\t"
|
||||
"movl 0x8(%ebp),%eax\n\t"
|
||||
"movl 0x10(%ebp),%esi\n\t"
|
||||
"movl 0xc(%ebp),%edx\n\t"
|
||||
"movl 0x10(%eax),%ecx\n\t"
|
||||
"movl 0xc(%eax),%edi\n\t"
|
||||
"addl $0x4,%eax\n\t"
|
||||
"movl %eax,-0x8(%ebp)\n\t"
|
||||
"pushl %ebp\n\t"
|
||||
"pushl %ebx\n\t"
|
||||
"pushl %es\n\t"
|
||||
"pushl %ds\n\t"
|
||||
"pushfl\n\t"
|
||||
"mov %cx,%es\n\t"
|
||||
"mov %dx,%ds\n\t"
|
||||
".byte 0x36, 0xff, 0x18\n\t" /* lcall *%ss:(%eax) */
|
||||
"popl %ds\n\t"
|
||||
"mov %es,%dx\n\t"
|
||||
"popl %es\n\t"
|
||||
"popl %ebx\n\t"
|
||||
"popl %ebp\n\t"
|
||||
"movl 0x14(%ebp),%eax\n\t"
|
||||
"movw %dx,(%eax)\n\t"
|
||||
"movl 0x18(%ebp),%edx\n\t"
|
||||
"movl %edi,(%edx)\n\t"
|
||||
"popl %esi\n\t"
|
||||
"popl %edi\n\t"
|
||||
"leave\n\t"
|
||||
"ret")
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* DPMI_CallRMCBProc
|
||||
|
@ -197,10 +257,11 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag )
|
|||
} else {
|
||||
#ifdef __i386__
|
||||
UINT16 ss,es;
|
||||
DWORD edi;
|
||||
DWORD esp,edi;
|
||||
|
||||
INT_SetRealModeContext((REALMODECALL *)PTR_SEG_OFF_TO_LIN( rmcb->regs_sel, rmcb->regs_ofs ), context);
|
||||
ss = SELECTOR_AllocBlock( DOSMEM_MemoryBase(0) + (DWORD)(SS_reg(context)<<4), 0x10000, SEGMENT_DATA, FALSE, FALSE );
|
||||
esp = ESP_reg(context);
|
||||
|
||||
FIXME("untested!\n");
|
||||
|
||||
|
@ -213,36 +274,18 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag )
|
|||
* real-mode call structure. */
|
||||
if (flag & 1) {
|
||||
/* 32-bit DPMI client */
|
||||
int _clobber;
|
||||
__asm__ __volatile__(
|
||||
"pushl %%ebp\n"
|
||||
"pushl %%ebx\n"
|
||||
"pushl %%es\n"
|
||||
"pushl %%ds\n"
|
||||
"pushfl\n"
|
||||
"mov %7,%%es\n"
|
||||
"mov %5,%%ds\n"
|
||||
".byte 0x36, 0xff, 0x18\n" /* lcall *%ss:(%eax) */
|
||||
"popl %%ds\n"
|
||||
"mov %%es,%0\n"
|
||||
"popl %%es\n"
|
||||
"popl %%ebx\n"
|
||||
"popl %%ebp\n"
|
||||
: "=d" (es), "=D" (edi), "=S" (_clobber), "=a" (_clobber), "=c" (_clobber)
|
||||
: "0" (ss), "2" (ESP_reg(context)),
|
||||
"4" (rmcb->regs_sel), "1" (rmcb->regs_ofs),
|
||||
"3" (&rmcb->proc_ofs) );
|
||||
DPMI_CallRMCB32(rmcb, ss, esp, &es, &edi);
|
||||
} else {
|
||||
/* 16-bit DPMI client */
|
||||
CONTEXT86 ctx = *context;
|
||||
CS_reg(&ctx) = rmcb->proc_sel;
|
||||
EIP_reg(&ctx) = rmcb->proc_ofs;
|
||||
DS_reg(&ctx) = ss;
|
||||
ESI_reg(&ctx) = ESP_reg(context);
|
||||
ESI_reg(&ctx) = esp;
|
||||
ES_reg(&ctx) = rmcb->regs_sel;
|
||||
EDI_reg(&ctx) = rmcb->regs_ofs;
|
||||
/* FIXME: I'm pretty sure this isn't right */
|
||||
Callbacks->CallRegisterShortProc(&ctx, 2);
|
||||
/* FIXME: I'm pretty sure this isn't right - should push flags first */
|
||||
Callbacks->CallRegisterShortProc(&ctx, 0);
|
||||
es = ES_reg(&ctx);
|
||||
edi = EDI_reg(&ctx);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue