;       SCCSID = @(#)int21tsr.asm	6.1 91/06/17

TEST_INT        equ     21h     ; Software interrtupt number to test.
MAJOR_CODE      equ     50h     ; DEKKO major code for this service.
DEKKO_SEGMENT   equ  0C800h     ; Memory mapped segment for DEKKO I/O.
MAJMIN_CODE     equ      4h     ; Offset into the Dekko memory mapped
                                ; segment where the DEKKO data is written.

CSEG    segment
        assume  cs:CSEG,ds:CSEG,es:CSEG,ss:CSEG
        org     100h
MAIN    proc    near

        jmp     short start

function db     ?,MAJOR_CODE
old_int dd      ?
int_ret dd      ?
vector  db      TEST_INT

start:

;------ set up registers
        xor     bx,bx
        mov     es,bx
        assume  es:nothing
        mov     bl,[vector]
        shl     bx,1
        shl     bx,1
        mov     ax,cs
        mov     cx,offset new_int
;ES:BX=dword vector in the IVT (Interrupt Vector Table)
;AX:CX=new interrupt vector

;------ perform the hook
        cli
        xchg    cx,es:[bx]
        xchg    ax,es:[bx]+2
        mov     word ptr [old_int],cx
        mov     word ptr [old_int]+2,ax
        sti

;------ Terminate stay resident, using int 27h
        mov     dx,offset TSR
        cmp     [vector],27h
        je      dont_use_int27h
        int     27h
dont_use_int27h:

;------ Terminate stay resident, using int 21h because this is hooking int 27h
        add     dx,15
        shr     dx,1
        shr     dx,1
        shr     dx,1
        mov     ax,3100h
        int     21h

MAIN    endp


new_int proc    far
        assume  cs:CSEG,ds:NOTHING,es:NOTHING,ss:NOTHING

;------ save the interrupt return address
        pop     word ptr [int_ret]
        pop     word ptr [int_ret]+2

;------ Execute DEKKO PreHook intructions.
        push    es
        push    ax

        mov     cs:[Function],ah
        mov     ax,DEKKO_SEGMENT
        mov     es,ax                   ;Addressibility to DEKKO I/O.
        mov     ax,word ptr cs:[Function]
        mov     es:[MAJMIN_CODE],ax

        pop     ax                      ;AX <- value from app program.
        pop     es                      ;ES <- value from app program.
                                        ;the PostHook event.

;------ perform the old interrupt action
        call    [old_int]
        pushf

;------ Execute DEKKO PostHook intructions.
        push    es
        push    ax

        mov     ax,DEKKO_SEGMENT
        mov     es,ax                   ;Addressibility to DEKKO I/O.
        mov     ax,word ptr cs:[Function]
        or      al,80h
        mov     es:[MAJMIN_CODE],ax

        pop     ax
        pop     es

;------ All done.  Return to software interrupt caller.
        push    word ptr [int_ret]+2
        push    word ptr [int_ret]
        iret

new_int endp
TSR:
CSEG    ends
        end     MAIN
