home *** CD-ROM | disk | FTP | other *** search
- PAGE 81,132
- ;INTRPT2.ASM
- ;-----------------------------------------------------------------------|
- ; -------- ---1991 Cornel H Huth ------------------- |
- ;-----------------------------------------------------------------------|
- ; date: 21 Jul 91 |
- ; function: 80xxx INTERRUPT dispatcher for QuickBASIC/BASIC PDS |
- ; caller: FAR call QuickBASIC convention, reference (INTERRUPT(X)) |
- ; call INTERRUPT(intnum%,ireg AS RegType,oreg AS RegType) |
- ; call INTERRUPTX(intnum%,ireg AS RegTypeX,oreg AS RegTypeX) |
- ; stack: +06 offset of return register pack |
- ; 08 offset of initial register pack |
- ; 10 interrupt number |
- ; return: interrupt return registers |
- ; NOTE: This routine is a direct replacement for QB's routine. |
- ; NOTE: INT24 handler is installed temporarily to handle fatal |
- ; DOS errors without the Abort, Retry, Fail or system crash. |
- ; NOTE: If intnum% is out of range intnum% is NOT returned as -1 |
- ; as the MS version does (no one is that stoopid, hey,hey). |
- ; NOTE: The interrupt is done without writing to the code segment. |
- ; NOTE: b$SaveBP is no longer needed with PDS version since fatal |
- ; errors are handled locally, not by the BASIC INT24 handler.|
- ; NOTE: For verbose source comments see INTRPT.ASM in QBNWS105. |
- ;-----------------------------------------------------------------------|
- ; This source file is based on: |
- ; INTERRUPT - BASCOM software interrupt calling routine |
- ; Copyright <C> 1986, 1987 Microsoft Corporation |
- ;-----------------------------------------------------------------------|
- ;This source was assembled using MASM 5.1. Previous or other versions of|
- ;assemblers should handle this source without any difficulty except for |
- ;perhaps the retf and retn mnemonics. Easy enough to use a macro or db. |
- ;-----------------------------------------------------------------------|
- WPTR EQU <WORD PTR>
- BPTR EQU <BYTE PTR>
-
- Aintnum EQU <WPTR [BP+10]>
- Aireg EQU <WPTR [BP+08]>
- Aoreg EQU <WPTR [BP+06]>
-
- OldSI EQU <WPTR [BP-02]>
- OldDI EQU <WPTR [BP-04]>
- OldDS EQU <WPTR [BP-06]>
- OldFLAGS EQU <WPTR [BP-08]>
- RegCnt EQU <WPTR [BP-10]>
- RegES EQU <WPTR [BP-12]>
- RegDS EQU <WPTR [BP-14]>
- RegFLAGS EQU <WPTR [BP-16]>
- RegDI EQU <WPTR [BP-18]>
- RegSI EQU <WPTR [BP-20]>
- RegBP EQU <WPTR [BP-22]>
- RegDX EQU <WPTR [BP-24]>
- RegCX EQU <WPTR [BP-26]>
- RegBX EQU <WPTR [BP-28]>
- RegAX EQU <WPTR [BP-30]>
-
- LocalSize = 30
-
- PostBP EQU <WPTR [BP-34]> ;returned bp pushed here (after INT call return)
-
- _BSS SEGMENT WORD PUBLIC 'BSS'
- INT24error dw 1 dup(?)
- INT24seg dw 1 dup(?)
- INT24off dw 1 dup(?)
- _BSS ENDS
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
- _DATA ENDS
-
- DGROUP GROUP _DATA,_BSS
-
- INTRPT2_TEXT SEGMENT WORD PUBLIC 'CODE'
- ASSUME cs:INTRPT2_TEXT,ds:DGROUP,es:DGROUP,ss:DGROUP
-
- PUBLIC INTERRUPT
- INTERRUPT PROC FAR
-
- push bp
- mov bp,sp
- sub sp,LocalSize
- mov RegCnt,8 ;8 registers passed for INTERRUPT
- jmp SHORT INTRPT1
-
- PUBLIC INTERRUPTX
- INTERRUPTX LABEL FAR
-
- push bp
- mov bp,sp
- sub sp,LocalSize
- mov RegCnt,10 ;10 passed for INTERRUPTX
-
- ;set up for interrupt call
-
- INTRPT1: mov bx,Aintnum
- mov bx,[bx] ;bx=interrupt to execute
- or bh,bh ;>255?
- jz INTRPT2 ;no
- jmp INTRPTxit ;yes,just exit
-
- INTRPT2: push bx
- mov bl,1 ;trap fatal errors
- call INT24switch
- pop bx
-
- mov OldSI,si ;save what we need to
- mov OldDI,di
- mov OldDS,ds
- pushf ;in case RegFLAGS changes DF?
- pop OldFLAGS
-
- cld
- mov si,Aireg ;ds:si->ireg pack
- mov ax,ss
- mov es,ax
- lea di,RegAX ;es:di->local stack vars
- mov cx,RegCnt
- rep movsw
-
- push bp ;save original frame base
-
- cmp bl,25h ;INT25?
- je INTRPT3 ; or
- cmp bl,26h ;INT26?
- jne INTRPT4 ;no
-
- ;INT25/26 specific stack program
-
- INTRPT3: mov ax,10
- push ax ;retf 10
- mov ax,0CA90h ;nop
- push ax ;sti
- mov ax,0FB44h ;inc sp
- push ax ;inc sp
- mov ax,44FAh ;cli -ensure sp stays even
- push ax
- jmp SHORT INTRPT5
-
- ;non-INT25/26 specific stack program
-
- INTRPT4: sub ax,ax
- push ax ;retf 6
- mov ax,06CAh
- push ax
-
- ;for either, the actual INT?? instruction
-
- INTRPT5: mov ah,bl
- mov al,0CDh
- push ax ;INT??
-
- ;set up the far return address for the stack program
-
- push cs
- mov ax,OFFSET INTRPT8 ;cs:ax->return to after INT??
- push ax
-
- ;store the address of the stack program--on the stack
-
- push ss
- mov ax,sp
- add ax,6 ;ss:ax->start of stack program
- push ax
-
- ;set up the registers for the INT call
-
- mov ax,RegFLAGS
- and ax,0000111111010101b ;mask valid 8086 flags
- push ax ;save flags for a sec
-
- mov ax,RegAX
- mov bx,RegBX
- mov cx,RegCX
- mov dx,RegDX
- mov si,RegSI
- mov di,RegDI
-
- cmp RegCnt,8 ;call INTERRUPT?
- je INTRPT7
-
- cmp RegDS,-1 ;no,INTERRUPTX,load ds segment?
- je INTRPT6
- mov ds,RegDS ;ds<>ss!
-
- INTRPT6: cmp RegES,-1 ;how about es segment?
- je INTRPT7
- mov es,RegES
-
- INTRPT7: mov bp,RegBP
- popf ;get the flags back
-
- retf ;execute the stack program
-
- ;come here after the stack program has executed the INT call
-
- INTRPT8: push bp ;save to PostBP
- mov bp,sp
- mov bp,[bp+2] ;get original frame base
-
- pushf ;get the return flags NOW
- pop RegFLAGS
-
- ;unhook temporary INT24 handler and process any error
-
- push bx ;we want
- sub bl,bl
- call INT24switch
- pop bx ;we need
- cmp ss:INT24error,0 ;fatal DOS error?
- je INTRPT9 ;no
- or RegFLAGS,1 ;set carry
- mov ah,30h ;clean up DOS
- int 21h
- mov ax,ss:INT24error ;return DOS error
-
- INTRPT9: push OldFlags
- popf
-
- ;save returned registers and send them back
-
- mov RegAX,ax
- mov RegBX,bx
- mov RegCX,cx
- mov RegDX,dx
-
- mov ax,PostBP ;get BP value returned from INT call
- mov RegBP,ax
-
- mov RegSI,si
- mov RegDI,di
- mov RegDS,ds
- mov RegES,es
-
- mov ds,OldDS ;ds=ss
-
- lea si,RegAX ;ds:si->stack vars (ds=ss)
- mov ax,ds
- mov es,ax
- mov di,Aoreg ;es:di->oreg pack
- mov cx,RegCnt
- rep movsw
-
- mov si,OldSI
- mov di,OldDI
-
- INTRPTxit: mov sp,bp ;deallocate locals
- pop bp
- retf 3*2 ;we're done
-
- ;temporary INT24 switch and handler
-
- INT24switch: push es
- push ds
- push dx
- push ax
-
- or bl,bl
- jz INT24s2
-
- mov ss:INT24error,0
- mov ax,3524h
- int 21h
- mov ss:INT24seg,es
- mov ss:INT24off,bx
- mov ax,2524h
- mov dx,OFFSET INT24handler
- push cs
- pop ds
- INT24s1: int 21h
- pop ax
- pop dx
- pop ds
- pop es
- retn
-
- INT24s2: mov ax,2524h
- mov dx,ss:INT24off
- mov ds,ss:INT24seg
- jmp INT24s1
-
- ;store the error number and return
-
- INT24handler: sti
- add sp,6
- add di,13h
- mov ss:INT24error,di
- pop ax
- pop bx
- pop cx
- pop dx
- pop si
- pop di
- pop bp
- pop ds
- pop es
- iret
-
- INTERRUPT ENDP
- INTRPT2_TEXT ENDS
- END
-