// File: mindbeast[P]rnes/apu.cpp
// Function: Rnes::Apu::writeReg(unsigned int, unsigned char)
void Apu::writeReg(uint32_t reg, uint8_t val) {
  regs[reg] = val;
  if (reg == SOFTCLOCK) {
    resetFrameCounter();
  } else if (reg == CONTROL_STATUS) {
    clearRequestDmcIrq();
    // xx what to do with the upper bits here
    if (~val & STATUS_CHANNEL1_LENGTH) {
      pulseA->zeroLength();
    }
    if (~val & STATUS_CHANNEL2_LENGTH) {
      pulseB->zeroLength();
    }
    if (~val & STATUS_CHANNEL3_LENGTH) {
      triangle->zeroLength();
    }
    if (~val & STATUS_CHANNEL4_LENGTH) {
      noise->zeroLength();
    }
  } else if (reg == CHANNEL1_LENGTH) {
    pulseA->resetLength();
    pulseA->resetSequencer();
    pulseA->resetEnvelope();
  } else if (reg == CHANNEL2_LENGTH) {
    pulseB->resetLength();
    pulseB->resetSequencer();
    pulseB->resetEnvelope();
  } else if (reg == CHANNEL3_LENGTH) {
    triangle->resetLength();
    triangle->setHaltFlag();
  } else if (reg == CHANNEL4_LENGTH) {
    noise->resetLength();
    noise->resetEnvelope();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movb %al, -0xd(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb -0xd(%rbp), %dl
movl -0xc(%rbp), %ecx
movb %dl, 0xb8(%rax,%rcx)
cmpl $0x17, -0xc(%rbp)
jne 0x2655d
movq -0x18(%rbp), %rdi
callq 0x25ee0
jmp 0x2672c
cmpl $0x15, -0xc(%rbp)
jne 0x26611
movq -0x18(%rbp), %rdi
callq 0x27620
movzbl -0xd(%rbp), %eax
xorl $-0x1, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x26597
movq -0x18(%rbp), %rdi
addq $0xe8, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x27650
movzbl -0xd(%rbp), %eax
xorl $-0x1, %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x265be
movq -0x18(%rbp), %rdi
addq $0xf0, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x27650
movzbl -0xd(%rbp), %eax
xorl $-0x1, %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x265e5
movq -0x18(%rbp), %rdi
addq $0xf8, %rdi
callq 0x27390
movq %rax, %rdi
callq 0x27670
movzbl -0xd(%rbp), %eax
xorl $-0x1, %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x2660c
movq -0x18(%rbp), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x273b0
movq %rax, %rdi
callq 0x27690
jmp 0x2672a
cmpl $0x3, -0xc(%rbp)
jne 0x26664
movq -0x18(%rbp), %rdi
addq $0xe8, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x276b0
movq -0x18(%rbp), %rdi
addq $0xe8, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x276f0
movq -0x18(%rbp), %rdi
addq $0xe8, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x27710
jmp 0x26728
cmpl $0x7, -0xc(%rbp)
jne 0x266b4
movq -0x18(%rbp), %rdi
addq $0xf0, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x276b0
movq -0x18(%rbp), %rdi
addq $0xf0, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x276f0
movq -0x18(%rbp), %rdi
addq $0xf0, %rdi
callq 0x27370
movq %rax, %rdi
callq 0x27710
jmp 0x26726
cmpl $0xb, -0xc(%rbp)
jne 0x266ec
movq -0x18(%rbp), %rdi
addq $0xf8, %rdi
callq 0x27390
movq %rax, %rdi
callq 0x27730
movq -0x18(%rbp), %rdi
addq $0xf8, %rdi
callq 0x27390
movq %rax, %rdi
callq 0x27770
jmp 0x26724
cmpl $0xf, -0xc(%rbp)
jne 0x26722
movq -0x18(%rbp), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x273b0
movq %rax, %rdi
callq 0x27790
movq -0x18(%rbp), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x273b0
movq %rax, %rdi
callq 0x277d0
jmp 0x26724
jmp 0x26726
jmp 0x26728
jmp 0x2672a
jmp 0x2672c
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)