// File: /workspace/github_c_makefile_star2_O2/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
movl %edi, %ebp
leaq 0x9144(%rip), %r15      # 0x12448
cmpb $0x0, 0x6(%r15)
movzwl %bp, %r14d
jne 0x933b
leaq 0x912a(%rip), %rax      # 0x12440
movq (%rax), %rax
cmpb %bl, (%rax,%r14)
je 0x933b
movss 0x9499(%rip), %xmm0     # 0x127c0
mulss 0x3f99(%rip), %xmm0     # 0xd2c8
cvttss2si %xmm0, %esi
movl %r14d, %edi
callq 0x9a6a
leal -0xff10(%r14), %eax
pushq $0x5
popq %rcx
cltd
idivl %ecx
movl %eax, %r12d
cmpl $0x0, (%r15)
movzbl %bl, %r15d
je 0x938d
cmpw $0xff26, %bp            # imm = 0xFF26
ja 0x9379
movl %edx, %ecx
leal 0x1(%r12), %edx
leaq 0x4075(%rip), %rdi      # 0xd3df
movl %r14d, %esi
movl %r15d, %r8d
xorl %eax, %eax
callq 0x817d
jmp 0x938d
leaq 0x4082(%rip), %rdi      # 0xd402
movl %r14d, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x817d
leal -0xff11(%r14), %eax
cmpl $0x14, %eax
ja 0x950c
leaq 0x3f5c(%rip), %rcx      # 0xd300
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl %r15d, %eax
andl $0x3f, %eax
movslq %r12d, %rcx
imulq $0x70, %rcx, %rcx
leaq 0x91ef(%rip), %rdx      # 0x125b0
movl %eax, 0x20(%rcx,%rdx)
shrl $0x6, %r15d
leaq 0x3f20(%rip), %rax      # 0xd2f0
movl (%rax,%r15,4), %eax
movl %eax, 0x5c(%rcx,%rdx)
jmp 0x9504
movslq %r12d, %rax
imulq $0x70, %rax, %rcx
leaq 0x91c5(%rip), %rdx      # 0x125b0
movl %ebx, %esi
andb $0x7, %sil
movb %sil, 0xd(%rcx,%rdx)
jmp 0x94cc
movl %r15d, %ecx
shrl $0x4, %ecx
movslq %r12d, %rax
imulq $0x70, %rax, %rax
leaq 0x91a1(%rip), %r12      # 0x125b0
movl %ecx, 0x8(%rax,%r12)
cmpb $0x8, %bl
setae 0x1(%rax,%r12)
jb 0x950c
addq %rax, %r12
cmpb $0x1, (%r12)
jne 0x950c
movl 0x30(%r12), %eax
testl %eax, %eax
je 0x95b1
movl %r15d, %ecx
andl $0x7, %ecx
cmpl %ecx, %eax
jne 0x9599
movl 0x4(%r12), %eax
jmp 0x95f8
movslq %r12d, %rax
imulq $0x70, %rax, %rax
leaq 0x914c(%rip), %rcx      # 0x125b0
movb %bl, 0xc(%rax,%rcx)
jmp 0x950c
movl %r15d, %eax
shrl $0x4, %eax
movw %ax, 0x9292(%rip)       # 0x1270c
testb $0x8, %bl
sete 0x92e2(%rip)            # 0x12766
andl $0x7, %r15d
movl %r15d, 0x92d9(%rip)     # 0x12768
jmp 0x950c
movl %r15d, %eax
shrl $0x4, %eax
andl $0x7, %eax
cvtsi2ss %eax, %xmm0
movss 0x3e26(%rip), %xmm1     # 0xd2cc
andl $0x7, %r15d
cvtsi2ss %r15d, %xmm2
divss %xmm1, %xmm0
movss %xmm0, 0x92bd(%rip)     # 0x12778
divss %xmm1, %xmm2
movss %xmm2, 0x92c1(%rip)     # 0x12788
jmp 0x950c
movslq %r12d, %rax
imulq $0x70, %rax, %rax
leaq 0x90d9(%rip), %rcx      # 0x125b0
movl %ebx, %edx
shrb $0x6, %dl
andb $0x1, %dl
movb %dl, 0x24(%rax,%rcx)
testb %bl, %bl
jns 0x950c
movl %r12d, %edi
callq 0x915b
jmp 0x950c
movslq %r12d, %rax
imulq $0x70, %rax, %rax
leaq 0x90b1(%rip), %rcx      # 0x125b0
movl %r15d, 0x20(%rax,%rcx)
movl %r12d, %edi
callq 0x92ad
leaq 0x8f2d(%rip), %rax      # 0x12440
movq (%rax), %rax
movb %bl, (%rax,%r14)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movslq %r12d, %rax
imulq $0x70, %rax, %rax
leaq 0x907f(%rip), %rcx      # 0x125b0
movl %ebx, %edx
shrb $0x7, %dl
movb %dl, 0x1(%rax,%rcx)
movzbl %dl, %esi
movl %r12d, %edi
callq 0x82fe
jmp 0x950c
leaq 0x9065(%rip), %rax      # 0x125b3
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x950c
movl %r15d, %edx
shrl %cl, %edx
andl $0x10, %edx
shrl $0x4, %edx
movb %dl, -0x1(%rax)
btl %ecx, %r15d
setb (%rax)
incq %rcx
addq $0x70, %rax
jmp 0x9550
movl %ebx, %eax
shrb $0x5, %al
andb $0x3, %al
movzbl %al, %eax
movslq %r12d, %rcx
imulq $0x70, %rcx, %rcx
leaq 0x9024(%rip), %rdx      # 0x125b0
movl %eax, 0x8(%rcx,%rdx)
movl %eax, 0x4(%rcx,%rdx)
jmp 0x950c
leaq 0x3e99(%rip), %rdi      # 0xd439
xorl %eax, %eax
callq 0x817d
pushq $0x10
popq %rax
subl 0x4(%r12), %eax
jmp 0x95f8
movss 0x3c(%r12), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x95c6
jnp 0x943e
testb $0x8, %bl
jne 0x95e3
leaq 0x3e57(%rip), %rdi      # 0xd429
xorl %eax, %eax
callq 0x817d
movl 0x4(%r12), %eax
addl $0x2, %eax
jmp 0x95f8
leaq 0x3e30(%rip), %rdi      # 0xd41a
xorl %eax, %eax
callq 0x817d
movl 0x4(%r12), %eax
incl %eax
andl $0xf, %eax
movl %eax, 0x4(%r12)
andl $0x7, %r15d
movl %r15d, 0x30(%r12)
jmp 0x950c
nop