X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcommon%2Fhexfile.c;h=c9c7de32ce9e8de8e90a4225254b7d6ea595cc1f;hb=fbbb71d6d8aa93bccc87b17408a89432e4b8161c;hp=6411166c5e8e80d97225e865902dcb0d2ec3e43d;hpb=1eb382f72510d50b3636fb88c4bfaf17183672b6;p=emu8051.git diff --git a/src/common/hexfile.c b/src/common/hexfile.c index 6411166..c9c7de3 100644 --- a/src/common/hexfile.c +++ b/src/common/hexfile.c @@ -4,28 +4,16 @@ * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * This file is released under the GPLv2 */ #if HAVE_CONFIG_H # include "config.h" #endif -#include #include #include +#include #if STDC_HEADERS # include @@ -36,16 +24,21 @@ #include "common.h" #include "memory.h" +/* Maximum of 75 digits with 32-bytes data records. */ +#define HEXFILE_LINE_BUFFER_LEN 128 + +static int asciihex2int_error; + /* Convert integer to ASCII hex string. */ void int2asciihex(int val, char *str, int width) { if (width == 1) - sprintf(str , "%.1X", (u_int8_t) val); + sprintf(str , "%.1X", (uint8_t) val); else if (width == 2) - sprintf(str , "%.2X", (u_int8_t) val); + sprintf(str , "%.2X", (uint8_t) val); else if (width == 4) - sprintf(str , "%.4X", (u_int16_t) val); + sprintf(str , "%.4X", (uint16_t) val); else sprintf(str , "Err"); } @@ -55,15 +48,21 @@ int asciihex2int(char *str) { int val; + int rc; + + rc = sscanf(str, "%X", &val); - sscanf(str, "%X", &val); + if (rc == 0) { + log_err("ASCII to hex conversion failure"); + asciihex2int_error = true; + } return val; } /* Convert an ascii string to an hexadecimal number. */ -unsigned int -Ascii2Hex(char *istring, int length) +static unsigned int +asciihex2int_len(char *istring, int length) { unsigned int result = 0; int i, ascii_code; @@ -77,7 +76,7 @@ Ascii2Hex(char *istring, int length) ascii_code &= 0xDF; if ((ascii_code >= 0x30 && ascii_code <= 0x39) || - (ascii_code >= 0x41 && ascii_code <= 0x46)) { + (ascii_code >= 0x41 && ascii_code <= 0x46)) { ascii_code -= 0x30; if (ascii_code > 9) ascii_code -= 7; @@ -85,35 +84,38 @@ Ascii2Hex(char *istring, int length) result <<= 4; result += ascii_code; } else { - printf("%s: In Ascii2Hex(), syntax error.\n", PACKAGE); - printf(" str=%s, length=%d\n", istring, length); + log_err("ASCII to hex conversion failure"); + asciihex2int_error = true; } } return result; } -void -LoadHexFile(const char *filename) +/* + * Return value: + * true: success + * false: failure + */ +int +hexfile_load(const char *filename) { - int i, j, RecLength, LoadOffset, RecType, Data, Checksum; - -#define LINE_BUFFER_LEN 256 + int i, j, rec_len, load_offset, rec_type, data, checksum; FILE *fp; int status; - char line[LINE_BUFFER_LEN]; + char line[HEXFILE_LINE_BUFFER_LEN]; + int valid = false; + int line_num = 1; - if (filename == NULL) { - printf("%s: No file specified\n", PACKAGE); - exit(EXIT_FAILURE); - } + log_debug("LoadHexFile"); + + if (filename == NULL) + log_fail("No file specified"); /* Trying to open the file. */ fp = fopen(filename, "r"); - if (fp == NULL) { - perror(filename); - /*ErrorLocation(__FILE__, __LINE__);*/ - exit(EXIT_FAILURE); - } + if (fp == NULL) + log_fail("Error opening hex file <%s>: %s", filename, + strerror(errno)); /* Reading one line of data from the hex file. */ /* char *fgets(char *s, int size, FILE *stream); @@ -121,66 +123,71 @@ LoadHexFile(const char *filename) stored into the buffer. A '\0' is stored after the last character in the buffer. */ - while (fgets(line, LINE_BUFFER_LEN, fp) != NULL) { + while (fgets(line, HEXFILE_LINE_BUFFER_LEN, fp) != NULL) { i = 0; - Checksum = 0; + checksum = 0; if (line[i++] != ':') { - printf("%s: line not beginning with \":\"\n", PACKAGE); + log_err("hexfile line not beginning with \":\""); goto close_file; } - RecLength = Ascii2Hex(&line[i], 2); + rec_len = asciihex2int_len(&line[i], 2); i += 2; - Checksum += RecLength; + checksum += rec_len; - LoadOffset = Ascii2Hex(&line[i], 4); - Checksum += LoadOffset / 256; - Checksum += LoadOffset % 256; + load_offset = asciihex2int_len(&line[i], 4); + checksum += load_offset / 256; + checksum += load_offset % 256; i += 4; - RecType = Ascii2Hex(&line[i], 2); + rec_type = asciihex2int_len(&line[i], 2); i += 2; - Checksum += RecType; - - if (RecType == 1) { - Checksum += Ascii2Hex(&line[i], 2); - Checksum &= 0x000000FF; - - if (Checksum) { - /* Error. */ - printf("%s: Invalid format\n", PACKAGE); - goto close_file; - } else { - /* OK */ - goto close_file; + checksum += rec_type; + + if (rec_type == 0) { + for (j = 0; j < rec_len; j++) { + data = asciihex2int_len(&line[i], 2); + mem_write8(PGM_MEM_ID, + (unsigned int) (load_offset + j), + (unsigned char) data); + i += 2; + checksum += data; } } - for (j = 0; j < RecLength; j++) { - Data = Ascii2Hex(&line[i], 2); - memory_write8(PGM_MEM_ID, - (unsigned int)(LoadOffset + j), - (unsigned char)Data); - i += 2; - Checksum += Data; - } + /* Read and add checksum value */ + checksum += asciihex2int_len(&line[i], 2); + checksum &= 0x000000FF; - RecType = Ascii2Hex(&line[i], 2); - Checksum += RecType; - Checksum &= 0x000000FF; + if (asciihex2int_error) { + log_err("hexfile parse error at line %d", line_num); + goto close_file; + } else if (checksum) { + log_err("hexfile checksum mismatch"); + goto close_file; + } - if (Checksum) { - printf("%s: Invalid format\n", PACKAGE); + if (rec_type == 0) { + log_debug("hex record: data"); + } else if (rec_type == 1) { + log_debug("hex record: End Of File"); + valid = true; goto close_file; + } else { + log_warn("hex record: Unsupported ($%02X)", rec_type); } + + line_num++; } close_file: status = fclose(fp); - if (status != EXIT_SUCCESS) { - fprintf(stderr, "%s: Error closing hex file.\n", PACKAGE); - /*ErrorLocation(__FILE__, __LINE__);*/ - exit(EXIT_FAILURE); - } + if (status != EXIT_SUCCESS) + log_fail("Error closing hex file"); + + if (!valid) + log_err("Error parsing hex file"); + + return valid; }