Эффект кипящей лавы Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 369 байт до 234 байт Код (ASM): ; masm dos com # .model tiny .686 .code org 100h WIDTH_SCREEN equ 320 HEIGHT_SCREEN equ 200 SCREENSIZE equ WIDTH_SCREEN*HEIGHT_SCREEN MEMBLOCKSIZE equ SCREENSIZE/16 IMPUT_STATUS_0 equ 3DAh ;регистр статуса ввода 0 VGA_SEGMENT equ 0A000h temp1 equ word ptr [bp-2] temp2 equ word ptr [bp-4] start: mov sp, 0A80h mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK) mov bx, 0A8h; ES = segment address of block to change int 21h; BX = new size in paragraphs enter 4,0 ;RANDOMIZE--------------------------------------- push 0 pop es ;получаем случайное значение rdtsc mov dword ptr temp1,eax ;------------------------------------------------------- mov ax,13h int 10h ; - VIDEO - SET VIDEO MODE ;setcolortable------------------------------------ ;Палитру надо выставить вот так: ;Номер цвета: 0 255 ;Цвет: красный -> желтый ; for(short k=0;k<=255;k++) ; setrgbpalette(k,63,k/4,0); mov cx,256 xor ax,ax xor bx,bx mov dx, 3C8h out dx, al inc dx @@: mov al,63 out dx,al;красный mov al,bl sar al,2 out dx,al;зеленый mov al,0 out dx,al;синий inc bx loop @b ;setcolortable----------------------------------- mov bx,MEMBLOCKSIZE mov ah,48h; ALLOCATE MEMORY int 21h; BX = number of 16-byte paragraphs desired mov fs,ax;fs=screen ;CLEARBLOCK----------------------------------- mov es,ax xor eax,eax xor di,di mov cx,SCREENSIZE/4;16000 rep stosd ;fillscreen------------------------------------ mov di,WIDTH_SCREEN+1 mov dx,HEIGHT_SCREEN-2 a0: mov si,WIDTH_SCREEN-2 @@: mov ax, temp2 mov cx, temp1 shld ax,cx,8 shl cx,8 rcr ax,1 rcr cx,1 add temp1,cx adc ax,temp2 add temp1,25321 adc ax,13849 mov temp2,ax stosb dec si jnz @b add di,2 dec dx jnz a0 ;lavascreen--------------------------------------------- ;screen[x][y]=(screen[x-1][y]+screen[x][y+1]+ ; screen[x][y-1]+screen[x+1][y])/4+number; ;От числа number зависит интенсивность "кипения", чем оно больше, ;тем интенсивней "кипит" лава. a1: push fs pop es;es=screen mov di,WIDTH_SCREEN+1 mov si,HEIGHT_SCREEN-2 a2: mov bx,WIDTH_SCREEN-2 @@: movzx ax,byte ptr es:[di-WIDTH_SCREEN] movzx cx,byte ptr es:[di-1] add ax,cx movzx cx,byte ptr es:[di+1] add ax,cx movzx cx,byte ptr es:[di+WIDTH_SCREEN] add ax,cx shr ax,2 add ax,2 stosb dec bx jnz @b add di,2 dec si jnz a2 ;copyvirtualscreen------------------------------- mov dx,IMPUT_STATUS_0 WaitVerticalSync:in al,dx test al,8 jz WaitVerticalSync WaitNotVerticalSync:in al,dx test al,8 jnz WaitNotVerticalSync mov cx,SCREENSIZE/4 xor si,si xor di,di push VGA_SEGMENT pop es rep movs dword ptr es:[di],fs:[si] ;----------------------------------- mov es,cx;es=0 mov ax,es:[41Ah];указатель на логическое начало буфера клавиатуры sub ax,es:[41Ch];указатель на логический конец буфера клавиатуры jz a1;если АХ не равно нулю, значит на клавиатуру нажали exit: mov ax,3 int 10h ; - VIDEO - SET VIDEO MODE int 20h end start Теперь применим наши знания на практике, красный оттенок будут меняться пилообразно от 0 до 63 и от 63 до 0 Код (ASM): mov cx,255 m0: mov dx,3C8h mov al,cl mov ah,cl test al,40h jz @f not ah @@: out dx,ax inc dx mov al,0 out dx,al out dx,al dec cx jnz m0 пусть "лава" заполнит не весь экран, а ограниченную область 64х120, Код (ASM): ; masm dos com # .model tiny .code .386 org 100h SCREEN_WIDTH equ 320 SCREEN_SQR equ 64 start: mov ax,13h int 10h push 0A000h pop es push 0 pop ds mov cx,255 m0: mov dx,3C8h mov al,cl mov ah,cl test al,40h jz @f not ah @@: out dx,ax inc dx mov al,0 out dx,al out dx,al dec cx jnz m0 M2: mov di,140;начало квадрата по формуле di = y * 320 + x mov cx,120;высота M4: push cx mov cl,SCREEN_SQR;ширина @@: push cx xor dx,dx movzx ax,byte ptr es:[di-1] add al,es:[di+1] adc ah,0 add al,es:[di-SCREEN_WIDTH] adc ah,0 add al,es:[di+SCREEN_WIDTH] adc ah,0 shr ax,2 add ax,2 stosb pop cx loop @b add di,SCREEN_WIDTH-SCREEN_SQR pop cx loop M4 mov ax,ds:[41Ah] sub ax,ds:[41Ch] jz M2 mov ax,3 int 10h ret ;выход из программы end start наслаждаемся результатом стоит уменьшить или увеличить величину SCREEN_WIDTH-SCREEN_SQR на единичку и мы получаем из прямоугольника параллелограмм Код (ASM): ; masm dos com # .model tiny .code .386 org 100h SCREEN_WIDTH equ 320 SCREEN_SQR equ 64 start: mov ax,13h int 10h push 0A000h pop es push 0 pop ds mov cx,255 m0: mov dx,3C8h mov al,cl mov ah,cl test al,40h jz @f not ah @@: out dx,ax inc dx mov al,0 out dx,al out dx,al dec cx jnz m0 M2: mov di,140;начало квадрата по формуле di = y * 320 + x mov cx,120;высота M4: push cx mov cl,SCREEN_SQR;ширина @@: push cx xor dx,dx movzx ax,byte ptr es:[di-1] add al,es:[di+1] adc ah,0 add al,es:[di-SCREEN_WIDTH] adc ah,0 add al,es:[di+SCREEN_WIDTH] adc ah,0 shr ax,2 add ax,2 stosb pop cx loop @b add di,SCREEN_WIDTH-SCREEN_SQR + 1 pop cx loop M4 mov ax,ds:[41Ah] sub ax,ds:[41Ch] jz M2 mov ax,3 int 10h ret; выход из программы end start Код (ASM): ; masm dos com # .model tiny .code .386 org 100h SCREEN_WIDTH equ 320 SCREEN_SQR equ 64 start: mov ax,13h int 10h push 0A000h pop ds push 0 pop es mov cx,255 m0: mov dx,3C8h mov al,cl mov ah,cl test al,40h jz @f not ah @@: out dx,ax inc dx mov al,0 out dx,al out dx,al dec cx jnz m0 M2: mov si,1 mov bx,340;начало квадрата по формуле bx = y * 320 + x y=1 x=20 mov bp,257;SCREEN_WIDTH-SCREEN_SQR + 1 call crest neg si mov bp,383; 1*320 + 63 mov bx,604;=1*320 + 284 call crest mov ax,es:[41Ah] sub ax,es:[41Ch] jz M2 ;;проверяем не нажата ли клавиша mov ax,3;устанавливаем текстовый режим int 10h ret ;и выходим из программы crest proc mov cx,200;высота M4: push cx mov cl,SCREEN_SQR;ширина @@: push cx movzx ax,byte ptr [bx-1] add al,[bx+1] adc ah,0 add al,[bx-SCREEN_WIDTH] adc ah,0 add al,[bx+SCREEN_WIDTH] adc ah,0 shr ax,2 add ax,2 mov [bx],al add bx,si pop cx loop @b add bx,bp pop cx loop M4 ret crest endp end start а теперь заглянем сюда