// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl $0x2, %ebp
testq %rdi, %rdi
je 0x5fc3
movl %r8d, %ebx
movl %ecx, %r15d
movl %edx, %r12d
movq %rdi, %r14
xorl %r13d, %r13d
btl $0x9, %r8d
jae 0x5eb8
movl (%r14), %r13d
cmpl $0x3, %r13d
jb 0x5eb8
movl $0x2, (%r14)
movl $0xf, %ebp
jmp 0x5fc3
testl %esi, %esi
js 0x5fa6
movl %esi, %edx
movq 0x1464f(%rip), %rcx     # 0x1a518
movq 0x14640(%rip), %rax     # 0x1a510
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rdx, %rcx
jbe 0x5fa6
movq (%rax,%rdx,8), %rdi
testq %rdi, %rdi
je 0x5fa6
movq %rdx, (%rsp)
movl %ebx, %eax
btl $0xe, %eax
jae 0x5f1f
movl %r12d, %esi
movl %r15d, %edx
callq 0xebea
testq %rax, %rax
sete %cl
cmpl $0x2, %r13d
setne %dl
orb %cl, %dl
jne 0x5f1f
movl 0x34(%r14), %ecx
movl %ecx, 0xc4(%rax)
movl %r13d, %eax
leaq 0x132ff(%rip), %rcx     # 0x19228
movslq (%rcx,%rax,4), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x4140
movq 0x145d2(%rip), %rax     # 0x1a510
movq (%rsp), %rcx
movq (%rax,%rcx,8), %rdi
movl %r12d, %esi
movl %r15d, %edx
movl %ebx, %ecx
callq 0xec28
testq %rax, %rax
je 0x5fd4
movl 0x108(%rax), %ecx
movl $0x3, %esi
cmpl %esi, %ecx
cmovael %esi, %ecx
movl $0x80000000, %edx       # imm = 0x80000000
movl %ecx, %edi
orl %edx, %edi
cmpl $0x0, 0xd0(%rax)
cmovel %ecx, %edi
cmpl $0x0, 0x44(%rax)
cmovnel %esi, %edi
orl %edi, %edx
cmpl $0x0, 0x40(%rax)
cmovel %edi, %edx
movq %r14, %rdi
movq %rax, %rsi
movl %ebx, %ecx
cmpl $0x2, %r13d
je 0x5fee
cmpl $0x1, %r13d
jne 0x5ff5
callq 0x6078
jmp 0x5ffa
movl %r13d, %eax
leaq 0x13278(%rip), %rcx     # 0x19228
movslq (%rcx,%rax,4), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x4140
movl $0x3, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x14535(%rip), %rax     # 0x1a510
movq (%rsp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x0, 0x8(%rax)
je 0x5fc3
movl 0xc(%rax), %ebp
jmp 0x5fc3
callq 0x60cd
jmp 0x5ffa
callq 0x5ffe
xorl %ebp, %ebp
jmp 0x5fc3