;----------------------------------------------------------------------------------------------------------------------------------------
;------------------------- ******   4. ZADANIE  -   SPRACOVANIE  POLA  ZNAKOV   ****** --------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------------------

;	Napiste program, ktory nacita z klavesnice retazec maximalne 90 znakov . Potom vykona jednu ulohu :
;	g) vymaze z retazca vsetky medzery a vypise pocet zmazanych medzier
	

;	autor:			Peter Gramblicka
;	rocnik:			2.
;	studijny program:	Telekomunikacie
;	akademicky rok:		2007/2008

;----------------------------------------------------------------------------------------------------------------------------------------

;----------------------------------------------------------------------------------------------------------------------------------------
;makro je definovane pred kodovym aj datovym segmentom a pouziva formalny parameter txt
;----------------------------------------------------------------------------------------------------------------------------------------

zobraz  MACRO txt		;definicia makra na zobrazenie textu
       	push ax			;vklada do zasobnika akumulator ax
       	push dx			;vklada do zasobnika akumulator dx
       	mov dx, offset txt	;do dx sa presunie offsetova adresa textu T
       	mov ah,09h		;do ah sa vlozi cislo obsluhy na vypisanie retazca
       	int 21h			;volanie prerusenia - funkcia dosu
       	pop dx			;vybera zo zasobnika akumulator dx
       	pop ax			;vybera zo zasobnika akumulator dx
endm				;ukoncenie makra

;----------------------------------------------------------------------------------------------------------------------------------------
;definicia zasobnikoveho segmentu
;----------------------------------------------------------------------------------------------------------------------------------------

ZAS   	SEGMENT STACK		;prikaz pre assembler (zaciatok zasobnikoveho segmentu)
        DW      64 DUP(?)	;definicia alokovania miesta pre 64*2=128 bitove slovo
ZAS     ENDS			;prikaz pre ukoncenie zasobnikoveho segmentu

;----------------------------------------------------------------------------------------------------------------------------------------
;definicia datoveho segmentu
;----------------------------------------------------------------------------------------------------------------------------------------

DATA    SEGMENT			;zaciatok datoveho segmentu



;------------------------------------- definicie retazcov a premennych-------------------------------------------------------------------


vstup      db 90       		;bude sa citat 90 znakov

pocet      db 0        		;tu sa ulozi ich skutocny pocet
           db 90 dup(?)  	;miesto pre citany retazec

nr         db 0dh, 0ah

vystup     db 93 dup(?)		;miesto pre vysledok + 13, 10, $


Zadanie db '********************************************************************',10,13 
	DB '*   Napiste program, ktory nacita z klavesnice retazec maximalne   *',10,13 
	db '*   90 znakov . Potom vykona jednu ulohu :                         *',10,13
	db '*                                                                  *',10,13 
       	DB '*   g) vymaze z retazca vsetky medzery a vypise pocet zmazanych    *',10,13
	db '*      medzier                                                     *',10,13 
	db '********************************************************************',10,13, '$'
       
newr	db 10,13, '$'

Finish  DB  'Koniec programu.$'


retazec1  db '****************************************************************',10,13 
	  DB '*        zadajte retazec s maximalnou dlzkou 90 znakov:        *',10,13 
	  db '****************************************************************',10,13 
	  db 10,13,'$'
	
	  
retazec2  db 10,13
	  db '****************************************************************',10,13 
	  DB '*                     Retazec bez medzier:                     *',10,13 
	  db '****************************************************************',10,13, '$'	


retazec3  db 10,13
	  db '****************************************************************',10,13 
	  DB '*             Pocet vymazanych medzier v retazci:              *',10,13 
	  db '****************************************************************',10,13 	  
	  db 10,13,'$'

nula 	db 0 

suma	db 3 dup(?)


;----------------------------------------------------------------------------------------------------------------------------------------

DATA     ENDS			;ukoncenie datoveho segmentu

;----------------------------------------------------------------------------------------------------------------------------------------
;definicia kodoveho segmentu
;----------------------------------------------------------------------------------------------------------------------------------------

CODE     SEGMENT				;zaciatok kodoveho segmentu
         ASSUME  CS:CODE, DS:DATA, SS:ZAS	;direktivy pre prekladac - pouzitie kodoveho, datoveho a zasobnikoveho segmentu


;----------------------------------------------------------------------------------------------------------------------------------------
;start programu a definovanie internych procedur 
;----------------------------------------------------------------------------------------------------------------------------------------


START: 		jmp START1		;skok na navestie START1

	
;----------------------------------------------------------------------------------------------------------------------------------------
clrscr  	proc  near		;procedura na vymazanie obrazovky
        	
		mov ax,0003h		;do AX sa vlozia parametre grafickeho modu 80x25
       		int 10h			;prerusenim sa vymaze obrazovka
        	ret			;navrat k miestu, odkial bola procedura volana

clrscr  	endp			;ukoncenie procedury
;----------------------------------------------------------------------------------------------------------------------------------------


;----------------------------------------------------------------------------------------------------------------------------------------
potvrd  	proc  NEAR			;procedura na identifikaciu ci bola stlacena klavesa ENTER
       		
		mov ah,00h			;do akumulatora ah vlozime 00h
		potvrd2:	int 16h		;prerusenie na cakanie ci bola stlacena klavesa
         			cmp al,13	;porovnava ci bola stlacena klavesa ENTER
                		jnz potvrd2	;ak nie tak skoci na navestie potvrd2
                		ret		;navrat k miestu, odkial bola procedura volana

potvrd  endp					;ukoncenie procedury
;----------------------------------------------------------------------------------------------------------------------------------------


;----------------------------------------------------------------------------------------------------------------------------------------
konec	proc     near			;procedura na korektne ukoncenie programu
        
	zobraz Finish			;volanie macra zobraz a retazca Finish
	konec2:		call potvrd	;volanie procedury potvrd na identifikaciu ci bola stlacena klavesa ENTER
          		jnz konec2	;ak nebola skace program na navestie konec2
          		mov ax,4c00h	;do AX vloz funkciu ukoncenie programu
          		int 21h		;prerusenim sa vykona ukoncenie programu a odovzdanie procesoru OS
          		ret		;navrat k miestu, odkial bola procedura volana 

konec   endp				;ukoncenie procedury
;----------------------------------------------------------------------------------------------------------------------------------------


;----------------------------------------------------------------------------------------------------------------------------------------
rataj	PROC 	near			;procedura na premenu cisla na znak
	
	XOR AX,AX			;vymaz AX
	MOV SI,OFFSET nula		;do SI vloz premennu nula			
	MOV AX,[SI]			;do AX vloz premennu nula
	MOV CL,10			;do cl vlozime 10 pre delenie 	
	DIV CL				;delime akumulator registrom cl kde je ulozena 10
	ADD AL,48			;do al sa prirata 48 pre vypis cisiel od nuly, v al je vysledok po deleni 10 	
	ADD AH,48			;do ah sa prirata 48 pre vypis cisiel od nuly, v al je zvysok po deleni 10 	
	MOV SI,OFFSET suma		;do SI sa vlozi premenna suma			
	cmp al,48
	jz zero
	MOV [SI],AL			;na prvu poziciu retazca vloz vysledok po deleni
zero:	MOV [SI+1],AH			;na druhu poziciu retazca vloz zvysok po deleni
	MOV BYTE PTR [SI+2],'$'		;ukonci retazec znakom & 
	RET				;navrat k miestu, odkial bola procedura volana 

rataj	ENDP				;koniec procedury
;----------------------------------------------------------------------------------------------------------------------------------------


START1:		mov ax,seg data		;do akumulatora vloz seg data
      		mov ds,ax		;do registra Ds vloz akumulator
		call clrscr		;zavolaj proceduru na vymazanie obrazovky
		zobraz zadanie		;zavolaj macro zobraz na vypisasnie ratazca zadanie 
		call potvrd		;zavolaj proceduru na stlacenie klavesy ENTER
		call clrscr		;zavolaj proceduru na vymazanie obrazovky
		zobraz retazec1		;zavolaj macro zobraz na vypisasnie ratazca retazec1
		
		mov ah,0ah   		;sluzba pre vstup retazca o dlzky maximalne 90 znakov z klavesnice
		mov dx,offset vstup	;do registra dx sa vlozi premenna vstup
      		int 21h			;volanie prerusenia na nacitanie znakov z klavesnice
		
     		zobraz newr		;zavolaj macro zobraz na vypisasnie ratazca newr
		zobraz retazec2		;zavolaj macro zobraz na vypisasnie ratazca retazec2
		
		xor ax,ax     			;nulovanie akumulatora ax
      		xor cx,cx     			;nulovanie pocitadla cx
      		mov cl,pocet  			;zapise pocet znakov do cl	    
      		add dx,2      			;nastav sa na citanie prveho znaku
      		mov si,dx     			;adresa prveho znaku v si
      		mov bx, offset vystup  		;priprav adresu pre vystupny retazec
	
znak:	mov al, [si]  		;uloz znak do al  
      	cmp al, 32 		;porovnaj ci je nacitany znak medzera  	 
      	jz incpocet		;ak hej tak skac na navestie incpocet
	
      	mov [bx], al  		;uloz citany znak na vystup
      	inc bx	    		;priprav dalsi znak
	jmp pokrac		;skac na navestie pokrac

incpocet:	inc nula	;inkrementuj premennu nula na pocitanie medzier
		jmp pokrac	;skac na navestie pokrac
	

pokrac:		inc si        			;priprav dalsi znak
      		loop znak    			;opakuj prehladavanie retazca     
      		mov byte ptr[bx], 13		;pridaj na vystupny retazec 13,10,$ pre skok na novy riadok
      		mov byte ptr[bx]+1, 10		;pridaj na vystupny retazec 13,10,$ pre skok na novy riadok
      		mov byte ptr[bx]+2, '$'		;pridaj na vystupny retazec 13,10,$ pre skok na novy riadok
      	
		mov ah,9		;do ah vloz 9 pre vypis retazca
	      	mov dx, offset nr       ;este jeden riadok
      		int 21h			;volanie prerusenia na vypis
			
		call rataj		;zavolaj proceduru na vymazanie obrazovky
		zobraz retazec3		;zavolaj macro zobraz na vypisasnie ratazca retazec3
      		zobraz suma		;zavolaj macro zobraz na vypisasnie ratazca suma
		zobraz newr		;zavolaj macro zobraz na vypisasnie ratazca newr
		zobraz newr		;zavolaj macro zobraz na vypisasnie ratazca newr		
		call konec		;volanie procedury na ukoncenie programu

;----------------------------------------------------------------------------------------------------------------------------------------

CODE	ENDS			;ukoncenie kodoveho segmentu
	END	START  


;----------------------------------------------------------------------------------------------------------------------------------------
;----------------------------------------------- *****  ZHODNOTENIE  ****** -------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------------------

;1. Zdrojovy kod bol napisany v textovom editore NOTEPAD a napisany pre prostredie systemu MS-DOS za pouzitia kompilatora TASM v. 2.02
;   a TLINK v. 3.01. 
;2. Pre spustenie tohoto programu potrebujeme procesor architektury  x86 najmenej vsak 80286 s nainstalovanym operacnym systemom MsDOS 
;3. Pamatove naroky su minimalne,program nealokuje ziadnu dalsiu pamat, V zasobnikovom segmente je alokovana pamat.
;4. Program nacita z klavesnice retazec maximalne 90 znakov a nasledne vymaze z retazca vsetky medzery a vypise pocet zmazanych medzier
;5. Vypisy boli uskutocnene pomocou DOS sluzieb Int 21h cislom sluzby bolo 09h.
;6. V programe su vyuzite interne procedury pre lepsiu orientaciu a to konkretne clrscr (na vymazanie obrazovky), konec (na korektne 
;   ukoncenie programu), potvrd (pre pokracovanie programu stlacenim klavesy ENTER), rataj (pre zobrazenie dvojmiestneho  desiatkoveho
;   cisla v retazci) Dalej sme tu vyuzili macro zobraz na zobrazenie retazcov a premennych.
;7. Program by sa dal vylepsit najma krajsim vzhladom (nastavenie farby podkladu, nastavenie fontu pisma...), a rychlejsimi instrukciami
;   assemblera, opakovanim volby znovu nacitania retazca a nasledneho vypisu medzier
;8. Program je plne funkcny bez dalsich odmedzeni
;----------------------------------------------------------------------------------------------------------------------------------------

