// File: /workspace/github_cpp_makefile_star2_O1/RegulusImpact[P]sadboy/src/Graphics/XGPU.cpp
// Function: XGPU::DumpTileset()
void XGPU::DumpTileset() {
    /*

    iterate through vram
    every 16 bytes is am 8x8 tile
    byte pairs read read low then high

    tileRow 0 | byte 0 | byte 1
    tileRow 1 | byte 2 | byte 3
    tileRow 3 | byte 4 | byte 5
    tileRow 3 | byte 6 | byte 7
    tileRow 4 | byte 8 | byte 9
    tileRow 5 | byte A | byte B
    tileRow 6 | byte C | byte D
    tileRow 7 | byte E | byte F

    Row
      byte one (hi)  |   byte two (lo)
        1234 5678    |     ABCD EFGH

    Colors:
    p0 p1 p2 p3 p4 p5 p6 p7
    1A 2B 3C 4D 5E 6F 7G 8G


    */
    uint32_t tileCounter = 0;
    uint16_t tileRow = 0;
    uint16_t tileRowOffset = 0;
    uint16_t maxVRAM = 0x2000;
    uint16_t vramStart = 0x8000;
    // pokemon sprite test
    // FF 00 7E FF      85 81 89 83     93 85 A5 8B    C9 97 7E FF
    // mmu->Write(vramStart, (uint8_t)0xFF);
    // mmu->Write(vramStart+1, (uint8_t)0x00);
    // mmu->Write(vramStart+2, (uint8_t)0x7E);
    // mmu->Write(vramStart+3, (uint8_t)0xFF);

    // mmu->Write(vramStart+4, (uint8_t)0x85);
    // mmu->Write(vramStart+5, (uint8_t)0x81);
    // mmu->Write(vramStart+6, (uint8_t)0x89);
    // mmu->Write(vramStart+7, (uint8_t)0x83);

    // mmu->Write(vramStart+8, (uint8_t)0x93);
    // mmu->Write(vramStart+9, (uint8_t)0x85);
    // mmu->Write(vramStart+10, (uint8_t)0xA5);
    // mmu->Write(vramStart+11, (uint8_t)0x8B);

    // mmu->Write(vramStart+12, (uint8_t)0xC9);
    // mmu->Write(vramStart+13, (uint8_t)0x97);
    // mmu->Write(vramStart+14, (uint8_t)0x7E);
    // mmu->Write(vramStart+15, (uint8_t)0xFF);

    for (uint16_t ii = 0; ii < maxVRAM; ii += 2) {
        // ii iterates through every byte in vram
        // ii % 16 is which byte of the tile we're looking at
        // each time ii % 16 == 0, increment our tile counter
        // we want to read two bytes at a time
        if (0 == ii % 16 && 0 != ii) {
            tileCounter++;
            // we reset tileRow when tileCounter goes up
            tileRow = 0;
        }

        if (16 < tileCounter) {
            tileCounter = 0;
            tileRowOffset++;
        }

        if (tileRowOffset == 3) {
            break;
        }


        // the bytes are in order lo to high
        uint8_t lo = mmu->Read((vramStart + ii));
        uint8_t hi = mmu->Read((vramStart + ii + 1));

        // 1000 0000 >> 6 & 2 == 0000 001x & 2 == 0000 0010
        uint8_t p0 = ((hi >> 6) & 2) | ((lo >> 7) & 1);
        uint8_t p1 = ((hi >> 5) & 2) | ((lo >> 6) & 1);
        uint8_t p2 = ((hi >> 4) & 2) | ((lo >> 5) & 1);
        uint8_t p3 = ((hi >> 3) & 2) | ((lo >> 4) & 1);
        uint8_t p4 = ((hi >> 2) & 2) | ((lo >> 3) & 1);
        uint8_t p5 = ((hi >> 1) & 2) | ((lo >> 2) & 1);
        uint8_t p6 =  (hi &  2)      | ((lo >> 1) & 1);
        uint8_t p7 = ((hi << 1) & 2) |  (lo &  1);

        // mvprintw(tileRow, 50, "%d", p0);
        // mvprintw(tileRow, 51, "%d", p1);
        // mvprintw(tileRow, 52, "%d", p2);
        // mvprintw(tileRow, 53, "%d", p3);
        // mvprintw(tileRow, 54, "%d", p4);
        // mvprintw(tileRow, 55, "%d", p5);
        // mvprintw(tileRow, 56, "%d", p6);
        // mvprintw(tileRow, 57, "%d", p7);

        Draw(mmu->bgp[p0], (tileRowOffset*9)+tileRow, (tileCounter*10)+0);
        Draw(mmu->bgp[p1], (tileRowOffset*9)+tileRow, (tileCounter*10)+1);
        Draw(mmu->bgp[p2], (tileRowOffset*9)+tileRow, (tileCounter*10)+2);
        Draw(mmu->bgp[p3], (tileRowOffset*9)+tileRow, (tileCounter*10)+3);
        Draw(mmu->bgp[p4], (tileRowOffset*9)+tileRow, (tileCounter*10)+4);
        Draw(mmu->bgp[p5], (tileRowOffset*9)+tileRow, (tileCounter*10)+5);
        Draw(mmu->bgp[p6], (tileRowOffset*9)+tileRow, (tileCounter*10)+6);
        Draw(mmu->bgp[p7], (tileRowOffset*9)+tileRow, (tileCounter*10)+7);

        // we've read two bytes for a row, increment
        tileRow++;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
xorl %eax, %eax
xorl %esi, %esi
xorl %r15d, %r15d
xorl %r8d, %r8d
testb $0xe, %r8b
sete %dl
testl %r8d, %r8d
setne %cl
andb %dl, %cl
movzbl %cl, %edx
addl %eax, %edx
cmpl $0x11, %edx
sbbw $-0x1, %r15w
cmpw $0x3, %r15w
je 0x1d097
cmpl $0x11, %edx
movl $0x0, %eax
cmovael %eax, %edx
movq %rdx, -0x38(%rbp)
testb %cl, %cl
cmovnel %eax, %esi
movq %rsi, -0x40(%rbp)
movq 0x5a98(%rbx), %rdi
movl %r8d, %esi
orl $0x8000, %esi           # imm = 0x8000
movl $0xffff, %r12d          # imm = 0xFFFF
andl %r12d, %esi
movq %r8, %r13
movq %r8, -0x48(%rbp)
callq 0x1b710
movl %eax, %r14d
movq 0x5a98(%rbx), %rdi
leal 0x8001(%r13), %esi
andl %r12d, %esi
callq 0x1b710
movl %eax, %edx
shrb $0x6, %dl
andb $0x2, %dl
movl %r14d, %ecx
shrb $0x7, %cl
orb %dl, %cl
movl %eax, %edx
shrb $0x5, %dl
andb $0x2, %dl
movl %r14d, %r13d
shrb $0x6, %r13b
andb $0x1, %r13b
orb %dl, %r13b
movl %eax, %edx
shrb $0x4, %dl
andb $0x2, %dl
movl %r14d, %esi
shrb $0x5, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x29(%rbp)
movl %eax, %edx
shrb $0x3, %dl
andb $0x2, %dl
movl %r14d, %esi
shrb $0x4, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2a(%rbp)
movl %eax, %edx
shrb $0x2, %dl
andb $0x2, %dl
movl %r14d, %esi
shrb $0x3, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2b(%rbp)
movl %eax, %edx
shrb %dl
andb $0x2, %dl
movl %r14d, %esi
shrb $0x2, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2c(%rbp)
movl %eax, %edx
andb $0x2, %dl
movl %r14d, %esi
shrb %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2d(%rbp)
addb %al, %al
andb $0x2, %al
andb $0x1, %r14b
orb %al, %r14b
movq 0x5a98(%rbx), %rax
movzbl %cl, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal (%r15,%r15,8), %eax
movq -0x40(%rbp), %rcx
addl %ecx, %eax
movq -0x38(%rbp), %rcx
addl %ecx, %ecx
leal (%rcx,%rcx,4), %ecx
movq (%rbx), %r8
movq %r15, -0x50(%rbp)
movzbl %al, %r15d
movzbl %cl, %r12d
movq %rbx, %rdi
movl %r15d, %edx
movl %r12d, %ecx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl %r13b, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x1(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x29(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x2(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2a(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x3(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2b(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x4(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2c(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x5(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2d(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x6(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r15d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl %r14b, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
addb $0x7, %r12b
movq (%rbx), %rax
movzbl %r12b, %ecx
movq %rbx, %rdi
movl %r15d, %edx
movq -0x50(%rbp), %r15
callq *0x78(%rax)
movq -0x40(%rbp), %rsi
incl %esi
movq -0x48(%rbp), %rdx
leal 0x2(%rdx), %ecx
movq -0x38(%rbp), %rax
cmpl $0x1ffe, %edx           # imm = 0x1FFE
movl %ecx, %r8d
jb 0x1cdf0
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq