; 	Zadanie c.1
;	Napiste program ktory po spusteni
;	vypise menu so siestimi volbami  potom podla pouzivatelom
;	zvolnej moznosti vykona jednu z cinnosti


zas segment stack 'stack'
	dw 64 dup (?)          ; vyhradenie
zas ends
dat segment
	vstup	db 103 dup (?)
        pocet	db 00h
	menu	db 13,10,'1 - Nacitat retazec',13,10
		db       '2 - Poradove cislo prvej medzery',13,10
		db       '3 - Pocet a vypis cislic v retazci',13,10
		db       '4 - Najst zadany znak',13,10
		db       '5 - Vypisat retazec odzadu',13,10
		db       '6 - Koniec',13,10
		db       '0 - Info',13,10,'-> $'
	znak	db ' $'
	medz    db ' '
	beep	db 7,'$'
	ent	db 13,10,'$'
	napis	db 13,10,'Napis retazec:',13,10,'> $'
	zmaz	db 8,' ',8,'$'
	tvstup	db 13,10,'Retazec:',13,10,'>$'
	prazdny	db 13,10,'Retazec je prazdny...',13,10,'$'
	odzadu	db 13,10,'Vypis retazca odzadu:',13,10,'>$'
	vysl    db 13,10,'Vysledok:','$'
	vystup_prevodu	db '   ',13,10,'$'
	cislice		db '0123456789'
	zadznak db 'Zadaj pozadovany  znak: $'
	nenasiel db 13,10,'Retazec neobsahuje zadany znak',13,10,'$'
	prginfo     db 13,10,'   ***** Naprogramoval : Michal Kaduc *****',13,10
                db       '   Zadanie c.1: Strojovo orientovane jazyky',13,10,'-> $'
                  
dat ends
cod segment
	assume cs:cod,ds:dat,ss:zas

;==============================================================================
; MENU , VYPIS, NACITANIE VOLBY , ROZVETVENIE PROGRAMU 

PressAny PROC
;	mov ah,07h
;	int 21h
	xor ax,ax
	int 16h
PressAny ENDP

start:
	mov ax,seg vstup
	mov ds,ax
	mov dx,offset menu      
	mov ah,09h
	int 21h                   ; Vypis hlavneho menu
	xor ax,ax
	int 16h				;cakanie na znak	
	mov [znak],al			
	mov dx,offset znak
	mov ah,09h
	int 21h	            ;    poz zadani volby sa ulozi do prem znak a vypise sa
	mov al,[znak]       ; testuje (hlavne menu)
	cmp al,'1'
	jz _1
	cmp al,'2'
	jz _2
	cmp al,'3'
	jz _3	
	cmp al,'4'
	jz _4
	cmp al,'5'
	jz _5
	cmp al,'6'
	jz _6
	cmp al,'0'
	jz _0
	mov dx,offset beep           
	mov ah,09h
	int 21h
	jmp start

;==============================================================================
; ZDROJOVY KOD JE VACSI AKO 128b TAKZE PODMIENENE SKOKY SA PREDLZUJU S JMP

_1:			
	jmp nacitaj_retazec 		;pouziva sa jmp lebo kod je dlhsi ako 128b
_2:
	jmp prva_medzera
_3:
	jmp pocet_cislic
_4:
	jmp najdi_znak
_5:
	jmp retazec_opacne 
_6:
	jmp koniec
_0:     
	jmp prg_info

;=============================================================================
; FUNKCIA NA NACITANIE RETAZCA

nacitaj_retazec:		;nacitanie retazca navestia s nr_... patria sem
	xor di,di				
	mov dx,offset napis	;Vypis 'Napis retazec'
	mov ah,09h
	int 21h			
nr_loop:
	xor ah,ah		
	int 16h			;prerusenie na nacitanie jedneho znaku do al
	cmp al,13		;kontrola ENTERu
	jz nr_enter			
	cmp si,100
	jz nr_full		;kontrola velkosti (100znakov)
	cmp al,8
	jz nr_delete
	mov [vstup+di],al       ;ulozi do vstupneho retazca dalsi znak
	mov [znak],al		;vypise prave zadany znak
	mov dx,offset [znak]
	mov ah,09h
	int 21h
	inc di			;pokracovanie v retazci
	jmp nr_loop
nr_enter:			; po stlacenie enteru doplni sa znak 13 10 a $
	mov [vstup+di],13
	mov [vstup+di+1],10
	mov [vstup+di+2],'$'
	mov ax,di		;a ulozi sa pocet nac znakov
	mov [pocet],al
	jmp start
nr_full:
	mov dx,offset beep	;ked je plny retazec tak to zapipa
	mov ah,09h
	int 21h
	jmp nr_loop

nr_delete:
	mov dx,offset zmaz	;zistenie klav. BckSPc vymaze jeden znak dozadu
	mov ah,09h
	int 21h
	dec di			;znizi pocet nacitanych znakov
	jmp nr_loop

vr_prazdny:			;funkcia na vypisanie hlasky 'retazec je prazdny'
	mov dx,offset prazdny
	mov ah,09h
	int 21h
	jmp start
;==============================================================================
; FUNKCIA NA VYPIS RETZCA ODZADU

retazec_opacne:			;do al sa ulozi pocet 
	xor ax,ax		;do si al , potom testujeme ci nie je prazdny retazec
	mov al,[pocet]
	mov si,ax
	cmp si,0
	jz vr_prazdny		
	mov dx,offset odzadu
	mov ah,09h
	int 21h
	mov cx,si
vo_loop:
	mov al,[vstup+si]	;al davame vstup +si ty znak (si sa znizuje)	
	mov [znak],al
	mov dx,offset znak	;vypis znaku 
	mov ah,09h
	int 21h
	dec si			;a o jeden znak spat
	loop vo_loop		;ked je cx<>0 tak spat 
	mov al,[vstup]		;vypisanie posledneho (prveho v retaczi) znaku
	mov [znak],al
	mov dx,offset znak
	mov ah,09h
	int 21h
	jmp start

najdi_znak:
	mov ah,[pocet]		;tu sa testuje ci retazec je prazdny
	cmp ah,0
	jnz nz_n_prazdny
	jmp vr_prazdny
nz_n_prazdny:

	mov dx,offset ent
	mov ah,09h
	int 21h		;skok na dalsi riadok
	mov dx,offset zadznak
	mov ah,09h
	int 21h
	xor ah,ah	;nacitanie zadaneho znaku
	int 16h
	mov bl,al
	mov [znak],al
	lea dx,znak
	mov ah,09h
	int 21h
	xor ax,ax
	xor si,si
nz_loop:		;opakuje sa testovanie znakov (si sa postupne inc)
	mov ah,[vstup+si]
	inc si
	cmp ah,bl	;samotne porovnavanie
	je  nz_nasiel	;nasiel?
	xor ax,ax	
	mov al,[pocet]	
	mov cx,si
	cmp cx,ax	;porovnanie ci nie sme na konci retazca
	jne nz_loop
	mov dx,offset [nenasiel]
	mov ah,09h
	int 21h
	jmp start
nz_nasiel:	
	mov ax,si
	cmp si,0
	mov di,3
	jne int2string
	jmp start


prva_medzera:
	mov ah,[pocet]	;testuje ci nie je retazec prazdny
	cmp ah,0
	jnz  vr_n_prazdny
	jmp vr_prazdny
vr_n_prazdny:
	xor ax,ax
	mov si,0
pm_loop:
	mov ah,[vstup+si]
	cmp ah,20H		;testuje ci al je rovny medzrere 
	je  mam_medzeru
	inc si			
	xor ax,ax
	mov al,[pocet]
        mov cx,si
        cmp ax,cx
        jne pm_loop
	jmp start

mam_medzeru:
			;...v ax je cislo, ktore chceme previest                                              |
	mov di,3
	inc si
	mov ax,si
int2string:			;samotne prevadzanie, cislo je v ax
	mov bl,10		;davame to do 10-kovej sustavy - delime 10-kou
	div bl			;div je delenie, deli sa takto:
				;ax / argument = al, ah = zvysok po deleni
				;plati to len ked je arg. 8-bit.
	dec di
	xor bx,bx
	mov bl,ah		;konvertujeme 8-bit. cislo na 16-bit.
	mov si,bx
	mov bl,[cislice+si]	;cislice : tam su ulozene 0..9
			
	mov [vystup_prevodu+di],bl
	xor ah,ah		;znulujeme si ah, aby sme potom mohli delit
				;cele ax
	cmp di,0		;prevadza len 3 miestne cislo (di sa dec az na 0)
	jnz int2string		;cyklus spat
	mov dx,offset vysl	;vysledok je trojmiestny retazec ukonceny $
	mov ah,09h	
	int 21h
	mov dx,offset vystup_prevodu
	mov ah,09h
	int 21h
	jmp start



pocet_cislic:
	mov ah,[pocet]		;v ah je ulozeny pocet znakov (celkovy)
	cmp ah,0		;kontrola ci je prazdny retazec
	jnz pc_n_prazdny
	jmp vr_prazdny
pc_n_prazdny:		
	mov dx,offset ent	;na dalsi riadok...
	mov ah,09h
	int 21h
	xor ax,ax
	xor bx,bx
	mov si,0
pc_loop:
        mov ah,[vstup+si]	;do ah sa vlozi i-ty znak (i=0..pocet)
	inc si			
	cmp ah,2FH		;skusa ci to je cislo (zdola)
	jg  pc_inter
pc_back:
	xor ax,ax
	mov al,[pocet]
	mov cx,si
	cmp cx,ax
	jne pc_loop		;pretestovali sme retazec????
	mov ax,bx		
	cmp bx,0
	mov di,3		;do di vlozi 3 (trojmiestne cislo)
	jne int2string
	jmp start

pc_inter:
	cmp ah,3AH		;skusa hornu hranicu znakov 	
	jl  pc_mam_cislo	;cize znak je v intervale <2FH,3AH>
	jmp pc_back		;ked je v tom tak je to cislica
				;a ako je to cislo tak skoci na mam_cislo

pc_mam_cislo:
	mov [znak],ah
	mov dx,offset znak
	mov ah,09H
	int 21h
	inc bl
	jmp pc_back

koniec:
	mov ax,4C00h
	int 21h
prg_info:
	mov dx,offset prginfo
	mov ah,09h
	int 21h
	jmp start	
cod ends
end start
; Program je funkcny, bol vypracovany v editore
; Norton Commander, a debuggovany v Turbo Debuggeri
; pouziva DOS prerusenie 21h a BIOS prerusenie 16h

