// File: /workspace/github_cpp_makefile_star2_O3/mindbeast[P]rnes/ppu.cpp
// Function: Rnes::Ppu::writeReg(unsigned int, unsigned char)
void Ppu::writeReg(uint32_t reg, uint8_t val) {
  // CONTROL1_REG            = 0,
  // CONTROL2_REG            = 1,
  // STATUS_REG              = 2,
  // SPR_ADDR_REG            = 3,
  // SPR_DATA_REG            = 4,
  // VRAM_ADDR_REG1          = 5,
  // VRAM_ADDR_REG2          = 6,
  // VRAM_DATA_REG           = 7,
  switch (reg) {
  case CONTROL1_REG:
    vramTempAddr = (vramTempAddr & 0xf3ff) | ((uint16_t)val & 0x3) << 10;
  case CONTROL2_REG:
    // Write only registers.
    regs[reg] = val;
    break;
  case STATUS_REG:
    // Read only register.
    break;
  case SPR_ADDR_REG:
    regs[reg] = val;
    break;
  case SPR_DATA_REG:
    memcpy(regs[SPR_ADDR_REG] + (uint8_t *)&spriteRam[0], &val, 1);
    regs[SPR_ADDR_REG]++;
    break;
  case VRAM_ADDR_REG1:
    if (vramToggle == 0) {
      vramTempAddr = (0xffe0 & vramTempAddr) | (val >> 3);
      vramFineXScroll = val & 0x7;
    } else {
      vramTempAddr =
          (0xc1f & vramTempAddr) | (((uint16_t)val & 0x7) << 12) | (((uint16_t)val & 0xf8) << 2);
    }
    vramToggle = not vramToggle;
    break;
  case VRAM_ADDR_REG2:
    if (vramToggle == 0) {
      vramTempAddr = (((uint16_t)val & 0x3f) << 8) | (vramTempAddr & 0xff);
    } else {
      vramTempAddr = val | (vramTempAddr & 0xff00);
      vramCurrentAddr = vramTempAddr;
    }
    vramToggle = not vramToggle;
    break;
  case VRAM_DATA_REG:
    nes->vidMemWrite(vramCurrentAddr, val);
    vramCurrentAddr += getVramAddrInc();
    break;
  default:
    assert(0);
    break;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
cmpl $0x7, %esi
ja 0x18636
movq %rdi, %rbx
movl %esi, %eax
leaq 0x1b741(%rip), %rcx     # 0x33c60
movslq (%rcx,%rax,4), %rsi
addq %rcx, %rsi
jmpq *%rsi
movzwl 0x13a(%rbx), %ecx
andl $0xfffff3ff, %ecx       # imm = 0xFFFFF3FF
movl %edx, %esi
andb $0x3, %sil
movzbl %sil, %esi
shll $0xa, %esi
orl %ecx, %esi
movw %si, 0x13a(%rbx)
movb %dl, 0x28(%rbx,%rax)
jmp 0x1862f
movzbl 0x2b(%rbx), %eax
movb %dl, 0x30(%rbx,%rax)
incl %eax
movb %al, 0x2b(%rbx)
jmp 0x1862f
movb %dl, 0x2b(%rbx)
jmp 0x1862f
movq 0x8(%rbx), %rdi
movzwl 0x138(%rbx), %esi
movzbl %dl, %edx
callq 0x207d0
testb $0x4, 0x28(%rbx)
movl $0x1, %eax
movl $0x20, %ecx
cmovel %eax, %ecx
addw %cx, 0x138(%rbx)
jmp 0x1862f
movl 0x130(%rbx), %eax
movzwl 0x13a(%rbx), %ecx
testl %eax, %eax
je 0x185fa
andl $0xc1f, %ecx            # imm = 0xC1F
movzbl %dl, %edx
movl %edx, %esi
shll $0xc, %esi
leal (%rsi,%rdx,4), %edx
andl $0x73e0, %edx           # imm = 0x73E0
orl %ecx, %edx
movw %dx, 0x13a(%rbx)
jmp 0x18622
movl 0x130(%rbx), %eax
testl %eax, %eax
je 0x18619
movzbl 0x13b(%rbx), %ecx
shll $0x8, %ecx
movzbl %dl, %edx
orl %ecx, %edx
movw %dx, 0x13a(%rbx)
movw %dx, 0x138(%rbx)
jmp 0x18622
andl $-0x20, %ecx
movzbl %dl, %edx
movl %edx, %esi
shrl $0x3, %esi
orl %ecx, %esi
movw %si, 0x13a(%rbx)
andl $0x7, %edx
movl %edx, 0x134(%rbx)
jmp 0x18622
andb $0x3f, %dl
movb %dl, 0x13b(%rbx)
xorl %ecx, %ecx
testl %eax, %eax
sete %cl
movl %ecx, 0x130(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
leaq 0x1ae67(%rip), %rdi     # 0x334a4
leaq 0x1b798(%rip), %rsi     # 0x33ddc
leaq 0x1b80a(%rip), %rcx     # 0x33e55
movl $0xfc, %edx
callq 0xa160
nop