// File: /workspace/github_cpp_makefile_star2_O1/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:
cmpl $0xff, %esi
ja 0x70f2
cmpb $0x1, 0x23(%rdi)
jne 0x70f2
movzwl %si, %eax
movq 0xa0(%rdi), %rcx
jmp 0x7121
testw %si, %si
js 0x710b
movq (%rdi), %rax
cmpb $0x1, 0x20(%rax)
jne 0x710b
movzwl %si, %esi
movq %rax, %rdi
jmp 0x2816
movswl %si, %eax
cmpl $0xffff9fff, %eax       # imm = 0xFFFF9FFF
jg 0x7125
movzwl %si, %eax
andl $0x1fff, %eax           # imm = 0x1FFF
movq 0x28(%rdi), %rcx
movb (%rcx,%rax), %al
retq
movl %esi, %eax
andl $0xe000, %eax           # imm = 0xE000
cmpl $0xc000, %eax           # imm = 0xC000
je 0x7145
cmpl $0xa000, %eax           # imm = 0xA000
jne 0x7154
movq (%rdi), %rdi
movzwl %si, %esi
jmp 0x2816
movq 0x40(%rdi), %rax
movzwl %si, %ecx
movb -0xc000(%rax,%rcx), %al
retq
leal 0x2000(%rsi), %eax
movzwl %ax, %eax
cmpl $0x1dff, %eax           # imm = 0x1DFF
ja 0x7173
movq 0x40(%rdi), %rax
movzwl %si, %ecx
movb -0xe000(%rax,%rcx), %al
retq
leal 0x200(%rsi), %eax
movzwl %ax, %eax
cmpl $0x9f, %eax
ja 0x7192
movq 0x58(%rdi), %rax
movzwl %si, %ecx
movb -0xfe00(%rax,%rcx), %al
retq
movl %esi, %eax
andl $0xff80, %eax           # imm = 0xFF80
cmpl $0xff00, %eax           # imm = 0xFF00
setne %al
cmpw $-0x1, %si
setne %cl
testb %al, %cl
jne 0x71d1
movzbl %sil, %ecx
cmpl $0x3f, %ecx
jle 0x71eb
leal -0x40(%rcx), %eax
cmpl $0xb, %eax
ja 0x7219
leaq 0x3848(%rip), %rcx      # 0xaa0c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb 0x18(%rdi), %al
retq
movb $-0x1, %al
cmpw $-0x80, %si
jb 0x71ea
movq 0x88(%rdi), %rax
movzwl %si, %ecx
movb -0xff80(%rax,%rcx), %al
retq
cmpl $0x7, %ecx
ja 0x720b
movl %ecx, %eax
leaq 0x37f3(%rip), %rcx      # 0xa9ec
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%rdi), %rdi
jmp 0x5eec
cmpl $0xf, %ecx
je 0x7287
movb $-0x1, %al
cmpl $0x13, %ecx
je 0x71ea
jmp 0x722c
cmpl $0xff, %ecx
jne 0x722c
movq 0x70(%rdi), %rax
movb 0xff(%rax), %al
retq
movq 0x70(%rdi), %rax
movzwl %si, %ecx
movb -0xff00(%rax,%rcx), %al
retq
movq 0x10(%rdi), %rax
movb 0x1(%rax), %al
retq
movq 0x10(%rdi), %rax
movb 0x2(%rax), %al
retq
movq 0x10(%rdi), %rax
movb 0x3(%rax), %al
retq
movq 0x10(%rdi), %rax
movb 0x4(%rax), %al
orb $-0x8, %al
retq
movb 0x20(%rdi), %al
retq
movb 0x21(%rdi), %al
retq
movb 0x1b(%rdi), %al
retq
movb 0x19(%rdi), %al
orb $-0x80, %al
retq
movb 0x1a(%rdi), %al
retq
movb 0x1d(%rdi), %al
retq
movb 0x1c(%rdi), %al
retq
movb 0x1f(%rdi), %al
retq
movb 0x1e(%rdi), %al
retq
movb 0x22(%rdi), %al
retq
movq 0x70(%rdi), %rax
movb 0xf(%rax), %al
orb $-0x20, %al
retq
nop