// File: 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
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x242e
jmp 0x2bdd
movb $-0x5f, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x2458
jmp 0x2bdd
movb $-0x5f, -0x9f(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x2482
jmp 0x2bdd
movb $-0x5f, -0x9e(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xfe, %eax
je 0x24ac
jmp 0x2bdd
movl -0xac(%rbp), %eax
movb %al, -0x9d(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xb0(%rbp)
cmpl $0x0, -0xb0(%rbp)
jge 0x24dd
jmp 0x2bdd
movl -0xb0(%rbp), %eax
movb %al, -0x9c(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xb4(%rbp)
cmpl $0x0, -0xb4(%rbp)
jge 0x250e
jmp 0x2bdd
movl -0xb4(%rbp), %eax
movb %al, -0x9b(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xb8(%rbp)
cmpl $0x0, -0xb8(%rbp)
jge 0x253f
jmp 0x2bdd
movl -0xb8(%rbp), %eax
movb %al, -0x9a(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xbc(%rbp)
cmpl $0x0, -0xbc(%rbp)
jge 0x2570
jmp 0x2bdd
movl -0xbc(%rbp), %eax
movb %al, -0x99(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x259d
jmp 0x2bdd
movl -0xac(%rbp), %eax
shll $0x8, %eax
movl %eax, -0xc0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x25cd
jmp 0x2bdd
movl -0xac(%rbp), %eax
addl -0xc0(%rbp), %eax
movl %eax, -0xc0(%rbp)
leaq -0xa0(%rbp), %rsi
movl $0xffff, %edi           # imm = 0xFFFF
movl $0x8, %edx
callq 0x78f0
movw %ax, -0xa6(%rbp)
movzwl -0xa6(%rbp), %eax
cmpl -0xc0(%rbp), %eax
je 0x2610
jmp 0x2bdd
movl -0xbc(%rbp), %ecx
movl $0x80, %eax
shll %cl, %eax
cmpl 0xbb51(%rip), %eax      # 0xe174
je 0x262a
jmp 0x2bdd
cmpl $0x1, -0xb8(%rbp)
jl 0x266f
movl -0xb8(%rbp), %eax
cmpl 0xbb29(%rip), %eax      # 0xe168
ja 0x266f
cmpl $0x0, -0xb4(%rbp)
jl 0x266f
movl -0xb4(%rbp), %eax
cmpl 0xbb16(%rip), %eax      # 0xe16c
jae 0x266f
cmpl $0x0, -0xb0(%rbp)
jl 0x266f
movl -0xb0(%rbp), %eax
cmpl 0xbb03(%rip), %eax      # 0xe170
jb 0x2674
jmp 0x2bdd
movslq -0xb0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movl 0xbae4(%rip), %eax      # 0xe16c
imulq -0xc8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movslq -0xb4(%rbp), %rax
addq -0xc8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movl 0xbab6(%rip), %eax      # 0xe168
imulq -0xc8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movslq -0xb8(%rbp), %rax
subq $0x1, %rax
addq -0xc8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq 0xfab1(%rip), %rdi      # 0x121a0
callq 0x3950
movq %rax, %rcx
movq -0x110(%rbp), %rax
cmpq %rcx, %rax
jae 0x2705
jmp 0x2724
leaq 0x68f8(%rip), %rdi      # 0x9004
leaq 0x690e(%rip), %rsi      # 0x9021
movl $0x6b, %edx
leaq 0x6910(%rip), %rcx      # 0x902f
callq 0x2120
movq -0xc8(%rbp), %rsi
leaq 0xfa6e(%rip), %rdi      # 0x121a0
callq 0x39d0
movq %rax, -0xd8(%rbp)
movq %rdx, -0xd0(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x3a30
testb $0x1, %al
jne 0x2757
jmp 0x275c
jmp 0x2bdd
movl -0xb0(%rbp), %esi
movl -0xb4(%rbp), %edx
movl -0xb8(%rbp), %eax
movl %eax, -0x114(%rbp)
movl -0xbc(%rbp), %ecx
movl $0x80, %r8d
shll %cl, %r8d
movl -0x114(%rbp), %ecx
leaq 0x68ee(%rip), %rdi      # 0x907e
movb $0x0, %al
callq 0x2050
movl $0x0, -0xdc(%rbp)
movl $0x0, -0xa4(%rbp)
cmpl $0x10, -0xa4(%rbp)
jae 0x283e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0x4e, -0xac(%rbp)
jne 0x27da
jmp 0x2828
cmpl $0x0, -0xac(%rbp)
jne 0x27e5
jmp 0x283e
cmpl $0x0, -0xac(%rbp)
jge 0x27fe
leaq 0x68b6(%rip), %rdi      # 0x90ab
movb $0x0, %al
callq 0x2050
jmp 0x283e
movl -0xdc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xdc(%rbp)
cmpl $0x8, %eax
jb 0x2822
leaq 0x68cd(%rip), %rdi      # 0x90e6
movb $0x0, %al
callq 0x2050
jmp 0x283e
jmp 0x2824
jmp 0x2826
jmp 0x2828
jmp 0x282a
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x27ab
cmpl $0x8, -0xa4(%rbp)
jae 0x2855
leaq 0x68c9(%rip), %rdi      # 0x9117
movb $0x0, %al
callq 0x2050
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7070
movq -0x10(%rbp), %rdi
callq 0x7150
cmpl $0x10, %eax
jb 0x28b5
movq -0x10(%rbp), %rdi
movl $0x10, %esi
callq 0x7210
cmpl $0x4489, %eax           # imm = 0x4489
jne 0x288b
jmp 0x28b5
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x7280
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7070
testb $0x1, %al
jne 0x28b3
jmp 0x2bdd
jmp 0x2866
movq -0x10(%rbp), %rdi
callq 0x7150
cmpl $0x10, %eax
jae 0x28c8
jmp 0x2bdd
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x28eb
jmp 0x2bdd
movb $-0x5f, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x2915
jmp 0x2bdd
movb $-0x5f, -0x9f(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0xffffff5f, %eax       # imm = 0xFFFFFF5F
je 0x293f
jmp 0x2bdd
movb $-0x5f, -0x9e(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
andl $0xfe, %eax
cmpl $0xfa, %eax
je 0x296e
jmp 0x2bdd
movl -0xac(%rbp), %eax
movb %al, -0x9d(%rbp)
leaq -0xa0(%rbp), %rsi
movl $0xffff, %edi           # imm = 0xFFFF
movl $0x4, %edx
callq 0x78f0
movw %ax, -0xa6(%rbp)
movl $0x0, -0xe0(%rbp)
movl -0xe0(%rbp), %eax
movl 0xb7c7(%rip), %ecx      # 0xe174
addl $0x2, %ecx
cmpl %ecx, %eax
jae 0x2a69
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7070
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xe8(%rbp)
movq -0x10(%rbp), %rdi
movl $0x10, %esi
callq 0x7210
movl %eax, -0xec(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7800
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x2a3b
movl -0xac(%rbp), %esi
movl -0xe0(%rbp), %edx
movl 0xb75a(%rip), %ecx      # 0xe174
movl -0xec(%rbp), %r8d
movq -0xe8(%rbp), %r9
leaq 0x66fc(%rip), %rdi      # 0x912b
movb $0x0, %al
callq 0x2050
jmp 0x2bdd
movl -0xac(%rbp), %eax
movb %al, %dl
movl -0xe0(%rbp), %eax
movl %eax, %ecx
leaq 0xb73e(%rip), %rax      # 0xe190
movb %dl, (%rax,%rcx)
movl -0xe0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe0(%rbp)
jmp 0x29a1
movw -0xa6(%rbp), %ax
movl 0xb6fe(%rip), %ecx      # 0xe174
movl %ecx, %edx
leaq 0xb711(%rip), %rsi      # 0xe190
movzwl %ax, %edi
callq 0x78f0
movw %ax, -0xa6(%rbp)
movl 0xb6e0(%rip), %eax      # 0xe174
addl $0x0, %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0xb6ee(%rip), %rax      # 0xe190
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
movl %eax, -0xc0(%rbp)
movl 0xb6bf(%rip), %eax      # 0xe174
addl $0x1, %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0xb6cd(%rip), %rax      # 0xe190
movzbl (%rax,%rcx), %eax
addl -0xc0(%rbp), %eax
movl %eax, -0xc0(%rbp)
movzwl -0xa6(%rbp), %eax
cmpl -0xc0(%rbp), %eax
je 0x2af5
leaq 0x6689(%rip), %rdi      # 0x9172
movb $0x0, %al
callq 0x2050
jmp 0x2bdd
leaq 0x668d(%rip), %rdi      # 0x9189
movb $0x0, %al
callq 0x2050
movq -0xc8(%rbp), %rax
movl 0xb664(%rip), %ecx      # 0xe174
imulq %rcx, %rax
movq %rax, -0xf8(%rbp)
movq -0x8(%rbp), %rdi
movq -0xf8(%rbp), %rsi
xorl %edx, %edx
callq 0x21a0
movq -0x8(%rbp), %rdi
callq 0x2030
cmpq -0xf8(%rbp), %rax
je 0x2b44
jmp 0x2bdd
movl 0xb62a(%rip), %eax      # 0xe174
movl %eax, %esi
movq -0x8(%rbp), %rcx
leaq 0xb639(%rip), %rdi      # 0xe190
movl $0x1, %edx
callq 0x22a0
movq -0xc8(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq 0xf62a(%rip), %rdi      # 0x121a0
callq 0x3950
movq %rax, %rcx
movq -0x120(%rbp), %rax
cmpq %rcx, %rax
jae 0x2b8c
jmp 0x2bab
leaq 0x6471(%rip), %rdi      # 0x9004
leaq 0x6487(%rip), %rsi      # 0x9021
movl $0xd4, %edx
leaq 0x6489(%rip), %rcx      # 0x902f
callq 0x2120
movq -0xc8(%rbp), %rsi
leaq 0xf5e7(%rip), %rdi      # 0x121a0
callq 0x39d0
movq %rax, -0x108(%rbp)
movq %rdx, -0x100(%rbp)
leaq -0x108(%rbp), %rdi
movl $0x1, %esi
callq 0x3a60
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopw %cs:(%rax,%rax)