// File: /workspace/github_cpp_makefile_star2_O2/mindbeast[P]rnes/apu.cpp
// Function: Rnes::Apu::Apu(Rnes::Nes*, Rnes::Sdl*)
Apu::Apu(Nes *parent, Sdl *audio)
    : nes{parent}, audio{audio}, frameDivider{0}, step{0}, halfTimerDivider{0},
      samplerDivider{0}, regs{0}, fourFrameCount{0}, fiveFrameCount{0}, sampleBuffer{} {
  // Create audio ringbuffer.
  std::unique_ptr<RingBuffer<uint16_t>> rbLocal(new RingBuffer<uint16_t>(1 << 12));
  rb = std::move(rbLocal);

  // Create apu units.
  std::unique_ptr<Pulse> pulseALocal(new Pulse{&regs[CHANNEL1_VOLUME_DECAY], true});
  pulseA = std::move(pulseALocal);

  std::unique_ptr<Pulse> pulseBLocal(new Pulse{&regs[CHANNEL2_VOLUME_DECAY], false});
  pulseB = std::move(pulseBLocal);

  std::unique_ptr<Triangle> triangleLocal(new Triangle{&regs[CHANNEL3_LINEAR_COUNTER]});
  triangle = std::move(triangleLocal);

  std::unique_ptr<Noise> noiseLocal(new Noise{&regs[CHANNEL4_VOLUME_DECAY]});
  noise = std::move(noiseLocal);

  // Get Current sample rate
  sampleRate = audio->getSampleRate();

  // Start audio callbacks.
  audio->registerAudioCallback(apuSdlCallback, rb.get());

  // compute clocks per sample
  clksPerSample = float(cpuClk) / float(sampleRate);

  nextSampleCountdown = 1;
  currentSampleClk = 0.0f;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbx
movq %rdi, %r14
movq %rsi, (%rdi)
movq %rdx, 0x8(%rdi)
leaq 0xe8(%rdi), %rax
movq %rax, -0x38(%rbp)
leaq 0xf0(%rdi), %rax
movq %rax, -0x30(%rbp)
leaq 0xf8(%rdi), %r12
leaq 0x100(%rdi), %r13
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rdi)
movups %xmm0, 0x2c(%rdi)
movups %xmm0, 0x3c(%rdi)
movups %xmm0, 0x4c(%rdi)
movups %xmm0, 0x5c(%rdi)
movups %xmm0, 0x6c(%rdi)
movups %xmm0, 0x7c(%rdi)
movups %xmm0, 0x8c(%rdi)
movups %xmm0, 0x9c(%rdi)
movups %xmm0, 0xb0(%rdi)
movups %xmm0, 0xc0(%rdi)
movups %xmm0, 0xd8(%rdi)
movups %xmm0, 0xe8(%rdi)
movups %xmm0, 0xf8(%rdi)
movups %xmm0, 0x108(%rdi)
movups %xmm0, 0x118(%rdi)
andq $0x0, 0x128(%rdi)
movl $0xb8, %edi
callq 0xb140
movq %rax, %r15
movq %rax, %rdi
movl $0x1000, %esi           # imm = 0x1000
callq 0x14fa6
leaq 0x108(%r14), %rdi
leaq -0x60(%rbp), %rsi
movq %r15, (%rsi)
callq 0x15772
pushq $0x20
popq %rdi
callq 0xb140
movq %rax, %r15
leaq 0xb8(%r14), %rsi
pushq $0x1
popq %rdx
movq %rax, %rdi
callq 0x1502e
andq $0x0, -0x58(%rbp)
movq -0x38(%rbp), %rdi
movq %r15, %rsi
callq 0x15232
pushq $0x20
popq %rdi
callq 0xb140
movq %rax, %r15
leaq 0xbc(%r14), %rsi
movq %rax, %rdi
xorl %edx, %edx
callq 0x1502e
andq $0x0, -0x50(%rbp)
movq -0x30(%rbp), %rdi
movq %r15, %rsi
callq 0x15232
pushq $0x38
popq %rdi
callq 0xb140
leaq 0xc0(%r14), %rcx
movups 0x1653a(%rip), %xmm0    # 0x2b190
movups %xmm0, 0x10(%rax)
movups 0x1651f(%rip), %xmm0    # 0x2b180
movups %xmm0, (%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
andl $0x0, 0x30(%rax)
andq $0x0, -0x48(%rbp)
movq %r12, %rdi
movq %rax, %rsi
callq 0x15256
pushq $0x38
popq %rdi
callq 0xb140
movq %rax, %r15
leaq 0xc4(%r14), %rsi
movq %rax, %rdi
callq 0x15056
andq $0x0, -0x40(%rbp)
movq %r13, %rdi
movq %r15, %rsi
callq 0x1527a
movq %rbx, %rdi
callq 0x1bfa4
movl %eax, 0xd0(%r14)
movq 0x108(%r14), %rdx
leaq -0x9b8(%rip), %rsi      # 0x14310
movq %rbx, %rdi
callq 0x1bf70
movl 0xd0(%r14), %eax
cvtsi2ss %rax, %xmm0
movss 0x1644c(%rip), %xmm1    # 0x2b130
divss %xmm0, %xmm1
movss %xmm1, 0x20(%r14)
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, 0x24(%r14)
leaq -0x40(%rbp), %rdi
callq 0x15088
leaq -0x48(%rbp), %rdi
callq 0x150ac
leaq -0x50(%rbp), %rdi
callq 0x150d0
leaq -0x58(%rbp), %rdi
callq 0x150d0
leaq -0x60(%rbp), %rdi
callq 0x150f4
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x14d71
movq %rax, %rbx
jmp 0x14d7a
movq %rax, %rbx
jmp 0x14d83
jmp 0x14d49
movq %rax, %rbx
jmp 0x14d8c
movq %rax, %rbx
movl $0xb8, %esi
movq %r15, %rdi
callq 0xb0f0
jmp 0x14d95
movq %rax, %rbx
jmp 0x14d95
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x15088
leaq -0x48(%rbp), %rdi
callq 0x150ac
leaq -0x50(%rbp), %rdi
callq 0x150d0
leaq -0x58(%rbp), %rdi
callq 0x150d0
leaq -0x60(%rbp), %rdi
callq 0x150f4
leaq 0x118(%r14), %rdi
callq 0x15610
addq $0x110, %r14            # imm = 0x110
movq %r14, %rdi
callq 0x1529e
movq %r13, %rdi
callq 0x15088
movq %r12, %rdi
callq 0x150ac
movq -0x30(%rbp), %rdi
callq 0x150d0
movq -0x38(%rbp), %rdi
callq 0x150d0
movq %rbx, %rdi
callq 0xb4e0