- 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
This commit is contained in:
242
utils/ecb-load.c
Normal file
242
utils/ecb-load.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/***************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user