DOS EGA图形编程在0Dh模式下

8

我正在进行一些有趣的复古编程。我想创建一个使用EGA图形的DOS游戏,但是我在网上找到参考资料有点困难。每个谈论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()更改为0x13而不是0x0d,则此示例代码非常有效,但像我说的那样,我正在尝试获取EGA图形,而不是VGA。 :) 我意识到为了每个像素使用四位,我要么需要假定plot_pixel同时写入两个像素,要么进行一些位操作以确保我只写入实际想要的四位。

我的问题是我没有看到我期望的输出 - 特别是,没有颜色!一切似乎都是单色的,这根本不是我想要的。在这种图形模式下,有没有一些不同的程序可以使用调色板,而不是13h?或者我是否已经调用了与我打算的完全不同的图形模式?指导将不胜感激。

我不认为我的编译器参数会相关,但以防万一:

..\dm\bin\dmc test.c -o test -mm
3个回答

4

0x0d 模式是基于平面模式,而0x13模式不是(除非进行特殊配置成为X模式)。您应该查看更多文档以了解如何在平面模式下工作。


谢谢提醒!我不知道平面图像,所以这会有所帮助。我真的很想查看文档,但我在这方面遇到的问题之一是我还没有找到好的文档资料。 :) - Parappa
3
请尝试访问http://www.phatcode.net/res/224/files/html/index.html。该网站对VGA和EGA都非常有帮助,因为在CGA、EGA和VGA上,平面模式的概念是相同的。 - Francis

3

嗯...我不知道这是否是一个有价值的答案,如果我没记错的话,您需要使用 inportinportboutportoutportb 来控制EGA寄存器,这些信息摘自FAQSYSW(一个包含从图形演示、数学、分形到压缩等各种材料的大型收藏),原始档案可以在这里这里找到。

3C0h:  Attribute Controller: Address register
bit 0-4  Address of data register to write to port 3C0h.
      5  If set screen output is enabled and the palette can not be modified,
         if clear screen output is disabled and the palette can be modified.
Port 3C0h is special in that it is both address and data-write register. An internal flip-flop remembers whether it is currently acting as address or data register. Accesses to the attribute controller must be separated by at least 250ns. Reading port 3dAh will reset the flip-flop to address mode.
3C0h index 0-Fh (W): Attribute: Palette bit 0 Primary Blue 1 Primary Green 2 Primary Red 3 Secondary Blue 4 Secondary Green 5 Secondary Red
3C0h index 10h (W): Attribute: Mode Control Register bit 0 Graphics mode if set, Alphanumeric mode else. 1 Monochrome mode if set, color mode else. 2 9-bit wide characters if set. The 9th bit of characters C0h-DFh will be the same as the 8th bit. Otherwise it will be the background color. 3 If set Attribute bit 7 is blinking, else high intensity.
3C0h index 11h (W): Attribute: Overscan Color Register. bit 0-5 Color of screen border. Color is defined as in the palette registers. Note: The EGA requires the Overscan color to be 0 in high resolution modes.
3C0h index 12h (W): Attribute: Color Plane Enable Register bit 0 Bit plane 0 is enabled if set. 1 Bit plane 1 is enabled if set. 2 Bit plane 2 is enabled if set. 3 Bit plane 3 is enabled if set. 4-5 Video Status MUX. Diagnostics use only. Two attribute bits appear on bits 4 and 5 of the Input Status Register 1 (3dAh). 0: Red/Blue, 1: Blue(I)/Green, 2: Red(I)/Green(I)
3C0h index 13h (W): Attribute: Horizontal PEL Panning Register bit 0-3 Indicates number of pixels to shift the display left Value 9bit textmode 256color mode Other modes 0 1 0 0 1 2 n/a 1 2 3 1 2 3 4 n/a 3 4 5 2 4 5 6 n/a 5 6 7 3 6 7 8 n/a 7 8 0 n/a n/a
3C2h (R): Input Status #0 Register bit 4 Status of the switch selected by the Miscellaneous Output Register 3C2h bit 2-3. Switch high if set. 5 Pin 19 of the Feature Connector (FEAT0) is high if set 6 Pin 17 of the Feature Connector (FEAT1) is high if set 7 If set IRQ 2 has happened due to Vertical Retrace. Should be cleared by IRQ 2 interrupt routine by clearing port 3d4h index 11h bit 4.
3C2h (W): Miscellaneous Output Register bit 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. 1 Enable CPU Access to video memory if set 2-3 Clock Select. 0: 14MHz, 1: 16MHz, 2: External 4 Disable internal video drivers if set 5 When in Odd/Even modes Select High 64k bank if set 6 Horizontal Sync Polarity. Negative if set 7 Vertical Sync Polarity. Negative if set Bit 6-7 indicates the number of lines on the display: 0: 200 lines, 2: 350 lines Note: Set to all zero on a hardware reset.
3C4h index 0 (W): Sequencer: Reset bit 0 Asynchronous Reset if clear 1 Synchronous Reset if clear 3C4h index 1 (W): Sequencer: Clocking Mode bit 0 If set character clocks are 8 dots wide, else 9. 1 If set the CRTC uses 2/5 of the clock cycles, else 4/5. 2 If set loads video serializers every other character clock cycle, else every one. 3 If set the Dot Clock is Master Clock/2, else same as Master Clock (See 3C2h bit 2-3). (Doubles pixels).
3C4h index 2 (W): Sequencer: Map Mask Register bit 0 Enable writes to plane 0 if set 1 Enable writes to plane 1 if set 2 Enable writes to plane 2 if set 3 Enable writes to plane 3 if set
3C4h index 3 (W): Sequencer: Character Map Select Register bit 0-1 Selects EGA Character Map (0..3) if bit 3 of the character attribute is clear. 2-3 Selects EGA Character Map (0..3) if bit 3 of the character attribute is set. Note: Character Maps are placed as follows: Map 0 at 0k, map 1 at 16k, map 2 at 32k and map 3 at 48k
3C4h index 4 (W): Sequencer: Memory Mode Register bit 0 Set if in an alphanumeric mode, clear in graphics modes. 1 Set if more than 64kbytes on the adapter. 2 Enables Odd/Even addressing mode if set. Odd/Even mode places all odd bytes in plane 1&3, and all even bytes in plane 0&2.
3CAh (W): Graphics 2 Position bit 0-1 Select which bit planes should be controlled by Graphics Controller #2. Always set to 1.
3CCh (W): Graphics 1 Position bit 0-1 Select which bit planes should be controlled by Graphics Controller #1. Always set to 0.
3CEh index 0 (W): Graphics: Set/Reset Register bit 0 If in Write Mode 0 and bit 0 of 3CEh index 1 is set a write to display memory will set all the bits in plane 0 of the byte to this bit, if the corresponding bit is set in the Map Mask Register (3CEh index 8). 1 Same for plane 1 and bit 1 of 3CEh index 1. 2 Same for plane 2 and bit 2 of 3CEh index 1. 3 Same for plane 3 and bit 3 of 3CEh index 1.
3CEh index 1 (W): Graphics: Enable Set/Reset Register bit 0 If set enables Set/reset of plane 0 in Write Mode 0. 1 Same for plane 1. 2 Same for plane 2. 3 Same for plane 3.
3CEh index 2 (W): Graphics: Color Compare Register bit 0-3 In Read Mode 1 each pixel at the address of the byte read is compared to this color and the corresponding bit in the output set to 1 if they match, 0 if not. The Color Don't Care Register (3CEh index 7) can exclude bitplanes from the comparison.
3CEh index 3 (W): Graphics: Data Rotate bit 0-2 Number of positions to rotate data right before it is written to display memory. Only active in Write Mode 0. 3-4 In Write Mode 2 this field controls the relation between the data written from the CPU, the data latched from the previous read and the data written to display memory: 0: CPU Data is written unmodified 1: CPU data is ANDed with the latched data 2: CPU data is ORed with the latch data. 3: CPU data is XORed with the latched data.
3CEh index 4 (W): Graphics: Read Map Select Register bit 0-1 Number of the plane Read Mode 0 will read from.
3CEh index 5 (W): Graphics: Mode Register bit 0-1 Write Mode: Controls how data from the CPU is transformed before being written to display memory: 0: Mode 0 works as a Read-Modify-Write operation. First a read access loads the data latches of the EGA with the value in video memory at the addressed location. Then a write access will provide the destination address and the CPU data byte. The data written is modified by the function code in the Data Rotate register (3CEh index 3) as a function of the CPU data and the latches, then data is rotated as specified by the same register. 1: Mode 1 is used for video to video transfers. A read access will load the data latches with the contents of the addressed byte of video memory. A write access will write the contents of the latches to the addressed byte. Thus a single MOVSB instruction can copy all pixels in the source address byte to the destination address. 2: Mode 2 writes a color to all pixels in the addressed byte of video memory. Bit 0 of the CPU data is written to plane 0 et cetera. Individual bits can be enabled or disabled through the Bit Mask register (3CEh index 8). 2 Forces all outputs to a high impedance state if set. 3 Read Mode 0: Data is read from one of 4 bit planes depending on the Read Map Select Register (3CEh index 4). 1: Data returned is a comparison between the 8 pixels occupying the read byte and the color in the Color Compare Register (3CEh index 2). A bit is set if the color of the corresponding pixel matches the register. 4 Enables Odd/Even mode if set (See 3C4h index 4 bit 2). 5 Enables CGA style 4 color pixels using even/odd bit pairs if set.
3CEh index 6 (W): Graphics: Miscellaneous Register bit 0 Indicates Graphics Mode if set, Alphanumeric mode else. 1 Enables Odd/Even mode if set. 2-3 Memory Mapping: 0: use A000h-BFFFh 1: use A000h-AFFFh EGA Graphics modes 2: use B000h-B7FFh Monochrome modes 3: use B800h-BFFFh CGA modes
3CEh index 7 (W): Graphics: Color Don't Care Register bit 0 Ignore bit plane 0 in Read mode 1 if clear. 1 Ignore bit plane 1 in Read mode 1 if clear. 2 Ignore bit plane 2 in Read mode 1 if clear. 3 Ignore bit plane 3 in Read mode 1 if clear.
3CEh index 8 (W): Graphics: Bit Mask Register bit 0-7 Each bit if set enables writing to the corresponding bit of a byte in display memory.
3d4h index 0 (W): CRTC: Horizontal Total Register bit 0-7 Horizontal Total Character Clocks-2
3d4h index 1 (W): CRTC: Horizontal Display End Register bit 0-7 Number of Character Clocks Displayed -1
3d4h index 2 (W): CRTC: Start Horizontal Blanking Register bit 0-7 The count at which Horizontal Blanking starts
3d4h index 3 (W): CRTC: End Horizontal Blanking Register bit 0-4 Horizontal Blanking ends when the last 5 bits of the character counter equals this field. 5-6 Number of character clocks to delay start of display after Horizontal Total has been reached.
3d4h index 4 (W): CRTC: Start Horizontal Retrace Register bit 0-7 Horizontal Retrace starts when the Character Counter reaches this value.
3d4h index 5 (W): CRTC: End Horizontal Retrace Register bit 0-4 Horizontal Retrace ends when the last 5 bits of the character counter equals this value. 5-6 Number of character clocks to delay start of display after Horizontal Retrace. 7 Provides Smooth Scrolling in Odd/Even mode. When set display starts from an odd byte.
3d4h index 6 (W): CRTC: Vertical Total Register bit 0-7 Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7 bit 0.
3d4h index 7 (W): CRTC: Overflow Register bit 0 Bit 8 of Vertical Total (3d4h index 6) 1 Bit 8 of Vertical Display End (3d4h index 12h) 2 Bit 8 of Vertical Retrace Start (3d4h index 10h) 3 Bit 8 of Start Vertical Blanking (3d4h index 15h) 4 Bit 8 of Line Compare Register (3d4h index 18h)
3d4h index 8 (W): CRTC: Preset Row Scan Register bit 0-4 Number of lines we have scrolled down in the first character row. Provides Smooth Vertical Scrolling.
3d4h index 9 (W): CRTC: Maximum Scan Line Register bit 0-4 Number of scan lines in a character row -1. In graphics modes this is the number of times (-1) the line is displayed before passing on to the next line (0: normal, 1: double, 2: triple...). This is independent of bit 7, except in CGA modes which seems to require this field to be 1 and bit 7 to be set to work.
3d4h index 0Ah (W): CRTC: Cursor Start Register bit 0-4 First scanline of cursor within character.
3d4h index 0Bh (W): CRTC: Cursor End Register bit 0-4 Last scanline of cursor within character 5-6 Delay of cursor data in character clocks.
3d4h index 0Ch (W): CRTC: Start Address High Register bit 0-7 Upper 8 bits of the start address of the display buffer 3d4h index 0Dh (W): CRTC: Start Address Low Register bit 0-7 Lower 8 bits of the start address of the display buffer 3d4h index 0Eh (W): CRTC: Cursor Location High Register bit 0-7 Upper 8 bits of the address of the cursor 3d4h index 0Fh (W): CRTC: Cursor Location Low Register bit 0-7 Lower 8 bits of the address of the cursor 3d4h index 10h (R): CRTC: Light Pen High Register bit 0-7 Upper 8 bits of the address of the lightpen position.
3d4h index 10h (W): CRTC: Vertical Retrace Start Register bit 0-7 Lower 8 bits of Vertical Retrace Start. Vertical Retrace starts when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 2.
3d4h index 11h (R): CRTC: Light Pen Low Register bit 0-7 Lower 8 bits of the address of the lightpen position.
3d4h index 11h (W): CRTC: Vertical Retrace End Register bit 0-3 Vertical Retrace ends when the last 4 bits of the line counter equals this value. 4 if clear Clears pending Vertical Interrupts. 5 Vertical Interrupts (IRQ 2) disabled if set. Can usually be left disabled, but some systems (including PS/2) require it to be enabled.
3d4h index 12h (W): CRTC: Vertical Display End Register bit 0-7 Lower 8 bits of Vertical Display End. The display ends when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1.
3d4h index 13h (W): CRTC: Offset register bit 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode.
3d4h index 14h (W): CRTC: Underline Location Register bit 0-4 Position of underline within Character cell.
3d4h index 15h (W): CRTC: Start Vertical Blank Register bit 0-7 Lower 8 bits of Vertical Blank Start. Vertical blanking starts when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 3.
3d4h index 16h (W): CRTC: End Vertical Blank Register bit 0-4 Vertical blanking stops when the lower 5 bits of the line counter equals this field.
3d4h index 17h (W): CRTC: Mode Control Register bit 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, thus creating 2 banks for even and odd scan lines. 1 If clear use Hercules compatible memory addressing system by substituting character row scan counter bit 1 for address bit 14, thus creating 4 banks. 2 If set increase scan line counter only every second line. 3 If set increase memory address counter only every other character clock. 4 If set disable the EGA output drivers. 5 When in Word Mode bit 15 is rotated to bit 0 if this bit is set else bit 13 is rotated into bit 0. 6 If clear system is in word mode. Addresses are rotated 1 position up bringing either bit 13 or 15 into bit 0. 7 Clearing this bit will reset the display system until the bit is set again.
3d4h index 18h (W): CRTC: Line Compare Register bit 0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this value, the display address wraps to 0. Provides Split Screen facilities. Bit 8 is found in 3d4h index 7 bit 4.
3dAh (R): Input Status #1 Register bit 0 Either Vertical or Horizontal Retrace active if set 1 Light Pen has triggered if set 2 Light Pen switch is open if set 3 Vertical Retrace in progress if set 4-5 Shows two of the 6 color outputs, depending on 3C0h index 12h. Attr: Bit 4-5: Out bit 4 Out bit 5 0 Blue Red 1 I Blue Green 2 I Red I Green
3dAh (W): Feature Control Register bit 0 Output to pin 21 of the Feature Connector. 1 Output to pin 20 of the Feature Connector.

2

它是单色的,因为它同时写入了所有四个颜色平面。正如其他答案所指出的那样,模式D是平面的,并且一个寄存器控制着循环中要写入哪个平面。默认情况下,它选择同时写入所有平面,因此是单色的。

例如,要选择“红色”平面和“强烈”,您可以执行以下操作:

mov dx, 3C4h       ; address of sequencer address register
mov al, 2h         ; index of map mask register
out dx, al

mov dx, 3C5h       ; address of sequencer data register
mov al, 00001100b  ; turn on the 'red' and 'intense' planes
out dx, al

对VRAM的后续写入会为每个写入的位(1位= 1像素)创建一个明亮的红色像素。当然,颜色假定调色板未从默认设置更改,您也可以进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接