Exemple #1
0
/*
 * Format parser
 *
 * Return program data line count
 */
int
inhx32(const char *filename)
{
	FILE *f1;
	char line[STRLEN];
	unsigned int extended_address = 0, bb, ix;
	int n;
	unsigned char tt = TT_DATA, cc;
	unsigned short aaaa;
	void *root = NULL;
	inhx32_data *inhx32 = NULL;

	inhx32_count = 0;
	inhx32_pdata = NULL;
	
	if ((f1 = fopen(filename, "rb")) == NULL) {
		printf("%s: error: file open failed [%s] [%s]\n",
		__func__, filename, strerror(errno));
		return -1;
	}

	while (tt != TT_EOF && fgets(line, STRLEN, f1) != NULL)
	{
		line[STRMAX] = '\0';

		/* Strip CRLF */
		n = strlen(line) - 1;
		while (n >= 0 && (line[n] == '\n' || line[n] == '\r'))
			line[n--] = '\0';

		/* Validate line prefix and length */
		if (line[0] != ':' || (strlen(line) & 1) == 0 || strlen(line) < 11) {
			printf("%s: warning: ignoring malformed line [%s] invalid format\n",
			__func__, line);
			continue;
		}

		/* Validate checksum */
		cc = 0;
		for (n = 1; line[n]; n += 2)
			cc += inhx32_gethexb(&line[n]); 
		if (cc != 0) {
			printf("%s: warning: ignoring malformed line [%s] invalid checksum [%02X]\n",
			__func__, line, cc);
			continue;
		}

		/* Determine number of data bytes in this line */
		bb = inhx32_gethexb(&line[BB]);

		/* Validate line length */
		if (strlen(line) != (2 * bb + 11)) {
			printf("%s: warning: ignoring malformed line [%s] invalid length [%zu]\n",
			__func__, line, strlen(line));
			continue;
		}

		/* Determine data address for this line */
		aaaa = (inhx32_gethexb(&line[AAAA]) << 8) | inhx32_gethexb(&line[AAAA + 2]);

		/* Determine record type */
		tt = inhx32_gethexb(&line[TT]);

		switch (tt) {
		case TT_DATA:   if (bb == 0) {
					printf("%s: warning: ignoring empty line [%s]\n",
					__func__, line);
					break;
				}

				/* Allocate new array entry for this line */
				inhx32 = (inhx32_data *)calloc(1, sizeof(inhx32_data));
				if (inhx32 == NULL) {
					printf("%s: fatal error: calloc failed\n", __func__);
					exit(EX_OSERR); /* Panic */
				}

				/* Increment line counter */
				inhx32_count++;

				/* Save address and word count */
				inhx32->address = extended_address | aaaa;
				inhx32->nbytes = bb;

				/* Extract data */
				ix = HHHH;
				for (n = 0; n < bb; n++) {
					inhx32->bytes[n] = inhx32_gethexb(&line[ix]);
					ix += 2;
				}
#ifdef DEBUG
				printf("ADDRESS=0x%08X NBYTES=%d ", inhx32->address, inhx32->nbytes);
				for (n = 0; n < bb; n++) {
					printf("0x%02x ", inhx32->bytes[n]);
				}
				printf("\n");
#endif
				/* Find entry in tree */
				if (tfind((void *)(inhx32), (void **)(&root), inhx32_compare) != NULL) {
					printf("%s: fatal error: duplicate address [%08X]\n",
					__func__, inhx32->address);
					exit(EX_SOFTWARE); /* Panic */
				}

				/* Add entry into tree */
				if (tsearch((void *)(inhx32), (void **)(&root), inhx32_compare) == NULL) {
					printf("%s: fatal error: tsearch failed\n", __func__);
					exit(EX_OSERR); /* Panic */
				}
				break;

		case TT_EOF:	break;

		case TT_EXTENDED_LINEAR_ADDRESS:
				if (aaaa == 0 && bb == 2)
					extended_address = (inhx32_gethexb(&line[HHHH]) << 24) | (inhx32_gethexb(&line[HHHH + 2]) << 16);
				else
					printf("%s: warning: ignoring invalid extended linear address [aaaa=%04X, bb=%d]\n", __func__, aaaa, bb);
				break;

		case TT_EXTENDED_SEGMENT_ADDRESS:
				printf("%s: warning: ignoring unhandled extended segment address\n", __func__);
				break;

		case TT_START_LINEAR_ADDRESS:
				printf("%s: warning: ignoring unhandled start linear address\n", __func__);
				break;

		case TT_START_SEGMENT_ADDRESS:
				printf("%s: warning: ignoring unhandled start segment address\n", __func__);
				break;

		default:	printf("%s: warning: ignoring unknown record type [%d]\n", __func__, tt);
				break;
		}
	}
	fclose(f1);

	/* Return error if no program data lines found */
	if (inhx32_count == 0) {
		printf("%s: error: file contains no data records [%s]\n", __func__, filename);
		return -5;
	}
	
	/* Create and populate program line data array from tree */
	inhx32_pdata = (inhx32_data **)calloc(inhx32_count, sizeof(inhx32_data *));
	if (inhx32_pdata == NULL) {
		printf("%s: fatal error: calloc failed\n", __func__);
		exit(EX_OSERR); /* Panic */
	}
	inhx32_index = 0;
	twalk((void *)(root), inhx32_order); 

	/* Free tree nodes */
	for (n = 0; n < inhx32_count; n++) {
		if (tdelete((void *)(inhx32_pdata[n]), (void **)(&root), inhx32_compare) == NULL) {
			printf("%s: fatal error: tdelete failed\n", __func__);
			exit(EX_OSERR); /* Panic */
		}
	}
	if (root != NULL) {
		printf("%s: fatal error: tree destroy failed\n", __func__);
		exit(EX_OSERR); /* Panic */
	}

	/* Return the program data line count */
	return inhx32_count;
}
Exemple #2
0
/*
 * Format parser
 *
 * Return program data line count
 */
uint32_t
inhx32(struct k8048 *k, const char *filename, uint32_t alignment)
{
	FILE *f1 = stdin;
	char line[STRLEN];
	uint32_t extended_address = 0, bb, ix;
	uint8_t tt = TT_DATA, cc;
	uint16_t aaaa;
	void *root = NULL;
	inhx32_data *data = NULL;

	k->count = 0;
	k->pdata = NULL;
	
	if (strcmp(filename, "-") && (f1 = fopen(filename, "rb")) == NULL) {
		printf("%s: error: file open failed [%s] [%s]\n",
		__func__, filename, strerror(errno));
		return 0;
	}
#ifdef DEBUG
	if (k->debug >= 100) {
		printf("FILE [%s]\n", filename);
	}
#endif
	while (tt != TT_EOF && fgets(line, STRLEN, f1) != NULL)
	{
		line[STRMAX] = '\0';

		/* Strip CRLF */
		int n = strlen(line) - 1;
		while (n >= 0 && (line[n] == '\n' || line[n] == '\r'))
			line[n--] = '\0';

		/* Validate line prefix and length */
		if (line[0] != ':' || (strlen(line) & 1) == 0 || strlen(line) < 11) {
			if (k->debug >= 10) {
				printf("%s: warning: ignoring malformed line [%s] invalid format\n", __func__, line);
			}
			continue;
		}

		/* Validate checksum */
		cc = 0;
		for (n = 1; line[n]; n += 2)
			cc += inhx32_gethexb(&line[n]); 
		if (cc != 0) {
			if (k->debug >= 10) {
				printf("%s: warning: ignoring malformed line [%s] invalid checksum [%02X]\n", __func__, line, cc);
			}
			continue;
		}

		/* Determine number of data bytes in this line */
		bb = inhx32_gethexb(&line[BB]);

		/* Validate line length */
		if (strlen(line) != (2 * bb + 11)) {
			if (k->debug >= 10) {
				printf("%s: warning: ignoring malformed line [%s] invalid length [%zu != %u] (BB=0x%02x)\n", __func__, line, strlen(line), 2 * bb + 11, bb);
			}
			continue;
		}

		/* Determine data address for this line */
		aaaa = (inhx32_gethexb(&line[AAAA]) << 8) | inhx32_gethexb(&line[AAAA + 2]);

		/* Determine record type */
		tt = inhx32_gethexb(&line[TT]);

		switch (tt) {
		case TT_DATA:   if (bb == 0) {
					if (k->debug >= 10) {
						printf("%s: warning: ignoring empty line [%s]\n", __func__, line);
					}
					break;
				}
				if (bb % alignment) {
					if (k->debug >= 10) {
						printf("%s: warning: ignoring line with incomplete word [%s]\n", __func__, line);
					}
					break;
				}

				/* Allocate new array entry for this line */
				data = (inhx32_data *)calloc(1, sizeof(inhx32_data));
				if (data == NULL) {
					printf("%s: fatal error: calloc failed\n", __func__);
					io_exit(k, EX_OSERR); /* Panic */
				}

				/* Increment line counter */
				k->count++;

				/* Save address and word count */
				data->address = extended_address | aaaa;
				data->nbytes = bb;

				/* Extract data */
				ix = HHHH;
				for (n = 0; n < bb; n++) {
					data->bytes[n] = inhx32_gethexb(&line[ix]);
					ix += 2;
				}
#ifdef DEBUG
				if (k->debug >= 100) {
					printf("AAAA=%04X BB=%02X ADDR=%06X >> %06X ",
						aaaa, bb, data->address, data->address >> 1);
					for (n = 0; n < bb; n++) {
						printf("%02X ", data->bytes[n]);
					}
					putchar('\n');
				}
#endif
				/* Find entry in tree */
				if (tfind((void *)(data), (void **)(&root), inhx32_compare) != NULL) {
					printf("%s: fatal error: duplicate address [%08X]\n",
					__func__, data->address);
					io_exit(k, EX_SOFTWARE); /* Panic */
				}

				/* Add entry into tree */
				if (tsearch((void *)(data), (void **)(&root), inhx32_compare) == NULL) {
					printf("%s: fatal error: tsearch failed\n", __func__);
					io_exit(k, EX_OSERR); /* Panic */
				}
				break;

		case TT_EOF:	break;

		case TT_EXTENDED_LINEAR_ADDRESS:
				if (aaaa == 0 && bb == 2) {
					extended_address = (inhx32_gethexb(&line[HHHH]) << 24) | (inhx32_gethexb(&line[HHHH + 2]) << 16);
#ifdef DEBUG
					if (k->debug >= 100) {
						printf("AAAA=%04X BB=%02X ADDR=%06X\n", aaaa, bb, extended_address);
					}
#endif
				} else {
					printf("%s: warning: ignoring invalid extended linear address [aaaa=%04X, bb=%d]\n", __func__, aaaa, bb);
				}
				break;

		case TT_EXTENDED_SEGMENT_ADDRESS:
				printf("%s: warning: ignoring unhandled extended segment address\n", __func__);
				break;

		case TT_START_LINEAR_ADDRESS:
				printf("%s: warning: ignoring unhandled start linear address\n", __func__);
				break;

		case TT_START_SEGMENT_ADDRESS:
				printf("%s: warning: ignoring unhandled start segment address\n", __func__);
				break;

		default:	printf("%s: warning: ignoring unknown record type [%d]\n", __func__, tt);
				break;
		}
	}