// File: /workspace/github_cpp_makefile_star2_O2/nicoeps[P]NicoGB/src/memory.cpp
// Function: Memory::read(unsigned short)
uint8_t Memory::read(uint16_t address) {
    if (address < 0x100 && bootEnabled) {
        return boot[address];
    } else if (address <= 0x7FFF && cartridge.loaded == true) {
        return cartridge.read(address);
    } else if (address >= 0x8000 && address <= 0x9FFF) {
        return vram[address - 0x8000];
    } else if (address >= 0xA000 && address <= 0xBFFF) {
        return cartridge.read(address);
    } else if (address >= 0xC000 && address <= 0xDFFF) {
        return wram[address - 0xC000];
    } else if (address >= 0xE000 && address <= 0xFDFF) {
        return wram[address - 0xE000];
    } else if (address >= 0xFE00 && address <= 0xFE9F) {
        return oam[address - 0xFE00];
    } else if ((address >= 0xFF00 && address <= 0xFF7F) || address == 0xFFFF) {
        switch (address) {
            case 0xFF00: return joypad.read();
            case 0xFF04: return timer.divider;
            case 0xFF05: return timer.tima;
            case 0xFF06: return timer.tma;
            case 0xFF07: return timer.tac | 0xF8;
            case 0xFF13: return 0xFF; // NR13
            case 0xFF40: return lcd.lcdc;
            case 0xFF41: return lcd.stat | 0x80;
            case 0xFF42: return lcd.scy;
            case 0xFF43: return lcd.scx;
            case 0xFF44: return lcd.ly;
            case 0xFF45: return lcd.lyc;
            case 0xFF47: return lcd.bgp;
            case 0xFF48: return lcd.obp0;
            case 0xFF49: return lcd.obp1;
            case 0xFF4A: return lcd.wy;
            case 0xFF4B: return lcd.wx;
            case 0xFFFF: return io[0xFF]; // IE
            case 0xFF0F: return io[0x0F] | 0xE0; // IF
            default:     return io[address - 0xFF00];
        }
    } else if (address >= 0xFF80 && address <= 0xFFFE) {
        return hram[address - 0xFF80];
    } else {
        return 0xFF;
    }
}

// Assembly:
cmpw $0xff, %si
ja 0x64ed
cmpb $0x1, 0x23(%rdi)
jne 0x64f2
movzwl %si, %eax
movq 0xa0(%rdi), %rcx
movb (%rcx,%rax), %al
retq
testw %si, %si
js 0x6506
movq (%rdi), %rax
cmpb $0x1, 0x20(%rax)
jne 0x651c
movzwl %si, %esi
movq %rax, %rdi
jmp 0x27b2
cmpw $0x9fff, %si            # imm = 0x9FFF
ja 0x651c
movq 0x28(%rdi), %rax
movzwl %si, %ecx
movb -0x8000(%rax,%rcx), %al
retq
movl %esi, %eax
andl $0xe000, %eax           # imm = 0xE000
cmpw $0xc000, %ax            # imm = 0xC000
je 0x653b
cmpl $0xa000, %eax           # imm = 0xA000
jne 0x654a
movq (%rdi), %rdi
movzwl %si, %esi
jmp 0x27b2
movq 0x40(%rdi), %rax
movzwl %si, %ecx
movb -0xc000(%rax,%rcx), %al
retq
leal 0x2000(%rsi), %eax
cmpw $0x1dff, %ax            # imm = 0x1DFF
ja 0x6564
movzwl %si, %eax
andl $0x1fff, %eax           # imm = 0x1FFF
movq 0x40(%rdi), %rcx
jmp 0x64e9
leal 0x200(%rsi), %eax
cmpw $0x9f, %ax
ja 0x657f
movq 0x58(%rdi), %rax
movzwl %si, %ecx
movb -0xfe00(%rax,%rcx), %al
retq
movl %esi, %eax
andl $0xff80, %eax           # imm = 0xFF80
cmpw $0xff00, %ax            # imm = 0xFF00
setne %al
cmpw $-0x1, %si
setne %cl
testb %al, %cl
jne 0x65b8
movzbl %sil, %eax
leal -0x40(%rax), %ecx
cmpl $0xb, %ecx
ja 0x65d2
leaq 0x3485(%rip), %rax      # 0x9a30
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movb 0x18(%rdi), %al
retq
movb $-0x1, %al
cmpw $-0x80, %si
jb 0x65d1
movq 0x88(%rdi), %rax
movzwl %si, %ecx
movb -0xff80(%rax,%rcx), %al
retq
cmpl $0x7, %eax
ja 0x65f2
movl %eax, %eax
leaq 0x3430(%rip), %rcx      # 0x9a10
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%rdi), %rdi
jmp 0x55e4
cmpl $0xf, %eax
je 0x666c
cmpl $0x13, %eax
je 0x6669
cmpl $0xff, %eax
jne 0x660e
movq 0x70(%rdi), %rax
movb 0xff(%rax), %al
retq
movq 0x70(%rdi), %rax
movzwl %si, %ecx
movb -0xff00(%rax,%rcx), %al
retq
movb 0x22(%rdi), %al
retq
movb 0x1f(%rdi), %al
retq
movb 0x1a(%rdi), %al
retq
movb 0x1b(%rdi), %al
retq
movb 0x1c(%rdi), %al
retq
movb 0x19(%rdi), %al
orb $-0x80, %al
retq
movb 0x21(%rdi), %al
retq
movb 0x1e(%rdi), %al
retq
movb 0x1d(%rdi), %al
retq
movb 0x20(%rdi), %al
retq
movq 0x10(%rdi), %rax
movb 0x2(%rax), %al
retq
movq 0x10(%rdi), %rax
movb 0x1(%rax), %al
retq
movq 0x10(%rdi), %rax
movb 0x4(%rax), %al
orb $-0x8, %al
retq
movq 0x10(%rdi), %rax
movb 0x3(%rax), %al
retq
movb $-0x1, %al
retq
movq 0x70(%rdi), %rax
movb 0xf(%rax), %al
orb $-0x20, %al
retq