aboutsummaryrefslogtreecommitdiff
path: root/newasm/input.s
blob: f3db1e978f8af9c27628c5b778db9f4a36f54f03 (plain)
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          // copy buffer start address
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 buffer 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 buffer start 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