// File: 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
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x160(%rbp)
movq %rdi, %rax
movq %rax, -0x158(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x6c10
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x150(%rbp)
movq -0x10(%rbp), %rdi
callq 0x40e0
movl -0x150(%rbp), %edi
movq %rax, %rsi
callq 0x6d90
movl %eax, -0x60(%rbp)
cmpl $0x0, -0x60(%rbp)
je 0x1a20e
movq 0xce04(%rip), %rdi      # 0x26fc0
leaq 0x41a7(%rip), %rsi      # 0x1e36a
callq 0x4220
movq %rax, %rdi
movl -0x60(%rbp), %esi
callq 0x4410
movq %rax, %rdi
leaq 0x423a(%rip), %rsi      # 0x1e417
callq 0x4220
movl -0x5c(%rbp), %edi
callq 0x6d00
movq -0x160(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x4140
movq -0x160(%rbp), %rdi
callq 0x1b390
jmp 0x1a832
movl -0x5c(%rbp), %esi
leaq -0x58(%rbp), %rdi
callq 0x70b0
movl -0x5c(%rbp), %edi
movl $0x1b34, %esi           # imm = 0x1B34
callq 0x7020
movq -0x160(%rbp), %rdi
movl -0x4c(%rbp), %ecx
movl -0x48(%rbp), %eax
subl %ecx, %eax
incl %eax
movl -0x40(%rbp), %ecx
movl -0x44(%rbp), %edx
subl %edx, %ecx
incl %ecx
imull %ecx, %eax
movl %eax, -0x64(%rbp)
movb $0x0, -0x65(%rbp)
callq 0x1b390
movq -0x160(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x1b3b0
jmp 0x1a264
movl $0x2, -0x78(%rbp)
movl -0x78(%rbp), %eax
cmpl -0x64(%rbp), %eax
jae 0x1a7e4
leaq -0x98(%rbp), %rdi
callq 0x4340
movl $0x1, -0xc8(%rbp)
movl -0x5c(%rbp), %esi
movl -0x78(%rbp), %eax
movl %eax, %edx
shrl %edx
testb $0x1, %al
sete %al
movzbl %al, %ecx
leaq -0xc8(%rbp), %rdi
movl $0x1b34, %r8d           # imm = 0x1B34
callq 0x72b0
movl %eax, -0x164(%rbp)
jmp 0x1a2b9
movl -0x164(%rbp), %eax
movl %eax, -0xcc(%rbp)
movl -0xac(%rbp), %eax
shrl $0x3, %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
callq 0x4330
jmp 0x1a2de
leaq -0x98(%rbp), %rdi
callq 0x42f0
movq %rax, %rdi
movq -0xb4(%rbp), %rsi
movl -0xac(%rbp), %eax
shrl $0x3, %eax
movl %eax, %eax
movl %eax, %edx
callq 0x41a0
leaq -0x98(%rbp), %rdi
callq 0x42f0
movq %rax, -0x180(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x4170
movq -0x180(%rbp), %rdi
movq %rax, %rsi
callq 0x1a0d0
leaq -0x98(%rbp), %rdi
callq 0x42f0
movq %rax, -0xd8(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x42f0
movq %rax, -0x178(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x4170
movq %rax, %rcx
movq -0x178(%rbp), %rax
addq %rcx, %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x170(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x4170
movq -0x170(%rbp), %rsi
addq %rax, %rsi
leaq -0xd8(%rbp), %rdi
callq 0x19f70
movl %eax, -0xe4(%rbp)
cmpl $-0x1, -0xe4(%rbp)
jne 0x1a433
movq 0xcc00(%rip), %rdi      # 0x26fc0
leaq 0x3faf(%rip), %rsi      # 0x1e376
callq 0x4220
movq %rax, -0x188(%rbp)
jmp 0x1a3d5
movq -0x188(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4310
movq %rax, -0x190(%rbp)
jmp 0x1a3ed
movq -0x190(%rbp), %rdi
leaq 0x3f8b(%rip), %rsi      # 0x1e386
callq 0x4220
jmp 0x1a402
movl $0x4, -0xe8(%rbp)
jmp 0x1a788
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x1a824
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x1a7d6
movl -0xe4(%rbp), %esi
movq -0xe0(%rbp), %rax
movq -0xd8(%rbp), %rcx
subq %rcx, %rax
movl $0x2, %ecx
cqto
idivq %rcx
movl %eax, %edx
subl $0x8, %edx
leaq -0xd8(%rbp), %rdi
callq 0x19e30
movq -0xd8(%rbp), %rax
addq $0x180c, %rax           # imm = 0x180C
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
cmpq -0xe0(%rbp), %rax
jbe 0x1a4e1
movq 0xcb30(%rip), %rdi      # 0x26fc0
leaq 0x3edf(%rip), %rsi      # 0x1e376
callq 0x4220
movq %rax, -0x198(%rbp)
jmp 0x1a4a5
movq -0x198(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4310
movq %rax, -0x1a0(%rbp)
jmp 0x1a4bd
movq -0x1a0(%rbp), %rdi
leaq 0x3f4c(%rip), %rsi      # 0x1e417
callq 0x4220
jmp 0x1a4d2
movl $0x4, -0xe8(%rbp)
jmp 0x1a788
leaq -0xd8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1a050
movl %eax, -0xf4(%rbp)
cmpl $0x534f5336, -0xf4(%rbp) # imm = 0x534F5336
je 0x1a55e
movq 0xcab3(%rip), %rdi      # 0x26fc0
leaq 0x3e62(%rip), %rsi      # 0x1e376
callq 0x4220
movq %rax, -0x1a8(%rbp)
jmp 0x1a522
movq -0x1a8(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4310
movq %rax, -0x1b0(%rbp)
jmp 0x1a53a
movq -0x1b0(%rbp), %rdi
leaq 0x3e51(%rip), %rsi      # 0x1e399
callq 0x4220
jmp 0x1a54f
movl $0x4, -0xe8(%rbp)
jmp 0x1a788
xorl %eax, %eax
subl -0xf4(%rbp), %eax
movl %eax, -0xf4(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1a050
addl -0xf4(%rbp), %eax
movl %eax, -0xf4(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1a050
movl %eax, %ecx
movl -0xf4(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xf4(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x1b440
movl $0x5ff, -0x114(%rbp)    # imm = 0x5FF
cmpl $0x0, -0x114(%rbp)
jl 0x1a644
leaq -0xd8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1a050
movl %eax, -0x118(%rbp)
movl -0x118(%rbp), %ecx
movl -0xf4(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xf4(%rbp)
movl -0x118(%rbp), %edi
callq 0x19e00
movl %eax, -0x11c(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x11c(%rbp), %rsi
callq 0x1b460
jmp 0x1a620
jmp 0x1a622
movl -0x114(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x114(%rbp)
jmp 0x1a5c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x1a7ca
cmpl $0x0, -0xf4(%rbp)
je 0x1a698
movq 0xc96c(%rip), %rdi      # 0x26fc0
leaq 0x3d24(%rip), %rsi      # 0x1e37f
callq 0x4220
movq %rax, -0x1b8(%rbp)
jmp 0x1a669
movq -0x1b8(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4310
movq %rax, -0x1c0(%rbp)
jmp 0x1a681
movq -0x1c0(%rbp), %rdi
leaq 0x3d22(%rip), %rsi      # 0x1e3b1
callq 0x4220
jmp 0x1a696
jmp 0x1a698
leaq -0x110(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0x1b490
movq -0x1e0(%rbp), %rdi
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x1e8(%rbp)
callq 0x1b4b0
movq -0x1e8(%rbp), %rdi
movq %rax, %rsi
shlq $0x2, %rsi
callq 0x1a0d0
movq -0x1e0(%rbp), %rdi
movq -0x128(%rbp), %rax
movq %rax, -0x1d8(%rbp)
callq 0x1b4b0
shlq $0x2, %rax
movq %rax, -0x1d0(%rbp)
leaq -0x149(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x4430
movq -0x1d8(%rbp), %rsi
movq -0x1d0(%rbp), %rdx
movq -0x1c8(%rbp), %rcx
leaq -0x148(%rbp), %rdi
callq 0x4280
jmp 0x1a73a
movq -0x160(%rbp), %rdi
movl -0x78(%rbp), %eax
movl %eax, %esi
callq 0x1b4d0
movq %rax, %rdi
leaq -0x148(%rbp), %rsi
callq 0x42c0
leaq -0x148(%rbp), %rdi
callq 0x4488
leaq -0x149(%rbp), %rdi
callq 0x4260
leaq -0x110(%rbp), %rdi
callq 0x1b4f0
movl $0x0, -0xe8(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x4488
movl -0xe8(%rbp), %eax
testl %eax, %eax
je 0x1a7a2
jmp 0x1a7a0
jmp 0x1a7a4
jmp 0x1a7a4
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x1a26b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x149(%rbp), %rdi
callq 0x4260
leaq -0x110(%rbp), %rdi
callq 0x1b4f0
leaq -0x98(%rbp), %rdi
callq 0x4488
jmp 0x1a824
movl -0x5c(%rbp), %edi
callq 0x78f0
jmp 0x1a7ee
movl -0x5c(%rbp), %edi
callq 0x6fa0
jmp 0x1a7f8
movl -0x5c(%rbp), %edi
callq 0x6d00
jmp 0x1a802
movb $0x1, -0x65(%rbp)
movl $0x1, -0xe8(%rbp)
testb $0x1, -0x65(%rbp)
jne 0x1a822
movq -0x160(%rbp), %rdi
callq 0x1b550
jmp 0x1a832
movq -0x160(%rbp), %rdi
callq 0x1b550
jmp 0x1a842
movq -0x158(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x4420
nopl (%rax,%rax)