
.globl __start

.eqv  testSym,3

.include "..\..\SrcAll\BasicMacros_Mars.asm"

.macro MonitorA0A1RAPCm
	push $ra
		move $t6,$ra
		jal MonitorA0A1RAPC
		nop
	pop $ra
.end_macro

.text
__start:

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  


	li $ra,0
	MonitorA0A1RAPCm	#;Show Starting point
	jal NewLine  
	nop
	#;j TestBasicMaths
	
	#;j TestMemory
	#;j TestJumps
	j TestDelays
#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
TestBasicMaths:	
	
    li $a0,192			#;Load 192 in decimal (0xC0)
    li $a1,0xFFEEDDCC	#;Load a hexadecimal value into A0
	li $a2,'A'			#;load 'A' in ascii (0x41)
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	
	li $a0,testSym		#;Load a symbol
    li $a1,testSym		#;Load a symbol
	li $a2,testSym		#;Load a symbol
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	
	li $a0,0x01020304	#;Load a hexadecimal value into A0
	move $a1,$a0		#;Move A0->A1
	move $a2,$a0		#;Move A0->A2
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	
	li $a0,192			#;Load 192 in decimal (0xC0)
	addi $a1,$a0,1		#; Add 1 to A0, store result in A1
	addi $a2,$a0,-1		#; Subtract 1 from A0, store result in A2
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	
	li $a0,192			#;Load 192 in decimal (0xC0)
	li $a2,0x00000100	#;Value to add or subtract
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop

	add $a1,$a0,$a2		#;A1 = A0+A2
	sub $a0,$a0,$a2		#;A0 = A0-A2
	jal MonitorA0A1A2 
	nop
	
	j Shutdown
#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
TestMemory:
	
	li $a1,0				#;Clear a1
	
	la $t7,TestData		#;Address
	li $t6,2				#;Line Count
	jal MemDump			#;Dump Ram to screen
	nop
	
	jal NewLine  
	nop
	
	la $a2,TestData		#;Load address of TestData
	lw $a0,($a2)			#;Load Word into A0 from address in A2
	jal MonitorA0A1A2 	
	nop
	
	lhu $a0,($a2)			#;Load Byte (other bits 0)
	lh $a1,($a2)			#;Load Byte (other bits bit7)
	jal MonitorA0A1A2 	
	nop
	
	lbu $a0,($a2)			#;Load Byte (other bits 0)
	lb $a1,($a2)			#;Load Byte (other bits bit7)
	jal MonitorA0A1A2 	
	nop
	
	jal NewLine  
	nop
	
	la $t7,TestData		#;Address
	li $t6,2				#;Line Count
	jal MemDump			#;Dump Ram to screen
	nop
	
	lw $a0,($a2)			#;Load Word into A0 from address in A2
	jal MonitorA0A1A2 	
	nop
	
	jal NewLine  
	nop
	
	sw $a2,($a2)			#;Store Word from A0 into address in A2
	sw $a0,4($a2)			#;Store Word from A0 into address in A2+4
		
	sh $a0,8($a2)			#;Store HalfWord from A0 into address in A2+8
	
	sb $a0,12($a2)		#;Store Byte from A0 into address in A2+12
	
	la $t7,TestData		#;Address
	li $t6,2				#;Line Count
	jal MemDump			#;Dump Ram to screen
	nop
	
	#;la a2,PrintString	#;This doesn't work as its not in the data area

	j Shutdown
	nop

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TestJumps:	

	j JumpTest1			#;Jump to a label
	nop
ReturnFromJumpB:
	
	la $a0,JumpTest		#;Jump to address in Register
	jr $a0
	nop
ReturnFromJump:

	jal JumpTest3		#;Jump And Link to label (PC->RA)
	nop

	la $a0,JumpTest2		
	jalr $a0		#;Jump And Link to address in Register (A0->RA)
	nop
	
	la $a0,JumpTest2b
	jalr $a1,$a0	#;Jump And Link to label (PC->A1)
	nop

	#;jalr ra,a0,0		#;Alternate form of JALR command
	
	jal NewLine  	
	nop
	j Shutdown
	nop
	
JumpTest:
	MonitorA0A1RAPCm
	la $a2,JumpToRegister
	jal PrintString
	nop
	push $ra
		jal NewLine       
		nop
	pop $ra
	j ReturnFromJump
  
JumpTest1:
	MonitorA0A1RAPCm
	la $a2,JumpTo
	jal PrintString
	nop
	push $ra
		jal NewLine       
		nop
	pop $ra
	j ReturnFromJumpB
	
JumpTest2:
	MonitorA0A1RAPCm
	push $ra
		la $a2,JumpAndLinkToRegister
		jal PrintString
		nop
		jal NewLine       
		nop
	pop $ra
	jr $ra
	
JumpTest2b:
	MonitorA0A1RAPCm
	push $a1
		la $a2,JumpAndLinkToRegister
		jal PrintString
		nop
		jal NewLine       
		nop
	pop $a1
	jr $a1 #;ret

	
JumpTest3:
	MonitorA0A1RAPCm
	push $ra
		la $a2,JumpAndLinkTo
		jal PrintString
		nop
		jal NewLine       
		nop
	pop $ra
	jr $ra	#;jr RA
	

TestDelays:

#; Load Delay slot test - Emulators don't emulate this - so beware!!!
	la $a0,TestData		#;Load a symbol
	lw $a1,0($a0)		
	ori $a1,$a1,0xFF	#;Load Delay slot - This may not occur correctly


#; branch Delay slot test - Emulators do emulate this (if you turn it on!)
	
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	ori $a2,$a2,0x00FF	#; In delay slot, occurs BEFORE JAL
	
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	ori $a2,$a2,0xFF00	#; after delay slot, occurs AFTER JAL
	
	jal NewLine         
	nop
		
	li $a0,0x4
LoopTest1:	
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	addi $a0,$a0,-1
	bne $a0,$0,LoopTest1
	nop					#;We didn't use the delay slot
	
	jal NewLine         
	nop
	
	li $a0,0x4
LoopTest2:
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen
	nop
	bne $a0,$0,LoopTest2
	addi $a0,$a0,-1			#;Loop DEC now in delay slot! - Runs AFTER the check, so a repeat occurs for Zero
	nop
	
	
	jal NewLine  	
	nop					#; I'm putting a NOP in the delayslots for simplicity... but we can use them!
	j Shutdown
	nop
	
Shutdown:
  #; ends the program with status code 0
	li $v0, 10          
	syscall
 #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 

MonitorA0A1RAPC:
	pushAs
	push $ra
		push $t6
			li $t5,'a'
			li $t6,'0'
			move $t7,$a0
			jal ShowRegTextB             #   ;A5 A6 : A7
			nop
			li $t5,'a'
			li $t6,'1'
			move $t7,$a1
			jal ShowRegTextB             #   ;A5 A6 : A7
			nop
			li $t5,'r'
			li $t6,'a'
		pop $t7
		jal ShowRegTextB             #   ;A5 A6 : A7
		nop
		li $t5,'p'
		li $t6,'c'
	pop $t7
	push $t7
		jal ShowRegTextB             #   ;A5 A6 : A7  
		nop
	pop $ra
	popAs
	jr $ra
	nop
 
MonitorA0A1A2:
	push $ra
	pushAs
	pushTs
	    li $t5,'a'
		li $t6,'0'
		move $t7,$a0
		jal ShowRegTextB             #   ;A5 A6 : A7
		nop
		li $t5,'a'
		li $t6,'1'
		move $t7,$a1
		jal ShowRegTextB             #   ;A5 A6 : A7
		nop
		li $t5,'a'
		li $t6,'2'
		move $t7,$a2
		jal ShowRegTextB             #   ;A5 A6 : A7
		nop
		jal NewLine         
		nop
	popTs
	popAs
	pop $ra
	jr $ra
	nop
  
.include "..\..\SrcAll\monitor_Mars.asm"  
.include "..\..\SrcAll\BasicFunctions_Mars.asm"  
  
#;All Data must go in the Data Segment - cannot read from code segment
.data
TestData:	#;Little Endian - so this is $F3F2F1F0
	.byte 0xF0,0xF1,0xF2,0xF3	
	.byte 0,0,0,0,0,0,0,0,0,0,0,0
	
JumpAndLinkTo: 
  .ascii "JAL "
  .byte 255 
JumpTo: 
  .ascii "J   "
  .byte 255 
JumpToRegister: 
  .ascii "JR  "
  .byte 255 
JumpAndLinkToRegister: 
  .ascii "JALR"
  .byte 255 