Структура видеопамяти в режиме 6.
Рисунок 5.2 Структура видеопамяти в режиме 6.
При непосредственном доступе к видеопамяти вы можете воспользоваться следующими формулами:
Если y четное число, то смещение байта = 50h*(y/2)+(x/8) Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/8)
Номер бита = 7-mod(x/8)
Эти формулы позволяют определить для пиксела, имеющего координаты (x,y), смещение от начала станицы видеопамяти байта и номер бита в нем, управляющего данным пикселом.
Теперь мы приведем программу, отображающую пикселы на экране через непосредственный доступ к видеопамяти. Стержнем этой программы является функция Pixel_Offs_6. Первые два ее параметра определяют координаты пиксела. Третий параметр - это указатель на смещение байта, определяющего пиксел в видеопамяти. Четвертый параметр определяет номер младшего из битов, который отвечает за данный пиксел. Заметим, что так как каждый байт в этом режиме определяет восемь пикселов, то при изменении одного пиксела надо позаботится о сохранении остальных семи пикселов.
#include "sysp.h"
void Pixel_Offs_6(unsigned x, unsigned y, unsigned *offset, unsigned char *shift) {
unsigned char bit_shift; unsigned byte_offset;
_asm {
; записываем в bx x-координату пиксела
mov bx,x
; запоминаем в регистре cl младший байт переменной x
mov cl,bl
; записываем в ax y-координату пиксела
mov ax,y
; вычисляем смещение байта, определяющего пиксел с ; координатами (x,y)
; ax = 100h * y
xchg ah,al
; в бит D7, регистра al, записываем младший бит ; переменной y; этот бит равен единице, если значение ; переменной y нечетное, и равен нулю, если оно четное
; al = 80h * (y&1) ; ax = ax/2 = 80h * y
shr ax,1
; bx = x/2
shr bx,1
; bx = x/2 + 8000h*(y&1)
add bh,al
; ax = 100h*(y/2)
xor al,al
; bx = x/2 + 8000h*(y&1) + 100h*(y/2)
add bx,ax
; ax = 40h*(y/2)
shr ax,1 shr ax,1
; bx = x/2 + 8000h*(y&1) + 140h*(y/2)
add bx,ax
; bx = x/8 + 2000h*(y&1) + 50h*(y/2)
shr bx,1 shr bx,1
; bx = byte offset in video buffer
mov byte_offset,bx
; cl = x & 7
and cl,7
; cl = number of bits to shift left
xor cl,7
mov bit_shift,cl }
*shift = bit_shift; *offset = byte_offset; }
// // главная функция //
void main(void) {
unsigned offset,i; unsigned char mask,shift;
unsigned char far *ptr; unsigned char current,w_pixel,color;
// устанавливаем режим 6
_asm { xor ax,ax mov al,6 int 10h }
// отображаем на экране несколько точек // непосредственно через видеопамять
for(i=0;i<199;i++){
color = i % 2;
// определяем смещение (offset) и сдвиг (shift) // для пиксела с координатами x и y
Pixel_Offs_6(i,i,&offset,&shift);
// получаем указатель на байт, определяющий // нужный нам пиксел
ptr = (unsigned char far*) (FP_MAKE(0xB800, offset));
// получаем старое значение байта, определяющего // пиксел
current = *ptr;
// записываем в видеопамять старое значение, // но с измененными битами, отвечающими за наш // пиксел
w_pixel = (unsigned char) color << shift; *ptr = current | w_pixel; }
getch(); }
Содержание раздела