// File: /workspace/github_cpp_makefile_star2_O3/khedoros[P]khednes/ppu3.cpp
// Function: ppu::reg_read(unsigned int, unsigned int)
unsigned char ppu::reg_read(const unsigned int addr, unsigned int cycle) {
    //cout<<"!! "<<phases[phase(cycle)]<<" Read address: 0x"<<hex<<addr<<dec<<" Cycle: "<<cycle<<endl;
    if(phase(cycle) == RENDER) ++s.reads_during_render;
    unsigned char retval = 0;
    switch(addr) {
    case 0x2002:
        if(!cleared_vsync && (phase(cycle) == VINT || cycle >= cycles_per_frame - 85)) {
            retval |= 0x80;
            cleared_vsync = true;
            //TODO: Reduce reliance on hard-coded cycle counts
            if(cycle >= cycles_per_frame - 85) late_vsync_clear = true;
        }
        if(s0_hit_cycle(cycle) <= cycle) {
            retval |= 0x40;
        }
        if(overflow_cycle(cycle) <= cycle) {
            retval |= 0x20;
        }
        scroll_latch = false;
        ++s.twok2_reads;
        break;
    case 0x2004:
        retval = sprites[spraddr/4].val[spraddr%4];
        break;
    case 0x2007:
        //cout<<"0x2007 (0x"<<hex<<vram_ptr.pointer<<dec<<"): (";
        if(vram_ptr.pointer < 0x2000) {
            //cout<<"Reading from Pattern Table)";
            retval = ppu_ram_buffer;
            ppu_ram_buffer = cart.get_cbyte(vram_ptr.pointer);
        }
        else {
            unsigned int ptr = vram_ptr.pointer;
            retval = ppu_ram_buffer;
            if(ptr >= 0x3000 && ptr < 0x3F00) ptr -= 0x1000;
            if(ptr < 0x23C0) {
                //cout<<"Reading from Name Table 0)";
                ppu_ram_buffer = nt[0][ptr - 0x2000];
            }
            else if(ptr < 0x2400) {
                //cout<<"Reading from Attribute Table 0)";
                ppu_ram_buffer = at[0][ptr - 0x23C0];
            }
            else if(ptr < 0x27C0) {
                //cout<<"Reading from Name Table 1)";
                ppu_ram_buffer = nt[1][ptr - 0x2400];
            }
            else if(ptr < 0x2800) {
                //cout<<"Reading from Attribute Table 1)";
                ppu_ram_buffer = at[1][ptr - 0x27C0];
            }
            else if(ptr < 0x2BC0) {
                //cout<<"Reading from Name Table 2)";
                ppu_ram_buffer = nt[2][ptr - 0x2800];
            }
            else if(ptr < 0x2C00) {
                //cout<<"Reading from Attribute Table 2)";
                ppu_ram_buffer = at[2][ptr - 0x2BC0];
            }
            else if(ptr < 0x2FC0) {
                //cout<<"Reading from Name Table 3)";
                ppu_ram_buffer = nt[3][ptr - 0x2C00];
            }
            else if(ptr < 0x3000) {
                //cout<<"Reading from Attribute Table 3)";
                ppu_ram_buffer = at[3][ptr - 0x2FC0];
            }
            else {
                ptr &= 0x1f;
                if(ptr < 0x10) {
                    //cout<<"Reading from Background Palette)";
                }
                else {
                    //cout<<"Reading from Sprite Palette)";
                }
                retval = *(pal[ptr]);
                ppu_ram_buffer = retval;
            }
        }
        //cout<<hex<<": 0x"<<int(retval)<<dec<<endl;
        vram_ptr.pointer++;
        if(control0.v_inc_down) vram_ptr.pointer +=31;
        break;
    default:
        //cout<<"Reading from register 0x"<<hex<<addr<<" isn't handled."<<dec<<endl;
        retval = control1.reg;
        break;
    }
    ++s.reads;
    return retval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %r14d
movq %rdi, %rbx
movl 0x2185c(%rdi), %eax
andl $0x1, %eax
movb 0x21854(%rdi), %bpl
testb $0x18, %bpl
setne %cl
cmpl $0x1aa4, %edx           # imm = 0x1AA4
setae %dl
andb %cl, %dl
movl %eax, %ecx
xorl $0x1bf9, %ecx           # imm = 0x1BF9
cmpl %r14d, %ecx
setbe %cl
andb %dl, %cl
xorl $0x15ba9, %eax          # imm = 0x15BA9
cmpl %r14d, %eax
seta %al
andb %cl, %al
cmpb $0x1, %al
jne 0xed58
incl 0x1c0(%rbx)
cmpl $0x2007, %esi           # imm = 0x2007
je 0xede5
cmpl $0x2004, %esi           # imm = 0x2004
je 0xedc6
cmpl $0x2002, %esi           # imm = 0x2002
jne 0xef90
cmpb $0x0, 0x6e3(%rbx)
jne 0xee1d
testb $0x18, %bpl
setne %al
cmpl $0x1aa4, %r14d          # imm = 0x1AA4
setb %cl
andb %al, %cl
movl 0x6e8(%rbx), %eax
addl $-0x55, %eax
cmpl %r14d, %eax
setbe %dl
orb %cl, %dl
cmpb $0x1, %dl
jne 0xee1d
movb $0x1, 0x6e3(%rbx)
movb $-0x80, %bpl
cmpl %r14d, %eax
ja 0xee1f
movb $0x1, 0x6e4(%rbx)
jmp 0xee1f
movzbl 0x308(%rbx), %eax
movl %eax, %ecx
andl $-0x4, %ecx
addq %rbx, %rcx
andl $0x3, %eax
movb 0x208(%rax,%rcx), %bpl
jmp 0xef90
movzwl 0x6dc(%rbx), %eax
movl %eax, %esi
andl $0x3fff, %esi           # imm = 0x3FFF
movb 0x6e1(%rbx), %bpl
cmpl $0x1fff, %esi           # imm = 0x1FFF
ja 0xee64
movq (%rbx), %rdi
callq 0xa03e
movb %al, 0x6e1(%rbx)
movzwl 0x6dc(%rbx), %eax
jmp 0xef5c
xorl %ebp, %ebp
movq %rbx, %rdi
callq 0xe900
movzbl %bpl, %ecx
orb $0x40, %bpl
cmpl %r14d, %eax
movzbl %bpl, %r15d
cmoval %ecx, %r15d
movq %rbx, %rdi
callq 0xebd0
movl %r15d, %ecx
orb $0x20, %cl
cmpl %r14d, %eax
movzbl %cl, %ebp
cmoval %r15d, %ebp
movb $0x0, 0x6e2(%rbx)
incl 0x1bc(%rbx)
jmp 0xef90
movzwl %si, %ecx
addl $0xffffd000, %ecx       # imm = 0xFFFFD000
movzwl %cx, %edx
leal -0x1000(%rsi), %ecx
cmpl $0xf00, %edx            # imm = 0xF00
cmovael %esi, %ecx
cmpl $0x23bf, %ecx           # imm = 0x23BF
ja 0xee9c
movq 0x16f0(%rbx), %rdx
movl %ecx, %ecx
movb -0x2000(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x23ff, %ecx           # imm = 0x23FF
ja 0xeeb9
movq 0x1710(%rbx), %rdx
movl %ecx, %ecx
movb -0x23c0(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x27bf, %ecx           # imm = 0x27BF
ja 0xeed6
movq 0x16f8(%rbx), %rdx
movl %ecx, %ecx
movb -0x2400(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x27ff, %ecx           # imm = 0x27FF
ja 0xeef0
movq 0x1718(%rbx), %rdx
movl %ecx, %ecx
movb -0x27c0(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x2bbf, %ecx           # imm = 0x2BBF
ja 0xef0a
movq 0x1700(%rbx), %rdx
movl %ecx, %ecx
movb -0x2800(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x2bff, %ecx           # imm = 0x2BFF
ja 0xef24
movq 0x1720(%rbx), %rdx
movl %ecx, %ecx
movb -0x2bc0(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x2fbf, %ecx           # imm = 0x2FBF
ja 0xef3e
movq 0x1708(%rbx), %rdx
movl %ecx, %ecx
movb -0x2c00(%rdx,%rcx), %cl
jmp 0xef56
cmpl $0x2fff, %ecx           # imm = 0x2FFF
ja 0xefa3
movq 0x1728(%rbx), %rdx
movl %ecx, %ecx
movb -0x2fc0(%rdx,%rcx), %cl
movb %cl, 0x6e1(%rbx)
leal 0x1(%rax), %edx
andl $0x3fff, %edx           # imm = 0x3FFF
movl %eax, %ecx
andl $0xc000, %ecx           # imm = 0xC000
orl %ecx, %edx
movw %dx, 0x6dc(%rbx)
testb $0x4, 0x21850(%rbx)
je 0xef90
addl $0x20, %eax
andl $0x3fff, %eax           # imm = 0x3FFF
orl %eax, %ecx
movw %cx, 0x6dc(%rbx)
incl 0x1b8(%rbx)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
andl $0x1f, %ecx
movq 0x1750(%rbx,%rcx,8), %rcx
movb (%rcx), %bpl
movb %bpl, 0x6e1(%rbx)
jmp 0xef5c