home *** CD-ROM | disk | FTP | other *** search
- PAGE 55,132
- TITLE ISRSUBX.ASM
- SUBTTL Copyright (C) 1990, South Mountain Software, Inc.
-
- IFNDEF NUMBER
- %OUT NUMBER MUST BE DEFINED, for example: /DNUMBER=1
- %OUT ASSEMBLY ABORTED
- END
- ENDIF
-
- IFDEF LARGEMODEL
- %OUT ***** Assembling LARGE MODEL *****
- ELSE
- IFDEF MEDIUM
- %OUT ***** Assembling MEDIUM MODEL *****
- ELSE
- %OUT ***** Assembling SMALL MODEL *****
- ENDIF
- ENDIF
-
-
- DATAMAC MACRO numb
- public _isr&numb&_ax, _isr&numb&_ah, _isr&numb&_al, _isr&numb&_bx, _isr&numb&_bh, _isr&numb&_bl
- public _isr&numb&_cx, _isr&numb&_ch, _isr&numb&_cl, _isr&numb&_dx, _isr&numb&_dh, _isr&numb&_dl
- public _isr&numb&_si, _isr&numb&_di, _isr&numb&_bp, _isr&numb&_ds, _isr&numb&_es, _isr&numb&_flags
- public _Isr&numb&24Error, _Isr&numb&24Result
- IFNDEF VARS_IN_CS
- even
- ENDIF
- _isr&numb&_ax label word
- _isr&numb&_al db 0
- _isr&numb&_ah db 0
-
- _isr&numb&_bx label word
- _isr&numb&_bl db 0
- _isr&numb&_bh db 0
-
- _isr&numb&_cx label word
- _isr&numb&_cl db 0
- _isr&numb&_ch db 0
-
- _isr&numb&_dx label word
- _isr&numb&_dl db 0
- _isr&numb&_dh db 0
-
- _isr&numb&_bp dw 0
- _isr&numb&_si dw 0
- _isr&numb&_di dw 0
- _isr&numb&_ds dw 0
- _isr&numb&_es dw 0
- _isr&numb&_flags dw 0
-
- _Isr&numb&24Error db 0
- _Isr&numb&24Result db 0
- ENDM
-
- PUBLICMAC MACRO numb
- public _initisr&numb,_freeisr&numb ; so C can set up isr and free isr
- endm
-
-
- START_INIT MACRO numb
- ifdef LARGEMODEL
- _initisr&numb proc far
- else
- ifdef MEDIUM
- _initisr&numb proc far
- else
- _initisr&numb proc near
- endif
- endif
- ENDM
-
- END_INIT MACRO numb
- _initisr&numb endp
- ENDM
-
- START_FREE MACRO numb
- ifdef LARGEMODEL
- _freeisr&numb proc far
- freeisr&numb label far
- else
- ifdef MEDIUM
- _freeisr&numb proc far
- freeisr&numb label far
- else
- _freeisr&numb proc near
- freeisr&numb label near
- endif
- endif
-
- ENDM
-
- END_FREE MACRO numb
- _freeisr&numb endp
- ENDM
-
- IFDEF VARS_IN_CS
- %OUT *** Assembling for SWAPPING COMBO ***
- START_COPY MACRO numb
- public _copy_regs_isr&numb
- ifdef LARGEMODEL
- _copy_regs_isr&numb proc far
- copy_regs_isr&numb label far
- else
- ifdef MEDIUM
- _copy_regs_isr&numb proc far
- copy_regs_isr&numb label far
- else
- _copy_regs_isr&numb proc near
- copy_regs_isr&numb label near
- endif
- endif
-
- ENDM
-
- END_COPY MACRO numb
- _copy_regs_isr&numb endp
- ENDM
- ENDIF
-
- MOVE_EM_IN MACRO numb
-
- mov _isr&numb&_ds,ax
-
- pop ax
- mov word ptr _isr&numb&_ax, ax ; initialize so C can access registers
- mov word ptr _isr&numb&_bx, bx
- mov word ptr _isr&numb&_cx, cx
- mov word ptr _isr&numb&_dx, dx
- mov _isr&numb&_si, si
- mov _isr&numb&_di, di
- mov _isr&numb&_bp, bp
- mov _isr&numb&_es,es
- ENDM
-
- MOVE_EM_OUT MACRO numb
- mov ax, _isr&numb&_ax ; set registers so calling program can see result
- mov bx, _isr&numb&_bx
- mov cx, _isr&numb&_cx
- mov dx, _isr&numb&_dx
- mov si, _isr&numb&_si
- mov di, _isr&numb&_di
- mov bp, _isr&numb&_bp
- mov es,_isr&numb&_es
- mov ds,_isr&numb&_ds
- ENDM
-
-
-
- MOVE_ERRORS MACRO numb
- IFNDEF VARS_IN_CS
- mov dgroup:_Isr&numb&24Error, 1 ; tell c a critical error occured
- mov ax, di
- mov dgroup:_Isr&numb&24Result, al ; tell c which error it was
- ENDIF
- ENDM
-
-
- _text segment byte public 'CODE' ; set up so C can access assembler
- _text ends
- _data segment word public 'DATA'
- _data ends
- _bss segment word public 'BSS'
- _bss ends
-
- dgroup group _bss, _data ; group so c and assembly can share data
- assume cs:_text, ds:dgroup
-
- _data segment word public 'DATA'
- IFNDEF VARS_IN_CS
- DATAMAC %NUMBER
-
- IFNDEF STACKIS
- %OUT ***** Assembling with default 500 byte stack *****
- stack1a db 100 dup ('STACK')
- ELSE
- %OUT ***** Assembling with STACKIS byte stack *****
- stack1a db STACKIS dup ('STACK')
- ENDIF
-
- stack1 db 0
- ENDIF
-
- _data ends
-
- _text segment byte public 'CODE' ; this is so C can call these routines
- assume cs:_text, ds:dgroup ; make routines accessible to C
-
- IFDEF VARS_IN_CS
- var_start label byte
- DATAMAC %NUMBER
- var_end label byte
- ENDIF
-
- PUBLICMAC %NUMBER
-
- IFDEF VARS_IN_CS
- IFNDEF STACKIS
- %OUT ***** Assembling with default 100 byte stack *****
- stack1a db 100 dup ('STACK')
- ELSE
- %OUT ***** Assembling with STACKIS byte stack *****
- stack1a db STACKIS dup ('STACK')
- ENDIF
-
- stack1 db 0
- ENDIF
-
- oldint16 label dword
- oldint16off dw 0
- oldint16seg dw 0
-
- oldint1b label dword ; original bios control break handler
- oldint1boff dw 0
- oldint1bseg dw 0
-
- oldint23 label dword ; original control-c handler
- oldint23off dw 0
- oldint23seg dw 0
-
- oldint24 label dword ; original critical error interrupt handler
- oldint24off dw 0
- oldint24seg dw 0
-
- oldint label dword
- oldintoff dw 0
- oldintseg dw 0
-
- library label dword ; resident program that is called when hotkey is hit
- libraryoff dw 0
- libraryseg dw 0
-
- isr_size dw 0 ; size of this isr in paragraphs
-
- oldss dw 0 ; interrupted stack
- oldsp dw 0
-
- ourss dw 0 ; C's stack
- oursp dw 0
-
- ourfuncid dw 0 ; INT16h AX val to get MyId
- ourisrid dw 0 ; ID of this isr
-
- ourpsp dw 0 ; C's psp
-
- isrfunc db 0
- oldbreak db 0 ; old break status
- dos3 db 0 ; dos3 = 1 if running dos 3.x
-
- inside_isr db 0 ; indicate in 16h isr already
- ; changed 11/9/87
-
- dummy_iret: iret ; dummy iret instruction
-
- ; initisr - Initialize C ISR
- ; --------------------------
-
- START_INIT %NUMBER
- jmp short past_flags
-
- ;*** put flags here so that they can be referenced later by C code
- ;*** as an offset to the pointer for the function name _initisrX
- do_chain db 1 ; default to chain
-
- do_skip db 0 ; default not to skip normal chaining logic
-
-
- past_flags:
- push bp
- mov bp, sp ; setup stack frame
- push ds
- push es
- push si
- push di
- assume ds:DGROUP
- mov ax, DGROUP ; address C's data segment
- mov ds, ax
- ifdef LARGEMODEL
- mov ax, [bp+6]
- mov isrfunc, al
- mov ax, [bp+12]
- mov do_chain, al
- mov ax, [bp+8]
- mov libraryoff, ax
- mov ax, [bp+10]
- mov libraryseg, ax
- else
- ifdef MEDIUM
- mov ax, [bp+6]
- mov isrfunc, al
- mov ax, [bp+12]
- mov do_chain, al
- mov ax, [bp+8]
- mov libraryoff, ax
- mov ax, [bp+10]
- mov libraryseg, ax
- else
- mov ax, [bp+4]
- mov isrfunc, al
- mov ax, [bp+8]
- mov do_chain, al
- mov ax, [bp+6]
- mov libraryoff, ax
- mov ax, cs
- mov libraryseg, ax
- endif
- endif
-
- ; check version of dos
-
- mov dos3, 0 ; assume not dos 3.x
- mov ah, 30h ; to get DOS version number
- int 21h ; version is AL.AH
- cmp al, 3 ; see if dos 3.x
- jb notdos3
- mov dos3, 1 ; well its dos 3.x
-
- notdos3:
- IFDEF VARS_IN_CS
- mov ourss, cs
- mov ax, offset cs:stack1
- ELSE
- mov ourss, DGROUP
- mov ax, offset DGROUP:stack1
- ENDIF
- mov oursp, ax
-
- ; save old interrupts
- cli
- mov al, isrfunc
- mov ah, 35h
- int 21h
- mov oldintoff, bx
- mov oldintseg, es
-
- ; take over control - c to prevent break during context switch
-
- push cs
- pop ds
- mov dx, offset dummy_iret ; DS:DX=dummy vector to set
- mov ax, 2523h ; to set ^C handler through DOS
- int 21h ; now, no break will occur
-
- ; replace with our isr
-
- mov al, isrfunc
- mov ah, 25h
- mov dx, offset initlib
- int 21h
- sti
- exit_initisr:
- pop di ; restore regs there was a error
- pop si
- pop es
- pop ds
- pop bp
- ret
-
- END_INIT %NUMBER
-
- ; InitRes - Initialize And Run Resident Program And Also Do HouseKeeping
- ; ----------------------------------------------------------------------
-
- ifdef LARGEMODEL
- initlib proc far
- else
- ifdef MEDIUM
- initlib proc far
- else
- initlib proc near
- endif
- endif
- cli
- pushf
- cmp inside_isr, 0 ; *** prevent recursive entry
- jz okay_isr ; ***
-
- cmp oldintoff, 0 ; see if handler loaded
- jnz do_old_call ; yep so do it
- cmp cs:oldintseg, 0 ; see if segment is nonzero
- jnz do_old_call
-
- popf
- stc ; set carry for error
- sti
- ret 2 ; leave carry set
-
- do_old_call:
-
- popf
- jmp oldint ; call previous handler
-
- okay_isr: ; ***
- popf
- mov inside_isr,1 ; tell everyone we are in int 16
-
- ; cmp isrfunc,21h ; is this int 21h?
- ; jne were_not_21
-
- were_not_21:
- mov oldss, ss ; save interrupted stack
- mov oldsp, sp
- cli
- mov ss, ourss ; move C's stack in
- mov sp, oursp
- sti
-
- push ax
- push ds
-
- IFNDEF VARS_IN_CS
- mov ax, dgroup
- mov ds, ax
- assume ds:dgroup
- ELSE
- mov ax, cs
- mov ds, ax
- assume ds:_text
- ENDIF
- pop ax
-
- MOVE_EM_IN %NUMBER
-
-
- ; save important interrupts
-
- push es
- push ds
- assume ds:nothing
- xor ax, ax
- mov ds, ax
- cli ; No Interrupts now
- les bx, ds:[24h * 4] ; Get Int 24 address
- mov oldint24off, bx ; save it
- mov oldint24seg, es
-
- les bx, ds:[23h * 4] ; Get Int 23 address
- mov oldint23off, bx ; save it
- mov oldint23seg, es
-
- les bx, ds:[1bh * 4] ; Get Int 1b address
- mov oldint1boff, bx ; save it
- mov oldint1bseg, es
- sti ; Interrupts back on
-
- ; load in our handlers
-
- xor ax, ax
- mov ds, ax
- cli ; no interrupts now
- mov word ptr ds:[1bh * 4], offset dummy_iret
- mov word ptr ds:[1bh * 4 + 2], cs
-
- mov word ptr ds:[23h * 4], offset dummy_iret
- mov word ptr ds:[23h * 4 + 2], cs
-
- mov word ptr ds:[24h * 4], offset ourint24
- mov word ptr ds:[24h * 4 + 2], cs
- sti ; interrupts on
- pop ds
- pop es
- assume ds:dgroup
-
-
- ifdef LARGEMODEL
- call library ; dword call to popup
- else
- ifdef MEDIUM
- call library
- else
- call libraryoff ; near call to handler
- endif
- endif
-
- ; see if normal return
-
-
- cmp ax, 0 ; if al != 0, set(ff) or clear zero flag
- ; if ah != 0, set(ff) or clear carry flag
- je norm
- inc do_skip
- cmp ah, 0
- je set_zero
- cmp ah, 0ffh ; if ah == ff, carry will be cleared here
- cmc ; complement carry flag
- jmp short norm
- set_zero:
- cmp al, 0ffh ; if al ne ff, zero will not be set
- jne norm
- sub ax, ax ; this will set zero flag
- norm:
- pushf
- ; restore old vectors
-
- push ds
- push es
- xor ax, ax
- mov es, ax
-
- cli ; no interrupts now
- lds dx, oldint1b ; BIOS ctrl-break handler
-
- assume ds:nothing
-
- mov word ptr es:[1bh * 4], dx
- mov word ptr es:[1bh * 4 + 2], ds
-
- lds dx, oldint23 ; DOS ctrl-C
- mov word ptr es:[23h * 4], dx
- mov word ptr es:[23h * 4 + 2], ds
-
- lds dx, oldint24 ; DOS crit err handler
- mov word ptr es:[24h * 4], dx
- mov word ptr es:[24h * 4 + 2], ds
- sti ; interrupts back on
- pop es
- IFNDEF VARS_IN_CS
- pop ds ; restore data seg DS
- assume ds:dgroup
- ELSE
- pop ax
- push CS
- POP DS
- assume ds:_text
- ENDIF
-
- ; set return registers
-
- MOVE_EM_OUT %NUMBER
-
- assume ds:nothing
-
- popf
-
- cli ; restore interrupted stack
- mov ss, oldss
- mov sp, oldsp
- sti
-
- pushf
-
- cmp do_skip, 0
- je get_out_isr
- dec do_skip
- jmp short skip_call
- get_out_isr: ;*** change 11/9/87
- cmp do_chain, 0
- jz skip_call
- try_old:
- cmp oldintoff, 0 ; see if handler loaded
- jnz old_call ; yep so do it
- cmp oldintseg, 0 ; see if segment is nonzero
- jz skip_call
-
- old_call:
- popf
- mov inside_isr, 0
- jmp oldint ; call previous handler
- skip_call:
- popf
- push ax
- push bp
- mov bp,sp
- lahf
- mov al,ah
- mov [bp+8],al ; replace flags byte on stack
- pop bp
- pop ax
- mov inside_isr, 0
- iret ; house cleaning is finished
- initlib endp
-
- ; Free ISR - Unload ISR From Memory
- ; ---------------------------------
-
- START_FREE %NUMBER
-
- push cx ; save regs just in case not successful
- push ds
- push es
- cli
-
- mov ah, 25h ; restore previous user interrupt
- mov al, isrfunc
- lds dx, oldint
- int 21h
-
- sti
- xor ax, ax ; tell C ISR is gone
- pop es
- pop ds
- pop cx
- ret ; return for final cleanup
- END_FREE %NUMBER
-
- IFDEF VARS_IN_CS
- START_COPY %NUMBER
- IFDEF LARGEMODEL
- dir equ 6 ; dir=0 for copy from code or =1 for copy to code
- ptr_parm equ 8
- ELSE
- dir equ 4
- ptr_parm equ 6
- ENDIF
- push bp
- mov bp, sp
- push si
- push di
- push es
- push ds
- push cx
- mov cx, offset var_end - offset var_start ;code_data variables
- cmp word ptr [bp+dir],0 ;is it copy from
- jne do_copy_to
- IFDEF LARGEMODEL
- les di,[bp+ptr_parm]
- ELSE
- push ds
- pop es
- mov di,[bp+ptr_parm]
- ENDIF
- mov si, offset cs:var_start
- push cs
- pop ds
- jmp short do_copy
- do_copy_to:
- IFDEF LARGEMODEL
- lds si,[bp+ptr_parm]
- ELSE
- mov si,[bp+ptr_parm]
- ENDIF
- mov di, offset var_start
- push cs
- pop es
- do_copy:
- cld
- rep movsb
- pop cx
- pop ds
- pop es
- pop di
- pop si
- pop bp
- ret
- END_COPY %NUMBER
- ENDIF
-
-
-
- ; Intercept of Interrupt 24h -- Critical Error Interrupt Handler
- ; --------------------------------------------------------------
-
- ourint24 proc far
- assume ds:dgroup, es:nothing, ss:nothing
- push ds
- push ax
- mov ax, dgroup
- mov ds, ax
- MOVE_ERRORS %NUMBER
- pop ax
- pop ds
- mov al, 3 ; AL=3=fail system call
- cmp dos3, 1
- jz exit24
- xor al, al ; NO - have to ignore err then
-
- Exit24:
- iret ; return to DOS
- ourint24 endp
-
- _text ends
-
- end
-