-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLPTCAP.HTM
1205 lines (961 loc) · 72.8 KB
/
LPTCAP.HTM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<HTML><HEAD><TITLE>The LPTCAP parallel print capture system release 1</TITLE>
<META HTTP-EQUIV="keywords" CONTENT="capture Centronics circuit design diagram
DIY documentation free LPTCAP homebuilt parallel plans port project">
<META HTTP-EQUIV="author" CONTENT="Kris Heidenstrom ([email protected])">
<META HTTP-EQUIV="abstract" CONTENT="Detailed information on a parallel print
capture system that allows any MS-DOS PC to capture print data from any device
that prints to a Centronics printer. Includes schematic and layout drawings for
the hardware adapter (approximate parts cost US $20), a linkable software
module, a test and demonstration program, and full documentation on hardware
construction and software usage. Free. Release 1c, 02 April 2000. Kris
Heidenstrom, [email protected].">
<META HTTP-EQUIV="revision" CONTENT="1">
</HEAD>
<!--
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ This is an HTML document. It should normally be viewed with ³
³ an HTML viewer or a web browser. The fact that you can read ³
³ this text means that you are viewing it using an ASCII file ³
³ viewer or a text editor which does not understand HTML, and ³
³ displays the document in raw form. If you meant to view the ³
³ file in this form, no problem, but this is not the way this ³
³ document is designed to be viewed. To view it as a properly ³
³ formatted document you need an HTML viewer or a web browser ³
³ such as Netscape Navigator or Microsoft Internet Explorer. ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
KH.19971108.001 First version
KH.19971208.002 Include URL at clear.net.nz.
KH.19971220.003 First release
KH.19980328.004 Corrected error in setup procedure
KH.19980728.005 Corrected errors on U2 pin 8 in layout (the connections to
CN1 pin 10 and CN2 pin 11 were not marked on the GIF file)
and corrected the assembly instructions - there are 13 wires
to each connector including grounds, not 12 as I had stated.
KH.20000402.006 Changed email address from [email protected] to [email protected]
-->
<BODY BACKGROUND="lptcapbg.jpg">
<H1 ALIGN=CENTER>LPTCAP</H1>
<H2 ALIGN=CENTER>Parallel print capture system</H2>
<H4 ALIGN=CENTER>By <A HREF="http://home.clear.net.nz/pages/kheidens/">Kris Heidenstrom</A> (<A HREF="mailto:[email protected]">[email protected]</A>)</H4>
<H4 ALIGN=CENTER>Release 1c, 02 April 2000</H4>
<H2>Introduction</H2>
LPTCAP is a hardware and software solution which allows an IBM-compatible PC
running MS-DOS to capture print data sent by another PC, or any device with a
Centronics parallel printer interface.<P>
It is mainly intended to allow PC-based capturing of data from
"closed" systems such as obsolete word processors which use
incompatible disks or disk formats, so that the old equipment can be thrown
out, or microcontroller-based embedded systems, where the only way to access
the data externally is via the unit's printer port, to eliminate paper
printouts and/or add processing capabilities.<P>
The LPTCAP system is not a product you can buy. The software is provided in
this package, and may be used in any personal or commercial application. The
hardware (the LPTCAP adapter) can be constructed by anyone with basic practical
electronic construction skills, and is documented in full in this package.
Parts cost is about US $20 excluding the case and cables. The author does not
sell the adapter as a kit or product.<P>
If you are browsing this document online, you may have noticed that it has no
links to other parts of the package. This is because I would prefer you to get
the full LPTCAP archive, which is available as
<A HREF="lptcap01.zip">http://home.clear.net.nz/pages/kheidens/lptcap/lptcap01.zip</A>.<P>
The LPTCAP system consists of a hardware adapter box called the LPTCAP adapter,
and associated support software. The LPTCAP adapter box has two connectors:<P>
<UL><LI>CN1 - a female 36-pin Centronics connector, and
<LI>CN2 - a male 25-pin D-sub connector.</UL><P>
CN1 is physically and electrically similar to the Centronics connector on a
parallel printer, and connects to the device which is sending printer data
(known as the Sender) via the cable that would normally be used to connect
the Sender to a Centronics parallel printer.<P>
Data from the Sender is latched in the adapter, and can be captured by a PC
(called the Capture PC) which is connected to CN2 (male 25-pin D-sub). The
connection between CN2 and the Capture PC is through a short pin-to-pin cable
which connects CN2 to a parallel printer port on the Capture PC. The Capture PC
controls and interrogates the LPTCAP adapter through this cable.<P>
The basic functions performed by the LPTCAP adapter are:<P>
<UL><LI>Provide electrical compatibility with the Sender and the Capture PC,
<LI>Capture parallel data from Sender and allow Capture PC to read captured
data via a standard parallel port in either polled or interrupt mode,
<LI>Provide timed Acknowledgement pulse generation,
<LI>Allow the Capture PC to monitor commands from the sender,
<LI>Allow the Capture PC to provide statuses to the sender.</UL><P>
The support software runs on the Capture PC. It consists of the LPTCAP software
module which is included in the LPTCAP package in source (assembly language) and
object form, to be linked into other programs. This module provides LPTCAP
auto-detection, testing and capturing functions which are easy to use.<P>
A small exerciser program called LPTEST (which uses the LPTCAP software module)
is also included. This program performs tests and simple capturing functions.
This program is included in source (Borland C) and executable forms, and can be
used as a starting point for other programs, or for basic capturing functions.
<P>
Capturing can be done in polled mode, or interrupt-driven mode if the Capture
PC's parallel port has interrupt capability. Interrupt-driven mode may be more
convenient and/or efficient than polled mode in some applications, but is not
required to prevent data overrun (as with serial communication, for example),
because the Centronics electrical protocol requires an explicit handshake on
each character. The LPTCAP adapter provides the handshaking signals and thus
prevents data overrun.<P>
<H4>Boring Legal Stuff</H4>
The LPTCAP hardware and software was designed and developed by the author,
Kris Heidenstrom. The LPTCAP package, including the hardware design, support
software and documentation, is Copyright © 1996-2000 by K. Heidenstrom.<P>
My philosophy is that this package should be freely available to anyone who
wants to use it, and that no-one should deny this to anyone else. By
"freely available" I mean easily available and with no specific
charge apart from any normal data or disk charges.<P>
You can use the hardware design and the support software freely in any personal
or commercial application. You can distribute the software, in its complete
and unmodified form only, as long as the author is identified, the package is
identified as free and no specific charge (other than data charges or disk
duplication) is made for it.<P>
You are welcome to build LPTCAP adapters (the hardware part of the package) and
sell them, but you must clearly identify the designer, and state that the
hardware design and support software are freely available and that the potential
buyer could get the design details for free and build the device him/herself.<P>
You may not distribute the LPTCAP package in an altered or incomplete form.
Please distribute only the original archive file.<P>
If you generate a freely distributable derived version of the design or code
such as a DOS protected-mode version or a version for a different operating
system, please include a note that your code was derived from mine, and please
consider sending me a copy of your package.<P>
I provide no warranty that the LPTCAP code and the LPTCAP design will perform
to any standard or at all. This is because I cannot control the environment in
which you use the software and the hardware design. Any use of the LPTCAP
system is entirely at your own risk. If this is not acceptable to you, then
do not use the LPTCAP package.<P>
You should also check the <A HREF="#Caveats">Caveats</A> section for notes on
the limitations of the design.<P>
I have tested the design thoroughly and I believe that it is sound. If you
have a problem with the LPTCAP design, please let me know and I will try to
help. You can contact me at:<P>
<TABLE><TR><TD> </TD><TD>Internet: </TD><TD><A HREF="mailto:[email protected]">[email protected]</A></TD><TD>(preferred)</TD></TR>
<TR><TD></TD><TD>Snail:</TD><TD>Kris Heidenstrom</TD></TR>
<TR><TD></TD><TD></TD><TD>c/- P.O Box 27-103</TD></TR>
<TR><TD></TD><TD></TD><TD>Wellington</TD></TR>
<TR><TD></TD><TD></TD><TD>New Zealand</TD></TR>
<TR><TD></TD><TD>Phone:</TD><TD>Work: +64 4 385-6611</TD></TR>
<TR><TD></TD><TD></TD><TD>Home: +64 4 475-7437</TD></TR>
<TR><TD></TD><TD></TD><TD>(We are 12 hours ahead of GMT.)</TD></TR></TABLE><P>
Please feel free to contact me via email, or to send a postcard to the snail
mail address above if you find the LPTCAP system useful.<P>
<H4>Versions</H4>
<I>Version 1 - released 20 December 1997</I><P>
Original release<P>
<I>Version 1a - released 28 March 1998</I><P>
Correction to setup procedure - in the second stage when measuring across R1 and
adjusting for half resistance, I had said to measure between U2 pin 8 and U1 pin
11 - the correct pins are U2 pin 8 and U1 pin 5. Thanks to Jay Pennell
(<I>[email protected]</I>) of Penntronics for finding this error.<P>
<I>Version 1b - released 28 July 1998</I><P>
Correction to layout illustration to add connection points to CN1 pin 10 and
CN2 pin 11, and change to the construction procedure to state that there are
thirteen wires from the board to each connector including grounds. Thanks to
Peter Scales (<I>[email protected]</I>) for reporting these errors.<P>
<I>Version 1c - released 02 April 2000</I><P>
Changed email address from [email protected] to [email protected].<P>
<H2>LPTCAP Adapter Hardware</H2>
The hardware design is provided in this package as a schematic diagram (circuit
diagram) and a stripboard layout diagram.<P>
<IMG SRC="lptcap-s.gif" WIDTH=1221 HEIGHT=771 ALT="LPTCAP Schematic diagram, LPTCAP-S.GIF, 33K"><P>
The schematic diagram (above) is contained in the file LPTCAP-S.GIF. As you can
see, it is quite large, and should be printed if possible. Note that on the
schematic, U1 is shown as six discrete components, named U1A to U1F.<P>
The stripboard layout is given in the file LPTCAP-L.GIF. This view shows the
adapter board looking down from above. See the
<A HREF="#Construction">Construction</A> section for more information.
<I>Important note</I>: There were two errors in the layout drawing which are
fixed in release 1b - connections to CN1 pin 10 and CN2 pin 11 were not marked
on previous versions.<P>
<H4>Parts List</H4>
The following parts list for the LPTCAP adapter excludes parallel cables.<P>
<TABLE><TR><TD> </TD><TD><U>Quantity</U> </TD><TD><U>Reference(s)</U> </TD><TD><U>Description</U></TD></TR>
<TR><TD></TD><TD>3</TD><TD>C1-3 </TD><TD>0.1µF 50V ceramic or monolithic capacitor</TD></TR>
<TR><TD></TD><TD>1</TD><TD>C4 </TD><TD>10µF 10V tantalum capacitor</TD></TR>
<TR><TD></TD><TD>2</TD><TD>C5,6 </TD><TD>470pF 50V ceramic capacitor</TD></TR>
<TR><TD></TD><TD>3</TD><TD>C7-9 </TD><TD>100pF 50V ceramic capacitor</TD></TR>
<TR><TD></TD><TD>1</TD><TD>CN1 </TD><TD>Female 36-pin Centronics connector, chassis mount</TD></TR>
<TR><TD></TD><TD>1</TD><TD>CN2 </TD><TD>Male 25-pin D-sub connector, chassis mount</TD></TR>
<TR><TD></TD><TD>2</TD><TD>R1,2 </TD><TD>50 kilohm preset potentiometer (trimpot)</TD></TR>
<TR><TD></TD><TD>2</TD><TD>RSIL1,2</TD><TD>Single-in-line resistor network, 9-pin, 8-element, 100 kilohm</TD></TR>
<TR><TD></TD><TD>1</TD><TD>JP1 </TD><TD>3-pin jumper block or single-pole changeover switch <A HREF="#JP1 notes">(see below)</A></TD></TR>
<TR><TD></TD><TD>1</TD><TD>U1 </TD><TD>74HC14 integrated circuit - hex Schmitt trigger inverter</TD></TR>
<TR><TD></TD><TD>1</TD><TD>U2 </TD><TD>74HC74 integrated circuit - dual D-type flip-flop</TD></TR>
<TR><TD></TD><TD>1</TD><TD>U3 </TD><TD>74HC165 integrated circuit - serial-output shift register</TD></TR>
<TR><TD></TD><TD>1</TD><TD> </TD><TD>Jumper shunting block for JP1</TD></TR>
<TR><TD></TD><TD>2</TD><TD> </TD><TD>14-pin DIP IC socket, dual-wipe (for U1 and U2)</TD></TR>
<TR><TD></TD><TD>1</TD><TD> </TD><TD>16-pin DIP IC socket, dual-wipe (for U3)</TD></TR>
<TR><TD></TD><TD>1</TD><TD> </TD><TD>Piece of stripboard - 25 tracks by 20 holes</TD></TR>
<TR><TD></TD><TD>1</TD><TD> </TD><TD>Plastic or metal case</TD></TR>
<TR><TD></TD><TD>2</TD><TD> </TD><TD>Screws, nuts and lockwashers for mounting CN1</TD></TR>
<TR><TD></TD><TD>2</TD><TD> </TD><TD>Hexagonal tapped-head screws with nuts and lockwashers for CN2</TD></TR>
<TR><TD></TD><TD>5m</TD><TD> </TD><TD>Hookup wire (stranded, insulated)</TD></TR>
<TR><TD></TD><TD>2m</TD><TD> </TD><TD>Solder</TD></TR></TABLE><P>
<A NAME="JP1 notes"><TABLE><TR><TD> </TD><TD VALIGN=TOP>Notes: </TD><TD><UL><LI>All
of the above parts should be readily available from electronic hobbyist
shops such as Radio Shack or the local equivalent.
<LI>R1 and R2 are 50 kilohm preset potentiometers (trimpots). These are
screwdriver-settable devices which are adjusted in the adjustment
procedure. Single-turn or ten-turn types are both suitable.
<LI>JP1 is listed as a three-pin jumper strip with a jumper shunt. This
jumper selects the interrupt polarity, which may be different for
different Capture PCs. If the LPTCAP adapter will regularly be used
with several different Capture PCs, it may be worthwhile connecting a
single-pole changeover (SPCO) switch such as a small slide switch or
toggle switch, instead of the jumper, so that the interrupt polarity
can be selected without opening the adapter case.
<LI>U1-3 must be 74HC<I>nn</I> types. 74<I>nn</I> (TTL), 74LS<I>nn</I>,
74ACT<I>nn</I> and 74HCT<I>nn</I> types are NOT suitable. Typical
manufacturers are Motorola, Philips, National Semiconductor, Harris
and Texas Instruments. Use DIP (dual in-line package) devices, not
surface-mount (SOIC) devices (surface mount devices do not go well
with stripboard).
<LI>U1-3 are static sensitive devices. Keep them in their anti-static
tubes until you are ready to use them.</UL></TD></TR></TABLE>
<A NAME="Construction"><H4>Construction</H4>
The LPTCAP adapter circuit is constructed on a rectangular piece of stripboard.
A printed circuit board could be designed, but these are uneconomical except in
large quantities, and would still require wire links (unless a double-sided PCB
was used, but these are even more expensive). The assembled board is connected
to connectors CN1 and CN2 (and a switch connected to the JP1 position, if a
switch is used) with hookup wire, and the unit is mounted in a plastic or metal
case. Cutouts and holes for the connectors must be made in the case. This is
easier with a plastic case than with a metal case.<P>
In addition to files and a drill, you will need pliers, side cutters, soldering
iron (or a "soddering iron" if you're American :-) and a small
screwdriver. During testing and adjustment, a multimeter (analogue or digital)
is required.<P>
<IMG SRC="lptcap-l.gif" WIDTH=606 HEIGHT=480 ALT="LPTCAP Layout diagram, LPTCAP-L.GIF, 21K"><P>
The stripboard layout drawing (above) is contained in the file LPTCAP-L.GIF.
This view is drawn looking down onto the adapter board from above. The copper
strips are shown in grey, with gaps indicating cuts where appropriate. Coloured
numbers refer to pins on CN1 (red numbers) and CN2 (blue numbers).
<I>Important note</I>: There were two errors in the layout drawing which are
fixed in release 1b - connections to CN1 pin 10 and CN2 pin 11 were not marked
on previous versions.<P>
Here is the full detailed construction procedure.<P>
<OL><LI>Drill and file holes in the case, to suit CN1 and CN2 (and the switch,
if you are using one). If possible, arrange things so that you will be
able to wire the connectors to the stripboard before mounting them on
the case. If you mount the connectors against the outside of the case,
you won't be able to push them through the apertures from the inside
after they have been wired up, so you would have to bring the wires
through the connector apertures when wiring the connectors up to the
stripboard. If the case is in two halves, you can make the apertures
open to the edge of one half, to avoid this problem.
<LI>Cut the stripboard to size and make the 31 cuts in the copper strips, using
a quarter-inch drill bit or a proper stripboard cutting tool. Just cut
deep enough to remove the copper, don't drill through the board. The
cut positions are indicated by gaps in the grey strips in the drawing.
<LI>Install the three IC sockets - these will act as position references. Don't
insert the ICs yet.
<LI>Install the link wires. These are shown as black lines joining two points.
Many of these are straight horizontal links, and uninsulated wire can be
used for these (if you use stranded wire, twist it tight). For the other
links, use insulated stranded hookup wire.
<LI>Install capacitors C1-9. C1-3 are not shown in the drawing - solder these on
the underside of the board, under U1, U2 and U3 respectively, across the
VCC and GND pins (the corner pins - pins 14 and 7 for U1 and U2, and
pins 16 and 8 for U3). Use lengths of insulation (taken from hookup
wire) on the leads, so they cannot touch other pins or tracks.<BR>
C4 is polarised. If the polarity is not marked on the body, the longer
lead is normally positive. C5-9 are not polarised.
<LI>Install R1, R2 and JP1. If you are using a switch instead of a jumper to set
the IRQ polarity, solder three lengths of hookup wire instead of JP1,
and take these to the IRQ polarity switch. Make sure that the middle pin
of the switch connects to the middle pin of the JP1 marking on the
drawing.
<LI>Solder resistor networks RSIL1 and RSIL2 directly to connectors CN1 and CN2
respectively. The resistor networks will have a dot or similar mark at
the pin 1 end. Pin 1 does not connect to the connector, but all other
pins do (they connect to pins 2 to 9 of the connector).
<LI>Make the connections from CN1 and CN2 to the stripboard, using lengths of
insulated stranded hookup wire. Connection points for these wires are
indicated by red and blue numbers on the drawing. Red indicates a wire
to a pin on CN1, and blue indicates a wire to a pin on CN2 (as
mentioned in the drawing).<BR>
Ground (common) on CN1 and CN2 must be connected to the stripboard
positions marked "GND" in red and blue. For CN1, connect
together pins 16, 17, 19-30 and 33 and the shield, and wire to the
stripboard. For CN2, connect together pins 18-25 and the shield, and
wire to the stripboard.<BR>
There are a total of 13 wires from CN1 to the stripboard, and 13 wires
from CN2 to the stripboard, including the "GND" wires.
<LI>Using hookup wire, connect pin 1 of RSIL1 and pin 1 of RSIL2 to the
stripboard positions marked "RSIL1" and "RSIL2".
<LI>Connect the following pins of CN1 and CN2 together using hookup wire. These
signals go directly between the two connectors, not via the stripboard.<BR>
<UL><LI>CN1 pin 13 to CN2 pin 6
<LI>CN1 pin 14 to CN2 pin 14
<LI>CN1 pin 31 to CN2 pin 16
<LI>CN1 pin 32 to CN2 pin 5
<LI>CN1 pin 36 to CN2 pin 17</UL>
<LI>Insert the ICs.
<LI>Place the stripboard in the case (if the case is metal, use corrugated
cardboard or similar, glued to the case, to insulate it from the bottom
of the board) and mount the connectors.</OL>
<A NAME="Adjustment"><H4>Adapter Adjustment And Testing Procedure</H4>
The adjustment procedure sets the timing of the Acknowledge pulse and the
<VAR>BUSY</VAR> latch reset using trimpots R1 and R2 on the LPTCAP adapter.
You will need a digital or analogue multimeter.<P>
The LPTEST program (included in the LPTCAP package) is required, to generate
timed signals during adjustment. Use the "generate adjustment signal"
option and enter a blank test duration (the adjustment signal will stop when
you press the Ctrl key).<P>
Disconnect the Sender cable from CN1. Connect the multimeter negative lead to
the common rail of the LPTCAP adapter (the connector shields are connected to
the common rail). Start the adjustment signal using the LPTEST program. With the
adjustment signal running, measure the voltage on VCC (pin 14 of U1). This
voltage should be stable, and between 3V and 5V. Note the actual voltage
measured.<P>
With the adjustment test still running, measure the voltage on pin 9 of U2 and
adjust trimpot R2 for a voltage of 14% of the VCC voltage measured earlier.
For example if VCC is 4.0V, adjust R2 until you measure 0.56V on U2 pin 9.<P>
With the adjustment test still running, measure the voltage on pin 3 of U2.
Rotate trimpot R1 to each end of its travel. At one end, the voltage should
be nearly zero, and at the other end the voltage should be about 0.5V (the
exact value is not important). The end where voltage is present is the minimum
resistance end. Turn R1 to this end, and rotate R1 slowly towards the other
end. The voltage should drop steadily, until a point is reached where the
voltage suddenly jumps to zero (or nearly zero). Leave R1 at this position.<P>
Unplug CN2 to power down the adapter, and remove U1 from its socket. Connect the
multimeter between pin 5 of U1's socket and pin 8 of U2 (i.e. across R1) and
note the reading, then rotate R1 towards the minimum resistance end until its
resistance is half of this value.<P>
Replace U1, reconnect CN2, run the LPTEST diagnostic test and check that the
tests pass.<P>
Optionally, temporarily connect a 68 ohm resistor from VCC to ground, measure
the VCC rail (should be around 2-3 volts) and repeat the diagnostic test - it
should pass.<P>
A data transfer test requires a second PC, to act as the Sender. Run the
PRNFILE.COM program (included in the package) on both machines to generate a
one megabyte file called PRNFILE.OUT containing pseudo-random data. Run the
capture software and start capturing to a file, then on the Sender, enter the
command
<PRE>COPY /B PRNFILE.OUT PRN</PRE><P>
You can measure the time taken to transfer the file and calculate the throughput
if you wish. When the file has been transferred, use a file-compare program such
as DOS's COMP to compare the captured file with PRNFILE.OUT on the Capture PC.
If the files do not match, see the
<A HREF="#Caveats">Caveats</A> section for suggestions.<P>
<H4>Signal Naming Conventions</H4>
LPTCAP documentation and comments in source code use signal names as marked on
the LPTCAP schematic. The Capture PC's parallel port is not used for printing,
so most of its standard signal names are not meaningful. Therefore, the signal
lines on the Capture PC's parallel port are assigned names (such as
<VAR>-DACK</VAR> and <VAR>SDI</VAR>) according to their function when used with
the LPTCAP adapter. Signals from the Sender are named using the standard
convention, since these signals are used for their normal purposes.<P>
The four control signals (<VAR>-INIT</VAR>, <VAR>-SELECT</VAR>,
<VAR>-AUTOFEED</VAR> and <VAR>-STROBE</VAR>) are connected directly from the
Sender's port to the same signals on the Capture PC, so they are named
identically on both CN1 and CN2.<P>
<H4>LPTCAP Adapter Technical Description</H4>
The adapter is controlled and powered by signals from the Capture PC. When data
lines from the Capture PC (pins 2-9 of CN2) are high, input protection diodes in
U1, U2 and U3 conduct and provide operating voltage for the circuit. This is why
the default state for the Capture PC's data register is 11111111b. C4 acts as a
reservoir for the supply rail and provides current for U1-3 when they switch
(change state).<P>
The LPTCAP adapter contains one 74HC14 hex Schmitt inverter chip (U1) which is
used to invert various signals and clean up slow signal transitions from the
parallel ports, one 74HC74 dual flip-flop (U2) which detects and latches data
bytes from the Sender and generates Acknowledge pulses, and one 74HC165
parallel/serial-input, serial-output shift register (U3) which loads and holds
each captured data byte and passes it serially to the Capture PC.<P>
These devices must be 74HC types. Other types with compatible pinouts, such
as 74LS and 74HCT, should not be used.<P>
The default state of the adapter is with U2A in the reset state, i.e. U2 pin
6 high and the <VAR>+-DRDY</VAR> signal line in the inactive state (whether
this is high or low depends on the setting of the IRQ Polarity switch or
jumper). In this state, assuming that <VAR>-RESETB</VAR> is inactive (high),
the adapter is ready to accept a data byte from the Sender machine.<P>
When the Sender wishes to send a byte, it asserts the data value on D0-7 and
then briefly pulses <VAR>-STROBE</VAR> active (low). This causes the
<VAR>BUSY</VAR> latch (U2A) to flip to the set state, giving a <VAR>BUSY</VAR>
indication back to the Sender, and switches the shift register (U3) from
transparent load mode to shift mode, latching the data byte into the shift
register in the process. The <VAR>+-DRDY</VAR> line goes active, indicating to
the Capture PC that a data byte has been captured and generating a parallel port
interrupt on the Capture PC if the interrupt is enabled and the port is
interrupt capable.<P>
The LPTCAP adapter will remain in the "busy" state until the Capture PC
detects and acknowledges the new data. In this state, the Sender cannot send a
new data byte, because <VAR>BUSY</VAR> is active and no <VAR>-ACK</VAR> pulse
has been sent by the adapter.<P>
When the Capture PC detects that new data is ready, via the <VAR>+-DRDY</VAR>
line, either by polling the line or through the parallel port interrupt, it can
read the data serially via the <VAR>SDI</VAR> and <VAR>-SDI</VAR> signals
(<VAR>-SDI</VAR> is always the complement of <VAR>SDI</VAR>), using the
<VAR>-SCL</VAR> signal to clock the data through U3. Initially when a data byte
is captured, bit 0 is present on <VAR>SDI</VAR>. On every falling edge of
<VAR>-SCL</VAR> from the Capture PC, the data shifts through the shift register
by one bit, shifting new data in from the <VAR>SDO</VAR> line (which is used in
the diagnostic test but not during normal operation) and presenting the next
data bit of the captured byte on <VAR>SDI</VAR> and <VAR>-SDI</VAR>.<P>
Once the Capture PC has read the data byte, it brings <VAR>-DACK</VAR> low,
clocking a "1" into U2B and starting a pulse on the <VAR>-ACK</VAR>
line back to the Sender (and to the Capture PC on the <VAR>-ACKP</VAR> line).
Approximately 5 microseconds (set by R1 and C5) after the start of this pulse,
U2A's clock goes high and U2A is reset (assuming that <VAR>-STROBE</VAR> from
the sender is high, which it should be). Approximately 10 microseconds (set by
R2 and C6) after the start of the <VAR>-ACK</VAR> pulse, U2B resets, ending the
<VAR>-ACK</VAR> pulse.<P>
The <VAR>-RESETB</VAR> signal is provided to allow the Capture PC to reset U2A
without generating an <VAR>-ACK</VAR> pulse, and is used only during
initialisation of the LPTCAP adapter. The 74HC74 device responds in a defined
way when its set and reset inputs are both active (low) - both the Q and Q-bar
outputs are forced high. With U2A, only the Q-bar output is used, so the reset
input (from <VAR>-RESETB</VAR>) has priority over the set input (from
<VAR>-STROBE</VAR>). Therefore, if <VAR>-RESETB</VAR> is active (low), U2A will
be in a known state regardless of the state of <VAR>-STROBE</VAR>. This is
important because the Capture PC cannot guarantee that <VAR>-STROBE</VAR> will
be high (inactive) - it may be being driven active by the Sender. By forcing
<VAR>-STROBE</VAR> low itself, the Capture PC can control U2A's Q-bar output
via <VAR>-RESETB</VAR>.<P>
The <VAR>DDATA</VAR> signal feeds the Data input of the acknowledge pulse
flip-flop and should be held at logic "1" at all times. It has no
practical purpose except to provide another source of supply current for the
adapter.<P>
The following diagram shows a typical data byte capture.<P>
<IMG SRC="lptcap-t.gif" WIDTH=640 HEIGHT=440 ALT="LPTCAP capture timing diagram, LPTCAP-T.GIF, 4K"><P>
<H4>Parallel Port Registers On The Capture PC</H4>
The tables in the following sections give the I/O assignment for the Capture
PC's parallel port, with standard parallel port functions given in parentheses.<P>
In these tables, the "!" symbol indicates that the PC's parallel port
circuitry inverts the data between the register and the hardware signal, i.e. a
bit value of "1" in the register corresponds to an electrically low
signal and vice versa. The "-" symbol indicates that the signal is
electrically active-low, i.e. it is active or "true" when it is
electrically low.<P>
Therefore a signal name which starts with "-" or "!" (but
not both) is in its active state when the register bit is 0, and a signal name
with both "!" and "-", or neither, is in its active state
when the register bit is 1.
The polarity of <VAR>+-DRDY</VAR> depends on the setting of the IRQ Polarity
jumper (JP1) or switch on the LPTCAP adapter. See the
<A HREF="#Status Register">Status register</A> section for details.<P>
<H5>Data Register</H5>
<TABLE><TR><TD COLSPAN=12><EM>Data register: LPTBase+0, read/write, driven by software</EM></TD></TR>
<TR><TD> </TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (D7)</TD><TD> DDATA </TD><TD>Should always be held at "1"</TD></TR>
<TR><TD></TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (D6)</TD><TD> -RESETB </TD><TD>Set to 0 to hold BUSY latch clear</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (D5)</TD><TD> -NOPAPER </TD><TD>Set to 0 to signal PAPER OUT to sender</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (D4)</TD><TD> SELCTD </TD><TD>Set to 1 to signal SELECTED to sender</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (D3)</TD><TD> -ERROR </TD><TD>Set to 0 to signal ERROR to sender</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD> (D2)</TD><TD> -DACK </TD><TD>Normally 1, 1-to-0 edge acknowledges data byte</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD> (D1)</TD><TD> -SCL </TD><TD>Normally 1, 1-to-0 edge clocks shift register</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD> (D0)</TD><TD> SDO </TD><TD>Drives serial data input of shift register</TD></TR></TABLE>
<A NAME="Status Register"><H5>Status Register</H5>
<TABLE><TR><TD COLSPAN=12><EM>Status register: LPTBase+1, read-only, driven by hardware, read by software</EM></TD></TR>
<TR><TD> </TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (!BUSY) </TD><TD> !-ACKP </TD><TD>Pulses to 1 when we acknowledge data</TD></TR>
<TR><TD></TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (-ACK) </TD><TD> +-DRDY </TD><TD>New data ready (see explanatory, below)</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (NOPAPER)</TD><TD> SDI </TD><TD>Carries serial data from shift register</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (SELCTD) </TD><TD> -SDI </TD><TD>Carries inverted shift register data</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> (-ERROR) </TD><TD> LOOPIN </TD><TD>Driven from bit 0 of data register</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD> </TD><TD> </TD><TD>Undefined</TD></TR></TABLE>
The <VAR>+-DRDY</VAR> signal on status register bit 6 indicates whether new data
is ready. Status register bit 6 (the <VAR>-ACK</VAR> input of the parallel port)
is the input which is fed to the IRQ line when the buffer is enabled. On some
older machines, the IRQ is triggered on the falling edge of this signal line,
but on most machines, the IRQ is triggered on the rising edge. To support both
port types, the LPTCAP adapter has an IRQ Polarity switch or jumper (JP1), which
feeds either a true signal or an inverted signal onto this line. The meaning of
<VAR>+-DRDY</VAR> for each position of this switch or jumper is:<P>
<TABLE><TR><TD> </TD><TD><U>JP1 position</U></TD><TD><U>Meaning of bit 6 of status register</U></TD></TR>
<TR><TD> </TD><TD>Negative IRQ </TD><TD>Normally 1; 0 means new data is ready;</TD></TR>
<TR><TD> </TD><TD>Positive IRQ </TD><TD>Normally 0; 1 means new data is ready.</TD></TR></TABLE>
<H5>Control Register</H5>
<TABLE><TR><TD COLSPAN=11><EM>Control register: LPTBase+2, read/write, driven by hardware and software</EM></TD></TR>
<TR><TD> </TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> </TD><TD>Not used in this application</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> </TD><TD>Interrupt Enable (1 = enable)</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> !-SELECT </TD><TD>Will be 1 if Sender is asserting -SELECT</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD> -INITIALIZE </TD><TD>Will be 0 if Sender is asserting -INITIALIZE</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD> !-AUTOFEED </TD><TD>Will be 1 if Sender is asserting -AUTOFEED</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD> !-STROBE </TD><TD>Will be 1 if Sender is asserting -STROBE</TD></TR>
<TR><TD COLSPAN=10></TD><TD>Can also be driven to 1 to trigger a Strobe.</TD></TR></TABLE><P>
The control register is used in a slightly unusual way. The electrical signal
lines driven by this port are all open-collector with pullup resistors. This
allows these signal lines to be used as inputs if the drivers are set to the
electrical high state. In this state, the pullup resistors pull the lines up
to electrical high, but the lines can be pulled to electrical low by the Sender.
Reading the control register yields the actual line states, so this port can be
used as an input port in this application.<P>
Because control register bits 0, 1 and 3 have inversion between the register
bits and the signal lines, a value of <I>xxxx</I>0100 binary must be written to
the control register to set the drivers to electrical high. This will appear as
<I>xxxx</I>0100 binary when reading the control register. If the Sender drives
any of those signals to electrical low, the corresponding bit(s) in the control
register will change to the opposite state.<P>
This software can cause a data strobe to occur explicitly by setting and then
clearing bit 0 of the control register. When this bit is set, the port output
forces the <VAR>-STROBE</VAR> signal line to electrical low, causing a data
strobe on the adapter even if the Sender is not driving <VAR>-STROBE</VAR> low.<P>
<H2>LPTCAP Software Module</H2>
The LPTCAP software module is included in this package in
<A HREF="lptcap.asm">source (LPTCAP.ASM)</A> and object forms. It provides a
set of functions which can be called from a C or assembly-language program,
which interface with the LPTCAP adapter and provide standard auto-detection,
diagnostic and data capture capabilities.<P>
<H4>Assembly Time Settings</H4>
There are two assembly-time settings for the LPTCAP software module - memory
model and slow-timing.These are controlled by constants which are defined on
the assembler command line. These constants are:<P>
<TABLE><TR><TD> </TD><TD>TINY </TD><TD>Selects tiny memory model</TD></TR>
<TR><TD></TD><TD>SMALL </TD><TD>Selects small memory model</TD></TR>
<TR><TD></TD><TD>COMPACT </TD><TD>Selects compact memory model</TD></TR>
<TR><TD></TD><TD>MEDIUM </TD><TD>Selects medium memory model</TD></TR>
<TR><TD></TD><TD>LARGE </TD><TD>Selects large memory model</TD></TR>
<TR><TD></TD><TD>HUGE </TD><TD>Selects huge memory model</TD></TR>
<TR></TR>
<TR><TD></TD><TD>SLOW </TD><TD>Selects slow timing</TD></TR>
<TR><TD></TD><TD>VERYSLOW </TD><TD>Selects very slow timing</TD></TR></TABLE><P>
These constants are defined on the assembler command-line with the
"/dname" option. For example, to specify large model and slow
timing, the command line to the assembler (TASM or MASM) should include:
<PRE>/dLARGE /dSLOW</PRE><P>
A memory model should be specified. If no memory model is specified, during
assembly the module issues a warning message and the module defaults to SMALL
model.<P>
The SLOW and VERYSLOW options may be useful during development. The VERYSLOW
setting should not be used when generating production code. If neither SLOW
nor VERYSLOW are specified, the module will be assembled for standard timing.<P>
Refer to the comments in LPTCAP.ASM for more detailed information on the memory
model support and the slow timing settings.<P>
<H4>Functions Provided</H4>
The following functions are provided in the LPTCAP software module:<P>
<TABLE><TR><TD>  
</TD><TD><A HREF="#lptcap_version">lptcap_version()</A> </TD><TD>Returns version numbers and assembly settings</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_port">lptcap_port()</A> ** </TD><TD>Detects LPTCAP adapter(s) on parallel ports</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_test">lptcap_test()</A> ** </TD><TD>Diagnostics - logic and data loopthrough tests</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_test_fail_data">lptcap_test_fail_data()</A> </TD><TD>Returns details of a diagnostic check failure</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_adjust">lptcap_adjust()</A> </TD><TD>Generates timed signals for adapter adjustment</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_get_cont">lptcap_get_cont()</A> </TD><TD>Returns states of control signals from Sender</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_set_stat">lptcap_set_stat()</A> </TD><TD>Sets states of printer status signals to Sender</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_send_ack">lptcap_send_ack()</A> </TD><TD>Sends an acknowledgement to the Sender</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_poll_new">lptcap_poll_new()</A> </TD><TD>Tests whether a new character has been captured</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_next_char">lptcap_next_char()</A> </TD><TD>Returns the next captured character</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_wait_char">lptcap_wait_char()</A> </TD><TD>Waits (with or without timeout) for a character</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_autodetect_irq">lptcap_autodetect_irq()</A> </TD><TD>Auto-detects the IRQ number of the LPTCAP port</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_intmode_install">lptcap_intmode_install()</A> </TD><TD>Installs interrupt-driven capture mode</TD></TR>
<TR><TD></TD><TD><A HREF="#lptcap_intmode_uninstall">lptcap_intmode_uninstall()</A> </TD><TD>Uninstalls interrupt-driven capture mode</TD></TR></TABLE><P>
<EM>** The functions lptcap_port() and lptcap_test() set up global variables
which are used by other functions, and must be called and return a successful
result before other functions are used.</EM><P>
The code in the LPTCAP module manipulates the interrupt flag extensively. All
functions return with the interrupt flag unmodified. Functions do not lock
interrupts out for more than about 50 microseconds at one time (any operations
which take longer than this are split into blocks, with the interrupt flag
restored to its initial between the blocks) except for lptcap_adjust() which
locks interrupts out for about 5 milliseconds at a time. Some functions
explicitly enable interrupts temporarily during their execution.<P>
<H4>Individual Function Descriptions</H4>
<A NAME="lptcap_version"><H5>lptcap_version()</H5>
<EM>unsigned int lptcap_version(int request)</EM><P>
This function returns version-related information, according to the
"request" parameter. Values for the "request" parameter
are:<P>
<TABLE><TR><TD> </TD><TD>0 </TD><TD>LPTCAP_REQ_MAJVER </TD><TD>Returns major version number</TD></TR>
<TR><TD></TD><TD>1 </TD><TD>LPTCAP_REQ_MINVER </TD><TD>Returns minor or sub-version number</TD></TR>
<TR><TD></TD><TD>2 </TD><TD>LPTCAP_REQ_MODVER </TD><TD>Returns modification or sub-sub-version number</TD></TR>
<TR><TD></TD><TD>3 </TD><TD>LPTCAP_REQ_FILREV </TD><TD>Returns file revision number</TD></TR>
<TR><TD></TD><TD>4 </TD><TD>LPTCAP_REQ_DATEL </TD><TD>Returns low word of YYYYMMDD value</TD></TR>
<TR><TD></TD><TD>5 </TD><TD>LPTCAP_REQ_DATEH </TD><TD>Returns high word of YYYYMMDD value</TD></TR>
<TR><TD></TD><TD>6 </TD><TD>LPTCAP_REQ_CONDS </TD><TD>Returns a bitstring indicating conditional assembly-time parameters (see below)</TD></TR></TABLE><P>
For a request parameter of LPTCAP_REQ_CONDS, the function returns an unsigned
integer which is bit-allocated as follows:<P>
<TABLE><TR><TD> </TD><TD>F</TD><TD>E</TD><TD>D</TD><TD>C</TD><TD>B</TD><TD>A</TD><TD>9</TD><TD>8</TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>Reserved for future use</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>Module was made with VERYSLOW option</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>Module was made with SLOW option</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>Module made for far data (0 = near)</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>Module made for far code (0 = near)</TD></TR></TABLE><P>
<A NAME="lptcap_port"><H5>lptcap_port()</H5>
<EM>int lptcap_port(int findmode)</EM><P>
This function detects and returns the LPT port number of the LPTCAP port.
It accepts a "findmode" parameter which specifies the search type
desired:<P>
<TABLE><TR><TD> </TD><TD>0 </TD><TD>LPTCAP_FIND_SAME </TD><TD>Return previously-found LPTCAP port</TD></TR>
<TR><TD></TD><TD>1 </TD><TD>LPTCAP_FIND_FIRST </TD><TD>Look for LPTCAP port starting from LPT1</TD></TR>
<TR><TD></TD><TD>2 </TD><TD>LPTCAP_FIND_NEXT </TD><TD>Find next LPTCAP port after last found port</TD></TR></TABLE><P>
This function is able to find more than one LPTCAP port, though no other
functions support capturing from more than one LPTCAP adapter simultaneously.<P>
This function returns the LPTx number of the port where the LPTCAP adapter was
found, in the range 1 to 4, or 0 if it could not find any port (or any
<EM>more</EM> ports, if findmode was LPTCAP_FIND_NEXT).<P>
Once a parallel port with an LPTCAP adapter is found, this function initialises
the parallel port's control register and outgoing status lines, and the port
becomes the LPTCAP port used by the other functions in this module.<P>
This function sets up several port-related global variables within this module
which are used by other functions. <EM>IT MUST BE CALLED AND RETURN A SUCCESSFUL
RESULT BEFORE OTHER FUNCTIONS IN THIS MODULE WILL WORK</EM>.<P>
This function should not be called while LPTCAP is capturing data as it will
disturb the capturing process.<P>
This function detects the LPTCAP adapter via the <VAR>LOOPOUT</VAR> and
<VAR>LOOPIN</VAR> signals. It does not perform any diagnostic check on the port,
so it should not disturb any printers or other standard parallel peripherals
that may be connected to ports as the ports are checked.<P>
Ports are located through the BIOS parallel port base address table in low
memory. This means that LPTCAP will respect any parallel port reassignments
that have been made during or after boot-up via the BIOS parallel port table
(this does not include reassignments from parallel to serial ports made via
MODE), and will support parallel ports at non-standard addresses provided that
they have been detected by the BIOS or by program executed during or after
boot-up, and that they are compatible or backward-compatible with standard PC
parallel ports in hardware and software.<P>
<A NAME="lptcap_test"><H5>lptcap_test()</H5>
<EM>int lptcap_test(unsigned int ntests)</EM><P>
This function performs diagnostic tests on the LPTCAP adapter. <EM>IT MUST BE
CALLED AND RETURN A SUCCESSFUL RESULT BEFORE OTHER FUNCTIONS IN THIS MODULE
WILL WORK</EM>. The test consists of a basic presence detection, followed by a
test loop consisting of a logic test and a data loopthrough test, which is
repeated according to the ntests parameter.<P>
The basic presence detection uses the loopback signal to check that the LPTCAP
adapter is present, and determines the setting of the IRQ Polarity switch or
jumper (JP1) on the LPTCAP adapter.<P>
The logic test checks the operation of the data capture flip-flop and the data
acknowledge flip-flop. The data loopthrough test checks the shift register by
shifting data values of 0, 0xFF, 0x55 and 0xAA through it.<P>
The test takes approximately 0.4 milliseconds to 2 milliseconds (depending on
the speed of the Capture PC) multiplied by the ntests value (longer if the
SLOW or VERYSLOW parameters were used when LPTCAP was assembled).<P>
If a test fails, the hardware is set to its default state and lptcap_test()
stops testing and returns the error number.<P>
If this function is called while interrupt-driven receive mode is enabled
(via <A HREF="#lptcap_intmode_install">lptcap_intmode_install()</A>) it will
return LPTCAP_<WBR>ADAPTER_<WBR>INTMODE and will not perform any logic or data tests.<P>
This function should not be called while LPTCAP is capturing data as it will
disturb the capturing process. It should not be called while the Sender is
trying to send data. This means that any capture program should perform its
initial setup and tests <EM>BEFORE</EM> the Sender is instructed to send data.<P>
Return values are:<P>
<TABLE><TR><TD> </TD><TD>0 </TD><TD>LPTCAP_ADAPTER_PRESENT </TD><TD>Adapter present and working normally</TD></TR>
<TR><TD></TD><TD>1 </TD><TD>LPTCAP_ADAPTER_NO_PORT </TD><TD>No parallel port has been selected</TD></TR>
<TR><TD></TD><TD>2 </TD><TD>LPTCAP_ADAPTER_MISSING </TD><TD>Adapter is not attached</TD></TR>
<TR><TD></TD><TD>3 </TD><TD>LPTCAP_ADAPTER_INTMODE </TD><TD>System is running in interrupt-driven mode</TD></TR>
<TR><TD></TD><TD>4 </TD><TD>LPTCAP_ADAPTER_NO_DRDY </TD><TD>Adapter failed to activate <VAR>+-DRDY</VAR> signal</TD></TR>
<TR><TD></TD><TD>5 </TD><TD>LPTCAP_ADAPTER_ACKSTUK </TD><TD>Adapter <VAR>-ACKP</VAR> is stuck in active state</TD></TR>
<TR><TD></TD><TD>6 </TD><TD>LPTCAP_ADAPTER_NO_DACK </TD><TD>Adapter failed to activate <VAR>-ACKP</VAR> signal</TD></TR>
<TR><TD></TD><TD>7 </TD><TD>LPTCAP_ADAPTER_ACKLONG </TD><TD>Adapter <VAR>-ACKP</VAR> pulse too long</TD></TR>
<TR><TD></TD><TD>8 </TD><TD>LPTCAP_ADAPTER_BSYSTUK </TD><TD>Adapter indicated <VAR>BUSY</VAR> active after <VAR>-ACK</VAR> pulse</TD></TR>
<TR><TD></TD><TD>9 </TD><TD>LPTCAP_ADAPTER_STRSTUK </TD><TD><VAR>-STROBE</VAR> line stuck low (see notes below)</TD></TR>
<TR><TD></TD><TD>10 </TD><TD>LPTCAP_ADAPTER_SDISERR </TD><TD>Adapter <VAR>SDI</VAR> and <VAR>-SDI</VAR> states inconsistent</TD></TR>
<TR><TD></TD><TD>11 </TD><TD>LPTCAP_ADAPTER_DATAERR </TD><TD>Data loopthrough error (see notes below)</TD></TR></TABLE><P>
All non-zero values indicate a problem with the LPTCAP adapter or the parallel
port of the Capture PC, except return codes LPTCAP_<WBR>ADAPTER_<WBR>BSYSTUK and
LPTCAP_<WBR>ADAPTER_<WBR>STRSTUK, which may indicate that the Sender is already trying
to send data when lptcap_test() is called, or possibly that the Sender is
faulty or is connected but powered off.<P>
For a return value of LPTCAP_DATAERR, the byte values that were sent and
received in the data loopthrough test that failed are available through the
<A HREF="#lptcap_test_fail_data">lptcap_test_fail_data()</A> function and may be
displayed in the error message to possibly help a user to diagnose the problem.<P>
This function temporarily uses timer channel 2 for timeout checking. This
may interfere with any background sound generation or timing that is being
done by other parts of the program using timer channel 2.<P>
<A NAME="lptcap_test_fail_data"><H5>lptcap_test_fail_data()</H5>
<EM>unsigned int lptcap_test_fail_data(void)</EM><P>
This function returns an unsigned integer which is comprised of the
"sent" value (in the low byte) and the "received" value
(in the high byte) from the data loopthrough test that failed, when
<A HREF="#lptcap_test">lptcap_test()</A> returns an error code of
LPTCAP_<WBR>ADAPTER_<WBR>DATAERR. This may be displayed as part of the failure report
message if desired.<P>
<A NAME="lptcap_adjust"><H5>lptcap_adjust()</H5>
<EM>void lptcap_adjust(unsigned int ticks)</EM><P>
This function generates a pattern of accurately timed signals which are used
during adjustment of the LPTCAP adapter. See the <A HREF="#Adjustment">
Adjustment</A> section for details.<P>
The "ticks" parameter specifies the duration of the test. One timer
tick is approximately 55 milliseconds, so one second is about 18 ticks and one
minute is about 1092 ticks. If a zero "ticks" parameter is supplied,
lptcap_adjust() will generate the test signal until the user presses the Ctrl
key.<P>
This function may be used even if <A HREF="#lptcap_test">lptcap_test()</A> has
not been called, or when lptcap_test() returned an error code. This is because
it may be necessary to adjust the LPTCAP adapter before lptcap_test() will
report success.<P>
This function should not be called while LPTCAP is capturing data as it will
disturb the capturing process. If it is called when the LPTCAP system is
operating in interrupt-driven receive mode (via
<A HREF="#lptcap_intmode_install">lptcap_intmode_install()</A>) it will return
without generating any adjustment signal.<P>
This function temporarily uses timer channel 2 for timekeeping. This may
interfere with any background sound generation or timing that is being done
by other parts of the program using timer channel 2.<P>
<A NAME="lptcap_get_cont"><H5>lptcap_get_cont()</H5>
<EM>unsigned int lptcap_get_cont(void)</EM><P>
This function returns the states of the control lines provided by the Sender
at the time the function is called. The return value is bit-allocated:<P>
<TABLE><TR><TD> </TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD> </TD><TD>Reserved for future use</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> SELECT </TD><TD>signal from Sender; 1 = active</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD> INITIALIZE </TD><TD>signal from Sender; 1 = active</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD> AUTOFEED </TD><TD>signal from Sender; 1 = active</TD></TR></TABLE><P>
<A NAME="lptcap_set_stat"><H5>lptcap_set_stat()</H5>
<EM>void lptcap_set_stat(unsigned int stat_word)</EM><P>
This function sets the printer status signals which are returned to the Sender,
according to the stat_word parameter which is bit-allocated:<P>
<TABLE><TR><TD> </TD><TD>7</TD><TD>6</TD><TD>5</TD><TD>4</TD><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD></TR>
<TR><TD></TD><TD>*</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>*</TD><TD>*</TD><TD COLSPAN=2> Reserved for future use; should be 0</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> PAPER OUT </TD><TD>signal to Sender; 1 = paper out</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> NOTSELCTD </TD><TD>signal to Sender; 1 = not selected</TD></TR>
<TR><TD></TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD>*</TD><TD>.</TD><TD>.</TD><TD>.</TD><TD> ERROR </TD><TD>signal to Sender; 1 = error</TD></TR></TABLE><P>
The default and initial values for these signals are the "0" values,
which are "normal" (i.e. "no-error") values. This function
need not be used in normal circumstances, since the outgoing signals are set to
their default values when <A HREF="#lptcap_port">lptcap_port()</A> is called.<P>
<A NAME="lptcap_send_ack"><H5>lptcap_send_ack()</H5>
<EM>void lptcap_send_ack(void)</EM><P>
This function sends an acknowledgement signal to the Sender, consisting of
<VAR>-ACK</VAR> going low, <VAR>BUSY</VAR> going inactive, then <VAR>-ACK</VAR>
rising again. This may be required if the Sender does not receive an
acknowledgement for some reason and gets stuck waiting for it.<P>
<A NAME="lptcap_poll_new"><H5>lptcap_poll_new()</H5>
<EM>int lptcap_poll_new(void)</EM><P>
This function tests whether a new character has been captured and is available.
It returns 0 if not, or 1 if so. It does not return the character value, and
does not remove the character from the buffer.<P>
This function behaves differently in polled and interrupt-driven modes.
In polled mode, it examines the <VAR>+-DRDY</VAR> signal from the LPTCAP adapter
directly to see whether a new character has been captured. In interrupt-driven
mode, it examines the receive buffer pointers to determine whether there is any
unread data in the buffer. Also, in interrupt-driven mode, it checks and
corrects a condition where a character has been received but the interrupt was
lost. This condition could occur when this software is used with badly behaved
TSRs. It does not result in loss of data.<P>
<A NAME="lptcap_next_char"><H5>lptcap_next_char()</H5>
<EM>int lptcap_next_char(void)</EM><P>
This function returns the next character which has been captured and is
available, or returns an indication that there is no data available.<P>
If no character is available, this function returns -1 immediately.<P>
If a character is available, this function acknowledges the character and
removes it from the buffer, and returns the character value, which will be
in the range 0 to 255.<P>
In polled mode, this function examines the LPTCAP adapter directly, and in
interrupt-driven mode, it examines the buffer pointers and checks for missed
interrupts - see notes on <A HREF="#lptcap_poll_new">lptcap_poll_new()</A> for
details.<P>
<A NAME="lptcap_wait_char"><H5>lptcap_wait_char()</H5>
<EM>int lptcap_wait_char(unsigned int timeout_ticks)</EM><P>
This function waits for a character to be received, and returns the character
value. If the timeout_ticks parameter is non-zero, it will implement a timeout
check, and if no character is received within the timeout period, it returns a
value of -1. The timeout value is in units of one timer tick, or about 55
milliseconds. A zero timeout value will give an infinite timeout. Because
timer ticks are not synchronised to the function call, the actual time before
a timeout is reported may be up to one tick longer than the specified value.<P>
In polled mode, this function examines the LPTCAP adapter directly, and in
interrupt-driven mode, it examines the buffer pointers and checks for missed
interrupts - see notes on <A HREF="#lptcap_poll_new">lptcap_poll_new()</A> for
details.<P>
<A NAME="lptcap_autodetect_irq"><H5>lptcap_autodetect_irq()</H5>
<EM>int lptcap_autodetect_irq(unsigned int irqmask)</EM><P>
This function attempts to auto-detect the IRQ (interrupt request) number
associated with the LPTCAP port. It returns a value from 2 to 15 indicating
the IRQ number, or one of these error indications:<P>
<TABLE><TR><TD> </TD><TD>0 </TD><TD>LPTCAP_IRQ_NONE </TD><TD>No associated IRQ detected</TD></TR>
<TR><TD></TD><TD>-1 </TD><TD>LPTCAP_IRQ_INVERTED </TD><TD>IRQ polarity was incorrect</TD></TR>
<TR><TD></TD><TD>-2 </TD><TD>LPTCAP_IRQ_SEVERAL </TD><TD>More than one IRQ detected</TD></TR></TABLE><P>
If lptcap_autodetect_irq() returns LPTCAP_<WBR>IRQ_<WBR>NONE or LPTCAP_<WBR>IRQ_<WBR>SEVERAL,
interrupt-driven capture (if enabled) will probably fail to work properly.
A return value of LPTCAP_<WBR>IRQ_<WBR>INVERTED means that the IRQ Polarity switch or
jumper on the LPTCAP adapter must be changed to the other position. When
this has been done, <A HREF="#lptcap_test">lptcap_test()</A> must be called to
detect the new state of this switch/jumper, then lptcap_autodetect_irq() may be
called again.<P>
Any other value indicates a valid and correct IRQ number that is associated
with the LPTCAP port. On PC and PC/XT machines the IRQ number will be in the
range 2-7. On the AT and later machines the IRQ will be in the range 3-15
excluding 8 and 13.<P>
If interrupt-driven capturing is not required, there is no need to call this
function at all.<P>
This function does not enable the interrupt (except briefly during its testing),
and does not install the LPTCAP interrupt-driven receiver.<P>
The irqmask parameter is a bitstring which specifies which IRQs are to be
tested. Most interrupt-capable parallel ports are wired to IRQ7 or IRQ5, and
some may be jumper-selectable to other IRQs. Bits 0 to 15 of the irqmask
parameter correspond to IRQs 0 to 15, and a 1-bit enables testing of that IRQ.
Therefore a typical value for irqmask is 0x00A0, allowing IRQs 5 and 7 to be
tested, though any value, including 0xFFFF, can also be used.<P>
Some IRQs are not available on the slot bus, and these are not tested by this
function even if enabled in irqmask. On PC and PC/XT machines, IRQs 2-7 are
available on the slot bus (IRQ0 and IRQ1 are used on the motherboard). On AT
and later machines, IRQs 3-7, 9-12, 14 and 15 are available on the slot bus
(IRQ0, IRQ1, IRQ8 and IRQ13 are used on the motherboard and IRQ2 doesn't
exist).<P>
This function will probably fail on MicroChannel machines (IBM PS/2). It will
also probably fail if used in a DOS compatibility box within a multi-process
operating system such as Windows 3.x, Windows 95, Windows NT, OS/2 or Linux.<P>
Many soundcards use IRQ7. If the sound card has not been initialised, its
IRQ line driver may be in the high-impedance state and the parallel port may
be able to use the IRQ line. However, software that uses the sound card (such
as Windows or game software) may leave the buffer enabled, and this may prevent
the parallel port IRQ from working after these programs have been run.<P>
This function should not be called while LPTCAP is capturing data as it will
disturb the capturing process.<P>
<A NAME="lptcap_intmode_install"><H5>lptcap_intmode_install()</H5>
<EM>int lptcap_intmode_install(unsigned int irqnum, lptcap_bufdescriptor * bdp)</EM><P>
This function installs and enables interrupt-driven reception for the LPTCAP
system. In interrupt-driven mode, reception of a character by the LPTCAP
adapter causes an interrupt, which causes the CPU to read the character and
place it in a circular buffer or "queue" for later processing.
Interrupt-driven mode is not necessary in order to keep up with the data rate