// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcComT3_AddressLoop(CapsFdc*)
void FdcComT3_AddressLoop(PCAPSFDC pc)
{
	// update data access
	FdcUpdateData(pc);

	// get access hook, crc
	FDCREAD ph=FdcGetReadAccess(pc);

	// clock cycles to complete
	UDWORD cst=pc->clockact;

	// process requested cycles
	while (!pc->endrequest && pc->clockact<pc->clockreq) {
		// read byte when ready
		if (!ph(pc))
			continue;

		// check ID
		switch (pc->dataphase) {
			// detect a1 sync
			case 0:
				// AM detected, read returns on dsr ready
				pc->amisigmask=CAPSFDC_AI_DSRREADY;
				pc->dataphase++;
				break;

			case 1:
				//if not fc...ff, restart
				if (pc->dsr < 0xfc) {
					FdcResetAm(pc);
					continue;
				}

				pc->dataphase++;
				break;

			case 2:
				// set the sector register to the track number
				pc->r_sector=pc->dsr;

			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				// dsr to data, drq signal
				pc->r_data=pc->dsr;
				FdcSetLine(pc, pc->lineout|CAPSFDC_LO_DRQSET);

				// next phase
				if (pc->dataphase++ == 7) {
					// if crc error, set crc flag
					if (pc->crc & 0xffff)
						pc->r_st0|=CAPSFDC_SR_CRCERR;

					// run cycles used on unselected drives
					FdcComIdleOther(pc, pc->clockact-cst);

					// end
					pc->endrequest|=CAPSFDC_ER_COMEND;
					return;
				}
				break;

			default:
				NODEFAULT;
		}
	}

	// end requested, set seek error
	if (pc->endrequest & CAPSFDC_ER_COMEND)
		pc->r_st0|=CAPSFDC_SR_RNF;

	// run cycles on unselected drives
	FdcComIdleOther(pc, pc->clockact-cst);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0xb000
movq -0x8(%rbp), %rdi
callq 0xb130
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x8(%rbp), %rcx
xorl %eax, %eax
cmpl $0x0, 0x8(%rcx)
movb %al, -0x15(%rbp)
jne 0x9bcf
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x10(%rcx), %eax
setb %al
movb %al, -0x15(%rbp)
movb -0x15(%rbp), %al
testb $0x1, %al
jne 0x9bdb
jmp 0x9d07
movq -0x10(%rbp), %rax
movq -0x8(%rbp), %rdi
callq *%rax
cmpl $0x0, %eax
jne 0x9bec
jmp 0x9bac
movq -0x8(%rbp), %rax
movl 0x8c(%rax), %eax
movq %rax, -0x20(%rbp)
subq $0x7, %rax
ja 0x9d00
movq -0x20(%rbp), %rax
leaq 0x144c9(%rip), %rcx     # 0x1e0d8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rax
movl $0x100, 0x64(%rax)      # imm = 0x100
movq -0x8(%rbp), %rax
movl 0x8c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8c(%rax)
jmp 0x9d02
movq -0x8(%rbp), %rax
cmpl $0xfc, 0x78(%rax)
jae 0x9c58
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0xb1a0
jmp 0x9bac
movq -0x8(%rbp), %rax
movl 0x8c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8c(%rax)
jmp 0x9d02
movq -0x8(%rbp), %rax
movl 0x78(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x44(%rax)
movq -0x8(%rbp), %rax
movl 0x78(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x48(%rax)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movl 0x24(%rax), %eax
orq $0x40, %rax
movl %eax, %esi
callq 0xa860
movq -0x8(%rbp), %rcx
movl 0x8c(%rcx), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x8c(%rcx)
cmpl $0x7, %eax
jne 0x9cfe
movq -0x8(%rbp), %rax
movl 0x54(%rax), %eax
andl $0xffff, %eax           # imm = 0xFFFF
cmpl $0x0, %eax
je 0x9cdb
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
orq $0x8, %rcx
movl %ecx, 0x30(%rax)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movl 0xc(%rax), %esi
subl -0x14(%rbp), %esi
callq 0xb200
movq -0x8(%rbp), %rax
movl 0x8(%rax), %ecx
orq $0x1, %rcx
movl %ecx, 0x8(%rax)
jmp 0x9d39
jmp 0x9d02
jmp 0x9d02
jmp 0x9bac
movq -0x8(%rbp), %rax
movl 0x8(%rax), %eax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x9d26
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
orq $0x10, %rcx
movl %ecx, 0x30(%rax)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movl 0xc(%rax), %esi
subl -0x14(%rbp), %esi
callq 0xb200
addq $0x20, %rsp
popq %rbp
retq
nop