Assembler - язык неограниченных возможностей


Вывод на экран через линейный кадровый буфер


; lfbfire.asm ; Программа, работающая с SVGA при помощи линейного кадрового буфера (LFB), ; демонстрирует стандартный алгоритм генерации пламени. ; Требуется поддержка LFB видеоплатой (или загруженный эмулятор univbe), ; для компиляции необходим DOS-расширитель ; .486p ; для команды xadd .model flat ; основная модель памяти в защищенном режиме .code assume fs:nothing ; нужно только для MASM _start: jmp short _main db "WATCOM" ; нужно только для DOS/4GW

; начало программы ; на входе обычно CS, DS и SS указывают на один и тот же сегмент с лимитом 4 Гб, ; ES указывает на сегмент с PSP на 100h байт, ; остальные регистры не определены _main: sti ; даже флаг прерываний не определен, cld ; не говоря уже о флаге направления

mov ax,0100h ; функция DPMI 0100h mov bx,100h ; размер в 16-байтных параграфах int 31h ; выделить блок памяти ниже 1 Мб jc DPMI_error mov fs,dx ; FS - селектор для выделенного блока

; получить блок общей информации о VBE 2.0 (см. главу 4.5.2) mov dword ptr fs:[0],'2EBV' ; сигнатура VBE2 в начало блока mov word ptr v86_eax,4F00h ; функция VBE 00h mov word ptr v86_es,ax ; сегмент, выделенный DPMI mov ax,0300h ; функция DPMI 300h mov bx,0010h ; эмуляция прерывания 10h xor есх,есх mov edi,offset v86_regs push ds pop es ; ES:EDI - структура v86_regs int 31h ; получить общую информацию VBE2 jc DPMI_error cmp byte ptr v86_eax,4Fh ; проверка поддержки VBE jne VBE_error movzx ebp,word ptr fs:[18] ; объем SVGA-памяти в EBP shl ebp,6 ; в килобайтах

; получить информацию о видеорежиме 101h mov word ptr v86_eax,4F01h ; номер функции INT 10h mov word ptr v86_ecx,101h ; режим 101h - 640x480x256 ; ES:EDI те же самые mov ax,0300h ; функция DPMI 300h - эмуляция mov bx,0010h ; прерывания INT 10h xor ecx,ecx int 31h ; получить данные о режиме jc DPMI_error cmp byte ptr v86_eax,4Fh jne VBE_error test byte ptr fs:[0],80h ; бит 7 байта атрибутов = 1 - LFB есть jz LFB_error

; построение дескриптора сегмента, описывающего LFB ; лимит mov eax,ebp ; видеопамять в килобайтах shl eax,10 ; теперь в байтах dec еах ; лимит = размер - 1 shr еах,12 ; лимит в 4-килобайтных единицах mov word ptr videodsc+0,ax ; записать биты 15-0 лимита shr еах,8 and ah,0Fh or byte ptr videodsc+6,ah ; и биты 19 - 16 лимита mov eax,ebp ; видеопамять в килобайтах shl eax,10 ; в байтах mov edx,dword ptr fs:[40] ; физический адрес LFB shld ebx,edx,16 ; поместить его в CX:DX, shld esi,eax,16 ; а размер - в SI:DI mov ax,800h ; и вызвать функцию DPMI 0800h int 31h ; отобразить физический адрес в линейный shrd edx,ebx,16 ; перенести полученный линейный адрес mov dx,cx ; из BS:CX в EDX mov word ptr videodsc+2,dx ; и записать биты 15-0 базы mov byte ptr videodsc+4,dl ; биты 23 - 16 mov byte ptr videodsc+7,dh ; и биты 31 -24 ; права mov bx,cs lar cx,bx ; прочитать права нашего сегмента and cx,6000h ; и перенести биты DPL or byte ptr videodsc+5,ch ; в строящийся дескриптор




Начало  Назад  Вперед