// File: /workspace/github_c_makefile_star2_O0/simh[P]simtools/converters/hpconvert/hpconvert.c
// Function: main
int main (int    argc,
          char **argv)

{
    const char *format [] = { "HPDrive", "SIMH" };

    const char *signatures [] = { "\x67\x6D\x06\xC0\x77\x6B\x0B\x40",   /* RTE ICD */
                                  "SYSTEM D" };                         /* MPE */

    #define  SIGNATURE_SIZE  sizeof (signatures [0])

    const int signature_count = sizeof (signatures) / SIGNATURE_SIZE;

    FILE   *fin, *fout;
    size_t file_size, record_size;
    char   *name_in, *name_out;
    char   sig_fwd [SIGNATURE_SIZE], sig_rev [SIGNATURE_SIZE];
    char   hold, cylinder [CYLINDER_SIZE];
    bool   identified = false, reversed = false, debug = false;
    int    i, cyl, from_cyl, to_cyl, remap;
    int    platter, cylinder_size, hole_size;


/* Read the disc image filename. */

    if (argc != 2) {
        puts ("\nHPConvert version 1.1");
        puts ("\nUsage: hpconvert <disc-image>");
        return 1;
        }

    name_in = argv [1];

/* Open the source image file. */

    fin = fopen (name_in, "rb");

    if (!fin) {
        printf ("Error: cannot open %s\n", name_in);
        return 1;
        }

/* Get the size of the image. */

    fseek (fin, 0, SEEK_END);
    file_size = ftell (fin);


/* The blocks of a 7905 or 7906 image (as determined by the image file size)
   will need to be rearranged.  Set "remap" to the number of surfaces that must
   be remapped. */

    if (file_size == HP7905_SIZE)
        remap = 1;
    else if (file_size == HP7906_SIZE)
        remap = 2;
    else
        remap = 0;


/* If the image is a 7905 or 7906, it must be remapped it for the target system.
   To do that, check the OS signature to determine if it is in SIMH or HPDrive
   format, and set the "reversed" flag if the signature bytes in the image are
   reversed (this implies a platter-to-cylinder remapping of a 7905 or 7906
   image. */

    if (remap) {
        rewind (fin);
        file_size = fread (sig_fwd, 1, SIGNATURE_SIZE, fin);

        for (i = 0; i < SIGNATURE_SIZE; i = i + 2) {
            sig_rev [i]     = sig_fwd [i + 1];
            sig_rev [i + 1] = sig_fwd [i];
            }

        for (i = 0; i < signature_count && identified == false; i++) {
            reversed = strncmp (sig_rev, signatures [i], SIGNATURE_SIZE) == 0;
            identified = reversed || strncmp (sig_fwd, signatures [i], SIGNATURE_SIZE) == 0;
            }

/* If the signature cannot be identified, then we do not know how to remap it,
   so report the problem and exit. */

        if (identified == false) {
            printf ("Error: 790%i image OS signature not recognized.\n", remap + 4);
            fclose (fin);
            return 1;
            }
        }


/* Generate a temporary filename for the converted image. */

    name_out = tmpnam (NULL);

    if (name_out == NULL) {
        puts ("Error: cannot generate a temporary filename.");
        fclose (fin);
        return 1;
        }

/* Create the temporary target image. */

    fout = fopen (name_out, "wb");

    if (!fout) {
        printf ("Error: cannot create %s\n", name_out);
        fclose (fin);
        return 1;
        }

/* Report the conversion that will be performed. */

    if (remap)
        printf ("Converting and remapping 790%i %s disc image to %s format.\n",
                remap + 4,
                format [reversed],
                format [!reversed]);
    else
        puts ("Converting disc image.");


/* Enable debugging output if stdout has been redirected to a file. */

    debug = isatty (fileno (stdout)) == 0;


/* Copy the source to the target image while swapping each byte pair.  If the
   disc image is for a 7905 or 7906, remap from platter to cylinder mode (or
   vice-versa if the source image is not reversed).

   In a platter-mode image, the upper platter tracks appear in order before the
   lower platter tracks.  For the 7906, the cylinder-head order of the tracks is
   0-0, 0-1, 1-0, 1-1, ..., 410-0, 410-1, 0-2, 0-3, 1-2, 1-3, ..., 410-2, 410-3.
   The 7905 order is the same, except that head 3 tracks are omitted.

   In a cylinder-mode image, all tracks appear in cylinder-head order, i.e.,
   0-0, 0-1, 0-2, 0-3, 1-0, 1-1, ..., 410-2, 410-3, for the 7906.

   Remapping is performed in two passes, corresponding to the two platters.  In
   the first pass, the source tracks corresponding to the upper platter are
   spread (platter-to-cylinder) or condensed (cylinder-to-platter) as they are
   copied to the target file.  In the second pass, the source tracks
   corresponding to the lower platter are interleaved (platter-to-cylinder) or
   appended (cylinder-to-platter) as they are copied to the target file.

   In either case, the bytes of each 16-bit word are swapped before copying.
*/

    rewind (fin);

/* If the image is not a 7905/06, simply swap each pair of bytes until EOF. */

    if (!remap)
        while (!feof (fin)) {
            record_size = fread (cylinder, 1, CYLINDER_SIZE, fin);

            for (i = 0; i < record_size; i = i + 2) {
                hold = cylinder [i];
                cylinder [i] = cylinder [i + 1];
                cylinder [i + 1] = hold;
                }

            fwrite (cylinder, 1, record_size, fout);
            }

/* If the image is a 7905/06, remap the tracks and swap pairs of bytes.  Because
   we know the disc type, we know the number of platters and cylinders present
   in the image. */

    else
        for (platter = 0; platter < 2; platter++) {

/* Calculate the number of bytes per cylinder for the current platter.  The
   upper platter always has two tracks per cylinder.  The lower platter has
   either one (7905) or two (7906) tracks per cylinder. */

            if (platter == 0) {
                cylinder_size = TRACK_SIZE * 2;
                hole_size     = TRACK_SIZE * remap;
                }
            else {
                cylinder_size = TRACK_SIZE * remap;
                hole_size     = TRACK_SIZE * 2;
                }

/* Copy a platter. */

            for (cyl = 0; cyl < 411; cyl++) {

/* If stdout has been redirected, output the remapping information. */

                if (debug) {
                    from_cyl = ftell (fin) / TRACK_SIZE;
                    to_cyl   = ftell (fout) / TRACK_SIZE;

                    if (platter == 1 && remap == 1)
                        printf ("track %i => %i\n", from_cyl, to_cyl);
                    else
                        printf ("track %i, %i => %i, %i\n",
                                from_cyl, from_cyl + 1, to_cyl, to_cyl + 1);
                    }

/* Read a cylinder from the source location. */

                record_size = fread (cylinder, 1, cylinder_size, fin);

/* Swap the bytes. */

                for (i = 0; i < record_size; i = i + 2) {
                    hold = cylinder [i];
                    cylinder [i] = cylinder [i + 1];
                    cylinder [i + 1] = hold;
                    }

/* Write the cylinder to the target location. */

                fwrite (cylinder, 1, record_size, fout);

/* For platter-to-cylinder remapping, spread the tracks by seeking ahead in the
   target file; this leaves room for the lower-platter tracks in between the
   upper-platter tracks.  For cylinder-to-platter remapping, condense the
   cylinders by seeking ahead in the source file to the next track on the
   current platter. */

                if (reversed)
                    fseek (fout, hole_size, SEEK_CUR);
                else
                    fseek (fin, hole_size, SEEK_CUR);
                }


/* End of the current platter.  For platter-to-cylinder remapping, reposition
   the target file to the first "hole" left for the lower-platter tracks.  For
   cylinder-to-platter remapping, reposition the source file to access the first
   lower-platter tracks. */

            if (reversed)
                fseek (fout, cylinder_size, SEEK_SET);
            else
                fseek (fin, cylinder_size, SEEK_SET);
            }


/* Close the files. */

    fclose (fin);
    fclose (fout);


/* Delete the original file and replace it by the reversed file. */

    if (unlink (name_in)) {
        puts ("Error: cannot replace original file, which is unchanged.");
        unlink (name_out);
        return 1;
        }

    else if (rename (name_out, name_in)) {
        printf ("Error: cannot rename temporary file %s.\n", name_out);
        return 1;
        }


/* Return success. */

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60b0, %rsp           # imm = 0x60B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x2b80(%rip), %rax      # 0x3dd0
movq %rax, -0x20(%rbp)
movq 0x2b7d(%rip), %rax      # 0x3dd8
movq %rax, -0x18(%rbp)
movq 0x2b7a(%rip), %rax      # 0x3de0
movq %rax, -0x30(%rbp)
movq 0x2b77(%rip), %rax      # 0x3de8
movq %rax, -0x28(%rbp)
movl $0x2, -0x34(%rbp)
movb $0x0, -0x6081(%rbp)
movb $0x0, -0x6082(%rbp)
movb $0x0, -0x6083(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x12bb
leaq 0xd85(%rip), %rdi       # 0x2023
callq 0x1050
leaq 0xd90(%rip), %rdi       # 0x203a
callq 0x1050
movl $0x1, -0x4(%rbp)
jmp 0x196c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
leaq 0xd87(%rip), %rsi       # 0x2059
callq 0x10f0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x1300
movq -0x60(%rbp), %rsi
leaq 0xd6f(%rip), %rdi       # 0x205c
movb $0x0, %al
callq 0x1090
movl $0x1, -0x4(%rbp)
jmp 0x196c
movq -0x40(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x10e0
movq -0x40(%rbp), %rdi
callq 0x10b0
movq %rax, -0x50(%rbp)
cmpq $0xe73000, -0x50(%rbp)  # imm = 0xE73000
jne 0x1335
movl $0x1, -0x6098(%rbp)
jmp 0x1357
cmpq $0x1344000, -0x50(%rbp) # imm = 0x1344000
jne 0x134b
movl $0x2, -0x6098(%rbp)
jmp 0x1355
movl $0x0, -0x6098(%rbp)
jmp 0x1357
cmpl $0x0, -0x6098(%rbp)
je 0x14e4
movq -0x40(%rbp), %rdi
callq 0x10a0
leaq -0x70(%rbp), %rdi
movq -0x40(%rbp), %rcx
movl $0x1, %esi
movl $0x8, %edx
callq 0x1070
movq %rax, -0x50(%rbp)
movl $0x0, -0x6088(%rbp)
movslq -0x6088(%rbp), %rax
cmpq $0x8, %rax
jae 0x13e4
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb -0x70(%rbp,%rax), %cl
movslq -0x6088(%rbp), %rax
movb %cl, -0x78(%rbp,%rax)
movslq -0x6088(%rbp), %rax
movb -0x70(%rbp,%rax), %cl
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb %cl, -0x78(%rbp,%rax)
movl -0x6088(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x6088(%rbp)
jmp 0x1392
movl $0x0, -0x6088(%rbp)
xorl %eax, %eax
cmpl $0x2, -0x6088(%rbp)
movb %al, -0x60a5(%rbp)
jge 0x1416
movb -0x6081(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
sete %al
movb %al, -0x60a5(%rbp)
movb -0x60a5(%rbp), %al
testb $0x1, %al
jne 0x1425
jmp 0x14a6
leaq -0x78(%rbp), %rdi
movslq -0x6088(%rbp), %rax
movq -0x30(%rbp,%rax,8), %rsi
movl $0x8, %edx
callq 0x1040
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, -0x6082(%rbp)
movb $0x1, %al
testb $0x1, -0x6082(%rbp)
movb %al, -0x60a6(%rbp)
jne 0x1484
leaq -0x70(%rbp), %rdi
movslq -0x6088(%rbp), %rax
movq -0x30(%rbp,%rax,8), %rsi
movl $0x8, %edx
callq 0x1040
cmpl $0x0, %eax
sete %al
movb %al, -0x60a6(%rbp)
movb -0x60a6(%rbp), %al
andb $0x1, %al
movb %al, -0x6081(%rbp)
movl -0x6088(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6088(%rbp)
jmp 0x13ee
movb -0x6081(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x14e2
movl -0x6098(%rbp), %esi
addl $0x4, %esi
leaq 0xbad(%rip), %rdi       # 0x2073
movb $0x0, %al
callq 0x1090
movq -0x40(%rbp), %rdi
callq 0x1080
movl $0x1, -0x4(%rbp)
jmp 0x196c
jmp 0x14e4
xorl %eax, %eax
movl %eax, %edi
callq 0x1120
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
jne 0x1519
leaq 0xba5(%rip), %rdi       # 0x20a4
callq 0x1050
movq -0x40(%rbp), %rdi
callq 0x1080
movl $0x1, -0x4(%rbp)
jmp 0x196c
movq -0x68(%rbp), %rdi
leaq 0xbad(%rip), %rsi       # 0x20d1
callq 0x10f0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x155b
movq -0x68(%rbp), %rsi
leaq 0xb95(%rip), %rdi       # 0x20d4
movb $0x0, %al
callq 0x1090
movq -0x40(%rbp), %rdi
callq 0x1080
movl $0x1, -0x4(%rbp)
jmp 0x196c
cmpl $0x0, -0x6098(%rbp)
je 0x15a1
movl -0x6098(%rbp), %esi
addl $0x4, %esi
movb -0x6082(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movq -0x20(%rbp,%rax,8), %rdx
movb -0x6082(%rbp), %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cltq
movq -0x20(%rbp,%rax,8), %rcx
leaq 0xb55(%rip), %rdi       # 0x20ed
movb $0x0, %al
callq 0x1090
jmp 0x15ad
leaq 0xb81(%rip), %rdi       # 0x2129
callq 0x1050
movq 0x2a2c(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10d0
movl %eax, %edi
callq 0x1060
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, -0x6083(%rbp)
movq -0x40(%rbp), %rdi
callq 0x10a0
cmpl $0x0, -0x6098(%rbp)
jne 0x16b2
jmp 0x15e9
movq -0x40(%rbp), %rdi
callq 0x10c0
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1603
jmp 0x16ad
leaq -0x6080(%rbp), %rdi
movq -0x40(%rbp), %rcx
movl $0x1, %esi
movl $0x6000, %edx           # imm = 0x6000
callq 0x1070
movq %rax, -0x58(%rbp)
movl $0x0, -0x6088(%rbp)
movslq -0x6088(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x168f
movslq -0x6088(%rbp), %rax
movb -0x6080(%rbp,%rax), %al
movb %al, -0x79(%rbp)
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb -0x6080(%rbp,%rax), %cl
movslq -0x6088(%rbp), %rax
movb %cl, -0x6080(%rbp,%rax)
movb -0x79(%rbp), %cl
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb %cl, -0x6080(%rbp,%rax)
movl -0x6088(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x6088(%rbp)
jmp 0x162b
leaq -0x6080(%rbp), %rdi
movq -0x58(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x1, %esi
callq 0x1110
jmp 0x15e9
jmp 0x18f8
movl $0x0, -0x609c(%rbp)
cmpl $0x2, -0x609c(%rbp)
jge 0x18f6
cmpl $0x0, -0x609c(%rbp)
jne 0x16ee
movl $0x6000, -0x60a0(%rbp)  # imm = 0x6000
imull $0x3000, -0x6098(%rbp), %eax # imm = 0x3000
movl %eax, -0x60a4(%rbp)
jmp 0x1708
imull $0x3000, -0x6098(%rbp), %eax # imm = 0x3000
movl %eax, -0x60a0(%rbp)
movl $0x6000, -0x60a4(%rbp)  # imm = 0x6000
movl $0x0, -0x608c(%rbp)
cmpl $0x19b, -0x608c(%rbp)   # imm = 0x19B
jge 0x18b1
testb $0x1, -0x6083(%rbp)
je 0x17bf
movq -0x40(%rbp), %rdi
callq 0x10b0
movl $0x3000, %ecx           # imm = 0x3000
cqto
idivq %rcx
movl %eax, -0x6090(%rbp)
movq -0x48(%rbp), %rdi
callq 0x10b0
movl $0x3000, %ecx           # imm = 0x3000
cqto
idivq %rcx
movl %eax, -0x6094(%rbp)
cmpl $0x1, -0x609c(%rbp)
jne 0x178f
cmpl $0x1, -0x6098(%rbp)
jne 0x178f
movl -0x6090(%rbp), %esi
movl -0x6094(%rbp), %edx
leaq 0x9ba(%rip), %rdi       # 0x2140
movb $0x0, %al
callq 0x1090
jmp 0x17bd
movl -0x6090(%rbp), %esi
movl -0x6090(%rbp), %edx
addl $0x1, %edx
movl -0x6094(%rbp), %ecx
movl -0x6094(%rbp), %r8d
addl $0x1, %r8d
leaq 0x99a(%rip), %rdi       # 0x2150
movb $0x0, %al
callq 0x1090
jmp 0x17bf
leaq -0x6080(%rbp), %rdi
movslq -0x60a0(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl $0x1, %esi
callq 0x1070
movq %rax, -0x58(%rbp)
movl $0x0, -0x6088(%rbp)
movslq -0x6088(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x184d
movslq -0x6088(%rbp), %rax
movb -0x6080(%rbp,%rax), %al
movb %al, -0x79(%rbp)
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb -0x6080(%rbp,%rax), %cl
movslq -0x6088(%rbp), %rax
movb %cl, -0x6080(%rbp,%rax)
movb -0x79(%rbp), %cl
movl -0x6088(%rbp), %eax
addl $0x1, %eax
cltq
movb %cl, -0x6080(%rbp,%rax)
movl -0x6088(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x6088(%rbp)
jmp 0x17e9
leaq -0x6080(%rbp), %rdi
movq -0x58(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x1, %esi
callq 0x1110
testb $0x1, -0x6082(%rbp)
je 0x1886
movq -0x48(%rbp), %rdi
movslq -0x60a4(%rbp), %rsi
movl $0x1, %edx
callq 0x10e0
jmp 0x189b
movq -0x40(%rbp), %rdi
movslq -0x60a4(%rbp), %rsi
movl $0x1, %edx
callq 0x10e0
jmp 0x189d
movl -0x608c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x608c(%rbp)
jmp 0x1712
testb $0x1, -0x6082(%rbp)
je 0x18ce
movq -0x48(%rbp), %rdi
movslq -0x60a0(%rbp), %rsi
xorl %edx, %edx
callq 0x10e0
jmp 0x18e0
movq -0x40(%rbp), %rdi
movslq -0x60a0(%rbp), %rsi
xorl %edx, %edx
callq 0x10e0
jmp 0x18e2
movl -0x609c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x609c(%rbp)
jmp 0x16bc
jmp 0x18f8
movq -0x40(%rbp), %rdi
callq 0x1080
movq -0x48(%rbp), %rdi
callq 0x1080
movq -0x60(%rbp), %rdi
callq 0x1030
cmpl $0x0, %eax
je 0x1936
leaq 0x849(%rip), %rdi       # 0x2168
callq 0x1050
movq -0x68(%rbp), %rdi
callq 0x1030
movl $0x1, -0x4(%rbp)
jmp 0x196c
movq -0x68(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1100
cmpl $0x0, %eax
je 0x1963
movq -0x68(%rbp), %rsi
leaq 0x84e(%rip), %rdi       # 0x21a1
movb $0x0, %al
callq 0x1090
movl $0x1, -0x4(%rbp)
jmp 0x196c
jmp 0x1965
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60b0, %rsp           # imm = 0x60B0
popq %rbp
retq