// File: /workspace/github_cpp_makefile_star2_O2/nicoeps[P]NicoGB/src/ppu.cpp
// Function: PPU::drawBackground()
void PPU::drawBackground() {
    if (!(lcdc & 0x1)) {
        if (ly < 144) {
            std::fill_n(writebuffer.begin() + ly * 160, 160, getPalette(bgp)[0]);
        }
        return;
    }
    uint16_t tileSelect = ((lcdc & 0x8) >> 3) ? 0x9C00 : 0x9800;
    uint16_t tileData = ((lcdc & 0x10) >> 4) ? 0x8000 : 0x9000;
    std::vector<uint32_t> col = getPalette(bgp);

    uint8_t tileY = ((ly + scy) / 8) % 32;
    for (int i = 0; i < 21; ++i) {
        uint8_t tileX = (scx / 8 + i) % 32;

        uint8_t tileNumber = memory.read(tileSelect + (tileY * 32) + tileX);
        uint8_t pixelY = (ly + scy) % 8;

        uint8_t byte1 = 0;
        uint8_t byte2 = 0;
        if (tileData == 0x8000) {
            byte1 = memory.read(tileData + tileNumber * 16 + (pixelY * 2));
            byte2 = memory.read(tileData + tileNumber * 16 + (pixelY * 2) + 1);
        } else {
            byte1 = memory.read(tileData + ((int8_t) (tileNumber) * 16) + (pixelY * 2));
            byte2 = memory.read(tileData + ((int8_t) (tileNumber) * 16) + (pixelY * 2) + 1);
        }

        for (uint8_t pixelX = 0; pixelX < 8; ++pixelX) {
            uint8_t bit1 = (byte1 >> (7 - pixelX)) & 0x1;
            uint8_t bit2 = (byte2 >> (7 - pixelX)) & 0x1;
            uint8_t color = (bit2 << 1) | bit1;
            uint32_t pixel = col[color];

            int X = i * 8 + pixelX - (scx % 8);
            if (X >= 0 && ly < 144 && X < 160) {
                writebuffer[ly * 160 + X] = pixel;
                line[X] = color;
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movq 0x28(%rdi), %rax
movzbl (%rax), %ebp
testb $0x1, %bpl
jne 0x7169
movq 0x48(%rbx), %rax
movzbl (%rax), %eax
cmpq $0x8f, %rax
ja 0x7307
imulq $0x280, %rax, %r14      # imm = 0x280
addq 0x88(%rbx), %r14
movq 0x58(%rbx), %rax
movzbl (%rax), %edx
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x701e
movq (%rbx), %rax
movl (%rax), %eax
xorl %ecx, %ecx
cmpq $0x280, %rcx            # imm = 0x280
je 0x72fd
movl %eax, (%r14,%rcx)
addq $0x4, %rcx
jmp 0x7152
movl %ebp, %r14d
andl $0x8, %r14d
movq 0x58(%rbx), %rax
movzbl (%rax), %edx
leaq 0x10(%rsp), %rdi
callq 0x701e
movq 0x38(%rbx), %rax
movq 0x48(%rbx), %rcx
movb (%rax), %al
addb (%rcx), %al
shrb $0x3, %al
shll $0x7, %r14d
movzbl %al, %eax
shll $0x5, %eax
addl %r14d, %eax
addl $0x9800, %eax           # imm = 0x9800
movl %eax, 0xc(%rsp)
xorl %r12d, %r12d
xorl %r13d, %r13d
movl %ebp, 0x8(%rsp)
cmpl $0x15, %r13d
je 0x72fd
movq (%rbx), %rdi
movq 0x40(%rbx), %rax
movzbl (%rax), %eax
shrl $0x3, %eax
addl %r13d, %eax
andl $0x1f, %eax
orl 0xc(%rsp), %eax
movzwl %ax, %esi
callq 0x64d2
movq 0x48(%rbx), %rcx
movq 0x38(%rbx), %rdx
movb (%rdx), %dl
addb (%rcx), %dl
movq (%rbx), %rdi
andb $0x7, %dl
movzbl %dl, %r14d
testb $0x10, %bpl
jne 0x7223
movsbl %al, %eax
shll $0x4, %eax
leal (%rax,%r14,2), %r14d
addl $0xffff9000, %r14d      # imm = 0xFFFF9000
movzwl %r14w, %esi
callq 0x64d2
movl %eax, %ebp
movq (%rbx), %rdi
orl $0x1, %r14d
movzwl %r14w, %esi
callq 0x64d2
jmp 0x7251
movzbl %al, %r15d
shll $0x4, %r15d
leal (%r15,%r14,2), %esi
addl $0x8000, %esi           # imm = 0x8000
callq 0x64d2
movl %eax, %ebp
leal (%r15,%r14,2), %eax
movq (%rbx), %rdi
movzwl %ax, %esi
orl $0x8001, %esi           # imm = 0x8001
callq 0x64d2
movzbl %bpl, %edx
movzbl %al, %eax
movl %r12d, %esi
pushq $0x7
popq %rcx
cmpl $-0x1, %ecx
je 0x72ed
xorl %r9d, %r9d
btl %ecx, %edx
setb %r11b
movl %eax, %r10d
shrl %cl, %r10d
movq 0x40(%rbx), %rdi
movzbl (%rdi), %r8d
andl $0x7, %r8d
movl %esi, %edi
subl %r8d, %edi
js 0x72e4
movq 0x48(%rbx), %r14
movzbl (%r14), %ebp
cmpl $0x90, %ebp
setae %r14b
cmpl $0xa0, %edi
setae %r15b
orb %r14b, %r15b
jne 0x72e4
movb %r11b, %r9b
andl $0x1, %r10d
leal (%r9,%r10,2), %r9d
movq 0x10(%rsp), %r10
movl (%r10,%r9,4), %r10d
imull $0xa0, %ebp, %r11d
addl %esi, %r11d
subl %r8d, %r11d
movq 0x88(%rbx), %r8
movl %r10d, (%r8,%r11,4)
movl %edi, %edi
movq 0xa0(%rbx), %r8
movb %r9b, (%r8,%rdi)
decl %ecx
incl %esi
jmp 0x725e
incl %r13d
addl $0x8, %r12d
movl 0x8(%rsp), %ebp
jmp 0x71b0
leaq 0x10(%rsp), %rdi
callq 0x5b6e
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x7318
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x5b6e
movq %rbx, %rdi
callq 0x22b0
nop