/*************************************************************************** * This file contains the download program the ECB system. * It reads a Tek-hex formated file and downloads it to the ECB-system. * The lowest address is used as the start address of the program. * * Project: ECB-C * Filename: ecb_load.c * * Author: L. S. Jensen 18. Feb 1993 * * Heavily reworked by code transfusions from tascom in order to * support new ECB file format. * * Mark Koennecke, May 2003 * * Copyright (C) Risoe National Laboratory, 1993, All rights reserved ****************************************************************************/ #include #include #include "ecb-drv.h" /* The ecb driver interface. */ #define MAX_BUFFER_SIZE 32767 /* Max. RAM in ECB system */ #define LINE_SIZE 128 #define LAST_LINE -125 #define CHECKSUM_ERR -100 #define FORMAT_ERR -101 #define FILE_ERR -102 #define CSTART_CODE 171 /* The number of ECB function cstart */ #define FOREVER 1 /* Used in a loop */ #define ECB_BYTES 65536L #define ECB_DOWN_LOAD 178 #define LOAD_NEXT 1 /***************************************************************************** * Local variables in this file. *****************************************************************************/ static char buffer[MAX_BUFFER_SIZE]; static int debug = 0; /******************************************************************************* * Convert HEX to bin *******************************************************************************/ static int look_up[] = {10, 11, 12, 13, 14 ,15}; static unsigned long Hex_to_bin(char c) { if(isdigit((int) c)) return (c - '0'); else return look_up[c - 'A']; } /******************************************************************************* * Convert Bin to HEX *******************************************************************************/ static char Bin_to_hex (int i) { if(i <= 9) return ( (char)(i + (int)('0')) ); else return ( (char)( (i - 10) + (int)('A')) ); } /*************************************************************************** * This function creates blocks as large as possible of consecutive data * bytes from the hex file in order to speed up the data transfer by * sending blocks of data to the ECB system rather than single lines. ****************************************************************************/ static Z80_reg x_outreg, x_inreg; static long Send_blocks(FILE *fp, Gpib_dev dev) { char line[LINE_SIZE]; char *point; int line_not_output, byte_count, line_no,type, no_bytes,total_bytes; int load_count = -1, function; unsigned char x_ecb_data[ECB_BYTES]; /* Array to hold data blocks for ECB */ unsigned long adrs, old_adrs, total0, total1, total2; void *line9 = &line[9]; unsigned short address; for (;;) { if (line_not_output == 1) line_not_output = 0; /* Start with old line */ else { /* Read a line from file */ point = fgets (line, LINE_SIZE, fp); if (point != NULL) { byte_count = strlen(line); byte_count -= 4; /* Remove checksum and \n in the */ line[byte_count+1] = '\0'; /* line, i.e. the four last characters */ line[0] = '0'; /* Replace : in line[0] with 0 */ } else { if (!ferror(fp)) byte_count = 0; else { fclose (fp); fp = NULL; return(FILE_ERR); } } } line_no += 1; if (byte_count != 0) { if (line_no == 1) strcpy (x_ecb_data, line); type = (Hex_to_bin(line[7]) << 4) + Hex_to_bin(line[8]); if (type != 0) { if (line_no > 1) /* Output buffer and mark that */ line_not_output = 1; /* last input line has not been output */ } else { no_bytes = (Hex_to_bin(line[1]) << 4) + Hex_to_bin(line[2]); adrs = (Hex_to_bin(line[3]) << 12) + (Hex_to_bin(line[4]) << 8) + (Hex_to_bin(line[5]) << 4) + Hex_to_bin(line[6]); if (line_no == 1) { total_bytes = no_bytes; old_adrs = adrs; continue; /* Get next input line */ } else { if (old_adrs + no_bytes == adrs) { /* Contigious addresses */ total_bytes += no_bytes; old_adrs = adrs; strcat (x_ecb_data, line9); /* Add the new bytes to buffer */ total0 = total_bytes/256; /* and adjust number of bytes */ x_ecb_data[0] = Bin_to_hex(total0); total1 = total_bytes - 256*total0; total2 = total1/16; x_ecb_data[1] = Bin_to_hex(total2); x_ecb_data[2] = Bin_to_hex(total1 - 16*total2); if (line_no < 20) /* Max 20 lines together */ continue; /* Get next input line */ } } line_not_output = 0; /* Output buffer, nothing waiting in line[] */ } address = 1; byte_count = strlen (x_ecb_data); Ecb_write (dev, x_ecb_data,byte_count,1); /* Write a line to ECB */ line_no = 0; if (load_count == -1) /* Type Loading followed by dots while */ { /* down loading the file */ printf ("Loading"); load_count = 0; } load_count += 1; if (load_count > 15) { printf ("."); load_count = 0; } function = ECB_DOWN_LOAD; Ecb_func (dev, function,x_inreg); /* Call ECB download function */ if (x_outreg.b != LOAD_NEXT) /* Wait for reply from ECB */ break; /* If LOAD_NEXT, get next line, else finished */ } } printf("\nLoading completed\n"); } /**************************************************************************** * Handles error in gpib driver. ****************************************************************************/ void Exit_code(int status) { if(debug) printf("exit status %d", status); exit(status); } /**************************************************************************** * ****************************************************************************/ int main(int argc, char *argv[]) { Gpib_dev dev; int dev_no; FILE *record_fp; long start_adr; Z80_reg z80; if (argc < 4|| argc > 5) { printf("used: %s Gpib-driver-name ECB-device-number ECB-hex-filename\n", argv[0]); exit(GPIB_ERR); } if (argc == 5) { if ((0 == strcasecmp(argv[4],"DEBUG"))||(0 == strcasecmp(argv[4],"VERBOSE"))) debug = 1; } record_fp = fopen(argv[3], "rb"); /* Open in read-only mode in binary mode */ if (record_fp == NULL) { printf("used: %s Gpib-driver-name ECB-device-number ECB-hex-filename\n", argv[0]); exit(FILE_ERR); } dev = Ecb_unit(argv[1], argv[2]); /* Open the ECB device */ start_adr = Send_blocks(record_fp, dev); if (start_adr < 0) /* An error */ exit(start_adr); z80.d = start_adr; /* Lsb part in Z80 reg. D */ z80.e = start_adr>>8; /* Msb part in Z80 reg. E */ Ecb_func(dev, CSTART_CODE, z80); /* And start the ecb-c program. */ return; }