FreeDOS/kernel/printer.asm

245 lines
6.8 KiB
NASM

;
; File:
; printer.asm
; Description:
; Printer device driver
;
; Copyright (c) 1998
; Pasquale J. Villani
; All Rights Reserved
;
; This file is part of DOS-C.
;
; DOS-C is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version
; 2, or (at your option) any later version.
;
; DOS-C is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
; the GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with DOS-C; see the file COPYING. If not,
; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA.
;
; $Header$
;
%include "io.inc"
%define PRT_TIMEOUT 01h
%define PRT_IOERROR 08h
%define PRT_SELECTED 10h
%define PRT_OUTOFPAPER 20h
%define PRT_ACK 40h
%define PRT_NOTBUSY 80h
%define PRT_WRITECHAR 00h
%define PRT_INITPORT 01h
%define PRT_GETSTATUS 02h
segment _IO_FIXED_DATA
global LptTable
LptTable db 18h
dw _IOExit
dw _IOExit
dw _IOExit
dw _IOCommandError
dw _IOSuccess
dw _IODone
dw _IOExit
dw _IOExit
dw PrtWrite
dw PrtWrite
dw PrtOutStat
dw _IOExit
dw _IOExit
dw _IOExit
dw _IOExit
dw _IOExit
dw PrtOutBsy
dw _IOExit
dw _IOExit
dw PrtGenIoctl
dw _IOExit
dw _IOExit
dw _IOExit
dw _IOCommandError
dw _IOCommandError
segment _IO_TEXT
global uPrtNo
uPrtNo db 0
uPrtQuantum dw 50h
dw 50h, 50h
db 50h, 00h
PrtWrite:
jcxz PrtWr3 ; Exit if nothing to write
PrtCharLoop: ; next character loop
mov bx, 2 ; number of retries
PrtRetryTwice:
mov ah, PRT_GETSTATUS ; get status, ah=2
call PrtIOCall ;
jnz PrtWr4
mov al,[es:di]
mov ah, PRT_WRITECHAR ; print character, ah=0
call PrtIOCall ; (0800)
jnz PrtWr4 ; NZ = error, retry
inc di
loop PrtCharLoop ; next character
PrtWr3:
jmp _IOExit
PrtWr4: ; repeat
dec bx
jnz PrtRetryTwice
PrtWr5:
jmp _IOErrCnt
PrtOutStat:
call GetPrtStat
jnz PrtWr5
mov al, E_PAPER
test ah, PRT_OUTOFPAPER
jnz PrtWr5
test ah, PRT_NOTBUSY
jnz PrtWr3
jmp _IODone
GetPrtStat:
mov ah,PRT_GETSTATUS
PrtIOCall:
call GetUnitNum
int 17h ; print char al, get status ah
mov al, ah ; if (stat & 0x30) == 0x30 return 10;
and al, PRT_SELECTED|PRT_OUTOFPAPER
cmp al, PRT_SELECTED|PRT_OUTOFPAPER
mov al, E_WRITE
je ret_error_code
test ah, PRT_OUTOFPAPER|PRT_IOERROR|PRT_TIMEOUT ; 29h
mov al, E_NOTRDY
jz ret_error_code
test ah, PRT_OUTOFPAPER ; 20h
mov al, E_WRITE
jz ret_error_code ; not out of paper -> E_WRITE
ret_error_code_9:
mov al, E_PAPER
ret_error_code:
cmp al, E_NOTRDY ; 2 = no error
retn
PrtOutBsy:
push ds
push es
pop ds
mov si,di
PrtOtBsy1:
push cx
push bx
xor bx,bx
mov bl,[cs:uPrtNo]
shl bx,1
mov cx,[cs:uPrtQuantum+bx]
pop bx
PrtOtBsy2:
call GetPrtStat
jnz PrtOtBsy3
test ah, PRT_NOTBUSY
loopz PrtOtBsy2
pop cx
jz PrtOtBsy4
lodsb
xor ah,ah
call PrtIOCall
jnz PrtOtBsy4
loop PrtOtBsy1
pop ds
lds bx,[cs:_ReqPktPtr]
sub [bx+12h],cx
jmp _IOExit
PrtOtBsy3:
pop cx
PrtOtBsy4:
pop ds
lds bx,[cs:_ReqPktPtr]
sub [bx+12h],cx
jmp _IOErrorExit
PrtGenIoctl:
les di,[cs:_ReqPktPtr]
cmp byte [es:di+0Dh],5
je PrtGnIoctl2
PrtGnIoctl1:
jmp _IOCommandError
PrtGnIoctl2:
mov al,[es:di+0Eh]
les di,[es:di+13h]
xor bx,bx
mov bl,[cs:uPrtNo]
shl bx,1
mov cx,[cs:uPrtQuantum+bx]
cmp al,65h
je PrtGnIoctl3
cmp al,45h
jne PrtGnIoctl1
mov cx,[es:di]
PrtGnIoctl3:
mov [cs:uPrtQuantum+bx],cx
mov [es:di],cx
jmp _IOExit
;
; some comments to last changes (TE, 23/09/01)
;
; original implementation didn't print at all - on my machine,LPT2
;
; maybe this one is not much better either,
; but should print a little bit
;
; the status bits = AH
;
; 1 0
; 80 - BUSY not busy busy
; 40 - ACK transfer finished not yet finished
; 20 - PAP no paper available paper OK
; 10 - ONOF printer online not online
; 08 - ERR some error no error
; 01 - TIM some error when transfer OK
;
; some states
; 30 - there is no printer at all
; c8 - there is a printer without power
; 10 - printer with power, but not initialized
; 90 - this one is fine
;
; you must not simply print without asking for status
; as the BIOS has a LARGE timeout before aborting
;