// File: /workspace/github_c_makefile_star2_O1/calmopyrin[P]tedplay/Sid.cpp
// Function: SIDsound::write(unsigned int, unsigned char)
void SIDsound::write(unsigned int adr, unsigned char value)
{
	lastByteWritten = value;

	SIDVoice &v = voice[adr/7];
	switch (adr) {
		case 0:
		case 7:
		case 14:
			v.freq = (unsigned short)((v.freq & 0xff00) | value);
			break;

		case 1:
		case 8:
		case 15:
			v.freq = (unsigned short)((v.freq & 0xff) | (value << 8));
			break;

		case 2:
		case 9:
		case 16:
			v.pw = (v.pw & 0xf00000) | (value << 12);
			break;

		case 3:
		case 10:
		case 17:
			v.pw = (v.pw & 0x0ff000) | ((value & 0xf) << 20);
			break;

		case 4:
		case 11:
		case 18:
			if ((value ^ v.gate) & 1) {
				if (value & 1) {
					// gate on
					v.egState = EG_ATTACK;
					v.envCounterCompare = v.envAttackAdd;
				} else {
					// gate off
					v.egState = EG_RELEASE;
					v.envCounterCompare = v.envReleaseSub;
				}
				v.gate = value & 1;
			}
			v.sync = value & 2;
			v.ring = value & 4;
			if ((value & 8) && !v.test) {
				v.accu = 0; //(model_ >= SID8580) ? 0 : 0;
				unsigned int bit19 = (v.shiftReg >> 19) & 1;
				v.shiftReg = (v.shiftReg & 0x7ffffd) | ((bit19^1) << 1);
				v.test = 0xFFF;
			} else if (v.test && !(value & 8)) {
				unsigned int bit0 = ((v.shiftReg >> 22) ^ (v.shiftReg >> 17)) & 0x1;
				v.shiftReg <<= 1;
				v.shiftReg &= 0x7fffff;
				v.shiftReg |= bit0;
				v.test = 0x000;
			}
			v.wave = (value >> 4) & 0x0F;
			if (v.wave > 8) {
				v.shiftReg &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2);
				v.waveNoiseOut = 0;
			}
			break;

		case 5:
		case 12:
		case 19:
			v.envAttackAdd = value >> 4;
			v.envDecaySub = value & 0x0F;
			if (v.egState == EG_ATTACK)
				v.envCounterCompare = v.envAttackAdd;
			else if (v.egState == EG_DECAY)
				v.envCounterCompare = v.envDecaySub;
			break;

		case 6:
		case 13:
		case 20:
			v.envSustainLevel = (value >> 4) * 0x11;
			v.envReleaseSub = value & 0x0F;
			if (v.egState == EG_RELEASE)
				v.envCounterCompare = v.envReleaseSub;
			break;

		case 21:
			if ((value ^ filterCutoff) & 7) {
				filterCutoff = (value & 7) | (filterCutoff & 0x7F8);
				setFilterCutoff();
			}
			break;

		case 22:
			filterCutoff = (value << 3) | (filterCutoff & 7);
			setFilterCutoff();
			break;

		case 23:
			voice[0].filter = value & 1;
			voice[1].filter = value & 2;
			voice[2].filter = value & 4;
			filterResonance = (unsigned char)(value >> 4);
			setResonance();
			break;

		case 24:
			volume = value & 0x0F;
			voice[2].muted = value & 0x80;
			filterType = (unsigned char)((value >> 4) & 7);
			break;

		case 30: // Digiblaster DAC
			if (enableDigiBlaster && model_ == SID8580)
			{
				dcDigiBlaster = (value ^ 0x00) << DIGIBLASTER_MULT;
			}
			break;

		case 31: // Digiblaster ADC
			break;
	}
}

// Assembly:
movb %dl, 0x41b4(%rdi)
cmpl $0x1e, %esi
ja 0x8e1a
movl %esi, %ecx
imulq $0x24924925, %rcx, %rax # imm = 0x24924925
shrq $0x20, %rax
subl %eax, %esi
shrl %esi
addl %eax, %esi
shrl $0x2, %esi
imulq $0x78, %rsi, %rax
addq %rdi, %rax
addq $0x8, %rax
leaq 0x7355(%rip), %rsi      # 0x10138
movslq (%rsi,%rcx,4), %rcx
addq %rsi, %rcx
jmpq *%rcx
movzbl 0x31(%rax), %ecx
shll $0x8, %ecx
movzbl %dl, %edx
jmp 0x8e65
movzbl %dl, %edx
movl %edx, %ecx
shrl $0x4, %ecx
movl %ecx, 0x38(%rax)
andl $0xf, %edx
movl %edx, 0x3c(%rax)
movl 0x8(%rax), %esi
cmpl $0x2, %esi
je 0x8f53
cmpl $0x1, %esi
je 0x8e89
retq
movzbl %dl, %ecx
movl 0x58(%rax), %esi
xorl %ecx, %esi
testb $0x1, %sil
je 0x8ffb
movl %ecx, %esi
andl $0x1, %esi
jne 0x8fe8
movl $0x3, 0x8(%rax)
leaq 0x44(%rax), %rdi
jmp 0x8ff3
movl $0xff000, %ecx          # imm = 0xFF000
andl 0x34(%rax), %ecx
andb $0xf, %dl
movzbl %dl, %edx
shll $0x14, %edx
jmp 0x8e9b
movzbl 0x30(%rax), %ecx
movzbl %dl, %edx
shll $0x8, %edx
orl %ecx, %edx
movl %edx, 0x30(%rax)
retq
movzbl %dl, %ecx
movl %ecx, %edx
shrl $0x4, %edx
movl %ecx, %esi
andl $-0x10, %esi
orl %edx, %esi
movl %esi, 0x40(%rax)
andl $0xf, %ecx
movl %ecx, 0x44(%rax)
cmpl $0x3, 0x8(%rax)
jne 0x8e1a
movl %ecx, 0x54(%rax)
retq
movl $0xf00000, %ecx         # imm = 0xF00000
andl 0x34(%rax), %ecx
movzbl %dl, %edx
shll $0xc, %edx
orl %ecx, %edx
movl %edx, 0x34(%rax)
retq
movzbl %dl, %ecx
movl 0x198(%rdi), %eax
movl %eax, %edx
xorl %ecx, %edx
testb $0x7, %dl
je 0x8e1a
andl $0x7, %ecx
andl $0x7f8, %eax            # imm = 0x7F8
orl %ecx, %eax
jmp 0x8f66
cmpb $0x1, 0x41b5(%rdi)
jne 0x8e1a
cmpl $0x1, 0x41bc(%rdi)
jne 0x8e1a
movzbl %dl, %eax
shll $0xe, %eax
movl %eax, 0x18c(%rdi)
retq
movzbl %dl, %eax
movl %eax, %ecx
andl $0x1, %ecx
movl %ecx, 0x6c(%rdi)
movl %eax, %ecx
andl $0x2, %ecx
movl %ecx, 0xe4(%rdi)
andl $0x4, %eax
movl %eax, 0x15c(%rdi)
shrb $0x4, %dl
movzbl %dl, %eax
cvtsi2sd %eax, %xmm0
mulsd 0x71da(%rip), %xmm0     # 0x100f8
divsd 0x71da(%rip), %xmm0     # 0x10100
addsd 0x71da(%rip), %xmm0     # 0x10108
movsd 0x71da(%rip), %xmm1     # 0x10110
divsd %xmm0, %xmm1
addsd 0x70f6(%rip), %xmm1     # 0x10038
movb %dl, 0x19c(%rdi)
cvttsd2si %xmm1, %eax
movl %eax, 0x41a0(%rdi)
retq
movl %edx, 0x54(%rax)
retq
movzbl %dl, %eax
movl 0x198(%rdi), %ecx
andl $0x7, %ecx
leal (%rcx,%rax,8), %eax
movl %eax, 0x198(%rdi)
movsd 0x7174(%rip), %xmm0     # 0x100e8
movsd 0x1a0(%rdi,%rax,8), %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %ecx
movl %ecx, 0x41a4(%rdi)
movl 0x41b8(%rdi), %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
mulsd 0x7097(%rip), %xmm1     # 0x10038
movsd 0x7147(%rip), %xmm2     # 0x100f0
minsd %xmm1, %xmm2
mulsd %xmm0, %xmm2
cvttsd2si %xmm2, %eax
cmpl %eax, %ecx
jle 0x8e1a
movl %eax, 0x41a4(%rdi)
retq
movzbl %dl, %eax
movl %eax, %ecx
andl $0xf, %ecx
movl %ecx, 0x170(%rdi)
andl $-0x80, %eax
movl %eax, 0x160(%rdi)
shrb $0x4, %dl
andb $0x7, %dl
movb %dl, 0x194(%rdi)
retq
movl $0x1, 0x8(%rax)
leaq 0x38(%rax), %rdi
movl (%rdi), %edi
movl %edi, 0x54(%rax)
movl %esi, 0x58(%rax)
movl %ecx, %esi
andl $0x2, %esi
movl %esi, 0x70(%rax)
movl %ecx, %esi
andl $0x4, %esi
movl %esi, 0x5c(%rax)
testb $0x8, %dl
je 0x9016
cmpl $0x0, 0x60(%rax)
je 0x904d
testb $0x8, %dl
jne 0x9074
cmpl $0x0, 0x60(%rax)
je 0x9074
movl 0x28(%rax), %esi
movl %esi, %edi
shrl $0x16, %edi
movl %esi, %r8d
shrl $0x11, %r8d
xorl %edi, %r8d
andl $0x1, %r8d
andl $0x3fffff, %esi         # imm = 0x3FFFFF
leal (%r8,%rsi,2), %esi
movl %esi, 0x28(%rax)
movl $0x0, 0x60(%rax)
jmp 0x9074
movl $0x0, 0x20(%rax)
movl 0x28(%rax), %esi
movl %esi, %edi
andl $0x7ffffd, %edi         # imm = 0x7FFFFD
shrl $0x12, %esi
andl $0x2, %esi
orl %edi, %esi
xorl $0x2, %esi
movl %esi, 0x28(%rax)
movl $0xfff, 0x60(%rax)      # imm = 0xFFF
shrl $0x4, %ecx
movl %ecx, 0x4(%rax)
cmpb $-0x70, %dl
jb 0x8e1a
andl $0x2ed76b, 0x28(%rax)   # imm = 0x2ED76B
movl $0x0, 0x2c(%rax)
retq