dsxhdlr.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 432 行

ASM
432
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;*               DESCRIBE IT HERE!
;*
;*****************************************************************************


.386p

    PUBLIC  RMTrapHandler_
    PUBLIC  RawSwitchHandler_
    PUBLIC  BackFromRealMode_
    PUBLIC RMTrapInit_
    PUBLIC RMTrapAccess_
    PUBLIC RMTrapFini_
    PUBLIC Interrupt10_
    PUBLIC Interrupt15_
    PUBLIC Interrupt1b_23_
    PUBLIC Interrupt24_
    PUBLIC _RMSegStart
    PUBLIC _RMDataStart
    PUBLIC _RMSegEnd


DEBUG           equ     0
include dsxdebug.inc

ifdef _NEC_PC
 DOS4G_COMM_VECTOR equ  7fh
else
 DOS4G_COMM_VECTOR equ  15h
endif


STKSIZE         equ     4096                    ;size of stack in bytes
MXENTRY_SIZE    equ     6                       ;sizeof( mx_entry )
PSP_ENVSEG_OFF  equ     2ch                     ;off in PSP holding seg of env
VECT_TABLE_SIZE equ     200h                    ;vector table size (in words)
MAX_MSG_SIZE    equ     400h                    ;max # of bytes for messages
TRAP_VER_SIZE   equ     3                       ;sizeof( trap_version )

;
; has match structure in CallTrapInit in DSXHDLR.C
;
INITSTRUCT      STRUC
remote          dw ?
initret         dw ?                            ;retcode from TrapInit()
version         db TRAP_VER_SIZE dup(?)         ;trap_version structure
buffoff         dw ?                            ;where to store errmsg
INITSTRUCT      ENDS

;
; has match structure in TrapAccess in DSXHDLR.C
;
REQSTRUCT       STRUC
in_ptr          dd ?                            ;ptr to input buffer
in_len          dw ?                            ;len of input buffer
out_ptr         dd ?                            ;ptr to output buffer
out_len         dw ?                            ;len of output buffer
reqret          dw ?                            ;ret code from TrapAccess()
REQSTRUCT       ENDS

;
; has to match rm_data structure in DSXUTIL.H
;
STATICDATA      STRUC
orig_vects      dw VECT_TABLE_SIZE dup('JJ')    ;original vector values
vecttable1      dw VECT_TABLE_SIZE dup('HH')    ;area to hold a vector table
vecttable2      dw VECT_TABLE_SIZE dup('II')    ;area to hold a vector table
rm_func         dw 0                            ;function in file to call
initfunc        dd 0aaaaaaaah                   ;addr of TrapInit()
reqfunc         dd 0bbbbbbbbh                   ;addr of TrapAccess()
finifunc        dd 0cccccccch                   ;addr of TrapFini()
envseg          dw 0                            ;seg of environment
envseg_pm       dw 0                            ;pm seg of environment
switchaddr      dd 0                            ;addr to switch back to pmode
saveaddr        dd 0                            ;addr of save state procedure
saveseg         dw 0                            ;segment of save state buffer
saveseg_pm      dw 0                            ; pm seg of save state buffer
savesize        dw 0 
pmode_ds        dw 0                            ;value to put in ds on return
pmode_es        dw 0                            ; ...
pmode_cs        dw 0                            ; ...
pmode_eip       dd 0                            ; ...
pmode_ss        dw 0                            ; ...
pmode_esp       dd 0                            ; ...
save_env        dw 'JJ'
savess          dw 'BB'                         ;ss provided by DOS4G
savesp          dw 'CC'                         ;sp corresponding to 'savess'
OldInt10        DD      0 
Pending         DB      0 
Fail            DB      0
ActFontTbls     DB      0
othersaved      db      0
parmarea        db 40h + MAX_MSG_SIZE dup('M')
stack           db STKSIZE dup('A')
STATICDATA      ENDS


rmhandlr_TEXT16 SEGMENT BYTE PUBLIC USE16 'CODE'
ASSUME  cs:rmhandlr_TEXT16, ds:rmhandlr_TEXT16, ss:rmhandlr_TEXT16

_RMSegStart     LABEL   BYTE


_RMDataStart    LABEL   BYTE
                STATICDATA      <>              ;make sure this is at offset 0

plsdebug        MACRO
        ;for debugging pls only
                cmp     word ptr ds:parmarea, TRAPREQ_FLAG
                jne     backtopm
                push    dx
                push    bx
                mov     bx, OFFSET parmarea + SIZE REQSTRUCT
                mov     dx, ds:[bx]
                mov     bx, dx
                mov     dl, byte ptr ds:[bx]
                setpage 0
                write8  24, 50, dl
                pop     bx
                cmp     dl, 23
                je      loadreq
                pop     dx
                jmp     backtopm
loadreq:        write16 2, 0, ds:pmode_ds
                write16 2, 5, ds:pmode_es
                write16 2, 10, ds:pmode_cs
                write16 2, 15, ds:pmode_ss
                write32 3, 0, ds:pmode_esp
                write32 3, 9, ds:pmode_eip
                write32 4, 0, ds:switchaddr
dummy:          jmp     dummy
                ENDM

;purpose of set_envseg:
;       DOS/4GW does not provide us with an environment so the debugger copies its
;       environment into low memory and we set/restore the env ptr in our
;       psp to this area just after we are called and just before we return
;       to protected mode
;on entry to set_envseg:
;       save_env is the address where the old psp environment seg will be
;                saved
;       new_env  is the address containing the seg of the new environment
set_envseg      MACRO   save_env, new_env
                push    ax
                push    bx
                push    es
                pushf

                mov     ah, 51h                 ;get the current PSP seg
                int     21h
                mov     es, bx
                mov     ax, es:[PSP_ENVSEG_OFF]
                mov     save_env, ax
                mov     ax, new_env
                mov     es:[PSP_ENVSEG_OFF], ax

                popf
                pop     es
                pop     bx
                pop     ax
                ENDM

copy_vectors    MACRO   src_seg, src_off, dst_seg, dst_off
                push    cx
                push    si
                push    di
                push    ds
                push    es

                push    src_seg
                push    dst_seg
                mov     si,src_off
                mov     di,dst_off
                pop     es
                pop     ds
                mov     cx, VECT_TABLE_SIZE

                cli
                rep     movsw
                sti

                pop     es
                pop     ds
                pop     di
                pop     si
                pop     cx
                ENDM

; set DI to offset of save area before calling routine
restore_state   PROC NEAR
                push    ax
                push    es
                mov     es, ds:saveseg
                mov     al, 1                   ;al=1 means restore state
                call    ds:saveaddr

                pop     es
                pop     ax
                ret
restore_state   ENDP

; set DI to offset of save area before calling routine
save_state      PROC NEAR
                push    ax
                push    es

                mov     es, ds:saveseg
                mov     al, 0                   ;al=0 means save state
                call    ds:saveaddr

                pop     es
                pop     ax
                ret
save_state      ENDP


;on entry to calltrapinit, the format of the parameter area is described by
;the INITSTRUCT STRUC - in addition, the string parm is located immediately
;after the last field in INITSTRUCT
;
;to call TrapInit( char far *parm, char far *buff, bool remote ) :
;       dx:ax   holds addr of parm
;       cx:bx   holds addr of buff
;       stack   holds value of remote
RMTrapInit_     PROC NEAR
                push    es
                push    cx
                push    si

                sub     sp, 4                   ;make space for return struct
                mov     si, sp                  ;ret value is stored at si

                push    ds:parmarea.remote      ;place remote on stack
                mov     ax, SIZE INITSTRUCT + OFFSET parmarea
                mov     dx, cs                  ;now dx:ax points to parm
                mov     bx, ds:parmarea.buffoff
                add     bx, OFFSET parmarea
                mov     cx, dx                  ;now cx:bx points to buff
                call    dword ptr ds:initfunc   ;call TrapInit
                pop     dx                      ;put loword of version in dx
                mov     word ptr ds:parmarea.version, dx
                pop     ax                      ;put hibyte of version in al
                mov     ds:parmarea.version+2, al

                pop     si
                pop     cx
                pop     es
                ret
RMTrapInit_     ENDP

;on entry to calltrapaccess, the format of the parameter area is described
;by the REQSTRUCT STRUC
;
;to call TrapAccess( unsigned_8 num_in_mx, mx_entry far *mx_in,
;                    unsigned_8 num_out_mx, mx_entry far *mx_out ) :
;       ax      holds num_in_mx (==1)
;       cx:bx   holds addr of mx_in
;       dx      holds num_out_mx (==1)
;       stack   holds addr of mx_out
;on calltrapaccess exit :
;       ax      holds TrapAccess return value
RMTrapAccess_   PROC NEAR
                push    ax
                push    bx
                push    cx
                push    dx

                cmp     word ptr cs:parmarea.out_ptr, 0
                jne     have_ret
                push    word ptr 0
                mov     dx,0
                push    word ptr 0
                jmp     short remainder
have_ret:
                mov     dx,1
                push    cs
                push    offset parmarea.out_ptr
remainder:
                mov     bx,offset parmarea.in_ptr
                mov     cx,cs
                mov     ax,1
                call    dword ptr ds:reqfunc
                mov     ds:parmarea.reqret, ax  ;store ret code

                pop     dx
                pop     cx
                pop     bx
                pop     ax
                ret
RMTrapAccess_   ENDP

RMTrapFini_     PROC NEAR
                call    dword ptr ds:finifunc
                ret
RMTrapFini_     ENDP

calltrapfile    PROC NEAR
                copy_vectors 0, 0, ds, vecttable2
                copy_vectors ds, vecttable1, 0, 0
                set_envseg ds:save_env, ds:envseg
                call    ds:rm_func
                set_envseg ds:envseg, ds:save_env
                copy_vectors 0, 0, ds, vecttable1
                copy_vectors ds, vecttable2, 0, 0
                ret
calltrapfile    ENDP

chain_down:
                jmp     dword ptr cs:orig_vects+1ah*4

RMTrapHandler_:
                cmp     ah,6
                jne     chain_down
                cmp     cx,0ffffh
                jne     chain_down
                push    ds
                push    ax

                mov     ax, cs
                mov     ds, ax
                mov     ds:savess, ss   ;save ss given to us by DOS4G
                mov     ds:savesp, sp   ;save sp
                mov     ss, ax
                mov     sp, OFFSET stack + STKSIZE

                call    calltrapfile

                mov     ss, ds:savess   ;restore ss
                mov     sp, ds:savesp   ;restore sp
                pop     ax
                pop     ds                      ;restore old ds
                iret

;on entry to RawSwitchProc_ ds, cs, es, and ss already point to
;rmhandlr_TEXT16, and ebp holds the value to put in esp when we return
;to the debugger

RawSwitchHandler_:
                sti
                mov     sp, OFFSET stack + STKSIZE
                mov     ds:pmode_esp, ebp
                xor     di,di
                call    save_state
                cmp     ds:othersaved,0
                je      skip_restore
                mov     di,ds:savesize
                call    restore_state
skip_restore:

                call    calltrapfile

                mov     ds:othersaved,1
                mov     di,ds:savesize
                call    save_state
                xor     di,di
                call    restore_state

                mov     ax, ds:pmode_ds
                mov     cx, ds:pmode_es
                mov     dx, ds:pmode_ss
                mov     si, ds:pmode_cs
                mov     edi, ds:pmode_eip
                mov     ebx, ds:pmode_esp
                jmp     dword ptr ds:switchaddr


Interrupt10_:
                cmp     ax, 1130h
                jne     continue
                mov     cs:ActFontTbls, bl
continue:       jmp     dword ptr cs:OldInt10


Interrupt1b_23_:
                mov     byte ptr cs:Pending, 0ffh
                iret

Interrupt24_:
                mov     al,byte ptr cs:Fail
                iret

Interrupt15_:
        cmp     ax, 0BF02h              ; DOS/16M find xbrk function
        je      hide_self
        cmp     ax, 0BFDCh              ; DOS/16M alternate find xbrk function
        je      hide_self
        jmp     dword ptr cs:orig_vects+DOS4G_COMM_VECTOR*4; chain to previous
hide_self:
        iret                            ; Don't share memory with anyone!

;;
;; The following routine executes in protected mode, but it
;; needs to be in a USE16 segment, which is why it's here
;;

BackFromRealMode_ PROC FAR
                db      066h    ; turn RET into RETD
                ret
BackFromRealMode_ ENDP

_RMSegEnd       LABEL   BYTE

rmhandlr_TEXT16 ENDS
                END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?