// File: /workspace/github_c_makefile_star2_O0/hamsternz[P]emulate-risc-v/uart.c
// Function: UART_get
int UART_get(struct region *r, uint32_t address, uint32_t *value) {
   uint32_t v = 0;
   char buffer[100];
   struct uart_data *data = r->data;

   if((address & 3) != 0) {
     fprintf(stderr,"Unaligned memory read 0x%08x\n", r->base+address);
     return 0;
   }

   if(address+4 > r->size) {
     fprintf(stderr,"Memory region boundary crossed at 0x%08x\n", r->base+address);
     return 0;
   }

   v = 0;

   switch(address) {
     case 0x00:
       v = (data->tx_count == UART_QUEUE_DEPTH) ? (1<<31) : 0;
       if(data->debug) {
         sprintf(buffer,"UART is %s to accept tx data",
           data->tx_count == UART_QUEUE_DEPTH ? "not ready" : "ready");
         display_log(buffer);
       }
       break;
     case 0x04:
       if(data->rx_count > 0) {
	 v = data->rx_fifo[data->rx_read_ptr];
	 data->rx_count--;
	 data->rx_read_ptr = (data->rx_read_ptr == UART_FIFO_SIZE-1) ? 0 : data->rx_read_ptr+1;

         if(data->debug) {
           sprintf(buffer,"UART rx queue read - 0x%03x", v);
	   display_log(buffer);
         }
       } else {
         v = (1<<31);
         if(data->debug) {
           display_log("UART rx queue is empty");
         }
       }
       break;
     case 0x08:
       v = 0;
       v |= data->tx_enable      ? 1 : 0;
       v |= data->stop_bits == 2 ? 2 : 0;
       v |= (data->tx_watermark << 16);
       if(data->debug) {
         sprintf(buffer,"UART get tx_enable = %i, stop_bits = %i, tx_watermark = %i",
           data->tx_enable, data->stop_bits, data->tx_watermark);
         display_log(buffer);
       }
       break;
     case 0x0C:
       v = 0;
       v |= data->rx_enable      ? 1 : 0;
       v |= (data->tx_watermark << 16);
       if(data->debug) {
         sprintf(buffer,"UART get rx_enable = %i, rx_watermark = %i",
           data->rx_enable, data->rx_watermark);
         display_log(buffer);
       }
       break;
     case 0x10:
       v = 0;
       v |= data->rx_irq_enable ? 1 : 0;
       v |= data->tx_irq_enable ? 2 : 0;
       if(data->debug) {
         sprintf(buffer,"UART get rx_irq_enable = %i, tx_irq_enable = %i",
                 data->rx_irq_enable, data->tx_irq_enable);
         display_log(buffer);
       }
       break;
     case 0x14:
       v = 0;
       v |= data->tx_count > data->tx_watermark ? 1 : 0;
       v |= data->rx_count > data->rx_watermark ? 2 : 0;
       if(data->debug) {
         sprintf(buffer,"UART get rx_irq_pending = %i, tx_irq_pending = %i",
                 v&1, v>>1);
         display_log(buffer);
       }
       break;
     case 0x18:
       v = data->divisor;
       if(data->debug) {
         sprintf(buffer,"UART get divisor = 0x%08x", v);
         display_log(buffer);
       }
       break;
     default:
       sprintf(buffer,"UART Wr unkown address 0x%08x: 0x%08x", address, v);
       display_log(buffer);
       break;
   }
   *value = v;

   return 1;
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0x98(%rsp)
movl %esi, 0x94(%rsp)
movq %rdx, 0x88(%rsp)
movl $0x0, 0x84(%rsp)
movq 0x98(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x18(%rsp)
movl 0x94(%rsp), %eax
andl $0x3, %eax
cmpl $0x0, %eax
je 0x5e43
movq 0x81e8(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq 0x98(%rsp), %rax
movl 0x8(%rax), %edx
addl 0x94(%rsp), %edx
leaq 0x514e(%rip), %rsi      # 0xaf7a
movb $0x0, %al
callq 0x2130
movl $0x0, 0xa4(%rsp)
jmp 0x62f1
movl 0x94(%rsp), %eax
addl $0x4, %eax
movq 0x98(%rsp), %rcx
cmpl 0xc(%rcx), %eax
jbe 0x5e94
movq 0x8197(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq 0x98(%rsp), %rax
movl 0x8(%rax), %edx
addl 0x94(%rsp), %edx
leaq 0x50b4(%rip), %rsi      # 0xaf31
movb $0x0, %al
callq 0x2130
movl $0x0, 0xa4(%rsp)
jmp 0x62f1
movl $0x0, 0x84(%rsp)
movl 0x94(%rsp), %eax
movq %rax, 0x10(%rsp)
subq $0x18, %rax
ja 0x62aa
movq 0x10(%rsp), %rax
leaq 0x526f(%rip), %rcx      # 0xb130
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%rsp), %rax
movzbl 0xc(%rax), %edx
xorl %eax, %eax
movl $0x80000000, %ecx       # imm = 0x80000000
cmpl $0x8, %edx
cmovel %ecx, %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x5f2d
leaq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rax
movzbl 0xc(%rax), %ecx
leaq 0x5466(%rip), %rdx      # 0xb36d
leaq 0x545b(%rip), %rax      # 0xb369
cmpl $0x8, %ecx
cmoveq %rax, %rdx
leaq 0x5430(%rip), %rsi      # 0xb34c
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
movq 0x18(%rsp), %rax
movzbl 0x17(%rax), %eax
cmpl $0x0, %eax
jle 0x5fd1
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl 0x15(%rcx), %ecx
movzbl 0xd(%rax,%rcx), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movb 0x17(%rax), %cl
addb $-0x1, %cl
movb %cl, 0x17(%rax)
movq 0x18(%rsp), %rax
movzbl 0x15(%rax), %eax
cmpl $0x7, %eax
jne 0x5f82
xorl %eax, %eax
movl %eax, 0xc(%rsp)
jmp 0x5f92
movq 0x18(%rsp), %rax
movzbl 0x15(%rax), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
movb %al, %cl
movq 0x18(%rsp), %rax
movb %cl, 0x15(%rax)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x5fcf
leaq 0x20(%rsp), %rdi
movl 0x84(%rsp), %edx
leaq 0x53b5(%rip), %rsi      # 0xb373
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x5ff5
movl $0x80000000, 0x84(%rsp) # imm = 0x80000000
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x5ff3
leaq 0x53a1(%rip), %rdi      # 0xb38f
callq 0x6b20
jmp 0x5ff5
jmp 0x62d5
movl $0x0, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x1a(%rax), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x20(%rax), %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x2, %edx
cmovel %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x18(%rax), %eax
shll $0x10, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x60ab
leaq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rax
movzbl 0x1a(%rax), %edx
movq 0x18(%rsp), %rax
movzbl 0x20(%rax), %ecx
movq 0x18(%rsp), %rax
movzbl 0x18(%rax), %r8d
leaq 0x530c(%rip), %rsi      # 0xb3a6
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
movl $0x0, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x1b(%rax), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x18(%rax), %eax
shll $0x10, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x6133
leaq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rax
movzbl 0x1b(%rax), %edx
movq 0x18(%rsp), %rax
movzbl 0x19(%rax), %ecx
leaq 0x52bf(%rip), %rsi      # 0xb3e1
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
movl $0x0, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x1d(%rax), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x1c(%rax), %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x61c5
leaq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rax
movzbl 0x1d(%rax), %edx
movq 0x18(%rsp), %rax
movzbl 0x1c(%rax), %ecx
leaq 0x5258(%rip), %rsi      # 0xb40c
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
movl $0x0, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0xc(%rax), %edx
movq 0x18(%rsp), %rax
movzbl 0x18(%rax), %esi
xorl %eax, %eax
movl $0x1, %ecx
cmpl %esi, %edx
cmovgl %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
movzbl 0x17(%rax), %edx
movq 0x18(%rsp), %rax
movzbl 0x19(%rax), %esi
xorl %eax, %eax
movl $0x2, %ecx
cmpl %esi, %edx
cmovgl %ecx, %eax
orl 0x84(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x6268
leaq 0x20(%rsp), %rdi
movl 0x84(%rsp), %edx
andl $0x1, %edx
movl 0x84(%rsp), %ecx
shrl %ecx
leaq 0x51e5(%rip), %rsi      # 0xb43c
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
movq 0x18(%rsp), %rax
movzwl (%rax), %eax
movl %eax, 0x84(%rsp)
movq 0x18(%rsp), %rax
cmpb $0x0, 0x21(%rax)
je 0x62a8
leaq 0x20(%rsp), %rdi
movl 0x84(%rsp), %edx
leaq 0x51d7(%rip), %rsi      # 0xb46e
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
jmp 0x62d5
leaq 0x20(%rsp), %rdi
movl 0x94(%rsp), %edx
movl 0x84(%rsp), %ecx
leaq 0x4ff5(%rip), %rsi      # 0xb2b9
movb $0x0, %al
callq 0x21e0
leaq 0x20(%rsp), %rdi
callq 0x6b20
movl 0x84(%rsp), %ecx
movq 0x88(%rsp), %rax
movl %ecx, (%rax)
movl $0x1, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
addq $0xa8, %rsp
retq