;author: Wilfried Mbouenda
;blog: http://bitly.com/willychallenge

DIM1      EQU 20       
DIM2	  EQU 40 
DIM3	  EQU 26  
ENTER     EQU 13; ascii code for carriage return
SPACE     EQU 32; ascii code for space key
K         EQU 3
       .MODEL small
       .STACK
       .DATA
MY_STRING DB DIM2 DUP(?)
OCCURENCE DB DIM3 DUP(0)
DIMS DW 0 
MAX_CHAR DB ?   
INDEX DW ? 
       .CODE
       .STARTUP
     ;1. Write the Assembly code required to get text by means of calls to INT 21H
 
; get  MY_STRING

GET1:  MOV CX,DIM2
       MOV DI,0
       MOV AH,1
lab1:  INT 21H  
       CMP AL,ENTER       ;verify if the user input the enter key
       JE END_ROW1 
       CMP AL,SPACE       ;verify if the user input the space key
       JE END_ROW1 
       MOV MY_STRING[DI],AL
       INC DI      
       INC DIMS
       DEC CX
       CMP CX,0
       JNZ lab1
END_ROW1:
       CMP DI,DIM1
       JL GET1:            ;the text lenght is too small           
                     
       

;2 For each row it is required to count the number of times each character
;appears (desired characters are only a..z, A...Z), printing, for each row, the
;character that appears a number of times equal the maximum times. If
;more than one character appears for the same number of times, it is required
;to print all of them.

;1.  create an occurence vector of 26 which has all letters
;2.  cycle the current row and for every caracter, increment the right value on the coccurence vector  
;3. find the max value in the occurence      


;Fill OCCURENCE

   MOV CX,DIMS
    MOV DI,0  
    XOR AX,AX 
cycle:MOV AL,MY_STRING[DI]
    CMP AL,41h ; A 
    JL end_continue; before A = invalid
    CMP AL,7Ah ; z 
    JG end_continue; after z = invalid
    CMP AL,5Ah ; Z
    JLE upper_case ;after A and before Z = valid and upper case
    CMP AL,61h ; a
    JL  end_continue;after A, after Z and before a = invalid
    ; after a and before z = valid
    MOV BL,61h ;   'a'     
continue:
    SUB AL,BL  ;char - 'a'/'A'         
    MOV BL,AL    
    MOV BH,0
    INC OCCURENCE[BX]
end_continue:
    INC DI      
    DEC CX
    CMP CX,0
    JNZ cycle
    JMP end_count
upper_case:
    MOV BL,41h  ; 'A'    
    JMP continue     
end_count:
 

;Find max value of OCCURENCE
;big = element[0]    
;for each element in array, starting from 1 (not 0):
;    if (element > big):        big = element
; 
;
     MOV DI, 0
     MOV AL,OCCURENCE[DI]
     MOV INDEX,DI
     MOV CX, DIM3-1 ; DIM2 == 26
     MOV DI, 1  
find:CMP AL,OCCURENCE[DI]
     JAE PASS
     MOV AL,OCCURENCE[DI] 
     MOV INDEX,DI;INDEX is a variable to track the max value position
PASS:INC DI
     DEC CX
     CMP CX,0             
     JNZ find         
     MOV AX,INDEX
     ADD AX,61h      ; index + 'a'
     MOV MAX_CHAR,AL ;MAX_CHAR is the charater with max occurences 
     
; PRINT NEW LINE
         MOV AX,10D
         MOV AH,0EH
         INT 10H
     
;PRINT MAN_CHAR
     MOV AH,2
     MOV DL,MAX_CHAR         
     INT 21H   
     
        
;4 print  the  text  using  a Caesar  cipher
; Let's transform MY_STRING
    MOV CX,DIMS
    MOV DI,0  
    XOR AX,AX 
caesar:
    MOV AL,MY_STRING[DI]
    CMP AL,41h ; A 
    JL end_test_caesar
    CMP AL,7Ah ; z 
    JG end_test_caesar
    CMP AL,5Ah ; Z
    JLE upper_case1
    CMP AL,61h ; a
    JL  end_test_caesar 
    MOV BL,7Ah 
test_caesar:
    ADD AL,K; letter + k
    CMP AL,7Ah
    JG modulo2        
    MOV MY_STRING[DI],AL    
end_test_caesar:    
    INC DI      
    DEC CX
    CMP CX,0
    JNZ caesar 
    JMP end_caesar
upper_case1:
    ADD AL,K; letter + k
    CMP AL,5Ah
    JG modulo1 
    MOV MY_STRING[DI],AL
    JMP end_test_caesar 
modulo1:
    ADD AL,6  ; after z -> A
    MOV MY_STRING[DI],AL  
    JMP end_test_caesar:    
modulo2: 
    MOV BL,58
    SUB AL,BL ; after Z -> a
    MOV MY_STRING[DI],AL
    JMP end_test_caesar:
end_caesar: 
     
    
     
    
;PRINT MY_STRING  

; PRINT NEW LINE
         MOV AX,10D
         MOV AH,0EH
         INT 10H  
         
     MOV DI, 0 
     MOV CX,DIMS
     
printf:
     MOV AH,2
     MOV DL,MY_STRING[DI]         
     INT 21H 
     INC DI
     DEC CX
     CMP CX,0             
     JNZ printf
     
       
       .EXIT
END
