From: kovert@wam.umd.edu (Todd Kover)
Subject: tsr
Keywords: int17 int dasness tsr
Organization: Workstations at Maryland, University of Maryland, College Park
Date: Wed, 16 Dec 1992 20:37:06 GMT


I'm in the process of writing a TSR that buffers the characters that go to
the LPT2 port so that they can be picked up by another program.  Unfortunately,
as I free up memory right before exiting (int 21h/4ah) I get a "memory
control block destroyed" error.  I'd imagine I've overlooked something, but
I've spent many hours last night (read: this morning) and today trying to
solve this final problem...  This is my first venture into TSR writing,
as well.

Anybody got any comments as to what I'm doing wrong? Thanks in advance for
your help!

-Todd

;
; RDLTSR.ASM -- Resident LPT Port printer memory buffer
;

.MODEL TINY
.STACK 400h
.CODE

@display MACRO msg
        push ax
        push ds
        push dx
        mov  ax,@code
        mov  ds,ax
        mov  dx,offset msg      ; msg to printout.
        mov  ah,09h             ; DOS PrintString function
        int  21h
        pop  dx
        pop  ds
        pop  ax
ENDM

StartOProgram:
        jmp Initilize_Program                  ; goto start of program

ACK             equ     4242h   ; acknowledge our existance with this #.
PrintStatus     equ     10010000B
BufSize         equ     8196    ; Size of the buffer we kee


LPTPort         dw      0       ; # for LPT port: 0==LPT1, 1==LPT2, 2==LPT3
old_17h         dd      0       ; Address of int 17h's old routine
LPTBuffer       db      BufSize DUP (?)
LPTHead         dw      (?)
LPTTail         dw      (?)

PUBLIC _int_17h_proc

;------------------------------------------------------------------------------
;
; Replacement interupt vector for INT 17
;
;------------------------------------------------------------------------------
PROC _int_17h_proc far
        ASSUME DS:NOTHING,ES:NOTHING
        pushf
        push ds
        push bx
        push ax

        cmp ah,05h      ; Looking to see if we're here?
        je  ack_em      ; tell em we're here.

        cmp ah,06h      ; They're asking for a byte.
        je  get_byte    ; give it to 'em

        cmp ah,07h      ; Setting the LPT port
        je  set_lpt     ; set it

        cmp DX, [cs:LPTPort]    ; our printer?
        jne old_handle17        ; no.

        cmp ah, 00h     ; print call?
        je  capture     ; go do stuff

ret_stat:               ; otherwise do the normal thang.
        pop ax
        pop bx
        pop ds
        popf
        mov ah, PrintStatus
        iret

ack_em:
        pop ax
        pop bx
        pop ds
        popf
        mov ax,ACK              ; We acknowledge our presence with this
        iret

set_lpt:
        mov LPTPort,dx          ; LPT port is put in dx
        pop ax
        pop bx
        pop ds
        popf
        mov ax,ACK              ; non-zero for success
        iret

get_byte:
        pop ax                          ; recover from before
        pop bx
        pop ds
        popf

        push bp                         ; let the games begin.
        push ds

        mov ax,cs
        mov ds,ax

        mov bp,sp
        xor ax,ax                       ; set value to zero in case 'o error

        mov bx,[LPTTail]                ; empty?
        cmp bx,[LPTHead]
        je  return_byte                 ; yes -- return

        mov al, [byte ptr bx]           ; get byte from current place
        inc [LPTTail]                   ; goto next space
        cmp [word ptr LPTTail], offset LPTBuffer+BufSize        ; end'obuf?
        jb  return_byte

        mov [LPTTail], offset LPTBuffer ; at end -- goto beginning

return_byte:
        pop ds
        pop bp
        mov ah,PrintStatus
        iret

old_handle17:
        pop ax
        pop bx
        pop ds
        popf
        jmp [CS:old_17h]

capture:
                                                ; al contains byte to write

        mov bx, [LPTHead]                       ; Place to put byte
        mov [byte ptr bx], al                   ; Move byte to place in
        inc bx                                  ; Next space is the place
        cmp bx, offset LPTBuffer + BufSize      ; at end?
        jb @@10
        mov bx, offset LPTBuffer                ; wrap around
@@10:
        cmp bx, [LPTTail]
        jne @@20
        mov bx, [LPTHead]
@@20:
        mov [LPTHead],bx
@@end:
        jmp ret_stat
ENDP    _int_17h_proc

EndOfRes        db      0

WelcomeMsg      db '',13,10
                db '                        ',13,10
                db ' RDLINK - PTRBUF TSR v1 ',13,10
                db '    by Todd M. Kover    ',13,10
                db '                        ',13,10
                db '',13,10,13,10,'$'

InstallMsg      db 'TSR Installed.',13,10,'$'
AlreadyHereMsg  db 'TSR Already Installed.',13,10,'$'
AllocErrorMsg   db 'Memory Allocation Error.  TSR Not Installed.',13,10,'$'

Initilize_Program:
        mov ax,cs
        mov ds,ax

        @display WelcomeMsg

        mov ah,05h                      ;Check to see if we're here
        int 17h
        je already_installed            ;notify user of carelessness

        mov ax, offset LPTBuffer        ;Set Head AND Tail to beginning
        mov [LPTHead], ax               ;of buffer
        mov [LPTTail], ax

        mov ax,3517h                    ;get current intvect for 17h
        int 21h
        mov [word ptr old_17h],bx
        mov [word ptr old_17h+2],es     ;save it for later use

        mov ax,2517h                    ;set current intvect for 17h
        mov dx, offset _int_17h_proc    ;Our interrupt vector
        int 21h                         ;ds == cs

        mov ax,@code
        mov es,ax                       ;Put SEGMENT of block in ES
        mov bx,offset EndOfRes          ;Get end of resident code
        add bx,15                       ;Add a paragraph
        mov cl,4                        ;Shift by 4 to divide by 16
        shr bx,cl                       ;This converts to paragraphs
        mov ax,4a00h                    ;Dos setblock function call
        int 21h                         ;Modify memory block
        jnc ExitTSR                     ;If it worked ok, then continue

Alloc_Error:
        @display AllocErrorMsg
        mov dx,[word ptr old_17h]       ;restore old int 17h vector
        mov ax,[word ptr old_17h+2]
        mov ds,ax
        mov ax,2517h                    ;Restore int 17h vector from DS:DX
        int 21h

        JMP ExitNoTSR                   ;Exit the TSR wo/residence

ExitTSR:
        @display InstallMsg

        mov dx,offset EndOfRes          ;Move End of Resident Part to dx
        add dx,15
        mov cl,4                        ;shifting right 4 == division by 16
        shr dx,cl                       ;Conversion to paragraphs
        mov ax,3100h                    ;func 31; return code == 0
        int 21h                         ;Terminate and Stay Resident

already_installed:
        @display AlreadyHereMsg

ExitNoTSR:
        mov ax,4c00h                    ;4c==exit, retcode==0
        int 21h                         ;c-ya

END

--<cut here>

-- 
Internet: kovert@wam.umd.edu +================+ #include <witty/disclaimer.h>
         kovert@glue.umd.edu | Todd Kover //  | "Murphy's Law of Dating II: If
Fido: 1:109/447 & 1:261/5016 |          \X/   |  you like her, she lives in a
             CIS: 70621,2376 +================+  different state."
Newsgroups: comp.os.msdos.programmer