Category : BASIC Source Code
Archive   : QBNWS203.ZIP
Filename : INTRPT2.ASM
;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
;-----------------------------------------------------------------------|
;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
BPTR EQU
Aintnum EQU
Aireg EQU
Aoreg EQU
OldSI EQU
OldDI EQU
OldDS EQU
OldFLAGS EQU
RegCnt EQU
RegES EQU
RegDS EQU
RegFLAGS EQU
RegDI EQU
RegSI EQU
RegBP EQU
RegDX EQU
RegCX EQU
RegBX EQU
RegAX EQU
LocalSize = 30
PostBP EQU
_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
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/