// File: mindbeast[P]rnes/mmc.cpp
// Function: Rnes::Mmc1::cpuMemRead(unsigned short)
uint8_t Mmc1::cpuMemRead(uint16_t addr) {
  assert(addr >= mmcCpuAddrBase);
  // prg rom @ 0x8000
  uint32_t prgRomMode = getPrgRomMode();
  uint8_t bank = prgBank & 0xf;
  if ((addr >= 0x8000) and (addr < 0x8000 + 0x4000)) {
    switch (prgRomMode) {
    case 0:
    case 1:
      return *(progRoms[bank & ~0x1] + addr - 0x8000);
      break;
    case 2:
      return *(progRoms[0] + addr - 0x8000);
      break;
    case 3:
      return *(progRoms[bank] + addr - 0x8000);
      break;
    default:
      assert(0);
      break;
    }
  }
  // prg rom @ 0xc000
  if (addr >= 0xc000) {
    switch (prgRomMode) {
    case 0:
    case 1:
      return *(progRoms[(bank & ~0x1) + 1] + addr - 0xc000);
      break;
    case 2:
      return *(progRoms[bank] + addr - 0xc000);
      break;
    case 3:
      return *(progRoms[progRoms.size() - 1] + addr - 0xc000);
      break;
    default:
      assert(0);
      break;
    }
  }
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movw %si, %ax
movq %rdi, -0x10(%rbp)
movw %ax, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movzwl -0x12(%rbp), %eax
cmpl $0x6000, %eax           # imm = 0x6000
jl 0x42258
jmp 0x42277
leaq 0x279af(%rip), %rdi     # 0x69c0e
leaq 0x27911(%rip), %rsi     # 0x69b77
movl $0xb1, %edx
leaq 0x27a9f(%rip), %rcx     # 0x69d11
callq 0xe240
movq -0x28(%rbp), %rdi
callq 0x43620
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, -0x18(%rbp)
movzbl 0x53(%rax), %eax
andl $0xf, %eax
movb %al, -0x19(%rbp)
movzwl -0x12(%rbp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jl 0x4237a
movzwl -0x12(%rbp), %eax
cmpl $0xc000, %eax           # imm = 0xC000
jge 0x4237a
movl -0x18(%rbp), %eax
movl %eax, -0x2c(%rbp)
subl $0x2, %eax
jb 0x422d5
jmp 0x422be
movl -0x2c(%rbp), %eax
subl $0x2, %eax
je 0x42305
jmp 0x422c8
movl -0x2c(%rbp), %eax
subl $0x3, %eax
je 0x4232f
jmp 0x4235b
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
movzbl -0x19(%rbp), %eax
andl $-0x2, %eax
movslq %eax, %rsi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0x8000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0x8000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
movzbl -0x19(%rbp), %eax
movl %eax, %esi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0x8000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
leaq 0x26167(%rip), %rdi     # 0x684c9
leaq 0x2780e(%rip), %rsi     # 0x69b77
movl $0xc2, %edx
leaq 0x2799c(%rip), %rcx     # 0x69d11
callq 0xe240
movzwl -0x12(%rbp), %eax
cmpl $0xc000, %eax           # imm = 0xC000
jl 0x42466
movl -0x18(%rbp), %eax
movl %eax, -0x30(%rbp)
subl $0x2, %eax
jb 0x423ad
jmp 0x42396
movl -0x30(%rbp), %eax
subl $0x2, %eax
je 0x423e0
jmp 0x423a0
movl -0x30(%rbp), %eax
subl $0x3, %eax
je 0x42409
jmp 0x42447
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
movzbl -0x19(%rbp), %eax
andl $-0x2, %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xc000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
movzbl -0x19(%rbp), %eax
movl %eax, %esi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xc000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
movq -0x28(%rbp), %rdi
movq %rdi, %rax
addq $0x8, %rax
movq %rax, -0x38(%rbp)
addq $0x8, %rdi
callq 0x3fb30
movq -0x38(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb -0xc000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x4246a
leaq 0x2607b(%rip), %rdi     # 0x684c9
leaq 0x27722(%rip), %rsi     # 0x69b77
movl $0xd4, %edx
leaq 0x278b0(%rip), %rcx     # 0x69d11
callq 0xe240
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)