// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcComReadNoise(CapsFdc*)
int FdcComReadNoise(PCAPSFDC pc)
{
	// clear dsr signals
	pc->aminfo&=~(CAPSFDC_AI_DSRREADY|CAPSFDC_AI_DSRAM|CAPSFDC_AI_DSRMA1);

	// get selected drive
	PCAPSDRIVE pd=pc->driveprc;

	// all cycles possibly advanced this time
	UDWORD dist=pd->idistance+(pc->clockreq-pc->clockact);

	// next bit complete divident, increased by clockrev
	UQUAD nextccn=(UQUAD)(pc->datalock+1)*pd->clockrev;

	// process until broken
	while (true) {
		// next bit is complete at this disk cycle
		UDWORD nextcyc=UDWORD(nextccn/pd->trackbits);

		// if not enough time to read bit, return
		if (dist < nextcyc) {
			pd->idistance=dist;
			pc->clockact=pc->clockreq;
			return 0;
		}

		// read bit into shifter
		FdcShiftBit(pc);

		// next bit
		pc->datalock++;
		nextccn+=pd->clockrev;

		// if index reached
		if (nextcyc >= pd->clockrev) {
			// adjust to index position
			dist-=pd->clockrev;
			pc->clockact+=pd->clockrev-pd->idistance;
			pd->idistance=0;
			pc->datalock=0;
			nextccn=pd->clockrev;

			// process disk index
			FdcIndex(pc, pc->driveact);

			// we read a complete byte exactly at index, set flag
			if (pc->aminfo & pc->amisigmask)
				return 1;

			// stop on end
			if (pc->endrequest)
				return 0;
		}

		// if a byte is complete, break and signal new byte
		if (pc->aminfo & pc->amisigmask) {
			int dst=pd->idistance;
			pd->idistance=nextcyc;
			pc->clockact+=nextcyc-dst;
			return 1;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x60(%rax), %ecx
andq $-0x701, %rcx           # imm = 0xF8FF
movl %ecx, 0x60(%rax)
movq -0x10(%rbp), %rax
movq 0x100(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl 0x24(%rax), %eax
movq -0x10(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x10(%rbp), %rdx
subl 0xc(%rdx), %ecx
addl %ecx, %eax
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl 0x80(%rax), %eax
addl $0x1, %eax
cltq
movq -0x18(%rbp), %rcx
movl 0x28(%rcx), %ecx
imulq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq 0x50(%rcx), %rcx
xorl %edx, %edx
divq %rcx
movl %eax, -0x2c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0xba44
movl -0x1c(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x10(%rbp), %rax
movl 0x10(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xc(%rax)
movl $0x0, -0x4(%rbp)
jmp 0xbb53
movq -0x10(%rbp), %rdi
callq 0xbfa0
movq -0x10(%rbp), %rax
movl 0x80(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x80(%rax)
movq -0x18(%rbp), %rax
movl 0x28(%rax), %eax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movl -0x2c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jb 0xbb0e
movq -0x18(%rbp), %rax
movl 0x28(%rax), %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0x18(%rbp), %rax
subl 0x24(%rax), %ecx
movq -0x10(%rbp), %rax
addl 0xc(%rax), %ecx
movl %ecx, 0xc(%rax)
movq -0x18(%rbp), %rax
movl $0x0, 0x24(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x80(%rax)
movq -0x18(%rbp), %rax
movl 0x28(%rax), %eax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0xfc(%rax), %esi
callq 0xb2d0
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movq -0x10(%rbp), %rcx
andl 0x64(%rcx), %eax
cmpl $0x0, %eax
je 0xbaf9
movl $0x1, -0x4(%rbp)
jmp 0xbb53
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0xbb0c
movl $0x0, -0x4(%rbp)
jmp 0xbb53
jmp 0xbb0e
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movq -0x10(%rbp), %rcx
andl 0x64(%rcx), %eax
cmpl $0x0, %eax
je 0xbb4e
movq -0x18(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x24(%rax)
movl -0x2c(%rbp), %ecx
subl -0x30(%rbp), %ecx
movq -0x10(%rbp), %rax
addl 0xc(%rax), %ecx
movl %ecx, 0xc(%rax)
movl $0x1, -0x4(%rbp)
jmp 0xbb53
jmp 0xba04
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)