// File: /workspace/github_cpp_makefile_star2_O2/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: CAPSFdcInit(CapsFdc*)
SDWORD __cdecl CAPSFdcInit(PCAPSFDC pc)
{
	if (!pc)
		return imgeGeneric;

	// check fdc workspace size
	if (pc->type < sizeof(CapsFdc))
		return imgeUnsupportedType;

	// get presets
	CapsFdc fdc=*pc;

	// clear structure
	memset(pc, 0, sizeof(CapsFdc));

	// restore presets
	pc->type=fdc.type;
	pc->model=fdc.model;
	pc->clockfrq=fdc.clockfrq;
	pc->drive=fdc.drive;
	pc->drivecnt=fdc.drivecnt;
	pc->drivemax=fdc.drivemax;
	pc->userptr=fdc.userptr;
	pc->userdata=fdc.userdata;

	// no drive selected, force change
	pc->drivesel=-1;
	pc->driveact=-1;
	pc->drivenew=-2;

	// error if unsupported fdc
	if (pc->model != cfdcmWD1772)
		return imgeUnsupportedType;

	// check valid drive numbers
	if (pc->drivecnt<=0 || pc->drivemax<0 || pc->drivemax>pc->drivecnt)
		return imgeOutOfRange;

	// check attached drives
	if (!pc->drive)
		return imgeGeneric;

	// check workspace size for all drives
	for (int drv=0; drv < pc->drivecnt; drv++) {
		if (pc->drive[drv].type < sizeof(CapsDrive))
			return imgeUnsupportedType;
	}

	// 2 address lines, 8 data lines, 0...3 sector length
	pc->addressmask=0x03;
	pc->datamask=0xff;
	pc->seclenmask=0x03;

	// index counter constants
	pc->readlimit=5;
	pc->verifylimit=6;
	pc->spinuplimit=6;
	pc->idlelimit=10;

	// stepping rates
	pc->steptime[0]=6000;
	pc->steptime[1]=12000;
	pc->steptime[2]=2000;
	pc->steptime[3]=3000;

	// head settling time
	pc->hstime=15000;

	// index pulse hold
	pc->iptime=4000;

	// update delay
	pc->updatetime=8;

	// initialise to default emulation state
	FdcSetTiming(pc);
	FdcInit(pc);

	return imgeOk;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
pushq $0x2
popq %rbp
testq %rdi, %rdi
je 0x5d60
movq %rdi, %rbx
movl (%rdi), %r14d
pushq $0xf
popq %rax
cmpl $0x134, %r14d           # imm = 0x134
jae 0x5c8b
movl %eax, %ebp
jmp 0x5d60
movl 0x4(%rbx), %r13d
movl 0x14(%rbx), %eax
movl %eax, 0x4(%rsp)
movl 0xec(%rbx), %eax
movq %rax, 0x8(%rsp)
movl 0xf0(%rbx), %r12d
movq 0x108(%rbx), %r15
movq 0x128(%rbx), %rax
movq %rax, 0x10(%rsp)
movl 0x130(%rbx), %eax
movl %eax, (%rsp)
leaq 0x8(%rbx), %rdi
movl $0x120, %edx            # imm = 0x120
xorl %esi, %esi
callq 0x3110
movq 0x8(%rsp), %rdx
movl %r14d, (%rbx)
movl %r13d, 0x4(%rbx)
movl 0x4(%rsp), %eax
movl %eax, 0x14(%rbx)
movq %r15, 0x108(%rbx)
movl %edx, 0xec(%rbx)
movl %r12d, 0xf0(%rbx)
movq 0x10(%rsp), %rax
movq %rax, 0x128(%rbx)
movl (%rsp), %eax
movl %eax, 0x130(%rbx)
orl $-0x1, 0xfc(%rbx)
movq $-0x2, 0xf4(%rbx)
cmpl $0x1, %r13d
jne 0x5d5d
testl %edx, %edx
setle %al
cmpl %edx, %r12d
seta %cl
orb %al, %cl
je 0x5d3b
pushq $0x3
jmp 0x5d5f
testq %r15, %r15
je 0x5d60
imulq $0x78, %rdx, %rax
addq $0x78, %rax
xorl %ecx, %ecx
leaq 0x78(%rcx), %rdx
cmpq %rdx, %rax
je 0x5d71
cmpl $0x78, (%r15,%rcx)
movq %rdx, %rcx
jae 0x5d4a
pushq $0xf
popq %rbp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x3
popq %rax
movl %eax, 0x18(%rbx)
movl $0xff, 0x20(%rbx)
movl %eax, 0x4c(%rbx)
movabsq $0x600000005, %rax      # imm = 0x600000005
movq %rax, 0x9c(%rbx)
movl $0x6, 0xa8(%rbx)
movl $0xa, 0xb0(%rbx)
movaps 0x9393(%rip), %xmm0     # 0xf140
movups %xmm0, 0xb8(%rbx)
movl $0x3a98, 0xd8(%rbx)     # imm = 0x3A98
movabsq $0x800000fa0, %rax      # imm = 0x800000FA0
movq %rax, 0xe0(%rbx)
movq %rbx, %rdi
callq 0x5de6
movq %rbx, %rdi
callq 0x5eaa
xorl %ebp, %ebp
jmp 0x5d60