// File: khedoros[P]khednes/apu.cpp
// Function: apu::clock_half()
void apu::clock_half() {
    for(uint8_t voice = 0; voice < 4; ++voice) {
        //clock length counter
        if(enabled[voice] && length[voice] > 0 && !loop_decay[voice] && (voice != TRI || !enable_linear_cntr)) length[voice]--;

        //Wavelength sweep
        if(voice < 2 && enabled[voice] && length[voice] > 0 && sweep_enable[voice]) {
            --sweep_count[voice];
            if(sweep_count[voice] == 0) {
                int sweep_amount = wavelength_count_reset[voice];
                sweep_amount>>=(sweep_shift[voice]);
                if(sweep_dir[voice] == 1) //decrease wavelength
                    sweep_amount *= -1;
                if(wavelength_count_reset[voice] + sweep_amount < 0x7ff && wavelength_count_reset[voice] + sweep_amount > 0x08) {
                    wavelength_count_reset[voice] += sweep_amount;
                    if(sweep_count[voice] == 0) sweep_count[voice] = sweep_rate[voice] + 1;
                }
                else {
                    length[voice] = 0;
                    //enabled[voice] = 0;
                }
            }
        }   
    }

}

// Assembly:
movq %rdi, -0x8(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x18(%rsp)
movb $0x0, -0x9(%rsp)
movzbl -0x9(%rsp), %eax
cmpl $0x4, %eax
jge 0x233a7
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
testb $0x1, 0xb4(%rax,%rcx)
je 0x23231
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
cmpl $0x0, 0x174(%rax,%rcx,4)
jle 0x23231
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
testb $0x1, 0xe9(%rax,%rcx)
jne 0x23231
movzbl -0x9(%rsp), %eax
cmpl $0x2, %eax
jne 0x23216
movq -0x18(%rsp), %rax
testb $0x1, 0x11c(%rax)
jne 0x23231
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x174(%rax,%rcx,4), %edx
addl $-0x1, %edx
movl %edx, 0x174(%rax,%rcx,4)
movzbl -0x9(%rsp), %eax
cmpl $0x2, %eax
jge 0x23396
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
testb $0x1, 0xb4(%rax,%rcx)
je 0x23396
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
cmpl $0x0, 0x174(%rax,%rcx,4)
jle 0x23396
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
testb $0x1, 0x11d(%rax,%rcx)
je 0x23396
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x160(%rax,%rcx,4), %edx
addl $-0x1, %edx
movl %edx, 0x160(%rax,%rcx,4)
movzbl -0x9(%rsp), %ecx
cmpl $0x0, 0x160(%rax,%rcx,4)
jne 0x23394
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x188(%rax,%rcx,4), %ecx
movl %ecx, -0x10(%rsp)
movzbl -0x9(%rsp), %ecx
movl 0x124(%rax,%rcx,4), %ecx
movl -0x10(%rsp), %edx
sarl %cl, %edx
movl %edx, %ecx
movl %ecx, -0x10(%rsp)
movzbl -0x9(%rsp), %ecx
cmpl $0x1, 0x138(%rax,%rcx,4)
jne 0x232fa
imull $-0x1, -0x10(%rsp), %eax
movl %eax, -0x10(%rsp)
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x188(%rax,%rcx,4), %eax
addl -0x10(%rsp), %eax
cmpl $0x7ff, %eax            # imm = 0x7FF
jge 0x2337d
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x188(%rax,%rcx,4), %eax
addl -0x10(%rsp), %eax
cmpl $0x8, %eax
jle 0x2337d
movq -0x18(%rsp), %rax
movl -0x10(%rsp), %edx
movzbl -0x9(%rsp), %ecx
addl 0x188(%rax,%rcx,4), %edx
movl %edx, 0x188(%rax,%rcx,4)
movzbl -0x9(%rsp), %ecx
cmpl $0x0, 0x160(%rax,%rcx,4)
jne 0x2337b
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl 0x14c(%rax,%rcx,4), %edx
addl $0x1, %edx
movzbl -0x9(%rsp), %ecx
movl %edx, 0x160(%rax,%rcx,4)
jmp 0x23392
movq -0x18(%rsp), %rax
movzbl -0x9(%rsp), %ecx
movl $0x0, 0x174(%rax,%rcx,4)
jmp 0x23394
jmp 0x23396
jmp 0x23398
movb -0x9(%rsp), %al
addb $0x1, %al
movb %al, -0x9(%rsp)
jmp 0x231b4
retq
nopl (%rax,%rax)