|
|
title "Parallel Write Loop" ;++ ; ;Copyright (c) 1994 Microsoft Corporation ; ;Module Name: ; ; parloop.c ; ;Abstract: ; ; This module contains the i386 version of the ; write loop for the parallel driver. ; ;Author: ; ; Norbert P. Kusters 9-Mar-1994 ; ;Environment: ; ; Kernel mode ; ;Notes: ; ; This module makes use of the IN and OUT commands. Making ; use of these commands is generally not portable and so using ; IN and OUT should only be used when performance is critical. ; ;Revision History : ; ;--
.386p
.xlist include callconv.inc .list
; ; Parallel control register definitions. ;
L_NORMAL equ 0CCH L_STROBE equ 0CDH
; ; Parallel status "ok to send" definition. ;
L_INVERT equ 098H L_NOT_READY equ 0B8H
_TEXT SEGMENT DWORD PUBLIC 'CODE' ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
;++ ; ;Routine Description: ; ; This routine outputs the given write buffer to the parallel port ; using the standard centronics protocol. ; ;Arguments: ; ; Controller - Supplies the base address of the parallel port. ; ; WriteBuffer - Supplies the buffer to write to the port. ; ; NumBytesToWrite - Supplies the number of bytes to write out to the port. ; ;Return Value: ; ; The number of bytes successfully written out to the parallel port. ; ;Notes: ; ; This routine runs at DISPATCH_LEVEL. ; ;--
Controller equ [esp + 8] WriteBuffer equ [esp + 12] NumBytesToWrite equ [esp + 16]
cPublicProc _ParWriteLoop, 3 cPublicFpo 3, 1
push ebx mov edx,Controller ; Set up DX for OUT mov ecx,NumBytesToWrite ; Set up CX for LOOP mov ebx,WriteBuffer ; Start of write buffer
inc edx ; Point to status register
align 4 @@:
; Get the status lines, read until two sucessive reads are the same.
in al,dx mov ah,al in al,dx cmp al,ah jnz @b
; Check the status lines.
xor al,L_INVERT and al,L_NOT_READY jnz short @f ; If the printer isn't ready then abort
; Output a character to the printer
mov al,[ebx] dec edx ; Point to data register inc ebx out dx,al ; Set data lines add edx,2 ; Point to control register mov al,L_STROBE out dx,al ; Turn strobe on mov al,L_NORMAL jmp $+2 jmp $+2 jmp $+2 jmp $+2 out dx,al ; Turn strobe off dec edx ; Point to status register
dec ecx jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jmp $+2 jnz short @b ; Continue until ECX = 0
@@:
; return the number of bytes output in EAX
mov eax,NumBytesToWrite ; Put 'NumBytesToWrite' in EAX sub eax,ecx ; Subtract the number of bytes not written pop ebx
stdRET _ParWriteLoop
stdENDP _ParWriteLoop
_TEXT ends
end
|