Article View: sci.electronics
Article #3026Printer Port
From: francis deck
Date: Fri, 17 Apr 1992 21:12
Date: Fri, 17 Apr 1992 21:12
246 lines
8415 bytes
8415 bytes
I got so many requests about my printer port FAQs that I thought
I'd just post them. They are in the form of two Turbo Pascal
programs:
{
SYSTEM RAM DATA
Location Size Description
$40:08 4 words I/O address of up to 4 printer adapters.
$40:10 1 word Bits 15-14 = Number of printer adapters.
$40:78 4 bytes One byte per adapter. Time-out values
for printers 1 through 4.
PARALLEL PRINTER I/O PORTS
The i/o address found by checking System RAM location $40:08
is first of a block of three i/o ports, here numbered A+0
through A+2.
Port Description
A+0 Data output port, bits D0-D7.
A+1 Status input port, where:
Bit Mnemonic
0-1 Reserved
2 IRQ has occurred
3 Error
4 Select Input
5 Paper Out
6 Acknowledge
7 Busy
A+2 Control output port, where:
Bit Mnemonic
0 Strobe
1 Auto Feed
2 Init Printer
3 Select
4 Enable IRQ
5-7 Reserved
PARALLEL PORT PINOUT
The parallel port is a female DB25 connector, with the
following pinout:
Pin Mnemonic
1 Strobe
2-9 D0-D7
10 Acknowledge
11 Busy
12 Paper Out
13 Select (input)
14 Auto Feed
15 Error
16 Init Printer
17 Select (output)
18-25 Ground
COMMENTS
Printer port outputs and inputs are simple TTL lines. For
high-speed applications, output lines may have to be
terminated with pull-up resistors at the receiving end.
I understand that some PCs implement the parallel port with
an 8255 or some such device, allowing reconfiguration of the
data direction of the port i/o lines. I don't do this,
since some PCs, my Zenith included, use unidirectional port
chips for all the LPT i/o lines. For greatest
compatibility, stick to the data directions listed above!
REFERENCES
System BIOS for IBM PC/XT/AT computers and compatibles; the
complete guide to ROM-based system software, Phoenix
Technologies, Ltd, (Reading Mass.: Addison-Wesley Pub. Co.,
1989)
Owner's manual for Zenith Z-148 PC.
{======== Turbo Pascal printer port demp LPTDEMO.PAS =======}
program lptdemo;
var
ina, outa, ctrla: word; {input, output, control port addresses}
const
nlpt = 1; {printer port number}
base: word = $40; {base address in BIOS system RAM}
offs: array[1..3] of word = ($08,$0A,$0C); {offset in system RAM}
begin
{This initialization is mandatory}
outa := memw[base:offs[nlpt]];
ina := outa + 1;
ctrla := outa + 2;
{now, let's play with the ports}
port[outa] := 1; {set D2 line}
writeln ('Pin 2 should be TTL HIGH');
readln;
port[outa] := 0; {reset D2 line}
writeln ('Pin 2 should be TTL LOW');
readln;
port[ctrla] := 1; {set strobe line}
writeln ('pin 1 should be TTL HIGH');
readln;
port[ctrla] := 0;
writeln ('pin 1 should be TTL LOW');
readln;
{endless loop reading Acknowledge line}
while true do if port[ina] and 64 <> 0
then writeln ('Pin 10 = HIGH')
else writeln ('Pin 10 = LOW');
end.
{-------- Demonstrate IRQ7 handler ---------}
{This program demonstrates the parallel printer interrupt IRQ7, by
counting transitions on the Acknowledge pin of the printer port.
I am indebted to Kerry Yackoboski at Univ. of Manitoba for writing
the interrupt handler--all I did was add the part which turns the
port's interrupt generator on.
Francis J. Deck
fdeck@grumpy.helios.nd.edu
"Elegance is for tailors!" -- Einstein}
program isrtest;
uses
crt,
dos;
const
pc_imr = $21; {interrupt mask register--which interrupts are
active?}
pc_isr = $20; {interrupt status register--will be used to send
an EOI (end of interrupt) command to the 8255
interrupt controller}
irq7 = $0f; {the interrupt number of IRQ7.}
eoi7 = $60 + 7; {EOI instruction for IRQ7};
var
imr: byte; {saved value of interrupt mask register}
count: integer;
{-------- Service routine for IRQ7 --------}
procedure int_7_handler;
interrupt;
begin
port[pc_imr] := imr; {restore old value of interrupt mask register
so subsequent IRQ7's won't happen while this
routine is running.}
count := count + 1;
writeln ('Interrupt ',count);
port[pc_isr] := eoi7; {send EOI to 8255 controller. You gotta send
this EOI before re-enabling the interrupt, or
a spurious IRQ7 will be generated.}
port[pc_imr] := port[pc_imr] and $7f; {set mask register again so
IRQ7 can happen.}
end;
{-------- Mainline --------}
const
nlpt = 1; {printer port number--1, 2, or 3}
base: word = $40; {base in memory for printer port info}
offs: array[1..3] of word = ($08,$0A,$0C); {offsets in RAM for info
on ports 1, 2, and 3}
var
ina, outa, ctrla: word; {input, output, control port addresses}
var
old_int_vec: pointer; {saved value of vector for IRQ7}
begin
clrscr;
writeln ('This program demonstrates the use of the parallel printer');
writeln ('port interrupt IRQ7. It generates an interrupt every time');
writeln ('the Acknowledge input of the printer port (pin 10) goes');
writeln ('from LOW to HIGH. You can test it at this point by');
writeln ('repeatedly connecting and disconnecting a jumper wire from');
writeln ('pin 10 to pin 18 of the port. The program will terminate');
writeln ('when you press any key...');
writeln;
count := 0;
port[pc_isr] := eoi7; {send an EOI to clear all pending interrupts}
getintvec (irq7,old_int_vec); {store away existing value of interrupt
vector}
setintvec (irq7,@int_7_handler); {now, point IRQ7 to our own little
routine}
{find out, from BIOS system RAM, where the printer port is...}
outa := memw[base:offs[nlpt]]; {data output port}
ina := outa + 1; {handshake input port}
ctrla := outa + 2; {handshake output port}
port[ctrla] := 16; {enable the port to generate IRQ7 upon positive-
going transition on Acknowledge pin.}
imr := port[pc_imr]; {save existing value of interrupt mask}
port[pc_imr] := port[pc_imr] and $7f; {set 7th. bit of IMR to 1}
repeat until keypressed; {just loop forever, while the user plays
with pin 10}
port[ctrla] := 0; {disable port's IRQ7 generation}
port[pc_imr] := imr; {restore IMR}
port[pc_isr] := eoi7; {send EOI, clearing any further interrupts}
setintvec ($f,old_int_vec); {restore value of interrupt vector}
end.
Technical Details
Message-ID:
<1992Apr17.211208.29470@news.nd.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!usc!sol.ctr.columbia.edu!spool.mu.edu!news.nd.edu!smiley!fdeckShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!usc!sol.ctr.columbia.edu!spool.mu.edu!news.nd.edu!smiley!fdeck From: fdeck@smiley.helios.nd.edu (francis deck) Newsgroups: sci.electronics Subject: Printer Port Message-ID: <1992Apr17.211208.29470@news.nd.edu> Date: 17 Apr 92 21:12:08 GMT Article-I.D.: news.1992Apr17.211208.29470 Sender: news@news.nd.edu (USENET News System) Organization: University of Notre Dame, Notre Dame Lines: 246