// File: /workspace/github_cpp_makefile_star2_O2/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
pushq $0x2
popq %rbp
testq %rdi, %rdi
je 0x4cb2
movl %r8d, %ebx
movl %ecx, %r15d
movl %edx, %r12d
movq %rdi, %r14
xorl %r13d, %r13d
btl $0x9, %r8d
jae 0x4bab
movl (%r14), %r13d
cmpl $0x3, %r13d
jb 0x4bab
movl $0x2, (%r14)
pushq $0xf
jmp 0x4cb1
testl %esi, %esi
js 0x4c97
movl %esi, %edx
movq 0x1395c(%rip), %rcx     # 0x18518
movq 0x1394d(%rip), %rax     # 0x18510
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rdx, %rcx
jbe 0x4c97
movq (%rax,%rdx,8), %rdi
testq %rdi, %rdi
je 0x4c97
movq %rdx, (%rsp)
movl %ebx, %eax
btl $0xe, %eax
jae 0x4c12
movl %r12d, %esi
movl %r15d, %edx
callq 0xc9c4
testq %rax, %rax
sete %cl
cmpl $0x2, %r13d
setne %dl
orb %cl, %dl
jne 0x4c12
movl 0x34(%r14), %ecx
movl %ecx, 0xc4(%rax)
movl %r13d, %eax
leaq 0x1260c(%rip), %rcx     # 0x17228
movslq (%rcx,%rax,4), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x3110
movq 0x138df(%rip), %rax     # 0x18510
movq (%rsp), %rcx
movq (%rax,%rcx,8), %rdi
movl %r12d, %esi
movl %r15d, %edx
movl %ebx, %ecx
callq 0xca02
testq %rax, %rax
je 0x4cc3
movl 0x108(%rax), %ecx
pushq $0x3
popq %rsi
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 0x4cdd
cmpl $0x1, %r13d
jne 0x4ce4
callq 0x4d63
jmp 0x4ce9
movl %r13d, %eax
leaq 0x12587(%rip), %rcx     # 0x17228
movslq (%rcx,%rax,4), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x3110
pushq $0x3
popq %rbp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x13846(%rip), %rax     # 0x18510
movq (%rsp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x0, 0x8(%rax)
je 0x4cb2
movl 0xc(%rax), %ebp
jmp 0x4cb2
callq 0x4db5
jmp 0x4ce9
callq 0x4ced
xorl %ebp, %ebp
jmp 0x4cb2