// File: /workspace/github_c_makefile_star2_O1/baines[P]MiniGBS/audio.c
// Function: audio_write
void audio_write(uint16_t addr, uint8_t val){

	if(!cfg.subdued && mem[addr] != val){
		ui_regs_set(addr, audio_rate / 8);
	}

	int i = (addr - 0xFF10)/5;

	if(cfg.debug_mode){
		if(addr <= 0xFF26){
			int j = (addr - 0xFF10)%5;
			debug_msg("Audio write: %4x / NR%1d%1d <- %2x", addr, i+1, j, val);
		} else {
			debug_msg("Audio write: %4x <- %2x", addr, val);
		}
	}

	switch(addr){

		case 0xFF12:
		case 0xFF17:
		case 0xFF21: {
			chans[i].volume_init = val >> 4;
			chans[i].powered = val >> 3;

			// "zombie mode" stuff, needed for Prehistorik Man and probably others
			if(chans[i].powered && chans[i].enabled){

				if((chans[i].env.step == 0 && chans[i].env.inc != 0)){
					if(val & 0x08){
						debug_msg("(zombie vol++)");
						chans[i].volume++;
					} else {
						debug_msg("(zombie vol+=2)");
						chans[i].volume+=2;
					}
				} else if(chans[i].env.step != (val & 0x07)) {
					debug_msg("(zombie swap)");
					chans[i].volume = 16 - chans[i].volume;
				}

				chans[i].volume &= 0x0F;
				chans[i].env.step = val & 0x07;
			}
		} break;

		case 0xFF1C:
			chans[i].volume = chans[i].volume_init = (val >> 5) & 0x03;
			break;

		case 0xFF11:
		case 0xFF16:
		case 0xFF20:
			chans[i].len.load = val & 0x3f;
			chans[i].duty = duty_lookup[val >> 6];
			chan_update_len(i);
			break;

		case 0xFF1B:
			chans[i].len.load = val;
			chan_update_len(i);
			break;

		case 0xFF13:
		case 0xFF18:
		case 0xFF1D:
			chans[i].freq &= 0xFF00;
			chans[i].freq |= val;
			break;

		case 0xFF1A:
			chans[i].powered = val & 0x80;
			chan_enable(i, val & 0x80);
			break;

		case 0xFF14:
		case 0xFF19:
		case 0xFF1E:
			chans[i].freq &= 0x00FF;
			chans[i].freq |= ((val & 0x07) << 8);
		case 0xFF23:
			chans[i].len.enabled = val & 0x40;
			if(val & 0x80){
				chan_trigger(i);
			}
			break;

		case 0xFF22:
			chans[3].freq = val >> 4;
			chans[3].lfsr_wide = !(val & 0x08);
			chans[3].lfsr_div = val & 0x07;
			break;

		case 0xFF24:
			vol_l = ((val >> 4) & 0x07) / 7.0f;
			vol_r = (val & 0x07) / 7.0f;
			break;

		case 0xFF25: {
			for(int i = 0; i < 4; ++i){
				chans[i].on_left  = (val >> (4 + i)) & 1;
				chans[i].on_right = (val >> i) & 1;
			}
		} break;
	}

	mem[addr] = val;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebx
leaq 0x7b61(%rip), %r12      # 0x11448
cmpb $0x0, 0x6(%r12)
movzwl %di, %r14d
jne 0x991f
leaq 0x7b46(%rip), %rax      # 0x11440
movq (%rax), %rax
cmpb %bl, (%rax,%r14)
je 0x991f
movss 0x7eb5(%rip), %xmm0     # 0x117c0
mulss 0x3981(%rip), %xmm0     # 0xd294
cvttss2si %xmm0, %esi
movl %r14d, %edi
callq 0xa110
leal -0xff10(%r14), %eax
cltq
imulq $0x66666667, %rax, %r15 # imm = 0x66666667
movq %r15, %rax
shrq $0x3f, %rax
sarq $0x21, %r15
addl %eax, %r15d
cmpl $0x0, (%r12)
je 0x998c
cmpl $0xff26, %r14d          # imm = 0xFF26
ja 0x9978
leal (%r15,%r15,4), %eax
negl %eax
leal (%r14,%rax), %ecx
addl $0xffff00f0, %ecx       # imm = 0xFFFF00F0
leal 0x1(%r15), %edx
movzbl %bl, %r8d
leaq 0x3a3b(%rip), %rdi      # 0xd3a7
movl %r14d, %esi
xorl %eax, %eax
callq 0x83f1
jmp 0x998c
movzbl %bl, %edx
leaq 0x3a48(%rip), %rdi      # 0xd3ca
movl %r14d, %esi
xorl %eax, %eax
callq 0x83f1
leal -0xff11(%r14), %eax
cmpl $0x14, %eax
ja 0x9caa
leaq 0x38fd(%rip), %rcx      # 0xd2a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl %bl, %eax
movl %eax, %ecx
andl $0x3f, %ecx
movslq %r15d, %rdx
imulq $0x70, %rdx, %rdx
shrl $0x6, %eax
leal -0xff1a(%r14), %esi
cmpl $0x5, %esi
movl $0x100, %esi            # imm = 0x100
movl $0x40, %edi
cmovbl %esi, %edi
leaq 0x7bd4(%rip), %rsi      # 0x115b0
movl %ecx, 0x20(%rdx,%rsi)
subl %ecx, %edi
leaq 0x3977(%rip), %rcx      # 0xd360
xorps %xmm0, %xmm0
cvtsi2ss %edi, %xmm0
movl (%rcx,%rax,4), %eax
movl %eax, 0x5c(%rdx,%rsi)
movss 0x3891(%rip), %xmm1     # 0xd290
divss %xmm0, %xmm1
divss 0x3851(%rip), %xmm1     # 0xd25c
movss %xmm1, 0x2c(%rdx,%rsi)
movl $0x0, 0x28(%rdx,%rsi)
jmp 0x9caa
movzbl %bl, %ebp
movl %ebp, %ecx
shrl $0x4, %ecx
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7b7c(%rip), %r15      # 0x115b0
movl %ecx, 0x8(%rax,%r15)
cmpb $0x8, %bl
setae 0x1(%rax,%r15)
jb 0x9caa
addq %rax, %r15
cmpb $0x1, (%r15)
jne 0x9caa
movl 0x30(%r15), %eax
testl %eax, %eax
je 0x9c5e
movl %ebp, %ecx
andl $0x7, %ecx
cmpl %ecx, %eax
je 0x9c9e
leaq 0x398c(%rip), %rdi      # 0xd401
xorl %eax, %eax
callq 0x83f1
movl $0x10, %eax
subl 0x4(%r15), %eax
movl %eax, 0x4(%r15)
jmp 0x9c9e
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7b14(%rip), %rcx      # 0x115b0
movl %ebx, %edx
andb $0x7, %dl
movb %dl, 0xd(%rax,%rcx)
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7afd(%rip), %rcx      # 0x115b0
movl %ebx, %edx
shrb $0x6, %dl
andb $0x1, %dl
movb %dl, 0x24(%rax,%rcx)
testb %bl, %bl
jns 0x9caa
movl %r15d, %edi
callq 0x96f6
jmp 0x9caa
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7ace(%rip), %rcx      # 0x115b0
movb %bl, 0xc(%rax,%rcx)
jmp 0x9caa
movl %ebx, %eax
shrb $0x5, %al
andb $0x3, %al
movzbl %al, %eax
movslq %r15d, %rcx
imulq $0x70, %rcx, %rcx
leaq 0x7aad(%rip), %rdx      # 0x115b0
movl %eax, 0x8(%rcx,%rdx)
movl %eax, 0x4(%rcx,%rdx)
jmp 0x9caa
movzbl %bl, %eax
movl %eax, %ecx
shrl $0x4, %ecx
andl $0x7, %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movss 0x376e(%rip), %xmm1     # 0xd298
andl $0x7, %eax
cvtsi2ss %eax, %xmm2
divss %xmm1, %xmm0
movss %xmm0, 0x7c3b(%rip)     # 0x11778
divss %xmm1, %xmm2
movss %xmm2, 0x7c3f(%rip)     # 0x11788
jmp 0x9caa
movzbl %bl, %eax
movl %eax, %ecx
shrl $0x4, %ecx
movw %cx, 0x7baf(%rip)       # 0x1170c
testb $0x8, %bl
sete 0x7bff(%rip)            # 0x11766
andl $0x7, %eax
movl %eax, 0x7bf8(%rip)      # 0x11768
jmp 0x9caa
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7a2d(%rip), %rcx      # 0x115b0
movl %ebx, %edx
shrb $0x7, %dl
movb %dl, 0x1(%rax,%rcx)
movb %dl, (%rax,%rcx)
leaq 0x78aa(%rip), %rax      # 0x11440
movq (%rax), %rax
movb 0xff26(%rax), %cl
andb $-0x80, %cl
movb 0x7b58(%rip), %dl       # 0x11700
shlb $0x3, %dl
orb %cl, %dl
movb 0x7add(%rip), %cl       # 0x11690
shlb $0x2, %cl
orb %dl, %cl
movb 0x7a62(%rip), %dl       # 0x11620
addb %dl, %dl
orb %cl, %dl
orb 0x79e8(%rip), %dl       # 0x115b0
movb %dl, 0xff26(%rax)
jmp 0x9caa
movzbl %bl, %eax
leaq 0x79d6(%rip), %rdx      # 0x115b3
xorl %ecx, %ecx
movl %eax, %esi
shrl %cl, %esi
andl $0x10, %esi
shrl $0x4, %esi
movb %sil, -0x1(%rdx)
btl %ecx, %eax
setb (%rdx)
incq %rcx
addq $0x70, %rdx
cmpq $0x4, %rcx
jne 0x9bdf
jmp 0x9caa
movzbl %bl, %eax
movslq %r15d, %rcx
imulq $0x70, %rcx, %rcx
leal -0xff1a(%r14), %edx
cmpl $0x5, %edx
movl $0x100, %edx            # imm = 0x100
movl $0x40, %esi
cmovbl %edx, %esi
subl %eax, %esi
xorps %xmm0, %xmm0
cvtsi2ss %esi, %xmm0
leaq 0x797a(%rip), %rdx      # 0x115b0
movl %eax, 0x20(%rcx,%rdx)
movss 0x364e(%rip), %xmm1     # 0xd290
divss %xmm0, %xmm1
divss 0x360e(%rip), %xmm1     # 0xd25c
movss %xmm1, 0x2c(%rcx,%rdx)
movl $0x0, 0x28(%rcx,%rdx)
jmp 0x9caa
movss 0x3c(%r15), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x9c72
jnp 0x9a61
testb $0x8, %bl
jne 0x9c8c
leaq 0x3773(%rip), %rdi      # 0xd3f1
xorl %eax, %eax
callq 0x83f1
addl $0x2, 0x4(%r15)
jmp 0x9c9e
leaq 0x374f(%rip), %rdi      # 0xd3e2
xorl %eax, %eax
callq 0x83f1
incl 0x4(%r15)
andl $0xf, 0x4(%r15)
andl $0x7, %ebp
movl %ebp, 0x30(%r15)
leaq 0x778f(%rip), %rax      # 0x11440
movq (%rax), %rax
movb %bl, (%rax,%r14)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)