+
+ irq_enable();
+
+ switch (regs->ah) {
+ case 0x00: handle_1400(regs); break;
+ case 0x01: handle_1401(regs); break;
+ case 0x02: handle_1402(regs); break;
+ case 0x03: handle_1403(regs); break;
+ default: handle_14XX(regs); break;
+ }
+ debug_exit(regs);
+}
+
+
+/****************************************************************
+ * LPT ports
+ ****************************************************************/
+
+static u16
+getLptAddr(struct bregs *regs)
+{
+ if (regs->dx >= 3) {
+ set_cf(regs, 1);
+ return 0;
+ }
+ u16 addr = GET_BDA(port_lpt[regs->dx]);
+ if (! addr)
+ set_cf(regs, 1);
+ return addr;
+}
+
+static void
+lpt_ret(struct bregs *regs, u16 addr, u16 timeout)
+{
+ u8 val8 = inb(addr+1);
+ regs->ah = (val8 ^ 0x48);
+ if (!timeout)
+ regs->ah |= 0x01;
+ set_cf(regs, 0);
+}
+
+// INT 17 - PRINTER - WRITE CHARACTER
+static void
+handle_1700(struct bregs *regs)
+{
+ u16 addr = getLptAddr(regs);
+ if (!addr)
+ return;
+ u16 timeout = GET_BDA(lpt_timeout[regs->dx]) << 8;
+
+ outb(regs->al, addr);
+ u8 val8 = inb(addr+2);
+ outb(val8 | 0x01, addr+2); // send strobe
+ nop();
+ outb(val8 & ~0x01, addr+2);
+ while (((inb(addr+1) & 0x40) == 0x40) && (timeout))
+ timeout--;
+
+ lpt_ret(regs, addr, timeout);
+}
+
+// INT 17 - PRINTER - INITIALIZE PORT
+static void
+handle_1701(struct bregs *regs)
+{
+ u16 addr = getLptAddr(regs);
+ if (!addr)
+ return;
+ u16 timeout = GET_BDA(lpt_timeout[regs->dx]) << 8;
+
+ u8 val8 = inb(addr+2);
+ outb(val8 & ~0x04, addr+2); // send init
+ nop();
+ outb(val8 | 0x04, addr+2);
+
+ lpt_ret(regs, addr, timeout);
+}
+
+// INT 17 - PRINTER - GET STATUS
+static void
+handle_1702(struct bregs *regs)
+{
+ u16 addr = getLptAddr(regs);
+ if (!addr)
+ return;
+ u16 timeout = GET_BDA(lpt_timeout[regs->dx]) << 8;
+
+ lpt_ret(regs, addr, timeout);
+}
+
+static void
+handle_17XX(struct bregs *regs)
+{
+ // Unsupported
+ set_cf(regs, 1);