HEX to BIN File Converter - CP/M

This is a discussion on HEX to BIN File Converter - CP/M ; I have just recreated the source code of 2 forgotten Programming Languages, which were, at one time, running on the MITS Altair 8800. Since I am planning to make CP/M versions of those interpreters, I used the standard 8080 assemblers ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: HEX to BIN File Converter

  1. HEX to BIN File Converter

    I have just recreated the source code of 2 forgotten Programming
    Languages, which were, at one time, running on the MITS Altair 8800.

    Since I am planning to make CP/M versions of those interpreters, I
    used the standard 8080 assemblers for CP/M: ASM and MAC (to get the
    SYMbol file, to debug them interactively with SID while seeing the
    name of the labels).

    Those 2 old PLs happens to either use data or "Restart points" in what
    is known as "Page Zero" under CP/M.

    This causes no problem with ASM or MAC, but the last versions of LOAD
    (HEXCOM under CP/M Plus) no longer accept to create a COM file from an
    HEX file containing data to be placed under 0100H, the location in
    memory where CP/M COMmand files are loaded.

    (There were several versions of LOAD. All were written in PL/M. Most
    people using CP/M 2.2 don't know it, but the first versions were able
    to read from an ASR-33 Teletype paper tape reader while producing the
    COM file.)

    Anyway, while communicating about the 2 above-mentioned PLs with the
    creator of the SIMH emulator, he asked me if I knew a way to create a
    BIN file from an Intel HEX file (outputted by ASM and MAC).

    Well, I know at least 3 ways to do it:

    1) The 8-bit versions of DDT and SID are able to read an Intel HEX
    file *AND* to add a "bias" to each record... This way, even if the HEX
    file says "load at 0000H", DDT/SID loads, in fact, at 0100H (for
    example). Once the file is loaded into the TPA, you simply save it as
    a COM file. (Don't forget to rename it!)

    2) Patch a version of LOAD, that will accept records below 0100H. Of
    course, you can take this opportunity to change the default filetype
    of the output file.

    3) Write a variation of LOAD in BASIC.

    But, first, let us define a little bit more what we means by "a BIN
    file".

    COM files are loading at 0100H.

    Most other special format files used by CP/M use 0000H.

    However, from time to time, for example for an interpreter to be burnt
    in ROM at the top of the memory, the start of the code to be loaded
    can be at any high address. Let us use F800 as an example.

    At the beginning, when I was using daily my NorthStar Horizon, I was
    naming my file with their load address as the last 4 characters of the
    file name. Example: MBASF800.BIN. The problem is that this leaves only
    4 chars for the file name... After a while, I thought about using the
    "page number". A page is the MSByte of an address, so range from 00H
    (hence the "Page Zero" of CP/M) to 0FFH. In short, that's 2 hex
    digits. To get a CP/M filetype, I simply added the P for page, thus
    getting: FILENAME.P00 etc, until FILENAME.PFF. This way, I had access
    to 8-characters filenames, with the indication of the page number
    where to load the binary file. (Of course, you need to use a page
    "boundary", but, to the human mind, it is easier to remember a memory
    location ending with lots of zeroes...)

    The little CP/M utility that you will find below happens to use a
    simple BIN filetype, because it is only intended to produce files
    loading at 0000H. (So, remember that BIN filetype = "Loading at
    0000H".) It is a "Quick And Dirty" patch of the CP/M Plus' HEXCOM,
    because HEXCOM is written totally in 8080 assembly language, rather
    than PL/M like CP/M 2.2's LOAD, and thus is about twice faster than
    LOAD. On a floppy, you feel the difference.

    (Warning: If you use it with a file starting at F800 (for example),
    you will get a 61K file, the first 60K being filled with 00H... In
    this case, either you keep using Good Old Intel HEX files, or you
    create a program that would take the load address on the command tail
    and would skip generating any filler byte before.)

    The less than can be said is that you don't create very often, under
    CP/M, a file loading at 0000H, but, when you need to recreate some old
    MITS or IMSAI source code, such an utility could be useful, as you can
    then put it in a SUBmit file, instead of doing it manually with
    DDT/SID.

    (I was forgetting: the utility is called HEXBIN.)

    :10010000C3800100000000000000000000000000AB
    :1001100000000000000000000000000000000000DF
    :1001200000000000000000000000000000000000CF
    :1001300000000000000000000000000000000000BF
    :1001400043502F4D2056657273696F6E20332E30E9
    :10015000434F5059524947485420313938322C20A6
    :100160004449474954414C20524553454152434824
    :100170003235313038320000000036353433323118
    :100180002100003922660531AE05114205CD080473
    :10019000115C00216805D5E50E211A7713230DC2E5
    :1001A0009A012171053648233645233658216500CA
    :1001B000364223364923364ED10E0FCD05003C1171
    :1001C0000905CA0D04D1D50E13CD0500D1D50E16E3
    :1001D000CD05003C112105CA0D043A0700D6106771
    :1001E0002E00228A05D6072E8067228C05CD3A0480
    :1001F000CD4E03FE3AC2F001CDC802328905CA696C
    :1002000002215B058677D20B022334CDC802F5CDDF
    :10021000C802E16F225E05EB2A60057B956F7A9C30
    :10022000672263052A58057CB5C23B0211CB04CD79
    :1002300003042A5E05225705CDDB03CDC802CDC8D5
    :1002400002CD740321890535C23E022A5905EBCD42
    :1002500049047B957A9CD25D022B225905CDC802B8
    :10026000CAF00111BB04C3F20211DA04CD03042A5F
    :100270005905CDDB0311E904CD03042A5B05CDDB71
    :10028000032A6305E511800619228A0521650534D4
    :10029000E12601226305228C05CD740311F804CDFB
    :1002A00003043A5D05CDE203CDF903D10E10CD056F
    :1002B000003C113005CA0D04CDF9031180000E1A5F
    :1002C000CD05002A6605F9C9CDDD0287878787F548
    :1002D000CDDD02C1B047216205867778C9CD4E03D6
    :1002E000D630FE0AD8D607FE0ADAEF02FE10D81181
    :1002F000A904CD0304118B04CD03042A5E05CDDBD4
    :1003000003119A04CD0304CD4904CDDB0311E904A4
    :10031000CD0304CD27042A5E05EBCD49047B957AF5
    :100320009CD2B8027BE60FCC27042A5E05EB2A603C
    :10033000057B956F7A9C67018006097ECDE2032AD2
    :100340005E0523225E053E20CDF303C316033A5615
    :10035000053CF26C031100060E1ACD05001168056C
    :100360000E14CD0500B7115B04C20D0432560526EC
    :10037000066F7EC9F52A6305EB3A8D053DBAD2CFEB
    :10038000032A8C057B954F7A9C47C5EB2A6005199B
    :100390002260052A8A051180067B957A9CD2C403C7
    :1003A000E5D50E1ACD05000E15115C00CD0500B780
    :1003B000118004C20D04D121800019EB215D0534A8
    :1003C000E1C399033A6505B7CC3A04D1C379032157
    :1003D000800619F17713EB226305C9E57CCDE203B2
    :1003E000E17DF50F0F0F0FCDEB03F1E60FC6902760
    :1003F000CE40275F0E02C305003E0DCDF3033E0A3B
    :10040000C3F303D5CDF903D10E09C30500D51153AC
    :1004100004CD0304D1CD0804118B04CD0304CD49D0
    :1004200004CDDB03C3BB02CDF9032A5E05CDDB039C
    :100430003E3ACDF3033E20C3F3032180063A8B05F9
    :100440000E007123BCC24204C92A6005444D2A63D0
    :100450000509C94552524F523A20244449534B2072
    :1004600052454144244C4F41442041444452455359
    :1004700053204C455353205448414E2031303024B2
    :100480004449534B205752495445244C4F41442032
    :10049000204144445245535320244552524F522048
    :1004A000414444524553532024494E56414C4944FB
    :1004B0002048455820444947495424434845434B24
    :1004C00053554D204552524F5220244649525354C1
    :1004D000204144445245535320244C41535420203E
    :1004E00041444452455353202442595445532052C9
    :1004F00045414420202020245245434F524453205C
    :100500005752495454454E202443414E4E4F542097
    :100510004F50454E20534F555243452046494C4578
    :10052000244449524543544F52592046554C4C247B
    :1005300043414E4E4F5420434C4F53452046494C67
    :10054000452448455842494E09564552533A2031B0
    :100550002E30300D0A247F00000000000000000053
    :0605600000000000000095
    :0000000000

    Yours Sincerely,
    "French Luser"


  2. Re: HEX to BIN File Converter


    Are you familiar with Ron
    Fowler's MLOAD and/or Hal
    Bower's MYLOAD? Iirc
    they both corrected all
    the feature shortcomings
    of LOAD and HEXCOM.


    French Luser wrote:

    >I have just recreated the source code of 2 forgotten Programming
    >Languages, which were, at one time, running on the MITS Altair 8800.
    >
    >Since I am planning to make CP/M versions of those interpreters, I
    >used the standard 8080 assemblers for CP/M: ASM and MAC (to get the
    >SYMbol file, to debug them interactively with SID while seeing the
    >name of the labels).
    >
    >Those 2 old PLs happens to either use data or "Restart points" in what
    >is known as "Page Zero" under CP/M.
    >
    >This causes no problem with ASM or MAC, but the last versions of LOAD
    >(HEXCOM under CP/M Plus) no longer accept to create a COM file from an
    >HEX file containing data to be placed under 0100H, the location in
    >memory where CP/M COMmand files are loaded.
    >
    >(There were several versions of LOAD. All were written in PL/M. Most
    >people using CP/M 2.2 don't know it, but the first versions were able
    >to read from an ASR-33 Teletype paper tape reader while producing the
    >COM file.)
    >
    >Anyway, while communicating about the 2 above-mentioned PLs with the
    >creator of the SIMH emulator, he asked me if I knew a way to create a
    >BIN file from an Intel HEX file (outputted by ASM and MAC).
    >
    >Well, I know at least 3 ways to do it:
    >
    >1) The 8-bit versions of DDT and SID are able to read an Intel HEX
    >file *AND* to add a "bias" to each record... This way, even if the HEX
    >file says "load at 0000H", DDT/SID loads, in fact, at 0100H (for
    >example). Once the file is loaded into the TPA, you simply save it as
    >a COM file. (Don't forget to rename it!)
    >
    >2) Patch a version of LOAD, that will accept records below 0100H. Of
    >course, you can take this opportunity to change the default filetype
    >of the output file.
    >
    >3) Write a variation of LOAD in BASIC.
    >
    >But, first, let us define a little bit more what we means by "a BIN
    >file".
    >
    >COM files are loading at 0100H.
    >
    >Most other special format files used by CP/M use 0000H.
    >
    >However, from time to time, for example for an interpreter to be burnt
    >in ROM at the top of the memory, the start of the code to be loaded
    >can be at any high address. Let us use F800 as an example.
    >
    >At the beginning, when I was using daily my NorthStar Horizon, I was
    >naming my file with their load address as the last 4 characters of the
    >file name. Example: MBASF800.BIN. The problem is that this leaves only
    >4 chars for the file name... After a while, I thought about using the
    >"page number". A page is the MSByte of an address, so range from 00H
    >(hence the "Page Zero" of CP/M) to 0FFH. In short, that's 2 hex
    >digits. To get a CP/M filetype, I simply added the P for page, thus
    >getting: FILENAME.P00 etc, until FILENAME.PFF. This way, I had access
    >to 8-characters filenames, with the indication of the page number
    >where to load the binary file. (Of course, you need to use a page
    >"boundary", but, to the human mind, it is easier to remember a memory
    >location ending with lots of zeroes...)
    >
    >The little CP/M utility that you will find below happens to use a
    >simple BIN filetype, because it is only intended to produce files
    >loading at 0000H. (So, remember that BIN filetype = "Loading at
    >0000H".) It is a "Quick And Dirty" patch of the CP/M Plus' HEXCOM,
    >because HEXCOM is written totally in 8080 assembly language, rather
    >than PL/M like CP/M 2.2's LOAD, and thus is about twice faster than
    >LOAD. On a floppy, you feel the difference.
    >
    >(Warning: If you use it with a file starting at F800 (for example),
    >you will get a 61K file, the first 60K being filled with 00H... In
    >this case, either you keep using Good Old Intel HEX files, or you
    >create a program that would take the load address on the command tail
    >and would skip generating any filler byte before.)
    >
    >The less than can be said is that you don't create very often, under
    >CP/M, a file loading at 0000H, but, when you need to recreate some old
    >MITS or IMSAI source code, such an utility could be useful, as you can
    >then put it in a SUBmit file, instead of doing it manually with
    >DDT/SID.
    >
    >(I was forgetting: the utility is called HEXBIN.)
    >
    >:10010000C3800100000000000000000000000000AB
    >:1001100000000000000000000000000000000000DF
    >:1001200000000000000000000000000000000000CF
    >:1001300000000000000000000000000000000000BF
    >:1001400043502F4D2056657273696F6E20332E30E9
    >:10015000434F5059524947485420313938322C20A6
    >:100160004449474954414C20524553454152434824
    >:100170003235313038320000000036353433323118
    >:100180002100003922660531AE05114205CD080473
    >:10019000115C00216805D5E50E211A7713230DC2E5
    >:1001A0009A012171053648233645233658216500CA
    >:1001B000364223364923364ED10E0FCD05003C1171
    >:1001C0000905CA0D04D1D50E13CD0500D1D50E16E3
    >:1001D000CD05003C112105CA0D043A0700D6106771
    >:1001E0002E00228A05D6072E8067228C05CD3A0480
    >:1001F000CD4E03FE3AC2F001CDC802328905CA696C
    >:1002000002215B058677D20B022334CDC802F5CDDF
    >:10021000C802E16F225E05EB2A60057B956F7A9C30
    >:10022000672263052A58057CB5C23B0211CB04CD79
    >:1002300003042A5E05225705CDDB03CDC802CDC8D5
    >:1002400002CD740321890535C23E022A5905EBCD42
    >:1002500049047B957A9CD25D022B225905CDC802B8
    >:10026000CAF00111BB04C3F20211DA04CD03042A5F
    >:100270005905CDDB0311E904CD03042A5B05CDDB71
    >:10028000032A6305E511800619228A0521650534D4
    >:10029000E12601226305228C05CD740311F804CDFB
    >:1002A00003043A5D05CDE203CDF903D10E10CD056F
    >:1002B000003C113005CA0D04CDF9031180000E1A5F
    >:1002C000CD05002A6605F9C9CDDD0287878787F548
    >:1002D000CDDD02C1B047216205867778C9CD4E03D6
    >:1002E000D630FE0AD8D607FE0ADAEF02FE10D81181
    >:1002F000A904CD0304118B04CD03042A5E05CDDBD4
    >:1003000003119A04CD0304CD4904CDDB0311E904A4
    >:10031000CD0304CD27042A5E05EBCD49047B957AF5
    >:100320009CD2B8027BE60FCC27042A5E05EB2A603C
    >:10033000057B956F7A9C67018006097ECDE2032AD2
    >:100340005E0523225E053E20CDF303C316033A5615
    >:10035000053CF26C031100060E1ACD05001168056C
    >:100360000E14CD0500B7115B04C20D0432560526EC
    >:10037000066F7EC9F52A6305EB3A8D053DBAD2CFEB
    >:10038000032A8C057B954F7A9C47C5EB2A6005199B
    >:100390002260052A8A051180067B957A9CD2C403C7
    >:1003A000E5D50E1ACD05000E15115C00CD0500B780
    >:1003B000118004C20D04D121800019EB215D0534A8
    >:1003C000E1C399033A6505B7CC3A04D1C379032157
    >:1003D000800619F17713EB226305C9E57CCDE203B2
    >:1003E000E17DF50F0F0F0FCDEB03F1E60FC6902760
    >:1003F000CE40275F0E02C305003E0DCDF3033E0A3B
    >:10040000C3F303D5CDF903D10E09C30500D51153AC
    >:1004100004CD0304D1CD0804118B04CD0304CD49D0
    >:1004200004CDDB03C3BB02CDF9032A5E05CDDB039C
    >:100430003E3ACDF3033E20C3F3032180063A8B05F9
    >:100440000E007123BCC24204C92A6005444D2A63D0
    >:100450000509C94552524F523A20244449534B2072
    >:1004600052454144244C4F41442041444452455359
    >:1004700053204C455353205448414E2031303024B2
    >:100480004449534B205752495445244C4F41442032
    >:10049000204144445245535320244552524F522048
    >:1004A000414444524553532024494E56414C4944FB
    >:1004B0002048455820444947495424434845434B24
    >:1004C00053554D204552524F5220244649525354C1
    >:1004D000204144445245535320244C41535420203E
    >:1004E00041444452455353202442595445532052C9
    >:1004F00045414420202020245245434F524453205C
    >:100500005752495454454E202443414E4E4F542097
    >:100510004F50454E20534F555243452046494C4578
    >:10052000244449524543544F52592046554C4C247B
    >:1005300043414E4E4F5420434C4F53452046494C67
    >:10054000452448455842494E09564552533A2031B0
    >:100550002E30300D0A247F00000000000000000053
    >:0605600000000000000095
    >:0000000000
    >
    >Yours Sincerely,
    >"French Luser"



  3. Re: HEX to BIN File Converter

    On Fri, 11 Aug 2006 13:26:11 +0200, French Luser
    wrote:

    >I have just recreated the source code of 2 forgotten Programming
    >Languages, which were, at one time, running on the MITS Altair 8800.
    >
    >Since I am planning to make CP/M versions of those interpreters, I
    >used the standard 8080 assemblers for CP/M: ASM and MAC (to get the
    >SYMbol file, to debug them interactively with SID while seeing the
    >name of the labels).
    >
    >Those 2 old PLs happens to either use data or "Restart points" in what
    >is known as "Page Zero" under CP/M.
    >
    >This causes no problem with ASM or MAC, but the last versions of LOAD
    >(HEXCOM under CP/M Plus) no longer accept to create a COM file from an
    >HEX file containing data to be placed under 0100H, the location in
    >memory where CP/M COMmand files are loaded.
    >
    >(There were several versions of LOAD. All were written in PL/M. Most
    >people using CP/M 2.2 don't know it, but the first versions were able
    >to read from an ASR-33 Teletype paper tape reader while producing the
    >COM file.)


    So were the later ones, least all the copies I have through those
    supplied with V1.4 through V2.2.

    To solve the problem of .BIN files and loading them I created (around
    thre decades ago) a simple monitor with a HEX->BIN loader that
    allowed me to specify an absolute load address (not an offset like
    DDT). It also can load a .BIN file at any address. The program
    itself runs under cp/m and and the first code section copies itself
    to a safe area (9000h is rarely used) and then allows overlaying
    the file to be loaded in low ram (Page zero) or it can load and move
    so that the file can overlay CP/M (the monitor has it's own IO
    package). It wasn't rocket science then.

    Another package that is very handy is UNLOAD.COM as it does
    bin-->hex making it easier for those pesky ascii only transfers.

    Its primary use was to load and run MITS 8K BASIC (low ram) or
    Netronics MSBASIC 8K (rommable at C000h) along with a few
    other of my own projects including CP/M BIOS development.
    I still use it or a derivitive that adds it's own disk drivers for
    BIOS development.


    Allison




  4. Re: HEX to BIN File Converter

    French Luser wrote:

    >
    > The little CP/M utility that you will find below happens to use a
    > simple BIN filetype, because it is only intended to produce files
    > loading at 0000H.


    You may also try this:

    /*
    * load - convert a hex file to a com file
    *
    * Expanded to HEXCOM by John Elliott, 25-5-1998
    *
    * Compiles with gcc or Pacific C
    *
    */

    #include
    #include

    unsigned char checksum;
    int L;

    FILE *fpout;

    unsigned char getbyte () {
    register int c;
    unsigned char x;

    c = getchar ();
    if ('0' <= c && c <= '9')
    x = c - '0';
    else
    if ('A' <= c && c <= 'F')
    x = c - 'A' + 10;
    else
    goto funny;

    x <<= 4;
    c = getchar ();
    if ('0' <= c && c <= '9')
    x |= c - '0';
    else
    if ('A' <= c && c <= 'F')
    x |= c - 'A' + 10;
    else {
    funny:
    fprintf (stderr, "Funny hex letter %c\n", c);
    exit (2);
    }
    checksum += x;
    return x;
    }

    main (int argc, char **argv) {
    register unsigned i, n;
    char c, buf[64];
    unsigned type;
    unsigned int al, ah, addr = 0, naddr;

    L = 0;
    if (argc < 2) fpout = stdout;
    else fpout = fopen(argv[1],"wb");

    do {
    do {
    c = getchar ();
    if (c == EOF) {
    fprintf (stderr, "Premature EOF colon missing\n");
    exit (1);
    }
    } while (c != ':');

    ++L;
    checksum = 0;
    n = getbyte (); /* bytes / line */
    ah = getbyte ();
    al = getbyte ();


    switch (type = getbyte ())
    {
    case 0:
    if (!n) /* MAC uses a line with no bytes as EOF */
    {
    type = 1;
    break;
    }
    naddr = (ah << 8) | al;
    if (!addr) addr = naddr;
    else while (addr < naddr)
    {
    fwrite("", 1, 1, fpout);
    ++addr;
    }
    if (addr > naddr)
    {
    fprintf(stderr,
    "Line %d: Records out of sequence at %x > %x\n",
    L, naddr, addr);
    exit(1);
    }

    for (i = 0; i < n; i++)
    buf[i] = getbyte ();
    fwrite (buf, 1, n, fpout);
    break;

    case 1:
    break;

    default:
    fprintf (stderr, "Line %d: Funny record type %d\n", L, type);
    exit (1);
    }

    (void) getbyte ();
    if (checksum != 0)
    {
    fprintf (stderr, "Line %d: Checksum error", L);
    exit (2);
    }

    addr += n;

    } while (type != 1);
    exit(0);
    }


    Piergiorgio



  5. Re: HEX to BIN File Converter

    Bruce wrote:

    >Are you familiar with Ron
    >Fowler's MLOAD and/or Hal
    >Bower's MYLOAD? Iirc
    >they both corrected all
    >the feature shortcomings
    >of LOAD and HEXCOM.


    No, I have never used them, prefering (at the time) to keep using the
    standard CP/M tools. (For some unknown reason, all the CP/M books and
    articles with CP/M assembly language programs I have used only ASM and
    DDT, while Digital Research was "offering" MAC and SID for serious
    assembly language programming. Me, I used, of course, the latter ones
    for 8080 ASM programming.) (Micro**** never sold a Z-80 debugger,
    since their software was developed under an emulator running under
    Unix on a DEC VAX. That's why the M80 manual says to use ZSID, and
    that L80 contains a switch generating SYMbol files for ZSID.) (You can
    also use it under SID.)

    Yours Sincerely,
    "French Luser"


  6. Re: HEX to BIN File Converter

    Allison wrote:

    >To solve the problem of .BIN files and loading them I created (around
    >thre decades ago) a simple monitor with a HEX->BIN loader that
    >allowed me to specify an absolute load address (not an offset like
    >DDT). It also can load a .BIN file at any address. The program
    >itself runs under cp/m and and the first code section copies itself
    >to a safe area (9000h is rarely used) and then allows overlaying
    >the file to be loaded in low ram (Page zero) or it can load and move
    >so that the file can overlay CP/M (the monitor has it's own IO
    >package). It wasn't rocket science then.


    I am afraid that there is a little misunderstanding from your part,
    Allison.

    I am not talking about "loading a file into memory" (that's the
    purpose of HEX files): I am talking about creating a BINary file (that
    is to say, containing stuff that needs to be loaded at a particular
    address, in the present case 0000H) despite the fact that both LOAD
    and HEXCOM refuse to create a file that is not starting at 0100H, the
    start of the TPA of CP/M.

    It is not a file-to-memory utility: it is a file-to-file utility.

    This way, I can assemble (and compare) files produced under CP/M with
    files (loading at 0000H) produced under other DOSes or Monitors (like
    the ones for MITS and IMSAI).

    (This could be useful if one wanted, for example, to recreate the
    source code of "4K BASIC"...)

    Yours Sincerely,
    "French Luser"


+ Reply to Thread