// File: /workspace/github_c_makefile_star2_O0/qad114[P]yobeboy/src/gpu.c
// Function: renderBgScanline
static void renderBgScanline(GPU* gpu, Memory* mem, int line) {
    if (line >= GB_SCREEN_HEIGHT) return; // VBlank period
    uint8_t SCX = mem->logicalMemory[REG_SCX];
    uint8_t SCY = mem->logicalMemory[REG_SCY];

    int tileXOffset = SCX / 8, tileYOffset = (SCY + line) / 8;
    int pixelXOffset = SCX % 8, pixelYOffset = (SCY + line) % 8;
    if (tileYOffset >= 32) tileYOffset -= 32;

    uint8_t* linePtr = gpu->framebuffer + (line * GB_SCREEN_WIDTH * 4);
    uint8_t* lineEndPtr = linePtr + (GB_SCREEN_WIDTH * 4);

    uint8_t* mapStartPtr = gpu->backgroundMap + (tileYOffset * 16 * 32);
    uint8_t* mapPtr = mapStartPtr + (tileXOffset * 16);

    // Draw the first few pixels separately
    uint8_t* firstChunk = mapPtr + (pixelYOffset * 2);
    uint8_t byte1 = firstChunk[0];
    uint8_t byte2 = firstChunk[1];
    for (int i = pixelXOffset; i < 8; ++i) {
        int color = getBit(byte2, 7 - i) << 1 | getBit(byte1, 7 - i);
        memcpy(linePtr + ((i - pixelXOffset) * 4), &(gpu->colorPalette[getColorNumber(mem, color, REG_BGP)]), 3);
        linePtr[((i - pixelXOffset) * 4) + 3] = 0xFF;
    }
    linePtr += ((8 - pixelXOffset) * 4);

    // Draw the remaining pixels
    for (int tileNo = tileXOffset + 1; linePtr < lineEndPtr; ++tileNo) {
        if (tileNo == 32) tileNo = 0;
        uint8_t* chunk = mapStartPtr + (tileNo * 16) + (pixelYOffset * 2);
        for (int i = 0; i < 8; ++i) {
            int color = getBit(chunk[1], 7 - i) << 1 | getBit(chunk[0], 7 - i);
            memcpy(linePtr + ((i) * 4), &(gpu->colorPalette[getColorNumber(mem, color, REG_BGP)]), 3);
            linePtr[((i) * 4) + 3] = 0xFF;
        }
        linePtr += (8 * 4);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
cmpl $0x90, -0x14(%rbp)
jl 0xb594
jmp 0xb89e
movq -0x10(%rbp), %rax
movb 0xff43(%rax), %al
movb %al, -0x15(%rbp)
movq -0x10(%rbp), %rax
movb 0xff42(%rax), %al
movb %al, -0x16(%rbp)
movzbl -0x15(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, -0x1c(%rbp)
movzbl -0x16(%rbp), %eax
addl -0x14(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, -0x20(%rbp)
movzbl -0x15(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %edx, -0x24(%rbp)
movzbl -0x16(%rbp), %eax
addl -0x14(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %edx, -0x28(%rbp)
cmpl $0x20, -0x20(%rbp)
jl 0xb5ff
movl -0x20(%rbp), %eax
subl $0x20, %eax
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
imull $0xa0, -0x14(%rbp), %ecx
shll $0x2, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x280, %rax            # imm = 0x280
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x20(%rbp), %ecx
shll $0x4, %ecx
shll $0x5, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl -0x1c(%rbp), %ecx
shll $0x4, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movl -0x28(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movb (%rax), %al
movb %al, -0x51(%rbp)
movq -0x50(%rbp), %rax
movb 0x1(%rax), %al
movb %al, -0x52(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x58(%rbp)
cmpl $0x8, -0x58(%rbp)
jge 0xb74c
movb -0x52(%rbp), %al
movl $0x7, %esi
subl -0x58(%rbp), %esi
movzbl %al, %edi
callq 0xb9f0
movzbl %al, %eax
shll %eax
movl %eax, -0x8c(%rbp)
movb -0x51(%rbp), %al
movl $0x7, %esi
subl -0x58(%rbp), %esi
movzbl %al, %edi
callq 0xb9f0
movb %al, %cl
movl -0x8c(%rbp), %eax
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x5c(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x58(%rbp), %eax
subl -0x24(%rbp), %eax
shll $0x2, %eax
cltq
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rdi
movl -0x5c(%rbp), %esi
movl $0xff47, %edx           # imm = 0xFF47
callq 0xc040
movq -0x88(%rbp), %rdx
movq -0x80(%rbp), %rcx
movl %eax, %esi
movq -0x78(%rbp), %rax
movslq %esi, %rsi
movw 0x28(%rdx,%rsi,4), %di
movw %di, (%rax,%rcx)
movb 0x2a(%rdx,%rsi,4), %dl
movb %dl, 0x2(%rax,%rcx)
movq -0x30(%rbp), %rax
movl -0x58(%rbp), %ecx
subl -0x24(%rbp), %ecx
shll $0x2, %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movb $-0x1, (%rax,%rcx)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0xb684
movl $0x8, %ecx
subl -0x24(%rbp), %ecx
shll $0x2, %ecx
movq -0x30(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
jae 0xb89e
cmpl $0x20, -0x60(%rbp)
jne 0xb789
movl $0x0, -0x60(%rbp)
movq -0x40(%rbp), %rax
movl -0x60(%rbp), %ecx
shll $0x4, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movl -0x28(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
cmpl $0x8, -0x6c(%rbp)
jge 0xb884
movq -0x68(%rbp), %rax
movb 0x1(%rax), %al
movl $0x7, %esi
subl -0x6c(%rbp), %esi
movzbl %al, %edi
callq 0xb9f0
movzbl %al, %eax
shll %eax
movl %eax, -0xac(%rbp)
movq -0x68(%rbp), %rax
movb (%rax), %al
movl $0x7, %esi
subl -0x6c(%rbp), %esi
movzbl %al, %edi
callq 0xb9f0
movb %al, %cl
movl -0xac(%rbp), %eax
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x70(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0x6c(%rbp), %eax
shll $0x2, %eax
cltq
movq %rax, -0xa0(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x70(%rbp), %esi
movl $0xff47, %edx           # imm = 0xFF47
callq 0xc040
movq -0xa8(%rbp), %rdx
movq -0xa0(%rbp), %rcx
movl %eax, %esi
movq -0x98(%rbp), %rax
movslq %esi, %rsi
movw 0x28(%rdx,%rsi,4), %di
movw %di, (%rax,%rcx)
movb 0x2a(%rdx,%rsi,4), %dl
movb %dl, 0x2(%rax,%rcx)
movq -0x30(%rbp), %rax
movl -0x6c(%rbp), %ecx
shll $0x2, %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movb $-0x1, (%rax,%rcx)
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0xb7af
movq -0x30(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x30(%rbp)
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0xb76e
addq $0xb0, %rsp
popq %rbp
retq
nopw (%rax,%rax)