// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmWriteBlockData(CapsFormatTrack*, unsigned int, CapsFormatBlock*)
UDWORD FmfmWriteBlockData(PCAPSFORMATTRACK pf, UDWORD state, PCAPSFORMATBLOCK pb)
{
	UWORD crc;

	// sector length
	int seclen=FmfmSectorLength(pb->sectorlen);

	// write sector ID
	// gap before first am
	state=FmfmWriteDataByte(pf, state, pb->gapavalue, pb->gapacnt);

	// 3 am a1/4489
	crc=~0;
	state=FmfmWriteMarkByte(pf, state, 0x4489, 3);
	crc=FmfmCrc(crc, 0xa1, 3);

	// fe
	state=FmfmWriteDataByte(pf, state, 0xfe, 1);
	crc=FmfmCrc(crc, 0xfe);

	// track#
	state=FmfmWriteDataByte(pf, state, pb->track, 1);
	crc=FmfmCrc(crc, pb->track);

	// side#
	state=FmfmWriteDataByte(pf, state, pb->side, 1);
	crc=FmfmCrc(crc, pb->side);

	// sector#
	state=FmfmWriteDataByte(pf, state, pb->sector, 1);
	crc=FmfmCrc(crc, pb->sector);

	// sector length
	state=FmfmWriteDataByte(pf, state, seclen, 1);
	crc=FmfmCrc(crc, seclen);

	// crc
	state=FmfmWriteDataByte(pf, state, crc>>8, 1);
	state=FmfmWriteDataByte(pf, state, crc, 1);

	// gap after first am
	state=FmfmWriteDataByte(pf, state, pb->gapbvalue, pb->gapbcnt);

	// write sector data
	// gap before second am
	state=FmfmWriteDataByte(pf, state, pb->gapcvalue, pb->gapccnt);

	// 3 am a1/4489
	crc=~0;
	state=FmfmWriteMarkByte(pf, state, 0x4489, 3);
	crc=FmfmCrc(crc, 0xa1, 3);

	// fb
	state=FmfmWriteDataByte(pf, state, 0xfb, 1);
	crc=FmfmCrc(crc, 0xfb);

	// data
	for (int i=0; i < pb->sectorlen; i++) {
		UDWORD data=pb->databuf ? pb->databuf[i] : pb->datavalue;
		state=FmfmWriteDataByte(pf, state, data, 1);
		crc=FmfmCrc(crc, data);
	}

	// crc
	state=FmfmWriteDataByte(pf, state, crc>>8, 1);
	state=FmfmWriteDataByte(pf, state, crc, 1);

	// gap after second am
	state=FmfmWriteDataByte(pf, state, pb->gapdvalue, pb->gapdcnt);

	return state;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl 0x30(%rax), %edi
callq 0xcb70
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x4(%rax), %edx
movq -0x18(%rbp), %rax
movl (%rax), %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw $0xffff, -0x1a(%rbp)    # imm = 0xFFFF
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl $0x4489, %edx           # imm = 0x4489
movl $0x3, %ecx
callq 0xd090
movl %eax, -0xc(%rbp)
movl $0xa1, %esi
movl $0x3, %edx
movzwl -0x1a(%rbp), %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl $0xfe, %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movl $0xfe, %esi
movl $0x1, %edx
movzwl -0x1a(%rbp), %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x24(%rax), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw -0x1a(%rbp), %ax
movq -0x18(%rbp), %rcx
movl 0x24(%rcx), %esi
movl $0x1, %edx
movzwl %ax, %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x28(%rax), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw -0x1a(%rbp), %ax
movq -0x18(%rbp), %rcx
movl 0x28(%rcx), %esi
movl $0x1, %edx
movzwl %ax, %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x2c(%rax), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw -0x1a(%rbp), %ax
movq -0x18(%rbp), %rcx
movl 0x2c(%rcx), %esi
movl $0x1, %edx
movzwl %ax, %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x20(%rbp), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw -0x1a(%rbp), %ax
movl -0x20(%rbp), %esi
movl $0x1, %edx
movzwl %ax, %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movzwl -0x1a(%rbp), %edx
sarl $0x8, %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movzwl -0x1a(%rbp), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0xc(%rax), %edx
movq -0x18(%rbp), %rax
movl 0x8(%rax), %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x14(%rax), %edx
movq -0x18(%rbp), %rax
movl 0x10(%rax), %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw $0xffff, -0x1a(%rbp)    # imm = 0xFFFF
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl $0x4489, %edx           # imm = 0x4489
movl $0x3, %ecx
callq 0xd090
movl %eax, -0xc(%rbp)
movl $0xa1, %esi
movl $0x3, %edx
movzwl -0x1a(%rbp), %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl $0xfb, %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movl $0xfb, %esi
movl $0x1, %edx
movzwl -0x1a(%rbp), %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl 0x30(%rcx), %eax
jge 0xd028
movq -0x18(%rbp), %rax
cmpq $0x0, 0x34(%rax)
je 0xcfde
movq -0x18(%rbp), %rax
movq 0x34(%rax), %rax
movslq -0x24(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, -0x2c(%rbp)
jmp 0xcfe8
movq -0x18(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x28(%rbp), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movw -0x1a(%rbp), %ax
movl -0x28(%rbp), %esi
movl $0x1, %edx
movzwl %ax, %edi
callq 0xd160
movw %ax, -0x1a(%rbp)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0xcfb2
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movzwl -0x1a(%rbp), %edx
sarl $0x8, %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movzwl -0x1a(%rbp), %edx
movl $0x1, %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %edx
movq -0x18(%rbp), %rax
movl 0x18(%rax), %ecx
callq 0xcbe0
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)