Question

I have a trouble with making TSR com file for DOS. It should set a new handler on a 21'th interrupt, terminate and stay resident. New handler should transfer control to an old interrupt 21h handler. I save its interrupt vector, but have no idea how to call it correctly. Here is a program:

.model tiny
.data
    old_int21h dw ?, ?
.code
org 100h
start:

    ;saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

    ;setting new interrupt vector
    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

    ; TSR
    lea dx, start
    int 27h

myint21h proc
    ; doing something
    ; want to transfer control to an old interrupt 21h handler here. How?
    iret
myint21h endp

end start
Was it helpful?

Solution

I understood the problem. The right solution is here. "Right" isn't sure "optimal", but works nice anyway, and it isn't hard enough to optimize this code now.

.model tiny
.code
org 100h
start:

    ; saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

    ; setting new interrupt vector
    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

    ; TSR
    mov dx, 00ffh
    mov ax, 3100h
    int 21h

    ; here comes data & hew handler part
    old_int21h dw ?, ?

    myint21h proc
                    ; some stuff
                    ; transfer control to an old interrupt 21h handler
        push word ptr [cs:old_int21h + 2] ; segment
        push word ptr [cs:old_int21h]     ; offset
        retf
    myint21h endp

end start

The answer below was almost right :)

OTHER TIPS

My 16-bit DOS ASM is a bit rusty, but if I recall correctly you need to do this:

push word ptr [old_int21h + 2] ; segment
push word ptr [old_int21h]     ; offset
retf
     .model tiny
     .code
     org 100h
     start:

; Inicializando la fecha para LotusWorks
    mov ax, 2A21h
    int 21h
    mov [Reg_DX], dx
        sub cx,064h
    mov [Reg_CX], cx

; saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

; setting new interrupt vector

    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

     ; TSR
    mov dx, 00ffh
    mov ax, 3100h
    int 21h

     ; here comes data & hew handler part

    old_int21h dw ?, ?
    Reg_DX     dw ?, ?
    Reg_CX     dw ?, ?

     myint21h proc

       cmp ah,2ah
       jne S1
           cmp al,56h
           je  S2
           mov ah,02h
           int 01AH
           cmp cx,0
           jne Mismodia
           mov ax,02A56h
           int 21h
      mov [CS:Reg_DX], dx

MismoDia:
       mov cx, [cs:Reg_CX]
       mov al,00
       mov dx, [cs:Reg_DX]
       iret

       S2:
           mov al,0

       S1:
        ; transfer control to an old
        ; interrupt 21h handler


        push word ptr [cs:old_int21h + 2]   ; segment
        push word ptr [cs:old_int21h]       ; offset
        retf
    myint21h endp

     end start
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top