Вывод монохромного рисунка на экран в DOSВывод монохромного рисунка на экран в режиме от 0Dh до 12h Программа приведенная ниже будет работать без изменений в следующих графических режимах приведенных в таблице номер режимаразрешение экраначисло цветов0Eh 640х200 160Fh 640х350 моно10h 640х350 1611h 640x480 моно12h 640x480 16 Код (ASM): ; masm dos com # .286 .model tiny .code .386; используется инструкция MOVSD org 100h BITMAPFILEHEADER STRUCT bfType WORD ? bfSize DWORD ? bfReserved1 WORD ? bfReserved2 WORD ? bfOffBits DWORD ? BITMAPFILEHEADER ENDS BITMAPINFOHEADER STRUCT biSize DWORD ? biWidth DWORD ? biHeight DWORD ? biPlanes WORD ? biBitCount WORD ? biCompression DWORD ? biSizeImage DWORD ? biXPelsPerMeter DWORD ? biYPelsPerMeter DWORD ? biClrUsed DWORD ? biClrImportant DWORD ? BITMAPINFOHEADER ENDS start: mov ax,12h;здесь может быть режим от 0Dh до 12h int 10h push 0A000h pop es mov ax,3D00h ;функция открытия, только чтение mov dx,offset filename;имя bmp-файла int 21h mov bx,ax ;запомнить номер файла mov cx,sizeof BITMAPFILEHEADER ;длина записи mov dx,offset buffer mov ah,3Fh ;функция чтения int 21h mov di,dx assume di: ptr BITMAPFILEHEADER cmp [di].bfType,"MB" ;bmp-файл? jnz exit mov si,word ptr [di].bfOffBits add si,dx add dx,sizeof BITMAPFILEHEADER mov cx,word ptr [di].bfSize sub cx,sizeof BITMAPFILEHEADER mov ah,3Fh ;функция чтения int 21h mov ah,3Eh ;закрываем файл int 21h add di,sizeof BITMAPFILEHEADER assume di: ptr BITMAPINFOHEADER cmp [di].biBitCount,1 ;если файл не монохром jnz exit ;завершаем программу mov bp,word ptr [di].biWidth add bp,15 and bp,not 15;делаем ширину кратной 16 shr bp,3;ширину делим на 8, так как в 1 байте 8 точек add word ptr [delta+2],bp shr bp,2;будем выводить на экран по 4 байта mov dx,word ptr [di].biHeight imul di,dx,80;(высота рисунка)х(ширина экрана)/8 точек @@: mov cx,bp rep movsd delta: sub di,80;(ширина экрана)/8 точек dec dx jnz @b mov ah,0 int 16h exit: mov ax,3 int 10h ret filename db "coon.bmp" buffer db 0 end start Вывод монохромного рисунка на экран в режиме 13h (320х200х256 цветов) Код (ASM): ; masm dos com # .286 .model tiny .code org 100h BITMAPFILEHEADER STRUCT bfType WORD ?; информация о типе файла bfSize DWORD ?; размер самого файла в байтах bfReserved1 WORD ?; нули (зарезервировано) bfReserved2 WORD ?; тоже нули bfOffBits DWORD ?; смещение относительно начала файла до битового массива картинки BITMAPFILEHEADER ENDS BITMAPINFOHEADER STRUCT biSize DWORD ?; размер структуры BITMAPINFOHEADER в байтах biWidth DWORD ?; ширина изображения (в пикселях) biHeight DWORD ?; высота изображения в пикселях biPlanes WORD ?; количество плоскостей biBitCount WORD ?; количество бит на пиксель biCompression DWORD ?; тип сжатия biSizeImage DWORD ?; размер изображения в байтах biXPelsPerMeter DWORD ?; горизонтальное разрешение biYPelsPerMeter DWORD ?; вертикальное разрешение biClrUsed DWORD ?; текущее число цветов графического движка biClrImportant DWORD ?; количество важных цветов BITMAPINFOHEADER ENDS start: mov ax,13h;установили видеорежим int 10h mov ax,1010h;установить один регистр цвета mov bx,0FFh;номер цвета=0FF mov dh,3Fh;яркость красного mov cx,3F3Fh;яркость зеленого (CH) и синего (CL) int 10h xor bx,bx;то же самое для цвета=0 mov dx,bx mov cx,bx int 10h push 0A000h;адрес видеобуфера pop es mov ax,3D00h ;функция открытия, только чтение mov dx,offset filename;имя bmp-файла int 21h mov bx,ax ;запомнить номер файла mov cx,sizeof BITMAPFILEHEADER;длина структуры mov dx,offset buffer mov ah,3Fh ;читаем BITMAPFILEHEADER из bmp-файла int 21h mov di,dx assume di: ptr BITMAPFILEHEADER cmp [di].bfType,"MB" ;это действительно bmp-файл? jnz exit ;если нет, тогда выходим из программы mov si,word ptr [di].bfOffBits;получаем смещение add si,dx;от начала буфера до начала растра bmp-файла add dx,sizeof BITMAPFILEHEADER mov cx,word ptr [di].bfSize;получаем размер bmp-файла и минусуем из этого размера sub cx,sizeof BITMAPFILEHEADER;структуру BITMAPFILEHEADER, которую уже прочитали mov ah,3Fh ;читаем в буфер остатки bmp-файла int 21h mov ah,3Eh ;закрываем файл, он нам уже не нужен int 21h add di,sizeof BITMAPFILEHEADER assume di: ptr BITMAPINFOHEADER cmp [di].biBitCount,1 ;если файл не монохром jnz exit ;завершаем программу mov bp,word ptr [di].biWidth;ширина рисунка add bp,31;делаем ее кратной 32. Откуда 32? (biWidth/8)/4 == biWidth/32. ;Ненулевой остаток от деления говорит о необходимости выравнивания and bp,not 31 add word ptr [delta+2],bp;рассчитываем смещение для вывода строк - пример модификации программного кода shr bp,3; запоминаем в регистре ВР ширину рисунка деленную на 8 mov dx,word ptr [di].biHeight; запоминаем в регистре DX высоту рисунка imul di,dx,320;координаты левого нижнего угла рисунка на экране @@@: mov cx,bp @@: lodsb mov ah,al rept 8;8 раз сдвигаем регистр АН и если есть единичка делаем AL=0FFh иначе AL=0 add ax,ax db 0D6h;salc == sbb al,al stosb;выводим содержимое регистра AL на экран endm loop @b delta: sub di,320;переходим на строку выше, вместо 320 тут будет другое значение dec dx jnz @@@ mov ah,0;ждем пока не нажмут любую клавишу int 16h exit: mov ax,3;устанавливаем текстовый режим int 10h ret;выходим из программы filename db "coon.bmp" buffer db 0; последняя метка в СОМ-программе, после нее можно организовать буфер размером до 63 кбайт end start
Вывод монохромного рисунка на экран в VESA-режиме 640x480x256 Код (ASM): ; masm dos com # .286 .model tiny .code org 100h BITMAPFILEHEADER STRUCT bfType WORD ? bfSize DWORD ? bfReserved1 WORD ? bfReserved2 WORD ? bfOffBits DWORD ? BITMAPFILEHEADER ENDS BITMAPINFOHEADER STRUCT biSize DWORD ? biWidth DWORD ? biHeight DWORD ? biPlanes WORD ? biBitCount WORD ? biCompression DWORD ? biSizeImage DWORD ? biXPelsPerMeter DWORD ? biYPelsPerMeter DWORD ? biClrUsed DWORD ? biClrImportant DWORD ? BITMAPINFOHEADER ENDS start: mov ax,4F02h mov bx,101h;установка режима 640*480*256 int 10h mov ax,1010h;установить один регистр цвета mov bx,0FFh;номер цвета mov dh,3Fh;яркость красного mov cx,3F3Fh;яркость зеленого (CH) и синего (CL) int 10h xor bx,bx mov dx,bx mov cx,bx int 10h push 0A000h pop es mov ax,3D00h ;функция открытия, только чтение mov dx,offset filename;имя bmp-файла int 21h mov bx,ax ;запомнить номер файла mov cx,sizeof BITMAPFILEHEADER ;длина записи mov dx,offset buffer mov ah,3Fh ;функция чтения int 21h mov di,dx assume di: ptr BITMAPFILEHEADER cmp [di].bfType,"MB" ;bmp-файл? jnz exit mov si,word ptr [di].bfOffBits add si,dx;offset buffer add dx,sizeof BITMAPFILEHEADER mov cx,word ptr [di].bfSize sub cx,sizeof BITMAPFILEHEADER mov ah,3Fh ;функция чтения int 21h mov ah,3Eh ;закрываем файл int 21h add di,sizeof BITMAPFILEHEADER assume di: ptr BITMAPINFOHEADER cmp [di].biBitCount,1 ;если файл не монохром jnz exit ;завершаем программу mov bp,word ptr [di].biWidth;берем ширину картинки add bp,31 and bp,not 31;делаем ширину кратной 32 add word ptr delta0+2,bp;изменяем смещение для перехода на новую строку shr bp,3;делим ширину на 8, так как в байте BMP информация о 8 пикселах mov ax,word ptr [di].biHeight;делим высоту картинки mov bx,0FFFFh/640;на высоту окна видеопамяти xor dx,dx;чтобы знать с какого окна видеопамяти начинать вывод div bx mov word ptr delta1+1,dx;изменяем количество циклов для последнего окна xor bx,bx;выбор окна видеопамяти mov dx,ax;адрес окна видеопамяти в единицах гранулярности (от 0 до 4) inc ax imul di,ax,-256;установка начального смещения di cmp di,-640 ;dx=0 di=-256, dx=1 di=-512, dx=2 di=-128 sbb ax,ax ;dx=3 di=-384, dx=4 di=-640 and ax,640 add di,ax @3: mov cx,0FFFFh/640 @2: mov ax,4F05h;управление доступом к видеопамяти int 10h @1: push cx mov cx,bp @@: lodsb mov ah,al rept 8 ;8 раз извлекаем по 1 биту и если бит равен 1 - делаем AL=0FF, add ax,ax;а если бит равен 0 - делаем AL=0 db 0D6h ;sbb al,al stosb ;пишем в видеопамять endm loop @b delta0: sub di,640;перемещеаемся на строку вверх pop cx loop @1 dec dx jg @3; если dx > 0 delta1: mov cx,0FFFFh jns @2; если dx < 0 выходим из цикла mov ah,0; ожидаем нажатия на любую клавишу int 16h exit: mov ax,3;восстанавливаем текстовый режим int 10h ret ;выходим из программы filename db "coon.bmp";имя ВМР-файла buffer db 0;начало буфера и одновременно терминирующий символ для имени файла end start