// File: /workspace/github_cpp_makefile_star2_O2/nicoeps[P]NicoGB/src/ppu.cpp
// Function: PPU::drawWindow()
void PPU::drawWindow() {
    if (!((lcdc & 0x20) && (lcdc & 0x1) && wx <= 166 && wy <= 143 && wy <= ly)) {
        return;
    }
    uint16_t tileSelect = (((lcdc & 0x40) >> 6)) ? 0x9C00 : 0x9800;
    uint16_t tileData = ((((lcdc & 0x10) >> 4)) ? 0x8000 : 0x9000);
    std::vector<uint32_t> col = getPalette(bgp);

    uint8_t tileY = windowCounter / 8;
    uint8_t pixelY = windowCounter % 8;
    windowCounter++;
    for (int i = 0; i < 21; ++i) {
        uint8_t tileNumber = memory.read(tileSelect + (tileY * 32) + i);

        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 (int pixelX = 0; pixelX < 8; ++pixelX) { // X
            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 + wx - 7;
            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 0x28(%rdi), %rax
movzbl (%rax), %r14d
movl %r14d, %eax
notl %eax
testb $0x21, %al
jne 0x7505
movq %rdi, %rbx
movq 0x78(%rdi), %rax
cmpb $-0x5a, (%rax)
ja 0x7505
movq 0x70(%rbx), %rax
movb (%rax), %al
cmpb $-0x71, %al
ja 0x7505
movq 0x48(%rbx), %rcx
cmpb (%rcx), %al
ja 0x7505
movl %r14d, %r15d
andl $0x40, %r15d
movq 0x58(%rbx), %rax
movzbl (%rax), %edx
leaq 0x10(%rsp), %rdi
callq 0x701e
movl 0x84(%rbx), %ecx
pushq $0x8
popq %rsi
movl %ecx, %eax
cltd
idivl %esi
incl %ecx
movl %ecx, 0x84(%rbx)
shll $0x4, %r15d
movzbl %al, %eax
shll $0x5, %eax
addl %r15d, %eax
addl $0x9800, %eax           # imm = 0x9800
movl %eax, 0x4(%rsp)
movzbl %dl, %eax
addl %eax, %eax
leal 0x8000(%rax), %ecx
movl %ecx, (%rsp)
orl $0x9000, %eax           # imm = 0x9000
movq %rax, 0x8(%rsp)
xorl %r13d, %r13d
pushq $-0x7
popq %r12
cmpl $0x15, %r13d
je 0x74fb
movq (%rbx), %rdi
movl %r13d, %eax
orl 0x4(%rsp), %eax
movzwl %ax, %esi
callq 0x64d2
movq (%rbx), %rdi
testb $0x10, %r14b
jne 0x742d
movsbl %al, %r15d
shll $0x4, %r15d
addl 0x8(%rsp), %r15d
movzwl %r15w, %esi
callq 0x64d2
movl %eax, %ebp
movq (%rbx), %rdi
orl $0x1, %r15d
movzwl %r15w, %esi
callq 0x64d2
jmp 0x7454
movzbl %al, %r15d
shll $0x4, %r15d
addl (%rsp), %r15d
movzwl %r15w, %esi
callq 0x64d2
movl %eax, %ebp
movq (%rbx), %rdi
orl $0x1, %r15d
movzwl %r15w, %esi
callq 0x64d2
movzbl %bpl, %edx
movzbl %al, %eax
movl %r12d, %esi
pushq $0x7
popq %rcx
cmpl $-0x1, %ecx
je 0x74ef
xorl %r8d, %r8d
btl %ecx, %edx
setb %r10b
movl %eax, %r9d
shrl %cl, %r9d
movq 0x78(%rbx), %rdi
movzbl (%rdi), %edi
leal (%rsi,%rdi), %ebp
addl $0x7, %ebp
cmpl $0x7, %ebp
jb 0x74e6
movq 0x48(%rbx), %r11
movzbl (%r11), %r11d
cmpl $0x90, %r11d
setae %r15b
cmpl $0xa7, %ebp
setae %bpl
orb %r15b, %bpl
jne 0x74e6
movb %r10b, %r8b
andl $0x1, %r9d
leal (%r8,%r9,2), %r8d
movq 0x10(%rsp), %r9
movl (%r9,%r8,4), %r9d
addl %esi, %edi
imull $0xa0, %r11d, %r10d
addl %edi, %r10d
movq 0x88(%rbx), %r11
movl %r9d, (%r11,%r10,4)
movl %edi, %edi
movq 0xa0(%rbx), %r9
movb %r8b, (%r9,%rdi)
decl %ecx
incl %esi
jmp 0x7461
incl %r13d
addl $0x8, %r12d
jmp 0x73de
leaq 0x10(%rsp), %rdi
callq 0x5b6e
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x7516
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x5b6e
movq %rbx, %rdi
callq 0x22b0
nop