// File: 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:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x28(%rax), %rax
movzbl (%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x11673
movq 0x18(%rsp), %rax
movq 0x28(%rax), %rax
movzbl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x11673
movq 0x18(%rsp), %rax
movq 0x78(%rax), %rax
movzbl (%rax), %eax
cmpl $0xa6, %eax
jg 0x11673
movq 0x18(%rsp), %rax
movq 0x70(%rax), %rax
movzbl (%rax), %eax
cmpl $0x8f, %eax
jg 0x11673
movq 0x18(%rsp), %rcx
movq 0x70(%rcx), %rax
movzbl (%rax), %eax
movq 0x48(%rcx), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jle 0x11678
jmp 0x119b6
movq 0x18(%rsp), %rsi
movq 0x28(%rsi), %rax
movzbl (%rax), %edx
andl $0x40, %edx
sarl $0x6, %edx
movl $0x9800, %eax           # imm = 0x9800
movl $0x9c00, %ecx           # imm = 0x9C00
cmpl $0x0, %edx
cmovnel %ecx, %eax
movw %ax, 0x6e(%rsp)
movq 0x28(%rsi), %rax
movzbl (%rax), %edx
andl $0x10, %edx
sarl $0x4, %edx
movl $0x9000, %eax           # imm = 0x9000
movl $0x8000, %ecx           # imm = 0x8000
cmpl $0x0, %edx
cmovnel %ecx, %eax
movw %ax, 0x6c(%rsp)
movq 0x58(%rsi), %rax
leaq 0x50(%rsp), %rdi
movzbl (%rax), %edx
callq 0x10e60
movq 0x18(%rsp), %rax
movl 0x84(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq 0x18(%rsp), %rax
movb %cl, 0x4f(%rsp)
movl 0x84(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq 0x18(%rsp), %rax
movb %dl, %cl
movb %cl, 0x4e(%rsp)
movl 0x84(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x84(%rax)
movl $0x0, 0x48(%rsp)
cmpl $0x15, 0x48(%rsp)
jge 0x119ac
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movzwl 0x6e(%rsp), %eax
movzbl 0x4f(%rsp), %ecx
shll $0x5, %ecx
addl %ecx, %eax
movl 0x48(%rsp), %ecx
addl %ecx, %eax
movzwl %ax, %esi
callq 0xef80
movb %al, 0x17(%rsp)
jmp 0x11756
movb 0x17(%rsp), %al
movb %al, 0x47(%rsp)
movb $0x0, 0x33(%rsp)
movb $0x0, 0x32(%rsp)
movzwl 0x6c(%rsp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x1180d
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movzwl 0x6c(%rsp), %edx
movzbl 0x47(%rsp), %eax
shll $0x4, %eax
addl %eax, %edx
movzbl 0x4e(%rsp), %eax
movl %eax, %ecx
movl %edx, %eax
leal (%rax,%rcx,2), %eax
movzwl %ax, %esi
callq 0xef80
movb %al, 0x16(%rsp)
jmp 0x117a9
movq 0x18(%rsp), %rax
movb 0x16(%rsp), %cl
movb %cl, 0x33(%rsp)
movq (%rax), %rdi
movzwl 0x6c(%rsp), %edx
movzbl 0x47(%rsp), %eax
shll $0x4, %eax
addl %eax, %edx
movzbl 0x4e(%rsp), %eax
movl %eax, %ecx
movl %edx, %eax
leal 0x1(%rax,%rcx,2), %eax
movzwl %ax, %esi
callq 0xef80
movb %al, 0x15(%rsp)
jmp 0x117e3
movb 0x15(%rsp), %al
movb %al, 0x32(%rsp)
jmp 0x11880
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
leaq 0x50(%rsp), %rdi
callq 0xd450
jmp 0x119bb
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movzwl 0x6c(%rsp), %edx
movsbl 0x47(%rsp), %eax
shll $0x4, %eax
addl %eax, %edx
movzbl 0x4e(%rsp), %eax
movl %eax, %ecx
movl %edx, %eax
leal (%rax,%rcx,2), %eax
movzwl %ax, %esi
callq 0xef80
movb %al, 0x14(%rsp)
jmp 0x1183e
movq 0x18(%rsp), %rax
movb 0x14(%rsp), %cl
movb %cl, 0x33(%rsp)
movq (%rax), %rdi
movzwl 0x6c(%rsp), %edx
movsbl 0x47(%rsp), %eax
shll $0x4, %eax
addl %eax, %edx
movzbl 0x4e(%rsp), %eax
movl %eax, %ecx
movl %edx, %eax
leal 0x1(%rax,%rcx,2), %eax
movzwl %ax, %esi
callq 0xef80
movb %al, 0x13(%rsp)
jmp 0x11878
movb 0x13(%rsp), %al
movb %al, 0x32(%rsp)
movl $0x0, 0x2c(%rsp)
cmpl $0x8, 0x2c(%rsp)
jge 0x1199a
movzbl 0x33(%rsp), %eax
movl $0x7, %ecx
subl 0x2c(%rsp), %ecx
sarl %cl, %eax
andl $0x1, %eax
movb %al, 0x2b(%rsp)
movzbl 0x32(%rsp), %eax
movl $0x7, %ecx
subl 0x2c(%rsp), %ecx
sarl %cl, %eax
andl $0x1, %eax
movb %al, 0x2a(%rsp)
movzbl 0x2a(%rsp), %eax
shll %eax
movzbl 0x2b(%rsp), %ecx
orl %ecx, %eax
movb %al, 0x29(%rsp)
movzbl 0x29(%rsp), %eax
movl %eax, %esi
leaq 0x50(%rsp), %rdi
callq 0x134d0
movq 0x18(%rsp), %rcx
movl (%rax), %eax
movl %eax, 0x24(%rsp)
movl 0x48(%rsp), %eax
shll $0x3, %eax
addl 0x2c(%rsp), %eax
movq 0x78(%rcx), %rcx
movzbl (%rcx), %ecx
addl %ecx, %eax
subl $0x7, %eax
movl %eax, 0x20(%rsp)
cmpl $0x0, 0x20(%rsp)
jl 0x11988
movq 0x18(%rsp), %rax
movq 0x48(%rax), %rax
movzbl (%rax), %eax
cmpl $0x90, %eax
jge 0x11988
cmpl $0xa0, 0x20(%rsp)
jge 0x11988
movq 0x18(%rsp), %rax
movl 0x24(%rsp), %ecx
movl %ecx, 0xc(%rsp)
movq %rax, %rdi
addq $0x88, %rdi
movq 0x48(%rax), %rax
movzbl (%rax), %eax
imull $0xa0, %eax, %eax
addl 0x20(%rsp), %eax
movslq %eax, %rsi
callq 0x134d0
movl 0xc(%rsp), %ecx
movq 0x18(%rsp), %rdi
movl %ecx, (%rax)
movb 0x29(%rsp), %al
movb %al, 0x12(%rsp)
addq $0xa0, %rdi
movslq 0x20(%rsp), %rsi
callq 0x40f0
movb 0x12(%rsp), %cl
movb %cl, (%rax)
jmp 0x1198a
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x11888
jmp 0x1199c
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0x11720
leaq 0x50(%rsp), %rdi
callq 0xd450
addq $0x78, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0x33d0
nopw %cs:(%rax,%rax)