BIOS calls or DOS functions are most likely adequate for the control of a printer in the polled mode. Direct machine-language control is necessary, however, in situations such as the following:
Interrupt-driven operation of the printer.
Polled operation with features which, e.g., permit taking the printer offline for adding paper without incurring the automatic 16-second timeout and the consequent loss of a character.
READING parallel data INTO the CPU from a device.
Machine-language control uses OUT instructions to transfer a byte from register AL of the CPU to the adapter's Out latches, or IN instructions to transfer data from the In buffers to register AL. A simplified logic diagram is shown in Figure 13-2. Machine language control is straightforward but several peculiarities of the adapter logic must be noted:
Data is sent to the printer by OUTputting a byte from register AL to the Data Out Latch. This latch has tri-state outputs which are always enabled. Thus, the printer's Data lines CANNOT be used for input; the Data In Buffer can only be used to read back to data in the Data Out Latch.
Status signals from the printer are INput into register AL via the Status In Buffer (bits 3-7 only). Table 13-3 shows the meaning assigned to the various bits. Note that some signals are complemented between the connector and the In Buffer. (The status byte returned by BIOS call 17h register AH has a timeout indicator added in bit 0 and, for some reason, has bits 3 and 6 complemented by software.)
Control signals are sent to the printer by OUTputting register AL (bits 0-5 only) to the Control Out Latch. Table 13-4 shows the meaning assigned to the various bits. Note that some signals are complemented between the latch output and the connector. Bit 4 (IRQ ENABLE) is not available at the connector; it is used to enable the ORing of the ACKNOWLEDGE status signal to the IRQ7 input to the 8259 Interrupt Controller (which will cause an interrupt 0Fh if not masked). Bit 5 is latched but not used further (see, however, the following section).
The control signals at the connector may be read back into register AL (bits 0-4 only) via the Control In Buffer. There are corresponding complementations between the connector and the In buffer (and bit 4 is simply a copy of the Out latch bit 4) so that Table 13-4 can be used in reverse for input. Note that since the Control Out Latch outputs are buffered, the control signal pins corresponding to control bits 0-3 can be used for input.
Table 13-4. Register AL Bit Assignments for Printer Control Signals
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|
| n.c. | n.c. | n.c. | IRQ Enable | Select | ~Initialize | Auto Feed | Strobe |
| Pin 17 | Pin 16 | Pin 14 | Pin 1 | ||||
|---|---|---|---|---|---|---|---|
| ~Select | ~Initialize | ~Autofeed | ~Strobe | ||||
To illustrate machine language control, a program fragment corresponding to subfunction 0 ("print the character in register AL") of BIOS call 17h is shown below:
sti ; allow higher-priority interrupt
...
mov si, dx ; printer number
mov bl, [PrintTimeout+si]
; load timeout parameter byte (=10 for PC)
shl si, 1
mov dx, [PrinterBase+si]
; Data port address of printer in DX
...
OR AH, AH
JZ .B2
...
.B2: ; subfunction 0
push ax
out dx, al ; send character to Data Out latch
inc dx ; point to Status port
.B3: ; loop while BUSY until timeout
sub cx, cx ; outer loop
.B3_1: ; inner loop
in al, dx ; read printer status
test al, 80h ; test the BUSY status bit
jnz .B4 ; not busy
loop .B3_1 ; busy: repeat inner loop
dec bl ; decr. outer loop counter
jnz .B3 ; repeat outer loop
or ah, 1 ; set timeout flag
and ah, 0F9h; clear unused bits
jmp ... ; go to return with error flag set
...
.B4: ; NOT BUSY: send ~STROBE
inc dx ; point to Control port
mov al, 0Dh ; set bit 0 (=STROBE) high -- also sets
; IRQ ENABLE low, SELECT high,
; ~INITIALIZE high, and AUTO FEED low
out dx, al ; send character to Control port
mov al, 0Ch ; set STROBE low again
out dx, al
pop ax
... ; go to read the status into AH
iret