; pozn. v BIOS_strprn je asi nekde chyba IDEAL MODEL tiny ; konstanty VRamSeg=0B800h VRamOff=0 delkaradky=50h ; s touto konstantou pracuju jenom ze zacatku, pak jsem na ni nejak zapomnel getstr_maxdelka=31d DATASEG vram dW VRamOff znak: char dB 's' attr dB 07h num dB ? ad_code dB 2 ; ASCII/displej kod, 0-ASCII, 1-displej vp_attr dB 07h vp_vram dW 143d window_attr dB ? window_rolovani db 06h window_radku_k_odrolovani db 0 window_x1_sourad: window_x1 dB ? window_y1 dB ? window_x2_sourad: window_x2 dB ? window_y2 dB ? sourad: sloupec dB 79d radka dB 5d aseg dW ? aoff dW ? a1seg dW 0B821h a1off dW 5423h a2seg dW 0B800h a2off dW 6 a3seg dW 0B800h a3off dW 5 seekseg dW ? ; seek segment seekoff dW ? ; seek offset upravseg dW ? upravoff dW ? konst dB ? backupkonst dB ? ; zalozni konst menu dB 'MONITOR', 13, '-------', 13, 'p a1 a2 ... vypis pameti v ASCII (od pameti a1 do a2)', 13, 'd a1 a2 ... vypis pameti v displejovem kodu', 13, 'k a1 a2 b ... vlozeni konstanty b od a1 do a2', 13, 'c a1 a2 a3 ... kopirovani pameti (od a1 az a2 do a3 az ...)', 13, 'h ... help', 13, 'e ... konec', 13, 13, ':', 0 errorno dB 0 error0 dB 'Zadna chyba.', 0 error1 dB 'Chyba v adresaci pameti. Spravny tvar je segment:offset (napr. B800:0000)', 0 error2 dB 'Chtelo by to vybrat jednu z moznosti.', 0 error4 dB 'Spravny tvar je XXXX:XXXX XXXX:XXXX XX, kde X je cislo v hexa soustave.', 0 error5 dB 'Vlozeni konstanty hotovo.', 0 ;MONITOR ;------- ;p a1 a2 ... vypis pameti v ASCII (od pameti a1 do a2) ;d a1 a2 ... vypis pameti v displejovem kodu ;s a1 ... vkladani dat (od adresy a1) ;k a1 a2 b ... vlozeni konstanty b od a1 do a2 ;c a1 a2 a3 ... kopirovani pameti (od a1 az a2 do a3 az ...) ;h ... help ;e ... konec prikaz dB 31d DUP (' '), 0 ; vyhradi si pamet pro prikaz vpvdk_string1 dB ' Vypis pameti v displejovem kodu', 0 vpvdk_string2 dB ' F2 - Skok na adresu, F3 - Rezim uprav Esc - navrat do hl. nabidky', 0 vpvdk_string3 dB ' Adresa (segment:offset): ', 0 vpvdk_string4 dB ' Rezim uprav | Klavesy: sipky, Home, End, 0 az F - zmena hodnoty Esc - zpet', 0 vpvdk_string5 dB ' Rezim uprav | 0 az F - zmena hodnoty, Enter - provest zmenu Esc - zpet', 0 vpvak_string1 dB ' Vypis pameti v ASCII', 0 CODESEG STARTUPCODE ;EXITCODE MAIN_start: mov [window_attr], 07h mov [window_x1], 0 mov [window_y1], 0 mov [window_x2], 79d mov [window_y2], 24d call BIOS_define_window mov bx, offset menu call BIOS_strprn ; call BIOS_show_cursor ; zobrazi kurzor ;---- HLAVNI CYKLUS ---- MAIN_wait_for_choice: call PROG_BIOS_getstr ; PROG_ je jenom kvuli escapu mov bx, offset prikaz call PROG_parse_str jmp MAIN_wait_for_choice ;---- /HLAVNI CYKLUS ---- MAIN_error: ; podle cisla v [errorno] vypise ruznou chybovou hlasku cmp [errorno], 0 je MAIN_error_0 cmp [errorno], 1 je MAIN_error_1 cmp [errorno], 2 je MAIN_error_2 cmp [errorno], 4 ; chyba pri zadavani v menu (vlozeni konstanty) je MAIN_error_4 cmp [errorno], 5 je MAIN_error_5 jmp MAIN_end MAIN_error_0: mov bx, offset error0 call BIOS_strprn jmp MAIN_end MAIN_error_1: mov bx, offset error1 MAIN_error_1_vypis_pockej: mov [sloupec], 1 call BIOS_gotoxy call BIOS_strprn call BIOS_getchar jmp MAIN_start MAIN_error_2: mov [sloupec], 1 call BIOS_gotoxy mov bx, offset error1 call BIOS_strprn call BIOS_getchar mov bx, offset vpvdk_string2 call PROG_prekresli_dolni_pruh jmp PROG_vpvdk_wait_for_key MAIN_error_3: mov bx, offset error2 jmp MAIN_error_1_vypis_pockej MAIN_error_4: mov bx, offset error4 jmp MAIN_error_1_vypis_pockej MAIN_error_5: mov bx, offset error5 jmp MAIN_error_1_vypis_pockej MAIN_end: EXITCODE ;**************************************** PROG **************************************** ;-------------------------------------------- PROG_parse_str_jump_MAIN_start: jmp MAIN_start PROG_parse_str: mov [errorno], 1 mov al, [bx] ; do al da bx-ty znak retezce cmp al, 'e' ; menu - konec je MAIN_end cmp al, 'h' ; menu - help je PROG_parse_str_jump_MAIN_start cmp al, 's' ; menu - vkladani dat je PROG_parse_str_s cmp al, 'd' ; menu - vypis pameti v diplej. kodu je PROG_parse_str_d cmp al, 'p' ; menu - vypis pameti v ASCII kodu je PROG_parse_str_p cmp al, 'k' ; menu - vlozeni konstanty je PROG_parse_str_k cmp al, 'c' ; menu - kopirovani pameti je PROG_parse_str_e jmp MAIN_error_3 ; zadna z moznosti ret PROG_parse_str_s: jmp PROG_vkladani_dat PROG_parse_str_d: jmp PROG_vpvdk PROG_parse_str_p: jmp PROG_vpvak PROG_parse_str_k: mov [errorno], 4 jmp PROG_vlozeni_konstanty PROG_parse_str_e: jmp PROG_kopirovani_pameti PROG_parse_str_a1: call PROG_parse_str_seg mov [a1seg], dx ; ted bych mel mit v dx segment, tak ho soupnu do promenne a1seg call PROG_parse_str_off mov [a1off], dx ; ted bych mel mit v dx offset, tak ho soupnu do promenne a1off ret PROG_parse_str_a2: call PROG_parse_str_seg mov [a2seg], dx call PROG_parse_str_off mov [a2off], dx ret PROG_parse_str_a3: call PROG_parse_str_seg mov [a3seg], dx call PROG_parse_str_off mov [a3off], dx ret PROG_parse_str_konst: call PROG_parse_str_dalsi_znak cmp al, ' ' jne PROG_parse_str_error ; nacte jeden bajt do konstanty (konst) xor dx, dx mov cx, 2 ; chci jenom jeden bajt call PROG_parse_str_nacti_adresy_lib_pocet mov [konst], dl ret PROG_parse_str_seg: call PROG_parse_str_dalsi_znak cmp al, ' ' ; je tam mezera? jne PROG_parse_str_error ; neni tam, musi tam byt call PROG_parse_str_nacti_adresy ;nactu seg ret PROG_parse_str_off: call PROG_parse_str_dalsi_znak cmp al, ':' ; je tam dvojtecka? jne PROG_parse_str_error ; neni tam, musi tam byt call PROG_parse_str_nacti_adresy ;nactu off ret PROG_parse_str_dalsi_znak: inc bx ; posune ukazatel na retezec mov al, [bx] ; do al da bx-ty znak retezce ret ; pokracuje v parsovani PROG_parse_str_nacti_adresy: xor dx, dx ; pripravim si dx, pac tam vlozim a1seg a pak a1off mov cx, 4 ; budu pocitat znaky, a to 4, pac adresa je napr. B800 PROG_parse_str_nacti_adresy_lib_pocet: PROG_parse_str_dalsi_cislo: call PROG_parse_str_dalsi_znak ; nactu dalsi znak mov [char], al ; ted ocekavam cisla call PROG_asc2num ; prevede [char] na non-ASCII kod cmp [num], '?' ; probehl prevod? je PROG_parse_str_error ; neprobehl, vytiskne chybu shl dx, 4 ; posunu dx o jeden pulbajt add dl, [num] ; prictu do dl [num] loop PROG_parse_str_dalsi_cislo ; celkem 4x ret ;-------------------------------------------- ;-------------------------------------------- PROG_parse_str_error: jmp MAIN_error ;-------------------------------------------- ;-------------------------------------------- PROG_vkladani_dat: ; tak tohle delat nebudu, pac lepsi verze je zabudovana v vpvdk a vpvak call PROG_parse_str_a1 ; call PROG_parse_str_a2 ; call PROG_parse_str_a3 mov dx, [a1seg] mov es, dx mov bx, [a1off] mov al, [es:bx] mov [char], al call chrprnt ret ;-------------------------------------------- ;-------------------------------------------- ; Vypis pameti v displejovem kodu a v ASCII ; PROG_vpvdk_format_adresses: ; vstup: bx, dx ; vystup: bx, ax ; prevod do formatu XXXX:000X mov ax, bx ; FFFF shr ax, 4 ; 0FFF add ax, dx ; dx=[a1seg] xor bh, bh ; 00FF shl bl, 4 shr bl, 4 ; 000F ret PROG_vpvdk: mov [ad_code], 1 ; displejovy kod jmp PROG_vpa PROG_vpvak: mov [ad_code], 0 ; ASCII kod PROG_vpa: ; vypis adresy call PROG_parse_str_a1 call PROG_parse_str_a2 ; call BIOS_hide_cursor ; schova kurzor ; prevede a1 do spravneho formatu mov bx, [a1off] mov dx, [a1seg] mov [aoff], bx ; ulozi a1off do pracovni aoff mov [aseg], dx ; ulozi a1seg do pracovni aseg call PROG_vpvdk_format_adresses mov [a1off], bx mov [a1seg], ax PROG_vpvdk_from_main_menu: ; z hl. menu mov [errorno], 2 ; PROSTREDI ; nadefinuje okno mov [window_attr], 1Fh mov [window_y1], 0 mov [window_y2], 1 call BIOS_define_window ; vypise hlavicku cmp [ad_code], 1 ; ASCII mov bx, offset vpvdk_string1 je PROG_vpvdk_print_vpvdk_string1 mov bx, offset vpvak_string1 PROG_vpvdk_print_vpvdk_string1: call BIOS_strprn mov bx, offset vpvdk_string2 call PROG_prekresli_dolni_pruh mov [window_attr], 07h mov [window_y1], 1 mov [window_y2], 23 call BIOS_define_window ; /PROSTREDI PROG_vpvdk_format_again: ; nejdriv adresu a2 mov bx, [a2off] ; dosadi do bx a2off pred volanim PROG_vpvdk_format_adresses mov dx, [a2seg] ; dosadi do dx a2seg - || - call PROG_vpvdk_format_adresses mov [a2off], bx ; obracene, tedy do a2off bx mov [a2seg], ax ; a1seg do ax ; pak adresu a1 mov bx, [aoff] ; dosadi do bx aoff pred volanim PROG_vpvdk_format_adresses mov dx, [aseg] ; dosadi do dx aseg - || - call PROG_vpvdk_format_adresses mov [aoff], bx ; obracene, tedy do aoff bx mov [aseg], ax ; aseg do ax PROG_vpvdk_print_full_screen: mov [vram], 160d mov cx, 22 ; pocet radek PROG_vpvdk_print_line: push cx ; ulozim ; vytiskne jeden radek ; segment mov bx, [aseg] cmp bx, [a1seg] ; je tato adresa pocatecni adresou? jne PROG_vpvdk_neni_a1seg ; neni mov [attr], 04h PROG_vpvdk_neni_a1seg: cmp bx, [a2seg] ; je tato adresa konecovou adresou? jne PROG_vpvdk_neni_a2seg ; neni mov [attr], 04h PROG_vpvdk_neni_a2seg: ; nula pred segmentem mov [char], '0' call chrprnt mov al, bh call PROG_vpvdk_print_addr mov al, bl call PROG_vpvdk_print_addr ; dvojtecku mov [char], ':' call chrprnt ; offset mov bx, [aoff] mov al, bh call PROG_vpvdk_print_addr mov al, bl call PROG_vpvdk_print_addr ; mezera inc [vram] inc [vram] ; separator mov [char], '|' call chrprnt ; mezera inc [vram] inc [vram] ; hexa ; nacte z pameti mov ax, [aseg] mov es, ax mov bx, [aoff] mov cx, 16 ; 16 krat ; xor dx, dx ; vynuluju PROG_vpvdk_hexa_repeat: mov al, [es:bx] ; add [vram], 100d ; bude psat sloupec znaku vpravo ; sub [vram], dx ; korekce ; call chrprn ; vytiskne znak ; sub [vram], 100d ; vrati se na puvodni pozici ; add [vram], dx ; korekce call PROG_num2asc ; prevede hexa cislo na znak mov [char], ah call chrprnt mov [char], al call chrprnt ; mezera inc [vram] inc [vram] ; add dx, 4 ; korekce inc bx loop PROG_vpvdk_hexa_repeat ; separator mov [char], '|' call chrprnt mov [attr], 07h ; atribut zpet ; add [vram], 36d ; korekce ; mezera inc [vram] inc [vram] mov cx, 16d mov bx, [aoff] PROG_vpvdk_chars_repeat: mov al, [es:bx] cmp [ad_code], 0 ; vpv ascii? 0 - ASCII, 1 - displej jne PROG_vpvdk_displej_kod ; 1 - displej kod ; 0 - ASCII kod xor ah, ah ; vynuluju ah, abych mel v ax jen al cmp ax, 20h ; je znak v displejovem kodu? ; tady musi byt cmp ax, kdyz tam je jenom al, tak no nefunguje a nevim proc jns PROG_vpvdk_displej_kod ; ne mov [char], '.' ; ano, nahradim ho teckou jmp PROG_vpvdk_ASCII_kod PROG_vpvdk_displej_kod: mov [char], al ; ne PROG_vpvdk_ASCII_kod: call chrprnt inc bx loop PROG_vpvdk_chars_repeat ; mezera inc [vram] inc [vram] pop cx ; obnovim cmp cx, 0 je PROG_vpvdk_wait_for_key dec cx inc [aseg] ; posune segment jmp PROG_vpvdk_print_line ; vytisknu dalsi radku PROG_vpvdk_wait_for_key: ; ceka na klavesy call BIOS_getchar cmp ah, 49h ; Page up je PROG_vpvdk_page_up cmp ah, 51h ; Page down je PROG_vpvdk_page_down cmp ah, 48h ; Up arrow je PROG_vpvdk_up_arrow cmp ah, 50h ; Down arrow je PROG_vpvdk_down_arrow cmp ah, 4Dh ; Right arrow je PROG_vpvdk_right_arrow cmp ah, 4Bh ; Left arrow je PROG_vpvdk_left_arrow cmp ah, 47h ; Home je PROG_vpvdk_home cmp ah, 4Fh ; End je PROG_vpvdk_end cmp ah, 01h ; Escape je PROG_vpvdk_escape jmp PROG_vpvdk_wait_for_key_2nd_part PROG_vpvdk_escape: jmp MAIN_start ; na hlavni menu PROG_vpvdk_page_up: sub [aseg], 45d ; 1 stranka jmp PROG_vpvdk_print_full_screen PROG_vpvdk_page_down: add [aseg], 1d ; 1 stranka jmp PROG_vpvdk_print_full_screen PROG_vpvdk_up_arrow: sub [aseg], 23d ; 1 radka jmp PROG_vpvdk_print_full_screen PROG_vpvdk_down_arrow: sub [aseg], 21d ; 1 radka jmp PROG_vpvdk_print_full_screen PROG_vpvdk_right_arrow: sub [aseg], 22d ; 1 radka inc [aoff] cmp [aoff], 10h js PROG_vpvdk_right_arrow_jump inc [aseg] mov [aoff], 0 PROG_vpvdk_right_arrow_jump: jmp PROG_vpvdk_print_full_screen PROG_vpvdk_left_arrow: sub [aseg], 22d ; 1 radka cmp [aoff], 0 jne PROG_vpvdk_left_arrow_2 dec [aseg] mov [aoff], 0010h PROG_vpvdk_left_arrow_2: dec [aoff] jmp PROG_vpvdk_print_full_screen PROG_vpvdk_home: mov dx, [a1off] mov bx, [a1seg] mov [aoff], dx mov [aseg], bx jmp PROG_vpvdk_print_full_screen PROG_vpvdk_end: mov dx, [a2off] mov bx, [a2seg] sub bx, 16h mov [aoff], dx mov [aseg], bx jmp PROG_vpvdk_print_full_screen PROG_vpvdk_wait_for_key_2nd_part: ; vyhodnoti klavesy - 2. cast cmp ah, 3Ch ; F2 je PROG_vpvdk_jump_to_adress cmp ah, 3Dh ; F3 je PROG_vpvdk_rezim_uprav jmp PROG_vpvdk_wait_for_key PROG_vpvdk_jump_to_adress: ; prekresli dolni pruh mov [window_attr], 1Fh mov [window_y1], 24 mov [window_y2], 24 call BIOS_define_window mov bx, offset vpvdk_string3 call BIOS_strprn call BIOS_getstr ; ceka na adresu call PROG_vpvdk_parse_str_seekadr ; rozparsuje ji ; nastavi aktualni pozici na tuto adresu mov dx, [seekoff] mov bx, [seekseg] mov [aoff], dx mov [aseg], bx mov [sloupec], 0 mov [radka], 1 mov bx, offset vpvdk_string2 call PROG_prekresli_dolni_pruh jmp PROG_vpvdk_format_again PROG_vpvdk_rezim_uprav: ; prekresli dolni pruh mov bx, offset vpvdk_string4 call PROG_prekresli_dolni_pruh mov [radka], 1 mov [sloupec], 14d call BIOS_gotoxy ; nastavi kurzor na zacatecni pozici xor cx, cx ; vynuluje cx, pac ho budu pouzivat k zjistovani pozice kurzoru a k prepocitavani na adresu pameti call PROG_vpvdk_rezim_uprav_uprav_adresu PROG_vpvdk_rezim_uprav_wait_for_key: call PROG_vpvdk_rezim_uprav_show_adress ; provizorni, ale nakonec to tam necham, hodi se to call BIOS_getchar ; ceka na klavesu cmp ah, 01h ; Escape je PROG_vpvdk_rezim_uprav_return cmp ah, 0Ch ; cislice od 0-9 (ne na numericke klavesnici) js PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump cmp ah, 4Dh ; Right arrow je PROG_vpvdk_rezim_uprav_right_arrow cmp ah, 4Bh ; Left arrow je PROG_vpvdk_rezim_uprav_left_arrow jmp PROG_vpvdk_rezim_uprav_wait_for_key_2nd_part PROG_vpvdk_rezim_uprav_return: ; prekresli dolni pruh mov bx, offset vpvdk_string2 call PROG_prekresli_dolni_pruh mov [radka], 1 mov [sloupec], 0 call BIOS_gotoxy sub [aseg], 22d jmp PROG_vpvdk_print_full_screen PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump: jmp PROG_vpvdk_rezim_uprav_vloz_hodnotu PROG_vpvdk_rezim_uprav_right_arrow: cmp [sloupec], 59d jne PROG_vpvdk_rezim_uprav_posun_do_prava cmp [radka], 23d jne PROG_vpvdk_rezim_uprav_posun_do_prava_o_radek_niz ; presune kurzor na levy horni roh xor cx, cx mov [sloupec], 14d mov [radka], 1 call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_posun_do_prava_o_radek_niz: ; adresa mov cx, 0FFFFh ; kurzor mov [sloupec], 11d inc [radka] PROG_vpvdk_rezim_uprav_posun_do_prava: ; adresa inc cx call PROG_vpvdk_rezim_uprav_uprav_adresu ; kurzor add [sloupec], 3 call BIOS_gotoxy jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_left_arrow: cmp [sloupec], 14d jne PROG_vpvdk_rezim_uprav_posun_do_leva cmp [radka], 1 jne PROG_vpvdk_rezim_uprav_posun_do_leva_o_radek_vys ; presune kurzor na pravy dolni roh mov cx, 15d ; na konci radku mov [sloupec], 59d mov [radka], 23d call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_posun_do_leva_o_radek_vys: ; adresa mov cx, 16d ; na konci radku ; kurzor mov [sloupec], 62d dec [radka] PROG_vpvdk_rezim_uprav_posun_do_leva: ; adresa dec cx call PROG_vpvdk_rezim_uprav_uprav_adresu ; kurzor sub [sloupec], 3 call BIOS_gotoxy jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_wait_for_key_jump: jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump_2: jmp PROG_vpvdk_rezim_uprav_vloz_hodnotu PROG_vpvdk_rezim_uprav_wait_for_key_2nd_part: ; 2. cast rozpoznavani klaves cmp ah, 48h ; Up arrow je PROG_vpvdk_rezim_uprav_up_arrow cmp ah, 50h ; Down arrow je PROG_vpvdk_rezim_uprav_down_arrow cmp ah, 47h ; Home je PROG_vpvdk_rezim_uprav_home cmp ah, 4Fh ; End je PROG_vpvdk_rezim_uprav_end cmp al, 41h ; nepropusti nizsi nez 41h (ASCII) js PROG_vpvdk_rezim_uprav_wait_for_key_jump cmp al, 47h ; znaky A-F v ASCII js PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump_2 jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_up_arrow: cmp [radka], 1 jne PROG_vpvdk_rezim_uprav_up_arrow_nahoru mov [radka], 24d PROG_vpvdk_rezim_uprav_up_arrow_nahoru: dec [radka] call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_down_arrow: cmp [radka], 23d jne PROG_vpvdk_rezim_uprav_down_arrow_dolu mov [radka], 0 PROG_vpvdk_rezim_uprav_down_arrow_dolu: inc [radka] call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_home: mov [radka], 1d call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_end: mov [radka], 23d call BIOS_gotoxy call PROG_vpvdk_rezim_uprav_uprav_adresu jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_vloz_hodnotu: mov bx, offset vpvdk_string5 call PROG_prekresli_dolni_pruh dec [sloupec] call gotoxy inc [sloupec] mov [char], '0' call chrprnt_noattr ; zachova puvodni atributy ; vlozi puvodni hodnotu do konstanty (backupkonst) mov dx, [upravseg] mov es, dx mov bx, [upravoff] mov dl, [es:bx] mov [backupkonst], dl mov [char], al call chrprn_noattr ; zachova puvodni atributy call PROG_asc2num mov bl, [num] ; 0X mov [konst], bl PROG_vpvdk_rezim_uprav_vloz_hodnotu_dalsi_cislo: call BIOS_getchar cmp ah, 01h ; Escape je PROG_vpvdk_rezim_uprav_vloz_cislice_cancel cmp ah, 1Ch ; Enter je PROG_vpvdk_rezim_uprav_vloz_cislice_apply cmp ah, 0Ch ; cislice od 0-9 (ne na numericke klavesnici) js PROG_vpvdk_rezim_uprav_vloz_hodnotu_nacti_dalsi_cislo cmp al, 41h ; nepropusti nizsi nez 41h (ASCII) js PROG_vpvdk_rezim_uprav_vloz_hodnotu_dalsi_cislo cmp al, 47h ; znaky A-F v ASCII jns PROG_vpvdk_rezim_uprav_vloz_hodnotu_dalsi_cislo PROG_vpvdk_rezim_uprav_vloz_hodnotu_nacti_dalsi_cislo: sub [vram], 2 call chrprnt_noattr ; zachova puvodni atributy shl bl, 4 ; X0 mov [char], al call chrprn_noattr ; zachova puvodni atributy call PROG_asc2num add bl, [num] ; XX mov [konst], bl PROG_vpvdk_rezim_uprav_vloz_hodnotu_wait_for_key: call BIOS_getchar cmp ah, 01h ; Escape je PROG_vpvdk_rezim_uprav_vloz_cislice_cancel cmp ah, 0Ch ; cislice od 0-9 (ne na numericke klavesnici) js PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump_3 cmp ah, 1Ch ; Enter je PROG_vpvdk_rezim_uprav_vloz_cislice_apply cmp al, 41h ; nepropusti nizsi nez 41h (ASCII) js PROG_vpvdk_rezim_uprav_vloz_hodnotu_wait_for_key cmp al, 47h ; znaky A-F v ASCII js PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump_3 jmp PROG_vpvdk_rezim_uprav_vloz_hodnotu_wait_for_key PROG_vpvdk_rezim_uprav_vloz_hodnotu_jump_3: jmp PROG_vpvdk_rezim_uprav_vloz_hodnotu PROG_vpvdk_rezim_uprav_vloz_cislice_cancel: mov al, [backupkonst] mov [num], al sub [vram], 2 call PROG_vpvdk_print_addr mov bx, offset vpvdk_string4 call PROG_prekresli_dolni_pruh jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_vloz_cislice_apply: ; ulozi hodnotu do pameti mov ax, [upravseg] mov es, ax mov bx, [upravoff] mov al, [konst] mov [es:bx], al mov [num], al sub [vram], 2 call PROG_vpvdk_print_addr_noattr ; zmena ve vypisu pameti mov bh, 80d mov al, [radka] dec al mul bh add ax, 143d ; 63d+80d add ax, cx sal ax, 1 mov [vram], ax mov al, [konst] mov [char], al call chrprn_noattr ; zachova puvodni atributy ; /zmena ve vypisu pameti mov bx, offset vpvdk_string4 call PROG_prekresli_dolni_pruh jmp PROG_vpvdk_rezim_uprav_wait_for_key PROG_vpvdk_rezim_uprav_show_adress: push ax push bx push dx ; obnovi puvodni atribut ve vypisu ; zmeni pouze atribut mov ax, VRamSeg mov es, ax mov bx, [vp_vram] mov al, [vp_attr] mov [es:bx+1], al ; /obnovi puvodni atribut ve vypisu mov [vram], 140d ; segment mov bx, [upravseg] mov al, bh call PROG_vpvdk_print_addr_noattr mov al, bl call PROG_vpvdk_print_addr_noattr ; dvojtecku mov [char], ':' call chrprnt_noattr ; offset mov bx, [upravoff] mov al, bh call PROG_vpvdk_print_addr_noattr mov al, bl call PROG_vpvdk_print_addr_noattr ; zvyrazneni ve vypisu pameti mov bh, 80d mov al, [radka] dec al mul bh add ax, 143d ; 63d+80d add ax, cx sal ax, 1 mov [vram], ax mov [vp_vram], ax ; zmeni pouze atribut mov ax, VRamSeg mov es, ax mov bx, [vram] mov al, [es:bx+1] mov [vp_attr], al mov al, 1Eh mov [es:bx+1], al ; /zvyrazneni ve vypisu pameti pop dx pop bx pop ax ret PROG_vpvdk_rezim_uprav_uprav_adresu: push ax push bx push dx ; ulozi aseg a aoff do upravseg a upravoff xor ah, ah mov al, [radka] mov dx, [aseg] sub dx, 23d add dx, ax mov bx, [aoff] add bx, cx call PROG_vpvdk_format_adresses ; upravi adresu mov [upravoff], bx mov [upravseg], ax pop dx pop bx pop ax ret PROG_vpvdk_parse_str_seekadr: push ax push bx push cx push dx mov bx, offset prikaz dec bx call PROG_parse_str_nacti_adresy mov [seekseg], dx call PROG_parse_str_off mov [seekoff], dx pop dx pop cx pop bx pop ax ret PROG_vpvdk_print_addr: call PROG_num2asc mov [char], ah call chrprnt mov [char], al call chrprnt ret PROG_vpvdk_print_addr_noattr: call PROG_num2asc mov [char], ah call chrprnt_noattr mov [char], al call chrprnt_noattr ret ;-------------------------------------------- ;-------------------------------------------- PROG_vlozeni_konstanty: ; nevim jakeho typu je konstanta - uz vim, konstanta je typu byte call PROG_parse_str_a1 ; nacte prvni adresu call PROG_parse_str_a2 ; nacte druhou call PROG_parse_str_konst ; nacte konstantu (jeden bajt) ; prevede adresu a2 na spravny format mov dx, [a2seg] mov bx, [a2off] call PROG_vpvdk_format_adresses mov [a2seg], ax mov [a2off], bx ; prevede adresu a1 na spravny format mov dx, [a1seg] mov bx, [a1off] call PROG_vpvdk_format_adresses mov [a1seg], ax mov [a1off], bx ; vyplni pamet konstantou PROG_vlozeni_konstanty_znovu: cmp [a2seg], ax jne PROG_vlozeni_konstanty_vloz_dalsi_byte cmp [a2off], bx jne PROG_vlozeni_konstanty_vloz_dalsi_byte jmp PROG_vlozeni_konstanty_hotovo PROG_vlozeni_konstanty_vloz_dalsi_byte: mov es, ax mov dl, [konst] mov [es:bx], dl inc bx ; posune offset cmp bl, 10h js PROG_vlozeni_konstanty_neposunuj_segment inc ax ; posune segment xor bx, bx ; vynuluje offset PROG_vlozeni_konstanty_neposunuj_segment: jmp PROG_vlozeni_konstanty_znovu PROG_vlozeni_konstanty_hotovo: mov [errorno], 5 jmp MAIN_error ret ;-------------------------------------------- ;-------------------------------------------- PROG_kopirovani_pameti: call PROG_parse_str_a1 ; nacte prvni adresu (a1seg:a1off) call PROG_parse_str_a2 ; nacte druhou (a2seg:a2off) ; call PROG_parse_str_a3 ; nacte treti (a3seg:a3off) push ds si es di push [a1seg] pop ds ; push [a1off] ; pop si mov si, 0 push [a2seg] pop es ; push [a2off] ; pop di mov di, 0 ; mov cx, 100 movsw ; mov ax, [a1seg] ; mov ds, ax ; mov ax, [a1off] ; mov si, 0 ; mov ax, [a1seg] ; mov es, ax ; mov di, [a2off] ; mov di, 10 ; cld ; + ; mov cx, 100 ; db 66h ; rep movsw pop di es si ds ret ;-------------------------------------------- ;-------------------------------------------- ; prekresli dolni pruh ; vstup: bx - ukazatel na zacatek retezce PROG_prekresli_dolni_pruh: push dx mov dx, [offset sourad] mov [window_attr], 1Fh mov [window_y1], 24 mov [window_y2], 24 call BIOS_define_window call BIOS_strprn mov [offset sourad], dx call BIOS_gotoxy pop dx ret ;-------------------------------------------- ;-------------------------------------------- ; Prevede 2-mistne hexa cislo v AL do ASCII a ulozi do AX ; Vstup: al ; Vystup: ax PROG_num2asc: xor ah, ah ; 00XX shl ax, 4 ; 0XX0 shr al, 4 ; 0X0X cmp al, 0Ah ; je to cislice js PROG_num2asc_next ; je :-( add al, 7h PROG_num2asc_next: cmp ah, 0Ah js PROG_num2asc_cislice ; je :-) add ah, 7h PROG_num2asc_cislice: add ax, 3030h ; prevod do ASCII ret ;-------------------------------------------- ;-------------------------------------------- ; Prevede ASCII cislo (v promenne [char]) ; do ne-ASCII a dosadi ho do promenne [num], ; kdyz se to nepovede, dosadi do [num] '?' ; (otaznik v ASCII, cili 3F) ; PROG_asc2num: push ax xor ah, ah mov al, [char] cmp ax, 47h ; je to cislo vubec ASCII cislo? 47h je 'G' jns PROG_asc2num_other cmp ax, 41h ; ma to cislo v sobe znak A-F? jns PROG_asc2num_AF cmp ax, 3Ah ; je to cislo vubec ASCII cislo? 3Ah je ';', 39h je '9' jns PROG_asc2num_other cmp ax, 30h ; ma to cislo v sobe znak 0-9? jns PROG_asc2num_09 jmp PROG_asc2num_other ; neni to hexa cislo PROG_asc2num_AF: sub ax, 07h PROG_asc2num_09: sub ax, 30h mov [num], al jmp PROG_asc2num_end ; na konec PROG_asc2num_other: mov [num], '?' ; znak '?' (3F v ASCII) rika, ze se prevod nepovedl PROG_asc2num_end: pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Stejne jako BIOS_getstr, akorat reaguje na Esc. Pouzito v hlavnim menu. ; Vim, ze je to udelany blbe, ale funguje to PROG_BIOS_getstr: push ax push bx push cx push dx ; sipky mov bx, offset prikaz mov dx, bx ; sipky xor cx, cx ; budu pocitat znaky PROG_BIOS_getstr_nextchar: call BIOS_getchar cmp ah, 4Bh ; Sipka vlevo je PROG_BIOS_getstr_leftarrow cmp ah, 4Dh ; Sipka vpravo je PROG_BIOS_getstr_rightarrow cmp ah, 3Ah ; Nepropusti klavesy vyssi nez 3Ah jns PROG_BIOS_getstr_nextchar cmp ah, 0Fh ; Tabulator je PROG_BIOS_getstr_nextchar cmp ah, 01h ; Escape je PROG_BIOS_getstr_escape cmp ah, 0Eh ; Backspace je PROG_BIOS_getstr_backspace cmp ah, 1Ch ; Enter je PROG_BIOS_getstr_end ; kvuli nevkladani enteru do retezce prikaz cmp cx, getstr_maxdelka ; zkontroluj maximalni delku jns PROG_BIOS_getstr_nextchar ; moc velka inc cx mov [bx], al mov [char], al call BIOS_chrprnt inc bx inc dx ; sipky - (delka napsaneho retezce)++ jmp PROG_BIOS_getstr_nextchar PROG_BIOS_getstr_end: xor al, al mov bx, dx ; sipky mov [bx], al ; ukonci retezec nulou pop dx ; sipky pop cx pop bx pop ax ret PROG_BIOS_getstr_escape: cmp [ad_code], 2 jns PROG_BIOS_getstr_nextchar sub [aseg], 22d ; zadny posun radka jmp PROG_vpvdk_from_main_menu PROG_BIOS_getstr_leftarrow: cmp cx, 0 ; jde kurzor jeste posunovat? jz PROG_BIOS_getstr_nextchar ; nejde dec cx dec bx call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru dec [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru jmp PROG_BIOS_getstr_nextchar PROG_BIOS_getstr_rightarrow: cmp bx, dx ; zkontroluj akt. pozici s celkovou delkou retezce jns PROG_BIOS_getstr_nextchar ; moc velka inc cx inc bx call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru inc [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru jmp PROG_BIOS_getstr_nextchar PROG_BIOS_getstr_backspace: cmp cx, 0 ; jde kurzor jeste posunovat? jz PROG_BIOS_getstr_nextchar ; nejde dec cx dec bx ; posune ukazatel na retezec zpet dec dx ; sipky - (delka napsaneho retezce)-- call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru dec [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru mov [char], 0FFh ; nastavi znak na 0, coz je prazdne misto call BIOS_chrprn ; smaze timto znakem znak predchozi jmp PROG_BIOS_getstr_nextchar ;-------------------------------------------- ;**************************************** BIOS **************************************** ;-------------------------------------------- BIOS_define_window: push ax push bx push cx push dx mov cx, [offset window_x1_sourad] mov [offset sourad], cx call BIOS_gotoxy ; nastavi souradnice na zacatek okna mov ah, [window_rolovani] ; 06h - nahoru; 07h - dolu mov al, [window_radku_k_odrolovani] mov dx, [offset window_x2_sourad] mov bh, [window_attr] int 10h pop dx pop cx pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- BIOS_gotoxy: push ax push bx push dx mov ah, 02h xor bh, bh mov dx, [offset sourad] int 10h pop dx pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; vystup: dh - radek ; dl - sloupec ; ch - poc. linka kurzoru (0-1Fh) ; cl - konc. linka kurzoru (0-1Fh) ; BIOS_cursor_actpos: push ax push bx push cx push dx mov ah, 03h xor bh, bh int 10h ; mov [offset sourad], dx ; !!! TOHLE NEJDE !!! SICE TO ZE ZACATKU VYPADA, ZE JO, ALE PAK TO HAZE CHYBY mov [sloupec], dl mov [radka], dh pop dx pop cx pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- BIOS_chrprnt: push ax push bx mov ah, 0Eh mov al, [char] xor bh, bh int 10h pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- BIOS_chrprn: push ax push bx push cx mov ah, 0Ah mov al, [char] xor bh, bh mov cx, 1 int 10h pop cx pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Vytiskne ASCII zero string ; bx - offset retezec BIOS_strprn: push ax push bx push dx BIOS_strprn_nextchr: mov al, [bx] ; do al da bx-ty znak retezce cmp al, 0 je BIOS_strprn_end ; uz netiskni cmp al, 13 ; enter? jne BIOS_strprn_continue call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru mov dh, [radka] inc dh ; posune kurzor o jednu radku xor dl, dl mov [offset sourad], dx ; dosadi do souradnic - TAKHLE TO NEJDE, HAZE TO CHYBU, no, nakonec nevim, jak to ma byt spravne ; mov [sloupec], 0 ; takhle to musi byt ; mov [radka], dh ; takhle to musi byt call BIOS_gotoxy ; nastavi je inc bx ; nastavi ukazatel na dalsi znak jmp BIOS_strprn_nextchr BIOS_strprn_continue: mov [char], al call BIOS_chrprnt inc bx jmp BIOS_strprn_nextchr BIOS_strprn_end: pop dx pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Nacte retezec z klavesnice ukonceny kl. enter (1C) do retezce prikaz a ukonci ho nulou. ; Reaguje na Backspace a na levou a pravou sipku. ; ; dx - adresa+delka napsaneho retezce BIOS_getstr: push ax push bx push cx push dx ; sipky mov bx, offset prikaz mov dx, bx ; sipky xor cx, cx ; budu pocitat znaky BIOS_getstr_nextchar: call BIOS_getchar cmp ah, 4Bh ; Sipka vlevo je BIOS_getstr_leftarrow cmp ah, 4Dh ; Sipka vpravo je BIOS_getstr_rightarrow cmp ah, 3Ah ; Nepropusti klavesy vyssi nez 3Ah jns BIOS_getstr_nextchar cmp ah, 0Fh ; Tabulator je BIOS_getstr_nextchar cmp ah, 01h ; Escape je BIOS_getstr_nextchar cmp ah, 0Eh ; Backspace je BIOS_getstr_backspace cmp ah, 1Ch ; Enter je BIOS_getstr_end ; kvuli nevkladani enteru do retezce prikaz cmp cx, getstr_maxdelka ; zkontroluj maximalni delku jns BIOS_getstr_nextchar ; moc velka inc cx mov [bx], al mov [char], al call BIOS_chrprnt inc bx inc dx ; sipky - (delka napsaneho retezce)++ jmp BIOS_getstr_nextchar BIOS_getstr_end: xor al, al mov bx, dx ; sipky mov [bx], al ; ukonci retezec nulou pop dx ; sipky pop cx pop bx pop ax ret BIOS_getstr_leftarrow: cmp cx, 0 ; jde kurzor jeste posunovat? jz BIOS_getstr_nextchar ; nejde dec cx dec bx call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru dec [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru jmp BIOS_getstr_nextchar BIOS_getstr_rightarrow: cmp bx, dx ; zkontroluj akt. pozici s celkovou delkou retezce jns BIOS_getstr_nextchar ; moc velka inc cx inc bx call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru inc [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru jmp BIOS_getstr_nextchar BIOS_getstr_backspace: cmp cx, 0 ; jde kurzor jeste posunovat? jz BIOS_getstr_nextchar ; nejde dec cx dec bx ; posune ukazatel na retezec zpet dec dx ; sipky - (delka napsaneho retezce)-- call BIOS_cursor_actpos ; zjisti aktualni pozici kurzoru dec [sloupec] ; zmensi sloupec o 1 call BIOS_gotoxy ; nastavi pozici kurzoru mov [char], 0FFh ; nastavi znak na 0, coz je prazdne misto call BIOS_chrprn ; smaze timto znakem znak predchozi jmp BIOS_getstr_nextchar ;-------------------------------------------- ;-------------------------------------------- ; Ceka na jeden znak z klavesnice a vlozi jeho ASCII hodnotu ; do al a scan kod do ah BIOS_getchar: mov ah, 00h int 16h ret ;-------------------------------------------- ;-------------------------------------------- ; Schova kurzor BIOS_hide_cursor: push ax push cx mov ah, 01h mov ch, 20h mov cl, 0h int 10h pop cx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Zobrazi kurzor BIOS_show_cursor: push ax push cx mov ah, 01h mov ch, 05h mov cl, 05h int 10h pop cx pop ax ret ;-------------------------------------------- ;**************************************** JINE **************************************** ;-------------------------------------------- ; Vytiskne ASCII zero string ; bx - offset retezec strprn: push ax xor ah, ah nextchr:mov al, [bx] ;do al da bx-ty znak retezce cmp al, 0 je endstr cmp al, 13 ; enter? jne str_continue mov al, delkaradky sub al, ah ; pocet do konce radky xor ah, ah sal ax, 1 ; ax*2 add [vram], ax xor ah, ah ; nova radka, tzn. nulty znak inc bx jmp nextchr str_continue: inc ah ; dalsi znak mov [char], al call chrprnt inc bx jmp nextchr endstr: pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Vytiskne na pozici [vram] jeden znak chrprn: push ax push bx push es mov ax, VRamSeg mov es, ax mov bx, [vram] mov ax, [offset znak] mov [es:bx], ax pop es pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Vytiskne na pozici [vram] jeden znak a ; posune na vedlejsi pozici chrprnt:call chrprn inc [vram] inc [vram] ret ;-------------------------------------------- ;-------------------------------------------- ; Stejne jako chrprn, akorat zachovava puvodni atributy chrprn_noattr: push ax push bx push es mov ax, VRamSeg mov es, ax mov bx, [vram] mov al, [char] mov [es:bx], al pop es pop bx pop ax ret ;-------------------------------------------- ;-------------------------------------------- ; Stejne jako chrprnt, akorat zachovava puvodni atributy chrprnt_noattr: call chrprn_noattr inc [vram] inc [vram] ret ;-------------------------------------------- ;-------------------------------------------- gotoxy: push ax push bx mov [vram], 0 mov al, [radka] xor ah, ah mov bh, delkaradky mul bh ;ax=al*bh xor bh, bh mov bl, [sloupec] add ax, bx sal ax, 1 mov [vram], ax pop bx pop ax ret ;-------------------------------------------- END