📄 ppwin.c
字号:
if (parport_win_read_status() & LPTSTAT_EPPTIMEOUT) { pp_win_epp_clear_timeout(); goto rt; } ret++; } rt: setecr(0x30); /* PS/2 mode */ return ret;}unsigned parport_win_epp_read_addr(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; setecr(0x90); /* EPP mode */ for (; sz > 0; sz--, bp++) { *bp = parport_win_read_eppaddr(); if (parport_win_read_status() & LPTSTAT_EPPTIMEOUT) { pp_win_epp_clear_timeout(); goto rt; } ret++; } rt: setecr(0x30); /* PS/2 mode */ return ret;}/* ---------------------------------------------------------------------- */unsigned parport_win_emul_epp_write_data(const void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo; parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE); for (; sz > 0; sz--, bp++) { parport_win_write_data(*bp); for (tmo = 0; ; tmo++) { if (parport_win_read_status() & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE | LPTCTRL_DATASTB); for (tmo = 0; ; tmo++) { if (!(parport_win_read_status() & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE); ret++; } return ret;}unsigned parport_win_emul_epp_read_data(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo; parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION); for (; sz > 0; sz--, bp++) { for (tmo = 0; ; tmo++) { if (parport_win_read_status() & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION | LPTCTRL_DATASTB); for (tmo = 0; ; tmo++) { if (!(parport_win_read_status() & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } *bp = parport_win_read_data(); parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION); ret++; } return ret;}unsigned parport_win_emul_epp_write_addr(const void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo; parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE); for (; sz > 0; sz--, bp++) { parport_win_write_data(*bp); for (tmo = 0; ; tmo++) { if (parport_win_read_status() & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE | LPTCTRL_ADDRSTB); for (tmo = 0; ; tmo++) { if (!(parport_win_read_status() & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_WRITE); ret++; } return ret;}unsigned parport_win_emul_epp_read_addr(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo; parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION); for (; sz > 0; sz--, bp++) { for (tmo = 0; ; tmo++) { if (parport_win_read_status() & LPTSTAT_WAIT) break; if (tmo > 1000) return ret; } parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION | LPTCTRL_ADDRSTB); for (tmo = 0; ; tmo++) { if (!(parport_win_read_status() & LPTSTAT_WAIT)) break; if (tmo > 1000) return ret; } *bp = parport_win_read_data(); parport_win_write_control(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION); ret++; } return ret;}/* ---------------------------------------------------------------------- */static int ecp_forward(void){ unsigned tmo = 0x10000; if (parport_win_read_status() & 0x20) return 0; /* Event 47: Set nInit high */ parport_win_write_control(0x26); /* Event 49: PError goes high */ while (!(parport_win_read_status() & 0x20)) { if (!(--tmo)) return -1; } /* start driving the bus */ parport_win_write_control(0x04); return 0;}static int ecp_reverse(void){ unsigned tmo = 0x10000; if (!(parport_win_read_status() & 0x20)) return 0; parport_win_write_control(0x24); /* Event 39: Set nInit low to initiate bus reversal */ parport_win_write_control(0x20); while (parport_win_read_status() & 0x20) { if (!(--tmo)) return -1; } return 0;}static unsigned emptyfifo(unsigned cnt){ unsigned fcnt = 0; parport_win_write_econtrol(0xd0); /* FIFOtest mode */ while ((parport_win_read_econtrol() & 0x01) && fcnt < 32 && fcnt < cnt) { parport_win_read_configa(); fcnt++; } lprintf(10, "emptyfifo: FIFO contained %d bytes\n", fcnt); parport_win_write_econtrol(0x30); /* PS/2 mode */ return cnt - fcnt;}unsigned parport_win_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; unsigned int i; if (ecp_forward()) return 0; parport_win_write_econtrol(0x70); /* ECP mode */ while (sz > 0) { while ((stat = parport_win_read_econtrol()) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { for (i = 0; i < 8; i++) parport_win_write_configa(bp[i]); bp += 8; sz -= 8; ret += 8; } else { parport_win_write_configa(*bp++); sz--; ret++; } tmo = 0x10000; } while (!(parport_win_read_econtrol() & 0x01) || !(parport_win_read_status() & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } parport_win_write_econtrol(0x30); /* PS/2 mode */ return ret;}unsigned parport_win_ecp_read_data(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; unsigned int i; if (ecp_reverse()) return 0; parport_win_write_econtrol(0x70); /* ECP mode */ while (sz > 0) { while ((stat = parport_win_read_econtrol()) & 0x01) if (!(--tmo)) { parport_win_write_econtrol(0xd0); /* FIFOTEST mode */ while (!(parport_win_read_econtrol() & 0x01) && sz > 0) { *bp++ = parport_win_read_configa(); sz--; ret++; } parport_win_write_econtrol(0x30); /* PS/2 mode */ return ret; } if (stat & 0x02 && sz >= 8) { for (i = 0; i < 8; i++) bp[i] = parport_win_read_configa(); bp += 8; sz -= 8; ret += 8; } else { *bp++ = parport_win_read_configa(); sz--; ret++; } tmo = 0x10000; } parport_win_write_econtrol(0x30); /* PS/2 mode */ return ret;}unsigned parport_win_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; unsigned int i; if (ecp_forward()) return 0; parport_win_write_econtrol(0x70); /* ECP mode */ while (sz > 0) { while ((stat = parport_win_read_econtrol()) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { for (i = 0; i < 8; i++) parport_win_write_data(bp[i]); bp += 8; sz -= 8; ret += 8; } else { parport_win_write_data(*bp++); sz--; ret++; } tmo = 0x10000; } while (!(parport_win_read_econtrol() & 0x01) || !(parport_win_read_status() & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } parport_win_write_econtrol(0x30); /* PS/2 mode */ return ret;}/* ---------------------------------------------------------------------- */unsigned parport_win_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 = parport_win_read_control() & ~PARPORT_CONTROL_AUTOFD; /* HostAck high (data, not command) */ parport_win_write_control(ctl); for (ret = 0; ret < sz; ret++, bp++) { parport_win_write_data(*bp); parport_win_write_control(ctl | PARPORT_CONTROL_STROBE); for (tmo = 0; parport_win_read_status() & PARPORT_STATUS_BUSY; tmo++) if (tmo > 0x1000) return ret; parport_win_write_control(ctl); for (tmo = 0; !(parport_win_read_status() & PARPORT_STATUS_BUSY); tmo++) if (tmo > 0x1000) return ret; } return ret;}unsigned parport_win_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 = parport_win_read_control() | PARPORT_CONTROL_AUTOFD; /* HostAck low (command, not data) */ parport_win_write_control(ctl); for (ret = 0; ret < sz; ret++, bp++) { parport_win_write_data(*bp); parport_win_write_control(ctl | PARPORT_CONTROL_STROBE); for (tmo = 0; parport_win_read_status() & PARPORT_STATUS_BUSY; tmo++) if (tmo > 0x1000) return ret; parport_win_write_control(ctl); for (tmo = 0; !(parport_win_read_status() & PARPORT_STATUS_BUSY); tmo++) if (tmo > 0x1000) return ret; } return ret;}unsigned parport_win_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 = parport_win_read_control(); /* Set HostAck low to start accepting data. */ parport_win_write_control(ctl | PARPORT_CONTROL_AUTOFD); while (ret < sz) { /* Event 43: Peripheral sets nAck low. It can take as long as it wants. */ tmo = 0; do { stat = parport_win_read_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 = parport_win_read_data(); /* Event 44: Set HostAck high, acknowledging handshake. */ parport_win_write_control(ctl & ~PARPORT_CONTROL_AUTOFD); /* Event 45: The peripheral has 35ms to set nAck high. */ tmo = 0; do { stat = parport_win_read_status(); if ((++tmo) > 0x10000) goto out; } while (!(stat & PARPORT_STATUS_ACK)); /* Event 46: Set HostAck low and accept the data. */ parport_win_write_control(ctl | PARPORT_CONTROL_AUTOFD); /* Normal data byte. */ bp++; ret++; } out: return ret;} /* ---------------------------------------------------------------------- */#if 1unsigned parport_win_fpgaconfig_write(const void *buf, unsigned sz){ const unsigned char *bp = buf; unsigned u; for (u = 0; u < sz; u++, bp++) parport_win_write_data(*bp); return sz;}#elseunsigned parport_win_fpgaconfig_write(const void *buf, unsigned sz){ const unsigned char *bp = buf; unsigned ret = 0; unsigned tmo = 0x10000; unsigned char stat; unsigned int i; if (pp_win_modes & PARPORT_MODE_PCECR) { parport_win_write_econtrol(0x50); /* COMPAT FIFO mode */ while (sz > 0) { while ((stat = parport_win_read_econtrol()) & 0x02) { if (!(--tmo)) return emptyfifo(ret); } if (stat & 0x01 && sz >= 8) { for (i = 0; i < 8; i++) parport_win_write_configa(bp[i]); bp += 8; sz -= 8; ret += 8; } else { parport_win_write_configa(*bp++); sz--; ret++; } tmo = 0x10000; } while (!(parport_win_read_econtrol() & 0x01) || !(parport_win_read_status() & 0x80)) { if (!(--tmo)) return emptyfifo(ret); } parport_win_write_econtrol(0x30); /* PS/2 mode */ return ret; } for (ret = 0; ret < sz; ret++, bp++) parport_win_write_data(*bp); return sz;}#endif/* ---------------------------------------------------------------------- */const struct parport_ops parport_win_ops = { parport_win_read_data, parport_win_write_data, parport_win_read_status, parport_win_read_control, parport_win_write_control, parport_win_frob_control, parport_win_epp_write_data, parport_win_epp_read_data, parport_win_epp_write_addr, parport_win_epp_read_addr, parport_win_ecp_write_data, parport_win_ecp_read_data, parport_win_ecp_write_addr, parport_win_fpgaconfig_write};const struct parport_ops parport_win_emul_ops = { parport_win_read_data, parport_win_write_data, parport_win_read_status, parport_win_read_control, parport_win_write_control, parport_win_frob_control, parport_win_emul_epp_write_data, parport_win_emul_epp_read_data, parport_win_emul_epp_write_addr, parport_win_emul_epp_read_addr, parport_win_emul_ecp_write_data, parport_win_emul_ecp_read_data, parport_win_emul_ecp_write_addr, parport_win_fpgaconfig_write};/* ---------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -