[org 100h] [segment .text] ; alokovani pameti mov AX, CS ; nejprv alokuju pamet mov ES, AX mov AH, 4Ah mov BX, 4000 ; 64000 / 16 = 4000 paragrafu int 21h jnc _stinram ; alokovano? ret ; ne, tak konec _stinram: mov AX, CS ; jo, tak nastavim promenou stinram add AX, 4096 mov [stinram], AX ; pritomnost mysi mov AX, 0 ; kouknem na mysku int 33h test AX, AX ; tak je tu? jnz _grmod ; jo je ret ; neni, tak konec ; puvodni graf. mod _grmod: mov AH, 0Fh ; zjistime puvodni graf. mod int 10h mov [grmod], AL ; ulozime ho mov AX, 0013h ; nastavim 320x200x256 int 10h ; nastaveni mysi mov AX, 7 ; max. a min. souradnice xor CX, CX mov DX, 321-2*R int 33h inc AX mov DX, 201-2*R int 33h ; cteni prikazoveho radku mov SI, 93 ; nacteme command line mov BX, filename ; potrebujeme nastavit jmeno mov CX, 8 ; soubor ma max 8 znaku jmena a koncovku .tga _nextchar: lodsb ; nactu znak cmp AL, ' ' ; je to prazdny? jz _finish ; jo, tak to bude uz cely jmeno mov [BX], AL ; ne tak pripiseme znak jmena inc BX ; a nastavime na dalsi znak loop _nextchar ; a znova _finish: mov EAX, '.tga' ; pripiseme koncovku mov [BX], EAX ; pokus o otevreni souboru mov AX, 3d00h ; budeme otevirat jen pro cteni mov DX, filename ; tady mame nacteny jmeno int 21h jnc _fileopen ; podarilo se otevrit? ret ; ne, tak konec (asi spatny jmeno) _fileopen: mov BX, AX ; jo, tak ulozime handle souboru ; cteni ze souboru mov AX, 4200h ; nastavime sluzbu, v BX je ulozen handle, od zacatku xor CX, CX mov DX, 18 ; offset 18, tam zacina paleta int 21h push DS ; budeme nahravat paletu ze souboru mov AX, [stinram] ; zatim si to dame do virtual screenu, protoze pak to stejne smazem mov DS, AX xor DX, DX mov AH, 3fh ; nacteme celou paletu do stinove RAM mov CX, 768 int 21h xor AX, AX xor SI, SI mov CX, 256 ; ma to 256 barev _palnext: mov DX, 03c8h ; port adres grafarny mov AL, AH ; index barvy out DX, AL inc DX ; port data grafarny inc AH mov AL, [DS:SI+2] ; R slozka vynasobena 4 shr AL, 2 ; delim 4 protoze to je inteligentne ulozeny ve 256 out DX, AL push AX ; ulozime AH (index barvy) lodsw ; nactem do AH G a do AL B push AX ; ulozime AH (B) mov AL, AH ; a odesleme G shr AL, 2 out DX, AL pop AX ; obnovime AH (B) shr AL, 2 out DX, AL ; a odesleme inc SI pop AX ; obnovim AH (index barvy) loop _palnext ; nastavime dalsi barvu ; cteni obrazku do stinove video RAM xor DX, DX mov AH, 3fh mov CX, 64000 int 21h mov AH, 3eh ; a uzavreme soubor int 21h pop DS ; a obnovime DS call MAPbuild ; zavolame proceduru, ktera vytvori mapu lupy ; cteni polohy mysi _prekresli: mov AX, 3h ; nacteme polohu mysi int 33h mov BX, CX ; ulozime si x do BX push BX ; ulozime si souradnice push DX call _uloz_vyrez ; musime si ulozit vyrez, ktery budeme lupit call _lupa ; vylupime call _flip ; a prekreslime, co mame ve virt scr do graf. pam _kontrola: mov AX, 0bh ; nacteme relativni zmenu int 33h test CX, CX ; pohnul uzivatel mysi v X? jnz _pohnul ; jo tak to musime prekreslit test DX, DX ; pohnul uzivatel mysi v Y? jnz _pohnul ; jo, prekreslit mov ah, 6 mov dl, 0ffh int 21h ; zmackl uzivatel klavesu? jnz _konec ; jo tak budeme koncit jmp _kontrola ; uzivatl nic nezmack ani nepoh mysi, tak se podivame znova, jestli neco neudelal _pohnul pop DX ; uzivatel pohnul mysi, tak vratime souradnice, co jsme lupili pop BX call _obnov_vyrez ; prekreslime zpet ten vyrez co sme si ulozili jmp _prekresli ; znova prekreslime lupu _konec: pop DX ; uzivatel neco zmacknul, tak si vybereme registry, co sou ulozeny pop BX xor AH, AH ; obnovime puvodni grafickej rezim mov AL, [grmod] int 10h ret ; a ukoncime program ; okopirovani stinove video RAM do video RAM _flip: push DS ; prekreslime virt screen do video ram push word 0A000h pop ES ; ES zacatek video ram mov DS, [stinram] ; DS zacatek virt screen xor DI, DI xor SI, SI mov CX, 32000 ; pekne to presypeme po dw rep movsw ; mame toho 32000 pop DS ; obnovime DS ret ; ulozeni vyrezu z originalniho obrazku do promenne vyrez, od souradnice BX, DX _uloz_vyrez: push DS push DX push BX mov SI, DX ; zjistime zacatek vyrezu shl DX, 8 ; 2^8 = 256 shl SI, 6 ; 2^6 = 64 add SI, DX ; y*320 add SI, BX ; +x push DS ; do ES dame data segment pop ES push word [stinram] ; do DS zacatek virt screenu pop DS mov DI, vyrez ; budeme presypavat do promenny mov CX, 2*R-1 ; velikost mapy y _uloz_dalsi: push CX mov CX, 2*R-1 ; velikost mapy x rep movsb ; presypeme po bytech protoze nevime, jak to bude velky add SI, 321-2*R ; skocime na dalsi radek ve virt screenu pop CX loop _uloz_dalsi ; a deme na dalsi radek pop BX pop DX pop DS ret ; obnoveni puvodniho obrazku pomoci obsahu promenne vyrez _obnov_vyrez: push DS push DX push BX mov DI, DX ; zjistime zacatek vyrezu shl DX, 8 ; 2^8 = 256 shl DI, 6 ; 2^6 = 64 add DI, DX ; y*320 add DI, BX ; +x push word [stinram] ; z promene vyrez obnovime do stinove RAM v ES pop ES mov SI,vyrez mov CX, 2*R-1 ; to samy jako pri ukladani _obnov_dalsi: push CX mov CX, 2*R-1 rep movsb add DI, 321-2*R pop CX loop _obnov_dalsi pop BX pop DX pop DS ret ; efekt lupy - z vyrezu do stinove video RAM _lupa: push DX push BX mov DI, DX ; zjistime zacatek vyrezu shl DX, 8 ; 2^8 = 256 shl DI, 6 ; 2^6 = 64 add DI, DX ; y*320 add DI, BX ; +x push word [stinram] ; do ES zacatek virt screenu pop ES mov SI, map mov BX, vyrez mov CX, 2*R-1 _lupa_y: push CX mov CX, 2*R-1 _lupa_x: lodsw ; nacteme z mapy offset add BX, AX ; pripocteme ho - kam se ma posunout mov AL, [DS:BX] ; zjistime ten pixel stosb ; a zapiseme ho loop _lupa_x add DI, 321-2*R ; a udelam to pro dalsi radku pop CX loop _lupa_y pop BX pop DX ret ; rutina pro vytvoreni mapy lupy MAPbuild mov AX, DS ; tak tohle sem uspesne rejpnul z netu mov ES, AX mov BX, 1-R mov SI, R*R mov DI, map mov BP, -2*R*(R-1) nok mov CX, 1-R nol mov AX, CX imul CX push AX mov AX, BX imul BX pop DX add AX, DX cmp AX, SI jc nor mov AX, BX push CX jmp short nos nor mov DX, 65536*(M-N)/M/N mul DX mov AX, DX add AX, R*R/M push AX imul CX idiv SI mov DX, AX pop AX push DX imul BX idiv SI nos mov AH, 2*R-1 imul AH pop DX add AX, DX push AX sub AX, BP stosw pop BP inc CX cmp CL, R jl nol inc BX cmp BL, R jl nok ret R equ 31 ; parametry lupy N equ 2 M equ 3 filename db ' ' ; jmeno souboru grmod db 0 ; puvodni grafiky mod vyrez resb (2*R-1)*(2*R-1) ; ulozeni vyrezu pred zvetsenim map resw (2*R-1)*(2*R-1) ; vlastni mapa, ze ktere pocitame zvetseni stinram dw 0 ; zacatek virtual screenu