// File: khedoros[P]khednes/mem.cpp
// Function: mem::read(unsigned int)
const unsigned int mem::read(unsigned int address) {
        address&=0xFFFF;
        read_from[address] = true;
        if(address<=0x1FFF) { 
                return ram[address&0x7ff];
        }
        if(address>=0x8000) {
                return cart.get_pbyte(address);
        }
        if(address>=0x2000&&address<0x4000) {
                //util::debug(ORIGIN, "Reading ppu register address %04x\n",address);
                return pu.reg_read((address&7)+0x2000, cycle);
        }
        if((address>=0x4000&&address<0x4014)||address==0x4015) {
                //util::debug(ORIGIN, "TODO: unimplemented audio stuff.\n");
                //if(address == 0x4015) cout<<"Read sound status"<<endl;
        return snd.read_status();
                //return 0;
        }
        if(address==0x4016) {//||address==0x4017) {
                //util::debug(ORIGIN, "TODO: unimplemented joypad handling.\n");
                if(joy1_strobe) {
                        //util::debug(ORIGIN,"A (strobe is on)\n");
                        //printf("Strobe is on!\n");
                        return joy1_buttons[0];
                }
                else if(joy1_bit<8) {
                        int retval=(joy1_buttons[joy1_bit])?1:0;
                        joy1_bit++;
                        return retval;
                }
                else {
                        return 1;
                }
                return 0;
        }
        else if(address==0x4017) {
                uint32_t color = pu.get_buffer_color(mouse_x, mouse_y);
                color |= pu.get_buffer_color(mouse_x+5, mouse_y+5);
                color |= pu.get_buffer_color(mouse_x+5, mouse_y-5);
                color |= pu.get_buffer_color(mouse_x-5, mouse_y+5);
                color |= pu.get_buffer_color(mouse_x-5, mouse_y-5);
                color |= pu.get_buffer_color(mouse_x, mouse_y+5);
                color |= pu.get_buffer_color(mouse_x, mouse_y-5);
                color |= pu.get_buffer_color(mouse_x-5, mouse_y);
                color |= pu.get_buffer_color(mouse_x-5, mouse_y);
                uint8_t r = color>>(16);
                uint8_t g = (color&0xFF00)>>(8);
                uint8_t b = (color&0xFF);
                if(r > 0x80 || g > 0x80 || b > 0x80) joy2_light = 0;
                else                                 joy2_light = 8;
                //cout<<"joy2_light: "<<((joy2_light)?"yes":"no")<<endl;
                if(joy1_strobe) {
                    return joy2_buttons[0];
                }
                else if(joy2_bit<8) {
                    int retval=(joy2_buttons[joy2_bit])?1:0;
                    joy2_bit++;
                    return retval|joy2_trigger|joy2_light;
                }
                else {
                    return 1|joy2_trigger|joy2_light;
                }
                return 0;
        }
        else if(address>=0x6000&&address<=0x7fff) {
            return sram[address&0x1fff];
        }
        util::debug(ORIGIN, "mem read of %04x unhandled. I don't know what the address does.\n",address);
        return 0;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x78(%rsp)
movl %esi, 0x74(%rsp)
movq 0x78(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movl 0x74(%rsp), %eax
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0x74(%rsp)
addq $0x80, %rdi
movl 0x74(%rsp), %eax
movl %eax, %esi
callq 0x15080
movl $0x1, (%rax)
cmpl $0x1fff, 0x74(%rsp)     # imm = 0x1FFF
ja 0x144d3
movq 0x10(%rsp), %rdi
addq $0x20, %rdi
movl 0x74(%rsp), %eax
andl $0x7ff, %eax            # imm = 0x7FF
movl %eax, %eax
movl %eax, %esi
callq 0x114a0
movzbl (%rax), %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
cmpl $0x8000, 0x74(%rsp)     # imm = 0x8000
jb 0x144fa
movq 0x10(%rsp), %rax
movq (%rax), %rdi
movl 0x74(%rsp), %esi
callq 0x10ed0
movl %eax, 0x84(%rsp)
jmp 0x1491e
cmpl $0x2000, 0x74(%rsp)     # imm = 0x2000
jb 0x1453b
cmpl $0x4000, 0x74(%rsp)     # imm = 0x4000
jae 0x1453b
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movl 0x74(%rsp), %esi
andl $0x7, %esi
addl $0x2000, %esi           # imm = 0x2000
movl 0x18(%rax), %edx
callq 0x1e4f0
movzbl %al, %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
cmpl $0x4000, 0x74(%rsp)     # imm = 0x4000
jb 0x1454f
cmpl $0x4014, 0x74(%rsp)     # imm = 0x4014
jb 0x14559
cmpl $0x4015, 0x74(%rsp)     # imm = 0x4015
jne 0x14573
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0x243b0
movl %eax, 0x84(%rsp)
jmp 0x1491e
cmpl $0x4016, 0x74(%rsp)     # imm = 0x4016
jne 0x1464a
movq 0x10(%rsp), %rax
testb $0x1, 0x54(%rax)
je 0x145c8
movq 0x10(%rsp), %rsi
addq $0x70, %rsi
leaq 0x60(%rsp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x14f60
leaq 0x60(%rsp), %rdi
callq 0x150a0
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x84(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x15010
jmp 0x1491e
movq 0x10(%rsp), %rax
cmpl $0x8, 0x58(%rax)
jge 0x1463a
movq 0x10(%rsp), %rax
movq %rax, %rsi
addq $0x70, %rsi
movslq 0x58(%rax), %rdx
leaq 0x48(%rsp), %rdi
callq 0x14f60
leaq 0x48(%rsp), %rdi
callq 0x150a0
movb %al, %dl
xorl %eax, %eax
movl $0x1, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, 0xc(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x15010
movl 0xc(%rsp), %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x5c(%rsp)
movl 0x58(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x58(%rax)
movl 0x5c(%rsp), %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
movl $0x1, 0x84(%rsp)
jmp 0x1491e
cmpl $0x4017, 0x74(%rsp)     # imm = 0x4017
jne 0x148bd
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
movl 0x6c(%rax), %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
addl $0x5, %esi
movl 0x6c(%rax), %edx
addl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
addl $0x5, %esi
movl 0x6c(%rax), %edx
subl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
subl $0x5, %esi
movl 0x6c(%rax), %edx
addl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
subl $0x5, %esi
movl 0x6c(%rax), %edx
subl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
movl 0x6c(%rax), %edx
addl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
movl 0x6c(%rax), %edx
subl $0x5, %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
subl $0x5, %esi
movl 0x6c(%rax), %edx
callq 0x1fe00
movl %eax, %ecx
movq 0x10(%rsp), %rax
orl 0x44(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movq 0x8(%rax), %rdi
movl 0x68(%rax), %esi
subl $0x5, %esi
movl 0x6c(%rax), %edx
callq 0x1fe00
orl 0x44(%rsp), %eax
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
shrl $0x10, %eax
movb %al, 0x43(%rsp)
movl 0x44(%rsp), %eax
andl $0xff00, %eax           # imm = 0xFF00
shrl $0x8, %eax
movb %al, 0x42(%rsp)
movl 0x44(%rsp), %eax
andl $0xff, %eax
movb %al, 0x41(%rsp)
movzbl 0x43(%rsp), %eax
cmpl $0x80, %eax
jg 0x147d0
movzbl 0x42(%rsp), %eax
cmpl $0x80, %eax
jg 0x147d0
movzbl 0x41(%rsp), %eax
cmpl $0x80, %eax
jle 0x147de
movq 0x10(%rsp), %rax
movl $0x0, 0x64(%rax)
jmp 0x147ea
movq 0x10(%rsp), %rax
movl $0x8, 0x64(%rax)
movq 0x10(%rsp), %rax
testb $0x1, 0x54(%rax)
je 0x14831
movq 0x10(%rsp), %rsi
addq $0x78, %rsi
leaq 0x30(%rsp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x14f60
leaq 0x30(%rsp), %rdi
callq 0x150a0
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x84(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x15010
jmp 0x1491e
movq 0x10(%rsp), %rax
cmpl $0x8, 0x5c(%rax)
jge 0x148a6
movq 0x10(%rsp), %rax
movq %rax, %rsi
addq $0x78, %rsi
movslq 0x5c(%rax), %rdx
leaq 0x18(%rsp), %rdi
callq 0x14f60
leaq 0x18(%rsp), %rdi
callq 0x150a0
movb %al, %dl
xorl %eax, %eax
movl $0x1, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, 0x8(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x15010
movl 0x8(%rsp), %eax
movq 0x10(%rsp), %rcx
movl %eax, 0x2c(%rsp)
movl 0x5c(%rcx), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rcx)
movl 0x2c(%rsp), %eax
orl 0x60(%rcx), %eax
orl 0x64(%rcx), %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
movq 0x10(%rsp), %rcx
movl 0x60(%rcx), %eax
orl $0x1, %eax
orl 0x64(%rcx), %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
cmpl $0x6000, 0x74(%rsp)     # imm = 0x6000
jb 0x148f8
cmpl $0x7fff, 0x74(%rsp)     # imm = 0x7FFF
ja 0x148f8
movq 0x10(%rsp), %rdi
addq $0x38, %rdi
movl 0x74(%rsp), %eax
andl $0x1fff, %eax           # imm = 0x1FFF
movl %eax, %eax
movl %eax, %esi
callq 0x114a0
movzbl (%rax), %eax
movl %eax, 0x84(%rsp)
jmp 0x1491e
jmp 0x148fa
jmp 0x148fc
movl 0x74(%rsp), %edx
movl $0x3, %edi
leaq 0x17140(%rip), %rsi     # 0x2ba4c
movb $0x0, %al
callq 0x20e00
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
addq $0x88, %rsp
retq
nopl (%rax)