// File: /workspace/github_cpp_makefile_star2_O2/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 %r15d, %r15d
xorl %r12d, %r12d
xorl %edx, %edx
xorl %esi, %esi
movzwl %r15w, %edi
cmpl $0x1fff, %edi           # imm = 0x1FFF
ja 0x1809d
testb $0xf, %r15b
sete %cl
testl %edi, %edi
setne %al
andb %cl, %al
movzbl %al, %ecx
addl %ecx, %esi
cmpl $0x11, %esi
sbbw $-0x1, %r12w
cmpw $0x3, %r12w
je 0x1809d
cmpl $0x11, %esi
movl $0x0, %ecx
cmovael %ecx, %esi
movl %esi, -0x34(%rbp)
movzbl %dl, %edx
testb %al, %al
cmovnel %ecx, %edx
movl %edx, -0x38(%rbp)
movl %edi, -0x3c(%rbp)
movq 0x5a98(%rbx), %rdi
movl %r15d, %esi
orl $0x8000, %esi           # imm = 0x8000
movl $0xffff, %r14d          # imm = 0xFFFF
andl %r14d, %esi
callq 0x167f6
movl %eax, %r13d
movq 0x5a98(%rbx), %rdi
addl $0xffff8001, %r15d      # imm = 0xFFFF8001
andl %r14d, %r15d
movl %r15d, %esi
callq 0x167f6
movl %eax, %edx
shrb $0x6, %dl
andb $0x2, %dl
movl %r13d, %ecx
shrb $0x7, %cl
orb %dl, %cl
movl %eax, %edx
shrb $0x5, %dl
andb $0x2, %dl
movl %r13d, %r15d
shrb $0x6, %r15b
andb $0x1, %r15b
orb %dl, %r15b
movl %eax, %edx
shrb $0x4, %dl
andb $0x2, %dl
movl %r13d, %r14d
shrb $0x5, %r14b
andb $0x1, %r14b
orb %dl, %r14b
movl %eax, %edx
shrb $0x3, %dl
andb $0x2, %dl
movl %r13d, %esi
shrb $0x4, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x29(%rbp)
movl %eax, %edx
shrb $0x2, %dl
andb $0x2, %dl
movl %r13d, %esi
shrb $0x3, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2a(%rbp)
movl %eax, %edx
shrb %dl
andb $0x2, %dl
movl %r13d, %esi
shrb $0x2, %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2b(%rbp)
movl %eax, %edx
andb $0x2, %dl
movl %r13d, %esi
shrb %sil
andb $0x1, %sil
orb %dl, %sil
movb %sil, -0x2c(%rbp)
addb %al, %al
andb $0x2, %al
andb $0x1, %r13b
orb %al, %r13b
movb %r13b, -0x2d(%rbp)
movq 0x5a98(%rbx), %rax
movzbl %cl, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal (%r12,%r12,8), %eax
addb -0x38(%rbp), %al
imull $0xa, -0x34(%rbp), %ecx
movq (%rbx), %r8
movq %r12, -0x48(%rbp)
movzbl %cl, %r12d
movzbl %al, %r13d
movq %rbx, %rdi
movl %r13d, %edx
movl %r12d, %ecx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl %r15b, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x1(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl %r14b, %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x2(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x29(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x3(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2a(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x4(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2b(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x5(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2c(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
leal 0x6(%r12), %eax
movq (%rbx), %r8
movzbl %al, %ecx
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%r8)
movq 0x5a98(%rbx), %rax
movzbl -0x2d(%rbp), %ecx
movzbl 0xe39e(%rax,%rcx), %esi
addb $0x7, %r12b
movq (%rbx), %rax
movzbl %r12b, %ecx
movq -0x48(%rbp), %r12
movq %rbx, %rdi
movl %r13d, %edx
callq *0x78(%rax)
movl -0x34(%rbp), %esi
movl -0x38(%rbp), %edx
incb %dl
movl -0x3c(%rbp), %r15d
addl $0x2, %r15d
jmp 0x17dfa
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq