/***************************************************************************** * FILE: adosx32.S * * * * DESC: * * - asm DOS 0x21 handler * * - debug handler for Windows 3.1 * * * * Copyright (C) 1993,1994 * * Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld * * email: rainer@mathematik.uni-bielefeld.de * * * *****************************************************************************/ #include "REGS386.INC" .text .globl _printk .align 2,144 _printk: jmp _printf /***************************************/ // Entry point for int 0x10 .globl _bioscall .align 2,144 _bioscall: // INT 0x10 handler entry cmpb $0x4F, %ah // vesa call ? jne not_vesa pushl $0x10 je common_int not_vesa: // jmp to orginal handler (DPMI-host) .byte 0xEA .globl _int10voff // label for writing in code _int10voff: .long 1 .globl _int10vsel // label for writing in code _int10vsel: .long 0 /***************************************/ // Entry point for int 0x33 .globl _mousecall .align 2,144 _mousecall: // INT 0x33 handler entry pushl $0x33 je common_int /***************************************/ common_int: // we do not save fs & gs pushl %esi call _load_ds // load 16 bit extender ds movl _npz, %esi // load process ptr popl R_ESI(%esi) // save ESI popl R_FAULTNO(%esi) // save int no movl %eax, R_EAX(%esi) movl %ebx, R_EBX(%esi) movl %ecx, R_ECX(%esi) movl %edx, R_EDX(%esi) movl %edi, R_EDI(%esi) movl %ebp, R_EBP(%esi) movw %es, %ax movw %ax, R_DS(%esi) movw %ax, R_ES(%esi) movw %ss, %ax movw %ax, R_SS(%esi) movl %esp, R_ESP(%esi) movl %esp, R_ESPORG(%esi) addl $12, R_ESPORG(%esi) movl %esp, %ebp // others regs are on user stack movl (%ebp), %eax // EIP movl %eax, R_EIP(%esi) movl 4(%ebp), %eax // CS movl %eax, R_CS(%esi) movl 8(%ebp), %eax // EFLAGS movl %eax, R_EFLAGS(%esi) movw %ds, %ax movw %ax, %es movw %ax, %ss movl R_KSTACK(%esi), %esp // load 16bit sp call _prot_mode_interrupt movl _npz, %esi // load process ptr movl R_EBX(%esi), %ebx // EBX movl R_ECX(%esi), %ecx // ECX movl R_EDX(%esi), %edx // EDX movl R_EDI(%esi), %edi // EDI movl R_EBP(%esi), %ebp // EBP movl R_SS(%esi), %eax movw %ax, %ss movl R_ESP(%esi), %esp movw R_ES(%esi), %ax movw %ax, %es movl R_EFLAGS(%esi), %eax movl %eax, 8(%esp) // EFLAGS movl R_CS(%esi), %eax movl %eax, 4(%esp) // CS movl R_EIP(%esi), %eax movl %eax, (%esp) // EIP movl R_EAX(%esi), %eax // EAX pushl R_DS(%esi) pushl R_ESI(%esi) popl %esi popl %ds // last segment restore iret /***************************************/ // Entry point for int 0x21 .globl _doscall .align 2,144 _doscall: // INT 0x21 handler entry cmpb $0x4C, %ah // exit call ? jne int32bit // no, must 32bit user int // ah=4Ch: recursive extender instance or 32bit user call ? // next instance reset interrupt handler and do int21/0x4c00 pushl %esi pushl %eax pushl %ds call _load_ds // load 16 bit extender ds movl _npz, %esi // load process ptr movw 16(%esp), %ax // 0:esi,eax,ds,eip,12:cs cmpw R_CS(%esi), %ax popl %ds popl %eax popl %esi je int32bit .align 2,144 // jmp to orginal handler (DPMI-host) jmp_inst: .byte 0xEA .globl _int21voff // label for writing in code _int21voff: .long 1 .globl _int21vsel // label for writing in code _int21vsel: .long 0 /***************************************/ .align 2,144 int32bit: // stack: 0=eip 4=cs 8=eflags pushl %esi call _load_ds // load 16 bit extender ds movl _npz, %esi // load process ptr popl R_ESI(%esi) // save ESI movl %eax, R_EAX(%esi) movl %ebx, R_EBX(%esi) movl %ecx, R_ECX(%esi) movl %edx, R_EDX(%esi) movl %edi, R_EDI(%esi) movl %ebp, R_EBP(%esi) movw %es, %ax movw %ax, R_DS(%esi) movw %ax, R_ES(%esi) movw %ss, %ax movw %ax, R_SS(%esi) movw %fs, %ax movw %ax, R_FS(%esi) movw %gs, %ax movw %ax, R_GS(%esi) movl %esp, R_ESP(%esi) movl %esp, R_ESPORG(%esi) addl $12, R_ESPORG(%esi) movl %esp, %ebp // others regs are on user stack movl (%ebp), %eax // EIP movl %eax, R_EIP(%esi) movl 4(%ebp), %eax // CS movl %eax, R_CS(%esi) movl 8(%ebp), %eax // EFLAGS movl %eax, R_EFLAGS(%esi) movw %ds, %ax movw %ax, %es movw %ax, %ss movl R_KSTACK(%esi), %esp // load 16bit sp call _int21 // call C-prg handler for int21h .globl _back_from_syscall _back_from_syscall: call _check_signals movl _npz, %esi // load process ptr movl R_EBX(%esi), %ebx // EBX movl R_ECX(%esi), %ecx // ECX movl R_EDX(%esi), %edx // EDX movl R_EDI(%esi), %edi // EDI movl R_EBP(%esi), %ebp // EBP movl R_SS(%esi), %eax movw %ax, %ss movl R_ESP(%esi), %esp movw R_ES(%esi), %ax movw %ax, %es movw R_FS(%esi), %ax movw %ax, %fs movw R_GS(%esi), %ax movw %ax, %gs movl R_EFLAGS(%esi), %eax movl %eax, 8(%esp) // EFLAGS movl R_CS(%esi), %eax movl %eax, 4(%esp) // CS movl R_EIP(%esi), %eax movl %eax, (%esp) // EIP movl R_EAX(%esi), %eax // EAX pushl R_DS(%esi) pushl R_ESI(%esi) popl %esi popl %ds // last segment restore iret .align 2,144 .globl _debug_entry _debug_entry: // int 0x03 handler pushl %ds call _load_ds movl %eax, REGF_EAX movl %ebx, REGF_EBX movl %ecx, REGF_ECX movl %edx, REGF_EDX movl %ebp, REGF_EBP movl %edi, REGF_EDI movl %esi, REGF_ESI xorl %eax, %eax movw %es, %ax movw %eax, REGF_ES movw %ss, %ax movw %eax, REGF_SS movw %fs, %ax movw %eax, REGF_FS movw %gs, %ax movw %eax, REGF_GS popl %eax // get orginal ds movl %eax, REGF_DS movl %esp, REGF_ESP addl $12, REGF_ESP movl %esp, REGF_ESPORG addl $12, REGF_ESPORG movl $1, REGF_FAULTNO movl %esp, %ebp movl (%ebp), %eax movl %eax, REGF_EIP movl 4(%ebp), %eax movl %eax, REGF_CS movl 8(%ebp), %eax movl %eax, REGF_EFLAGS movl _npz, %esi movw %ds, %ax // set other segment registers movw %ax, %es // make ds = es = ss movw %ax, %ss // load ss movl R_KSTACK(%esi), %esp // load esp call _myexcep13 // call C-handler jmp _back_from_syscall iret .align 2,144 .globl _execute_dpmi_function _execute_dpmi_function: pusha pushl %ds pushl %es movl _npz, %esi movl R_EAX(%esi), %eax movl R_EBX(%esi), %ebx movl R_ECX(%esi), %ecx movl R_EDX(%esi), %edx movl R_EBP(%esi), %ebp movl R_EDI(%esi), %edi pushl R_DS(%esi) pushl R_ES(%esi) movl R_ESI(%esi), %esi popl %es popl %ds int $0x31 popl %es popl %ds popa nop pushf popl %eax andl $1, %eax ret