📄 ppnt.c
字号:
/*****************************************************************************//* * ppnt.c -- Parport direct access with NT eppflex.sys. * * Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Please note that the GPL allows you to use the driver, NOT the radio. * In order to use the radio, you need a license from the communications * authority of your country. * *//*****************************************************************************/#include <windows.h>#include "parport.h"/* ---------------------------------------------------------------------- */#define DEVICE_TYPE DWORD#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \)#define METHOD_BUFFERED 0#define METHOD_IN_DIRECT 1#define METHOD_OUT_DIRECT 2#define METHOD_NEITHER 3#define FILE_ANY_ACCESS 0#define FILE_READ_ACCESS (0x0001) #define FILE_WRITE_ACCESS (0x0002)#include "eppflex.h"/* ---------------------------------------------------------------------- *//* LPT registers *//* ECP specific registers */#define LPTREG_ECONTROL 0x402#define LPTREG_CONFIGB 0x401#define LPTREG_CONFIGA 0x400#define LPTREG_TFIFO 0x400#define LPTREG_DFIFO 0x400#define LPTREG_AFIFO 0x000#define LPTREG_DSR 0x001#define LPTREG_DCR 0x002/* EPP specific registers */#define LPTREG_EPPDATA 0x004#define LPTREG_EPPADDR 0x003/* standard registers */#define LPTREG_CONTROL 0x002#define LPTREG_STATUS 0x001#define LPTREG_DATA 0x000/* ECP config A */#define LPTCFGA_INTRISALEVEL 0x80#define LPTCFGA_IMPIDMASK 0x70#define LPTCFGA_IMPID16BIT 0x00#define LPTCFGA_IMPID8BIT 0x10#define LPTCFGA_IMPID32BIT 0x20#define LPTCFGA_NOPIPELINE 0x04#define LPTCFGA_PWORDCOUNT 0x03/* ECP config B */#define LPTCFGB_COMPRESS 0x80#define LPTCFGB_INTRVALUE 0x40#define LPTCFGB_IRQMASK 0x38#define LPTCFGB_IRQ5 0x38#define LPTCFGB_IRQ15 0x30#define LPTCFGB_IRQ14 0x28#define LPTCFGB_IRQ11 0x20#define LPTCFGB_IRQ10 0x18#define LPTCFGB_IRQ9 0x10#define LPTCFGB_IRQ7 0x08#define LPTCFGB_IRQJUMPER 0x00#define LPTCFGB_DMAMASK 0x07#define LPTCFGB_DMA7 0x07#define LPTCFGB_DMA6 0x06#define LPTCFGB_DMA5 0x05#define LPTCFGB_DMAJUMPER16 0x04#define LPTCFGB_DMA3 0x03#define LPTCFGB_DMA2 0x02#define LPTCFGB_DMA1 0x01#define LPTCFGB_DMAJUMPER8 0x00/* ECP ECR */#define LPTECR_MODEMASK 0xe0#define LPTECR_MODESPP 0x00#define LPTECR_MODEPS2 0x20#define LPTECR_MODESPPFIFO 0x40#define LPTECR_MODEECP 0x60#define LPTECR_MODEECPEPP 0x80#define LPTECR_MODETEST 0xc0#define LPTECR_MODECFG 0xe0#define LPTECR_NERRINTRDIS 0x10#define LPTECR_DMAEN 0x08#define LPTECR_SERVICEINTR 0x04#define LPTECR_FIFOFULL 0x02#define LPTECR_FIFOEMPTY 0x01/* ---------------------------------------------------------------------- */HANDLE pp_nt_handle = INVALID_HANDLE_VALUE;unsigned int pp_nt_flags = 0;#define FLAGS_PCSPP (1<<0)#define FLAGS_PCPS2 (1<<1)#define FLAGS_PCEPP (1<<2)#define FLAGS_PCECR (1<<3) /* ECR Register Exists */#define FLAGS_PCECP (1<<4)#define FLAGS_PCECPEPP (1<<5)#define FLAGS_PCECPPS2 (1<<6)/* ---------------------------------------------------------------------- */unsigned char parport_nt_read_data(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_DATA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_data failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_data(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_DATA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_data failed, error 0x%08lx\n", GetLastError());}unsigned char parport_nt_read_status(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_STATUS, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_status failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_status(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_STATUS, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_status failed, error 0x%08lx\n", GetLastError());}unsigned char parport_nt_read_control(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_CONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_control failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_control(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_CONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_control failed, error 0x%08lx\n", GetLastError());}void parport_nt_frob_control(unsigned char mask, unsigned char val){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = val; rw.mask = mask; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_FROB_CONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_frob_control failed, error 0x%08lx\n", GetLastError()); return; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return; }}unsigned char parport_nt_read_configa(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_CONFIGA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_configa failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_configa(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_CONFIGA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_configa failed, error 0x%08lx\n", GetLastError());}unsigned char parport_nt_read_configb(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_CONFIGB, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_configb failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_configb(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_CONFIGB, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_configb failed, error 0x%08lx\n", GetLastError());}unsigned char parport_nt_read_econtrol(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_ECONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_econtrol failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_econtrol(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_ECONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_econtrol failed, error 0x%08lx\n", GetLastError());}void parport_nt_frob_econtrol(unsigned char mask, unsigned char val){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = val; rw.mask = mask; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_FROB_ECONTROL, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_frob_econtrol failed, error 0x%08lx\n", GetLastError()); return; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return; }}unsigned char parport_nt_read_eppaddr(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_EPPADDR, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_eppaddr failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_eppaddr(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_EPPADDR, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_eppaddr failed, error 0x%08lx\n", GetLastError());}unsigned char parport_nt_read_eppdata(void){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return 0xff; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_READ_EPPDATA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) { lprintf(0, "Parport: parport_nt_read_eppdata failed, error 0x%08lx\n", GetLastError()); return 0xff; } if (retl != sizeof(rw)) { lprintf(0, "Parport: ioctl returned invalid length, %lu\n", retl); return 0xff; } return rw.data;}void parport_nt_write_eppdata(unsigned char d){ struct eppflex_rwdata rw; BOOL res; DWORD retl; if (pp_nt_handle == INVALID_HANDLE_VALUE) return; rw.data = d; res = DeviceIoControl(pp_nt_handle, IOCTL_EPPFLEX_WRITE_EPPDATA, &rw, sizeof(rw), &rw, sizeof(rw), &retl, NULL); if (!res) lprintf(0, "Parport: parport_nt_write_eppdata failed, error 0x%08lx\n", GetLastError());}/* ---------------------------------------------------------------------- */extern inline void setecr(unsigned char ecr){ if (pp_nt_flags & FLAGS_PCECR) parport_nt_write_econtrol(ecr);}int pp_nt_epp_clear_timeout(void){ unsigned char r; if (!(parport_nt_read_status() & LPTSTAT_EPPTIMEOUT)) return 1; /* To clear timeout some chips require double read */ parport_nt_read_status(); r = parport_nt_read_status(); parport_nt_write_status(r | 0x01); /* Some reset by writing 1 */ parport_nt_write_status(r & 0xfe); /* Others by writing 0 */ r = parport_nt_read_status(); return !(r & 0x01);}/* ---------------------------------------------------------------------- */unsigned parport_nt_epp_write_data(const void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; setecr(0x90); /* EPP mode */ for (; sz > 0; sz--, bp++) { parport_nt_write_eppdata(*bp); if (parport_nt_read_status() & LPTSTAT_EPPTIMEOUT) { pp_nt_epp_clear_timeout(); goto rt; } ret++; } rt: setecr(0x30); /* PS/2 mode */ return ret;}unsigned parport_nt_epp_read_data(void *buf, unsigned sz){ unsigned char *bp = (unsigned char *)buf; unsigned ret = 0; setecr(0x90); /* EPP mode */ for (; sz > 0; sz--, bp++) { *bp = parport_nt_read_eppdata(); if (parport_nt_read_status() & LPTSTAT_EPPTIMEOUT) { pp_nt_epp_clear_timeout(); goto rt; } ret++; } rt: setecr(0x30); /* PS/2 mode */ return ret;}unsigned parport_nt_epp_write_addr(const void *buf, unsigned sz){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -