// File: /workspace/github_cpp_makefile_star2_O2/Jumperr-labs[P]at25sf081/AT25SF081.cpp
// Function: AT25SF081::Main()
void AT25SF081::Main() {
    while (!should_stop_) {
        uint8_t opcode = 0;
        if (spi_slave_->Transmit(&opcode, nullptr, 1) == 0) {
            continue;
        }

        switch (opcode) {
            case (OP_READ_ARRAY_0B): {
                ReadArray(true);
                break;
            }

            case (OP_READ_ARRAY_03): {
                ReadArray(false);
                break;
            }

            case (OP_BYTE_OR_PAGE_PROGRAM): {
                ByteOrPageProgram();
                break;
            }

            case (OP_WRITE_ENABLE): {
                WriteEnable();
                break;
            }

            case (OP_WRITE_DISABLE): {
                WriteDisable();
                break;
            }

            case (OP_BLOCK_ERASE_4KB): {
                BlockErase(1U << 12);
                break;
            }

            case (OP_BLOCK_ERASE_32KB): {
                BlockErase(1U << 15);
                break;
            }

            case (OP_BLOCK_ERASE_64KB): {
                BlockErase(1U << 16);
                break;
            }

            case (OP_CHIP_ERASE_60): {
                ChipErase();
                break;
            }

            case (OP_CHIP_ERASE_C7): {
                ChipErase();
                break;
            }

            case (OP_READ_STATUS_REGISTER_BYTE_1): {
                ReadStatusRegister(STATUS_REGISTER_BYTE_1);
                break;
            }

            case (OP_READ_STATUS_REGISTER_BYTE_2): {
                ReadStatusRegister(STATUS_REGISTER_BYTE_2);
                break;
            }

            case (OP_READ_MANUFACTURER_AND_DEVICE_ID): {
                ReadManufacturerAndDeviceId();
                break;
            }

            case (OP_READ_DEVICE_ID): {
                ReadDeviceId();
                break;
            }

            default: {
                std::cerr << "AT25SF081: [Warning] Unsupported opcode 0x" << std::hex << (int) opcode << std::dec << std::endl;
                throw std::logic_error("AT25SF081: Unsupported opcode " + std::to_string(opcode));
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
movq %rdi, %rbx
leaq 0xf(%rsp), %r14
pushq $0x1
popq %r15
pushq $0x1
popq %rbp
leaq 0x2630(%rip), %r12      # 0x8000
cmpb $0x0, 0x100018(%rbx)
jne 0x5b03
movb $0x0, 0xf(%rsp)
movq 0x8(%rbx), %rdi
movq (%rdi), %rax
movq %r14, %rsi
xorl %edx, %edx
movq %r15, %rcx
callq *(%rax)
testq %rax, %rax
je 0x59d0
movzbl 0xf(%rsp), %eax
leal -0x2(%rax), %ecx
cmpl $0x9, %ecx
jbe 0x5a57
cmpl $0x20, %eax
je 0x5add
cmpl $0x35, %eax
je 0x5ac1
cmpl $0x52, %eax
je 0x5af1
cmpl $0x60, %eax
je 0x5a6d
cmpl $0x90, %eax
je 0x5ad0
cmpl $0x9f, %eax
je 0x5ae4
cmpl $0xc7, %eax
je 0x5a6d
cmpl $0xd8, %eax
jne 0x5b10
movl $0x10000, %esi          # imm = 0x10000
jmp 0x5af6
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x52b0
jmp 0x59d0
movq %rbx, %rdi
callq 0x52f0
jmp 0x59d0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x5160
jmp 0x59d0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x51f0
jmp 0x59d0
movq %rbx, %rdi
callq 0x55e0
jmp 0x59d0
movq %rbx, %rdi
callq 0x5270
jmp 0x59d0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x51f0
jmp 0x59d0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5160
jmp 0x59d0
movq %rbx, %rdi
callq 0x5550
jmp 0x59d0
movl $0x1000, %esi           # imm = 0x1000
jmp 0x5af6
movq %rbx, %rdi
callq 0x5410
jmp 0x59d0
movl $0x8000, %esi           # imm = 0x8000
movq %rbx, %rdi
callq 0x5070
jmp 0x59d0
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x54d9(%rip), %rdi      # 0xaff0
leaq 0x252a(%rip), %rsi      # 0x8048
callq 0x5300
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%rax,%rcx)
movzbl 0xf(%rsp), %esi
movq %rax, %rdi
callq 0x5590
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movq %rax, %rdi
callq 0x5170
pushq $0x10
popq %rdi
callq 0x5180
movq %rax, %rbx
movzbl 0xf(%rsp), %esi
leaq 0x10(%rsp), %rdi
callq 0x53e0
leaq 0x24f0(%rip), %rsi      # 0x8073
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x5560
movb $0x1, %bpl
leaq 0x30(%rsp), %rsi
movq %rbx, %rdi
callq 0x54d0
xorl %ebp, %ebp
movq 0x5425(%rip), %rsi      # 0xafd0
movq 0x5406(%rip), %rdx      # 0xafb8
movq %rbx, %rdi
callq 0x5580
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x5140
jmp 0x5bcf
movq %rax, %r14
movb $0x1, %bpl
leaq 0x10(%rsp), %rdi
callq 0x5140
testb %bpl, %bpl
jne 0x5be3
jmp 0x5beb
movq %rax, %r14
movq %rbx, %rdi
callq 0x5220
movq %r14, %rdi
callq 0x55c0
nop