/* copro struct */ #define i_orgeip _info #define i_retsys _info+4 #define i_ebx _info+8 #define i_ecx _info+12 #define i_edx _info+16 #define i_esi _info+20 #define i_edi _info+24 #define i_ebp _info+28 #define i_eax _info+32 #define i_ds _info+36 #define i_es _info+40 #define i_fs _info+44 #define i_gs _info+48 #define i_orgeax _info+52 #define i_eip _info+56 #define i_cs _info+60 #define i_eflags _info+64 #define i_esp _info+68 #define i_ss _info+72 #define i_vm86_es _info+76 #define i_vm86_ds _info+80 #define i_vm86_fs _info+84 #define i_vm86_gs _info+88 .globl _fpu_entry .globl _back_to_prg .globl _debugged .globl _used_math .globl _raise .text /* called from extender: 1. init exception ; 2. change mathe state */ /* gs = emu data seg */ _fpu_entry: cmpl $0x12345678,%eax /* init call ? */ jz L10 movl %edx, %gs:_debugged /* debugged>0 : don't lookahead */ movl %ecx, %gs:_used_math /* used_math>0: don't init */ lret /* ! can't use movl %eax,gs:xx (bug ??) */ _emu_selector: .long 0 .align 2,144 /* init exception vector 7 */ L10: movw %gs, %cx movw %cx, %gs:_emu_selector /* save dataseg in code */ movw %edx, %gs:emu_esp /* save dataseg in code */ movw %cs,%cx /* cx:edx exception-handler */ movl $_exception7,%edx movw $0x203,%ax movw $0x7,%bx /* 387 exception */ int $0x31 jnc 1f movl $0,%eax /* 0 = error */ jmp 2f 1: movl $_copro , %eax /* return coprostruct */ 2: lret /* stack after exception : * * 0 = DPMIeip, * 4 = DPMIcs, * 8 = error code, * 12 = eip, * 16 = cs, * 20 = eflags, * 24 = esp, * 28 = ss */ #define EIP 12 #define CS 16 #define EFLAGS 20 #define ESP 24 #define SS 28 /* entry for emulation : ** ds,es,fs,gs = user_prg_ds ** stack = dpmi-server ss,esp */ .align 2,144 _exception7: pushl %cs:_emu_selector /* load datasegment */ popl %ds movw %es, i_ds movw %es, i_es movw %fs, i_fs movl %eax, i_eax movl %eax, i_orgeax movl %ebx, i_ebx movl %ecx, i_ecx movl %edx, i_edx movl %esi, i_esi movl %edi, i_edi movl %ebp, i_ebp /* save regs on dpmi stack */ movl EIP(%esp), %eax movl %eax, i_orgeip movl %eax, i_eip movl CS(%esp), %eax movl %eax, i_cs movl EFLAGS(%esp), %eax andl $0xFFFEFFFF,%eax /* clear resume flag */ movl %eax, i_eflags andl $0xFFFFFEFF,%eax /* clear step flag */ orl $0x200,%eax /* set iflag */ movl %eax, EFLAGS(%esp) /* save back */ movl ESP(%esp), %eax movl %eax, i_esp movl SS(%esp), %eax movl %eax, i_ss /* prepare stack frame for lret */ movw %ds, %ax movw %ax, SS(%esp) movl emu_esp, %eax movl %eax, ESP(%esp) movw %cs, %ax movw %ax, CS(%esp) movl $emulate, %eax movl %eax, EIP(%esp) /* resore eax (not necessary?) */ movl i_eax, %eax pushl %es popl %ds lret /* back to dpmi-handler */ /* jmp to our handler cs:emulate */ /* called from DPMI-server after return from exception7 */ /* cs:eip and ss:esp are ok */ .align 2,144 emulate: movw %ss, %ax /* set ds,es */ movw %ax, %ds movw %ax, %es pushl $_info call _math_emulate _back_to_prg: movl i_eax,%eax movl i_ebx,%ebx movl i_ecx,%ecx movl i_edx,%edx movl i_esi,%esi movl i_edi,%edi movl i_ebp,%ebp movw i_es,%es movw i_fs,%fs movw i_ss,%ss /* change stack to user */ movl i_esp,%esp pushl i_eflags pushl i_cs pushl i_eip movw i_ds,%ds iret _abort_emu: _raise: movw $0x7f0e,%ax movw $0x8 ,%cx int $0x21 movw $0x4cff,%ax int $0x21 ret .data rsxfpu_ver: .long 109 dpmi_esp: .long 0 dpmi_ss: .long 0 emu_esp: .long 0xfff0 _debugged: .long 0 _used_math: .long 0 .globl _process_npx _process_npx: .long _copro .lcomm _copro,172 .comm _info,92