8

私は楽しみのために少しレトロなプログラミングをしています。私が作成したいのは、EGA グラフィックスを使用した DOS ゲームですが、Web 上で適切なリファレンスを見つけるのに少し苦労しています。DOS プログラミングについて話す人は皆、プログラマーがモード 13h を使用することを想定しています。他のグラフィック モードについて言及しているページもありますが、それらの適切な使用法について説明しているページはまだ見つけていません。

これが私が今働こうとしているものです:

//------------------------------------------------------------------------------
//  DOS graphics test
//
//  Thanks to the following links:
//    http://gamebub.com/cpp_graphics.php
//
//  Written for Digital Mars C compiler to be compiled as a DOS 16 bit binary.
//------------------------------------------------------------------------------

#include <dos.h>
#include <stdio.h>

#define SCREEN_WIDTH  320;
#define SCREEN_HEIGHT 200;

unsigned char far *vram = (unsigned char far *)0xA0000000L;

//------------------------------------------------------------------------------
void set_video_mode(unsigned char mode)
{
    union REGS in, out;
    in.h.ah = 0;
    in.h.al = mode;
    int86(0x10, &in, &out);
}

//------------------------------------------------------------------------------
void plot_pixel(unsigned int x, unsigned int y, unsigned char color)
{
    // this is wrong because it's only 4 bpp not 8
    vram[y * 320 + x] = color;
    //vram[((y<<8)+(y<<6))+x] = color;
}

//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    // EGA 320 x 200 x 16
    set_video_mode(0x0d);

    for (unsigned char i = 0; i < 255; i++)
    {
        vram[i] = i;
    }

    //plot_pixel(10, 10, 1);

    getc(stdin);
    return 0;
}

このサンプル コードは、set_video_mode() を 0x0d の代わりに 0x13 を取るように変更するとうまく機能しますが、前述したように、ここでは VGA ではなく EGA グラフィックを取得しようとしています。:) ピクセルあたり 4 ビットを実行するには、plot_pixel が同時に 2 つのピクセルを書き込むと仮定するか、少しいじって、4 ビットのみを書き込むようにする必要があることを認識しています。実際に欲しい。

私の問題は、期待どおりの出力が表示されないことです。特に、色がありません。すべてが単色に見えますが、これは私が望んでいるものではありません。このグラフィック モードでカラー パレットを使用するには、13h とは異なる手順がありますか? それとも、意図したものとはまったく異なるグラフィック モードを何らかの方法で呼び出したのでしょうか? ガイダンスをいただければ幸いです。

コンパイラの引数は関係ないと思いますが、念のため:

..\dm\bin\dmc test.c -o test -mm
4

3 に答える 3

4

モード0x0dは平面ベースですが、0x13は平面ベースではありません(モードXとしての特別な構成なし)。平面モードでの作業方法については、さらにドキュメントを確認する必要があります。

于 2010-01-18T10:29:36.140 に答える
3

うーん..これが価値のある答えである場合、思い出せば、EGAレジスタを制御するためにポートに、、、inportinportb使用outportする必要があります。 outportb、フラクタルから圧縮)、元のアーカイブはここここで見つかりました.:

3C0h: アトリビュート コントローラ: アドレス レジスタ
ビット 0 ~ 4 ポート 3C0h に書き込むデータ レジスタのアドレス。
      5 設定画面出力が有効でパレットが変更できない場合、
         クリアスクリーン出力が無効で、パレットを変更できる場合。


ポート 3C0h は、アドレスとデータ書き込みレジスタの両方であるという点で特別です。
内部フリップフロップは、現在アドレスとして機能しているか、またはアドレスとして機能しているかを記憶しています。
データレジスタ。属性コントローラへのアクセスは at で区切る必要があります
少なくとも 250ns。ポート 3dAh を読み取ると、フリップフロップがアドレス モードにリセットされます。


3C0h インデックス 0 ~ Fh (W): アトリビュート: パレット
ビット 0 プライマリ ブルー
      1 プライマリ グリーン
      2 プライマリーレッド
      3 セカンダリ ブルー
      4 セカンダリ グリーン
      5 セカンダリーレッド

3C0h インデックス 10h (W): 属性: モード制御レジスタ
ビット 0 設定されている場合はグラフィック モード、設定されていない場合は英数字モード。
      1 設定されている場合はモノクロ モード、設定されていない場合はカラー モード。
      2 つの 9 ビット幅文字 (設定されている場合)。
         文字 C0h ~ DFh の 9 番目のビットは、
         8番目のビット。それ以外の場合は、背景色になります。
      3 設定されている場合、属性ビット 7 が点滅します。それ以外の場合は高輝度です。

3C0h インデックス 11h (W): 属性: オーバースキャン カラー レジスタ。
ビット 0 ~ 5 画面の境界線の色。色は、パレット レジスタと同じように定義されます。
注: EGA では、高解像度モードでオーバースキャン カラーを 0 にする必要があります。

3C0h インデックス 12h (W): 属性: カラー プレーン イネーブル レジスタ
ビット 0 設定すると、ビット プレーン 0 が有効になります。
      1 ビットプレーン 1 が設定されている場合、有効になります。
      2 ビットプレーン 2 が設定されている場合、有効になります。
      3 ビットプレーン 3 が設定されている場合、有効になります。
    4-5 ビデオ ステータス MUX。診断用途のみ。
         入力ステータスのビット 4 と 5 に 2 つの属性ビットが表示されます。
         レジスタ 1 (3dAh)。0: 赤/青、1: 青(I)/緑、2: 赤(I)/緑(I)

3C0h index 13h (W): アトリビュート: Horizo​​ntal PEL Panning Register
ビット 0 ~ 3 は、表示を左にシフトするピクセル数を示します
         値 9bit textmode 256color mode その他のモード
           0 1 0 0
           1 2 該当なし 1
           2 3 1 2
           3 4 該当なし 3
           4 5 2 4
           5 6 該当なし 5
           6 7 3 6
           7 8 該当なし 7
           8 0 なし

3C2h (R): 入力ステータス #0 レジスタ
ビット 4 その他の出力によって選択されたスイッチのステータス
         レジスタ 3C2h ビット 2 ~ 3。設定されている場合はスイッチを高くします。
      5 機能コネクタ (FEAT0) のピン 19 は、設定されている場合は高です
      6 機能コネクタ (FEAT1) のピン 17 は、設定されている場合は高です
      7 垂直帰線により IRQ 2 が発生した場合。クリアするべし
         ポート 3d4h インデックス 11h ビット 4 をクリアすることにより、IRQ 2 割り込みルーチンによって。

3C2h (W): その他の出力レジスタ
ビット 0 カラー エミュレーションが設定されている場合。Base Address=3Dxh else Mono エミュレーション。ベース
         アドレス=3Bxh.
      1 設定されている場合、ビデオ メモリへの CPU アクセスを有効にします
    2-3 クロック選択。0:14MHz、1:16MHz、2:外部
      4 設定されている場合、内部ビデオ ドライバを無効にします
      5 奇数/偶数モードの場合 設定されている場合は High 64k バンクを選択します
      6 水平同期極性。設定されている場合は負
      7 垂直同期極性。設定されている場合は負
         ビット 6 ~ 7 は、ディスプレイ上の行数を示します。
           0:200本、2:350本
注: ハードウェア リセットですべてゼロに設定します。

3C4h インデックス 0 (W): シーケンサー: リセット
ビット 0 クリアの場合は非同期リセット
      1 クリアの場合は同期リセット

3C4h インデックス 1 (W): シーケンサー: クロッキング モード
ビット 0 設定された文字クロックが 8 ドット幅の場合、それ以外の場合は 9。
      1 設定されている場合、CRTC はクロック サイクルの 2/5 を使用し、それ以外の場合は 4/5 を使用します。
      2 設定すると、1 文字おきにビデオ シリアライザがロードされます
         クロックサイクル、それ以外はすべて。
      3 ドット クロックがマスター クロック/2 に設定されている場合、そうでない場合はマスター クロックと同じ
          (3C2h ビット 2 ~ 3 を参照)。(ピクセルを 2 倍にします)。

3C4h インデックス 2 (W): シーケンサー: マップ マスク レジスタ
ビット 0 設定されている場合、プレーン 0 への書き込みを有効にします
      1 設定されている場合、プレーン 1 への書き込みを有効にします
      2 設定されている場合、プレーン 2 への書き込みを有効にします
      3 設定されている場合、プレーン 3 への書き込みを有効にします

3C4h インデックス 3 (W): シーケンサー: 文字マップ選択レジスタ
ビット 0-1 文字のビット 3 の場合、EGA 文字マップ (0..3) を選択します。
         属性はクリア。
    2-3 文字のビット 3 の場合、EGA 文字マップ (0..3) を選択します。
         属性が設定されます。
注: キャラクター マップは次のように配置されます。
      マップ 0 は 0k、マップ 1 は 16k、マップ 2 は 32k、マップ 3 は 48k

3C4h インデックス 4 (W): シーケンサー: メモリ モード レジスタ
ビット 0 英数字モードの場合はセット、グラフィック モードの場合はクリアします。
      1 アダプタに 64k バイトを超える場合に設定します。
      2 設定されている場合、奇数/偶数アドレッシング モードを有効にします。奇数/偶数モードでは、すべてが奇数になります
         プレーン 1 と 3 のバイト、およびプレーン 0 と 2 のすべての偶数バイト。

3CAh (W): グラフィックス 2 ポジション
ビット 0-1 グラフィックス コントローラによって制御されるビット プレーンを選択します。
         #2。常に 1 に設定します。

3CCh (W): グラフィックス 1 位置
ビット 0-1 グラフィックス コントローラによって制御されるビット プレーンを選択します。
         #1。常に 0 に設定します。

3CEh インデックス 0 (W): グラフィック: セット/リセット レジスタ
ビット 0 書き込みモード 0 で、3CEh インデックス 1 のビット 0 に書き込みが設定されている場合
         表示メモリは、バイトのプレーン 0 のすべてのビットをこれに設定します。
         ビット、対応するビットがマップ マスク レジスタ (3CEh) に設定されている場合
         インデックス 8)。
      1 プレーン 1 と 3CEh インデックス 1 のビット 1 についても同じ。
      2 プレーン 2 と 3CEh インデックス 1 のビット 2 についても同じ。
      3 プレーン 3 と 3CEh インデックス 1 のビット 3 についても同じ。

3CEh インデックス 1 (W): グラフィックス: イネーブル セット/リセット レジスタ
ビット 0 設定すると、書き込みモード 0 でのプレーン 0 のセット/リセットが有効になります。
      1 平面 1 と同じ。
      2 平面 2 も同様。
      3 平面 3 も同様。

3CEh index 2 (W): グラフィック: カラーコンペアレジスタ
ビット 0 ~ 3 読み取りモード 1 では、読み取りバイトのアドレスにある各ピクセルが比較されます
         この色と、出力の対応するビットが 1 に設定される場合
         それらは一致し、そうでない場合は 0 です。カラー ドント ケア レジスタ (3CEh インデックス 7)
         比較からビットプレーンを除外できます。

3CEh インデックス 3 (W): グラフィック: データ回転
ビット 0-2 データが書き込まれる直前に回転する位置の数
         メモリを表示します。書き込みモード 0 でのみ有効です。
    3-4 書き込みモード 2 では、このフィールドはデータ間の関係を制御します。
         CPU から書き込まれたデータ、前回の読み取りでラッチされたデータ、および
         表示メモリに書き込まれたデータ:
           0: CPU データは変更されずに書き込まれます
           1: CPU データはラッチされたデータと AND を取ります
           2: CPU データとラッチ データの OR をとります。
           3: CPU データはラッチされたデータと XOR されます。

3CEh インデックス 4 (W): グラフィック: マップ選択レジスタの読み取り
ビット 0-1 読み取りモード 0 が読み取るプレーンの番号。

3CEh インデックス 5 (W): グラフィック: モード レジスタ
ビット 0-1 書き込みモード: CPU からのデータが変換前にどのように変換されるかを制御します。
         表示メモリに書き込まれます:
           0: モード 0 は、Read-Modify-Write 操作として機能します。
              最初の読み取りアクセスは、EGA のデータ ラッチに
              アドレスされた場所のビデオ メモリ内の値。次に、書き込み
              アクセスは宛先アドレスと CPU データを提供します
              バイト。書き込まれたデータは、関数コードによって変更されます。
              CPU の関数としてのデータ回転レジスタ (3CEh インデックス 3)
              データとラッチ、次にデータは、
              同じレジスター。
           1: モード 1 は、ビデオからビデオへの転送に使用されます。
              読み取りアクセスは、データ ラッチに次の内容をロードします。
              ビデオ メモリのアドレス指定されたバイト。書き込みアクセスは書き込みます
              アドレス指定されたバイトへのラッチの内容。したがって、単一の
              MOVSB 命令は、ソース アドレス バイト内のすべてのピクセルをコピーできます。
              宛先アドレスに。
           2: モード 2 は、アドレス指定されたバイトのすべてのピクセルに色を書き込みます。
              ビデオメモリ。CPU データのビット 0 がプレーン 0 et に書き込まれます
              セテラ。個々のビットは、
              ビット マスク レジスタ (3CEh インデックス 8)。
      2 設定されている場合、すべての出力を強制的に高インピーダンス状態にします。
      3 読み取りモード
           0: データは、読み取りマップに応じて 4 つのビット プレーンのいずれかから読み取られます。
              登録 (3CEh インデックス 4) を選択します。
           1: 返されるデータは、領域を占める 8 ピクセル間の比較です。
              カラー比較レジスタ (3CEh) のバイトと色を読み取る
              インデックス 2)。対応するピクセルの色が
              レジスターと一致します。
      4 設定されている場合、奇数/偶数モードを有効にします (3C4h インデックス 4 ビット 2 を参照)。
      5 設定されている場合、偶数/奇数のビット ペアを使用して CGA スタイルの 4 色ピクセルを有効にします。

3CEh インデックス 6 (W): グラフィック: その他のレジスタ
ビット 0 設定されている場合はグラフィック モードを示し、設定されていない場合は英数字モードを示します。
      1 設定すると、奇数/偶数モードが有効になります。
    2-3 メモリ マッピング:
           0: A000h-BFFFh を使用
           1: A000h-AFFFh EGA グラフィックモードを使用
           2: B000h-B7FFh モノクロモードを使用
           3: B800h-BFFFh CGA モードを使用

3CEh インデックス 7 (W): グラフィックス: カラー ドント ケア レジスタ
ビット 0 クリアされている場合、読み取りモード 1 でビット プレーン 0 を無視します。
      1 クリアの場合、読み取りモード 1 でビットプレーン 1 を無視します。
      2 クリアの場合、読み取りモード 1 でビットプレーン 2 を無視します。
      3 クリアの場合、読み取りモード 1 でビットプレーン 3 を無視します。

3CEh インデックス 8 (W): グラフィック: ビット マスク レジスタ
ビット 0 ~ 7 各ビットが設定されている場合、バイトの対応するビットへの書き込みが有効になります。
         メモリを表示します。

3d4h インデックス 0 (W): CRTC: 水平合計レジスタ
ビット 0 ~ 7 水平合計文字クロック数 - 2

3d4h index 1 (W): CRTC: 水平表示終了レジスタ
ビット 0 ~ 7 表示される文字クロック数 -1

3d4h index 2 (W): CRTC: 水平ブランキング レジスタの開始
ビット 0 ~ 7 水平ブランキングが開始するカウント

3d4h インデックス 3 (W): CRTC: 水平ブランキング レジスタの終了
ビット 0 ~ 4 水平ブランキングは、文字の最後の 5 ビットが終了したときに終了します。
         カウンターはこのフィールドと同じです。
    5-6 水平表示後の表示開始を遅らせる文字クロック数
         合計に達しました。

3d4h index 4 (W): CRTC: 水平帰線レジスタの開始
ビット 0 ~ 7 文字カウンターがこの値に達すると、水平帰線が開始されます。
         価値。

3d4h index 5 (W): CRTC: 水平帰線レジスターの終了
ビット 0-4 文字カウンターの最後の 5 ビットが終了すると、水平帰線が終了します。
         はこの値に等しくなります。
    5-6 水平表示後の表示開始を遅らせる文字クロック数
         引き返す。
      7 奇数/偶数モードでスムーズなスクロールを提供します。設定表示開始時
         奇数バイトから。

3d4h インデックス 6 (W): CRTC: バーティカル トータル レジスタ
ビット 0 ~ 7 垂直合計の下位 8 ビット。ビット 8 は 3d4h インデックス 7 にあります
         ビット 0。

3d4h インデックス 7 (W): CRTC: オーバーフロー レジスタ
ビット 0 垂直合計のビット 8 (3d4h インデックス 6)
      1 垂直表示終了のビット 8 (3d4h インデックス 12h)
      2 垂直帰線開始のビット 8 (3d4h インデックス 10h)
      3 開始垂直ブランキングのビット 8 (3d4h インデックス 15h)
      4 ライン比較レジスタのビット 8 (3d4h インデックス 18h)

3d4h インデックス 8 (W): CRTC: プリセット行スキャン レジスタ
ビット 0-4 最初の文字行で下にスクロールした行数。
         スムーズな垂直スクロールを提供します。

3d4h インデックス 9 (W): CRTC: 最大スキャン ライン レジスタ
ビット 0 ~ 4 文字行のスキャン ライン数 -1。グラフィックモードでは、これは
         に渡される前に行が表示される回数 (-1)
         次の行 (0: 通常、1: ダブル、2: トリプル...)。
         これはビット 7 とは無関係です。
         このフィールドを 1 にし、ビット 7 を有効に設定する必要があります。

3d4h インデックス 0Ah (W): CRTC: カーソル開始レジスタ
ビット 0-4 文字内のカーソルの最初のスキャンライン。

3d4h インデックス 0Bh (W): CRTC: カーソル終了レジスタ
ビット 0-4 文字内のカーソルの最後のスキャンライン
    5-6 文字クロックでのカーソル データの遅延。

3d4h インデックス 0Ch (W): CRTC: 開始アドレス上位レジスタ
bit 0-7 表示バッファの先頭アドレスの上位8ビット

3d4h インデックス 0Dh (W): CRTC: 開始アドレス下位レジスタ
bit 0-7 表示バッファの先頭アドレスの下位8ビット

3d4h インデックス 0Eh (W): CRTC: カーソル位置上位レジスタ
ビット 0-7 カーソルのアドレスの上位 8 ビット

3d4h インデックス 0Fh (W): CRTC: カーソル位置下位レジスタ
bit 0-7 カーソルのアドレスの下位8ビット

3d4h インデックス 10h (R): CRTC: ライト ペン ハイ レジスタ
ビット 0-7 ライトペン位置のアドレスの上位 8 ビット。

3d4h index 10h (W): CRTC: 垂直帰線開始レジスタ
bit 0-7 垂直帰線開始の下位 8 ビット。垂直帰線が開始されるタイミング
         ライン カウンタがこの値に達します。ビット 8 は 3d4h インデックス 7 にあります
         ビット 2。

3d4h インデックス 11h (R): CRTC: ライト ペン ロウ レジスタ
ビット 0-7 ライトペン位置のアドレスの下位 8 ビット。

3d4h index 11h (W): CRTC: 垂直帰線終了レジスタ
ビット 0 ~ 3 ライン カウンタの最後の 4 ビットが等しくなると、垂直帰線が終了します。
         この値。
      4 if clear 保留中の垂直割り込みをクリアします。
      5 垂直割り込み (IRQ 2) が設定されている場合は無効になります。普通に残せる
         無効になっていますが、一部のシステム (PS/2 を含む) では有効にする必要があります。

3d4h index 12h (W): CRTC: 垂直表示終了レジスタ
bit 0-7 垂直表示終了の下位 8 ビット。行が終了すると表示が終了します。
         カウンターがこの値に達します。ビット 8 は 3d4h インデックス 7 ビット 1 にあります。

3d4h インデックス 13h (W): CRTC: オフセット レジスタ
ビット 0 ~ 7 スキャンラインのバイト数 / K。ここで、K はバイト モードの場合は 2、バイト モードの場合は 4 です。
         ワード モード、ダブル ワード モードの場合は 8 です。

3d4h index 14h (W): CRTC: Underline Location Register
ビット 0 ~ 4 文字セル内の下線の位置。

3d4h index 15h (W): CRTC: Start Vertical Blank Register
bit 0-7 垂直ブランク開始の下位 8 ビット。垂直ブランキングが開始されるタイミング
         ライン カウンタがこの値に達します。ビット 8 は 3d4h インデックス 7 にあります
         ビット 3。

3d4h index 16h (W): CRTC: End Vertical Blank Register
ビット 0 ~ 4 ライン カウンタの下位 5 ビットがカウントされると、垂直ブランキングが停止します。
         このフィールドに等しい。

3d4h index 17h (W): CRTC: モード制御レジスタ
ビット 0 クリアの場合、CGA 互換のメモリ アドレス指定システムを使用
         アドレス ビット 13 を文字行スキャン カウンタ ビット 0 に置き換えることにより、
         したがって、偶数および奇数のスキャン ライン用に 2 つのバンクが作成されます。
      1 明確な場合は、Hercules 互換のメモリ アドレス指定システムを使用します。
         アドレス ビット 14 を文字行スキャン カウンタ ビット 1 に置き換え、
         したがって、4 つのバンクが作成されます。
      2 スキャン ライン カウンタを 2 行ごとに増やすように設定した場合。
      3 設定されている場合、1 文字おきにのみメモリ アドレス カウンタを増やします
         時計。
      4 設定されている場合、EGA 出力ドライバーを無効にします。
      5 ワード モードの場合、ビット 15 がビット 0 にローテーションされる (このビットが設定されている場合)
         ビット 13 はビット 0 にローテーションされます。
      6 クリアシステムがワードモードの場合。住所は 1 桁上に回転します
         ビット 13 または 15 のいずれかをビット 0 にします。
      7 このビットをクリアすると、ビットがセットされるまで表示システムがリセットされます。
         また。

3d4h index 18h (W): CRTC: ラインコンペアレジスタ
ビット 0 ~ 7 ライン比較の下位 8 ビット。ラインカウンターがこれに達すると
         値、表示アドレスは 0 にラップします。分割画面を提供します。
         設備。ビット 8 は 3d4h インデックス 7 ビット 4 にあります。

3dAh (R): 入力ステータス #1 レジスタ
ビット 0 設定されている場合、垂直帰線または水平帰線のいずれかがアクティブ
      設定されている場合、1つのライトペンがトリガーされました
      2 ライトペンスイッチが設定されている場合は開いています
      3 設定されている場合、進行中の垂直帰線
    4-5 3C0h インデックス 12h に応じて、6 つのカラー出力のうちの 2 つを示します。
          Attr: Bit 4-5: Out bit 4 Out bit 5
                   0 青 赤
                   1 I 青 緑
                   2 I 赤 I 緑

3dAh (W): 機能制御レジスタ
ビット 0 機能コネクタのピン 21 への出力。
      1 機能コネクタのピン 20 への出力。
于 2010-01-25T23:00:31.513 に答える