// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::ProcessStreamMFM(ImageStreamInfo*)
void CCapsImageStd::ProcessStreamMFM(PIMAGESTREAMINFO pstr)
{
	// get process state
	uint32_t bitpos=pstr->prcbitpos;
	int maxbc=pstr->prcrembc;
	int skipbc=pstr->prcskipbc;
	int actbc=0;

	// ignore last bit written if encoding the first bit and new encoding, use last bit otherwise
	uint32_t lv;
	if (!pstr->prcwritebc && pstr->prcencstate)
		lv=0;
	else {
		uint32_t bp=(bitpos ? bitpos : di.trackbc)-1;
		lv = trackbuf.ReadBit(bp);
	}

	// process remaining bits
	while (maxbc > 0) {
		// read the ipf stream
		int readbc=ReadSample(pstr, mfmreadlen);

		// number of bits not read/missing
		int diffbc=mfmreadlen-readbc;

		// write track data if anything was read
		if (readbc > 0) {
			// number of mfm encoded bits to be written
			int writebc=readbc << 1;

			// skip bits if needed and write bitfield
			if (writebc > skipbc) {
				writebc-=skipbc;
				skipbc=0;

				// calculate the number of missing bits for indexing the mfm code table
				// index size-number of bits to be encoded to reach the target encoded length
				int encodebc=mfmreadlen-((writebc+1) >> 1);

				// get value read
				uint32_t value=pstr->readvalue;

				// add 0 bits for any missing data bits; get correct table index
				value <<= encodebc;

				// convert to mfm
				value=CDiskEncoding::mfmcode[value & mfmindexmask];

				// fix mfm encoding if last bit written is 1
				if (lv & 1)
					value &= mfmmsbclear;

				// right align all valid bits to bit#0; size doubled since value is in mfm now
				value >>= (encodebc << 1);

				// if less bits to write than available, right align field to bit#0
				if (writebc > maxbc) {
					value >>= (writebc-maxbc);
					writebc=maxbc;
				}

				// save last value writen
				lv=value;

				// write value as bitfield
				trackbuf.WriteBitWrap(bitpos, value, writebc);

				// next write position
				actbc+=writebc;
				maxbc-=writebc;
				bitpos+=writebc;

				// handle track buffer wrap around (disk rotation)
				if (bitpos >= di.trackbc)
					bitpos-=di.trackbc;
			} else
				skipbc-=writebc;
		}

		// stop processing if encoding method changed or stream stopped 
		if (diffbc)
			break;
	}

	// set the type of the very first data
	if (!pstr->prcwritebc && pstr->prcencstate && actbc)
		di.block[pstr->actblock].fdenc=ibieMFM;

	// save process state
	pstr->prcbitpos=bitpos;
	pstr->prcrembc=maxbc;
	pstr->prcskipbc=skipbc;
	pstr->prcwritebc+=actbc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl 0x70(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl 0x74(%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x78(%rax), %eax
movl %eax, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x80(%rax)
jne 0x1256d
movq -0x10(%rbp), %rax
cmpl $0x0, 0x7c(%rax)
je 0x1256d
movl $0x0, -0x24(%rbp)
jmp 0x125a7
cmpl $0x0, -0x14(%rbp)
je 0x1257b
movl -0x14(%rbp), %eax
movl %eax, -0x4c(%rbp)
jmp 0x12588
movq -0x48(%rbp), %rax
movl 0x1c0(%rax), %eax
movl %eax, -0x4c(%rbp)
movq -0x48(%rbp), %rdi
movl -0x4c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x28(%rbp)
addq $0xb8, %rdi
movl -0x28(%rbp), %esi
callq 0x13ad0
movl %eax, -0x24(%rbp)
jmp 0x125a9
cmpl $0x0, -0x18(%rbp)
jle 0x1270f
movq -0x48(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl 0x220(%rdi), %edx
callq 0x11ac0
movl %eax, %ecx
movq -0x48(%rbp), %rax
movl %ecx, -0x2c(%rbp)
movl 0x220(%rax), %eax
subl -0x2c(%rbp), %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x2c(%rbp)
jle 0x12702
movl -0x2c(%rbp), %eax
shll %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x126f5
movq -0x48(%rbp), %rdx
movl -0x1c(%rbp), %ecx
movl -0x34(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x34(%rbp)
movl $0x0, -0x1c(%rbp)
movl 0x220(%rdx), %eax
movl -0x34(%rbp), %ecx
addl $0x1, %ecx
sarl %ecx
subl %ecx, %eax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl 0x40(%rax), %eax
movl %eax, -0x3c(%rbp)
movl -0x38(%rbp), %ecx
movl -0x3c(%rbp), %eax
shll %cl, %eax
movl %eax, -0x3c(%rbp)
leaq 0x16f7a(%rip), %rax     # 0x295b8
movq (%rax), %rax
movl -0x3c(%rbp), %ecx
andl 0x224(%rdx), %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x3c(%rbp)
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1266d
movq -0x48(%rbp), %rax
movl 0x228(%rax), %eax
andl -0x3c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x38(%rbp), %ecx
shll %ecx
movl -0x3c(%rbp), %eax
shrl %cl, %eax
movl %eax, -0x3c(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x18(%rbp), %eax
jle 0x12696
movl -0x34(%rbp), %ecx
subl -0x18(%rbp), %ecx
movl -0x3c(%rbp), %eax
shrl %cl, %eax
movl %eax, -0x3c(%rbp)
movl -0x18(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x48(%rbp), %rdi
movl -0x3c(%rbp), %eax
movl %eax, -0x24(%rbp)
addq $0xb8, %rdi
movl -0x14(%rbp), %esi
movl -0x3c(%rbp), %edx
movl -0x34(%rbp), %ecx
callq 0x13a60
movq -0x48(%rbp), %rcx
movl -0x34(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x34(%rbp), %edx
movl -0x18(%rbp), %eax
subl %edx, %eax
movl %eax, -0x18(%rbp)
movl -0x34(%rbp), %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl 0x1c0(%rcx), %eax
jb 0x126f3
movq -0x48(%rbp), %rax
movl 0x1c0(%rax), %ecx
movl -0x14(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x14(%rbp)
jmp 0x12700
movl -0x34(%rbp), %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
jmp 0x12702
cmpl $0x0, -0x30(%rbp)
je 0x1270a
jmp 0x1270f
jmp 0x125a9
movq -0x10(%rbp), %rax
cmpl $0x0, 0x80(%rax)
jne 0x1274d
movq -0x10(%rbp), %rax
cmpl $0x0, 0x7c(%rax)
je 0x1274d
cmpl $0x0, -0x20(%rbp)
je 0x1274d
movq -0x48(%rbp), %rax
movq 0x1f8(%rax), %rax
movq -0x10(%rbp), %rcx
movslq 0x4(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl $0x2, 0x20(%rax)
movl -0x14(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x70(%rax)
movl -0x18(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x74(%rax)
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x78(%rax)
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %rax
addl 0x80(%rax), %ecx
movl %ecx, 0x80(%rax)
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)