// File: /workspace/github_cpp_makefile_star2_O2/khedoros[P]khednes/apu.cpp
// Function: apu::get_sample(int)
int apu::get_sample(int voice) {
    if(!enabled[voice] || length[voice] == 0 || wavelength_count_reset[voice] == 0) {
        //cout<<"Returning 0"<<endl;
        //cout<<"Enabled: "<<enabled[voice]<<" wavelength: "<<wavelength_count[voice]<<endl;
        return 0;
    }
    //cout<<"Generating something."<<endl;
    int to_gen = 0;
    float interleave = float(CLK_PER_FRAME * 20) / float(SAMPLE_RATE);
    if(interleave - int(interleave) >= 0.5) to_gen = int(interleave) + 1;
    else to_gen = int(interleave);
    //cout<<"to_gen: "<<to_gen<<endl;
    int accum = 0;
    int vol = 0;
    while(to_gen > 0) {
        //cout<<to_gen<<" left to go!"<<endl;
        int this_one = 0;
        if(wavelength_count[voice] == 0) clock_duty(voice);
        if(wavelength_count[voice] >= to_gen) {
            this_one = to_gen;
        }
        else this_one = wavelength_count[voice];
            
        //cout<<"Doing "<<this_one<<" for this iteration"<<endl;
        switch(voice) {
            case SQ1:
                vol = sq1_duty();
                break;
            case SQ2:
                vol = sq2_duty();
                break;
            case TRI:
                vol = tri_duty();
                break;
            case NOISE:
                vol = noise_duty();
                break;
        }
        //if(vol != 0) cout<<"Vol: "<<vol<<endl;
        to_gen -= this_one;
        wavelength_count[voice] -= this_one;
        accum += (vol * this_one);
        if(wavelength_count[voice] == 0) {
            //clock the channel's duty thingie
            clock_duty(voice);
        }
    }
    //cout<<"Accum: "<<accum<<" returning: "<<accum/41<<endl;
    return accum / 41;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, 0x4(%rsp)
movslq %esi, %rcx
xorl %eax, %eax
cmpb $0x1, 0xb4(%rdi,%rcx)
jne 0xf914
movq %rdi, %r14
cmpl $0x0, 0x174(%rdi,%rcx,4)
je 0xf914
cmpl $0x0, 0x188(%r14,%rcx,4)
je 0xf914
xorl %ebp, %ebp
pushq $0x29
popq %r15
movl 0x4(%rsp), %eax
movq %rax, 0x10(%rsp)
xorl %eax, %eax
movq %rcx, 0x8(%rsp)
movl %ebp, %r13d
testl %r15d, %r15d
jle 0xf90b
movl %r15d, %ebx
movl 0x19c(%r14,%rcx,4), %r12d
testl %r12d, %r12d
jne 0xf875
movq %r14, %rdi
movq 0x8(%rsp), %rsi
movl %eax, %ebp
callq 0xf9ec
movl %ebp, %eax
movq 0x8(%rsp), %rcx
movl 0x19c(%r14,%rcx,4), %r12d
cmpl %ebx, %r12d
movl %ebx, %ebp
cmovll %r12d, %ebp
cmpl $0x3, 0x4(%rsp)
ja 0xf8cf
movq 0x10(%rsp), %rax
leaq 0x449f(%rip), %rdx      # 0x13d30
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
movq %r14, %rdi
callq 0xfa58
jmp 0xf8ca
movslq 0x1b8(%r14), %rax
leaq 0x1dc9e(%rip), %rdx     # 0x2d550
movzbl (%rax,%rdx), %eax
jmp 0xf8cf
movq %r14, %rdi
callq 0xfae4
jmp 0xf8ca
movq %r14, %rdi
callq 0xfa94
movq 0x8(%rsp), %rcx
movl %ebx, %r15d
subl %ebp, %r15d
movl %r12d, %edx
subl %ebp, %edx
movl %edx, 0x19c(%r14,%rcx,4)
imull %eax, %ebp
addl %r13d, %ebp
cmpl %ebx, %r12d
jg 0xf83b
movq %r14, %rdi
movl 0x4(%rsp), %esi
movl %eax, %ebx
callq 0xf9ec
movl %ebx, %eax
movq 0x8(%rsp), %rcx
jmp 0xf83b
pushq $0x29
popq %rcx
movl %r13d, %eax
cltd
idivl %ecx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop