// File: /workspace/github_c_makefile_star2_O3/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 0x7c1c(%rip), %r12      # 0x11448
cmpb $0x0, 0x6(%r12)
movzwl %di, %r14d
jne 0x9864
leaq 0x7c01(%rip), %rax      # 0x11440
movq (%rax), %rax
cmpb %bl, (%rax,%r14)
je 0x9864
movss 0x7f70(%rip), %xmm0     # 0x117c0
mulss 0x3a70(%rip), %xmm0     # 0xd2c8
cvttss2si %xmm0, %esi
movl %r14d, %edi
callq 0xa048
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 0x98d1
cmpl $0xff26, %r14d          # imm = 0xFF26
ja 0x98bd
leal (%r15,%r15,4), %eax
negl %eax
leal (%r14,%rax), %ecx
addl $0xffff00f0, %ecx       # imm = 0xFFFF00F0
leal 0x1(%r15), %edx
movzbl %bl, %r8d
leaq 0x3b5e(%rip), %rdi      # 0xd40f
movl %r14d, %esi
xorl %eax, %eax
callq 0x8340
jmp 0x98d1
movzbl %bl, %edx
leaq 0x3b6b(%rip), %rdi      # 0xd432
movl %r14d, %esi
xorl %eax, %eax
callq 0x8340
leal -0xff11(%r14), %eax
cmpl $0x14, %eax
ja 0x9bec
leaq 0x3a48(%rip), %rcx      # 0xd330
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 0x7c8f(%rip), %rsi      # 0x115b0
movl %ecx, 0x20(%rdx,%rsi)
subl %ecx, %edi
leaq 0x39f2(%rip), %rcx      # 0xd320
xorps %xmm0, %xmm0
cvtsi2ss %edi, %xmm0
movl (%rcx,%rax,4), %eax
movl %eax, 0x5c(%rdx,%rsi)
movss 0x3980(%rip), %xmm1     # 0xd2c4
divss %xmm0, %xmm1
divss 0x393c(%rip), %xmm1     # 0xd28c
movss %xmm1, 0x2c(%rdx,%rsi)
movl $0x0, 0x28(%rdx,%rsi)
jmp 0x9bec
movslq %r15d, %rax
imulq $0x70, %rax, %rcx
leaq 0x7c3f(%rip), %rdx      # 0x115b0
movl %ebx, %esi
andb $0x7, %sil
movb %sil, 0xd(%rcx,%rdx)
jmp 0x9a59
movzbl %bl, %ebp
movl %ebp, %ecx
shrl $0x4, %ecx
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7c19(%rip), %r15      # 0x115b0
movl %ecx, 0x8(%rax,%r15)
cmpb $0x8, %bl
setae 0x1(%rax,%r15)
jb 0x9bec
addq %rax, %r15
cmpb $0x1, (%r15)
jne 0x9bec
movl 0x30(%r15), %eax
testl %eax, %eax
je 0x9b9a
movl %ebp, %ecx
andl $0x7, %ecx
cmpl %ecx, %eax
jne 0x9b81
movl 0x4(%r15), %eax
jmp 0x9bde
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7bc8(%rip), %rcx      # 0x115b0
movb %bl, 0xc(%rax,%rcx)
jmp 0x9bec
movzbl %bl, %eax
movl %eax, %ecx
shrl $0x4, %ecx
movw %cx, 0x7d0c(%rip)       # 0x1170c
testb $0x8, %bl
sete 0x7d5c(%rip)            # 0x11766
andl $0x7, %eax
movl %eax, 0x7d55(%rip)      # 0x11768
jmp 0x9bec
movzbl %bl, %eax
movl %eax, %ecx
shrl $0x4, %ecx
andl $0x7, %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movss 0x389a(%rip), %xmm1     # 0xd2cc
andl $0x7, %eax
cvtsi2ss %eax, %xmm2
divss %xmm1, %xmm0
movss %xmm0, 0x7d33(%rip)     # 0x11778
divss %xmm1, %xmm2
movss %xmm2, 0x7d37(%rip)     # 0x11788
jmp 0x9bec
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7b4c(%rip), %rcx      # 0x115b0
movl %ebx, %edx
shrb $0x6, %dl
andb $0x1, %dl
movb %dl, 0x24(%rax,%rcx)
testb %bl, %bl
jns 0x9bec
movl %r15d, %edi
callq 0x9645
jmp 0x9bec
movzbl %bl, %eax
movslq %r15d, %rcx
imulq $0x70, %rcx, %rcx
movl $0x100, %edx            # imm = 0x100
subl %eax, %edx
xorps %xmm0, %xmm0
cvtsi2ss %edx, %xmm0
leaq 0x7b0c(%rip), %rdx      # 0x115b0
movl %eax, 0x20(%rcx,%rdx)
movss 0x3814(%rip), %xmm1     # 0xd2c4
divss %xmm0, %xmm1
divss 0x37d0(%rip), %xmm1     # 0xd28c
movss %xmm1, 0x2c(%rcx,%rdx)
movl $0x0, 0x28(%rcx,%rdx)
jmp 0x9bec
movslq %r15d, %rax
imulq $0x70, %rax, %rax
leaq 0x7ad3(%rip), %rcx      # 0x115b0
movl %ebx, %edx
shrb $0x7, %dl
movb %dl, 0x1(%rax,%rcx)
movb %dl, (%rax,%rcx)
leaq 0x7950(%rip), %rax      # 0x11440
movq (%rax), %rax
movb 0xff26(%rax), %cl
andb $-0x80, %cl
movb 0x7bfe(%rip), %dl       # 0x11700
shlb $0x3, %dl
orb %cl, %dl
movb 0x7b83(%rip), %cl       # 0x11690
shlb $0x2, %cl
orb %dl, %cl
movb 0x7b08(%rip), %dl       # 0x11620
addb %dl, %dl
orb %cl, %dl
orb 0x7a8e(%rip), %dl       # 0x115b0
movb %dl, 0xff26(%rax)
jmp 0x9bec
movzbl %bl, %eax
leaq 0x7a7c(%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 0x9b39
jmp 0x9bec
movl %ebx, %eax
shrb $0x5, %al
andb $0x3, %al
movzbl %al, %eax
movslq %r15d, %rcx
imulq $0x70, %rcx, %rcx
leaq 0x7a39(%rip), %rdx      # 0x115b0
movl %eax, 0x8(%rcx,%rdx)
movl %eax, 0x4(%rcx,%rdx)
jmp 0x9bec
leaq 0x38e1(%rip), %rdi      # 0xd469
xorl %eax, %eax
callq 0x8340
movl $0x10, %eax
subl 0x4(%r15), %eax
jmp 0x9bde
movss 0x3c(%r15), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x9bae
jnp 0x99c4
testb $0x8, %bl
jne 0x9bca
leaq 0x389f(%rip), %rdi      # 0xd459
xorl %eax, %eax
callq 0x8340
movl 0x4(%r15), %eax
addl $0x2, %eax
jmp 0x9bde
leaq 0x3879(%rip), %rdi      # 0xd44a
xorl %eax, %eax
callq 0x8340
movl 0x4(%r15), %eax
incl %eax
andl $0xf, %eax
movl %eax, 0x4(%r15)
andl $0x7, %ebp
movl %ebp, 0x30(%r15)
leaq 0x784d(%rip), %rax      # 0x11440
movq (%rax), %rax
movb %bl, (%rax,%r14)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop