home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n11.zip / LABNOT.ZIP / INTTRPT.ASM < prev    next >
Assembly Source File  |  1992-02-24  |  7KB  |  217 lines

  1. ;Inttrpt.ASM
  2. ;Copyright (c) 1992 Jay Munro
  3. ;First published in PC Magazine June 16, 1992
  4.  
  5. ;----------------------------------------------------------------------------
  6. ;Interrupt is a Call Interupt replacement for Visual Basic.  Using the same
  7. ;register structure as the QuickBasic/BC7 InterruptX it allows the Visual
  8. ;Basic programmer access to DOS interrupts.
  9. ;If an error occurs, the function will return a value otherwise it returns
  10. ;a 0.
  11. ;
  12. ;Not all interrupts may be called.  Some will just be ignored, as in
  13. ;early FCB functions or may cause UAEs.
  14. ;
  15. ;  Syntax:
  16. ;  Declare Function Interrupt% Lib "Labnotes.DLL" (Regs as Registers,
  17. ;                                                       Byval IntNum%)
  18. ;  IntError% = Interrupt%(Regs, IntNum%)
  19. ;----------------------------------------------------------------------------
  20. ;Call Interrupt for Visual Basic 
  21. ; TYPE RegType
  22. ;     AX    AS INTEGER
  23. ;     BX    AS INTEGER
  24. ;     CX    AS INTEGER
  25. ;     DX    AS INTEGER
  26. ;     BP    AS INTEGER  ;unused on incoming registers
  27. ;     SI    AS INTEGER
  28. ;     DI    AS INTEGER
  29. ;     Flags AS INTEGER
  30. ;     DS    AS INTEGER
  31. ;     ES    AS INTEGER
  32. ; END TYPE
  33.  
  34. ; Outputs:
  35. ;       If no errors occured:
  36. ;          RegType = resulting values of register after interrupt was
  37. ;                    was executed.
  38. ;       If errors did occur:
  39. ;          function returns error (AX)
  40. ;          RegType will remain unchanged
  41.  
  42. .286P
  43.  
  44. .Model Medium
  45.         Include LabNotes.Inc
  46.         Extrn AllocCStoDSAlias:Proc
  47.         Extrn FreeSelector:Proc
  48.         Public Interrupt
  49.  
  50.         User_Flgs       Equ [BP-2h]
  51.         User_DS         Equ [BP-4h]
  52.         Int_ES          Equ [BP-6h]
  53.         Int_DS          Equ [BP-8h]
  54.         Int_Flags       Equ [BP-0Ah]
  55.         Int_DI          Equ [BP-0Ch]
  56.         Int_SI          Equ [BP-0Eh]
  57.         Int_BP          Equ [BP-10h]                  ;
  58.         Int_DX          Equ [BP-12h]
  59.         Int_CX          Equ [BP-14h]
  60.         Int_BX          Equ [BP-16h]
  61.         Int_AX          Equ [BP-18h]
  62.         Old_SI          Equ [BP-1Ah]
  63.         Old_DI          Equ [BP-1Ch]
  64.         AliasCS         Equ [BP-1Eh]          ;aliased CS
  65.         User_ES         Equ [BP-20h]
  66.         ReturnError     Equ [BP-22h]
  67.  
  68. .Code
  69.  
  70. Interrupt Proc Far
  71.    Push DS                      ;no DGroup, so ignore this code
  72.    Pop  AX
  73.    Nop
  74.    Inc  BP
  75.    Push BP
  76.    Mov  BP,SP
  77.    Sub  SP,22h                  ;set aside stack space
  78.    Mov  Old_SI,SI               ;save DI,SI and DS
  79.    Mov  Old_DI,DI
  80.    Mov  User_DS,DS              ; good ol DS
  81.    Mov  User_ES,ES              ; save ES
  82.    Mov  Word Ptr ReturnError,0
  83.    PushF
  84.    Pop  User_Flgs               ;save Flags
  85.    Lds  SI,[BP+8]               ;get pointer to users Type
  86.    Lea  DI,Int_AX               ;get pointer to BP
  87.    Mov  CX,10                   ;move 10 regs from users type
  88.    Push SS                      ;point ES at SS
  89.    Pop  ES                      ;
  90.    Cld                          ;move forward
  91.    Rep  MovSw                   ;move 10 regs into stack 
  92.    Push BP                      ;save BP to recover reg's after interrupt
  93.  
  94.    Push CS
  95.    Call AllocCSToDSAlias        ;make code seg writeable
  96.    Mov  AliasCS,AX              ;save alloc'd CS for later    
  97.    Mov  CX,[BP+6]               ;get int value into CL
  98.    Or   CH,CH                   ;check for bad interrupt
  99.    Jz   @F                      ;int is between 0 and 255 - ok
  100.    Jmp  ErrorExit               ;OOPS bad int
  101.    
  102. @@:
  103.    Push DS
  104.    Mov  DS,AX                   ;point DS at new selector
  105.    Lea  BX,IntNum
  106.    Mov  [BX],CL                 ;retread IntNum with new interrupt
  107.    Lea  BX, RegUInt
  108.    Mov  Word Ptr [BX],0BEBh     ;set opcodes for Jmp Int_Return
  109.  
  110.    Cmp  CL,25h                  ;interrupt 25h or 26?
  111.    Jz   @F                      ;yes, special handling
  112.    Cmp  CL,26h                  ;  ditto
  113.    Jnz  NormalInt               ;
  114. @@: 
  115.    Mov  Word Ptr [BX],9090h     ;nop out the jump
  116.                                 
  117. NormalInt:                      ;now move input registers to actual registers
  118.    Pop  DS                      ;retread DS
  119.    Mov  AX,Int_Flags            ;flag regester
  120.    And  AX,0111111010101b       ;and out unused flags
  121.    Push AX
  122.    Mov  AX,Int_AX
  123.    Mov  BX,Int_BX
  124.    Mov  CX,Int_CX
  125.    Mov  DX,Int_DX
  126.    Mov  SI,Int_SI
  127.    Mov  DI,Int_DI
  128.  
  129.    Cmp  Word Ptr Int_ES,-1      ;are we doing ES?
  130.    Jz   @F
  131.    Mov  ES,Int_ES               ;yes use it
  132. @@:
  133.    Cmp  Word Ptr Int_DS,-1      ;how about DS?
  134.    Jz   @F
  135.    Mov  DS,Int_DS               ;use incoming
  136. @@:
  137.    Cmp  Word Ptr Int_BP,-1      ;how about BP?
  138.    Jz   @F
  139.    Mov  BP,Int_BP               ;use incoming
  140. @@:
  141.  
  142. ;---- Self modifying code (and they said it couldn't be done)
  143.          Popf                   ;pop flags
  144.          DB      0CDh           ;interrupt number
  145. IntNum   DB      0              ;goes here
  146.  
  147. ;RegUInt:   Jmp Short Int_Return
  148.  
  149. RegUInt: DB      0EBh           ;Jmp or not
  150.          DB      0Bh            ;
  151.  
  152.         Push    AX
  153.         Push    BP
  154.         Mov     BP,SP
  155.         Lahf                     ;load AX with flags
  156.         Mov     [BP+4],AH        ;store flags into stack
  157.         Pop     BP
  158.         Pop     AX               ;retrieve original AX
  159.         PopF                     ;clear old flags
  160.  
  161. Int_Return:
  162.      Push  BP                     ;save post Interrupt BP into temp
  163.      Mov   BP,SP                  ;Temp Frame is second word past this
  164.      Mov   BP,[BP+2h]             ;get actual (old frame value)
  165.      Jnc   @F
  166.      Mov   ReturnError,AX           ;assign error
  167. @@:     
  168.    
  169. ;Now assign back regs
  170.      PushF
  171.      Pop   Int_Flags
  172.      Push  User_Flgs
  173.      Popf                         ;retrieve incoming flags
  174.      Mov   Int_AX,AX              ;save AX - ES back for type array
  175.      Mov   Int_BX,BX
  176.      Mov   Int_CX,CX
  177.      Mov   Int_DX,DX
  178.      Mov   AX,[BP-22]             ;get temp BP that was saved
  179.      Mov   Int_BP,AX              ;and into struct
  180.      Mov   Int_SI,SI
  181.      Mov   Int_DI,DI
  182.      Mov   Int_DS,DS
  183.      Mov   Int_ES,ES
  184.  
  185.      Push  AliasCS                ;free alias
  186.      Call  FreeSelector           ;
  187.  
  188.      Lea   SI,Int_AX
  189.      Push  SS                     ;point DS at stack where outgoing regs are
  190.      Pop   DS                     ;  stored
  191.      Les   DI,[BP+8]              ;get pointer to register type
  192.      Cld                          ;forward moves
  193.      Mov   CX,10                  ;move 10 reg's
  194.      Rep   MovSW                  ;move um
  195.      Mov   DI,Old_DI              ;retrieve original DI & SI
  196.      Mov   SI,Old_SI
  197.      Mov   DS,User_DS             ;retread DS
  198.      Mov   ES,User_ES             ;retread ES
  199.      Jmp   Exit
  200. CritErrExit:
  201.  
  202. ErrorExit:
  203.      Pop   BP
  204.      Push  AliasCS                ;free alias
  205.      Call  FreeSelector           ;
  206.      Mov   Word Ptr ReturnError,-1
  207.      
  208. Exit:
  209.      Mov  AX, ReturnError
  210.      Mov  SP,BP                    ;reset SP
  211.      Pop  BP                       ;retrieve original BP
  212.      Dec  BP                       ;readjust BP
  213.      Ret  6
  214.    
  215. Interrupt EndP
  216. End
  217.