Всем привет:
Приходится мне ручками реализовывать некоторые функции BGI из Borland C++ 3.1 ( это под ДОС). Работаю в графическом режиме 12h
ПРи работе на уровне БИОСА наблюдаются ужасные тормоза. Начал искать инфу, как работать напрямую с видеопамятью в данном случае. Не нашел. Но в зубкове в разделе про программирование портов нашел работу через регистры. Хотя тоже достаточно медленно (виден процесс прорисовки), но это лучше, чем было. Но честно говоря, не врубаюсь я, как там это сделано.
Нормальной литературы, где это было бы написано понятно, я не нашел
Теперь следующая проблема. Для создания рисования в режиме XOR нужно получать цвет старой точки( т.е. новая точка ксорится со старой, что нужно для динамического рисования прямой (и ее стирания) ) . Но как это сделать НЕ ЧЕРЕЗ БИОС??? Через биос это очень медленно.
Вот то, что я наработал:
void PutPixel( int x, int y, COLOR color )
{
if( writeMode == XOR_PUT ) // глобальная переменная
{
color ^= GetPixel( x, y );
}
#ifdef BIOS
_asm {
mov ah, 0xC
mov al, color
mov bh, 0
mov cx, x
mov dx, y
int 0x10
}
#else
_asm {
pusha
push 0xA000
pop es
mov cx, x
mov dx,y
mov al,color
cbw
push ax
pop bp
// вычислить номер байта в видеопамяти
xor bx, bx
mov ax,dx // AX = строка
push bx
mov bx, 5
mul bx
pop bx
// lea eax, [eax + eax * 4] //АХ = АХ * 5
shl ax, 4 // АХ = АХ * 16
// АХ = строка * байт_в_строке
// (строка * 80)
push cx
shr cx,3 // CX = номер байта в строке
add ax,cx // АХ = номер байта в видеопамяти
mov di,ax // сохранить его в DI
// вычислить номер бита в байте
pop cx
and cx,0x07 // остаток от деления на 8 - номер
// бита в байте, считая справа налево
mov bx,0x0080
shr bx,cl // в BL теперь нужный бит установлен в 1
// программирование портов
mov dx,0x03CE // индексный порт
// графического контроллера
mov ax,0x0F01 // регистр 01h: разрешение
// установки/сброса
out dx,ax // разрешить установку/сброс для
// всех плоскостей (эту часть лучше
// сделать однажды в программе, например сразу после установки
// видеорежима, и не повторять каждый раз при вызове процедуры)
mov ax,bp
shl ax,8 // регистр 00h: регистр
// установки/сброса
out dx,ax // АН = цвет
mov al,0x08 // порт 08h: битовая маска
mov ah,bl // записать в битовую маску нули
// всюду, кроме
out dx,ax // бита, соответствующего выводимому пикселю
mov ah,byte ptr es:[di] // заполнить
// регистры-защелки
mov byte ptr es:[di],ah // вывод на экран:
// выводится единственный бит
// в соответствии с содержимым регистра битовой маски, остальные
// биты берутся из защелки, то есть не изменяются. Цвет выводимого
// бита полностью определяется значением регистра установки/сброса
popa
}
#endif
}
//---------------------------------------------------------------------------
COLOR GetPixel( int x, int y )
{
COLOR color;
_asm {
mov ah, 0xD
mov bh, 0
mov cx, x
mov dx, y
int 0x10
mov color, al
}
return color;
}
Как быть? Может, кто-нибудь занимался таким?
Буду рад помощи.
Здравствуйте, Kuvaldis, Вы писали:
K>Как быть? Может, кто-нибудь занимался таким?
K>Буду рад помощи.
Ну ты вспомнил... Как давно это было
В общем. Ключевые слова для тебя: "Программирование EGA и VGA видеоадаптеров".
Еще советую поискать VESA BIOS Extension.
Еще советую изучить карту памяти в реальном режиме... Видеопамять так-то доступна в обычном адресном пространстве...
Могу предложить вот такой архив (это подборка для студентов, там много лишнего, всего он 60Мб весит):
ftp://fde.uran.ru/DOS.zip
Там есть очень хороший справочник Norton's Guide, Ralf's Brown interrupt list, статьи Юрия Лукача и т.п.
Читай, изучай. Большая часть вопросов должна пропасть.