LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcIndex(CapsFdc*, int)
void FdcIndex(PCAPSFDC pc, int drive)
{
	// must be valid drive
	if (drive < 0)
		return;

	// get selected drive
	PCAPSDRIVE pd=pc->drive+drive;

	// if drive empty, no index signal, stop
	if (!(pd->diskattr & CAPSDRIVE_DA_IN))
		return;

	// start index pulse
	pd->ipcnt=-1;

	// if track is changing, request new track data
	if ((pd->ttype & CTIT_FLAG_FLAKEY))
		pc->cbtrk(pc, drive);

	// update track parameters
	FdcUpdateTrack(pc, drive);

	// if drive not selected, index signal not routed, stop
	if (drive != pc->driveact)
		return;

	// set index signal
	pc->r_st0|=CAPSFDC_SR_IP_DRQ;

	// increment index pulse counter
	pc->indexcount++;

	// if index abort allowed and limit reached set end and disable abort
	if (pc->indexlimit>=0 && pc->indexcount>=pc->indexlimit) {
		pc->endrequest|=CAPSFDC_ER_COMEND;
		pc->indexlimit=-1;
	}

	// set spin-up flag if limit reached
	if (pc->spinupcnt>=pc->spinuplimit || ++pc->spinupcnt>=pc->spinuplimit)
		pc->r_st0|=CAPSFDC_SR_SU_RT;

	// if fdc is not busy turn motor off once idle limit reached, apparently SR spin-up is not reset
	if (!(pc->r_st0 & CAPSFDC_SR_BUSY)) {
		if (pc->idlecnt>=pc->idlelimit || ++pc->idlecnt>=pc->idlelimit) {
			pc->lineout&=~CAPSFDC_LO_MO;
			pd->diskattr&=~CAPSDRIVE_DA_MO;
			pc->r_st0&=~CAPSFDC_SR_MO;
			pc->spinupcnt=0;
		}
	}

	// set index pulse interrupt if enabled
	if (pc->lineout & CAPSFDC_LO_INTIP)
		FdcSetLine(pc, pc->lineout | CAPSFDC_LO_INTRQ);
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
testl %esi, %esi
js 0x7bc4
movl %esi, %ebp
movq %rdi, %rbx
movq 0x108(%rdi), %r14
movl %esi, %eax
imulq $0x78, %rax, %rax
testb $0x1, 0x20(%r14,%rax)
je 0x7bc4
addq %rax, %r14
movl $0xffffffff, 0x30(%r14) # imm = 0xFFFFFFFF
cmpl $0x0, 0x34(%r14)
jns 0x7b09
movq %rbx, %rdi
movl %ebp, %esi
callq *0x120(%rbx)
movq %rbx, %rdi
movl %ebp, %esi
callq 0x7c72
cmpl %ebp, 0xfc(%rbx)
jne 0x7bc4
movl 0x30(%rbx), %ecx
movl 0x94(%rbx), %edx
movl %ecx, %eax
orl $0x2, %eax
movl %eax, 0x30(%rbx)
incl %edx
movl %edx, 0x94(%rbx)
movl 0x98(%rbx), %esi
testl %esi, %esi
sets %dil
cmpl %esi, %edx
setl %dl
orb %dil, %dl
jne 0x7b5c
orb $0x1, 0x8(%rbx)
movl $0xffffffff, 0x98(%rbx) # imm = 0xFFFFFFFF
movl 0xa4(%rbx), %edx
movl 0xa8(%rbx), %esi
cmpl %esi, %edx
jge 0x7b78
incl %edx
movl %edx, 0xa4(%rbx)
cmpl %esi, %edx
jl 0x7b80
orl $0x22, %ecx
movl %ecx, 0x30(%rbx)
movl %ecx, %eax
testb $0x1, %al
jne 0x7bbb
movl 0xac(%rbx), %ecx
movl 0xb0(%rbx), %edx
cmpl %edx, %ecx
jge 0x7ba0
incl %ecx
movl %ecx, 0xac(%rbx)
cmpl %edx, %ecx
jl 0x7bbb
andb $-0x9, 0x24(%rbx)
andb $-0x5, 0x20(%r14)
andl $0xffffff7e, %eax       # imm = 0xFFFFFF7E
movl %eax, 0x30(%rbx)
movl $0x0, 0xa4(%rbx)
movl 0x24(%rbx), %esi
testb $0x20, %sil
jne 0x7bc9
popq %rbx
popq %r14
popq %rbp
retq
orl $0x2, %esi
movq %rbx, %rdi
popq %rbx
popq %r14
popq %rbp
jmp 0x7624
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcLockData(CapsFdc*)
void FdcLockData(PCAPSFDC pc)
{
	// get selected drive
	PCAPSDRIVE pd=pc->driveprc;

	// check input available
	if (!pd || !(pd->diskattr & CAPSDRIVE_DA_IN)) {
		// if no input read 0 on reference clock
		pc->datamode=cfdcdmNoline;

		// lock onto reference clock 2us mfm*(8clock+8data)
		pc->datalock=UDWORD(((UQUAD)pc->clockfrq*2*16)/1000000);
		pc->datacycle=0;
		return;
	}

	// true if track data is defined
	int dat=pd->trackbuf && pd->tracklen;

	// density map is only used when track data is available
	if (pd->timebuf && dat) {
		pc->datamode=cfdcdmDMap;
		FdcLockTime(pc);
		return;
	}

	// noise or data input read
	pc->datamode=dat ? cfdcdmData : cfdcdmNoise;

	// lock onto bit in progress at the drive cycle
	pc->datalock=UDWORD(((UQUAD)pd->idistance*pd->trackbits)/pd->clockrev);
	pc->datacycle=0;
}

// Assembly:
movq 0x100(%rdi), %rax
testq %rax, %rax
je 0x7bea
testb $0x1, 0x20(%rax)
jne 0x7c0a
movq $0x0, 0x84(%rdi)
movl 0x14(%rdi), %eax
imulq $0x431bde83, %rax, %rax # imm = 0x431BDE83
shrq $0x2d, %rax
movl %eax, 0x80(%rdi)
retq
cmpq $0x0, 0x38(%rax)
je 0x7c36
movl 0x48(%rax), %ecx
testl %ecx, %ecx
sete %dl
cmpq $0x0, 0x40(%rax)
sete %sil
orb %dl, %sil
jne 0x7c3d
movl $0x3, 0x84(%rdi)
jmp 0x7d3c
movl $0x1, %ecx
jmp 0x7c48
cmpl $0x1, %ecx
movl $0x1, %ecx
sbbl $-0x1, %ecx
movl %ecx, 0x84(%rdi)
movl 0x24(%rax), %ecx
movl 0x28(%rax), %esi
movslq 0x50(%rax), %rax
imulq %rcx, %rax
xorl %edx, %edx
divq %rsi
movl %eax, 0x80(%rdi)
movl $0x0, 0x88(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcUpdateTrack(CapsFdc*, int)
void FdcUpdateTrack(PCAPSFDC pc, int drive)
{
	// must be valid drive
	if (drive < 0)
		return;

	// get selected drive
	PCAPSDRIVE pd=pc->drive+drive;

	// no disk inserted, no input
	if (!(pd->diskattr & CAPSDRIVE_DA_IN))
		return;

	// get base track length in bits
	if (!pd->trackbuf || !pd->tracklen) {
		// generate different track size on track updates
		PSDWORD ns=fdcddnoise;
		pd->trackbits=ns[pd->nact++]<<3;
		if (ns[pd->nact] < 0)
			pd->nact=0;
		pd->overlap=0;
	} else
		pd->trackbits=pd->tracklen<<3;

	// if overlap position exists
	int rb;
	if (pd->overlap >= 0) {
		// rob bit count, updated on track updates
		rb=fdcrobbit[pd->ovlact++];
		if (fdcrobbit[pd->ovlact] < 0)
			pd->ovlact=0;
	} else
		rb=0;

	pd->ovlcnt=rb;

	// set bits to remove and their start if any
	if (rb) {
		pd->ovlmin=((pd->overlap+1)<<3)-rb;
		pd->ovlmax=pd->ovlmin+rb-1;
	} else {
		pd->ovlmin=-1;
		pd->ovlmax=-1;
	}
}

// Assembly:
testl %esi, %esi
js 0x7d3b
movq 0x108(%rdi), %rax
movl %esi, %ecx
imulq $0x78, %rcx, %rcx
testb $0x1, 0x20(%rax,%rcx)
je 0x7d3b
addq %rcx, %rax
cmpq $0x0, 0x38(%rax)
je 0x7cb8
movl 0x48(%rax), %ecx
testl %ecx, %ecx
je 0x7cb8
shll $0x3, %ecx
movl %ecx, 0x50(%rax)
cmpl $0x0, 0x4c(%rax)
jns 0x7ce8
movl $0x0, 0x5c(%rax)
jmp 0x7d2c
movslq 0x64(%rax), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, 0x64(%rax)
leaq 0x11596(%rip), %rdx     # 0x19260
movl (%rdx,%rcx,4), %esi
shll $0x3, %esi
movl %esi, 0x50(%rax)
cmpl $0x0, 0x4(%rdx,%rcx,4)
jns 0x7ce1
movl $0x0, 0x64(%rax)
movl $0x0, 0x4c(%rax)
movslq 0x60(%rax), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, 0x60(%rax)
leaq 0x11546(%rip), %rsi     # 0x19240
xorl %edi, %edi
cmpl $0x0, 0x4(%rsi,%rcx,4)
cmovnsl %edx, %edi
movl (%rsi,%rcx,4), %ecx
movl %edi, 0x60(%rax)
movl %ecx, 0x5c(%rax)
testl %ecx, %ecx
je 0x7d2c
movl 0x4c(%rax), %edx
leal (,%rdx,8), %esi
subl %ecx, %esi
addl $0x8, %esi
movl %esi, 0x54(%rax)
leal 0x7(,%rdx,8), %ecx
jmp 0x7d38
movl $0xffffffff, 0x54(%rax) # imm = 0xFFFFFFFF
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl %ecx, 0x58(%rax)
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcLockTime(CapsFdc*)
void FdcLockTime(PCAPSFDC pc)
{
	PCAPSDRIVE pd=pc->driveprc;
	int lo=0;
	int hi=pd->tracklen-1;
	UDWORD sum=pd->timebuf[hi];

	// binary search for the nearest item to the actual clock distance
	while (lo <= hi) {
		int mid=(lo+hi)/2;
		UDWORD atm=UDWORD(((UQUAD)pd->timebuf[mid]*pd->clockrev)/sum);

		if (atm <= pd->idistance)
			lo=mid+1;
		else
			hi=mid-1;
	}

	// safety check can only happen if distance was >= clockrev
	if ((unsigned)lo >= pd->tracklen)
		lo=pd->tracklen-1;

	UDWORD base=lo ? pd->timebuf[lo-1] : 0;
	UDWORD diff=pd->timebuf[lo]-base;

	// linear search for nearest distance
	for (hi=1; hi < 8; hi++) {
		UDWORD atm=UDWORD(((UQUAD)(base+(hi*diff)/8)*pd->clockrev)/sum);
		if (pd->idistance < atm)
			break;
	}

	pc->datalock=lo*8+hi-1;
	pc->datacycle=base;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq 0x100(%rdi), %r9
movl 0x48(%r9), %r11d
leal -0x1(%r11), %ecx
movq 0x40(%r9), %r10
movslq %ecx, %rax
movl (%r10,%rax,4), %r8d
xorl %esi, %esi
movl $0x0, %ebx
testl %eax, %eax
js 0x7da1
movl 0x24(%r9), %ebp
movl 0x28(%r9), %r14d
xorl %ebx, %ebx
movl %ecx, %r15d
leal (%rbx,%r15), %r12d
shrl %r12d
movl (%r10,%r12,4), %eax
imulq %r14, %rax
xorl %edx, %edx
divq %r8
cmpl %eax, %ebp
jb 0x7d96
incl %r12d
movl %r12d, %ebx
jmp 0x7d9c
decl %r12d
movl %r12d, %r15d
cmpl %r15d, %ebx
jle 0x7d76
cmpl %r11d, %ebx
cmovbl %ebx, %ecx
testl %ecx, %ecx
je 0x7db5
movslq %ecx, %rax
movl -0x4(%r10,%rax,4), %esi
jmp 0x7db7
xorl %eax, %eax
movl (%r10,%rax,4), %r10d
subl %esi, %r10d
movl 0x24(%r9), %r11d
movl 0x28(%r9), %ebx
movl $0x1, %r9d
movl %r10d, %ebp
movl %ebp, %eax
shrl $0x3, %eax
addl %esi, %eax
imulq %rbx, %rax
xorl %edx, %edx
divq %r8
cmpl %eax, %r11d
jb 0x7df6
incl %r9d
addl %r10d, %ebp
cmpl $0x8, %r9d
jne 0x7dcf
movl $0x8, %r9d
leal (%r9,%rcx,8), %eax
decl %eax
movl %eax, 0x80(%rdi)
movl %esi, 0x88(%rdi)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFDCEmulator.cpp
// Function: FdcComReadNoise(CapsFdc*)
int FdcComReadNoise(PCAPSFDC pc)
{
	// clear dsr signals
	pc->aminfo&=~(CAPSFDC_AI_DSRREADY|CAPSFDC_AI_DSRAM|CAPSFDC_AI_DSRMA1);

	// get selected drive
	PCAPSDRIVE pd=pc->driveprc;

	// all cycles possibly advanced this time
	UDWORD dist=pd->idistance+(pc->clockreq-pc->clockact);

	// next bit complete divident, increased by clockrev
	UQUAD nextccn=(UQUAD)(pc->datalock+1)*pd->clockrev;

	// process until broken
	while (true) {
		// next bit is complete at this disk cycle
		UDWORD nextcyc=UDWORD(nextccn/pd->trackbits);

		// if not enough time to read bit, return
		if (dist < nextcyc) {
			pd->idistance=dist;
			pc->clockact=pc->clockreq;
			return 0;
		}

		// read bit into shifter
		FdcShiftBit(pc);

		// next bit
		pc->datalock++;
		nextccn+=pd->clockrev;

		// if index reached
		if (nextcyc >= pd->clockrev) {
			// adjust to index position
			dist-=pd->clockrev;
			pc->clockact+=pd->clockrev-pd->idistance;
			pd->idistance=0;
			pc->datalock=0;
			nextccn=pd->clockrev;

			// process disk index
			FdcIndex(pc, pc->driveact);

			// we read a complete byte exactly at index, set flag
			if (pc->aminfo & pc->amisigmask)
				return 1;

			// stop on end
			if (pc->endrequest)
				return 0;
		}

		// if a byte is complete, break and signal new byte
		if (pc->aminfo & pc->amisigmask) {
			int dst=pd->idistance;
			pd->idistance=nextcyc;
			pc->clockact+=nextcyc-dst;
			return 1;
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
andb $-0x8, 0x61(%rdi)
movq 0x100(%rdi), %r12
movl 0x10(%rdi), %ebp
addl 0x24(%r12), %ebp
subl 0xc(%rdi), %ebp
movslq 0x80(%rdi), %rax
incq %rax
movl 0x28(%r12), %r13d
imulq %rax, %r13
movq %r13, %r14
movslq 0x50(%r12), %rcx
movq %r14, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %r15
cmpl %r15d, %ebp
jb 0x7f09
movq %rbx, %rdi
callq 0x81b5
incl 0x80(%rbx)
movl 0x28(%r12), %r13d
cmpl %r15d, %r13d
jbe 0x7ecc
addq %r13, %r14
movl 0x64(%rbx), %eax
testl %eax, 0x60(%rbx)
je 0x7e92
jmp 0x7f15
movl 0x24(%r12), %eax
movl %r13d, %ecx
subl %eax, %ecx
addl %ecx, 0xc(%rbx)
xorl %eax, %eax
movl %eax, 0x24(%r12)
movl %eax, 0x80(%rbx)
movl 0xfc(%rbx), %esi
movq %rbx, %rdi
callq 0x7ac2
movl 0x64(%rbx), %eax
testl %eax, 0x60(%rbx)
jne 0x7f3c
subl %r13d, %ebp
cmpl $0x0, 0x8(%rbx)
je 0x7e8f
xorl %eax, %eax
jmp 0x7f2d
movl %ebp, 0x24(%r12)
movl 0x10(%rbx), %ecx
xorl %eax, %eax
jmp 0x7f2a
movl %r15d, %ecx
subl 0x24(%r12), %ecx
movl %r15d, 0x24(%r12)
addl 0xc(%rbx), %ecx
movl $0x1, %eax
movl %ecx, 0xc(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %eax
jmp 0x7f2d
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFile.cpp
// Function: CCapsFile::Close()
int CCapsFile::Close()
{
	int res=0;

	if (file) {
		res = file->Close();
		delete file;
		file = NULL;
	}

	return res;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0x8506
movq (%rdi), %rax
callq *0x10(%rax)
movl %eax, %ebp
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x84fc
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x8(%rbx)
jmp 0x8508
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFile.cpp
// Function: CCapsFile::Open(CapsFile*)
int CCapsFile::Open(PCAPSFILE pcf)
{
	int res=true;

	Close();

	if (!pcf)
		return res;

	if (pcf->flag & CFF_MEMMAP) {
		PCMEMORYFILE f = new CMemoryFile();
		file = f;
		int mode = (pcf->flag & CFF_MEMREF) ? 0 : BFFLAG_CREATE;
		res=f->Open(pcf->memmap, pcf->size, mode);
	}	else {
		PCDISKFILE f = new CDiskFile();
		file = f;
		int fm = (pcf->flag & CFF_WRITE) ? BFFLAG_WRITE : 0;
		if (pcf->flag & CFF_CREATE)
			fm |= BFFLAG_CREATE;
		res = f->Open(pcf->name, fm);
	}

	return res;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0x855b
movq (%rdi), %rax
callq *0x10(%rax)
movq 0x8(%r14), %rdi
testq %rdi, %rdi
je 0x8553
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x8(%r14)
testq %rbx, %rbx
je 0x859f
testb $0x2, 0x10(%rbx)
jne 0x85aa
movl $0x228, %edi            # imm = 0x228
callq 0x4200
movq %rax, %r15
movq %rax, %rdi
callq 0xdf88
movq %r15, 0x8(%r14)
movl 0x10(%rbx), %edx
movl %edx, %eax
andl $0x1, %eax
shrl $0x2, %edx
andl $0x2, %edx
orl %eax, %edx
movq (%rbx), %rsi
movq %r15, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0xdfe8
movl $0x1, %eax
popq %rbx
popq %r14
popq %r15
retq
movl $0x48, %edi
callq 0x4200
movq %rax, %r15
movq %rax, %rdi
callq 0xf738
movq %r15, 0x8(%r14)
movl 0x10(%rbx), %ecx
notl %ecx
shrl %ecx
andl $0x2, %ecx
movq 0x8(%rbx), %rsi
movslq 0x14(%rbx), %rdx
movq %r15, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0xf836
movq %rax, %rbx
movl $0x48, %esi
jmp 0x85f4
movq %rax, %rbx
movl $0x228, %esi            # imm = 0x228
movq %r15, %rdi
callq 0x4210
movq %rbx, %rdi
callq 0x43a0
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: CAPSFormatDataToMFM(void*, unsigned int)
SDWORD __cdecl CAPSFormatDataToMFM(PVOID pformattrack, UDWORD flag)
{
	if (!pformattrack)
		return imgeGeneric;

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

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

	PCAPSFORMATTRACK pf=(PCAPSFORMATTRACK)pformattrack;

	// if buffer not set, return the required buffer size
	if (!pf->trackbuf || !pf->tracklen || !pf->buflen)
		return FmfmGetSize(pf);

	// track buffer should not exceed allocated memory
	if (pf->tracklen > pf->buflen)
		return imgeBufferShort;

	// calculate track size and check descriptors
	int res=FmfmGetSize(pf);

	// cancel if track definition error
	if (res != imgeOk)
		return res;

	// cancel if track size too short
	if (pf->tracklen < pf->bufreq)
		return imgeBufferShort;

	// error if data start position is invalid
	if (pf->startpos >= pf->tracklen)
		return imgeBadDataStart;

	// convert the data
	return FmfmConvert(pf);
}

// Assembly:
pushq %rbx
testq %rdi, %rdi
je 0x86d6
movq %rdi, %rbx
btl $0x9, %esi
jae 0x8689
cmpl $0x0, (%rbx)
je 0x8689
movl $0x0, (%rbx)
movl $0xf, %eax
jmp 0x86db
cmpq $0x0, 0x10(%rbx)
je 0x86dd
movl 0x18(%rbx), %ecx
testl %ecx, %ecx
je 0x86dd
movl 0x1c(%rbx), %edx
testl %edx, %edx
je 0x86dd
movl $0x13, %eax
cmpl %edx, %ecx
ja 0x86db
movq %rbx, %rdi
callq 0x86e6
testl %eax, %eax
jne 0x86db
movl 0x18(%rbx), %ecx
movl $0x13, %eax
cmpl 0x20(%rbx), %ecx
jb 0x86db
movl $0x12, %eax
cmpl %ecx, 0x24(%rbx)
jae 0x86db
movq %rbx, %rdi
callq 0x877c
xorl %eax, %eax
jmp 0x86db
movl $0x2, %eax
popq %rbx
retq
movq %rbx, %rdi
popq %rbx
jmp 0x86e6
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmConvert(CapsFormatTrack*)
int FmfmConvert(PCAPSFORMATTRACK pf)
{
	// reset size
	pf->size=0;

	// reset size counter and mfm state
	UDWORD state=(0)<<15 ^ 0xffff;

	// write index gap
	state=FmfmWriteDataByte(pf, state, pf->gapavalue, pf->gapacnt);

	// process all blocks
	for (int blk=0; blk < pf->blockcnt; blk++) {
		// get block
		PCAPSFORMATBLOCK pb=pf->block+blk;

		// write block data
		switch (pb->blocktype) {
			// index block; 3am, fc,gap
			case cfrmbtIndex:
				state=FmfmWriteBlockIndex(pf, state, pb);
				break;

			// data block; 3am, fe, 4hdr, 2crc, 3am, fb, data, 2crc
			case cfrmbtData:
				state=FmfmWriteBlockData(pf, state, pb);
				break;
		}
	}

	// write gap size before index
	int gapbcnt=(pf->tracklen-pf->size)/2;
	if (gapbcnt > 0)
		state=FmfmWriteDataByte(pf, state, pf->gapbvalue, gapbcnt);

	return imgeOk;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movl $0x0, 0x34(%rdi)
movl 0x4(%rdi), %ecx
movl 0x8(%rdi), %edx
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x8822
cmpl $0x0, 0x28(%rbx)
jle 0x87e3
xorl %r14d, %r14d
xorl %r15d, %r15d
movq 0x2c(%rbx), %rdx
movl 0x20(%rdx,%r14), %ecx
addq %r14, %rdx
cmpl $0x2, %ecx
je 0x87c9
cmpl $0x1, %ecx
jne 0x87d3
movq %rbx, %rdi
movl %eax, %esi
callq 0x8892
jmp 0x87d3
movq %rbx, %rdi
movl %eax, %esi
callq 0x88e3
incq %r15
movslq 0x28(%rbx), %rcx
addq $0x40, %r14
cmpq %rcx, %r15
jl 0x87a7
movl 0x18(%rbx), %ecx
subl 0x34(%rbx), %ecx
cmpl $0x2, %ecx
jb 0x87fd
shrl %ecx
movl 0xc(%rbx), %edx
movq %rbx, %rdi
movl %eax, %esi
callq 0x8822
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmWriteDataByte(CapsFormatTrack*, unsigned int, unsigned int, int)
UDWORD FmfmWriteDataByte(PCAPSFORMATTRACK pf, UDWORD state, UDWORD value, int count)
{
	pf->size+=count*2;
	UDWORD pos=pf->startpos;

	// write mfm bytes
	while (count--) {
		UDWORD val=CDiskEncoding::mfmcode[value & 0xff] & state;
		state=(val & 1)<<15 ^ 0xffff;

		pf->trackbuf[pos++]=UBYTE(val>>8);
		if (pos >= pf->tracklen)
			pos=0;

		pf->trackbuf[pos++]=(UBYTE)val;
		if (pos >= pf->tracklen)
			pos=0;
	}

	pf->startpos=pos;

	return state;
}

// Assembly:
leal (%rcx,%rcx), %eax
addl %eax, 0x34(%rdi)
movl %esi, %eax
movl 0x24(%rdi), %r9d
testl %ecx, %ecx
je 0x888a
pushq %rbp
pushq %rbx
movzbl %dl, %edx
leaq 0x12d3a(%rip), %rsi     # 0x1b578
xorl %r8d, %r8d
movq (%rsi), %r10
andl (%r10,%rdx,4), %eax
movl %eax, %r11d
shll $0xf, %r11d
movq 0x10(%rdi), %rbx
movl %r9d, %ebp
incl %r9d
movb %ah, (%rbx,%rbp)
cmpl 0x18(%rdi), %r9d
cmovael %r8d, %r9d
movq 0x10(%rdi), %rbx
leal 0x1(%r9), %r10d
movb %al, (%rbx,%r9)
cmpl 0x18(%rdi), %r10d
cmovael %r8d, %r10d
notl %r11d
movzwl %r11w, %eax
movl %r10d, %r9d
decl %ecx
jne 0x8841
popq %rbx
popq %rbp
jmp 0x888d
movl %r9d, %r10d
movl %r10d, 0x24(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmWriteBlockIndex(CapsFormatTrack*, unsigned int, CapsFormatBlock*)
UDWORD FmfmWriteBlockIndex(PCAPSFORMATTRACK pf, UDWORD state, PCAPSFORMATBLOCK pb)
{
	// gap before first am
	state=FmfmWriteDataByte(pf, state, pb->gapavalue, pb->gapacnt);

	// 3 am c2/5224
	state=FmfmWriteMarkByte(pf, state, 0x5224, 3);

	// fc
	state=FmfmWriteDataByte(pf, state, 0xfc, 1);

	// gap after first am
	state=FmfmWriteDataByte(pf, state, pb->gapbvalue, pb->gapbcnt);

	return state;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rdi, %r14
movl (%rdx), %ecx
movl 0x4(%rdx), %edx
callq 0x8822
movq %r14, %rdi
movl $0x5224, %edx           # imm = 0x5224
movl $0x3, %ecx
callq 0x8b88
movq %r14, %rdi
movl %eax, %esi
movl $0xfc, %edx
movl $0x1, %ecx
callq 0x8822
movl 0x8(%rbx), %ecx
movl 0xc(%rbx), %edx
movq %r14, %rdi
movl %eax, %esi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x8822
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmWriteMarkByte(CapsFormatTrack*, unsigned int, unsigned int, int)
UDWORD FmfmWriteMarkByte(PCAPSFORMATTRACK pf, UDWORD state, UDWORD value, int count)
{
	pf->size+=count*2;
	UDWORD pos=pf->startpos;
	UDWORD val=value & 0xffff;
	state=(val & 1)<<15 ^ 0xffff;

	// write mfm bytes
	while (count--) {
		pf->trackbuf[pos++]=UBYTE(val>>8);
		if (pos >= pf->tracklen)
			pos=0;

		pf->trackbuf[pos++]=(UBYTE)val;
		if (pos >= pf->tracklen)
			pos=0;
	}

	pf->startpos=pos;

	return state;
}

// Assembly:
leal (%rcx,%rcx), %eax
addl %eax, 0x34(%rdi)
movl 0x24(%rdi), %esi
testl %ecx, %ecx
je 0x8bce
movl %edx, %eax
shrl $0x8, %eax
xorl %r8d, %r8d
movq 0x10(%rdi), %r9
movl %esi, %r10d
incl %esi
movb %al, (%r9,%r10)
cmpl 0x18(%rdi), %esi
cmovael %r8d, %esi
movq 0x10(%rdi), %r10
leal 0x1(%rsi), %r9d
movb %dl, (%r10,%rsi)
cmpl 0x18(%rdi), %r9d
cmovael %r8d, %r9d
movl %r9d, %esi
decl %ecx
jne 0x8b9d
jmp 0x8bd1
movl %esi, %r9d
shll $0xf, %edx
notl %edx
movzwl %dx, %eax
movl %r9d, 0x24(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsFormatMFM.cpp
// Function: FmfmCrc(unsigned short, unsigned int, int)
UWORD FmfmCrc(UWORD crc, UDWORD value, int count)
{
	value&=0xff;

	while (count--)
		crc=crctab_ccitt[value^(crc>>8)] ^ (crc << 8);

	return crc;
}

// Assembly:
movl %edi, %eax
testl %edx, %edx
je 0x8c02
movzbl %sil, %ecx
leaq 0x11501(%rip), %rsi     # 0x1a0f0
movzwl %ax, %edi
shrl $0x8, %edi
xorl %ecx, %edi
shll $0x8, %eax
xorw (%rsi,%rdi,2), %ax
decl %edx
jne 0x8bef
retq
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::CompareImage()
int CCapsImage::CompareImage()
{
	PDISKTRACKINFO pti=di.pdt;

	int res=imgeOk;

	// default track size
	pti->tracklen=pti->ci.trksize;

	// generate 1 revolution
	pti->trackcnt=1;

	// unformatted track ignored
	if (pti->ci.dentype == cpdenNoise)
		pti->trackcnt=0;

	pti->tracklen*=pti->trackcnt;

	// allocate and set buffer
	if (pti->tracklen) {
		pti->trackbuf=new UBYTE[pti->tracklen];
		memset(pti->trackbuf, 0, pti->tracklen);
	}

	// set track size and pointer
	pti->trackdata[0]=pti->trackbuf;
	pti->tracksize[0]=0;
	pti->trackstart[0]=0;

	// decoder start position is always 0
	pti->comppos=0;
	pti->sdpos=0;

	// decode blocks
	if (pti->trackcnt) {
		int eblk=pti->compeblk;
		if (eblk < 0)
			eblk=pti->ci.blkcnt;
		else
			eblk++;

		for (int blk=pti->compsblk; blk < eblk; blk++)
			if ((res=CompareBlock(blk)) != imgeOk)
				return res;
	}

	pti->tracksize[0]=pti->comppos;
	return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x210(%rdi), %r12
movl 0x108(%r12), %r13d
xorl %eax, %eax
xorl %ecx, %ecx
cmpl $0x1, %r13d
setne %cl
movl %ecx, 0x28(%r12)
je 0x8c3b
movl 0x110(%r12), %eax
movl %eax, 0x50(%r12)
testl %eax, %eax
je 0x8c66
movslq %eax, %r15
movq %r15, %rdi
callq 0x4040
movq %rax, %r14
movq %rax, 0x48(%r12)
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x4140
jmp 0x8c6b
movq 0x48(%r12), %r14
xorl %ebp, %ebp
movq %r14, 0x58(%r12)
movl %ebp, 0x80(%r12)
movl %ebp, 0x94(%r12)
movq $0x0, 0xbc(%r12)
movl $0x0, %eax
cmpl $0x1, %r13d
je 0x8cdf
movl 0xcc(%r12), %r15d
testl %r15d, %r15d
js 0x8cab
incl %r15d
jmp 0x8cb3
movl 0x128(%r12), %r15d
movl 0xc8(%r12), %r14d
cmpl %r15d, %r14d
jge 0x8cdf
movq %rbx, %rdi
movl %r14d, %esi
callq 0x8cfc
testl %eax, %eax
jne 0x8cf8
incl %r14d
cmpl %r14d, %r15d
jne 0x8cc0
movl 0xbc(%r12), %eax
movl %eax, 0x80(%r12)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %ebp
jmp 0x8ce7
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::DecompressDump()
int CCapsImage::DecompressDump()
{
	// raw images can't be: compared, 16 bit aligned
	if (di.flag & (DI_LOCK_COMP | DI_LOCK_ALIGN))
		return imgeUnsupported;

	PDISKTRACKINFO pti = di.pdt;
	uint8_t *buf=di.data;

	CCTRawCodec ctr;

	// decompress data
	int res=ctr.DecompressDump(buf, pti->datasize);
	if (res == imgeOk) {
		ConvertDumpInfo(ctr.GetInfo());
	} else
		pti->type=dtitError;

	return res;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movl $0x1, %ebx
testl $0x80000002, 0x208(%rdi) # imm = 0x80000002
jne 0x9014
movq %rdi, %r14
movq 0x1e8(%rdi), %rbx
movq 0x210(%rdi), %r12
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x515c
movl 0x24(%r12), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x533c
movl %eax, %ebx
testl %eax, %eax
je 0x8ffd
movl $0x1, (%r12)
jmp 0x900a
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x903a
leaq 0x8(%rsp), %rdi
callq 0x5186
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x5186
movq %rbx, %rdi
callq 0x43a0
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::InitFirstBitTables()
void CCapsImage::InitFirstBitTables()
{
	// stop if already initialized
	if (fb_init)
		return;

	// initialize only once
	fb_init = 1;

	// process all positions
	for (int startbit = 0; startbit < 8; startbit++) {
		// position#0 is bit#7...position#7 is bit#0
		int bitmask = 1 << (7-startbit);

		// process all values
		for (int value = 0; value < 256; value++) {

			// find the first 0 bit starting with the current position
			int bitpos = startbit;
			for (int bm = bitmask; bm; bm >>= 1, bitpos++) {
				if (!(value & bm))
					break;
			}

			// store the position; 8 means not found
			f0b_table[startbit][value] = bitpos;

			// find the first 1 bit starting with the current position
			bitpos = startbit;
			for (int bm = bitmask; bm; bm >>= 1, bitpos++) {
				if (value & bm)
					break;
			}

			// store the position; 8 means not found
			f1b_table[startbit][value] = bitpos;
		}
	}
}

// Assembly:
cmpl $0x0, 0x1136b(%rip)     # 0x1a544
je 0x91dc
retq
pushq %rbx
movl $0x1, 0x1135d(%rip)     # 0x1a544
xorl %eax, %eax
leaq 0x11360(%rip), %rdx     # 0x1a550
leaq 0x11b59(%rip), %rsi     # 0x1ad50
movb $0x7, %cl
subb %al, %cl
movl $0x1, %edi
shll %cl, %edi
movq %rax, %rcx
shlq $0x8, %rcx
leaq (%rdx,%rcx), %r8
addq %rsi, %rcx
xorl %r9d, %r9d
movl %eax, %r10d
movl %edi, %r11d
testl %r9d, %edi
je 0x9237
shrl %r11d
incb %r10b
testl %r9d, %r11d
jne 0x921e
movb %r10b, (%r9,%r8)
movl %eax, %r10d
testl %r9d, %edi
jne 0x9255
jmp 0x923b
movb %al, (%r9,%r8)
movl %edi, %r11d
movl %eax, %r10d
incl %r10d
cmpl $0x2, %r11d
jb 0x9255
shrl %r11d
movl %r11d, %ebx
andl %r9d, %ebx
je 0x9241
movb %r10b, (%r9,%rcx)
incq %r9
cmpq $0x100, %r9             # imm = 0x100
jne 0x9213
incq %rax
cmpq $0x8, %rax
jne 0x91f7
popq %rbx
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::UpdateDump()
int CCapsImage::UpdateDump()
{
	PDISKTRACKINFO pti = di.pdt;

	// get actual revolution number, restart after the last revolution
	int rev = dii.nextrev % pti->rawtrackcnt;

	// true if all the available revolutions should be returned
	int allrev = (pti->trackcnt == pti->rawtrackcnt);

	// if all revolutions used the used data must be revolution#0
	if (allrev)
		rev = 0;

	// save the real revolution number
	dii.realrev = rev;

	// set data buffer
	pti->trackbuf = pti->trackdata[rev];
	pti->tracklen = allrev ? pti->rawlen : pti->tracksize[rev];
	pti->trackbc = pti->tracklen << 3;
	pti->singletrackbc = pti->trackbc;

	// timing information is the same size as the current data, rev#0 for all revolutions
	pti->timecnt = pti->tracksize[rev];

	// the real size of the sampled timings
	int rawsize = pti->rawtimecnt;

	// the amount of timing to be copied track size or real size - whichever is shorter
	int tsize = std::min(rawsize, pti->timecnt);

	// copy the timing
	memcpy(pti->timebuf, pti->rawtimebuf, tsize*sizeof(UDWORD));

	// If sampled timing is shorter, fill the remaining area with 1000, default value
	// This does not change the average, since the previous data adds up to an average of 1000
	int pos;
	for (pos = tsize; pos < pti->timecnt; pos++) {
			pti->timebuf[pos] = 1000;
	}

	// reset alternate density
	pti->timebuf[pos] = 0;

	// density map conversion
	if (di.flag & DI_LOCK_DENALT)
		ConvertDensity(pti);

	UpdateImage(rev);

	return imgeOk;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x210(%rdi), %r14
movl 0x3c(%rdi), %eax
movl 0x28(%r14), %ecx
movl 0x2c(%r14), %esi
cltd
idivl %esi
xorl %ebp, %ebp
cmpl %esi, %ecx
cmovnel %edx, %ebp
leaq 0x30(%r14), %rax
movl %ebp, 0x44(%rdi)
movslq %ebp, %rcx
movq 0x58(%r14,%rcx,8), %rdx
movq %rdx, 0x48(%r14)
leaq 0x80(%r14,%rcx,4), %rcx
cmovneq %rcx, %rax
movl (%rax), %eax
movl %eax, 0x50(%r14)
shll $0x3, %eax
movl %eax, 0xe8(%r14)
movl %eax, 0xec(%r14)
movl (%rcx), %r12d
movl %r12d, 0xa8(%r14)
movl 0x34(%r14), %r13d
cmpl %r13d, %r12d
movl %r13d, %eax
cmovll %r12d, %eax
movq 0xb0(%r14), %rdi
movq 0x38(%r14), %rsi
movslq %eax, %r15
leaq (,%r15,4), %rdx
callq 0x4190
movq 0xb0(%r14), %rax
cmpl 0xa8(%r14), %r15d
jge 0x94fb
cmpl %r13d, %r12d
cmovll %r12d, %r13d
movslq %r13d, %rcx
movq %rcx, %r15
shlq $0x20, %r15
movabsq $0x100000000, %rdx      # imm = 0x100000000
addq %rdx, %r15
movl $0x3e8, (%rax,%rcx,4)   # imm = 0x3E8
incq %rcx
movslq 0xa8(%r14), %rsi
cmpq %rsi, %rcx
jl 0x94de
sarq $0x20, %r15
movl $0x0, (%rax,%r15,4)
testb $0x4, 0x209(%rbx)
je 0x9517
movq %rbx, %rdi
movq %r14, %rsi
callq 0xb36a
movq %rbx, %rdi
movl %ebp, %esi
callq 0x9ca2
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::AddWeakBitArea(int, int, int)
void CCapsImage::AddWeakBitArea(int group, int bitpos, int size)
{
	DiskDataMark ddm;
	ddm.group = group;
	ddm.position = bitpos;
	ddm.size = size;
	AddFD(di.pdt, &ddm, 1, (CAPS_MTRS * DEF_CTRAW_FDALLOC));
}

// Assembly:
subq $0x18, %rsp
leaq 0xc(%rsp), %rax
movl %esi, (%rax)
movl %edx, 0x4(%rax)
movl %ecx, 0x8(%rax)
movq 0x210(%rdi), %rdi
movq %rax, %rsi
movl $0x1, %edx
movl $0x140, %ecx            # imm = 0x140
callq 0xf1de
addq $0x18, %rsp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::InitSystem()
void CCapsImageStd::InitSystem()
{
	// set bitfield write length supported
	maxwritelen = MAX_BITBUFFER_LEN;

	// keep number of bits to read at maximum supported by streaming for raw encoding
	rawreadlen=MAX_STREAMBIT;

	// initialize mfm encoding tables
	CDiskEncoding::InitMFM(0x10000);

	// keep number of bits to read at maximum supported by mfm encoding
	mfmreadlen=CDiskEncoding::mfmcodebit;

	// mfm encoding table index mask
	mfmindexmask=(1 << mfmreadlen)-1;

	// the mfm encoding table assumes the last bit to be 0, correct encoding if it's 1
	// 1: 1-01 -> 1-01 unchanged after AND, msb already 0
	// 0: 1-10 -> 1-00 AND clears msb
	mfmmsbclear=(1 << ((mfmreadlen*2)-1))-1;
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movabsq $0x2000000020, %rax     # imm = 0x2000000020
movq %rax, 0x218(%rdi)
movl $0x10000, %edi          # imm = 0x10000
callq 0xd6c4
leaq 0x11ec8(%rip), %rax     # 0x1b574
movl (%rax), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
movl %ecx, 0x220(%rbx)
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
addl %ecx, %ecx
decb %cl
shll %cl, %edx
notl %eax
movl %eax, 0x224(%rbx)
notl %edx
movl %edx, 0x228(%rbx)
popq %rbx
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::Lock(CapsFile*)
int CCapsImageStd::Lock(PCAPSFILE pcf)
{
	// release image data
	Unlock();

	// try to lock
	switch (loader.Lock(pcf)) {
		// file open error
		case CCapsLoader::ccidErrFile:
			return imgeOpen;

		// not a caps file
		case CCapsLoader::ccidErrType:
			return imgeType;

		// yes, caps file
		case CCapsLoader::ccidCaps:
			break;

		// unknown problem
		default:
			return imgeGeneric;
	}

	// store open mode
	dii.readonly=(pcf->flag & CFF_WRITE) ? 0 : 1;

	// scan whole file for information
	int res=ScanImage();
	if (res != imgeOk)
		return res;

	return CheckEncoder(dii.ci.encoder, dii.ci.encrev);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0xd0(%rbx), %rdi
movq %r14, %rsi
callq 0xced6
testl %eax, %eax
je 0x9803
cmpl $0x1, %eax
je 0x97fc
cmpl $0x2, %eax
jne 0x983d
movl $0x6, %eax
jmp 0x9842
movl $0x5, %eax
jmp 0x9842
movl 0x10(%r14), %eax
notl %eax
andl $0x1, %eax
movl %eax, 0x14(%rbx)
movq %rbx, %rdi
callq 0x985e
testl %eax, %eax
jne 0x9842
cmpl $0x0, 0x48(%rbx)
je 0x984a
movl 0x54(%rbx), %ecx
movl 0x50(%rbx), %edx
cmpl $0x2, %edx
je 0x984e
movl $0xe, %eax
cmpl $0x1, %edx
jne 0x9842
xorl %edx, %edx
cmpl $0x1, %ecx
jmp 0x9858
movl $0x2, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
xorl %eax, %eax
jmp 0x9842
xorl %edx, %edx
cmpl $0x1, %ecx
movl $0xe, %eax
cmovel %edx, %eax
jmp 0x9842
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::LoadTrack(DiskTrackInfo*, unsigned int)
int CCapsImageStd::LoadTrack(PDISKTRACKINFO pti, UDWORD flag)
{
	// set lock flags
	di.pdt=pti;
	di.flag=flag;

	int res = imgeOk;

	// update the track image if already available
	if (pti->trackcnt) {
		switch (pti->type) {
			case dtitCapsDump:
				res = UpdateDump();
				break;

			case dtitCapsImage:
				res = UpdateImage(0);
				break;

			default:
				res = imgeGeneric;
				break;
		}

		return res;
	}

	// process stored track data or generate data
	if (pti->datasize) {
		// load data, check data header
		loader.SetPosition(pti->datapos);
		if (loader.ReadChunk() == CCapsLoader::ccidData) {
			// allocate data buffer if needed
			AllocDiskData(pti->datasize);
			di.datacount=pti->datasize;

			// load and decode data
			if (loader.ReadData(di.data) == pti->datasize) {
				switch (pti->type) {
					case dtitCapsDump:
						res=DecompressDump();
						break;

					case dtitCapsImage:
						res=DecodeImage();
						break;

					default:
						res=imgeGeneric;
						break;
				}
			} else
				res=imgeGeneric;
		} else
			res=imgeGeneric;
	} else {
		// generate data
		switch (pti->type) {
			case dtitCapsImage:
				di.datacount=0;
				res=DecodeImage();
				break;

			default:
				res=imgeGeneric;
				break;
		}
	}

	return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, 0x210(%rdi)
movl %edx, 0x208(%rdi)
cmpl $0x0, 0x28(%rsi)
je 0x9bdf
movl (%r14), %eax
cmpl $0x3, %eax
je 0x9c60
movl $0x2, %ebp
cmpl $0x2, %eax
jne 0x9c95
movq (%rbx), %rax
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmpq *0x40(%rax)
cmpl $0x0, 0x24(%r14)
je 0x9c6e
leaq 0xd0(%rbx), %r15
movl 0x20(%r14), %esi
movq %r15, %rdi
callq 0xd2be
movq %r15, %rdi
xorl %esi, %esi
callq 0xcf7a
movl $0x2, %ebp
cmpl $0xa, %eax
jne 0x9c95
movl 0x24(%r14), %esi
movq %rbx, %rdi
callq 0x9d2c
movl 0x24(%r14), %eax
movl %eax, 0x1f4(%rbx)
movq 0x1e8(%rbx), %rsi
movq %r15, %rdi
callq 0xd1d8
cmpl 0x24(%r14), %eax
jne 0x9c95
movl (%r14), %eax
cmpl $0x3, %eax
je 0x9c83
cmpl $0x2, %eax
jne 0x9c95
movq (%rbx), %rax
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmpq *0x38(%rax)
xorl %ebp, %ebp
movq %rbx, %rdi
xorl %esi, %esi
callq 0x9ca2
jmp 0x9c95
movl $0x2, %ebp
cmpl $0x3, (%r14)
jne 0x9c95
movl $0x0, 0x1f4(%rbx)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9d82
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::UpdateImage(int)
int CCapsImageStd::UpdateImage(int group)
{
	int res=imgeOk;

	// set track buffer information
	di.track=di.pdt->trackbuf;
	di.trackbc=di.pdt->trackbc;
	di.singletrackbc=di.pdt->singletrackbc;
	trackbuf.InitBitSize(di.track, di.trackbc);
	
	// stop if track buffer is invalid
	if (!di.track || !di.trackbc || !di.singletrackbc)
		return imgeOk;

	// don't change track data if updates are disabled
	if (di.flag & DI_LOCK_NOUPDATE)
		return imgeOk;

	// update weak bit areas
	if (di.pdt->fdpsize && (di.flag & DI_LOCK_UPDATEFD))
		res=UpdateWeakBit(group);

	return res;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %ebx
movq %rdi, %r14
movq 0x210(%rdi), %rax
movq 0x48(%rax), %rsi
movq %rsi, 0x1b8(%rdi)
movq 0xe8(%rax), %rdx
movq %rdx, 0x1c0(%rdi)
addq $0xb8, %rdi
callq 0x4994
cmpq $0x0, 0x1b8(%r14)
je 0x9d22
cmpl $0x0, 0x1c0(%r14)
je 0x9d22
cmpl $0x0, 0x1c4(%r14)
je 0x9d22
movl 0x208(%r14), %eax
btl $0xd, %eax
jb 0x9d22
btl $0x8, %eax
jae 0x9d22
movq 0x210(%r14), %rax
cmpl $0x0, 0xd0(%rax)
je 0x9d22
movq %r14, %rdi
movl %ebx, %esi
callq 0x9ddc
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::AllocDiskData(int)
void CCapsImageStd::AllocDiskData(int maxsize)
{
	if (di.datasize < maxsize) {
		FreeDiskData();

		di.data=new uint8_t[maxsize];
		di.datasize=maxsize;
	}
}

// Assembly:
cmpl %esi, 0x1f0(%rdi)
jge 0x9d81
pushq %rbp
pushq %r14
pushq %rbx
movl %esi, %ebp
movq %rdi, %rbx
movq $0x0, 0x1f0(%rdi)
movq 0x1e8(%rdi), %rdi
testq %rdi, %rdi
je 0x9d59
callq 0x4280
movq $0x0, 0x1e8(%rbx)
movslq %ebp, %r14
movq %r14, %rdi
callq 0x4040
movq %rax, 0x1e8(%rbx)
movl %r14d, 0x1f0(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::DecodeImage()
int CCapsImageStd::DecodeImage()
{
	// initialize disk and track data used by decoder
	int res=InitDecoder();

	// run supported encoders only
	if (res == imgeOk) {
		switch (dii.ci.encoder) {
			case CAPS_ENCODER:
			case SPS_ENCODER:
				res=ProcessImage();
				break;

			default:
				res=imgeIncompatible;
				break;
		}
	}

	// if any error destroy track buffers and supress later calls
	if (res != imgeOk) {
		FreeTrack(di.pdt, 1);
		di.pdt->type=dtitError;
	}

	return res;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
callq 0x9f5e
testl %eax, %eax
je 0x9d95
movl %eax, %ebp
jmp 0x9db4
movl 0x50(%rbx), %eax
decl %eax
movl $0xe, %ebp
cmpl $0x1, %eax
ja 0x9db4
movq %rbx, %rdi
callq 0xa078
testl %eax, %eax
jne 0x9d91
xorl %ebp, %ebp
jmp 0x9dd2
movq 0x210(%rbx), %rdi
movl $0x1, %esi
callq 0xe8dc
movq 0x210(%rbx), %rax
movl $0x1, (%rax)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::UpdateWeakBit(int)
int CCapsImageStd::UpdateWeakBit(int group)
{
	// don't change track data if updates are disabled
	if (di.flag & DI_LOCK_NOUPDATE)
		return imgeOk;

	// get random seed
	uint32_t seed=di.pdt->wseed;

	// update all areas marked
	for (int pos=0; pos < di.pdt->fdpsize; pos++) {
		PDISKDATAMARK pd=di.pdt->fdp+pos;

		// skip markers that belong to a different group
		if (pd->group != group)
			continue;

		uint32_t bitpos=pd->position;
		int bitcnt=pd->size;

		// write generated data
		while (bitcnt > 0) {
			// simple random generator
			seed<<=1;
			if ((seed>>22 ^ seed) & DF_1)
				seed++;

			// write largest possible bitfield
			int writebc=(bitcnt >= maxwritelen) ? maxwritelen : bitcnt;

			// write bitfield
			trackbuf.WriteBitWrap(bitpos, seed, writebc);

			// next write position
			bitcnt-=writebc;
			bitpos+=writebc;

			// handle track buffer wrap around (disk rotation)
			if (bitpos >= di.trackbc)
				bitpos-=di.trackbc;
		}
	}

	// save random seed, so any new update on the same track would give new results
	di.pdt->wseed=seed;

	return imgeOk;
}

// Assembly:
testb $0x20, 0x209(%rdi)
jne 0x9ec1
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r14
movq 0x210(%rdi), %rax
movl 0xc4(%rax), %ebx
cmpl $0x0, 0xd0(%rax)
jle 0x9ead
xorl %ebp, %ebp
movl %esi, 0x4(%rsp)
movq 0xd8(%rax), %rcx
leaq (,%rbp,2), %rdx
addq %rbp, %rdx
cmpl %esi, (%rcx,%rdx,4)
jne 0x9e9a
leaq (%rcx,%rdx,4), %rcx
movl 0x8(%rcx), %r13d
testl %r13d, %r13d
jle 0x9e9a
movl 0x4(%rcx), %r15d
movl %ebx, %eax
shrl $0x16, %eax
xorl %ebx, %eax
andl $0x1, %eax
leal (%rax,%rbx,2), %ebx
movl 0x218(%r14), %r12d
cmpl %r12d, %r13d
cmovll %r13d, %r12d
movq 0xc0(%r14), %rdi
movl 0xcc(%r14), %esi
movl %r15d, %edx
movl %ebx, %ecx
movl %r12d, %r8d
callq 0x4a6a
xorl %ecx, %ecx
addl %r12d, %r15d
movl 0x1c0(%r14), %eax
cmpl %eax, %r15d
cmovbl %ecx, %eax
subl %eax, %r15d
subl %r12d, %r13d
jg 0x9e3f
movq 0x210(%r14), %rax
movl 0x4(%rsp), %esi
incq %rbp
movslq 0xd0(%rax), %rcx
cmpq %rcx, %rbp
jl 0x9e17
movl %ebx, 0xc4(%rax)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
xorl %eax, %eax
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::UpdateOverlap()
void CCapsImageStd::UpdateOverlap()
{
	// don't change track data if updates are disabled
	if (di.flag & DI_LOCK_NOUPDATE)
		return;

	// stop if no bits to change
	int ovlsize=CIMG_OVERLAPBIT;
	if (ovlsize <= 0)
		return;

	// stop if overlap position is not available
	if (di.pdt->overlapbit < 0)
		return;

	uint32_t bitpos=di.pdt->overlapbit;

	// flip all bits at the overlap position for all tracks
	for (int trk=0; trk < di.pdt->trackcnt; trk++) {
		uint32_t value=trackbuf.ReadBitWrap(bitpos, ovlsize);
		value=~value;
		trackbuf.WriteBitWrap(bitpos, value, ovlsize);

		// next track
		bitpos+=di.singletrackbc;

		// handle track buffer wrap around (disk rotation)
		if (bitpos >= di.trackbc)
			bitpos-=di.trackbc;
	}
}

// Assembly:
testb $0x20, 0x209(%rdi)
jne 0x9f5d
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x210(%rdi), %rax
movl 0xe4(%rax), %ebp
testl %ebp, %ebp
js 0x9f53
cmpl $0x0, 0x28(%rax)
jle 0x9f53
xorl %r14d, %r14d
xorl %r15d, %r15d
movq 0xc0(%rbx), %rdi
movl 0xcc(%rbx), %esi
movl %ebp, %edx
movl $0x3, %ecx
callq 0x49a6
notl %eax
movq 0xc0(%rbx), %rdi
movl 0xcc(%rbx), %esi
movl %ebp, %edx
movl %eax, %ecx
movl $0x3, %r8d
callq 0x4a6a
addl 0x1c4(%rbx), %ebp
movl 0x1c0(%rbx), %eax
cmpl %eax, %ebp
cmovbl %r14d, %eax
subl %eax, %ebp
incl %r15d
movq 0x210(%rbx), %rax
cmpl 0x28(%rax), %r15d
jl 0x9ef8
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::InitDecoder()
int CCapsImageStd::InitDecoder()
{
	// stop if image descriptor is not available
	if (!dii.civalid)
		return imgeIncompatible;

	// allocate and create block descriptors
	AllocImageBlock(di.pdt->ci.blkcnt);
	di.blockcount=di.pdt->ci.blkcnt;

	int blk;

	// initialize block descriptors from image data
	for (blk=0; blk < di.blockcount; blk++) {
		int res=GetBlock(di.block+blk, blk);
		if (res != imgeOk)
			return res;
	}

	// reset track info
	di.dsctrackbc=0;
	di.dscdatabc=0;
	di.dscgapbc=0;
	di.dscstartbit=0;

	// calculate data and gap sizes
	for (blk=0; blk < di.blockcount; blk++) {
		PIMAGEBLOCKINFO pi=di.block+blk;

		// only allow gap size of 1 byte or more
		if (pi->gapbits < 8)
			pi->gapbits=0;

		di.dscdatabc+=pi->blockbits;
		di.dscgapbc+=pi->gapbits;
	}

	// track size
	di.dsctrackbc=di.dscdatabc+di.dscgapbc;

	// set encoding start position, limit to track size
	if (di.dsctrackbc)
		di.dscstartbit=di.pdt->ci.startbit % di.dsctrackbc;

	return imgeOk;
}

// Assembly:
cmpl $0x0, 0x48(%rdi)
je 0xa04c
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x210(%rdi), %rax
movl 0x128(%rax), %esi
callq 0xb3ca
movq 0x210(%rbx), %rax
movl 0x128(%rax), %eax
movl %eax, 0x204(%rbx)
testl %eax, %eax
jle 0xa053
xorl %r15d, %r15d
xorl %r14d, %r14d
movq 0x1f8(%rbx), %rsi
addq %r15, %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0xb462
testl %eax, %eax
jne 0xa06e
incq %r14
movslq 0x204(%rbx), %rcx
addq $0x28, %r15
cmpq %rcx, %r14
jl 0x9fa3
xorps %xmm0, %xmm0
movups %xmm0, 0x1c8(%rbx)
testl %ecx, %ecx
jle 0xa05d
movq 0x1f8(%rbx), %rax
shlq $0x3, %rcx
leaq (%rcx,%rcx,4), %rdx
xorl %edi, %edi
xorl %ecx, %ecx
xorl %esi, %esi
movl 0x4(%rax,%rdi), %r8d
cmpl $0x7, %r8d
ja 0xa00c
movl $0x0, 0x4(%rax,%rdi)
xorl %r8d, %r8d
addl %r8d, %esi
addl (%rax,%rdi), %ecx
addq $0x28, %rdi
cmpq %rdi, %rdx
jne 0x9ff6
movl %ecx, 0x1cc(%rbx)
movl %esi, 0x1d0(%rbx)
addl %ecx, %esi
movl %esi, 0x1c8(%rbx)
je 0xa06a
movq 0x210(%rbx), %rax
movl 0x118(%rax), %eax
xorl %ecx, %ecx
xorl %edx, %edx
divl %esi
movl %edx, 0x1d4(%rbx)
jmp 0xa070
movl $0xe, %ecx
jmp 0xa075
xorps %xmm0, %xmm0
movups %xmm0, 0x1c8(%rbx)
addq $0x1c8, %rbx            # imm = 0x1C8
movl $0x0, (%rbx)
xorl %ecx, %ecx
jmp 0xa070
movl %eax, %ecx
popq %rbx
popq %r14
popq %r15
movl %ecx, %eax
retq
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::ProcessBlock(int, unsigned int, int, int)
int CCapsImageStd::ProcessBlock(int blk, uint32_t bitpos, int datasize, int gapsize)
{
	int res;

	// set encoding parameters
	di.encbitpos=bitpos;
	di.encwritebc=0;
	di.encgsvalid=0;
	di.encgapsplit=0;

	// check parameters
	if (blk<0 || blk>=di.blockcount || datasize<0 || gapsize<0)
		return imgeGeneric;

	if (blk >= di.pdt->sipsize)
		return imgeGeneric;

	// set encoding information
	di.block[blk].fdenc=ibieNA;
	di.block[blk].fdbitpos=bitpos;

	PDISKSECTORINFO si=di.pdt->sip+blk;
	si->descdatasize=di.block[blk].blockbits;
	si->descgapsize=di.block[blk].gapbits;
	si->celltype=di.block[blk].celltype;
	si->enctype=di.block[blk].enctype;

	// create block data
	si->datastart=di.encbitpos;
	si->datasize=datasize;
	res=ProcessBlockData(blk, datasize);
	if (res != imgeOk)
		return res;

	// create gap data
	si->gapstart=di.encbitpos;
	si->gapsize=gapsize;
	res=ProcessBlockGap(blk, gapsize);
	if (res != imgeOk)
		return res;

	return imgeOk;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, 0x1d8(%rdi)
movq $0x0, 0x1dc(%rdi)
movl $0x0, 0x1e4(%rdi)
movl $0x2, %eax
testl %esi, %esi
js 0xa5ba
movl %r8d, %ebx
movl %esi, %ebp
movl %r8d, %esi
orl %ecx, %esi
js 0xa5ba
movq %rdi, %r14
cmpl %ebp, 0x204(%rdi)
jle 0xa5ba
movq 0x210(%r14), %rsi
cmpl %ebp, 0xf4(%rsi)
jle 0xa5ba
movq 0x1f8(%r14), %rax
movl %ebp, %edi
leaq (%rdi,%rdi,4), %r8
movl $0x0, 0x20(%rax,%r8,8)
movl %edx, 0x24(%rax,%r8,8)
movq 0xf8(%rsi), %r15
leaq (%rdi,%rdi,2), %r12
shlq $0x4, %r12
movq (%rax,%r8,8), %rsi
movq %rsi, (%r15,%r12)
movq 0xc(%rax,%r8,8), %rax
movq %rax, 0x28(%r15,%r12)
movl %edx, 0x10(%r15,%r12)
movl %ecx, 0x8(%r15,%r12)
movq %r14, %rdi
movl %ebp, %esi
movl %ecx, %edx
callq 0xc3e4
testl %eax, %eax
je 0xa5c3
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
addq %r12, %r15
movl 0x1d8(%r14), %eax
movl %eax, 0x14(%r15)
movl %ebx, 0xc(%r15)
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0xc462
nop
// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::MFMFixup()
void CCapsImageStd::MFMFixup()
{
	// process all blocks
	for (int blk=0; blk < di.blockcount; blk++) {
		PIMAGEBLOCKINFO pi=di.block+blk;

		// don't fix if not MFM
		if (pi->fdenc != ibieMFM)
			continue;

		// get bit before the first data bit written
		uint32_t lbp=(pi->fdbitpos ? pi->fdbitpos : di.trackbc)-1;
		int lv = trackbuf.ReadBit(lbp);

		// mfm encoding assumed the last bit to be 0; fix if it is 1
		if (lv)
			trackbuf.ClearBit(pi->fdbitpos, 1);
	}
}

// Assembly:
movl 0x204(%rdi), %eax
testl %eax, %eax
jle 0xa667
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movl $0x24, %r14d
xorl %r15d, %r15d
movq 0x1f8(%rbx), %rcx
cmpl $0x2, -0x4(%rcx,%r14)
jne 0xa653
movl (%rcx,%r14), %esi
movl %esi, %ecx
testl %esi, %esi
jne 0xa624
movl 0x1c0(%rbx), %ecx
decl %ecx
movq 0xc0(%rbx), %rdi
movl %ecx, %edx
shrl $0x3, %edx
movzbl (%rdi,%rdx), %edx
notb %cl
movzbl %cl, %ecx
andl $0x7, %ecx
btl %ecx, %edx
jae 0xa653
movl $0x1, %edx
callq 0x4c12
movl 0x204(%rbx), %eax
incq %r15
movslq %eax, %rcx
addq $0x28, %r14
cmpq %rcx, %r15
jl 0xa605
popq %rbx
popq %r14
popq %r15
retq