⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unload.c

📁 Embedded magazine source code. this is the source code in the year 1989
💻 C
字号:
/*
    UNLOAD.C    Convert binary file to Intel hex file.

    Copyright (C) 1989 Ray Duncan

    Compile:    CL UNLOAD.C

    Usage:      UNLOAD filename.ext [-address]

                After the program terminates, filename.ext 
                is unchanged, and filename.HEX is created.
                The optional load address defaults to zero; 
                if supplied, it is assumed to be hex, e.g. 

                UNLOAD MYFILE.BIN -8000
*/

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>

#define  RECSIZE  16                /* input file max read length */
#define  DATAREC   0                /* data record type */
#define  EOFREC    1                /* end-of-file record type */

void wbuff(void);                   /* local function prototypes */
void wchar(char);
void wnibl(unsigned);
void wbyte(unsigned);
void wword(unsigned);
void whead(void);
void wcsum(void);
void weof(void);
void wrec(char *, int);

char ibuff[RECSIZE];                /* input file buffer */
char obuff[80];                     /* output file buffer */
int optr = 0;                       /* current output buffer offset */
unsigned addr = 0;                  /* load address */
unsigned csum;                      /* record checksum */
unsigned ifh;                       /* handle for input file */
unsigned ofh;                       /* handle for output file */

main(int argc, char *argv[])
{
    int rdlen;                      /* actual length of read */
    char iname[80];                 /* name of input file */
    char oname[80];                 /* name of output file */
    char *p;                        /* scratch pointer */

    if(argc < 2)                    /* make sure filename present */
    {
        fprintf(stderr, "\nusage: unload filename.ext [-address]\n");
        exit(1);
    }

    if(argc == 3)                   /* convert load address if any */
    {
        if(*argv[2] == '-')
            addr = (unsigned) strtoul(argv[2]+1, &p, 16);
        else
        {
            fprintf(stderr, "\nunload: bad load address\n");
            exit(1);
        }
    }

    strcpy(iname, argv[1]);         /* get input filename */
    strcpy(oname, argv[1]);         /* build output filename */
    if(! (p = strchr(oname, '.')))  /* clip off existing */
        p = strchr(oname, '\0');    /* extension (if any) */
    strcpy(p, ".hex");              /* append new extension */

                                    /* open input file */
    if((ifh = open(iname, O_RDONLY|O_BINARY)) == -1)
    {
        fprintf(stderr, "\nunload: can't find input file\n");
        exit(1);
    }

                                    /* create output file */
    if((ofh = open(oname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IWRITE)) == -1)
    {
        fprintf(stderr, "\nunload: can't create output file\n");
        exit(1);
    }

    printf("\nInput file:\t%s", strlwr(iname));
    printf("\nOutput file:\t%s", strlwr(oname));
    printf("\nLoad address:\t%04xh\n", addr);

                                    /* read binary data */
    while(rdlen = read(ifh, ibuff, RECSIZE))
        wrec(ibuff, rdlen);         /* write Intel hex record */
    
    weof();                         /* write end-of-file record */

    close(ifh);                     /* close input file */
    close(ofh);                     /* close output file */
}

/*
    WBUFF:  write contents of output buffer to output file,
            reset output buffer pointer.
*/
void wbuff(void)
{
    write(ofh, obuff, optr);        /* write data waiting in buffer */
    optr = 0;                       /* reset output buffer pointer */
}

/*
    WCHAR:  put one character into output buffer, increment
            output buffer pointer.
*/
void wchar(char data)
{
    obuff[optr++] = data;           /* put character in output buffer */
}

/*                                  
    WNIBL:  convert 4 bits to ASCII character, send to output buffer.
*/
void wnibl(unsigned data)
{
    data = (data & 0x0f) + '0';     /* mask and convert to ASCII */
    if(data > '9') data += ('A' - '9' - 1);
    wchar(data);                    /* write ASCII character */
}

/*
    WBYTE:  convert 8 bits to 2 ASCII characters, send to output buffer.
*/
void wbyte(unsigned data)
{
    csum += data & 0x0ff;           /* update checksum */
    wnibl(data >> 4);               /* write upper 4 bits */
    wnibl(data);                    /* write lower 4 bits */
}

/*
    WWORD: convert 16 bits to 4 ASCII characters, send to output buffer.
*/
void wword(unsigned data)
{
    wbyte(data >> 8);               /* write high byte */
    wbyte(data);                    /* write low byte */
}

/*
    WHEAD:  put start of record marker into output buffer,
            initialize record checksum.
*/
void whead(void)
{
    wchar(':');                     /* write start-of-record marker */
    csum = 0;                       /* initialize checksum */
}

/*
    WCSUM:  Put checksum and logical end-of-line into output buffer, 
            write output buffer to output file.  Logical end-of-line
            should be modified as needed for the host operating system.
*/
void wcsum(void)
{
    wbyte(-csum);                   /* write negative checksum */
    wchar(0x0d); wchar(0x0a);       /* write logical end-of-line */
    wbuff();                        /* write buffer to file */
}

/*
    WEOF:   Send special end-of-file record to output file.
*/
void weof(void)
{
    whead();                        /* write record header */
    wbyte(0);                       /* write length of data */
    wword(0);                       /* write load address */
    wbyte(EOFREC);                  /* write EOF record type */
    wcsum();                        /* write checksum */
}

/*
    WREC:   Write one data record to output.
*/
void wrec(char *ibuff, int rdlen)
{
    int i;                          /* scratch variable */

    whead();                        /* write record header */
    wbyte(rdlen);                   /* write length of data */
    wword(addr);                    /* write current load address */
    wbyte(DATAREC);                 /* write DATA record type */

    for(i = 0; i < rdlen; i++)      /* write actual data */
        wbyte(ibuff[i]);

    wcsum();                        /* write record checksum */
    addr += rdlen;                  /* advance load address */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -