我有一些代码可以写入和读取VGA的I / O端口。我试图在内联汇编程序中实现工作C代码功能。我正在使用Open Watcom 2.0并编译DOS 16bit。
要写入VGA上的调色板,我想出了这个。这不能正常工作。
编辑:setPaletteColor的代码并不完全准确。我已更新以反映实际代码。
void setPaletteColor (unsigned char index, rgbColor *p_color)
{
_asm
{
; tell VGA card we are going to update a palette register
mov dx,PALETTE_MASK
mov al,0xff
out dx,al
; tell VGA which register we will be updating
mov dx,PALETTE_REGISTER_WR
mov al,index
out dx,al
; update the color in the register at index
mov dx,PALETTE_DATA
mov al,*p_color
out dx,al
mov al,*p_color // this is actually *(p_color+1) but this actually gets the next structure not the next data member, so I left it out of the code I typed for my question.
out dx,al
mov al,*p_color // same here, actually is *(p_color+2)
out dx,al
}
}
为了阅读,我有这个。这也无法正常工作。
void getPaletteColor (unsigned char index, rgbColor *p_color)
{
unsigned char *p_red = &p_color->red;
unsigned char *p_green = &p_color->green;
unsigned char *p_blue = &p_color->blue;
_asm
{
; tell VGA card we are going to read a palette register
mov dx,PALETTE_MASK
mov al,0xff
out dx,al
; tell VGA which register we will be reading
mov dx,PALETTE_REGISTER_RD
mov al,index
out dx,al
; read the data into the color struct at 'p_color'
mov dx,PALETTE_DATA
in al,dx
mov *p_red,al
in al,dx
mov *p_green,al
in al,dx
mov *p_blue,al
}
}
现在这里有纯C版本。
void setPaletteColor (unsigned char index, rgbColor *p_color)
{
outp(PALETTE_MASK,0xff);
outp(PALETTE_REGISTER_WR, index);
outp(PALETTE_DATA,p_color->red);
outp(PALETTE_DATA,p_color->green);
outp(PALETTE_DATA,p_color->blue);
}
阅读。
void getPaletteColor (unsigned char index, rgbColor *p_color)
{
outp(PALETTE_MASK,0xff);
outp(PALETTE_REGISTER_RD, index);
p_color->red = inp(PALETTE_DATA);
p_color->green = inp(PALETTE_DATA);
p_color->blue = inp(PALETTE_DATA);
}
注意:我不能使用'。'运算符也不是' - >'内联汇编中的运算符,因为编译器不支持它。
这是rgbColor结构的定义。
typedef struct rgbColorTag
{
unsigned char red;
unsigned char green;
unsigned char blue;
} rgbColor;
答案 0 :(得分:1)
一个好问题将描述它是如何运作的。只是说它"不起作用"让我觉得这是一个语法错误,因为我不知道Watcom风格的内联asm。我只是假设它类似于MSVC样式,并且在asm中使用C解除引用运算符是语法错误(例如在mov al,*p_color
中)。
显然,这是Open Watcom的有效语法,但是您将加载相同的字节3次。也许尝试mov al, *(p_color+1)
第二个字节?虽然那可能只是做C指针数学,并获得下一个结构的开始。查看编译器手册以获取可用的语法选项。
您也可以将指针加载到寄存器中并自己使用偏移量(使用mov al, [si+1]
等寻址模式)。这取决于按顺序排列的3个结构成员没有填充,但我认为这应该是一个安全的假设。您可以随时检查编译器的asm输出,看看它是如何布局结构的。
由于您的结构以正确的顺序排列,您应该能够使用OUTS
在其中循环3个字节。甚至REP OUTS,所以你不需要写一个循环。
cld
mov si, p_color ; get the function arg in a register
mov dx, PALETTE_DATA
mov cx, 3
rep outsb ; OUT 3 times, to port DX, using data from DS:[SI] (and do SI++ post-increment)
同样,对于阅读,
cld
mov di, p_color
mov dx, PALETTE_DATA
mov cx, 3
rep insb ; IN 3 times, to port DX, using data from DS:[DI] (and do DI++)