// File: mindbeast[P]rnes/mmc.cpp
// Function: Rnes::Mmc3::cpuMemRead(unsigned short)
uint8_t Mmc3::cpuMemRead(uint16_t addr) {
  assert(addr >= mmcCpuAddrBase);

  // prg rom @ 0x8000
  if ((addr >= 0x8000) and (addr < 0x8000 + 0x2000)) {
    uint8_t bank;
    if (isLowerPrgRomSwappable())
      bank = bankRegister[6];
    else
      bank = get8kPrgBankCount() - 2;
    return *(get8kPrgBank(bank) + addr - 0x8000);
  }
  // prg rom @ 0xa000
  if ((addr >= 0xa000) and (addr < 0xa000 + 0x2000)) {
    uint8_t bank = bankRegister[7];
    return *(get8kPrgBank(bank) + addr - 0xa000);
  }

  // prg rom @ 0xc000
  if ((addr >= 0xc000) and (addr <= 0xdfff)) {
    uint8_t bank;
    if (isLowerPrgRomSwappable())
      bank = get8kPrgBankCount() - 2;
    else
      bank = bankRegister[6];
    return *(get8kPrgBank(bank) + addr - 0xc000);
  }
  // prg rom @ 0xe000
  if ((addr >= 0xe000) and (addr <= 0xffff)) {
    return *(get8kPrgBank(get8kPrgBankCount() - 1) + addr - 0xe000);
  }
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movw %si, %ax
movq %rdi, -0x10(%rbp)
movw %ax, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movzwl -0x12(%rbp), %eax
cmpl $0x6000, %eax           # imm = 0x6000
jl 0x42e78
jmp 0x42e97
leaq 0x26d8f(%rip), %rdi     # 0x69c0e
leaq 0x26cf1(%rip), %rsi     # 0x69b77
movl $0x17b, %edx            # imm = 0x17B
leaq 0x26f9d(%rip), %rcx     # 0x69e2f
callq 0xe240
movzwl -0x12(%rbp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jl 0x42efa
movzwl -0x12(%rbp), %eax
cmpl $0xa000, %eax           # imm = 0xA000
jge 0x42efa
movq -0x20(%rbp), %rdi
callq 0x43890
testb $0x1, %al
jne 0x42ebc
jmp 0x42ec8
movq -0x20(%rbp), %rax
movb 0x59(%rax), %al
movb %al, -0x13(%rbp)
jmp 0x42ed7
movq -0x20(%rbp), %rdi
callq 0x438b0
subl $0x2, %eax
movb %al, -0x13(%rbp)
movq -0x20(%rbp), %rdi
movzbl -0x13(%rbp), %esi
callq 0x438e0
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0x8000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x42fdd
movzwl -0x12(%rbp), %eax
cmpl $0xa000, %eax           # imm = 0xA000
jl 0x42f39
movzwl -0x12(%rbp), %eax
cmpl $0xc000, %eax           # imm = 0xC000
jge 0x42f39
movq -0x20(%rbp), %rdi
movb 0x5a(%rdi), %al
movb %al, -0x14(%rbp)
movzbl -0x14(%rbp), %esi
callq 0x438e0
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xa000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x42fdd
movzwl -0x12(%rbp), %eax
cmpl $0xc000, %eax           # imm = 0xC000
jl 0x42f99
movzwl -0x12(%rbp), %eax
cmpl $0xdfff, %eax           # imm = 0xDFFF
jg 0x42f99
movq -0x20(%rbp), %rdi
callq 0x43890
testb $0x1, %al
jne 0x42f5e
jmp 0x42f6f
movq -0x20(%rbp), %rdi
callq 0x438b0
subl $0x2, %eax
movb %al, -0x15(%rbp)
jmp 0x42f79
movq -0x20(%rbp), %rax
movb 0x59(%rax), %al
movb %al, -0x15(%rbp)
movq -0x20(%rbp), %rdi
movzbl -0x15(%rbp), %esi
callq 0x438e0
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xc000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x42fdd
movzwl -0x12(%rbp), %eax
cmpl $0xe000, %eax           # imm = 0xE000
jl 0x42fd9
movzwl -0x12(%rbp), %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jg 0x42fd9
movq -0x20(%rbp), %rdi
callq 0x438b0
movq -0x20(%rbp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x438e0
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xe000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x42fdd
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)