Emulateur de port parallèle virtuel

Dans mon cours sur les réseaux informatiques, nous sums supposés apprendre la programmation par port parallèle en utilisant les registres natifs (comme en utilisant outportb comme des commandes). Je n’ai pas de port parallèle (car je vis en 2011), mais je veux pratiquer les programmes (j’ai installé l’ancien turboc 3 IDE en utilisant dosbox). Existe-t-il un programme émulant des ports parallèles comme ce programme émule des ports série?

Comme l’environnement est de toute façon faux, c’est-à-dire que vous n’avez pas de port réel sur lequel jouer, vous pouvez également émuler la fonctionnalité de portage de votre programme.

Voici comment procéder dans Windows à l’aide de SEH ( Structured Exception Handling ):

// Filename: PortEmu.c // Comstackd 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; } 

Sortie:

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

Il suffit de modifier l’implémentation de ReadPort() et WritePort() pour faire quelque chose de plus utile ou plus WritePort() au fonctionnement du port d’imprimante.

Il semble que dosbox puisse ne pas prendre en charge les ports parallèles sans correctifs . Il semble également que virtualbox ne supporte pas encore les ports parallèles. Mais même s’ils prenaient en charge les ports parallèles, vous auriez toujours besoin de quelque chose à l’autre extrémité – soit un pilote de débogage sur votre système d’exploitation hôte, soit un adaptateur USB vers parallèle (disponible chez les détaillants habituels).

Pouvez-vous en dire plus sur les raisons pour lesquelles vous souhaitez en savoir plus sur le port parallèle ? C’est une interface presque morte en 2011, comme vous le suggérez. Si vous voulez vraiment jouer avec des E / S de style parallèle de bas niveau, vous pouvez vous tourner vers la plate – forme Arduino .

Je ne connais aucun logiciel en amont, mais je ne serais pas surpris si Linux Wine supporte bien un port parallèle, mais je ne sais pas s’il peut être complètement virtualisé en l’absence d’un LPT physique.

Lorsque je dois effectuer des tests de compatibilité, je suis toujours étonné de constater à quel point il est facile de trouver un vieux PC bon marché .

Hélas, cela est très centré sur les régions, mais visitez un magasin de revente local ou une opération de recyclage d’ordinateurs. Par exemple, à Portland, je rendrais visite à Free Geek et Goodwill et je ne m’attendais pas à payer plus de 15 dollars. Si votre temps vaut beaucoup, c’est probablement plus abordable que de jouer avec des émulateurs et de vous demander à quel point ils sont bons.