  ; Procedura read nacita cislo z klavesnice
    ; a vrati ho v registri AX
    ; Pouziva Odriadkuj
     
    Read proc
    LOCAL NacitanyRetazec:byte:12, PomocnaPremenna:word:1 = symbol ;Deklarujeme dve lokalne premenne
            push bp
            mov bp, sp
            sub sp, symbol
           
            pusha
            push ds
            mov ax,ss
            mov ds,ax
     
            mov NacitanyRetazec, 10 ;Dlzka nacitavaneho retazca
            mov ah, 0Ah
            lea dx, NacitanyRetazec
        int 21h
           
            call Odriadkuj
           
            mov di, 2       ;Retazec budeme prechádzať od 2 znaku (prve dva neobsahuju zadany text
            xor ax, ax
            xor dx, dx
            mov cx, 10      ;Pri prevádzaní násobime císlom 10
     
            SpracujNacitanyZnak:
                    mov dl, [NacitanyRetazec+di]
                    inc di
                    cmp dl,0Dh                                              ;Bol enter?
                    jz SpracujZnamienkoCisla
     
                    cmp dl,'-'                                              ;Bolo minusko?
                    jz SpracujNacitanyZnak
     
                    and dl,00001111b                                ;ASCII kod znaku prevedie na číslo
                    movzx bx, dl
                    mul cx
                    add ax, bx
                       
                    jmp SpracujNacitanyZnak
     
            SpracujZnamienkoCisla:
                    cmp [NacitanyRetazec+2], '-'    ;Porovnáme prvý znak v nacitanom retazci zo "-"
                    jnz KoniecReadProcedury
                    neg ax                                                  ;Urobíme dvojkovy doplnok cisla (tj spravime z neho zaporne)
            KoniecReadProcedury:
                    mov PomocnaPremenna, ax
                    pop ds
                    popa
                    mov ax, PomocnaPremenna
                    mov sp, bp
                    pop bp
                    ret
    Read ENDP
     
    ; Write procedura
    ; ax vstupny parameter, cislo ktore sa ma vypisat
    Write proc
            pusha
           
            mov cx, 10
            xor di, di                      ;di budeme pouzivat na pocet cislic v danom císle, aby sme vedeli kolko cisel sme dali do zasobnika
            xor dx, dx
            cmp ax, 0
            jnl PocitajCislicu      ;Pokial nieje ax zaporne skoc na navestie PocitajCislicu
            push ax
            mov ah, 2                      
            mov dl,'-'                    
            int 21h                         ;Vypíšeme -
            pop ax
            xor dx, dx
            neg ax
           
           
            PocitajCislicu:
                    div cx                  ;Vydelí císlo (v dx:ax)
                    push dx                 ;Zvyšok si odložíme do zásobnika
                    xor dx, dx
                    inc di
                    cmp ax, 0               ;Porovnáme vydelené císlo s nulou (už dalej nieje potrebne spracovavat)
                    jnz PocitajCislicu
                   
            mov cx, di
           
            mov ah, 2
            WriteCislica:
                    pop dx
                    or dl,110000b
                    int 21h                 ;Vypiseme ju
            loop WriteCislica
           
            popa
            ret
    Write ENDP
     
     
    ; Procedúra Odriadkuj
    ; Vypíse \r\n tj odriadkuje
    Odriadkuj proc
            push ax
            push dx
           
            mov ah,2                ;Sluzba 2 na vypis znaku
            mov dl, 0Dh            
            int 21h
                       
            mov dl, 0Ah
            int 21h
           
            pop dx
            pop ax
     
            ret
    Odriadkuj ENDP
     
    ; Procedura VypisTabulator
    ; Vypise tabulator
    ; Vhodné pri maticiach a podobne
    VypisTabulator proc
            push ax
            push dx
           
            mov ah,2                ;Sluzba 2 na vypis znaku
            mov dl, '   '
            int 21h
           
            pop dx
            pop ax
     
            ret
    VypisTabulator ENDP
     
    ; Procedura na vytvorenie prazdneho subru
    ; pokial subor existuje tak ho vyprazdni
    ; DX offset mena/cesty k súboru
    VytvorSubor proc
            push cx
            push ax
            xor cx,cx       ;Vynulujeme cx - vytvarame obycajny subor
            mov ah,3Ch    
            int 21h
           
            mov FileHandler, ax     ;Ulozime si file handler do premennej ktorá je definovaná v hlavnom programe
            pop ax
            pop cx
            ret
    VytvorSubor ENDP
     
    ; Procedura na otvorenie suboru
    ; DX offset mena/cesty k súboru
    OtvorSubor proc
            push ax
            mov al, 2
            mov ah,3Dh    
            int 21h
           
            mov FileHandler, ax     ;Ulozime si file handler do premennej ktorá je definovaná v hlavnom programe
            pop ax
            ret
    OtvorSubor ENDP
     
    ; Procedura ZatvorSubor
    ; Zatvorí subor
    ; Handler pouziva z FileHandler premennej
     
    ZatvorSubor proc
            push bx
            push ax
           
            mov bx, FileHandler
            mov ah,3Eh
            int 21h
           
            pop ax
            pop bx
            ret
    ZatvorSubor ENDP
     
    ; Procedura ZapisBajt
    ; Zapise jeden bajt do suboru
    ; dl - kod znaku na zapis
    ZapisBajt proc
    LOCAL Znak:byte:1 = symbol ;Deklarujeme lokalnu premennu
     
            push bp
            mov bp, sp
            sub sp, symbol
     
            push ax
            push bx
            push cx
            push dx
           
            mov bx, FileHandler             ;Do bx skopirujeme file handler
                                                            ;Musime to spravit skôr ako zmeníme ds
                                                           
            push ds
            mov ax,ss
            mov ds,ax
           
            mov Znak, dl                    ;Do loklakne premennej znak vlozime znak na zapis (dl)
            mov cx, 1                               ;Do cx dame 1 - ideme zapisovat len jeden znak
            lea dx, Znak                    ;Do dx dáme adresu kde je znak na zapis
            mov ah,40h            
            int 21h
           
            pop ds
            pop dx
            pop cx
            pop bx
            pop ax
           
            mov sp, bp
            pop bp
           
            ret
    ZapisBajt ENDP
     
    ; WriteToFile procedura
    ; ax vstupny parameter, cislo ktore sa ma zapisat do suboru
    WriteToFile proc
            pusha           ;Ulozime si registre
           
            mov cx, 10
            xor di, di                      ;di budeme pouzivat na pocet cislic v danom císle, aby sme vedeli kolko cisel sme dali do zasobnika
            xor dx, dx
            cmp ax, 0
            jnl PocitajCislicuW     ;Pokial nieje ax zaporne skoc na navestie PocitajCislicu
            push ax
            mov dl,'-'                    
            call ZapisBajt          ;Zapiseme minusko do suboru
            pop ax
            xor dx, dx
            neg ax                          ;Prekonvertujeme ho na kladné, a budeme ho vypisovať ako kladne
           
           
            PocitajCislicuW:
                    div cx                  ;Vydelí císlo (v dx:ax)
                    push dx                 ;Zvyšok si odložíme do zásobnika
                    xor dx, dx
                    inc di
                    cmp ax, 0               ;Porovnáme vydelené císlo s nulou (už dalej nieje potrebne spracovavat)
                    jnz PocitajCislicuW;Pokial este nieje nula, delime dalej
                   
            mov cx, di
           
            WriteCislicaW:
                    pop dx
                    or dl,110000b
                    call ZapisBajt
            loop WriteCislicaW
           
            popa
            ret
    WriteToFile ENDP
     
     
    ; Procedúra OdriadkujToFile
    ; Odriadkuje v subore
    OdriadkujToFile proc
            push dx
           
            mov dl, 0Dh            
            call ZapisBajt
                       
            mov dl, 0Ah
            call ZapisBajt
           
            pop dx
            ret
    OdriadkujToFile ENDP
     
    ; Procedura VypisTabulatorToFile
    ; Vypise tabulator do suboru
    ; Vhodné pri maticiach a podobne
    VypisTabulatorToFile proc
            push dx
           
            mov dl, '   '
            call ZapisBajt
           
            pop dx
            ret
    VypisTabulatorToFile ENDP
     
     
    ; Procedura na vypis matice
    ; parametre cez zasobnik        - offset matice, pocet stlpcov, pocet riadkov
    VypisMaticu proc
    ARG paRiadkov, paStlpcov, paOffset = Navrat     ; Parametre    
            push bp
            mov bp,sp
            pusha
           
            xor si, si                      ; Vynulujeme si (v si budeme pocitat prvky v riadku)
            mov ax, paRiadkov       ; Vypocitame pocet prvkov matice riadkov * stlpcov
            mul paStlpcov
            mov cx, ax                      ; Priradime počet prvkov do cx
            mov di, paOffset        ; Do di dáme offset matice
           
            VypisPrvokMatice:
                    mov ax, [di]    ; Zoberieme prvok z matice
                    inc di                  ; Zväčšíme di o 2, lebo matica pá prvky typu word
                    inc di
                    inc si
                    call Write              ; Vypiseme prvok matice
                    call VypisTabulator     ;Vypiseme tabulator (kôli formatovaniu)
                   
                    cmp si, paStlpcov               ;Porovname si s poctom stlpcov
                    jnz VypisPokracovanie   ;Ak sa nerovná si poctu stlpcov skocime na VypisPokracovanie
                    call Odriadkuj;                 ;Ak sa si rovna poctu stlpcov odriadkujeme
                    xor si, si                              ;Vynulujeme si (pocitame prvky v novom riadku)
            VypisPokracovanie:
            loop VypisPrvokMatice
           
            popa
            pop bp
            ret Navrat
    VypisMaticu ENDP
     
    ; Procedura na zapis matice do suboru
    ; parametre cez zasobnik        - offset matice, pocet stlpcov, pocet riadkov
    VypisMaticuToFile proc
    ARG paRiadkov, paStlpcov, paOffset = Navrat     ; Parametre    
            push bp
            mov bp,sp
            pusha
           
            xor si, si                      ; Vynulujeme si (v si budeme pocitat prvky v riadku)
            mov ax, paRiadkov       ; Vypocitame pocet prvkov matice riadkov * stlpcov
            mul paStlpcov
            mov cx, ax                      ; Priradime počet prvkov do cx
            mov di, paOffset        ; Do di dáme offset matice
           
            VypisPrvokMaticeW:
                    mov ax, [di]    ; Zoberieme prvok z matice
                    inc di                  ; Zväčšíme di o 2, lebo matica pá prvky typu word
                    inc di
                    inc si
                    call WriteToFile                ; Vypiseme prvok matice
                    call VypisTabulatorToFile       ;Vypiseme tabulator (kôli formatovaniu)
                   
                    cmp si, paStlpcov               ;Porovname si s poctom stlpcov
                    jnz VypisPokracovanieW  ;Ak sa nerovná si poctu stlpcov skocime na VypisPokracovanie
                    call OdriadkujToFile;                   ;Ak sa si rovna poctu stlpcov odriadkujeme
                    xor si, si                              ;Vynulujeme si (pocitame prvky v novom riadku)
            VypisPokracovanieW:
            loop VypisPrvokMaticeW
           
            popa
            pop bp
            ret Navrat
    VypisMaticuToFile ENDP
     
    ; Nacita cislo zo súboru
    ; FileHandler prememenna z hlavneho programu
    ; Cislo vracia v AX
    ReadIntFromFile proc
    LOCAL Znak:byte:1, VysledneCislo:word:1, Desat:word:1, Zaporne:byte:1 = symbol ;Deklaracia lokalnych premennych, Znak - nacitany bajt zo suboru, Cislo - Vysledne cislo, Zaporne - boolovska premenna tj, mali sme uz minusko?
            push bp
            mov bp, sp
            sub sp, symbol
           
            pusha
            mov bx, FileHandler             ;Ulozime File handler do bx
            push ds
            mov ax,ss
            mov ds,ax
            xor di,di
           
            mov VysledneCislo, 0                    ;Inicializujeme premenne
            mov Desat, 10
            mov Zaporne, 0
           
            RIFFCitaj:                              ;Cyklus na nacitavanie bajtov zo suboru
                    mov ah, 3Fh
                    lea dx, Znak
                    mov cx, 1
                    int 21h                         ;Nacita znak zo suboru do premennej Znak
                   
                    cmp ax, 0                       ;Pokial sa nic nenacitalo (zrejme koniec suboru)
                    jz RIFFKoniec           ;Skoc na koniec
                    cmp Znak, '0'
                    jb RIFFNeplatnyZnak     ;Pokiaľ je znak menši ako znak 0 (v ascii tabulke) skoc na navestie RIFFNeplatnyZnak, tj nenacitali sme cislo
                    cmp Znak, '9'
                    ja RIFFNeplatnyZnak ;Pokiaľ je znak vacsi ako znak 9 (v ascii tabulke) skoc na navestie RIFFNeplatnyZnak, tj nenacitali sme cislo
                   
                    RIFFVlozNacitanyZnak:   ;Nacitali sme cislo, tak ho spracujeme
                            mov ax, VysledneCislo           ;Nase vysledne cislo dame do ax
                            mul Desat                       ;Vynasobime ho 10
                            and Znak,00001111b      ;Z ascii kodu cisla spravíme cislo
                            movzx cx, Znak          ;Zlozime ho do cx
                            add ax, cx                      ;Pripocitame k ax
                            mov VysledneCislo, ax           ;Ax skopirujeme do premennej vysledne cislo
                            inc di                          ;Zvacsime di (pocitame pocet cislic ktore sme nacitali)
                           
                    jmp RIFFCitaj                   ;Skoc na citanie dalšieho znaku
           
            RIFFNeplatnyZnak:                       ;Spracujeme neplatne znaky
                    cmp di, 0                               ;Porovnaj di (pocet doterajsich cislic s 0)
                    jnz RIFFKoniec                  ;Pokial sme doteraz už niejake cislo nacitali, a teraz mame nespravny znak (zrejme koniec cisla), tak skoncime na koniec
                   
                    cmp Znak, '-'                   ;Znak - interpretujeme ako minusko pred cislom, tj zaporne cislo
                    jz RIFFNastavZapornyFlag;Skoc na nastavenie zaporneho cisla
                    mov Zaporne, 0                  ;Bolo by dobre vynulovat aby nieco v zmysle "a-b 120" nevzalo ako -120
                    jmp RIFFCitaj                   ;Nemame ešste ziadne cislo nacitane, a nezadali sme ani - tak citame dalej
                                   
                   
            RIFFNastavZapornyFlag:
                    mov Zaporne, 1                  ;Nastav ze sa jedna o zaporne cislo
                    jmp RIFFCitaj                   ;Citaj dalej
                   
            RIFFKoniec:
                    pop ds
                    popa
                    mov ax, VysledneCislo                                   ;Dáme do ax späť výsledok
                    cmp Zaporne, 1                                  ;Ak mame zaporne cislo, tak urobime neg operaciu
                    jnz RIFFReturn
                    neg ax
            RIFFReturn:
                    mov sp, bp
                    pop bp
                    ret
    ReadIntFromFile ENDP
     
    ClrScr PROC
            pusha
            mov ah, 0
            mov al, 3
            int 10h
           
            mov ax,0B800h
            mov es,ax
            mov di,0
            mov cx,2000; počet znakov na obrazovke
            mov al,' '
            mov ah, 7
            cld
            rep stosw
     
            ;Nastavi kurzor na vrch stranky
            mov dh, 0       ;riadok
            mov dl, 0       ;stlpec
            call GoToxy
            popa
            ret
    ClrScr ENDP
     
    ;DH - riadok
    ;DL - stlpec
    GoToxy PROC
           
            push ax
            push bx
            mov ah, 0Fh
            int 10h
            mov ah, 2
            int 10h
            pop bx
            pop ax
           
            ret
    GoToxy ENDP