@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Program part 0: initial declarations
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.globl _start

.equ RXFE, 0x10
.equ TXFF, 0x20

.equ OFFSET_FR, 0x018
.equ IO_ADDRESS, 0x101f1000

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Program part 1: definition of main.
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	
_start:        
	mov sp,#0x100000		@ set up stack
	
	@ program main body
	ldr r4,=IO_ADDRESS		@ r4 := 0x 101f 1000
	ldr r0,=string_start
	bl print_string
	
wait:
	ldr r2,[r4,#OFFSET_FR]		@ load flag register
	and r3,r2,#RXFE			@ mask non receive fifo empty bits
	cmp r3, #0			@ r3 == 0?
	bne wait			@ wait until ready
	
	ldr r1,[r4]

	ldr r0,=string_received
	bl print_string
	str r1,[r4]		@ echo typed character to screen
	bl newline
	
	@ quit if q found
	cmp r1,#'q'
	ldreq r0,=string_quit
	bleq print_string
	beq program_exit

	@ else, repeat echoing characters
	b wait

program_exit:		@ print "END" on a new line
	mov r1, #'\r'
	str r1, [r4]		
	mov r1, #'\n'		
	str r1, [r4]		
	mov r1, #'E'		
	str r1, [r4]		
	mov r1, #'N'		
	str r1, [r4]		
	mov r1, #'D'		
	str r1, [r4]

the_end:			@ do infinite loop at the end
	b the_end	


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Program part 2: definition of functions
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

print_end:
	@ preamble
	push {r1, r4, lr}

	@ main body
	ldr r4,=IO_ADDRESS		@ r4 := 0x 101f 1000
	mov r1, #13
	str r1, [r4]		
	mov r1, #10		
	str r1, [r4]		
	mov r1, #'E'		
	str r1, [r4]		
	mov r1, #'N'		
	str r1, [r4]		
	mov r1, #'D'		
	str r1, [r4]		

	@ wrap-up
	pop {r1, r4, lr}
	bx lr

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

newline:
	@ preamble
	push {r2, r4, lr}

	@ main body
	ldr r4,=IO_ADDRESS		@ r4 := 0x 101f 1000
	mov r2, #'\n'
	str r2,[r4]
	mov r2, #'\r'
	str r2,[r4]

	@ wrap-up
	pop {r2, r4, lr}
	bx lr


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ r0 should be address of first character of string to display
print_string:
	@preamble
	push {r0,r4,r5,lr}

	@ main body
	ldr r4,=IO_ADDRESS		@ r0 := 0x 101f 1000

str_out:
	ldrb r5,[r0]
	cmp r5,#0x00	@ '\0' = 0x00: null character?
	beq str_done	@ if yes, quit
	str r5,[r4]		@ otherwise, write character
	add r0,r0,#1	@ go to next character
	b str_out		@ repeat

	@ wrap-up
str_done:
	pop {r0,r4,r5,lr}
	bx lr

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Program part 3: data
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	

string_start:
	.asciz "Starting echo program\n\r"

string_received:
	.ascii "received character: "
	.byte 0x00

string_quit:
	.ascii "exiting echo program\n\r"
	.word 0x00
