// File: 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
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x9e12
movl $0x2, -0x4(%rbp)
jmp 0xa082
movq -0x10(%rbp), %rax
movl (%rax), %eax
cmpq $0x134, %rax            # imm = 0x134
jae 0x9e2c
movl $0xf, -0x4(%rbp)
jmp 0xa082
movq -0x10(%rbp), %rsi
leaq -0x144(%rbp), %rdi
movl $0x134, %edx            # imm = 0x134
callq 0x41a0
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl $0x134, %edx            # imm = 0x134
callq 0x4140
movl -0x144(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movl -0x140(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movl -0x130(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x3c(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x108(%rax)
movl -0x58(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xec(%rax)
movl -0x54(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xf0(%rax)
movq -0x1c(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x128(%rax)
movl -0x14(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x130(%rax)
movq -0x10(%rbp), %rax
movl $0xffffffff, 0xf8(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movl $0xffffffff, 0xfc(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movl $0xfffffffe, 0xf4(%rax) # imm = 0xFFFFFFFE
movq -0x10(%rbp), %rax
cmpl $0x1, 0x4(%rax)
je 0x9efc
movl $0xf, -0x4(%rbp)
jmp 0xa082
movq -0x10(%rbp), %rax
cmpl $0x0, 0xec(%rax)
jle 0x9f2c
movq -0x10(%rbp), %rax
cmpl $0x0, 0xf0(%rax)
jl 0x9f2c
movq -0x10(%rbp), %rax
movl 0xf0(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0xec(%rcx), %eax
jle 0x9f38
movl $0x3, -0x4(%rbp)
jmp 0xa082
movq -0x10(%rbp), %rax
cmpq $0x0, 0x108(%rax)
jne 0x9f52
movl $0x2, -0x4(%rbp)
jmp 0xa082
movl $0x0, -0x148(%rbp)
movl -0x148(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0xec(%rcx), %eax
jge 0x9fae
movq -0x10(%rbp), %rax
movq 0x108(%rax), %rax
movslq -0x148(%rbp), %rcx
imulq $0x78, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
cmpq $0x78, %rax
jae 0x9f9b
movl $0xf, -0x4(%rbp)
jmp 0xa082
jmp 0x9f9d
movl -0x148(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x148(%rbp)
jmp 0x9f5c
movq -0x10(%rbp), %rax
movl $0x3, 0x18(%rax)
movq -0x10(%rbp), %rax
movl $0xff, 0x20(%rax)
movq -0x10(%rbp), %rax
movl $0x3, 0x4c(%rax)
movq -0x10(%rbp), %rax
movl $0x5, 0x9c(%rax)
movq -0x10(%rbp), %rax
movl $0x6, 0xa0(%rax)
movq -0x10(%rbp), %rax
movl $0x6, 0xa8(%rax)
movq -0x10(%rbp), %rax
movl $0xa, 0xb0(%rax)
movq -0x10(%rbp), %rax
movl $0x1770, 0xb8(%rax)     # imm = 0x1770
movq -0x10(%rbp), %rax
movl $0x2ee0, 0xbc(%rax)     # imm = 0x2EE0
movq -0x10(%rbp), %rax
movl $0x7d0, 0xc0(%rax)      # imm = 0x7D0
movq -0x10(%rbp), %rax
movl $0xbb8, 0xc4(%rax)      # imm = 0xBB8
movq -0x10(%rbp), %rax
movl $0x3a98, 0xd8(%rax)     # imm = 0x3A98
movq -0x10(%rbp), %rax
movl $0xfa0, 0xe0(%rax)      # imm = 0xFA0
movq -0x10(%rbp), %rax
movl $0x8, 0xe4(%rax)
movq -0x10(%rbp), %rdi
callq 0xa090
movq -0x10(%rbp), %rdi
callq 0xa1c0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
nop