// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsAPI.cpp
// Function: CAPSLockTrack(void*, int, unsigned int, unsigned int, unsigned int)
SDWORD __cdecl CAPSLockTrack(PVOID ptrackinfo, SDWORD id, UDWORD cylinder, UDWORD head, UDWORD flag)
{
	if (!ptrackinfo)
		return imgeGeneric;

	// structure revision is zero, unless newer one requested
	unsigned rev=0;
	if (flag & DI_LOCK_TYPE)
		rev=*(PUDWORD)ptrackinfo;

	// if unsupported type set the highest supported version
	if (rev > 2) {
		*(PUDWORD)ptrackinfo=2;
		return imgeUnsupportedType;
	}

	// check id
	if (id < 0 || (unsigned)id >= img.size() || !img[id]) {
		// clear structure
		memset(ptrackinfo, 0, sizetrackinfo[rev]);

		return imgeOutOfRange;
	}

	// set weak bit generator
	if (flag & DI_LOCK_SETWSEED) {
		PDISKTRACKINFO pt=img[id]->GetTrack(cylinder, head);
		if (pt) {
			switch (rev) {
				case 2:
					pt->wseed=((PCAPSTRACKINFOT2)ptrackinfo)->wseed;
					break;
			}
		}
	}

	// clear structure
	memset(ptrackinfo, 0, sizetrackinfo[rev]);

	// lock track
	PDISKTRACKINFO pt=img[id]->LockTrack(cylinder, head, flag);
	if (!pt) {
		PDISKIMAGEINFO pd=img[id]->GetInfo();

		return pd ? pd->error : imgeGeneric;
	}

	// track type conversion
	UDWORD ttype;
	switch (pt->ci.dentype) {
		case cpdenNA:
			ttype=ctitNA;
			break;

		case cpdenNoise:
			ttype=ctitNoise;
			break;

		case cpdenAuto:
			ttype=ctitAuto;
			break;

		default:
			ttype=ctitVar;
			break;
	}

	// signal track update
	if (pt->fdpsize)
		ttype|=CTIT_FLAG_FLAKEY;

	// track type is variable density for raw dumps
	if (pt->rawdump)
		ttype = ctitVar;

	// if multiple revolutions used by a raw dump signal track update
	if (pt->rawupdate)
		ttype |= CTIT_FLAG_FLAKEY;

	// get the correct structure
	switch (rev) {
		case 0:
			CAPSLockTrackT0((PCAPSTRACKINFO)ptrackinfo, pt, ttype, flag);
			break;

		case 1:
			CAPSLockTrackT1((PCAPSTRACKINFOT1)ptrackinfo, pt, ttype, flag);
			break;

		case 2:
			CAPSLockTrackT2((PCAPSTRACKINFOT2)ptrackinfo, pt, ttype, flag);
			break;
	}

	return imgeOk;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x72dc
movl $0x2, -0x4(%rbp)
jmp 0x7556
movl $0x0, -0x24(%rbp)
movl -0x20(%rbp), %eax
andq $0x200, %rax            # imm = 0x200
cmpq $0x0, %rax
je 0x72fb
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $0x2, -0x24(%rbp)
jbe 0x7317
movq -0x10(%rbp), %rax
movl $0x2, (%rax)
movl $0xf, -0x4(%rbp)
jmp 0x7556
cmpl $0x0, -0x14(%rbp)
jl 0x7352
movl -0x14(%rbp), %eax
movq %rax, -0x50(%rbp)
leaq 0x21225(%rip), %rdi     # 0x28550
callq 0x8100
movq %rax, %rcx
movq -0x50(%rbp), %rax
cmpq %rcx, %rax
jae 0x7352
movslq -0x14(%rbp), %rsi
leaq 0x21209(%rip), %rdi     # 0x28550
callq 0x8120
cmpq $0x0, (%rax)
jne 0x7379
movq -0x10(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, %ecx
leaq 0x1ff12(%rip), %rax     # 0x27274
movslq (%rax,%rcx,4), %rdx
xorl %esi, %esi
callq 0x4140
movl $0x3, -0x4(%rbp)
jmp 0x7556
movl -0x20(%rbp), %eax
andq $0x4000, %rax           # imm = 0x4000
cmpq $0x0, %rax
je 0x73d0
movslq -0x14(%rbp), %rsi
leaq 0x211bd(%rip), %rdi     # 0x28550
callq 0x8120
movq (%rax), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
callq 0x182b0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x73ce
movl -0x24(%rbp), %eax
subl $0x2, %eax
jne 0x73cc
jmp 0x73bb
movq -0x10(%rbp), %rax
movl 0x34(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0xc4(%rax)
jmp 0x73ce
jmp 0x73d0
movq -0x10(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, %ecx
leaq 0x1fe94(%rip), %rax     # 0x27274
movslq (%rax,%rcx,4), %rdx
xorl %esi, %esi
callq 0x4140
movslq -0x14(%rbp), %rsi
leaq 0x2115a(%rip), %rdi     # 0x28550
callq 0x8120
movq (%rax), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
movl -0x20(%rbp), %ecx
callq 0x18350
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x745b
movslq -0x14(%rbp), %rsi
leaq 0x2112e(%rip), %rdi     # 0x28550
callq 0x8120
movq (%rax), %rdi
callq 0x81b0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x7446
movq -0x40(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x54(%rbp)
jmp 0x7450
movl $0x2, %eax
movl %eax, -0x54(%rbp)
jmp 0x7450
movl -0x54(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x7556
movq -0x38(%rbp), %rax
movl 0x108(%rax), %eax
movl %eax, -0x58(%rbp)
testl %eax, %eax
je 0x7482
jmp 0x746e
movl -0x58(%rbp), %eax
subl $0x1, %eax
je 0x748b
jmp 0x7478
movl -0x58(%rbp), %eax
subl $0x2, %eax
je 0x7494
jmp 0x749d
movl $0x0, -0x44(%rbp)
jmp 0x74a4
movl $0x1, -0x44(%rbp)
jmp 0x74a4
movl $0x2, -0x44(%rbp)
jmp 0x74a4
movl $0x3, -0x44(%rbp)
movq -0x38(%rbp), %rax
cmpl $0x0, 0xd0(%rax)
je 0x74c4
movl -0x44(%rbp), %eax
movabsq $0x80000000, %rcx       # imm = 0x80000000
orq %rcx, %rax
movl %eax, -0x44(%rbp)
movq -0x38(%rbp), %rax
cmpl $0x0, 0x44(%rax)
je 0x74d5
movl $0x3, -0x44(%rbp)
movq -0x38(%rbp), %rax
cmpl $0x0, 0x40(%rax)
je 0x74f2
movl -0x44(%rbp), %eax
movabsq $0x80000000, %rcx       # imm = 0x80000000
orq %rcx, %rax
movl %eax, -0x44(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x5c(%rbp)
testl %eax, %eax
je 0x7512
jmp 0x74fe
movl -0x5c(%rbp), %eax
subl $0x1, %eax
je 0x7527
jmp 0x7508
movl -0x5c(%rbp), %eax
subl $0x2, %eax
je 0x753c
jmp 0x754f
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x44(%rbp), %edx
movl -0x20(%rbp), %ecx
callq 0x7560
jmp 0x754f
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x44(%rbp), %edx
movl -0x20(%rbp), %ecx
callq 0x7680
jmp 0x754f
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x44(%rbp), %edx
movl -0x20(%rbp), %ecx
callq 0x7750
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop