// File: /workspace/github_c_makefile_star2_O0/qad114[P]yobeboy/src/gpu.c
// Function: GPU_update
void GPU_update(CPU* cpu, GPU* gpu, Memory* mem) {
    uint8_t* IF = &(mem->logicalMemory[REG_IF]);
    uint8_t* LYC = &(mem->logicalMemory[REG_LYC]);
    uint8_t* LY = &(mem->logicalMemory[REG_LY]);
    uint8_t* STAT = &(mem->logicalMemory[REG_STAT]);

    if (*LY < 144) {
        // Cycle through modes 2, 3, 0
        switch (gpu->machineCycleCounter) {
            case 0: // Mode 2
                *STAT = (*STAT & 0xFC) | 2;
                break;

            case 19: // Mode 3
                *STAT = (*STAT & 0xFC) | 3;
                break;

            case 61: // Mode 0 (HBlank)
                *STAT = (*STAT & 0xFC) | 0;
                updateBackgroundMap(gpu, mem);
                renderBgScanline(gpu, mem, *LY);
                break;

            case 113: // Go to next line
                ++*LY;
                *STAT = (*STAT & 0xFC) | 2;
                break;

            default:
                break;
        }

    } else if (*LY == 144) {
        // Mode 1 (VBlank)
        *STAT = (*STAT & 0xFC) | 1;
        if (gpu->machineCycleCounter == 113) {
            GPU_renderToFrameBuffer(gpu, mem);
            *IF |= 0x1;
            ++*LY;
        }

    } else if (*LY == 154) {
        // VBlank end
        if (gpu->machineCycleCounter == 113) {
            *LY = 0;
        }

    } else {
        if (gpu->machineCycleCounter == 113) {
            ++*LY;
        }
    }

    // Check for LYC=LY
    if (*LYC == *LY) {
        *STAT = setBit(*STAT, 2, 1);
        *IF = setBit(*IF, 1, 1);
    } else {
        *STAT = setBit(*STAT, 2, 0);
    }

    if (gpu->machineCycleCounter == 113) {
        gpu->machineCycleCounter = 0;
    } else {
        ++(gpu->machineCycleCounter);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
addq $0xff0f, %rax           # imm = 0xFF0F
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
addq $0xff45, %rax           # imm = 0xFF45
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
addq $0xff44, %rax           # imm = 0xFF44
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
addq $0xff41, %rax           # imm = 0xFF41
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x90, %eax
jge 0xb2e5
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
testl %eax, %eax
je 0xb24e
jmp 0xb22d
movl -0x3c(%rbp), %eax
subl $0x13, %eax
je 0xb267
jmp 0xb237
movl -0x3c(%rbp), %eax
subl $0x3d, %eax
je 0xb280
jmp 0xb241
movl -0x3c(%rbp), %eax
subl $0x71, %eax
je 0xb2ba
jmp 0xb2de
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0xfc, %eax
orl $0x2, %eax
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
jmp 0xb2e0
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0xfc, %eax
orl $0x3, %eax
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
jmp 0xb2e0
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0xfc, %eax
orl $0x0, %eax
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb410
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rax
movzbl (%rax), %edx
callq 0xb570
jmp 0xb2e0
movq -0x30(%rbp), %rax
movb (%rax), %cl
addb $0x1, %cl
movb %cl, (%rax)
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0xfc, %eax
orl $0x2, %eax
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
jmp 0xb2e0
jmp 0xb2e0
jmp 0xb373
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x90, %eax
jne 0xb339
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0xfc, %eax
orl $0x1, %eax
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
movq -0x10(%rbp), %rax
cmpl $0x71, (%rax)
jne 0xb337
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb8b0
movq -0x20(%rbp), %rax
movzbl (%rax), %ecx
orl $0x1, %ecx
movb %cl, (%rax)
movq -0x30(%rbp), %rax
movb (%rax), %cl
addb $0x1, %cl
movb %cl, (%rax)
jmp 0xb371
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x9a, %eax
jne 0xb359
movq -0x10(%rbp), %rax
cmpl $0x71, (%rax)
jne 0xb357
movq -0x30(%rbp), %rax
movb $0x0, (%rax)
jmp 0xb36f
movq -0x10(%rbp), %rax
cmpl $0x71, (%rax)
jne 0xb36d
movq -0x30(%rbp), %rax
movb (%rax), %cl
addb $0x1, %cl
movb %cl, (%rax)
jmp 0xb36f
jmp 0xb371
jmp 0xb373
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
movq -0x30(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0xb3c0
movq -0x38(%rbp), %rax
movl $0x2, %esi
movl $0x1, %edx
movzbl (%rax), %edi
callq 0xb9a0
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
movq -0x20(%rbp), %rax
movl $0x1, %edx
movzbl (%rax), %edi
movl %edx, %esi
callq 0xb9a0
movb %al, %cl
movq -0x20(%rbp), %rax
movb %cl, (%rax)
jmp 0xb3db
movq -0x38(%rbp), %rax
movl $0x2, %esi
xorl %edx, %edx
movzbl (%rax), %edi
callq 0xb9a0
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, (%rax)
movq -0x10(%rbp), %rax
cmpl $0x71, (%rax)
jne 0xb3f0
movq -0x10(%rbp), %rax
movl $0x0, (%rax)
jmp 0xb3fb
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)