У меня есть код, который записывает и считывает порты ввода-вывода для VGA. Я пытаюсь реализовать функциональность C-кода в встроенном ассемблере. Я использую Open Watcom 2.0 и компилирую для DOS 16 бит.Доступ к структурному элементу из указателя структуры с помощью встроенной сборки Open Watcom
Чтобы написать цветную палитру на VGA, я придумал это. Это работает неправильно.
EDIT: Код для 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, которые работают DO.
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;
ли http://bos.asmhackers.net/docs/vga_without_bios/docs/palettesetting.pdf помочь? Похоже, он делает то же, что и ты. –
* ПРИМЕЧАНИЕ. Я не могу использовать '.' оператора или оператора '->' в встроенной сборке, потому что компилятор не поддерживает его. * Поэтому присвойте данные локальной переменной на C и прочитайте или напишите, что в inline asm. Это может заставить компилятор сделать что-то глупое, например, на самом деле исправить дополнительные инструкции, чтобы скопировать его в стек. Что случилось с чистой версией C? Вызывает ли компилятор медленный код для этого?Почему, по-вашему, вы можете получить более быстрый код от его выполнения с помощью встроенного asm? Или это 'outp' фактическая функция, вызываемая, а не внутренняя? –
@PeterCordes Посмотрите на мою сборку «getPaletteColor()« Я использую переменные локального указателя, чтобы получить смещения членов для цветовой структуры. Чистая версия C прекрасна, но я хочу знать, как все это делать. Вот почему я пишу программу DOS в первую очередь. Это все учебный опыт, и до сих пор я многому научился. 'outp' - это функция, предоставляемая компилятором для записи в порты ввода-вывода. То же самое с 'inp'. – SeanRamey