1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
.syntax unified
.cpu cortex-m0plus
.thumb
.type getline, %function
.global getline
getline:
PUSH {R4, R5, LR} // save registers
MOVS R4, R0 // put strbuf in R4
next: BL uart_recv // get a char
CMP R0, 0x03 // end of text (^C)
BEQ cancel // don't submit, start on next line
CMP R0, 0x04 // end of transmission (^D)
BEQ done // begin of line done, in a line submit the line
CMP R0, 0x7F // delete (backspace)
BEQ back // in a line go back a space, begin of line do nothing
CMP R0, 0x0D // carriage return (Enter)
BEQ submit // submit the line
CMP R0, 0x15 // NAK (^U)
BEQ retry // restart the line
// CMP R0, 0x1B // Escape (ESC)
// BEQ address // enter a new address to edit at
CMP R0, 0x20 // start of printable range
BLO next
CMP R0, 0x7E // end of printable range
BHI next
good: BL uart_send // echo the printable char
STRB R0, [R4, R5] // write the printable char
ADDS R5, 1 // increment strbuf offset
B next // get another char
cancel: MOVS R5, 0 // reset offset
STRB R5, [R4, R5] // write empty string
LDR R0, =crlf // newline
BL putstr
MOVS R0, 1 // error code 1 (line canceled)
POP {R4, R5, PC} // return
done: TST R5, R5 // check if offset is zero
BNE submit // if not zero submit line
STRB R5, [R4, R5] // clear input buffer
LDR R0, =crlf // newline
BL putstr
MOVS R0, 2 // error code 2 (end of input)
POP {R4, R5, PC} // return
back: TST R5, R5 // check if offset is zero
BEQ next // if so get another char
SUBS R5, 1 // push back offset
MOVS R0, 0 // null byte
STRB R0, [R4, R5] // delete character
MOVS R0, 0x08 // backspace
BL uart_send // move cursor back
MOVS R0, ' // space
BL uart_send // overwrite
MOVS R0, 0x08 // backspace
BL uart_send // move cursor back again
B next // get another char
submit: MOVS R0, 0 // null byte
STRB R0, [R4, R5] // terminate string
MOVS R0, 0x0D // carriage return
BL uart_send
MOVS R0, 0x0A // line feed
BL uart_send
MOVS R0, 0 // return code 0 (success)
POP {R4, R5, PC}
retry: MOVS R0, 0x08 // backspace
MOVS R1, ' // space
MOVS R2, R5 // repeat once per character
MOVS R5, 0 // reset offset
TST R2, R2 // check if already zero
1: BEQ 2f // while not zero
STRB R0, [R4, R5] // write backspace
ADDS R5, 1
STRB R1, [R4, R5] // write space
ADDS R5, 1
STRB R0, [R4, R5] // write backspace
ADDS R5, 1
SUBS R2, 1 // decrement amount
B 1b // repeat
2: STRB R2, [R4, R5] // terminate string
MOVS R0, R4 // copy strbuf address
BL putstr // print backspace sequence
MOVS R5, 0 // null byte and reset offset
STRB R5, [R4] // write empty string
B next // get new chars
|