Вывод монохромного рисунка на экран в DOS

Тема в разделе "WASM.DOS/BIOS/Vesa/ports", создана пользователем Mikl___, 23 дек 2016.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708

    Вывод монохромного рисунка на экран в DOS

    Вывод монохромного рисунка на экран в режиме от 0Dh до 12h


    [​IMG]
    Программа приведенная ниже будет работать без изменений в следующих графических режимах приведенных в таблице
    номер
    режима
    разрешение
    экрана
    число
    цветов
    0Eh 640х200 16
    0Fh 640х350 моно
    10h 640х350 16
    11h 640x480 моно
    12h 640x480 16
    Код (ASM):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. .386; используется инструкция MOVSD
    6. org 100h
    7. BITMAPFILEHEADER STRUCT
    8.   bfType        WORD      ?
    9.   bfSize        DWORD      ?
    10.   bfReserved1   WORD      ?
    11.   bfReserved2   WORD      ?
    12.   bfOffBits     DWORD      ?
    13. BITMAPFILEHEADER ENDS
    14.  
    15. BITMAPINFOHEADER STRUCT
    16.   biSize            DWORD      ?
    17.   biWidth           DWORD      ?
    18.   biHeight          DWORD      ?
    19.   biPlanes          WORD       ?
    20.   biBitCount        WORD       ?
    21.   biCompression     DWORD      ?
    22.   biSizeImage       DWORD      ?
    23.   biXPelsPerMeter   DWORD      ?
    24.   biYPelsPerMeter   DWORD      ?
    25.   biClrUsed         DWORD      ?
    26.   biClrImportant    DWORD      ?
    27. BITMAPINFOHEADER ENDS
    28. start:  mov ax,12h;здесь может быть режим от 0Dh до 12h
    29.     int 10h
    30.     push 0A000h
    31.     pop es
    32.     mov ax,3D00h    ;функция открытия, только чтение
    33.     mov dx,offset filename;имя bmp-файла
    34.     int 21h
    35.     mov bx,ax   ;запомнить номер файла
    36.     mov cx,sizeof BITMAPFILEHEADER   ;длина записи
    37.     mov dx,offset buffer
    38.     mov ah,3Fh      ;функция чтения
    39.     int 21h
    40.     mov di,dx
    41.     assume di: ptr BITMAPFILEHEADER
    42.     cmp [di].bfType,"MB" ;bmp-файл?
    43.     jnz exit
    44.     mov si,word ptr [di].bfOffBits
    45.     add si,dx
    46.     add dx,sizeof BITMAPFILEHEADER
    47.     mov cx,word ptr [di].bfSize
    48.     sub cx,sizeof BITMAPFILEHEADER
    49.     mov ah,3Fh      ;функция чтения
    50.     int 21h
    51.     mov ah,3Eh      ;закрываем файл
    52.     int 21h
    53.     add di,sizeof BITMAPFILEHEADER
    54.     assume di: ptr BITMAPINFOHEADER
    55.     cmp [di].biBitCount,1 ;если файл не монохром
    56.     jnz exit ;завершаем программу
    57.     mov bp,word ptr [di].biWidth
    58.     add bp,15
    59.     and bp,not 15;делаем ширину кратной 16
    60.     shr bp,3;ширину делим на 8, так как в 1 байте 8 точек
    61.     add word ptr [delta+2],bp
    62.         shr bp,2;будем выводить на экран по 4 байта
    63.     mov dx,word ptr [di].biHeight
    64.         imul di,dx,80;(высота рисунка)х(ширина экрана)/8 точек
    65. @@: mov cx,bp
    66.     rep movsd
    67. delta:  sub di,80;(ширина экрана)/8 точек
    68.     dec dx
    69.     jnz @b
    70.     mov ah,0
    71.     int 16h
    72. exit:   mov ax,3
    73.     int 10h
    74.     ret
    75. filename db "coon.bmp"
    76. buffer db 0
    77. end start

    Вывод монохромного рисунка на экран в режиме 13h (320х200х256 цветов)

    Код (ASM):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. org 100h
    6. BITMAPFILEHEADER STRUCT
    7.   bfType        WORD      ?; информация о типе файла
    8.   bfSize        DWORD      ?; размер самого файла в байтах
    9.   bfReserved1   WORD      ?; нули (зарезервировано)
    10.   bfReserved2   WORD      ?; тоже нули
    11.   bfOffBits     DWORD      ?; смещение относительно начала файла до битового массива картинки
    12. BITMAPFILEHEADER ENDS
    13.  
    14. BITMAPINFOHEADER STRUCT
    15.   biSize            DWORD      ?; размер структуры BITMAPINFOHEADER в байтах
    16.   biWidth           DWORD      ?; ширина изображения (в пикселях)
    17.   biHeight          DWORD      ?; высота изображения в пикселях
    18.   biPlanes          WORD       ?; количество плоскостей
    19.   biBitCount        WORD       ?; количество бит на пиксель
    20.   biCompression     DWORD      ?; тип сжатия
    21.   biSizeImage       DWORD      ?; размер изображения в байтах
    22.   biXPelsPerMeter   DWORD      ?; горизонтальное разрешение
    23.   biYPelsPerMeter   DWORD      ?; вертикальное разрешение
    24.   biClrUsed         DWORD      ?; текущее число цветов графического движка
    25.   biClrImportant    DWORD      ?; количество важных цветов
    26. BITMAPINFOHEADER ENDS
    27. start:  mov ax,13h;установили видеорежим
    28.     int 10h
    29.     mov ax,1010h;установить один регистр цвета
    30.     mov bx,0FFh;номер цвета=0FF
    31.     mov dh,3Fh;яркость красного
    32.     mov cx,3F3Fh;яркость зеленого (CH) и синего (CL)
    33.     int 10h
    34.     xor bx,bx;то же самое для цвета=0
    35.     mov dx,bx
    36.     mov cx,bx
    37.     int 10h
    38.     push 0A000h;адрес видеобуфера
    39.     pop es
    40.     mov ax,3D00h    ;функция открытия, только чтение
    41.     mov dx,offset filename;имя bmp-файла
    42.     int 21h
    43.     mov bx,ax   ;запомнить номер файла
    44.     mov cx,sizeof BITMAPFILEHEADER;длина структуры
    45.     mov dx,offset buffer
    46.     mov ah,3Fh      ;читаем BITMAPFILEHEADER из bmp-файла
    47.     int 21h
    48.     mov di,dx
    49.         assume di: ptr BITMAPFILEHEADER
    50.         cmp [di].bfType,"MB" ;это действительно bmp-файл?
    51.         jnz exit        ;если нет, тогда выходим из программы
    52.     mov si,word ptr [di].bfOffBits;получаем смещение
    53.     add si,dx;от начала буфера до начала растра bmp-файла
    54.     add dx,sizeof BITMAPFILEHEADER
    55.     mov cx,word ptr [di].bfSize;получаем размер bmp-файла и минусуем из этого размера
    56.     sub cx,sizeof BITMAPFILEHEADER;структуру BITMAPFILEHEADER, которую уже прочитали
    57.     mov ah,3Fh      ;читаем в буфер остатки bmp-файла
    58.     int 21h
    59.     mov ah,3Eh      ;закрываем файл, он нам уже не нужен
    60.     int 21h
    61.     add di,sizeof BITMAPFILEHEADER
    62.         assume di: ptr BITMAPINFOHEADER
    63.     cmp [di].biBitCount,1 ;если файл не монохром
    64.         jnz exit ;завершаем программу
    65.         mov bp,word ptr [di].biWidth;ширина рисунка
    66.         add bp,31;делаем ее кратной 32. Откуда 32? (biWidth/8)/4 == biWidth/32.
    67. ;Ненулевой остаток от деления говорит о необходимости выравнивания
    68.         and bp,not 31
    69.         add word ptr [delta+2],bp;рассчитываем смещение для вывода строк - пример модификации программного кода
    70.     shr bp,3; запоминаем в регистре ВР ширину рисунка деленную на 8
    71.         mov dx,word ptr [di].biHeight; запоминаем в регистре DX высоту рисунка
    72.         imul di,dx,320;координаты левого нижнего угла рисунка на экране
    73. @@@:    mov cx,bp
    74. @@: lodsb
    75.         mov ah,al
    76.     rept 8;8 раз сдвигаем регистр АН и если есть единичка делаем AL=0FFh иначе AL=0
    77.         add ax,ax
    78.         db 0D6h;salc == sbb al,al
    79.         stosb;выводим содержимое регистра AL на экран
    80.         endm
    81.         loop @b
    82. delta: sub di,320;переходим на строку выше, вместо 320 тут будет другое значение
    83.     dec dx
    84.     jnz @@@
    85.     mov ah,0;ждем пока не нажмут любую клавишу
    86.     int 16h
    87. exit:   mov ax,3;устанавливаем текстовый режим
    88.     int 10h
    89.     ret;выходим из программы
    90. filename db "coon.bmp"
    91. buffer   db 0; последняя метка в СОМ-программе, после нее можно организовать буфер размером до 63 кбайт
    92. end start
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708

    Вывод монохромного рисунка на экран в VESA-режиме 640x480x256

    Код (ASM):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. org 100h
    6. BITMAPFILEHEADER STRUCT
    7.   bfType        WORD      ?
    8.   bfSize        DWORD      ?
    9.   bfReserved1   WORD      ?
    10.   bfReserved2   WORD      ?
    11.   bfOffBits     DWORD      ?
    12. BITMAPFILEHEADER ENDS
    13.  
    14. BITMAPINFOHEADER STRUCT
    15.   biSize            DWORD      ?
    16.   biWidth           DWORD      ?
    17.   biHeight          DWORD      ?
    18.   biPlanes          WORD       ?
    19.   biBitCount        WORD       ?
    20.   biCompression     DWORD      ?
    21.   biSizeImage       DWORD      ?
    22.   biXPelsPerMeter   DWORD      ?
    23.   biYPelsPerMeter   DWORD      ?
    24.   biClrUsed         DWORD      ?
    25.   biClrImportant    DWORD      ?
    26. BITMAPINFOHEADER ENDS
    27. start:  mov ax,4F02h
    28.         mov bx,101h;установка режима 640*480*256
    29.     int 10h
    30.     mov ax,1010h;установить один регистр цвета
    31.     mov bx,0FFh;номер цвета
    32.     mov dh,3Fh;яркость красного
    33.     mov cx,3F3Fh;яркость зеленого (CH) и синего (CL)
    34.     int 10h
    35.     xor bx,bx
    36.     mov dx,bx
    37.     mov cx,bx
    38.     int 10h
    39.     push 0A000h
    40.     pop es
    41.     mov ax,3D00h    ;функция открытия, только чтение
    42.     mov dx,offset filename;имя bmp-файла
    43.     int 21h
    44.     mov bx,ax   ;запомнить номер файла
    45.     mov cx,sizeof BITMAPFILEHEADER   ;длина записи
    46.     mov dx,offset buffer
    47.     mov ah,3Fh      ;функция чтения
    48.     int 21h
    49.     mov di,dx
    50.         assume di: ptr BITMAPFILEHEADER
    51.         cmp [di].bfType,"MB" ;bmp-файл?
    52.         jnz exit
    53.     mov si,word ptr [di].bfOffBits
    54.     add si,dx;offset buffer
    55.     add dx,sizeof BITMAPFILEHEADER
    56.     mov cx,word ptr [di].bfSize
    57.     sub cx,sizeof BITMAPFILEHEADER
    58.     mov ah,3Fh      ;функция чтения
    59.     int 21h
    60.     mov ah,3Eh      ;закрываем файл
    61.     int 21h
    62.     add di,sizeof BITMAPFILEHEADER
    63.         assume di: ptr BITMAPINFOHEADER
    64.     cmp [di].biBitCount,1 ;если файл не монохром
    65.         jnz exit ;завершаем программу
    66.         mov bp,word ptr [di].biWidth;берем ширину картинки
    67.         add bp,31
    68.         and bp,not 31;делаем ширину кратной 32
    69.         add word ptr delta0+2,bp;изменяем смещение для перехода на новую строку
    70.     shr bp,3;делим ширину на 8, так как в байте BMP информация о 8 пикселах
    71.         mov ax,word ptr [di].biHeight;делим высоту картинки
    72.     mov bx,0FFFFh/640;на высоту окна видеопамяти
    73.     xor dx,dx;чтобы знать с какого окна видеопамяти начинать вывод
    74.     div bx
    75.     mov word ptr delta1+1,dx;изменяем количество циклов для последнего окна
    76.     xor bx,bx;выбор окна видеопамяти
    77.     mov dx,ax;адрес окна видеопамяти в единицах гранулярности (от 0 до 4)
    78.     inc ax
    79.     imul di,ax,-256;установка начального смещения di
    80.     cmp di,-640    ;dx=0 di=-256, dx=1 di=-512, dx=2 di=-128
    81.     sbb ax,ax      ;dx=3 di=-384, dx=4 di=-640
    82.     and ax,640
    83.     add di,ax
    84. @3: mov cx,0FFFFh/640
    85. @2: mov ax,4F05h;управление доступом к видеопамяти
    86.         int 10h
    87. @1: push cx
    88.     mov cx,bp
    89. @@: lodsb
    90.         mov ah,al
    91.     rept 8   ;8 раз извлекаем по 1 биту и если бит равен 1 - делаем AL=0FF,
    92.         add ax,ax;а если бит равен 0 - делаем AL=0
    93.         db 0D6h  ;sbb al,al
    94.         stosb    ;пишем в видеопамять
    95.         endm
    96.         loop @b
    97. delta0: sub di,640;перемещеаемся на строку вверх
    98.     pop cx
    99.     loop @1
    100.     dec dx
    101.     jg @3; если dx > 0
    102. delta1: mov cx,0FFFFh
    103.     jns @2; если dx < 0  выходим из цикла
    104.     mov ah,0; ожидаем нажатия на любую клавишу
    105.     int 16h
    106. exit:   mov ax,3;восстанавливаем текстовый режим
    107.     int 10h
    108.     ret     ;выходим из программы
    109. filename db "coon.bmp";имя ВМР-файла
    110. buffer db 0;начало буфера и одновременно терминирующий символ для имени файла
    111. end start
     
    >Quiet Snow< и rococo795 нравится это.