// File: /workspace/github_cpp_makefile_star2_O1/OpenFodder[P]SOS_Unpacker/SOS_Unpacker.cpp
// Function: GetSOSTracks(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
std::vector<std::string> GetSOSTracks(const std::string& pFilename) {
    CapsImageInfo CapsImageInfo;

    int CapsID = CAPSAddImage();

    // lock this image into the container
    auto ret = CAPSLockImage(CapsID, (PCHAR) pFilename.c_str());
    if (ret != imgeOk) {
		std::cout << "Bad Image: " << ret << "\n";
        CAPSRemImage(CapsID);
        return {};
    }

    // get some information about the image
    CAPSGetImageInfo(&CapsImageInfo, CapsID);
    CAPSLoadImage(CapsID, gCapsFlags);

    auto MaxTracks = (CapsImageInfo.maxcylinder - CapsImageInfo.mincylinder + 1) *  (CapsImageInfo.maxhead - CapsImageInfo.minhead + 1);

    std::vector<std::string> TrackBuffers;
    TrackBuffers.resize(MaxTracks);

    // Track 0 is standard Amiga DOS
    // Track 1 is unformatted
    // Track 2 is the first SOS track
    for (UDWORD Track = 2; Track < MaxTracks; ++Track) {
        std::string FullTrack;
        CapsTrackInfoT1 TrackInfo;
        TrackInfo.type = ctitNoise;

        // SOS has the sides inverted
        auto Data = CAPSLockTrack((PCAPSTRACKINFO)&TrackInfo, CapsID, Track / 2, (Track & 1) ? 0 : 1, gCapsFlags);
        
        FullTrack.resize(TrackInfo.tracklen / 8);
        memcpy((UWORD*)FullTrack.data(), TrackInfo.trackbuf, TrackInfo.tracklen / 8);
        tool_EndianSwap((UBYTE*)FullTrack.data(), FullTrack.size());

        UBYTE* Ptr = (UBYTE*)FullTrack.data();
        UBYTE* PtrEnd = (UBYTE*)FullTrack.data() + FullTrack.size();

        // Find the track start marker
        auto SkipBits = sectorFindSync(&Ptr, Ptr + FullTrack.size());
        if (SkipBits == -1) {
            std::cout << "Skipping Track " << Track << " (SYNC not found)\n";
            continue;
        }
        trackbuffer_shift_bits(&Ptr, SkipBits, (int)((PtrEnd - Ptr) / 2) - 8);

        UBYTE* PtrOdd = Ptr + 0x180c;
        if (PtrOdd > PtrEnd) {
            std::cout << "Skipping Track " << Track << "\n";
            continue;
        }
        SDWORD Checksum = sos_ReadUDWord(Ptr, PtrOdd);

        // Check for Sensible Software marker
        if (Checksum != 'SOS6') {
            std::cout << "Skipping Track " << Track << " (Invalid SOS6 Marker)\n";
            continue;
        }
        Checksum = -Checksum;
        Checksum += sos_ReadUDWord(Ptr, PtrOdd);
        Checksum -= sos_ReadUDWord(Ptr, PtrOdd);

        std::vector<UDWORD> TrackDecodedBuffer;
        for (int count = 0x1800 / 4 - 1; count >= 0; --count) {
            UDWORD NewData = sos_ReadUDWord(Ptr, PtrOdd);
            Checksum -= NewData;
            TrackDecodedBuffer.push_back(swapDWord(NewData));
        }

        if (Checksum) {
            std::cout << "Track " << Track << " has invalid checksum.\n";
        }

        // Track CRC Matches
        UBYTE* TrackData = (UBYTE*)TrackDecodedBuffer.data();
        tool_EndianSwap(TrackData, TrackDecodedBuffer.size() * 4);
        TrackBuffers[Track] = std::string((char*)TrackData, TrackDecodedBuffer.size() * 4);
    }

    CAPSUnlockAllTracks(CapsID);
    CAPSUnlockImage(CapsID);
    CAPSRemImage(CapsID);

    return TrackBuffers;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %rbx
movq %rdi, %r15
callq 0x5aeb
movl %eax, %ebp
movq (%rbx), %rsi
movl %eax, %edi
callq 0x5bdb
testl %eax, %eax
je 0xfd04
movl %eax, %ebx
movq 0x931c(%rip), %r14      # 0x18fd0
leaq 0x2735(%rip), %rsi      # 0x123f0
movl $0xb, %edx
movq %r14, %rdi
callq 0x4240
movq %r14, %rdi
movl %ebx, %esi
callq 0x4380
leaq 0x27c4(%rip), %rsi      # 0x1249d
movl $0x1, %edx
movq %rax, %rdi
callq 0x4240
movl %ebp, %edi
callq 0x5b87
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movq $0x0, 0x10(%r15)
movq %r15, %rax
jmp 0x10142
leaq 0xb0(%rsp), %r14
movq %r14, %rdi
movl %ebp, %esi
callq 0x5d7e
movl %ebp, %edi
movl $0x1b34, %esi           # imm = 0x1B34
callq 0x5d44
movl 0x10(%r14), %eax
movl 0x18(%r14), %ebx
subl 0xc(%r14), %eax
incl %eax
subl 0x14(%r14), %ebx
incl %ebx
imull %eax, %ebx
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movq $0x0, 0x10(%r15)
movq %r15, %rdi
movq %rbx, %rsi
movq %r15, 0x28(%rsp)
callq 0x10a7e
cmpl $0x3, %ebx
jb 0x10128
leaq 0x40(%rsp), %r14
movl %ebx, %r12d
movl $0x2, %ebx
movl %ebp, 0x54(%rsp)
movq %r12, 0x58(%rsp)
movq %r14, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
movb $0x0, 0x40(%rsp)
movl $0x1, 0x80(%rsp)
movl %ebx, %ecx
notl %ecx
movl %ebx, %edx
shrl %edx
andl $0x1, %ecx
leaq 0x80(%rsp), %rdi
movl %ebp, %esi
movl $0x1b34, %r8d           # imm = 0x1B34
callq 0x5ea6
movl 0x9c(%rsp), %esi
shrl $0x3, %esi
leaq 0x30(%rsp), %rdi
xorl %edx, %edx
callq 0x4090
movq 0x30(%rsp), %rdi
movq 0x94(%rsp), %rsi
movl 0x9c(%rsp), %edx
shrl $0x3, %edx
callq 0x4190
movq 0x38(%rsp), %rax
cmpq $0x2, %rax
jb 0xfe09
movq 0x30(%rsp), %rcx
shrq %rax
xorl %edx, %edx
rolw $0x8, (%rcx,%rdx,2)
incq %rdx
cmpq %rdx, %rax
jne 0xfdfc
movq 0x30(%rsp), %r13
movq %r13, (%rsp)
addq 0x38(%rsp), %r13
movq %rsp, %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0xfbdb
cmpl $-0x1, %eax
je 0xfea9
movq %rbx, 0x8(%rsp)
movq %r13, %rcx
subq (%rsp), %rcx
movq %rcx, %rdx
shrq $0x3f, %rdx
addq %rcx, %rdx
shrq %rdx
addl $-0x8, %edx
movq %r15, %rdi
movl %eax, %esi
callq 0xfb65
movq (%rsp), %rbx
leaq 0x180c(%rbx), %rax
cmpq %r13, %rax
jbe 0xfee9
movl $0xf, %edx
movq 0x9160(%rip), %rdi      # 0x18fd0
leaq 0x2585(%rip), %rsi      # 0x123fc
callq 0x4240
movq 0x8(%rsp), %rbx
movq 0x9148(%rip), %rdi      # 0x18fd0
movq %rbx, %rsi
callq 0x4150
movl $0x1, %edx
movq %rax, %rdi
leaq 0x25fe(%rip), %rsi      # 0x1249d
callq 0x4240
jmp 0x10105
movl $0xf, %edx
movq 0x911b(%rip), %rdi      # 0x18fd0
leaq 0x2540(%rip), %rsi      # 0x123fc
callq 0x4240
movq 0x9108(%rip), %rdi      # 0x18fd0
movq %rbx, %rsi
callq 0x4150
movl $0x12, %edx
movq %rax, %rdi
leaq 0x252d(%rip), %rsi      # 0x1240c
callq 0x4240
jmp 0x10105
leaq 0x4(%rbx), %rax
movl (%rbx), %ecx
movl $0x55555555, %esi       # imm = 0x55555555
andl %esi, %ecx
movl 0x180c(%rbx), %edx
movl $0xd5555555, %edi       # imm = 0xD5555555
andl %edi, %edx
movq %rax, (%rsp)
leal (%rcx,%rdx,2), %eax
cmpl $0x5336534f, %eax       # imm = 0x5336534F
jne 0x100c5
leaq 0x8(%rbx), %rax
movl 0x4(%rbx), %ecx
andl %esi, %ecx
movl 0x1810(%rbx), %edx
andl %edi, %edx
leal (%rcx,%rdx,2), %ebp
roll $0x10, %ebp
movq %rax, (%rsp)
leaq 0xc(%rbx), %r13
movl 0x8(%rbx), %eax
andl %esi, %eax
movl 0x1814(%rbx), %ecx
andl %edi, %ecx
movq %r13, (%rsp)
leal (%rax,%rcx,2), %eax
roll $0x10, %eax
subl %eax, %ebp
addl $0xacb0acca, %ebp       # imm = 0xACB0ACCA
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
xorl %r12d, %r12d
xorl %r15d, %r15d
movl $0x55555555, %ecx       # imm = 0x55555555
movl $0xd5555555, %edx       # imm = 0xD5555555
movl (%r13,%r15,4), %eax
andl %ecx, %eax
movl 0x1818(%rbx,%r15,4), %ecx
andl %edx, %ecx
leal (%rax,%rcx,2), %r14d
movl %r14d, 0x60(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0xffa8
movl %r14d, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0xffb7
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x10ef4
roll $0x10, %r14d
subl %r14d, %ebp
incq %r15
addq $-0x4, %r12
cmpl $0x600, %r15d           # imm = 0x600
movl $0x55555555, %ecx       # imm = 0x55555555
movl $0xd5555555, %edx       # imm = 0xD5555555
jne 0xff74
subq %r12, %r13
movq %r13, (%rsp)
testl %ebp, %ebp
je 0x10020
movl $0x6, %edx
movq 0x8fe1(%rip), %rdi      # 0x18fd0
leaq 0x240f(%rip), %rsi      # 0x12405
callq 0x4240
movq 0x8fce(%rip), %rdi      # 0x18fd0
movq 0x8(%rsp), %rsi
callq 0x4150
movl $0x17, %edx
movq %rax, %rdi
leaq 0x241c(%rip), %rsi      # 0x12437
callq 0x4240
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rax
subq %rsi, %rax
cmpq $0x2, %rax
movl 0x54(%rsp), %ebp
leaq 0x70(%rsp), %rbx
movq 0x58(%rsp), %r12
leaq 0x60(%rsp), %r15
jb 0x10058
shrq %rax
xorl %ecx, %ecx
rolw $0x8, (%rsi,%rcx,2)
incq %rcx
cmpq %rcx, %rax
jne 0x1004b
movq 0x18(%rsp), %rdx
subq 0x10(%rsp), %rdx
movq %rbx, 0x60(%rsp)
addq %rsi, %rdx
movq %r15, %rdi
leaq 0x40(%rsp), %r14
callq 0x10b94
movq 0x8(%rsp), %rdi
shlq $0x5, %rdi
movq 0x28(%rsp), %rax
addq (%rax), %rdi
movq %r15, %rsi
callq 0x4270
movq 0x60(%rsp), %rdi
cmpq %rbx, %rdi
je 0x100a7
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x4210
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x100be
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x4210
movq 0x8(%rsp), %rbx
jmp 0x10105
movl $0xf, %edx
movq 0x8eff(%rip), %rdi      # 0x18fd0
leaq 0x2324(%rip), %rsi      # 0x123fc
callq 0x4240
movq 0x8(%rsp), %rbx
movq 0x8ee7(%rip), %rdi      # 0x18fd0
movq %rbx, %rsi
callq 0x4150
movl $0x17, %edx
movq %rax, %rdi
leaq 0x231f(%rip), %rsi      # 0x1241f
callq 0x4240
movq 0x30(%rsp), %rdi
cmpq %r14, %rdi
je 0x1011c
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x4210
incq %rbx
cmpq %r12, %rbx
jne 0xfd77
movl %ebp, %edi
callq 0x61c7
movl %ebp, %edi
callq 0x5d0f
movl %ebp, %edi
callq 0x5b87
movq 0x28(%rsp), %rax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1015b
movq %rax, %rbx
jmp 0x101ac
movq %rax, %rbx
jmp 0x10174
jmp 0x1018d
jmp 0x1018d
jmp 0x1018d
movq %rax, %rbx
subq %r12, %r13
addq $0x4, %r13
movq %r13, (%rsp)
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x10190
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x4210
jmp 0x10190
movq %rax, %rbx
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x101ac
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x4210
movq 0x28(%rsp), %rdi
callq 0x10aae
movq %rbx, %rdi
callq 0x43a0