📄 ppntddkgenport.c
字号:
unsigned ret = 0; unsigned tmo; pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_WRITE, LPTREG_CONTROL); for (; sz > 0; sz--, bp++) { pp_ntddkgenport_outb(*bp, LPTREG_DATA); for (tmo = 0; ; tmo++) { if (pp_ntddkgenport_inb(LPTREG_STATUS) & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_WRITE | LPTCTRL_ADDRSTB, LPTREG_CONTROL); for (tmo = 0; ; tmo++) { if (!(pp_ntddkgenport_inb(LPTREG_STATUS) & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_WRITE, LPTREG_CONTROL); ret++; } return ret;}unsigned parport_ntddkgenport_emul_epp_read_addr(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo; pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION, LPTREG_CONTROL); for (; sz > 0; sz--, bp++) { for (tmo = 0; ; tmo++) { if (pp_ntddkgenport_inb(LPTREG_STATUS) & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION | LPTCTRL_ADDRSTB, LPTREG_CONTROL); for (tmo = 0; ; tmo++) { if (!(pp_ntddkgenport_inb(LPTREG_STATUS) & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } *bp = pp_ntddkgenport_inb(LPTREG_DATA); pp_ntddkgenport_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION, LPTREG_CONTROL); ret++; } return ret;}/* ---------------------------------------------------------------------- */static int ecp_forward(void){ unsigned tmo = 0x10000; if (pp_ntddkgenport_inb(LPTREG_DSR) & 0x20) return 0; /* Event 47: Set nInit high */ pp_ntddkgenport_outb(0x26, LPTREG_DCR); /* Event 49: PError goes high */ while (!(pp_ntddkgenport_inb(LPTREG_DSR) & 0x20)) { if (!(--tmo)) return -1; } /* start driving the bus */ pp_ntddkgenport_outb(0x04, LPTREG_DCR); return 0;}static int ecp_reverse(void){ unsigned tmo = 0x10000; if (!(pp_ntddkgenport_inb(LPTREG_DSR) & 0x20)) return 0; pp_ntddkgenport_outb(0x24, LPTREG_DCR); /* Event 39: Set nInit low to initiate bus reversal */ pp_ntddkgenport_outb(0x20, LPTREG_DCR); while (pp_ntddkgenport_inb(LPTREG_DSR) & 0x20) { if (!(--tmo)) return -1; } return 0;}static unsigned emptyfifo(unsigned cnt){ unsigned fcnt = 0; pp_ntddkgenport_outb(0xd0, LPTREG_ECONTROL); /* FIFOtest mode */ while ((pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x01) && fcnt < 32 && fcnt < cnt) { pp_ntddkgenport_inb(LPTREG_TFIFO); fcnt++; } lprintf(10, "emptyfifo: FIFO contained %d bytes\n", fcnt); pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return cnt - fcnt;}unsigned parport_ntddkgenport_ecp_write_data(const void *buf, unsigned sz){ const unsigned char *bp = (const unsigned char *)buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; if (ecp_forward()) return 0; pp_ntddkgenport_outb(0x70, LPTREG_ECONTROL); /* ECP mode */ while (sz > 0) { while ((stat = pp_ntddkgenport_inb(LPTREG_ECONTROL)) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { pp_ntddkgenport_outsb(LPTREG_DFIFO, bp, 8); bp += 8; sz -= 8; ret += 8; } else { pp_ntddkgenport_outb(*bp++, LPTREG_DFIFO); sz--; ret++; } tmo = 0x10000; } while (!(pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x01) || !(pp_ntddkgenport_inb(LPTREG_DSR) & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return ret;}unsigned parport_ntddkgenport_ecp_read_data(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; if (ecp_reverse()) return 0; pp_ntddkgenport_outb(0x70, LPTREG_ECONTROL); /* ECP mode */ while (sz > 0) { while ((stat = pp_ntddkgenport_inb(LPTREG_ECONTROL)) & 0x01) if (!(--tmo)) { pp_ntddkgenport_outb(0xd0, LPTREG_ECONTROL); /* FIFOTEST mode */ while (!(pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x01) && sz > 0) { *bp++ = pp_ntddkgenport_inb(LPTREG_TFIFO); sz--; ret++; } pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return ret; } if (stat & 0x02 && sz >= 8) { pp_ntddkgenport_insb(LPTREG_DFIFO, bp, 8); bp += 8; sz -= 8; ret += 8; } else { *bp++ = pp_ntddkgenport_inb(LPTREG_DFIFO); sz--; ret++; } tmo = 0x10000; } pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return ret;}unsigned parport_ntddkgenport_ecp_write_addr(const void *buf, unsigned sz){ const unsigned char *bp = (const unsigned char *)buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; if (ecp_forward()) return 0; pp_ntddkgenport_outb(0x70, LPTREG_ECONTROL); /* ECP mode */ while (sz > 0) { while ((stat = pp_ntddkgenport_inb(LPTREG_ECONTROL)) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { pp_ntddkgenport_outsb(LPTREG_AFIFO, bp, 8); bp += 8; sz -= 8; ret += 8; } else { pp_ntddkgenport_outb(*bp++, LPTREG_AFIFO); sz--; ret++; } tmo = 0x10000; } while (!(pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x01) || !(pp_ntddkgenport_inb(LPTREG_DSR) & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return ret;}/* ---------------------------------------------------------------------- */unsigned parport_ntddkgenport_emul_ecp_write_data(const void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret; unsigned char ctl; unsigned tmo; if (ecp_forward()) return 0; ctl = pp_ntddkgenport_inb(LPTREG_CONTROL) & ~PARPORT_CONTROL_AUTOFD; /* HostAck high (data, not command) */ pp_ntddkgenport_outb(ctl, LPTREG_CONTROL); for (ret = 0; ret < sz; ret++, bp++) { pp_ntddkgenport_outb(*bp, LPTREG_DATA); pp_ntddkgenport_outb(ctl | PARPORT_CONTROL_STROBE, LPTREG_CONTROL); for (tmo = 0; pp_ntddkgenport_inb(LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++) if (tmo > 0x1000) return ret; pp_ntddkgenport_outb(ctl, LPTREG_CONTROL); for (tmo = 0; !(pp_ntddkgenport_inb(LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++) if (tmo > 0x1000) return ret; } return ret;}unsigned parport_ntddkgenport_emul_ecp_write_addr(const void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret; unsigned char ctl; unsigned tmo; if (ecp_forward()) return 0; ctl = pp_ntddkgenport_inb(LPTREG_CONTROL) | PARPORT_CONTROL_AUTOFD; /* HostAck low (command, not data) */ pp_ntddkgenport_outb(ctl, LPTREG_CONTROL); for (ret = 0; ret < sz; ret++, bp++) { pp_ntddkgenport_outb(*bp, LPTREG_DATA); pp_ntddkgenport_outb(ctl | PARPORT_CONTROL_STROBE, LPTREG_CONTROL); for (tmo = 0; pp_ntddkgenport_inb(LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++) if (tmo > 0x1000) return ret; pp_ntddkgenport_outb(ctl, LPTREG_CONTROL); for (tmo = 0; !(pp_ntddkgenport_inb(LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++) if (tmo > 0x1000) return ret; } return ret;}unsigned parport_ntddkgenport_emul_ecp_read_data(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned char ctl, stat; int command; unsigned tmo; if (ecp_reverse()) return 0; ctl = pp_ntddkgenport_inb(LPTREG_CONTROL); /* Set HostAck low to start accepting data. */ pp_ntddkgenport_outb(ctl | PARPORT_CONTROL_AUTOFD, LPTREG_CONTROL); while (ret < sz) { /* Event 43: Peripheral sets nAck low. It can take as long as it wants. */ tmo = 0; do { stat = pp_ntddkgenport_inb(LPTREG_STATUS); if ((++tmo) > 0x10000) goto out; } while (stat & PARPORT_STATUS_ACK); /* Is this a command? */ command = stat & PARPORT_STATUS_BUSY; if (command) { //lprintf(3, "ECP: warning: emulation does not support RLE\n"); goto out; } /* Read the data. */ *bp = pp_ntddkgenport_inb(LPTREG_DATA); /* Event 44: Set HostAck high, acknowledging handshake. */ pp_ntddkgenport_outb(ctl & ~PARPORT_CONTROL_AUTOFD, LPTREG_CONTROL); /* Event 45: The peripheral has 35ms to set nAck high. */ tmo = 0; do { stat = pp_ntddkgenport_inb(LPTREG_STATUS); if ((++tmo) > 0x10000) goto out; } while (!(stat & PARPORT_STATUS_ACK)); /* Event 46: Set HostAck low and accept the data. */ pp_ntddkgenport_outb(ctl | PARPORT_CONTROL_AUTOFD, LPTREG_CONTROL); /* Normal data byte. */ bp++; ret++; } out: return ret;} /* ---------------------------------------------------------------------- */#if 1unsigned parport_ntddkgenport_fpgaconfig_write(const void *buf, unsigned sz){ const unsigned char *bp = buf; unsigned u; for (u = 0; u < sz; u++, bp++) pp_ntddkgenport_outb(*bp, LPTREG_DATA); return sz;}#elseunsigned parport_ntddkgenport_fpgaconfig_write(const void *buf, unsigned sz){ const unsigned char *bp = buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; if (pp_ntddkgenport_modes & PARPORT_MODE_PCECR) { pp_ntddkgenport_outb(0x50, LPTREG_ECONTROL); /* COMPAT FIFO mode */ while (sz > 0) { while ((stat = pp_ntddkgenport_inb(LPTREG_ECONTROL)) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { pp_ntddkgenport_outsb(LPTREG_DFIFO, bp, 8); bp += 8; sz -= 8; ret += 8; } else { pp_ntddkgenport_outb(*bp++, LPTREG_DFIFO); sz--; ret++; } tmo = 0x10000; } while (!(pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x01) || !(pp_ntddkgenport_inb(LPTREG_DSR) & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } pp_ntddkgenport_outb(0x30, LPTREG_ECONTROL); /* PS/2 mode */ return ret; } for (ret = 0; ret < sz; ret++, bp++) pp_ntddkgenport_outb(*bp, LPTREG_DATA); return sz;}#endif/* ---------------------------------------------------------------------- */const struct parport_ops parport_ntddkgenport_ops = { parport_ntddkgenport_read_data, parport_ntddkgenport_write_data, parport_ntddkgenport_read_status, parport_ntddkgenport_read_control, parport_ntddkgenport_write_control, parport_ntddkgenport_frob_control, parport_ntddkgenport_epp_write_data, parport_ntddkgenport_epp_read_data, parport_ntddkgenport_epp_write_addr, parport_ntddkgenport_epp_read_addr, parport_ntddkgenport_ecp_write_data, parport_ntddkgenport_ecp_read_data, parport_ntddkgenport_ecp_write_addr, parport_ntddkgenport_fpgaconfig_write};const struct parport_ops parport_ntddkgenport_emul_ops = { parport_ntddkgenport_read_data, parport_ntddkgenport_write_data, parport_ntddkgenport_read_status, parport_ntddkgenport_read_control, parport_ntddkgenport_write_control, parport_ntddkgenport_frob_control, parport_ntddkgenport_emul_epp_write_data, parport_ntddkgenport_emul_epp_read_data, parport_ntddkgenport_emul_epp_write_addr, parport_ntddkgenport_emul_epp_read_addr, parport_ntddkgenport_emul_ecp_write_data, parport_ntddkgenport_emul_ecp_read_data, parport_ntddkgenport_emul_ecp_write_addr, parport_ntddkgenport_fpgaconfig_write};/* ---------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -