// File: /workspace/github_c_makefile_star2_O2/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:
movl %edx, %ecx
movb %cl, 0x41b4(%rdi)
pushq $0x7
popq %r8
movl %esi, %eax
xorl %edx, %edx
divl %r8d
cmpl $0x1e, %esi
ja 0x8ac8
imulq $0x78, %rax, %rax
addq %rdi, %rax
addq $0x8, %rax
movl %esi, %edx
leaq 0x66de(%rip), %rsi      # 0xf168
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movzbl 0x31(%rax), %edx
shll $0x8, %edx
movzbl %cl, %ecx
jmp 0x8b6d
movzbl %cl, %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 0x8c71
cmpl $0x1, %esi
je 0x8b91
retq
movzbl %cl, %edx
movl 0x58(%rax), %esi
xorl %edx, %esi
testb $0x1, %sil
je 0x8b03
leaq 0x38(%rax), %rsi
leaq 0x44(%rax), %rdi
xorl %r8d, %r8d
movl %edx, %r9d
andl $0x1, %r9d
sete %r8b
leal 0x1(%r8,%r8), %r8d
cmoveq %rdi, %rsi
movl (%rsi), %esi
movl %r8d, 0x8(%rax)
movl %esi, 0x54(%rax)
movl %r9d, 0x58(%rax)
movl %edx, %esi
andl $0x2, %esi
movl %esi, 0x70(%rax)
movl %edx, %esi
andl $0x4, %esi
movl %esi, 0x5c(%rax)
movl 0x60(%rax), %esi
testb $0x8, %cl
je 0x8ba9
testl %esi, %esi
jne 0x8bd6
andl $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
jmp 0x8bd6
movl $0xff000, %edx          # imm = 0xFF000
andl 0x34(%rax), %edx
andb $0xf, %cl
movzbl %cl, %ecx
shll $0x14, %ecx
jmp 0x8ba3
movzbl 0x30(%rax), %edx
movzbl %cl, %ecx
shll $0x8, %ecx
orl %edx, %ecx
movl %ecx, 0x30(%rax)
retq
movzbl %cl, %ecx
movl %ecx, %edx
shrl $0x4, %edx
imull $0x11, %edx, %edx
movl %edx, 0x40(%rax)
andl $0xf, %ecx
movl %ecx, 0x44(%rax)
cmpl $0x3, 0x8(%rax)
jne 0x8ac8
movl %ecx, 0x54(%rax)
retq
movl $0xf00000, %edx         # imm = 0xF00000
andl 0x34(%rax), %edx
movzbl %cl, %ecx
shll $0xc, %ecx
orl %edx, %ecx
movl %ecx, 0x34(%rax)
retq
jne 0x8bd6
testl %esi, %esi
je 0x8bd6
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)
andl $0x0, 0x60(%rax)
shrl $0x4, %edx
movl %edx, 0x4(%rax)
cmpb $-0x70, %cl
jb 0x8ac8
andl $0x2ed76b, 0x28(%rax)   # imm = 0x2ED76B
andl $0x0, 0x2c(%rax)
retq
movzbl %cl, %eax
movl 0x198(%rdi), %ecx
movl %ecx, %edx
xorl %eax, %edx
testb $0x7, %dl
je 0x8ac8
andl $0x7, %eax
andl $0x7f8, %ecx            # imm = 0x7F8
orl %eax, %ecx
movl %ecx, 0x198(%rdi)
jmp 0x8eac
cmpb $0x1, 0x41b5(%rdi)
jne 0x8ac8
cmpl $0x1, 0x41bc(%rdi)
jne 0x8ac8
movzbl %cl, %eax
shll $0xe, %eax
movl %eax, 0x18c(%rdi)
retq
movzbl %cl, %eax
movl %eax, %edx
andl $0x1, %edx
movl %edx, 0x6c(%rdi)
movl %eax, %edx
andl $0x2, %edx
movl %edx, 0xe4(%rdi)
andl $0x4, %eax
movl %eax, 0x15c(%rdi)
shrb $0x4, %cl
movb %cl, 0x19c(%rdi)
jmp 0x8f04
movl %edx, 0x54(%rax)
retq
movzbl %cl, %eax
movl 0x198(%rdi), %ecx
andl $0x7, %ecx
leal (%rcx,%rax,8), %eax
movl %eax, 0x198(%rdi)
jmp 0x8eac
movzbl %cl, %eax
movl %eax, %edx
andl $0xf, %edx
movl %edx, 0x170(%rdi)
andl $-0x80, %eax
movl %eax, 0x160(%rdi)
shrb $0x4, %cl
andb $0x7, %cl
movb %cl, 0x194(%rdi)
retq
nop