#  zoran graonic 260110350
#  COMP 273 - Keyboard and Text Screen Drivers
#------  GETCHAR driver --------------
#  GETCHAR driver interfaces with the keyboard’s status and data registers
#  This driver when called, with no parameters, returns the characterin the keyboard buffer in register $V0.	
#------  PUTCHAR driver --------------	
#  PUTCHAR driver interfaces with the screen’s (console’s)status and data registers. 
#  This driver when called assumes the register $A0 contains the address of the character that needs to be output. Only one character is output.	
#------  ISCANF and IPRINTF driver --------------	
#int iscanf(string, var-list-of-arguments)
#int printf(string, var-list-of-arguments)	
# Where:
#     string - works as in C, any character with (to make things simple) %c, %d and %f with no size descriptors.	
# 	  int - The integer return value for iscanf counts the number of valid inputs read in.
# 	        The integer return value for iprintf is simply a boolean, 0 for false and 1 for true, indicating 
#           whether the entire string and values were output to the console.
#     var-list-of-arguments - operates as in C except that we will not use the & symbol but simply assume that 
#                             the arguments are always only addresses, for both iprintf and iscanf.	
#  A letter I in ISCANF and IPRINTF stands for Intelligent.   
# If it comes to an unexpected input value it ignores the character and continues on reading characters until it either comes to
# the end of line (in which case it terminates early) or it comes to a character that matches what it expects and then continues processing the rest of the input. In the
# case of iprintf, output is simpler and the errors that can occur here are simply that the device was not functioning properly. In this case, iprintf, uses a simple
# exception handler that displays the message: “IPRINTF EXCEPTION WITH ADDRESS <address of data trying to output>”.	
	
	.text 
	
	.globl main
#-----------MAIN--------------------------------
main:    
   		# ---printing for the first iscanf---------
		# ---Type two arguments character and integer
		#---- [Example: iscanf(''%c %d'',scf1Arg1,scf1Arg2)] with StdIn <cefta -123 d> will save scf1Arg1='c' and scf1Arg1='-123'. ]
		li $v0, 4 	# load appropriate system call code into register $v0;
				# code for printing string is 4
		la $a0, str1	# load address of string to be printed into $a0
		syscall		# call operating system	
 	
		
     ## -- the first iscanf ---------------------------------------------------
	## --- the stack(array of args) is use to transfer the arg addresss into the function
	## ----  $fp ----points into the end of the array (arg 1 is in the possition n, arg n on possition 0 of array )-
	## ---- the last element of array is the first argument -(because stack grows down)-----------------------

		move $fp,$sp
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
		move $a0,$fp   #
		la $s0,scf1Arg1
		la $s1,scf1Arg2
		    # store addres of the arg on the stack  
		    # $a0 keep address of the end of the array of the argumnents
		    #  the last element of the array is the first arg
			addi $sp,$sp,-8
			sw  $s1,0($sp)
			sw  $s0,4($sp)
		addi $a1,$zero,2       # number of arguments
		la $a2,scf1Str	       # the address of the string
		

		jal iscanf
		       addi $sp,$sp,8      #return the stack
	## --------------end of the first iscanf -----------------	
						move $t7,$v0  # save $v0 duting the printing
						#------print the arguments of the first scanif-------
						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,str6	# load address of string to be printed into 
						syscall	
								li $v0, 4 	# load appropriate system call code into register $v0;
										# code for printing string is 4
								la $a0,str4	# load address of string to be printed into 
								syscall		# call operating system

						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,str7	# load address of string to be printed into 
						syscall	

						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,scf1Arg1	# load address of string to be printed into 
						syscall	
								li $v0, 4 	# load appropriate system call code into register $v0;
										# code for printing string is 4
								la $a0,str4	# load address of string to be printed into 
								syscall		# call operating system
						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,str8	# load address of string to be printed into 
						syscall	
						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,scf1Arg2	# load address of string to be printed into 
						syscall	
								li $v0, 4 	# load appropriate system call code into register $v0;
										# code for printing string is 4
								la $a0,str4	# load address of string to be printed into 
								syscall		# call operating system	
						#------prints the definition of the first iprintf-------						
						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,str2	# load address of string to be printed into 
						syscall	
						move $v0,$t7

	
   ## -- the first iprintf -----iprint(''Category: %c    H: %d mm.'',prt1Arg1,prt1Arg2)----
	#--Should be printed:  Category: C   H: -1234 mm.	
	## --- the stack(array of args) is use to transfer the arg addresss into the function
	## ----  $fp ----points into the end of the array (arg 1 is in the possition n, arg n on possition 0 of array )-
	## ---- the last element of array is the first argument -(because stack grows down)-----------------------

		move $fp,$sp
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
		move $a0,$fp   #  input address of $fp (address of arg's addresses)
		la $s0,prt1Arg1
		la $s1,prt1Arg2
		    # store addres of the arg on the stack  
		    # $a0 keep address of the end of the array of the argumnents
		    #  the last element of the array is the first arg
			addi $sp,$sp,-8
			sw  $s1,0($sp)
			sw  $s0,4($sp)
		        addi $a1,$zero,2       # number of arguments
		        la $a2,prt1Str	       # the address of the string
		

		        jal iprintf
		       addi $sp,$sp,8      #return the stack
        #----------------- end of the first iprintf()--------------
				
				move $t7,$v0  # save $v0 duting the printing
			# ---Type two arguments character and float
			#---[Example: iscanf(''%c %f'',scf2Arg1,scf2Arg2)] with StdIn <cefta -12.3 d> will save scf2Arg1='c' and scf2Arg1='-12.3'. ]
		 
				li $v0, 4 	# load appropriate system call code into register $v0;
						# code for printing string is 4
				la $a0, str3	# load address of string to be printed into $a0
				syscall		# call operating system	
				move $v0,$t7



   ## -- the second iscanf ---------------------------------------------------
	## --- the stack(array of args) is use to transfer the arg addresss into the function
	## ----  $fp ----points into the end of the array (arg 1 is in the possition n, arg n on possition 0 of array )-
	## ---- the last element of array is the first argument -(because stack grows down)-----------------------


		move $fp,$sp
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
		move $a0,$fp   # 
		la $s0,scf2Arg1
		la $s1,scf2Arg2
		    # store addresses of the arg on the stack  
		    # $a0 keep address of the end of the array of the argumnents
		    #  the last element of the array is the first arg
			addi $sp,$sp,-8
			sw  $s1,0($sp)
			sw  $s0,4($sp)
		addi $a1,$zero,2       # number of arguments
		la $a2,scf2Str	       # the address of the string
		

		jal iscanf
		       addi $sp,$sp,8      #return the stack
	## --------------end of the second iscanf -----------------
						
  ## -- the second iprintf -----iprint(''Arguments of the second iscanf are: scf2Arg1: %c , scf2Arg2: %f'',scf2Arg1,scf2Arg2)----
	#--Should be printed:  Category: C   H: -1234 mm.	
	## --- the stack(array of args) is use to transfer the arg addresss into the function
	## ----  $fp ----points into the end of the array (arg 1 is in the possition n, arg n on possition 0 of array )-
	## ---- the last element of array is the first argument -(because stack grows down)-----------------------

		move $fp,$sp
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
		move $a0,$fp   #  input address of $fp (address of arg's addresses)
		la $s0,scf2Arg1
		la $s1,scf2Arg2
		    # store addresses of the arg on the stack  
		    # $a0 keep address of the end of the array of the argumnents
		    #  the last element of the array is the first arg
			addi $sp,$sp,-8
			sw  $s1,0($sp)
			sw  $s0,4($sp)
		        addi $a1,$zero,2       # number of arguments
		        la $a2,prt2Str	       # the address of the string
		

		        jal iprintf
		       addi $sp,$sp,8      #return the stack
        #----------------- end of the second iprintf()--------------	   
j Exit


##-----FUNCTIONS-----------------------------------------------------------------------------

#--------GETCHAR---------returns char into reg $v0-------
getchar:	
	lui	$t0, 0xffff 	#ffff0000
WaitG:	lw	$t1, 0($t0) 	#control
	andi	$t1,$t1,0x0001
	beq	$t1,$zero, WaitG 
	lw	$v0, 4($t0)	 #data  should be $v0 register

   jr $ra




#------- PUTCHAR-------input $a0-address of the char to be printed----
putchar:        
	

	lui	$t0, 0xffff 	#ffff0000
WaitP:	lw	$t1, 8($t0)	 #control
	andi	$t1,$t1,0x0001
	beq	$t1,$zero, WaitP
	lb 	$t1,($a0)       #load  char   
	sw	$t1, 12($t0) 	#data
jr $ra

#------isInt -- test for Int input $a0-address $a1-0(test with "-") return TRUE=1 if it is Int (In use $t0,$t1,$t2,$t3)
isInt:
        sgt     $t0,$a0,47      #int > '0'-1
        slt     $t1,$a0,58      #int < '9'+1
        and     $t2,$t1,$t0     #(int >= '0' and int <= '9')
        move    $v0,$t2         # if "-" is not included set return
	bne     $a1,$zero,isIntEx # return $a1=1
	sgt     $t0,$a0,44      #int > '-'-1
        slt     $t1,$a0,46      #int < '-'+1
	and     $t3,$t1,$t0     #(int = '-')        
        or      $v0, $t2,$t3    # $v0 = Int truth value returned
isIntEx:jr      $ra

#------isChar -- test for Char input $a0-address return TRUE=1 if it is Char (In use $t0,$t1,$t2,$t3)
isChar:
        sgt     $t0,$a0,64      #char > 'A'-1
        slt     $t1,$a0,91      #char < 'Z'+1
        and     $t2,$t1,$t0     #(char >= 'A' and char <= 'Z')
        sgt     $t0,$a0,96      #char > 'a'-1
        slt     $t1,$a0,123     #char < 'z'+1
	and     $t3,$t1,$t0     #(char >= 'a' and char <= 'z')        
        or      $v0, $t2,$t3    # $v0 = Int truth value returned
	jr $ra

#--fInt----FIND_INTEGER--------------------------------
	#--$a0-address of the string ,$a1- address of the arg 
	#--$V0-address in the string where find was returned
	#--$v1 - TRUE=1 if int is found
	#--(In use $t0,$t1,$t2,$t3+v0(IsInt)+$t4,$t5,$t6,$t7)
fInt:	  add $sp,$sp,-4
	  sw $ra,($sp)
          move $t4,$a0    # address of the string
	  move $t8,$a0    # STOP address =$v0
	  move $t5,$a1	  # address of the argument
	  move $v1,$zero  # set output to zero
	  addi $t7,$zero,1 # holds one	  

	# move to the first int char
fInt2:	 lb $t6,($t4)         # load char  from address
	 beq $t6,$zero,fInt1  # end of the line
	 addi $t4,$t4,1	      #  next char
		# Call isInt test if the shar is int
	 	move $a0,$t6	      # input for function isInt      
	 	addi $a1,$zero,0      # chars "0-9"+"-"
		jal isInt	      # test if the char is int 
	 beq $v0,$zero,fInt2  # if char is not int brach
		
        # start position of the int 
	#int colud be "-" or "0-9" 
	 sb $t6,($t5)         #	 copy int to arg
	 addi $t5,$t5,1	      #  next empty space in arg
	#int colud be "0-9" 
fInt3:	 
	  lb $t6,($t4)         # load char  from address
	  move $t8,$t4         # the address where we STOPed	
	 beq $t6,$zero,fInt1  # end of the line
	   addi $t4,$t4,1	      #  next char
		# Call isInt test if the shar is int
	 	move $a0,$t6	      # input for function isInt      
	 	addi $a1,$zero,1      # chars "0-9"
		jal isInt	      # test if the char is int 
	 beq $v0,$zero,fInt1  # if char is not int exit the func
	
	 sb $t6,($t5)         #	 copy int to arg
	 addi $t5,$t5,1	      #  next empty space in arg
	 move $v1,$t7         # set output to one
 	 bne $v0,$zero,fInt3  # if char is int brach	

fInt1:	move $v0,$t8
	lw $ra,($sp)
	add $sp,$sp,4
    jr $ra

#--ffloat----FIND_FLOAT--------------------------------
	#--$a0-address of the string ,$a1- address of the arg
	#--$V0-address in the string where find was returned  
	#--$v1 - TRUE=1 if float is found
	#--(In use $t0,$t1,$t2,$t3+v0(IsInt)+$t4,$t5,$t6,$t7,$t8)
ffloat:	  addi $sp,$sp,-4
	  sw $ra,($sp)
          move $t4,$a0    # address of the string
	  move $t8,$a0    # STOP address =$v0
	  move $t5,$a1	  # address of the argument
	  move $v1,$zero  # set output to zero	  	  

	# move to the first float char
ffloat2: lb $t6,($t4)         # load char  from address
	 beq $t6,$zero,ffloat1  # end of the line
	 addi $t4,$t4,1	      #  next char
		# Call isInt test if the shar is int
	 	move $a0,$t6	      # input for function isInt      
	 	addi $a1,$zero,0      # chars "0-9"+"-"
		jal isInt	      # test if the char is int 
	 beq $v0,$zero,ffloat2  # if char is not int brach
		
        # start position of the float

	# char could be "-" or "0-9"
	 sb $t6,($t5)         #	 copy float to arg
	 addi $t5,$t5,1	      #  next empty space in arg
	
	# char could be only "0-9"
ffloat3:  	 
	  lb $t6,($t4)         # load char  from address
	 move $t8,$t4         # the address where we STOPed 
	 beq $t6,$zero,ffloat1  # end of the line
	 addi $t4,$t4,1	      #  next char
		# Call isInt test if the char is int
	 	move $a0,$t6	      # input for function isInt      
	 	addi $a1,$zero,1      # chars "0-9"
		jal isInt	      # test if the char is int 
	 beq $v0,$zero,ffloat4  # if char is not float ,check if it is dot
	
	 sb $t6,($t5)         #	 copy int to arg
	 addi $t5,$t5,1	      #  next empty space in arg	 
 	 addi $v1,$zero,1     # set output to one
	 bne $v0,$zero,ffloat3  # if char is float brach
	
	# char should be "." , otherwise exit
ffloat4: addi $t7,$t6,-46
	 bne  $t7,$zero,ffloat1  
         sb $t6,($t5)         #	 copy float to arg
	 addi $t5,$t5,1	      #  next empty space in arg
	
	# char could be only "0-9"
ffloat5:  	 
	  lb $t6,($t4)         # load char  from address
	  move $t8,$t4         # the address where we STOPed
	 beq $t6,$zero,ffloat1  # end of the line
	  addi $t4,$t4,1	      #  next char
		# Call isInt test if the char is int
	 	move $a0,$t6	      # input for function isInt      
	 	addi $a1,$zero,1      # chars "0-9"
		jal isInt	      # test if the char is int 
	 beq $v0,$zero,ffloat1  # if char is not float exit the func
	
	 sb $t6,($t5)         #	 copy int to arg
	 addi $t5,$t5,1	      #  next empty space in arg	 
 	 addi $v1,$zero,1     # set output to one
	 bne $v0,$zero,ffloat5  # if char is float brach	


ffloat1: move $v0,$t8
	lw $ra,($sp)
	addi $sp,$sp,4
    jr $ra

#--fchar----FIND_char--------------------------------
fchar:	#--$a0-address of the string ,$a1- address of the arg
	#--$V0-address in the string where find was returned  
	#--$v1 - TRUE=1 if char is found
	#--(In use $t0,$t1,$t2,$t3+v0(IsChar)+$t4,$t5,$t6,$t7,$t8)

	  addi $sp,$sp,-4
	  sw $ra,($sp)
          move $t4,$a0    # address of the string
	  move $t8,$a0    # STOP address =$v0
	  move $t5,$a1	  # address of the argument
	  move $v1,$zero  # set output to zero
	  addi $t7,$zero,1 # holds one	
	
	# move to the first int char
fchar2:	 lb $t6,($t4)         # load char  from address
	
	 beq $t6,$zero,fchar1  # end of the line
	 addi $t4,$t4,1	      #  next char
		# Call isChar test if the shar is int
	 	move $a0,$t6	      # input for function isChar 	 	 
		jal isChar	      # test if the char is char
	 beq $v0,$zero,fchar2  # if char is not int brach
		
        # start position of a char	 
	 sb $t6,($t5)         #	 copy char to arg
	 move $t8,$t4         # the address where we STOPed
	 addi $v1,$zero,1     # set output to zero

fchar1: move $v0,$t8
	lw $ra,($sp)
	addi $sp,$sp,4
    jr $ra

# ----getI --- save input from I/O(stdin) into temp-----------
#   (in use $t0,$t1(getchar)+ $t2)
   
getI:	add $sp,$sp,-4
	sw $ra,($sp)
        la $t2,temp  #temp array to store input      

getI1:		
	#--------GETCHAR  jal getchar
		jal getchar
	#--------GETCHAR ----end----
	# ---- print char ----- 					
	move $t3,$v0						
	li $v0, 11 	# load appropriate system call code into register $v0;
			# code for printing string is 4
	move $a0,$t3	# load address of string to be printed into 
	syscall
	move $v0,$t3

	sb $v0,($t2)
        addi $t2,$t2,1
	addi $t3,$v0,-10
	bne $t3,$zero,getI1  # branch if it is not end of line
  	sb $zero,($t2)
	
	lw $ra,($sp)
	add $sp,$sp,4
    jr $ra

#-------findArg----------find type of arg in the string $s2 and store them into tempS
	# --- $a0 --- address of the string
	
findArg:
	add $sp,$sp,-4
	sw $ra,($sp)
        move $t0,$a0
	la $t1,tempS  #temp array to store input

findArg1:      
	lb $t2,($t0)	
	add $t4,$t2,-37         # % = 37 ascii 
	beq $t2,$zero,findArg2  # if end of line save and exit
	addi $t0,$t0,1          #   increment address
	bne $t4,$zero,findArg1  # if it is %, then save the char after the %
	
findArg2:
	lb $t3,($t0)
	sb $t3,($t1)
	addi $t1,$t1,1          #   increment address
	bne $t2,$zero,findArg1  # end of line - exit
			
	lw $ra,($sp)
	add $sp,$sp,4
    jr $ra      



#--iscanf(string,arg1,arg2)-----------------------------------
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
#-------------------------------------------------------------
iscanf:			add $sp,$sp,-36
	  		sw $ra,0($sp)			
	  		sw $s0,4($sp)			
	  		sw $s1,8($sp)			
	  		sw $s2,12($sp)			
	  		sw $s3,16($sp)			
	  		sw $s4,20($sp)			
	  		sw $s5,24($sp)			
	  		sw $s6,28($sp)
			sw $s7,32($sp)			
	  	move $s0,$a0
		move $s1,$a1
		move $s2,$a2
    #.... find type of arg in the string $s2 and store them into tempS....(call findArg)
     			move $a0,$a2
			jal findArg
			la $s2,tempS

	#.... load the value of arg from stdin and store string into temp (function getI)....
 			jal getI
			la $s6,temp
		
		move $s7,$zero	#  number or arg loaded
		
iscanf1:	#load arg from stdin into agr - array

		addi $s0,$s0,-4   #  move ponter on the stack
		lw $s3,($s0)      #  address of the argument
		lb $s4,($s2)      #   type of the argument (char , int , float)
		addi $s2,$s2,1    #   move pointer to the next type of the argument
		
		

		move $a0,$s6   # same for all function
		move $a1,$s3   # same for all function
		#--- check if the type of arg is integer  (d=100ascii)--
		addi $s5,$s4,-100
		bne $s5,$zero,iscanf2  # is not "d"  check next
		
			#  *********call fint**********
			jal fInt
			move $s6,$v0       # stop address is the start address for next search of the string
			add  $s7,$s7,1	   # add new load
		
		j iscanfL  # end of the Integer
		
iscanf2:	#--- check if the type of arg is float  (f=102ascii)--    
		addi $s5,$s4,-102
		bne $s5,$zero,iscanf3  # is not "f"  check next


			#  *********call ffloat**********
			jal ffloat
			move $s6,$v0       # stop address is the start address for next search of the string
			add  $s7,$s7,1	    # add new load

		j iscanfL  # end of the Float

iscanf3:	#--- check if the type of arg is char  (c=99ascii)-- #	
		addi $s5,$s4,-99
		bne $s5,$zero,iscanf4  # is not "c"  check exit or write message "type is wrong"


			#  ********* call fchar**********
			jal fchar
			move $s6,$v0       # stop address is the start address for next search of the string
			add  $s7,$s7,1	    # add new load

		j iscanfL  # end of the char


iscanf4:               				# error message "type is wrong"
						li $v0, 4 	# load appropriate system call code into register $v0;
								# code for printing string is 4
						la $a0,str5	# load address of string to be printed into 
						syscall		# call operating system

iscanfL:
		add $s1,$s1,-1         #  decrease number of arg ($s1)
		bne $s1,$zero,iscanf1  # if there is more arg brunch   

iscanfEx:
                        move $v0,$s7
		
	  		lw $ra,0($sp)			
	  		lw $s0,4($sp)			
	  		lw $s1,8($sp)			
	  		lw $s2,12($sp)			
	  		lw $s3,16($sp)			
	  		lw $s4,20($sp)			
	  		lw $s5,24($sp)			
	  		lw $s6,28($sp)
			lw $s7,32($sp)	  		
			add $sp,$sp,36	
		jr $ra


#--iprintf(string,arg1,arg2)-----------------------------------
	#$a0 - address of $fp (address of arg's addresses)
	#$a1 - number of arg
	#$a2 - address of the string 
	#$v0  - number of valid reading
#-------------------------------------------------------------
iprintf:		add $sp,$sp,-36
	  		sw $ra,0($sp)			
	  		sw $s0,4($sp)			
	  		sw $s1,8($sp)			
	  		sw $s2,12($sp)			
	  		sw $s3,16($sp)			
	  		sw $s4,20($sp)			
	  		sw $s5,24($sp)			
	  		sw $s6,28($sp)
			sw $s7,32($sp)			
	  	move $s0,$a0  
		move $s1,$a1
		move $s2,$a2  # address of the string

		addi $s0,$s0,-4   #  move ponter on the stack
		lw $s3,($s0)      #  address $s3 of the argument
		
iprintf1:      
	lb $s4,($s2)	
	add $s5,$s4,-37         # % = 37 ascii 
	beq $s4,$zero,iprintfEx  # if end of line  exit
	  # --- put char --  with address $s2--- 
	         move $a0,$s2              
		 jal putchar
			                      
				
	addi $s2,$s2,1          #   increment address
	bne $s5,$zero,iprintf1  # if it is %, then print arg
	
	
	#  ---print arguments---
	               addi $s2,$s2,1   ##  skip type of arg
iprintf2:	
	lb $s6,($s3)
	   # --- put char --  with address $s3--- 
			move $a0,$s3
			jal putchar
				
	addi $s3,$s3,1 
	bne $s6,$zero,iprintf2
	# -- move address to the next argument on the stack
		addi $s0,$s0,-4   #  move ponter on the stack
		lw $s3,($s0)      #  address of the argument
	j iprintf1 

iprintfEx:			
	  		lw $ra,0($sp)			
	  		lw $s0,4($sp)			
	  		lw $s1,8($sp)			
	  		lw $s2,12($sp)			
	  		lw $s3,16($sp)			
	  		lw $s4,20($sp)			
	  		lw $s5,24($sp)			
	  		lw $s6,28($sp)
			lw $s7,32($sp)	  		
			add $sp,$sp,36	
	jr $ra



#-----EXIT-----------
Exit:
	li $v0,10	 # load appropriate system call code into register $v0;
			 # code for sys exit is 10
	syscall 	 # call operating system





#-----------DATA--------------------------------------------

.data
#--- the first iscanf----
scf1Str:	.asciiz "%c %d"
scf1Arg1:	.space 1024
scf1Arg2:	.space 1024

#--- the second iscanf----
scf2Str:	.asciiz "%c %f"
scf2Arg1:	.space 1024
scf2Arg2:	.space 1024

temp:	.space  1024
tempS:	.space  1024

#--- the first iprintf----
prt1Str:	.asciiz "\nCategory: %c    Elevation: %d m."
prt1Arg1:	.asciiz "C"
prt1Arg2:	.asciiz "-1234"
#--- the second iprintf----
prt2Str:	.asciiz "\nThe arguments of the second iscanf are: scf2Arg1: %c , scf2Arg2: %f!"
     #  the second iprintf uses the arg location of the secon iscenf



#---messages-------
str1: .asciiz "\nType two arguments character and integer\n[Example: iscanf(''%c %d'',scf1Arg1,scf1Arg2)] with StdIn <cefta -123 d> will save scf1Arg1='c' and scf1Arg1='-123'. ]\n"
str2: .asciiz "\nThe first  iprintf(''Category: %c    Elevation: %d m'',prt1Arg1,prt1Arg2) prints:\n"
str3: .asciiz "\n\nType two arguments character and float\n[Example: iscanf(''%c %f'',scf2Arg1,scf2Arg2)] with StdIn <cefta -12.3 d> will save scf2Arg1='c' and scf2Arg1='-12.3'. ]\n"

str4: .asciiz "\n"
str5: .asciiz "\nWrong type!(c,d,f)\n"
str6: .asciiz "The arguments value of the first iscanf, printed with syscall from the main, are:"
str7: .asciiz  "\tThe value of the first argument (cf1Arg1) is :"
str8: .asciiz  "\tThe value of the second argument (cf1Arg2) is :"






#-----EXCEPTION-------------------------
.ktext 0x80000180  # MIPS jumps to here on an exception


	sw $a0, save0   # save registers that will be used by  this routine on memory
	sw $a1, save1   # move EPC to $k1
	sw $a2, save2
	la $a3,Exit
	sw $a3,save3

	mfc0  $k0,$13   # move cause register to $k0
	mfc0  $k1,$14

	sgt $v0,$k0,0x44
	bgt $v0,$zero,done	# if it is an interrupt, ignore(or we should do Vice versa)

	move $a0,$k0
	move $a1,$k1

	jal print_excp

done:
	lw $a0,save0
	lw $a1,save1
	lw $a3,save2
	addiu $k1,$k1,4   # will return to saved PC + 4
	rfe	# restore interrupted state

	jr $k1

print_excp:
		li $v0, 4 	# load appropriate system call code into register $v0;
				# code for printing string is 4
		la $a0, pr1	# load address of string to be printed into $a0
		syscall		# call operating system	
	
	lw $a0,save0  # address of data traying to print
         	li $v0, 1 	# load appropriate system call code into register $v0;
				# code for printing int is 1		
		syscall		# call operating system

		li $v0, 4 	# load appropriate system call code into register $v0;
				# code for printing string is 4
		la $a0, pr2	# load address of string to be printed into $a0
		syscall		# call operating system	
	
	lw $a3,save3  # jump to exit    (This is the first choice to exit the program)
	addi $a1,$a1,4  #return address plus 4 (Or the second choice is to continue with next inst after the one which cause exception)
 	jr $a3  #(I chose exit..)

#----------KDATA-----------------------------
.kdata
save0: .word 0
save1: .word 0
save2: .word 0
save3: .word 0

pr1: .asciiz "\n''IPRINTF EXCEPTION WITH ADDRESS:<  "
pr2: .asciiz "  >''\n "