// File: /workspace/github_cpp_makefile_star2_O2/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 %r14
pushq %rbx
movl %edx, %ebp
movl %esi, %r14d
movq %rdi, %rbx
movl %edx, %esi
callq 0xce48
cmpl $0x3, %eax
jne 0xd286
incl 0x1c0(%rbx)
cmpl $0x2007, %r14d          # imm = 0x2007
je 0xd341
cmpl $0x2004, %r14d          # imm = 0x2004
je 0xd322
cmpl $0x2002, %r14d          # imm = 0x2002
jne 0xd378
cmpb $0x0, 0x6e3(%rbx)
jne 0xd2dc
movq %rbx, %rdi
movl %ebp, %esi
callq 0xce48
cmpl $0x1, %eax
setne %cl
movl 0x6e8(%rbx), %eax
addl $-0x55, %eax
cmpl %ebp, %eax
seta %dl
testb %dl, %cl
je 0xd3d5
xorl %r14d, %r14d
movq %rbx, %rdi
callq 0xce9c
movzbl %r14b, %ecx
orb $0x40, %r14b
cmpl %ebp, %eax
movzbl %r14b, %r14d
cmoval %ecx, %r14d
movq %rbx, %rdi
callq 0xd15a
movl %r14d, %ecx
orb $0x20, %cl
cmpl %ebp, %eax
movzbl %cl, %ebp
cmoval %r14d, %ebp
movb $0x0, 0x6e2(%rbx)
incl 0x1bc(%rbx)
jmp 0xd4ca
movzbl 0x308(%rbx), %eax
movl %eax, %ecx
andl $-0x4, %ecx
addq %rbx, %rcx
andl $0x3, %eax
movb 0x208(%rax,%rcx), %bpl
jmp 0xd4ca
movzwl 0x6dc(%rbx), %eax
movl %eax, %esi
andl $0x3fff, %esi           # imm = 0x3FFF
movb 0x6e1(%rbx), %bpl
cmpw $0x1fff, %si            # imm = 0x1FFF
ja 0xd384
movq (%rbx), %rdi
callq 0x8f1a
movb %al, 0x6e1(%rbx)
movzwl 0x6dc(%rbx), %eax
jmp 0xd496
movb 0x21854(%rbx), %bpl
jmp 0xd4ca
movzwl %si, %edx
addl $0xffffd000, %edx       # imm = 0xFFFFD000
leal -0x1000(%rsi), %ecx
cmpw $0xf00, %dx             # imm = 0xF00
cmovael %esi, %ecx
cmpl $0x23bf, %ecx           # imm = 0x23BF
ja 0xd3b8
movq 0x16f0(%rbx), %rdx
movl %ecx, %ecx
movb -0x2000(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x23ff, %ecx           # imm = 0x23FF
ja 0xd3f3
movq 0x1710(%rbx), %rdx
movl %ecx, %ecx
movb -0x23c0(%rdx,%rcx), %cl
jmp 0xd490
movb $0x1, 0x6e3(%rbx)
movb $-0x80, %r14b
cmpl %ebp, %eax
ja 0xd2df
movb $0x1, 0x6e4(%rbx)
jmp 0xd2df
cmpl $0x27bf, %ecx           # imm = 0x27BF
ja 0xd410
movq 0x16f8(%rbx), %rdx
movl %ecx, %ecx
movb -0x2400(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x27ff, %ecx           # imm = 0x27FF
ja 0xd42a
movq 0x1718(%rbx), %rdx
movl %ecx, %ecx
movb -0x27c0(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x2bbf, %ecx           # imm = 0x2BBF
ja 0xd444
movq 0x1700(%rbx), %rdx
movl %ecx, %ecx
movb -0x2800(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x2bff, %ecx           # imm = 0x2BFF
ja 0xd45e
movq 0x1720(%rbx), %rdx
movl %ecx, %ecx
movb -0x2bc0(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x2fbf, %ecx           # imm = 0x2FBF
ja 0xd478
movq 0x1708(%rbx), %rdx
movl %ecx, %ecx
movb -0x2c00(%rdx,%rcx), %cl
jmp 0xd490
cmpl $0x2fff, %ecx           # imm = 0x2FFF
ja 0xd4d7
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 0xd4ca
addl $0x20, %eax
andl $0x3fff, %eax           # imm = 0x3FFF
orl %eax, %ecx
movw %cx, 0x6dc(%rbx)
incl 0x1b8(%rbx)
movl %ebp, %eax
popq %rbx
popq %r14
popq %rbp
retq
andl $0x1f, %ecx
movq 0x1750(%rbx,%rcx,8), %rcx
movb (%rcx), %bpl
movb %bpl, 0x6e1(%rbx)
jmp 0xd496