// File: /workspace/github_cpp_makefile_star2_O3/joncampbell123[P]floppytools/kryoflux7.cpp
// Function: process_sync(_IO_FILE*, flux_bits&, kryoflux_event&, _IO_FILE*)
void process_sync(FILE *dsk_fp,struct flux_bits &fb,struct kryoflux_event &ev,FILE *fp) {
    unsigned char tmp[128];
    unsigned int count;
    mfm_crc16fd_t check;
    int c;

    // A1 A1 A1
    // FE
    // track number
    // side
    // sector number
    // sector size as power of 2
    // <TWO BYTE CRC>
    // 22 bytes of 4E
    // 12 bytes of 00
    //
    // A1 A1 A1
    // FA/FB
    // <SECTOR DATA>
    // <TWO BYTE CRC>
    //
    // (inter-sector gap filled with 4E)

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[0] = (unsigned char)MFM_A1_SYNC_BYTE;

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[1] = (unsigned char)MFM_A1_SYNC_BYTE;

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[2] = (unsigned char)MFM_A1_SYNC_BYTE;

    // we are expecting FE
    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != 0xFE) return; // FE
    tmp[3] = (unsigned char)c;

    int track = flux_bits_mfm_decode(fb,ev,fp);
    if (track < 0) return;
    tmp[4] = (unsigned char)track;

    int side = flux_bits_mfm_decode(fb,ev,fp);
    if (side < 0) return;
    tmp[5] = (unsigned char)side;

    int sector = flux_bits_mfm_decode(fb,ev,fp);
    if (sector < 0) return;
    tmp[6] = (unsigned char)sector;

    int ssize = flux_bits_mfm_decode(fb,ev,fp);
    if (ssize < 0) return;
    tmp[7] = (unsigned char)ssize;

    unsigned int crc;
    if ((c=flux_bits_mfm_decode(fb,ev,fp)) < 0) return;//CRC-hi
    crc  = (unsigned int)c << 8;

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) < 0) return;//CRC-hi
    crc += (unsigned int)c;

    check = mfm_crc16fd_update(0xffff,tmp,8);
    if (check != crc) return;

    if ((128 << ssize) != sector_size) {
//        printf("Not what we're looking for, wrong sector size\n");
        return;
    }
    if (sector < 1 || sector > sectors ||
        side < 0 || side >= heads ||
        track < 0 || track >= tracks) {
//        printf("Not what we're looking for, track/side/sector %d/%d/%d out of range\n",track,side,sector);
        return;
    }

    unsigned long sector_num;

    sector_num  = (unsigned long)track;
    sector_num *= (unsigned long)heads;
    sector_num += (unsigned long)side;
    sector_num *= (unsigned long)sectors;
    sector_num += (unsigned long)sector - 1;

    assert(sector_num < captured.size());
    if (captured[sector_num]) {
//        printf("Already captured\n");
        return;
    }

    printf("Sector: track=%u side=%u sector=%u ssize=%u\n",track,side,sector,128 << ssize);

    /* 4E 4E .... */
    {
        unsigned int errs = 0;

        for (count=0;count < 16;count++) {
            c = flux_bits_mfm_decode(fb,ev,fp);

            if (c == 0x4E) {
            }
            else if (c == 0x00) {
                break;
            }
            else if (c < 0) {
                printf("* Gap between A1 sync where 4E should exist ends abruptly\n");
                break;
            }
            else {
                if (++errs >= 8) {
                    printf("* Gap between A1 sync has too many non-4E bytes\n");
                    break;
                }
            }
        }

        if (count < 8)
            printf("* Too few 4E bytes\n");
    }

    /* look for A1 sync.
     * mem_decode() won't reliably find it */
    kryoflux_bits_refill(fb,ev,fp);
    while (fb.avail() >= MFM_A1_SYNC_LENGTH) {
        if (fb.peek(MFM_A1_SYNC_LENGTH) == MFM_A1_SYNC) {
            break;
        }
        else {
            fb.get(1);
        }

        if (!kryoflux_bits_refill(fb,ev,fp))
            return;
    }

    if (fb.avail() < MFM_A1_SYNC_LENGTH)
        return;

    // A1 A1 A1 FA/FB
    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[0] = (unsigned char)MFM_A1_SYNC_BYTE;

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[1] = (unsigned char)MFM_A1_SYNC_BYTE;

    if ((c=flux_bits_mfm_decode(fb,ev,fp)) != -MFM_A1_SYNC_BYTE) return; // A1
    tmp[2] = (unsigned char)MFM_A1_SYNC_BYTE;

    // we are expecting FA/FB
    if (((c=flux_bits_mfm_decode(fb,ev,fp))&0xFE) != 0xFA) return; // FA/FB
    tmp[3] = (unsigned char)c;

    /* begin checksum */
    check = mfm_crc16fd_update(0xffff,tmp,4);

    // sector data follows
    for (unsigned int b=0;b < (sector_size+2);b++) {
        kryoflux_bits_refill(fb,ev,fp);

        unsigned long cstart = ev.offset;
        unsigned int cpeek = fb.peek(16);

        if ((c=flux_bits_mfm_decode(fb,ev,fp)) < 0) {
            printf(" ! flux error in sector (%d) at byte %u / %u (flux 0x%04x offset %lu)\n",c,b,sector_size,cpeek,cstart);
            return;
        }
        sector_buf[b] = (unsigned char)c;
    }
    check = mfm_crc16fd_update(check,sector_buf,sector_size);

    crc  = (unsigned int)sector_buf[sector_size+0u] << 8u;
    crc += (unsigned int)sector_buf[sector_size+1u];

    if (check != crc) {
        printf("Sector checkum failed\n");
        return;
    }

    printf(" * DATA OK\n");

    unsigned long sector_ofs;

    sector_ofs = sector_num * (unsigned long)sector_size;

    fseek(dsk_fp,sector_ofs,SEEK_SET);
    if (ftell(dsk_fp) != sector_ofs) return;

    fwrite(sector_buf,sector_size,1,dsk_fp);

    assert(sector_num < captured.size());
    captured[sector_num] = true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %rbx
movq %rsi, %rdi
movq %rdx, %rsi
movq %rcx, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xe0(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xdf(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xde(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xfe, %eax
jne 0x26f6
movb $-0x2, -0xdd(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
testl %eax, %eax
js 0x26f6
movl %eax, %r13d
movb %r13b, -0xdc(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
movl %eax, -0x38(%rbp)
testl %eax, %eax
js 0x26f6
movl -0x38(%rbp), %eax
movb %al, -0xdb(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
movl %eax, -0x30(%rbp)
testl %eax, %eax
js 0x26f6
movl -0x30(%rbp), %eax
movb %al, -0xda(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
movl %eax, -0x2c(%rbp)
testl %eax, %eax
js 0x26f6
movl -0x2c(%rbp), %eax
movb %al, -0xd9(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
testl %eax, %eax
js 0x26f6
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl %eax, -0x40(%rbp)
callq 0x41ae
movl -0x40(%rbp), %ecx
testl %eax, %eax
js 0x26f6
shll $0x8, %ecx
addl %ecx, %eax
movl %eax, -0x40(%rbp)
leaq -0xe0(%rbp), %rsi
movl $0x8, %edx
movl $0xffff, %edi           # imm = 0xFFFF
callq 0x4259
movzwl %ax, %eax
cmpl %eax, -0x40(%rbp)
jne 0x26f6
movl $0x80, %r8d
movl -0x2c(%rbp), %ecx
shll %cl, %r8d
cmpl $0x0, -0x30(%rbp)
je 0x26f6
cmpl 0x5b09(%rip), %r8d      # 0x8144
jne 0x26f6
movl 0x5af1(%rip), %eax      # 0x8138
cmpl %eax, -0x30(%rbp)
ja 0x26f6
movl 0x5ae6(%rip), %ecx      # 0x813c
cmpl %ecx, -0x38(%rbp)
jae 0x26f6
cmpl 0x5ada(%rip), %r13d     # 0x8140
jae 0x26f6
movl %r13d, %edx
imulq %rdx, %rcx
movl -0x38(%rbp), %edx
addq %rcx, %rdx
imulq %rax, %rdx
movl -0x30(%rbp), %eax
leaq (%rax,%rdx), %rcx
decq %rcx
movq 0x9af2(%rip), %rsi      # 0xc180
movl 0x9af4(%rip), %edx      # 0xc188
movq 0x9ad5(%rip), %rax      # 0xc170
subq %rax, %rsi
leaq (%rdx,%rsi,8), %rdx
cmpq %rdx, %rcx
jae 0x29fa
leaq 0x3f(%rcx), %r9
testq %rcx, %rcx
cmovnsq %rcx, %r9
sarq $0x6, %r9
movabsq $-0x8000000000000000, %rdi # imm = 0x8000000000000000
leaq 0x3f(%rdi), %rsi
andq %rcx, %rsi
xorl %edx, %edx
cmpq %rdi, %rsi
setbe %dl
movl $0x1, %esi
shlq %cl, %rsi
movq %rsi, -0x50(%rbp)
movq %r9, -0x58(%rbp)
leaq (%rax,%r9,8), %rax
movq -0x8(%rax,%rdx,8), %rax
movq %rcx, -0x40(%rbp)
btq %rcx, %rax
jae 0x2708
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x8(,%rdx,8), %rax
movq %rax, -0x48(%rbp)
leaq 0x2963(%rip), %rdi      # 0x507e
movl $0x0, -0x2c(%rbp)
movl %r13d, %esi
movl -0x38(%rbp), %edx
movl -0x30(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq 0x2b99(%rip), %rax      # 0x52d2
movq %rax, -0x38(%rbp)
xorl %r13d, %r13d
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0x4e, %eax
je 0x2762
testl %eax, %eax
je 0x2785
js 0x277c
incl %r13d
cmpl $0x7, %r13d
ja 0x2771
movl -0x2c(%rbp), %eax
incl %eax
movl %eax, -0x2c(%rbp)
cmpl $0x10, %eax
jne 0x2740
jmp 0x2797
leaq 0x2b2a(%rip), %rax      # 0x52a2
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x21e0
cmpl $0x7, -0x2c(%rbp)
ja 0x2797
leaq 0x2b7a(%rip), %rdi      # 0x530c
callq 0x21e0
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3e32
movq %r12, %rdi
callq 0x3eb4
cmpl $0x10, %eax
jb 0x27ea
movq %r12, %rdi
movl $0x10, %esi
callq 0x3f0e
cmpl $0x4489, %eax           # imm = 0x4489
je 0x27ea
movq %r12, %rdi
movl $0x1, %esi
callq 0x3f34
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3e32
testb %al, %al
jne 0x27a5
jmp 0x26f6
movq %r12, %rdi
callq 0x3eb4
cmpl $0x10, %eax
jb 0x26f6
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xe0(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xdf(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x26f6
movb $-0x5f, -0xde(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
movl %eax, %ecx
andl $0xfe, %ecx
cmpl $0xfa, %ecx
jne 0x26f6
leaq -0xe0(%rbp), %rsi
movb %al, 0x3(%rsi)
movl $0x4, %edx
movl $0xffff, %edi           # imm = 0xFFFF
callq 0x4259
movw %ax, -0x2c(%rbp)
movl $0xfffffffe, %edx       # imm = 0xFFFFFFFE
cmpl $-0x2, 0x589e(%rip)     # 0x8144
je 0x2904
xorl %r13d, %r13d
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3e32
movq 0x8(%r15), %rax
movq %rax, -0x38(%rbp)
movq %r12, %rdi
movl $0x10, %esi
callq 0x3f0e
movl %eax, -0x30(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x41ae
testl %eax, %eax
js 0x29d4
leaq 0x5872(%rip), %rcx      # 0x8160
movb %al, (%r13,%rcx)
incq %r13
movl 0x5848(%rip), %edx      # 0x8144
leal 0x2(%rdx), %eax
cmpq %rax, %r13
jb 0x28ab
movzwl -0x2c(%rbp), %edi
leaq 0x5851(%rip), %r14      # 0x8160
movq %r14, %rsi
callq 0x4259
movl 0x5827(%rip), %ecx      # 0x8144
movzbl (%rcx,%r14), %edx
shll $0x8, %edx
incl %ecx
movzbl (%rcx,%r14), %ecx
orl %edx, %ecx
movzwl %ax, %eax
cmpl %eax, %ecx
jne 0x29c3
leaq 0x29df(%rip), %rdi      # 0x531f
callq 0x21e0
movl 0x57f8(%rip), %r14d     # 0x8144
imulq -0x40(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x2170
movq %rbx, %rdi
callq 0x2030
cmpq %r14, %rax
jne 0x26f6
movl 0x57cf(%rip), %esi      # 0x8144
leaq 0x57e4(%rip), %rdi      # 0x8160
movl $0x1, %edx
movq %rbx, %rcx
callq 0x2240
movq 0x97f0(%rip), %rcx      # 0xc180
movl 0x97f2(%rip), %edx      # 0xc188
movq 0x97d3(%rip), %rax      # 0xc170
subq %rax, %rcx
leaq (%rdx,%rcx,8), %rcx
cmpq %rcx, -0x40(%rbp)
jae 0x2a19
movq -0x58(%rbp), %rcx
leaq (%rax,%rcx,8), %rax
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %rdx
orq %rcx, (%rdx,%rax)
jmp 0x26f6
leaq 0x2960(%rip), %rdi      # 0x532a
callq 0x21e0
jmp 0x26f6
movl 0x576a(%rip), %ecx      # 0x8144
leaq 0x26ca(%rip), %rdi      # 0x50ab
movl %eax, %esi
movl %r13d, %edx
movl -0x30(%rbp), %r8d
movq -0x38(%rbp), %r9
xorl %eax, %eax
callq 0x2040
jmp 0x26f6
leaq 0x2603(%rip), %rdi      # 0x5004
leaq 0x2619(%rip), %rsi      # 0x5021
leaq 0x2620(%rip), %rcx      # 0x502f
movl $0x6b, %edx
callq 0x20e0
leaq 0x25e4(%rip), %rdi      # 0x5004
leaq 0x25fa(%rip), %rsi      # 0x5021
leaq 0x2601(%rip), %rcx      # 0x502f
movl $0xd4, %edx
callq 0x20e0