3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
10 #include <hw/cpu/cpu.h>
11 #include <hw/dos/dos.h>
12 #include <hw/dos/doswin.h>
13 #include <hw/parport/parport.h>
15 const char *parport_type_str[PARPORT_MAX] = {
23 int init_parports = 0;
24 int bios_parports = 0;
25 uint16_t standard_parport_ports[STANDARD_PARPORT_PORTS] = {0x3BC,0x378,0x278};
26 struct info_parport info_parport[MAX_PARPORTS];
29 int already_got_parport(uint16_t port) {
32 for (i=0;i < (unsigned int)info_parports;i++) {
33 if (info_parport[i].port == port)
40 uint16_t get_bios_parport(unsigned int index) {
41 if (index >= (unsigned int)bios_parports)
44 #if TARGET_MSDOS == 32
45 return *((uint16_t*)(0x400 + 8 + (index*2)));
47 return *((uint16_t far*)MK_FP(0x40,8 + (index*2)));
59 memset(info_parport,0,sizeof(info_parport));
61 /* read the BIOS equipment word[11-9]. how many serial ports? */
62 #if TARGET_MSDOS == 32
63 eqw = *((uint16_t*)(0x400 + 0x10));
65 eqw = *((uint16_t far*)MK_FP(0x40,0x10));
67 bios_parports = (eqw >> 14) & 3;
73 /* TODO: Add code where if caller guesses by PnP info the port is ECP or EPP (or both) we
74 * omit some tests and assume it's correct.
76 * Example: If the BIOS reports two I/O ports and they are 0x400 apart, then the port
77 * is an ECP type and ECP type tests are unnecessary. If PnP data lists the I/O range
78 * as being 8 ports long, then it's probably an EPP type port too and we can omit
80 int add_pnp_parport(uint16_t port,int irq,int dma,int type) {
81 struct info_parport *prt;
86 if (already_got_parport(port))
88 if (info_parports >= MAX_PARPORTS)
90 prt = &info_parport[info_parports];
92 prt->max_xfer_size = 1;
94 prt->output_mode = PARPORT_MODE_STANDARD_STROBE_ACK;
95 prt->type = PARPORT_STANDARD;
100 /* if the caller knows better than us, then take his word for it */
103 if (PARPORT_SUPPORTS_ECP(prt->type)) {
106 /* detect ECP by attempting to enable the configuration mode */
107 outp(prt->port+PARPORT_IO_ECP_CONTROL,7 << 5);
108 a = inp(prt->port+PARPORT_IO_ECP_REG_A);
109 b = inp(prt->port+PARPORT_IO_ECP_REG_B);
111 if (a != 0xFF && b != 0xFF) {
112 prt->type = PARPORT_ECP;
114 switch ((a >> 4) & 7) {
115 case 0: prt->max_xfer_size = 2; break;
116 case 1: prt->max_xfer_size = 1; break;
117 case 2: prt->max_xfer_size = 4; break;
121 switch ((b >> 3) & 7) {
122 case 1: prt->irq = 7; break;
123 case 2: prt->irq = 9; break;
124 case 3: prt->irq = 10; break;
125 case 4: prt->irq = 11; break;
126 case 5: prt->irq = 14; break;
127 case 6: prt->irq = 15; break;
128 case 7: prt->irq = 5; break;
134 case 1: prt->dma = 1; break;
135 case 2: prt->dma = 2; break;
136 case 3: prt->dma = 3; break;
137 case 5: prt->dma = 5; break;
138 case 6: prt->dma = 6; break;
139 case 7: prt->dma = 7; break;
144 /* switch to EPP mode for the test below if the ECP port supports it */
145 if (prt->type == PARPORT_ECP)
146 outp(prt->port+PARPORT_IO_ECP_CONTROL,4 << 5);
150 /* this might be one of those EPP/ECP ports, set it to "standard byte mode" to enable the below test to find the port.
151 * documentation mentions that "in ECP mode the SPP ports may disappear" so to successfully probe ports left in ECP
152 * mode we have to write to the control register to bring it back.
154 * The (minimal) documentation I have doesn't say whether this port can be read back.
155 * On older 10-bit decode hardware, this will probably only end up writing over the control bits (0x77A -> 0x37A)
156 * and should be safe to carry out. On newer hardware (mid 90's) it's highly unlikely anything would be assigned
157 * to I/O ports 0x778-0x77F. On newer PCI hardware, it's even less likely. */
158 outp(prt->port+PARPORT_IO_ECP_CONTROL,1 << 5); /* mode=byte (bi-directional) ecpint=0 dma=0 ecpserv=0 */
160 /* put it back into Standard mode, disable bi-directional */
161 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 */
162 /* control ports are usually readable. if what we wrote didn't take then this is probably not a parallel port */
163 if ((inp(prt->port+PARPORT_IO_CONTROL) & 0xF) != 0x4) return 0;
165 /* write to the control port again. if this is ancient 10-bit decode hardware, then it is probably NOT ECP/EPP
166 * compliant. we detect this by whether this IO write corrupts the control register.
167 * note control = port+2 and extended control = port+0x402 */
168 outp(prt->port+PARPORT_IO_ECP_CONTROL,(1 << 5) | 0xC); /* CONTROL = sets bidirectional, and two control lines. EXTCTRL = maintains byte mode and turns on ECP interrupt+DMA */
169 if ((inp(prt->port+PARPORT_IO_CONTROL) & 0xF) == 0xC) /* if the +0x402 IO write changed the control register, then it's 10-bit decode and not EPP/ECP */
172 outp(prt->port+PARPORT_IO_ECP_CONTROL,(1 << 5) | 0x0); /* regain sane extended control */
173 outp(prt->port+PARPORT_IO_CONTROL,0x04);
175 /* the data port is write only, though you are always allowed to read it back.
176 * on bidirectional ports this is how you read back data.
177 * we do not attempt to write to the status port. it is read only. worse, on modern
178 * systems it can conflict with the ISA Plug & Play protocol (0x279) */
179 outp(prt->port,0x55); if (inp(prt->port) != 0x55) return 0;
180 outp(prt->port,0xAA); if (inp(prt->port) != 0xAA) return 0;
181 outp(prt->port,0xFF); if (inp(prt->port) != 0xFF) return 0;
182 outp(prt->port,0x00); if (inp(prt->port) != 0x00) return 0;
184 /* do a parport init printer */
185 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 */
186 if ((inp(prt->port+PARPORT_IO_CONTROL)&0xF) != 0x4) return 0;
188 /* try to toggle bit 5 (bi-directional enable) */
189 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=0 */
190 if ((inp(prt->port+PARPORT_IO_CONTROL) & (1 << 5)) == 0) {
191 outp(prt->port+PARPORT_IO_CONTROL,0x24); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=1 */
192 if ((inp(prt->port+PARPORT_IO_CONTROL) & (1 << 5)) != 0)
193 prt->type = PARPORT_BIDIRECTIONAL;
195 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=0 */
198 /* standard I/O locations have standard IRQ assignments, apparently */
200 if (!bit10) { /* if not 10-bit decode, then check for ECP control registers */
203 /* detect ECP by attempting to enable the configuration mode */
204 outp(prt->port+PARPORT_IO_ECP_CONTROL,7 << 5);
205 a = inp(prt->port+PARPORT_IO_ECP_REG_A);
206 b = inp(prt->port+PARPORT_IO_ECP_REG_B);
208 if (a != 0xFF && b != 0xFF) {
209 prt->type = PARPORT_ECP;
211 switch ((a >> 4) & 7) {
212 case 0: prt->max_xfer_size = 2; break;
213 case 1: prt->max_xfer_size = 1; break;
214 case 2: prt->max_xfer_size = 4; break;
218 switch ((b >> 3) & 7) {
219 case 1: prt->irq = 7; break;
220 case 2: prt->irq = 9; break;
221 case 3: prt->irq = 10; break;
222 case 4: prt->irq = 11; break;
223 case 5: prt->irq = 14; break;
224 case 6: prt->irq = 15; break;
225 case 7: prt->irq = 5; break;
231 case 1: prt->dma = 1; break;
232 case 2: prt->dma = 2; break;
233 case 3: prt->dma = 3; break;
234 case 5: prt->dma = 5; break;
235 case 6: prt->dma = 6; break;
236 case 7: prt->dma = 7; break;
241 /* switch to EPP mode for the test below if the ECP port supports it */
242 if (prt->type == PARPORT_ECP)
243 outp(prt->port+PARPORT_IO_ECP_CONTROL,4 << 5);
247 if (type < 0 || PARPORT_SUPPORTS_EPP(type)) {
248 /* the caller might be autodetecting EPP based on the I/O length.
249 * we double-check to be sure, it might be some bullshit BIOS
250 * reporting 8 ports long for a device that only responds to the
253 /* an EPP port could conceivably exist on a 10-bit decode ISA card */
254 /* NOTES: Toshiba laptops do NOT support EPP mode, only ECP. There appears to be a hardware
255 * bug in decoding the 0x778-0x77F I/O region where port 0x77A is repeated on 0x77B,
258 * The Compaq LTE Elite supports EPP and ECP. It follows the standard in ignoring
259 * the bidir bit when setting mode 0, but does not disable EPP registers when
261 * ... erm, well, at least I think the extra registers are EPP. The address port
262 * always returns 0x00 and the data port always returns 0x25 (this is with nothing
263 * attached to the parallel port). The problem is we can only detect if something
264 * is there, we can't tell if it's an EPP port or just some ancient ISA card that
265 * responds to 0x3FB-0x3FF with it's own weirdness. A Google search for Compaq LTE
266 * Elite and parallel port suggests that there are tools to configure the port as
267 * EPP, so obviously at some level it speaks EPP mode. */
268 if (inp(prt->port+PARPORT_IO_EPP_ADDRESS) != 0xFF && inp(prt->port+PARPORT_IO_EPP_DATA) != 0xFF) {
269 if (prt->type == PARPORT_ECP)
270 prt->type = PARPORT_ECP_AND_EPP;
272 prt->type = PARPORT_EPP;
276 /* return the port to standard bidir mode */
277 if (PARPORT_SUPPORTS_ECP(prt->type))
278 outp(prt->port+PARPORT_IO_ECP_CONTROL,1 << 5);
280 /* shut off the lines */
281 outp(prt->port+PARPORT_IO_CONTROL,0x00); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=0 */
282 outp(prt->port+PARPORT_IO_DATA,0x00);
288 int probe_parport(uint16_t port) {
289 struct info_parport *prt;
294 if (already_got_parport(port))
296 if (info_parports >= MAX_PARPORTS)
298 prt = &info_parport[info_parports];
300 prt->max_xfer_size = 1;
302 prt->output_mode = PARPORT_MODE_STANDARD_STROBE_ACK;
303 prt->type = PARPORT_STANDARD;
307 /* this might be one of those EPP/ECP ports, set it to "standard byte mode" to enable the below test to find the port.
308 * documentation mentions that "in ECP mode the SPP ports may disappear" so to successfully probe ports left in ECP
309 * mode we have to write to the control register to bring it back.
311 * The (minimal) documentation I have doesn't say whether this port can be read back.
312 * On older 10-bit decode hardware, this will probably only end up writing over the control bits (0x77A -> 0x37A)
313 * and should be safe to carry out. On newer hardware (mid 90's) it's highly unlikely anything would be assigned
314 * to I/O ports 0x778-0x77F. On newer PCI hardware, it's even less likely. */
315 outp(prt->port+PARPORT_IO_ECP_CONTROL,1 << 5); /* mode=byte (bi-directional) ecpint=0 dma=0 ecpserv=0 */
317 /* put it back into Standard mode, disable bi-directional */
318 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 */
319 /* control ports are usually readable. if what we wrote didn't take then this is probably not a parallel port */
320 if ((inp(prt->port+PARPORT_IO_CONTROL) & 0xF) != 0x4) return 0;
322 /* write to the control port again. if this is ancient 10-bit decode hardware, then it is probably NOT ECP/EPP
323 * compliant. we detect this by whether this IO write corrupts the control register.
324 * note control = port+2 and extended control = port+0x402 */
325 outp(prt->port+PARPORT_IO_ECP_CONTROL,(1 << 5) | 0xC); /* CONTROL = sets bidirectional, and two control lines. EXTCTRL = maintains byte mode and turns on ECP interrupt+DMA */
326 if ((inp(prt->port+PARPORT_IO_CONTROL) & 0xF) == 0xC) /* if the +0x402 IO write changed the control register, then it's 10-bit decode and not EPP/ECP */
329 outp(prt->port+PARPORT_IO_ECP_CONTROL,(1 << 5) | 0x0); /* regain sane extended control */
330 outp(prt->port+PARPORT_IO_CONTROL,0x04);
332 /* the data port is write only, though you are always allowed to read it back.
333 * on bidirectional ports this is how you read back data.
334 * we do not attempt to write to the status port. it is read only. worse, on modern
335 * systems it can conflict with the ISA Plug & Play protocol (0x279) */
336 outp(prt->port,0x55); if (inp(prt->port) != 0x55) return 0;
337 outp(prt->port,0xAA); if (inp(prt->port) != 0xAA) return 0;
338 outp(prt->port,0xFF); if (inp(prt->port) != 0xFF) return 0;
339 outp(prt->port,0x00); if (inp(prt->port) != 0x00) return 0;
341 /* do a parport init printer */
342 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 */
343 if ((inp(prt->port+PARPORT_IO_CONTROL)&0xF) != 0x4) return 0;
345 /* try to toggle bit 5 (bi-directional enable) */
346 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=0 */
347 if ((inp(prt->port+PARPORT_IO_CONTROL) & (1 << 5)) == 0) {
348 outp(prt->port+PARPORT_IO_CONTROL,0x24); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=1 */
349 if ((inp(prt->port+PARPORT_IO_CONTROL) & (1 << 5)) != 0)
350 prt->type = PARPORT_BIDIRECTIONAL;
352 outp(prt->port+PARPORT_IO_CONTROL,0x04); /* select=0 init=1 autolinefeed=0 strobe=0 bidir=0 */
355 /* standard I/O locations have standard IRQ assignments, apparently */
357 if (prt->port == 0x3BC)
359 else if (prt->port == 0x378)
361 else if (prt->port == 0x278)
364 if (!bit10) { /* if not 10-bit decode, then check for ECP control registers */
367 /* detect ECP by attempting to enable the configuration mode */
368 outp(prt->port+PARPORT_IO_ECP_CONTROL,7 << 5);
369 a = inp(prt->port+PARPORT_IO_ECP_REG_A);
370 b = inp(prt->port+PARPORT_IO_ECP_REG_B);
372 if (a != 0xFF && b != 0xFF) {
373 prt->type = PARPORT_ECP;
375 switch ((a >> 4) & 7) {
376 case 0: prt->max_xfer_size = 2; break;
377 case 1: prt->max_xfer_size = 1; break;
378 case 2: prt->max_xfer_size = 4; break;
381 switch ((b >> 3) & 7) {
382 case 1: prt->irq = 7; break;
383 case 2: prt->irq = 9; break;
384 case 3: prt->irq = 10; break;
385 case 4: prt->irq = 11; break;
386 case 5: prt->irq = 14; break;
387 case 6: prt->irq = 15; break;
388 case 7: prt->irq = 5; break;
392 case 1: prt->dma = 1; break;
393 case 2: prt->dma = 2; break;
394 case 3: prt->dma = 3; break;
395 case 5: prt->dma = 5; break;
396 case 6: prt->dma = 6; break;
397 case 7: prt->dma = 7; break;
401 /* switch to EPP mode for the test below if the ECP port supports it */
402 if (prt->type == PARPORT_ECP)
403 outp(prt->port+PARPORT_IO_ECP_CONTROL,4 << 5);
406 /* an EPP port could conceivably exist on a 10-bit decode ISA card */
407 /* NOTES: Toshiba laptops do NOT support EPP mode, only ECP. There appears to be a hardware
408 * bug in decoding the 0x778-0x77F I/O region where port 0x77A is repeated on 0x77B,
411 * The Compaq LTE Elite supports EPP and ECP. It follows the standard in ignoring
412 * the bidir bit when setting mode 0, but does not disable EPP registers when
414 * ... erm, well, at least I think the extra registers are EPP. The address port
415 * always returns 0x00 and the data port always returns 0x25 (this is with nothing
416 * attached to the parallel port). The problem is we can only detect if something
417 * is there, we can't tell if it's an EPP port or just some ancient ISA card that
418 * responds to 0x3FB-0x3FF with it's own weirdness. A Google search for Compaq LTE
419 * Elite and parallel port suggests that there are tools to configure the port as
420 * EPP, so obviously at some level it speaks EPP mode. */
421 if (inp(prt->port+PARPORT_IO_EPP_ADDRESS) != 0xFF && inp(prt->port+PARPORT_IO_EPP_DATA) != 0xFF) {
422 if (prt->type == PARPORT_ECP)
423 prt->type = PARPORT_ECP_AND_EPP;
425 prt->type = PARPORT_EPP;
428 /* return the port to standard bidir mode */
429 if (PARPORT_SUPPORTS_ECP(prt->type))
430 outp(prt->port+PARPORT_IO_ECP_CONTROL,1 << 5);
432 /* shut off the lines */
433 outp(prt->port+PARPORT_IO_CONTROL,0x00); /* select=0 init=0 autolinefeed=0 strobe=0 bidir=0 */
434 outp(prt->port+PARPORT_IO_DATA,0x00);