Files
sicspsi/utils/ecb-load.c
cvs 064ec37e9a - Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module
- PSI specific stuff is now in the PSI directory.
- The old version has been tagged with pre-ansto
2003-06-20 10:18:47 +00:00

243 lines
7.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***************************************************************************
* 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 <stdio.h>
#include <string.h>
#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;
}