// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcComReadDMap(CapsFdc*)
int FdcComReadDMap(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);

	// bit complete
	UDWORD sum=pd->timebuf[pd->tracklen-1];
	UDWORD base=pc->datacycle;
	PUDWORD time=pd->timebuf+(pc->datalock>>3);
	UDWORD diff=*time-base;
	int hi=(pc->datalock&7)+1;

	// process until broken
	while (true) {
		// bit is complete at this disk cycle
		UDWORD nextcyc=UDWORD(((UQUAD)(base+(hi*diff)/8)*pd->clockrev)/sum);

		// 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++;

		// next bit timing
		if (hi == 8) {
			hi=1;
			base=*time++;
			pc->datacycle=base;
			diff=*time-base;
		} else
			hi++;

		// 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;
			base=0;
			pc->datacycle=0;
			time=pd->timebuf;
			diff=*time;
			hi=1;

			// 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 $0x40, %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 -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x48(%rcx), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl 0x88(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x80(%rcx), %ecx
sarl $0x3, %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl (%rax), %eax
subl -0x24(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rax
movl 0x80(%rax), %eax
andl $0x7, %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
movl -0x24(%rbp), %eax
movl -0x38(%rbp), %ecx
imull -0x34(%rbp), %ecx
shrl $0x3, %ecx
addl %ecx, %eax
movl %eax, %eax
movq -0x18(%rbp), %rcx
movl 0x28(%rcx), %ecx
imulq %rcx, %rax
movl -0x20(%rbp), %ecx
xorl %edx, %edx
divq %rcx
movl %eax, -0x3c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jae 0xbe22
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 0xbf8d
movq -0x10(%rbp), %rdi
callq 0xbfa0
movq -0x10(%rbp), %rax
movl 0x80(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x80(%rax)
cmpl $0x8, -0x38(%rbp)
jne 0xbe7a
movl $0x1, -0x38(%rbp)
movq -0x30(%rbp), %rax
movq %rax, %rcx
addq $0x4, %rcx
movq %rcx, -0x30(%rbp)
movl (%rax), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x88(%rax)
movq -0x30(%rbp), %rax
movl (%rax), %eax
subl -0x24(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0xbe83
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
movl -0x3c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jb 0xbf48
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)
movl $0x0, -0x24(%rbp)
movq -0x10(%rbp), %rax
movl $0x0, 0x88(%rax)
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x34(%rbp)
movl $0x1, -0x38(%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 0xbf33
movl $0x1, -0x4(%rbp)
jmp 0xbf8d
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0xbf46
movl $0x0, -0x4(%rbp)
jmp 0xbf8d
jmp 0xbf48
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movq -0x10(%rbp), %rcx
andl 0x64(%rcx), %eax
cmpl $0x0, %eax
je 0xbf88
movq -0x18(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x24(%rax)
movl -0x3c(%rbp), %ecx
subl -0x40(%rbp), %ecx
movq -0x10(%rbp), %rax
addl 0xc(%rax), %ecx
movl %ecx, 0xc(%rax)
movl $0x1, -0x4(%rbp)
jmp 0xbf8d
jmp 0xbdcf
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)