// File: AndreRenaud[P]simple_uart/simple_uart.c
// Function: simple_uart_read_line
ssize_t simple_uart_read_line(struct simple_uart *uart, char *buffer, int max_len, uint64_t ms_timeout)
{
    int pos = 0;
    uint64_t last = mseconds();
    uint64_t now = mseconds();

    if (!uart || !buffer || max_len <= 0)
        return -EINVAL;

    *buffer = '\0';

    do {
        char ch;
        ssize_t ret = simple_uart_read(uart, &ch, 1);
        if (ret < 0)
            return ret;
        if (ret > 0) {
            if (ch == '\n' || ch == '\r') {
                break;
            } else {
                last = mseconds();
                buffer[pos] = ch;
                buffer[pos + 1] = '\0';
                pos++;
            }
        }
        now = mseconds();
    } while (pos < max_len - 1 && now - last < ms_timeout);

    /* If we got a carriage return + line feed, just collapse them */
    while (pos > 0 && (buffer[pos - 1] == '\r' || buffer[pos - 1] == '\n')) {
        buffer[pos - 1] = '\0';
        pos--;
    }

    if (now - last >= ms_timeout)
        return -ETIMEDOUT;

    return pos;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x1, %edi
leaq -0x48(%rbp), %rsi
callq 0x20e0
imulq $0x3e8, -0x48(%rbp), %rax # imm = 0x3E8
movq %rax, -0xc0(%rbp)
movq -0x40(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
cqto
idivq %rcx
movq %rax, %rcx
movq -0xc0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x1, %edi
leaq -0x68(%rbp), %rsi
callq 0x20e0
imulq $0x3e8, -0x68(%rbp), %rax # imm = 0x3E8
movq %rax, -0xb8(%rbp)
movq -0x60(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
cqto
idivq %rcx
movq %rax, %rcx
movq -0xb8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x7e8d
cmpq $0x0, -0x18(%rbp)
je 0x7e8d
cmpl $0x0, -0x1c(%rbp)
jg 0x7e9a
movq $-0x16, -0x8(%rbp)
jmp 0x8094
movq -0x18(%rbp), %rax
movb $0x0, (%rax)
movq -0x10(%rbp), %rdi
leaq -0x71(%rbp), %rsi
movl $0x1, %edx
callq 0x6600
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jge 0x7ecb
movq -0x80(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x8094
cmpq $0x0, -0x80(%rbp)
jle 0x7f6a
movsbl -0x71(%rbp), %eax
cmpl $0xa, %eax
je 0x7ee8
movsbl -0x71(%rbp), %eax
cmpl $0xd, %eax
jne 0x7eed
jmp 0x7ff5
movl $0x1, %edi
leaq -0x90(%rbp), %rsi
callq 0x20e0
imulq $0x3e8, -0x90(%rbp), %rax # imm = 0x3E8
movq %rax, -0xc8(%rbp)
movq -0x88(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
cqto
idivq %rcx
movq %rax, %rcx
movq -0xc8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x38(%rbp)
movb -0x71(%rbp), %dl
movq -0x18(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x18(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x7f6a
movl $0x1, %edi
leaq -0xa8(%rbp), %rsi
callq 0x20e0
imulq $0x3e8, -0xa8(%rbp), %rax # imm = 0x3E8
movq %rax, -0xd0(%rbp)
movq -0xa0(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
cqto
idivq %rcx
movq %rax, %rcx
movq -0xd0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x58(%rbp)
movl -0x2c(%rbp), %ecx
movl -0x1c(%rbp), %edx
subl $0x1, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xd1(%rbp)
jge 0x7fe7
movq -0x58(%rbp), %rax
subq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
setb %al
movb %al, -0xd1(%rbp)
movb -0xd1(%rbp), %al
testb $0x1, %al
jne 0x7ea1
jmp 0x7ff7
xorl %eax, %eax
cmpl $0x0, -0x2c(%rbp)
movb %al, -0xd2(%rbp)
jle 0x804c
movq -0x18(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %ecx
movb $0x1, %al
cmpl $0xd, %ecx
movb %al, -0xd3(%rbp)
je 0x8040
movq -0x18(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xa, %eax
sete %al
movb %al, -0xd3(%rbp)
movb -0xd3(%rbp), %al
movb %al, -0xd2(%rbp)
movb -0xd2(%rbp), %al
testb $0x1, %al
jne 0x8058
jmp 0x8074
movq -0x18(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movl -0x2c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x7ff7
movq -0x58(%rbp), %rax
subq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
jb 0x808c
movq $-0x6e, -0x8(%rbp)
jmp 0x8094
movslq -0x2c(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)