@ XXX: All items in data section might require double address. See `test.s'
	.include	"features.inc"
	.set	BUFFER_SIZE, 512
	.section	.data

# Reserve BUFFER_SIZE bytes
	.type	buffer, %object
buffer:
	.space	BUFFER_SIZE

# Current location in the buffer. Initially set to zero
	.type	index, %object
index:
	.long	0

# The length of string. Initially set to zero
	.type	length, %object
length:
	.long	0

# Flag for end of file. Initially set to false
	.type	end_flag, %object
end_flag:
	.long	0

	.section	.text
	.syntax	divided
	.type	read_string, %function
read_string:
	ldr	r1, end_flag_adr
	ldr	r2, [r1]
	cmp	r2, #0
	beq	read_string.poke	@ Read file if the end has not been found
	mov	r0, #0			@ Nothing to read
	str	r0, [r1]		@ Set end_flag to false
	b	read_string.reset
read_string.poke:
	ldr	r1, buffer_adr
	mov	r2, #BUFFER_SIZE
	.ifdef	NetBSD
	swi	#10485763		@ 10485760 + read system call number
	.else
	str	r7, [sp, #-4]!		@ Preserve R7
	mov	r7, #3			@ Read system call number
	swi	#0
	ldr	r7, [sp], #4		@ Restore R7
	.endif
	cmp	r0, #0
	bmi	read_string.end		@ Return immediately if an error occured
	cmp	r0, #BUFFER_SIZE
	beq	read_string.reset	@ The end has yet to be found
	mov	r1, #1
	ldr	r2, end_flag_adr
	str	r1, [r2]		@ Set end_flag to true
read_string.reset:
	ldr	r1, length_adr
	str	r0, [r1]		@ Set length
	ldr	r2, index_adr
	mov	r1, #0
	str	r1, [r2]		@ Set index to zero
read_string.end:
	RET
end_flag_adr:
	.long	end_flag

@ Not a leaf function
	.global get_line
	.type	get_line, %function
get_line:
	stmdb	sp!, {fp, lr}		@ Preserve FP and LR
	mov	fp, sp
	sub	sp, sp, #12		@ Allocate memory
	str	r0, [fp, #-4]		@ file descriptor
	str	r1, [fp, #-8]		@ buffer
	mov	r0, #0
	str	r0, [fp, #-12]		@ length = 0
get_line.compare_byte:
	ldr	r0, index_adr
	ldr	r0, [r0]
	ldr	r1, length_adr
	ldr	r1, [r1]
	cmp	r0, r1
	bne	get_line.copy_byte	@ internal index <> internal length
	ldr	r0, [fp, #-4]		@ file descriptor
	bl	read_string
	cmp	r0, #0
	bmi	get_line.end		@ Return if an error occured
	beq	get_line.assign_length	@ Set length if nothing was read
get_line.copy_byte:
	ldr	r1, [fp, #-12]		@ Length
	ldr	r2, [fp, #-8]		@ Copy address of buffer
	ldr	r3, [r2, #-8]
	cmp	r1, r3
	beq	get_line.overflow	@ length == maximum length
	add	r2, r1			@ buffer = buffer + length
	add	r1, r1, #1
	str	r1, [fp, #-12]		@ length = length + 1
	ldr	r1, index_adr
	ldr	r1, [r1]
	ldr	r0, buffer_adr
	ldrb	r3, [r0, r1]		@ Get next byte in internal buffer
	strb	r3, [r2]		@ ^buffer = byte
	add	r1, r1, #1
	ldr	r2, index_adr
	str	r1, [r2]		@ internal index = internal index + 1
	cmp	r3, #10
	bne	get_line.compare_byte	@ Assign the length if its a new-line character
get_line.assign_length:
	ldr	r0, [fp, #-12]		@ length
	ldr	r1, [fp, #-8]		@ Copy address of buffer
	str	r0, [r1, #-4]		@ Set length of string
	b	get_line.end
get_line.overflow:
	mov	r0, #-35		@ Error number for string overflow
get_line.end:
	mov	sp, fp
	ldm	sp!, {fp, pc}		@ Restore FP and return
buffer_adr:
	.long	buffer
index_adr:
	.long	index
length_adr:
	.long	length
