2011-10-17 38 views
9

私のコンピュータネットワークコースでは、(outportbのようなコマンドを使うなどの)ネイティブレジスタを使ってパラレルポートプログラミングを学ぶことになっています。私は並列ポートを持っていません(私は2011年に住んでいるからです)が、プログラムを練習したいのです(私はdosboxを使って古いturboc 3 IDEをインストールしました)。 thisのようなパラレルポートをエミュレートするプログラムはシリアルポートをエミュレートしますか?仮想パラレルポートエミュレータ

+6

「私が2011年に住んでいるから」:-) –

+0

あなたは自分でそれをエミュレートしてみませんか? outportb()の独自のバージョンを書いてください。 –

+0

$ 10で誰かがあなたの原因に古いペンティアムを寄付してくれると確信しています:) – Earlz

答えて

0

dosboxはpatchesのないパラレルポートをサポートしていないようです。 virtualboxdoesn't yet supportパラレルポートも表示されます。しかし、パラレルポートをサポートしていても、ホストオペレーティングシステム上のデバッグドライバか、USB to Parallelアダプタ(通常の小売店で入手可能)のようなものが必要です。

parallel portについて学ぶ理由を詳しく教えてください。あなたが提案するように、2011年にはほとんど死んでいるインターフェースです。低レベルの並列スタイルのI/Oで実際にプレイしたい場合は、Arduinoプラットフォームを参照してください。

+0

私はたわごとと遊びたくありません。その上に3つのラボ課題があり、古いWindows 98システムが保管されているラボには行きたくありません。 –

+0

十分ですが、いくつかのLEDをパラレルポートに差し込んで点滅させたり、何かを印刷したりする必要がありますか? – ObscureRobot

+0

2台のコンピュータがシリアルポートを使って話す必要があります –

0

Linux Wineがパラレルポートをサポートしていれば、私は驚くことはありませんが、物理的なLPTがないと完全に仮想化できるかどうかわかりません。

従来の互換性テストを行う必要があるとき、私はいつも安価の古いPCを見つけるのが驚いています。

あまりにも地域中心ですが、地元の再販店やコンピュータのリサイクルにお立ち寄りください。たとえば、ポートランドでは、私はFree GeekとGoodwillを訪問し、15ドル以上を支払うことは期待していません。あなたの時間が大いに価値があるなら、これはおそらく、エミュレータを使いこなし、それがどれほど優れているか不思議に思うよりも、手頃な価格です。

2

とにかく実際のポートを持っていない環境は偽物なので、プログラムのポート機能をエミュレートすることもできます。ただ、より有用以上の何かをReadPort()WritePort()の実装を変更

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

// Filename: PortEmu.c 
// Compiled with Open Watcom 1.9 as: wcl386 PortEmu.c 

#include <windows.h> 
#include <stdio.h> 
#include <conio.h> 

// 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; 
} 

出力:ここ

は(SEH)はStructured Exception Handlingを使用して、Windowsでそれを行う方法ですプリンタのポート操作に合わせて設定します。

+0

2台のPC間で実際に通信するために、舞台裏で(ReadPort()とWritePort()で)TCP/IP通信を行うことがあります。 –