Code:
$DIM ALL
$COMPILE UNIT
 
DECLARE FUNCTION SetOnExit(BYVAL ProcedurePointer AS DWORD) AS INTEGER
 
SUB ISR() PRIVATE
 
  DIM IsrStack AS STATIC STRING * 2048
 
IsrChain:
  ! db 0
 
OldAddress:
  ! dw 0
  ! dw 0
 
IsrAddress:
  ! dw 0
  ! dw 0
 
SaveDS:
  ! dw 0
 
SaveSS:
  ! dw 0
 
SaveSP:
  ! dw 0
 
IsrHandler:
  ! pushf
  ! cmp  Byte Ptr CS: IsrChain, 1
  ! jne  NoPreChain
  ! call DWord CS:OldAddress
  ! jmp  Short SaveRegisters
NoPreChain:
  ! popf
SaveRegisters:
  ! push bp
  ! mov  bp, sp
  ! pushf                         ; save the flags register
  ! push es
  ! push ds
  ! push di
  ! push si
  ! push dx
  ! push cx
  ! push bx
  ! push ax                       ; save the general registers
  ! mov  bp, sp                   ; set up the stack pointer
  ! cli                           ; suspend all maskable interrupts
  ! cld                           ; clear the direction flag
 
  ! mov Word Ptr CS:SaveSS, SS    ; save current stack segment
  ! mov Word Ptr CS:SaveSP, SP    ; save current stack pointer
  ! mov DS, Word Ptr CS:SaveDS    ; restore PowerBASIC data segment
 
  ' Create a local stack frame
  ! mov SS, Word Ptr CS:SaveDS    ; SS must equal DS for PowerBASIC runtime
  ! lea BX, IsrStack              ; get address of the local stack frame
  ! add BX, 2048                  ; point to the end of the fixed-length string
  ! mov SP, BX                    ; set the stack pointer
 
  ' Call the Basic code
  ! mov  BX, CS: SaveSS           ; segment of original stack
  ! push BX                       ;
  ! mov  BX, BP                   ; pointer to the register stack frame
  ! push BX                       ;
  ! call Dword Ptr CS:IsrAddress
 
  ' Restore the stack
  ! mov SP, Word Ptr CS:SaveSP ; restore the original stack segment
  ! mov SS, Word Ptr CS:SaveSS ;  and stack pointer before restoring the registers
 
  ! pop ax
  ! pop bx
  ! pop cx
  ! pop dx
  ! pop si
  ! pop di
  ! pop ds
  ! pop es
  ! popf               ; restore the flags register
  ! pop bp
 
  ! cmp  Byte Ptr CS: IsrChain, 2
  ! jne  IsrDone
  ! jmp  DWord Ptr CS: OldAddress
 
IsrDone:
  ! sti                ; re-enable maskable interrupt processing
  ! iret               ; return from our interrupt handler
 
END SUB
 
SUB SetInterruptVector(BYVAL Intr AS BYTE, BYVAL NewAddr AS DWORD) PRIVATE
  ! push ds            ; save DS
  ! mov ah, &H25       ; set AH to 25h (function number)
  ! mov al, Intr       ; set AL to interrupt vector being redirected
  ! lds DX, NewAddr    ;
  ! int &H21           ; call DOS services
  ! pop ds             ; restore DS
END SUB
 
SUB GetInterruptVector(BYVAL Intr AS BYTE, VAddr AS DWORD) PRIVATE
  ! push ds            ; save DS
  ! push si            ; save SI
  ! mov ah, &H35       ; set AH to 35h (function number)
  ! mov al, Intr?      ; set AL to interrupt vector
  ! int &H21           ; call DOS services (ES:BX now holds address)
  ! lds si, VAddr???   ; get a pointer to VSeg??
  ! mov ds:[si+2], es  ; copy ES (segment address) into VSeg??
  ! mov ds:[si], bx    ; copy BX (offset address) into VOff??
  ! pop si             ; restore SI
  ! pop ds             ; restore DS
END SUB
 
SUB IsrEnd() PUBLIC
 
  DIM OldAddr AS SHARED DWORD
  DIM IntSave AS SHARED WORD
 
  IF IntSave AND OldAddr THEN
    SetInterruptVector IntSave, OldAddr
    IntSave = 0
  END IF
 
END SUB
 
SUB IsrBegin(BYVAL Intr AS WORD, BYVAL Address AS DWORD, BYVAL fChain AS INTEGER) PUBLIC
 
  DIM OldAddr  AS SHARED DWORD
  DIM IntSave  AS SHARED WORD
  DIM SaveExit AS STATIC INTEGER
 
  IF IntSave THEN
    IsrEnd
  END IF
 
  IF SaveExit = 0 THEN
    SetOnExit CODEPTR32(IsrEnd)
    SaveExit = 1
  END IF
 
  GetInterruptVector Intr, OldAddr
 
  ! mov  Word Ptr CS: SaveDS, DS   ;store PowerBASIC Data segment
  ! les  DI, Address
  ! mov  Word Ptr CS: IsrAddress, DI
  ! mov  Word Ptr CS: IsrAddress[2], ES
  ! les  DI, DS: OldAddr
  ! mov  Word Ptr CS: OldAddress, DI
  ! mov  Word Ptr CS: OldAddress[2], ES
  ! mov  AX, fChain
  ! mov  Byte Ptr CS: IsrChain, AL
 
  SetInterruptVector Intr, CODEPTR32(IsrHandler)
 
  IntSave = Intr
 
END SUB

-------------
PowerBASIC Support
mailto:[email protected][email protected]</A>