// File: mindbeast[P]rnes/mmc.cpp
// Function: Rnes::Mmc1::vidMemRead(unsigned short)
uint8_t Mmc1::vidMemRead(uint16_t addr) {
  bool chr8kMode = getChrRomMode() == 0;
  if (charRoms.size() > 0) {
    // chr rom @ 0x0
    if (addr < 0x1000) {
      if (chr8kMode) {
        return *(charRoms[chr0Bank >> 1] + addr);
      } else {
        return *(charRoms[chr0Bank >> 1] + addr + ((chr0Bank & 0x1) ? 0x1000 : 0));
      }
    }
    // chr rom @ 0x1000
    if ((addr >= 0x1000) and (addr <= 0x1fff)) {
      if (chr8kMode) {
        return *(charRoms[chr0Bank >> 1] + addr);
      } else {
        return *(charRoms[chr1Bank >> 1] + addr + ((chr1Bank & 0x1) ? 0x1000 : 0) - 0x1000);
      }
    }
  } else {
    if (chr8kMode) {
      if (addr < 0x2000) {
        return videoMemory->patternTableMemory[addr];
      }
    } else {
      if (addr < 0x1000) {
        return videoMemory->patternTableMemory[addr + (chr0Bank & 0x1) ? 0x1000 : 0];
      }
      if ((addr >= 0x1000) and (addr <= 0x1fff)) {
        return videoMemory->patternTableMemory[addr - 0x1000 + (chr1Bank & 0x1) ? 0x1000 : 0];
      }
    }
  }

  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), %rdi
movq %rdi, -0x20(%rbp)
callq 0x43640
movq -0x20(%rbp), %rdi
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, -0x13(%rbp)
addq $0x20, %rdi
callq 0x3fb30
cmpq $0x0, %rax
jbe 0x42738
movzwl -0x12(%rbp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
jge 0x42691
testb $0x1, -0x13(%rbp)
je 0x42645
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x20, %rdi
movzbl 0x51(%rax), %eax
sarl %eax
movslq %eax, %rsi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x20, %rdi
movzbl 0x51(%rax), %eax
sarl %eax
movslq %eax, %rsi
callq 0x43600
movq -0x20(%rbp), %rcx
movq (%rax), %rax
movzwl -0x12(%rbp), %edx
movslq %edx, %rdx
addq %rdx, %rax
movzbl 0x51(%rcx), %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1000, %edx           # imm = 0x1000
cmpl $0x0, %esi
cmovnel %edx, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
movzwl -0x12(%rbp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
jl 0x42733
movzwl -0x12(%rbp), %eax
cmpl $0x1fff, %eax           # imm = 0x1FFF
jg 0x42733
testb $0x1, -0x13(%rbp)
je 0x426e3
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x20, %rdi
movzbl 0x51(%rax), %eax
sarl %eax
movslq %eax, %rsi
callq 0x43600
movq (%rax), %rax
movzwl -0x12(%rbp), %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x20, %rdi
movzbl 0x52(%rax), %eax
sarl %eax
movslq %eax, %rsi
callq 0x43600
movq -0x20(%rbp), %rcx
movq (%rax), %rax
movzwl -0x12(%rbp), %edx
movslq %edx, %rdx
addq %rdx, %rax
movzbl 0x52(%rcx), %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1000, %edx           # imm = 0x1000
cmpl $0x0, %esi
cmovnel %edx, %ecx
movslq %ecx, %rcx
movb -0x1000(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
jmp 0x427ed
testb $0x1, -0x13(%rbp)
je 0x42766
movzwl -0x12(%rbp), %eax
cmpl $0x2000, %eax           # imm = 0x2000
jge 0x42761
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movzwl -0x12(%rbp), %ecx
movb 0x8(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
jmp 0x427eb
movzwl -0x12(%rbp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
jge 0x4279f
movq -0x20(%rbp), %rcx
movq 0x48(%rcx), %rax
movzwl -0x12(%rbp), %esi
movzbl 0x51(%rcx), %ecx
andl $0x1, %ecx
addl %ecx, %esi
xorl %ecx, %ecx
movl $0x1000, %edx           # imm = 0x1000
cmpl $0x0, %esi
cmovnel %edx, %ecx
movslq %ecx, %rcx
movb 0x8(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
movzwl -0x12(%rbp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
jl 0x427e9
movzwl -0x12(%rbp), %eax
cmpl $0x1fff, %eax           # imm = 0x1FFF
jg 0x427e9
movq -0x20(%rbp), %rcx
movq 0x48(%rcx), %rax
movzwl -0x12(%rbp), %esi
subl $0x1000, %esi           # imm = 0x1000
movzbl 0x52(%rcx), %ecx
andl $0x1, %ecx
addl %ecx, %esi
xorl %ecx, %ecx
movl $0x1000, %edx           # imm = 0x1000
cmpl $0x0, %esi
cmovnel %edx, %ecx
movslq %ecx, %rcx
movb 0x8(%rax,%rcx), %al
movb %al, -0x1(%rbp)
jmp 0x427f1
jmp 0x427eb
jmp 0x427ed
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)