// File: /workspace/github_cpp_makefile_star2_O3/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:
movl $0x2, %eax
testq %rdi, %rdi
je 0x71f0
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl (%rdi), %r12d
cmpl $0x134, %r12d           # imm = 0x134
jb 0x71dd
movl 0x4(%rbx), %r13d
movl 0x14(%rbx), %eax
movl %eax, 0xc(%rsp)
movl 0xec(%rbx), %r15d
movl 0xf0(%rbx), %ebp
movq 0x108(%rbx), %r14
movq 0x128(%rbx), %rax
movq %rax, 0x10(%rsp)
movl 0x130(%rbx), %eax
movl %eax, 0x8(%rsp)
leaq 0x8(%rbx), %rdi
movl $0x120, %edx            # imm = 0x120
xorl %esi, %esi
callq 0x4140
movl %r12d, (%rbx)
movl %r13d, 0x4(%rbx)
movl 0xc(%rsp), %eax
movl %eax, 0x14(%rbx)
movq %r14, 0x108(%rbx)
movl %r15d, 0xec(%rbx)
movl %ebp, 0xf0(%rbx)
movq 0x10(%rsp), %rax
movq %rax, 0x128(%rbx)
movl 0x8(%rsp), %eax
movl %eax, 0x130(%rbx)
movl $0xffffffff, 0xfc(%rbx) # imm = 0xFFFFFFFF
movq $-0x2, 0xf4(%rbx)
cmpl $0x1, %r13d
jne 0x71dd
testl %r15d, %r15d
setle %al
cmpl %r15d, %ebp
seta %cl
orb %al, %cl
movl $0x3, %eax
jne 0x71e2
movl $0x2, %eax
testq %r14, %r14
je 0x71e2
imulq $0x78, %r15, %rax
xorl %ecx, %ecx
cmpl $0x78, (%r14,%rcx)
jb 0x71dd
addq $0x78, %rcx
cmpq %rcx, %rax
jne 0x7159
movl $0x3, %eax
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 0xafc9(%rip), %xmm0     # 0x12170
movups %xmm0, 0xb8(%rbx)
movl $0x3a98, 0xd8(%rbx)     # imm = 0x3A98
movabsq $0x800000fa0, %rax      # imm = 0x800000FA0
movq %rax, 0xe0(%rbx)
movq %rbx, %rdi
callq 0x71f1
movq %rbx, %rdi
callq 0x72b6
xorl %eax, %eax
jmp 0x71e2
movl $0xf, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq