home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast.iso
/
pcmag
/
vol11n11.zip
/
LABNOT.ZIP
/
INTTRPT.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-02-24
|
7KB
|
217 lines
;Inttrpt.ASM
;Copyright (c) 1992 Jay Munro
;First published in PC Magazine June 16, 1992
;----------------------------------------------------------------------------
;Interrupt is a Call Interupt replacement for Visual Basic. Using the same
;register structure as the QuickBasic/BC7 InterruptX it allows the Visual
;Basic programmer access to DOS interrupts.
;If an error occurs, the function will return a value otherwise it returns
;a 0.
;
;Not all interrupts may be called. Some will just be ignored, as in
;early FCB functions or may cause UAEs.
;
; Syntax:
; Declare Function Interrupt% Lib "Labnotes.DLL" (Regs as Registers,
; Byval IntNum%)
; IntError% = Interrupt%(Regs, IntNum%)
;----------------------------------------------------------------------------
;Call Interrupt for Visual Basic
; TYPE RegType
; AX AS INTEGER
; BX AS INTEGER
; CX AS INTEGER
; DX AS INTEGER
; BP AS INTEGER ;unused on incoming registers
; SI AS INTEGER
; DI AS INTEGER
; Flags AS INTEGER
; DS AS INTEGER
; ES AS INTEGER
; END TYPE
; Outputs:
; If no errors occured:
; RegType = resulting values of register after interrupt was
; was executed.
; If errors did occur:
; function returns error (AX)
; RegType will remain unchanged
.286P
.Model Medium
Include LabNotes.Inc
Extrn AllocCStoDSAlias:Proc
Extrn FreeSelector:Proc
Public Interrupt
User_Flgs Equ [BP-2h]
User_DS Equ [BP-4h]
Int_ES Equ [BP-6h]
Int_DS Equ [BP-8h]
Int_Flags Equ [BP-0Ah]
Int_DI Equ [BP-0Ch]
Int_SI Equ [BP-0Eh]
Int_BP Equ [BP-10h] ;
Int_DX Equ [BP-12h]
Int_CX Equ [BP-14h]
Int_BX Equ [BP-16h]
Int_AX Equ [BP-18h]
Old_SI Equ [BP-1Ah]
Old_DI Equ [BP-1Ch]
AliasCS Equ [BP-1Eh] ;aliased CS
User_ES Equ [BP-20h]
ReturnError Equ [BP-22h]
.Code
Interrupt Proc Far
Push DS ;no DGroup, so ignore this code
Pop AX
Nop
Inc BP
Push BP
Mov BP,SP
Sub SP,22h ;set aside stack space
Mov Old_SI,SI ;save DI,SI and DS
Mov Old_DI,DI
Mov User_DS,DS ; good ol DS
Mov User_ES,ES ; save ES
Mov Word Ptr ReturnError,0
PushF
Pop User_Flgs ;save Flags
Lds SI,[BP+8] ;get pointer to users Type
Lea DI,Int_AX ;get pointer to BP
Mov CX,10 ;move 10 regs from users type
Push SS ;point ES at SS
Pop ES ;
Cld ;move forward
Rep MovSw ;move 10 regs into stack
Push BP ;save BP to recover reg's after interrupt
Push CS
Call AllocCSToDSAlias ;make code seg writeable
Mov AliasCS,AX ;save alloc'd CS for later
Mov CX,[BP+6] ;get int value into CL
Or CH,CH ;check for bad interrupt
Jz @F ;int is between 0 and 255 - ok
Jmp ErrorExit ;OOPS bad int
@@:
Push DS
Mov DS,AX ;point DS at new selector
Lea BX,IntNum
Mov [BX],CL ;retread IntNum with new interrupt
Lea BX, RegUInt
Mov Word Ptr [BX],0BEBh ;set opcodes for Jmp Int_Return
Cmp CL,25h ;interrupt 25h or 26?
Jz @F ;yes, special handling
Cmp CL,26h ; ditto
Jnz NormalInt ;
@@:
Mov Word Ptr [BX],9090h ;nop out the jump
NormalInt: ;now move input registers to actual registers
Pop DS ;retread DS
Mov AX,Int_Flags ;flag regester
And AX,0111111010101b ;and out unused flags
Push AX
Mov AX,Int_AX
Mov BX,Int_BX
Mov CX,Int_CX
Mov DX,Int_DX
Mov SI,Int_SI
Mov DI,Int_DI
Cmp Word Ptr Int_ES,-1 ;are we doing ES?
Jz @F
Mov ES,Int_ES ;yes use it
@@:
Cmp Word Ptr Int_DS,-1 ;how about DS?
Jz @F
Mov DS,Int_DS ;use incoming
@@:
Cmp Word Ptr Int_BP,-1 ;how about BP?
Jz @F
Mov BP,Int_BP ;use incoming
@@:
;---- Self modifying code (and they said it couldn't be done)
Popf ;pop flags
DB 0CDh ;interrupt number
IntNum DB 0 ;goes here
;RegUInt: Jmp Short Int_Return
RegUInt: DB 0EBh ;Jmp or not
DB 0Bh ;
Push AX
Push BP
Mov BP,SP
Lahf ;load AX with flags
Mov [BP+4],AH ;store flags into stack
Pop BP
Pop AX ;retrieve original AX
PopF ;clear old flags
Int_Return:
Push BP ;save post Interrupt BP into temp
Mov BP,SP ;Temp Frame is second word past this
Mov BP,[BP+2h] ;get actual (old frame value)
Jnc @F
Mov ReturnError,AX ;assign error
@@:
;Now assign back regs
PushF
Pop Int_Flags
Push User_Flgs
Popf ;retrieve incoming flags
Mov Int_AX,AX ;save AX - ES back for type array
Mov Int_BX,BX
Mov Int_CX,CX
Mov Int_DX,DX
Mov AX,[BP-22] ;get temp BP that was saved
Mov Int_BP,AX ;and into struct
Mov Int_SI,SI
Mov Int_DI,DI
Mov Int_DS,DS
Mov Int_ES,ES
Push AliasCS ;free alias
Call FreeSelector ;
Lea SI,Int_AX
Push SS ;point DS at stack where outgoing regs are
Pop DS ; stored
Les DI,[BP+8] ;get pointer to register type
Cld ;forward moves
Mov CX,10 ;move 10 reg's
Rep MovSW ;move um
Mov DI,Old_DI ;retrieve original DI & SI
Mov SI,Old_SI
Mov DS,User_DS ;retread DS
Mov ES,User_ES ;retread ES
Jmp Exit
CritErrExit:
ErrorExit:
Pop BP
Push AliasCS ;free alias
Call FreeSelector ;
Mov Word Ptr ReturnError,-1
Exit:
Mov AX, ReturnError
Mov SP,BP ;reset SP
Pop BP ;retrieve original BP
Dec BP ;readjust BP
Ret 6
Interrupt EndP
End