// File: khedoros[P]khednes/apu.cpp
// Function: apu::apu(bool)
apu::apu(bool headless/* =false */) {
    //std::cout<<"apu constructor"<<std::endl;
    stat.val = 0;
    linear_cntr = 0;
    enable_linear_cntr = false;
    pin1_enabled = 0;
    pin2_enabled = 0;
    noise_flip_flop = false;
    framecounter_pos = 0;
    framecounter_reset = 89490;
    enable_irq = false;
    counter_mode = 0;

    dmc_pcm_data = 0;
    dmc_addr=0;
    dmc_addr_reset=0xc000;
    dmc_freq_cnt=0;
    dmc_freq=0;
    dmc_length=0;
    dmc_gen_irq=false;
    dmc_loop=false;

    buffer_read_pos = 0;
    buffer_write_pos = 0;

    for(int i=0; i<5; ++i) {
        enabled[i] = false;
        vol[i] = 0;
        decay_count[i] = 0;
        enable_decay[i] = false;
        loop_decay[i] = false;
        decay_vol_lvl[i] = 0;
        duty_cycle[i] = 0;
        sweep_enable[i] = false;
        sweep_shift[i] = 0;
        sweep_dir[i] = 0;
        sweep_rate[i] = 0;
        sweep_count[i] = 0;
        length[i] = 0;
        wavelength_count_reset[i] = 0;
        wave_pos[i] = 0;
    }

    id = 0;
    frame = 0;
    write_pos = 1;

    init(headless);
    generate_arrays();
    
    //Unpause the audio stream
    if(id > 0)
        SDL_PauseAudioDevice(id, false);
}

// Assembly:
subq $0x38, %rsp
movb %sil, %al
movq %rdi, 0x30(%rsp)
andb $0x1, %al
movb %al, 0x2f(%rsp)
movq 0x30(%rsp), %rdi
movq %rdi, 0x10(%rsp)
addq $0x38, %rdi
movq %rdi, (%rsp)
callq 0x112d0
movq 0x10(%rsp), %rdi
addq $0x50, %rdi
movq %rdi, 0x8(%rsp)
callq 0x24910
movq 0x10(%rsp), %rax
movb $0x0, 0xb0(%rax)
movl $0x0, 0x118(%rax)
movb $0x0, 0x11c(%rax)
movl $0x0, 0x1c4(%rax)
movl $0x0, 0x1c8(%rax)
movb $0x0, 0x1cc(%rax)
movl $0x0, 0x1d0(%rax)
movl $0x15d92, 0x1d4(%rax)   # imm = 0x15D92
movb $0x0, 0x1d8(%rax)
movl $0x0, 0x1dc(%rax)
movl $0x0, 0x220(%rax)
movl $0x0, 0x224(%rax)
movl $0xc000, 0x228(%rax)    # imm = 0xC000
movl $0x0, 0x22c(%rax)
movl $0x0, 0x230(%rax)
movl $0x0, 0x238(%rax)
movb $0x0, 0x234(%rax)
movb $0x0, 0x235(%rax)
movq $0x0, 0x10(%rax)
movq $0x0, 0x8(%rax)
movl $0x0, 0x28(%rsp)
cmpl $0x5, 0x28(%rsp)
jge 0x22f4f
movq 0x10(%rsp), %rax
movslq 0x28(%rsp), %rcx
movb $0x0, 0xb4(%rax,%rcx)
movslq 0x28(%rsp), %rcx
movl $0x0, 0xbc(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0xd0(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movb $0x0, 0xe4(%rax,%rcx)
movslq 0x28(%rsp), %rcx
movb $0x0, 0xe9(%rax,%rcx)
movslq 0x28(%rsp), %rcx
movl $0x0, 0xf0(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x104(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movb $0x0, 0x11d(%rax,%rcx)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x124(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x138(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x14c(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x160(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x174(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x188(%rax,%rcx,4)
movslq 0x28(%rsp), %rcx
movl $0x0, 0x1b0(%rax,%rcx,4)
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x22e4b
movq 0x10(%rsp), %rdi
movl $0x0, 0x68(%rdi)
movl $0x0, 0x244(%rdi)
movb $0x1, (%rdi)
movzbl 0x2f(%rsp), %esi
andl $0x1, %esi
callq 0x22340
jmp 0x22f77
movq 0x10(%rsp), %rdi
callq 0x22750
movq 0x10(%rsp), %rax
cmpl $0x0, 0x68(%rax)
jbe 0x22fc2
movq 0x10(%rsp), %rax
movl 0x68(%rax), %edi
xorl %esi, %esi
callq 0x44b0
jmp 0x22f9d
jmp 0x22fc2
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x20(%rsp)
movl %eax, 0x1c(%rsp)
callq 0x24920
movq (%rsp), %rdi
callq 0x112f0
jmp 0x22fc7
addq $0x38, %rsp
retq
movq 0x20(%rsp), %rdi
callq 0x4680
nopw %cs:(%rax,%rax)