The Parallel Port: Standard/Traditional/Compatibility/Centronics Mode

This is the traditional mode for sending data to the printer. It lacks
a proper handshake mechanism, so you have to be fast enough to react
to the bytes tho host sends. Because it is the original protocal used
by printers without a reverse channel, it is often called the compatibility
mode.

For the compatibility mode to be active, any 1284 extended mode has to be
terminated.

This mode is old and probably not properly implemented according the
current 1284 specs by many printers. That may be one reason why precise
information was hard to get and I had to comment with 'I do not know' at
quite a few details. There is no proper handshaking, probably because the
mode was not thoroughly thought through when first implemented well over
a decade ago. The following diagram shows my suggestion to implement
a working interface.

Unfortunately, when implementing a 1284 compliant device, I suspect it
must implement this mode, because it is the fall-back mode for
most host implementations.

Notes

Because the /Strobe signal was once specified(?)/used for a hardware
latch in the printer that triggers on the falling edge, I suspect that
bad hosts may choose to invalidate the data as soon as the
/Strobe pulse is deactivated. Do not be too surprised if
this happens and try to have P read the data
by 0.5us after /Strobe is activated.

My own implementation of a peripheral is not fast enough to get the
data 0.5us after /Strobe. It communicates with a Linux
kernel that yields each half pulse of /Strobe for 1us, so
there is more time to get the data.

I do not know whether P needs to pulse the Busy signal. The
Linux kernel only checks the signal in step 1.

When implementing this mode in a peripheral, my advice is to try to
use Busy as a handshake for /Strobe. However, when
P becomes busy, it must react in 1us time after /Strobe
goes low.

I do not know when to precisely indicate an error condition. The signal
is asynchronous. Since Linux checks the error in step 1,
the diagram suggests to use the same timing as for Busy.

I do not know whether the /Ack signal has to be signalled
relative to the timing of Busy, or whether it is asynchronous.
My implementation pulses /Ack just before Busy gets
low again. I do not know whether that is correct. Maybe Busy
has to be low before /Ack may become high again.

The /Ack signal can be used by the host to run interrupt driven,
since the PC port can generate interrupts on this pin. This would indicate
that indeed Busy should be low when /Ack, by getting
high, generates an interrupt.

The Linux kernel does not seem to pay too much attention to the /Ack
signal. To stop the host sending, the Busy signal is the important
signal.