虚拟并行端口仿真器

在我的计算机网络课程中,我们应该通过使用本机寄存器来学习并行端口编程(比如使用outportb之类的命令)。 我没有并行端口(因为我住在2011年)但想要练习程序(我使用dosbox安装了旧的turboc 3 IDE)。 是否有一个模拟并行端口的程序, 如此程序模拟串口?

由于环境是假的,即你没有可以使用的实际端口,你也可以模拟程序中的端口function。

以下是使用结构化exception处理 (SEH)在Windows中执行此操作的方法

// Filename: PortEmu.c // Compiled with Open Watcom 1.9 as: wcl386 PortEmu.c #include  #include  #include  // Port state. Holds the last value written by OUT. // IN reads from it. volatile UINT32 PortState = 0; UINT32 ReadPort(UINT16 PortNumber, UINT OperandSize) { UNREFERENCED_PARAMETER(PortNumber); switch (OperandSize) { default: case 8: return PortState & 0xFF; case 16: return PortState & 0xFFFF; case 32: return PortState; } } void WritePort(UINT16 PortNumber, UINT OperandSize, UINT32 Value) { UNREFERENCED_PARAMETER(PortNumber); switch (OperandSize) { default: case 8: PortState = (PortState & ~0xFF) | (Value & 0xFF); break; case 16: PortState = (PortState & ~0xFFFF) | (Value & 0xFFFF); break; case 32: PortState = Value; break; } } // Exception filter to emulate x86 IN and OUT instructions // in 32-bit Windows application. int IoExceptionFilter(LPEXCEPTION_POINTERS ep) { CONTEXT* c = ep->ContextRecord; UINT8* instr = (UINT8*)c->Eip; int OperandSizeIs16Bit = 0; switch (ep->ExceptionRecord->ExceptionCode) { case EXCEPTION_PRIV_INSTRUCTION: if (instr[0] == 0x66) { OperandSizeIs16Bit = 1; instr++; } switch (instr[0]) { case 0xE4: // IN AL, imm8 *(UINT8*)&c->Eax = ReadPort(instr[1], 8); c->Eip += 2 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xE5: // IN (E)AX, imm8 if (OperandSizeIs16Bit) *(UINT16*)&c->Eax = ReadPort(instr[1], 16); else c->Eax = ReadPort(instr[1], 32); c->Eip += 2 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xEC: // IN AL, DX *(UINT8*)&c->Eax = ReadPort((UINT16)c->Edx, 8); c->Eip += 1 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xED: // IN (E)AX, DX if (OperandSizeIs16Bit) *(UINT16*)&c->Eax = ReadPort((UINT16)c->Edx, 16); else c->Eax = ReadPort((UINT16)c->Edx, 32); c->Eip += 1 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xE6: // OUT imm8, AL WritePort(instr[1], 8, (UINT8)c->Eax); c->Eip += 2 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xE7: // OUT imm8, (E)AX if (OperandSizeIs16Bit) WritePort(instr[1], 16, (UINT16)c->Eax); else WritePort(instr[1], 32, c->Eax); c->Eip += 2 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xEE: // OUT DX, AL WritePort((UINT16)c->Edx, 8, (UINT8)c->Eax); c->Eip += 1 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; case 0xEF: // OUT DX, (E)AX if (OperandSizeIs16Bit) WritePort((UINT16)c->Edx, 16, (UINT16)c->Eax); else WritePort((UINT16)c->Edx, 32, c->Eax); c->Eip += 1 + OperandSizeIs16Bit; return EXCEPTION_CONTINUE_EXECUTION; default: return EXCEPTION_CONTINUE_SEARCH; } default: return EXCEPTION_CONTINUE_SEARCH; } } int main(void) { __try { outp(0x278, 0x00); printf("portb=0x%X\n", inp(0)); outp(0x278, 0x55); printf("portb=0x%X\n", inp(0)); outp(0x278, 0xFF); printf("portb=0x%X\n", inp(0)); outpw(0x278, 0xAAAA); printf("portw=0x%X\n", inpw(0)); outpd(0x278, 0x12345678); printf("portd=0x%X\n", inpd(0)); outpw(0x278, 0xAAAA); outp(0x278, 0x55); printf("portd=0x%X\n", inpd(0)); } __except(IoExceptionFilter(GetExceptionInformation())) { } return 0; } 

输出:

 C:\>PortEmu.exe portb=0x0 portb=0x55 portb=0xFF portw=0xAAAA portd=0x12345678 portd=0x1234AA55 

只需改变ReadPort()WritePort() ,就可以根据打印机端口操作执行更有用或更多的操作。

看起来dosbox可能不支持没有补丁的并行端口。 虚拟机 似乎还不支持并行端口。 但即使他们确实支持并行端口,你仍然需要另一端的东西 – 主机操作系统上的调试驱动程序,或USB转并行适配器(通常在零售商处可用)。

您能详细说明为什么要了解并行端口吗? 正如你的建议,它在2011年是一个基本上死机的界面。 如果您真的想要使用低级并行风格的I / O,您可能需要查看Arduino平台。

我不知道有任何软件,但是如果Linux Wine在支持并行端口方面表现不错,我也不会感到惊讶,尽管我不知道在缺少物理LPT的情况下它是否可以完全虚拟化。

当必须进行遗留兼容性测试时,我总是惊讶于找到便宜的旧PC是多么容易。

唉,这是一个高度区域性的,但访问当地的转售商店或电脑回收业务。 例如,在波特兰,我会访问Free Geek和Goodwill,并且不会期望支付超过15美元。 如果你的时间价值很高,这可能比搞乱仿真器更实惠,然后想知道它们有多好。