// File: /workspace/github_cpp_makefile_star2_O2/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 $0xa8, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %rbx
movq %rsi, %rdi
movq %rdx, %rsi
movq %rcx, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xd0(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xcf(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xce(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xfe, %eax
jne 0x25ab
movb $-0x2, -0xcd(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
testl %eax, %eax
js 0x25ab
movl %eax, %r13d
movb %r13b, -0xcc(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
movl %eax, -0x38(%rbp)
testl %eax, %eax
js 0x25ab
movl -0x38(%rbp), %eax
movb %al, -0xcb(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
movl %eax, -0x48(%rbp)
testl %eax, %eax
js 0x25ab
movl -0x48(%rbp), %eax
movb %al, -0xca(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
movl %eax, -0x2c(%rbp)
testl %eax, %eax
js 0x25ab
movl -0x2c(%rbp), %eax
movb %al, -0xc9(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
testl %eax, %eax
js 0x25ab
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl %eax, -0x3c(%rbp)
callq 0x3f49
movl -0x3c(%rbp), %ecx
testl %eax, %eax
js 0x25ab
shll $0x8, %ecx
addl %ecx, %eax
movl %eax, -0x3c(%rbp)
leaq -0xd0(%rbp), %rsi
pushq $0x8
popq %rdx
movl $0xffff, %edi           # imm = 0xFFFF
callq 0x3fe7
movzwl %ax, %eax
cmpl %eax, -0x3c(%rbp)
jne 0x25ab
movl $0x80, %edx
movl -0x2c(%rbp), %ecx
shll %cl, %edx
cmpl $0x0, -0x48(%rbp)
je 0x25ab
cmpl 0x5c12(%rip), %edx      # 0x8144
jne 0x25ab
movl 0x5bfe(%rip), %eax      # 0x8138
cmpl %eax, -0x48(%rbp)
ja 0x25ab
movl 0x5bf7(%rip), %ecx      # 0x813c
cmpl %ecx, -0x38(%rbp)
jae 0x25ab
cmpl 0x5bef(%rip), %r13d     # 0x8140
jae 0x25ab
movl %edx, -0x3c(%rbp)
movl %r13d, %edx
imulq %rdx, %rcx
movl -0x38(%rbp), %edx
addq %rcx, %rdx
imulq %rax, %rdx
movl -0x48(%rbp), %eax
leaq (%rax,%rdx), %rsi
decq %rsi
movq 0x9c08(%rip), %rax      # 0xc180
movl 0x9c0a(%rip), %ecx      # 0xc188
subq 0x9beb(%rip), %rax      # 0xc170
leaq (%rcx,%rax,8), %rax
cmpq %rax, %rsi
jae 0x2899
leaq 0x9bd7(%rip), %rdi      # 0xc170
movq %rsi, -0x50(%rbp)
callq 0x3006
testq %rdx, (%rax)
movl -0x3c(%rbp), %r8d
je 0x25bd
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2aba(%rip), %rdi      # 0x507e
movl $0x0, -0x2c(%rbp)
movl %r13d, %esi
movl -0x38(%rbp), %edx
movl -0x48(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq 0x2cc6(%rip), %rax      # 0x52a8
movq %rax, -0x38(%rbp)
xorl %r13d, %r13d
cmpl $0x10, %r13d
je 0x2640
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0x4e, %eax
je 0x2615
testl %eax, %eax
je 0x262e
js 0x2625
movl -0x2c(%rbp), %eax
incl %eax
movl %eax, -0x2c(%rbp)
cmpl $0x7, %eax
ja 0x261a
incl %r13d
jmp 0x25e9
leaq 0x2c57(%rip), %rax      # 0x5278
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x21f0
cmpl $0x7, %r13d
ja 0x2640
leaq 0x2ca7(%rip), %rdi      # 0x52e2
callq 0x21f0
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3b90
pushq $0x10
popq %r13
movq %r12, %rdi
callq 0x3c1a
cmpl $0x10, %eax
jb 0x2693
movq %r12, %rdi
movl %r13d, %esi
callq 0x3c86
cmpl $0x4489, %eax           # imm = 0x4489
je 0x2693
movq %r12, %rdi
pushq $0x1
popq %rsi
callq 0x3cc2
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3b90
testb %al, %al
jne 0x2652
jmp 0x25ab
movq %r12, %rdi
callq 0x3c1a
cmpl $0x10, %eax
jb 0x25ab
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xd0(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xcf(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
jne 0x25ab
movb $-0x5f, -0xce(%rbp)
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
movl %eax, %ecx
andl $0xfe, %ecx
cmpl $0xfa, %ecx
jne 0x25ab
leaq -0xd0(%rbp), %rsi
movb %al, 0x3(%rsi)
pushq $0x4
popq %rdx
movl $0xffff, %edi           # imm = 0xFFFF
callq 0x3fe7
movw %ax, -0x2c(%rbp)
movq $0x0, -0x38(%rbp)
movl 0x59f5(%rip), %edx      # 0x8144
leal 0x2(%rdx), %eax
cmpq %rax, -0x38(%rbp)
jae 0x27a9
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3b90
movq 0x8(%r15), %rax
movq %rax, -0x48(%rbp)
movq %r12, %rdi
pushq $0x10
popq %rsi
callq 0x3c86
movl %eax, %r13d
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x3f49
testl %eax, %eax
js 0x2862
leaq 0x59c7(%rip), %rcx      # 0x8160
movq -0x38(%rbp), %rdx
movb %al, (%rdx,%rcx)
incq %rdx
movq %rdx, -0x38(%rbp)
jmp 0x2749
movzwl -0x2c(%rbp), %edi
leaq 0x59ac(%rip), %r14      # 0x8160
movq %r14, %rsi
callq 0x3fe7
movl 0x5982(%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 0x2888
leaq 0x2b10(%rip), %rdi      # 0x52f5
callq 0x21f0
movl 0x5953(%rip), %r14d     # 0x8144
imulq -0x50(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x2160
movq %rbx, %rdi
callq 0x2030
cmpq %r14, %rax
jne 0x25ab
movl 0x592a(%rip), %esi      # 0x8144
leaq 0x593f(%rip), %rdi      # 0x8160
pushq $0x1
popq %rdx
movq %rbx, %rcx
callq 0x2240
movq 0x994d(%rip), %rax      # 0xc180
movl 0x994f(%rip), %ecx      # 0xc188
subq 0x9930(%rip), %rax      # 0xc170
leaq (%rcx,%rax,8), %rax
cmpq %rax, -0x50(%rbp)
jae 0x28b6
leaq 0x991f(%rip), %rdi      # 0xc170
movq -0x50(%rbp), %rsi
callq 0x3006
orq %rdx, (%rax)
jmp 0x25ab
movl 0x58dc(%rip), %ecx      # 0x8144
leaq 0x283c(%rip), %rdi      # 0x50ab
movl %eax, %esi
movq -0x38(%rbp), %rdx
movl %r13d, %r8d
movq -0x48(%rbp), %r9
xorl %eax, %eax
callq 0x2040
jmp 0x25ab
leaq 0x2a71(%rip), %rdi      # 0x5300
callq 0x21f0
jmp 0x25ab
leaq 0x2764(%rip), %rdi      # 0x5004
leaq 0x277a(%rip), %rsi      # 0x5021
leaq 0x2781(%rip), %rcx      # 0x502f
pushq $0x6b
popq %rdx
callq 0x20f0
leaq 0x2747(%rip), %rdi      # 0x5004
leaq 0x275d(%rip), %rsi      # 0x5021
leaq 0x2764(%rip), %rcx      # 0x502f
movl $0xd4, %edx
callq 0x20f0