Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

pdfaoa / CH21

.PDF
Скачиваний:
13
Добавлен:
15.06.2014
Размер:
88.16 Кб
Скачать

 

 

 

The PC Parallel Ports

SyncLoop:

mov

cx, 0

;For time out purposes.

SyncLoop0:

inc

dx

;Point at input port.

 

in

al, dx

;Read our input bits.

 

dec

dx

 

 

and

al, 78h

;Keep only the data bits.

 

cmp

al, 78h

;Check for all ones.

 

je

Got1s

;Branch if all ones.

 

cmp

al, 0

;See if all zeros.

 

loopne

SyncLoop0

 

; Since we just saw a zero, write all ones to the output port.

mov

al,

0FFh

;Write all ones

out

dx,

al

 

; Now wait for all ones to arrive from the transmitting site.

SyncLoop1:

inc

dx

;Point at status register.

 

in

al, dx

;Read status port.

 

dec

dx

;Point back at data register.

 

and

al, 78h

;Keep only the data bits.

 

cmp

al, 78h

;Are they all ones?

 

loopne

SyncLoop1

;Repeat while not ones.

 

je

Got1s

;Branch if got ones.

;If we’ve timed out, check to see if the user has pressed ctrl-C to

;abort.

call

TestAbort

;Check for ctrl-C.

dec

bx

;See if we’ve timed out.

jne

SyncLoop

;Repeat if time-out.

print

 

 

byte

“Receive: connection timed out during synchronization”

byte

cr,lf,0

 

clc

 

;Signal time-out.

ret

 

 

;Jump down here once we’ve seen both a zero and a one. Send the two

;in combinations until we get a 05h from the transmitting site or the

;user presses Ctrl-C.

Got1s:

inc

dx

;Point at status register.

 

in

al, dx

;Just copy whatever appears

 

dec

dx

; in our input port to the

 

shr

al, 3

; output port until the

 

and

al, 0Fh

; transmitting site sends

 

cmp

al, 05h

; us the value 05h

 

je

Synchronized

 

 

not

al

;Keep inverting what we get

 

out

dx, al

; and send it to xmitter.

 

call

TestAbort

;Check for CTRL-C here.

 

jmp

Got1s

 

; Okay, we’re synchronized. Return to the caller.

Synchronized:

 

 

 

 

and

al, 0Fh

;Make sure busy bit is one

 

out

dx, al

; (bit 4=0 for busy=1).

 

print

 

 

 

byte

“Synchronized with transmitting site”

 

byte

cr,lf,0

 

 

stc

 

 

 

ret

 

 

Synchronize

endp

 

 

;GetFileInfoThe transmitting program sends us the file length and a

;zero terminated filename. Get that data here.

GetFileInfo

proc

near

 

 

mov

dx, MyPortAdrs

 

 

mov

al, 10h

;Set busy bit to zero.

Page 1219

Chapter 21

out

dx, al

;Tell xmit pgm, we’re ready.

; First four bytes contain the filesize:

call

GetByte

mov

byte ptr FileSize, al

call

GetByte

mov

byte ptr FileSize+1, al

call

GetByte

mov

byte ptr FileSize+2, al

call

GetByte

mov

byte ptr FileSize+3, al

; The next n bytes (up to a zero terminating byte) contain the filename:

 

mov

bx, 0

GetFileName:

call

GetByte

 

mov

FileName[bx], al

 

call

TestAbort

 

inc

bx

 

cmp

al, 0

 

jne

GetFileName

 

ret

 

GetFileInfo

endp

 

;GetFileDataReceives the file data from the transmitting site

;and writes it to the output file.

GetFileData

proc

near

 

; First, see if we have more than 512 bytes left to go

 

 

cmp

word ptr FileSize+2, 0

;If H.O. word is not

 

jne

MoreThan512

; zero, more than 512.

 

cmp

word ptr FileSize, 512

;If H.O. is zero, just

 

jbe

LastBlock

; check L.O. word.

;We’ve got more than 512 bytes left to go in this file, read 512 bytes

;at this point.

MoreThan512:

mov

cx, 512

;Receive 512 bytes

 

lea

bx, FileBuffer

; from the xmitter.

ReadLoop:

call

GetByte

;Read a byte.

 

mov

[bx], al

;Save the byte away.

 

inc

bx

;Move on to next

 

loop

ReadLoop

; buffer element.

; Okay, write the data to the file:

mov

ah, 40h

;DOS write opcode.

mov

bx, FileHandle

;Write to this file.

mov

cx, 512

;Write 512 bytes.

lea

dx, Filebuffer

;From this address.

int

21h

 

jc

BadWrite

;Quit if error.

; Decrement the file size by 512 bytes:

 

sub

word ptr FileSize, 512

;32-bit subtraction

sbb

word ptr FileSize, 0

; of 512.

jmp

GetFileData

 

; Process the last block, that contains 1..511 bytes, here.

LastBlock:

 

 

 

 

mov

cx, word ptr FileSize

;Receive the last

 

lea

bx, FileBuffer

; 1..511 bytes from

ReadLB:

call

GetByte

; the transmitter.

 

mov

[bx], al

 

 

inc

bx

 

 

loop

ReadLB

 

Page 1220

 

 

 

The PC Parallel Ports

 

mov

ah, 40h

;Write the last block

 

mov

bx, FileHandle

; of bytes to the

 

mov

cx, word ptr FileSize

; file.

 

lea

dx, Filebuffer

 

 

int

21h

 

 

jnc

Closefile

 

BadWrite:

print

 

 

 

byte

“DOS error #”,0

 

 

puti

 

 

 

print

 

 

 

byte

“ while writing data.”,cr,lf,0

 

; Close the file here.

 

 

CloseFile:

mov

bx, FileHandle

;Close this file.

 

mov

ah, 3Eh

;DOS close opcode.

 

int

21h

 

 

ret

 

 

GetFileData

endp

 

 

; Here’s the main program that gets the whole ball rolling.

Main

proc

 

 

mov

ax, dseg

 

mov

ds, ax

 

meminit

 

; First, get the address of LPT1: from the BIOS variables area.

 

mov

ax, 40h

;Point at BIOS variable segment.

 

mov

es, ax

 

 

mov

ax, es:[PrtrBase]

 

 

mov

MyPortAdrs, ax

 

 

call

Synchronize

;Wait for the transmitter program.

 

jnc

Quit

 

 

call

GetFileInfo

;Get file name and size.

 

printf

 

 

 

byte

“Filename: %s\nFile size: %ld\n”,0

 

dword

Filename, FileSize

 

mov

ah, 3Ch

;Create file.

 

mov

cx, 0

;Standard attributes

 

lea

dx, Filename

 

 

int

21h

 

 

jnc

GoodOpen

 

 

print

 

 

 

byte

“Error opening file”,cr,lf,0

 

jmp

Quit

 

GoodOpen:

mov

FileHandle, ax

 

 

call

GetFileData

;Get the file’s data.

Quit:

ExitPgm

 

;DOS macro to quit program.

Main

endp

 

 

cseg

ends

 

 

sseg

segment

para stack ‘stack’

stk

byte

1024 dup (“stack “)

sseg

ends

 

 

zzzzzzseg

segment

para public ‘zzzzzz’

LastBytes

byte

16 dup (?)

 

zzzzzzseg

ends

 

 

 

end

Main

 

Page 1221

Chapter 21

21.5Summary

The PC’s parallel port, though originally designed for controlling parallel printers, is a general purpose eight bit output port with several handshaking lines you can use to control many other devices in addition to printers.

In theory, parallel communications should be many times faster than serial communications. In practice, however, real world constraints and economics prevent this from being the case. Nevertheless, you can still connect high performance devices to the PC’s parallel port.

The PC’s parallel ports come in two varieties: unidirectional and bidirectional. The bidirectional versions are available only on PS/2s, certain laptops, and a few other machines. Whereas the eight data lines are output only on the unidirectional ports, you can program them as inputs or outputs on the bidirectional port. While this bidirectional operation is of little value to a printer, it can improve the performance of other devices that connect to the parallel port, such as disk and tape drives, network adapters, SCSI adapters, and so on.

When the system communicates with some other device over the parallel port, it needs some way to tell that device that data is available on the data lines. Likewise, the devices needs some way to tell the system that it is not busy and it has accepted the data. This requires some additional signals on the parallel port known as handshaking lines. A typical PC parallel port provides three handshaking signals: the data available strobe, the data taken acknowledge signal, and the device busy line. These lines easily control the flow of data between the PC and some external device.

In addition to the handshaking lines, the PC’s parallel port provides several other auxiliary I/O lines as well. In total, there are 12 output lines and five input lines on the PC’s parallel port. There are three I/O ports in the PC’s address space associated with each I/O port. The first of these (at the port’s base address) is the data register. This is an eight bit output register on unidirectional ports, it is an input/output register on bidirectional ports. The second register, at the base address plus one, is the status register. The status register is an input port. Five of those bits correspond to the five input lines on the PC’s parallel port. The third register (at base address plus two) is the control register. Four of these bits correspond to the additional four output bits on the PC, one of the bits controls the IRQ line on the parallel port, and a sixth bit controls the data direction on the birdirectional ports.

For more information on the parallel port’s hardware configuration, see:

“Basic Parallel Port Information” on page 1199

“The Parallel Port Hardware” on page 1201

Although many vendors use the parallel port to control lots of different devices, a parallel printer is still the device most often connected to the parallel port. There are three ways application programs commonly send data to the printer: by calling DOS to print a character, by calling BIOS’ int 17h ISR to print a character, or by talking directly to the parallel port. You should avoid this last technique because of possible software incompatibilities with other devices that connect to the parallel port. For more information on printing data, including how to write your own int 17h ISR/printer driver, see:

“Controlling a Printer Through the Parallel Port” on page 1202

“Printing via DOS” on page 1203

“Printing via BIOS” on page 1203

“An INT 17h Interrupt Service Routine” on page 1203

One popular use of the parallel port is to transfer data between two computers; for example, transferring data between a desktop and a laptop machine. To demonstrate how to use the parallel port to control other devices besides printers, this chapter presents a program to transfer data between computers on the unidirectional parallel ports (it also works on bidirectional ports). For all the details, see

“Inter-Computer Communications on the Parallel Port” on page 1209

Page 1222

Соседние файлы в папке pdfaoa