// File: /workspace/github_cpp_makefile_star2_O3/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 $0x38, %rsp
movq 0x28(%rdi), %rax
movzbl (%rax), %r14d
movl %r14d, %eax
notl %eax
testb $0x21, %al
jne 0x83c6
movq %rdi, %rbx
movq 0x78(%rdi), %rax
cmpb $-0x5a, (%rax)
ja 0x83c6
movq 0x70(%rbx), %rax
movb (%rax), %al
cmpb $-0x71, %al
ja 0x83c6
movq 0x48(%rbx), %rcx
cmpb (%rcx), %al
ja 0x83c6
movl %r14d, %r15d
andl $0x40, %r15d
movq 0x58(%rbx), %rax
movzbl (%rax), %edx
leaq 0x20(%rsp), %rdi
callq 0x7e84
movl 0x84(%rbx), %eax
leal 0x7(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
movl %ecx, %edx
andl $-0x8, %edx
movl %eax, %esi
subl %edx, %esi
sarl $0x3, %ecx
incl %eax
movl %eax, 0x84(%rbx)
shll $0x4, %r15d
movzbl %cl, %eax
shll $0x5, %eax
addl %r15d, %eax
addl $0x9800, %eax           # imm = 0x9800
movq %rax, 0x18(%rsp)
movzbl %sil, %eax
addl %eax, %eax
leal 0x8000(%rax), %ecx
movl %ecx, 0xc(%rsp)
orl $0x9000, %eax           # imm = 0x9000
movq %rax, 0x10(%rsp)
xorl %r13d, %r13d
movl $0xfffffff9, %r12d      # imm = 0xFFFFFFF9
movq (%rbx), %rdi
movq 0x18(%rsp), %rax
addl %r13d, %eax
movzwl %ax, %esi
callq 0x7022
movq (%rbx), %rdi
testb $0x10, %r14b
jne 0x82df
movsbl %al, %r15d
shll $0x4, %r15d
addl 0x10(%rsp), %r15d
movzwl %r15w, %esi
callq 0x7022
movl %eax, %ebp
movq (%rbx), %rdi
orl $0x1, %r15d
movzwl %r15w, %esi
callq 0x7022
jmp 0x8307
movzbl %al, %r15d
shll $0x4, %r15d
addl 0xc(%rsp), %r15d
movzwl %r15w, %esi
callq 0x7022
movl %eax, %ebp
movq (%rbx), %rdi
orl $0x1, %r15d
movzwl %r15w, %esi
callq 0x7022
movzbl %bpl, %edx
movzbl %al, %eax
movl $0x7, %ecx
movl %r12d, %esi
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 0x8393
movq 0x48(%rbx), %r11
movzbl (%r11), %r11d
cmpl $0x90, %r11d
setae %r15b
cmpl $0xa7, %ebp
setae %bpl
orb %r15b, %bpl
jne 0x8393
movb %r10b, %r8b
andl $0x1, %r9d
leal (%r8,%r9,2), %r8d
movq 0x20(%rsp), %r9
movl (%r9,%r8,4), %r9d
addl %esi, %edi
leal (%r11,%r11,4), %r10d
shll $0x5, %r10d
addl %edi, %r10d
movq 0x88(%rbx), %r11
movl %r9d, (%r11,%r10,4)
movl %edi, %edi
movq 0xa0(%rbx), %r9
movb %r8b, (%r9,%rdi)
incl %esi
addl $-0x1, %ecx
jb 0x8316
incl %r13d
addl $0x8, %r12d
cmpl $0x15, %r13d
jne 0x8299
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x83c6
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x21c0
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x83d7
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x83f1
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x21c0
movq %rbx, %rdi
callq 0x2270
nop