/******************************** includes ********************************/ #ifdef LINUX /* linux stuph, not all of it is necessary */ #include #include #include #include #include #include /* assembly stuph, not all of it is necessary */ #include #include #include #include #include #endif #ifdef DOS #include #define inb(a) inp(a) #define outb(a,b) outp(b,a) #endif #include /********************************* defines **********************************/ /* stylistic defines */ #define IS == #define AINT != #define AND && #define OR || /* kit timeout in hard-coded loops */ #define TIMEOUT 100000 /* hardware naming abstractions */ /* information from http://www.paranoia.com/~filipg/HTML/LINK/PORTS/F_PARALLEL5.html by Kris Heidenstrom , 10/19/1994 and http://www.paranoia.com/~filipg/HTML/LINK/PORTS/F_PARALLEL1.html by Zahahai Stewart , 1/9/94 (general good stuff here) */ /*** offsets for parallel port ***/ /* I'm hard coding in the device address of lpt1 because this needs * to be portable between linux and DOS. :-P Wait...that doesn't * quite make sense, but let's just say it's harder to code an autodetect * sequence for both linux and DOS than to assume that lpt1 is always at * the same place (which it usually is, and most people only use lpt1 * anyways). */ #define LP1_BASE 0x378 #define DR_OFF 0x0 #define SR_OFF 0x1 #define CR_OFF 0x2 #define LP1_DR LP1_BASE + DR_OFF #define LP1_SR LP1_BASE + SR_OFF #define LP1_CR LP1_BASE + CR_OFF /**** * 7. Data Register * * The data register is at IOBase+0. It may be read and written (using * the IN and OUT instructions, or inportb() and outportb() or inp() and * outp()). Writing a byte to this register causes the byte value to * appear on pins 2 through 9 of the D-sub connector (unless the port is * bidirectional and is set to input mode). The value will remain latched * until you write another value to the data register. Reading this * register yields the state of those pins. * * 7 6 5 4 3 2 1 0 * * . . . . . . . D7 (pin 9), 1=High, 0=Low * . * . . . . . . D6 (pin 8), 1=High, 0=Low * . . * . . . . . D5 (pin 7), 1=High, 0=Low * . . . * . . . . D4 (pin 6), 1=High, 0=Low * . . . . * . . . D3 (pin 5), 1=High, 0=Low * . . . . . * . . D2 (pin 4), 1=High, 0=Low * . . . . . . * . D1 (pin 3), 1=High, 0=Low * . . . . . . . * D0 (pin 2), 1=High, 0=Low * ****/ /* no bit twiddles here */ /**** * 8. Status Register * * The status register is at IOBase+1. It is read-only (writes will be * ignored). Reading the port yields the state of the five status input * pins on the parallel port connector at the time of the read access: * * 7 6 5 4 3 2 1 0 * * . . . . . . . Busy . . (pin 11), high=0, low=1 (inverted) * . * . . . . . . Ack . . (pin 10), high=1, low=0 (true) * . . * . . . . . No paper (pin 12), high=1, low=0 (true) * . . . * . . . . Selected (pin 13), high=1, low=0 (true) * . . . . * . . . Error. . (pin 15), high=1, low=0 (true) * . . . . . * * * Undefined * ****/ #define SR_BUSY 0x80 #define SR_ACK 0x40 #define SR_NP 0x20 #define SR_SEL 0x10 #define SR_ERR 0x08 /**** * 9. Control Register * * The control register is at IOBase+2. It is read/write: * * 7 6 5 4 3 2 1 0 * * * . . . . . . Unused (undefined on read, ignored on write) * . . * . . . . . Bidirectional control, see below * . . . * . . . . Interrupt control, 1=enable, 0=disable * . . . . * . . . Select . . (pin 17), 1=low, 0=high (inverted) * . . . . . * . . Initialize (pin 16), 1=high, 0=low (true) * . . . . . . * . Auto Feed (pin 14), 1=low, 0=high (inverted) * . . . . . . . * Strobe . . (pin 1), 1=low, 0=high (inverted) * ****/ #define CR_BID 0x20 #define CR_INT 0x10 #define CR_SEL 0x08 #define CR_INIT 0x04 #define CR_AUTO 0x02 #define CR_STB 0x01 /**** * 10. Bidirectional Control Bit * * The bidirectional control bit is only supported on true bidirectional * ports - on other ports, it behaves like bits 7 and 6. On a proper * bidirectional port, setting this bit to '1' causes the outputs of the * buffer that drives pins 2 through 9 of the 25-pin connector to go into * a high-impedance state, so that data can be _input_ on those pins. * * In this state, values written to the data register will be stored in * the latch chip, but not asserted on the connector, and reading the * data register will yield the states of the pins, which may be driven * by an external device without stressing or damaging the port driver. * * Also note that on some machines, another port must be set correctly to * enable the bidirectional features, in addition to this bit. ****/