; Svjatoslav Agejenko ; 2002.08 ; compile with FASM - Flat Assembler ; TSR driver for LPT1 communication. ; Functions by INT 63h: ; Deactivate ; AH = 0 ; Activate ; AH = 1 ; Get downloaded data ; AH = 2 ; ES:DI - pointer where to place downloaded data ; on return: ; AX = Number of bytes downloaded ; copies downloaded data from driver input buffers to ; specified place. ; Upload data ; AH = 3 ; DS:SI - pointer for data to be uploaded ; CX - amount of bytes to upload ; After interrupt, data will be immediately ; moved to communication driver own output buffer, ; and sent when line becomes avaiable. myint = 63h ; interrupt to hook upbuf = 5000 ; upload buffer size downbuf = 5000 ; download buffer size InPort = 37ah ; input port, for Parallel Printer Port Control Register defspd = 3 ; Default communication speed upbufp = last + downbuf org 100h ;============================ TSR initialization ==================== mov dx, InPort ; reset line mov al, 0 out dx, al mov ax, 0 ; Saves old interrupt vector mov es, ax mov eax, [es:32] mov [d2], eax cli mov ax, cs ; Set new interrupt vector for IRQ 0 shl eax, 16 mov ax, custom mov [es:32], eax mov ax, int63 ; Set new interrupt vector for INT 63 mov [es:4 * myint], eax sti mov ax, last ; Calculate needed memory size, begin TSR add ax, upbuf + downbuf + 1000 mov dx, 0 mov bx, 16 div bx mov dx, ax mov ax, 3100h int 21h d2 dd 0 ;============================ IRQ 0 handler ========================= custom: pushf ; Execute default code in old int vector call dword [cs:d2] ;pusha ; Write 1 character, for debugging ;mov ax, 0e01h ;mov bx, 0 ;int 10h ;popa inc byte [cs:tmr] ; Update timer cmp [cs:progress], 0 ; Check if custom routine is already active jne EndOfRoutine cmp [cs:enabled], 0 ; Check if driver is enabled je EndOfRoutine mov [cs:progress], 1 ; Set active flag pusha push ds push es mov dx, InPort in al, dx shl al, 4 cmp al, 128 jb checkdone ;============================ download data from LPT ================ mov ax, cs mov es, ax mov ds, ax mov di, last add di, [dbufsiz] mov bh, 0 SkipHeader: in al, dx shl al, 6 cmp al, 128 jae SkipHeader mov ah, 255 mov cx, 0 SkipBit: inc cx cmp cx, 30 je MkHeader in al, dx cmp al, ah je SkipBit in al, dx mov cx, 0 mov ah, al shr al, 3 or al, 254 sub al, 254 shl bl, 1 add bl, al inc bh cmp bh, 8 jb SkipBit mov al, bl stosb mov bh, 0 mov bl, bh jmp SkipBit MkHeader: mov ax, di sub ax, last sub ax, [dbufsiz] stosw mov ax, di sub ax, last mov [dbufsiz], ax checkdone: cmp word [cs:ubufsiz], 0 je alldone ; =========================== send data to LPT ====================== mov ax, cs mov ds, ax mov byte [tmr], 0 mov dx, InPort mov al, 255 out dx, al mov si, upbufp mov cx, [ubufsiz] sti SendHeader: cmp byte [tmr], 2 jb SendHeader cli SendByte: cmp cx, 0 je sent mov bl, 0 lodsb SendBit: push ax push cx shr al, 4 or al, 247 sub al, 247 mov bh, bl or bh, 254 sub bh, 254 shl bh, 1 add al, bh mov ch, 0 mov cl, [spd] WaitForBit: out dx, al loop WaitForBit pop cx pop ax inc bl shl al, 1 cmp bl, 8 jb SendBit dec cx jmp SendByte sent: mov al, 0 out dx, al mov word [ubufsiz], 0 alldone: pop es pop ds popa mov [cs:progress], 0 ; Terminate active flag EndOfRoutine: iret progress db 0 enabled db 0 dbufsiz dw 0 ubufsiz dw 0 tmr db 0 spd db defspd ;============================ INT 63h handler ======================= int63: cmp ah, 0 je set_unactive cmp ah, 1 je set_active cmp ah, 2 je get_data cmp ah, 3 je send_data jmp EndOfRoutine set_active: mov dx, InPort ; reset line mov al, 0 out dx, al mov [cs:enabled], 1 jmp EndOfRoutine set_unactive: mov [cs:enabled], 0 jmp EndOfRoutine get_data: push ds mov ax, cs mov ds, ax mov si, last mov cx, [dbufsiz] rep movsb pop ds mov ax, [cs:dbufsiz] mov [cs:dbufsiz], 0 jmp EndOfRoutine send_data: push es mov dx, cx mov bx, cs mov es, bx mov di, upbufp add di, [cs:ubufsiz] rep movsb add [cs:ubufsiz], dx pop es jmp EndOfRoutine last: