/*
Copyright (C) 1998 T. Scott Dattalo
This file is part of gpsim.
gpsim 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, or (at your option)
any later version.
gpsim 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 gpasm; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
// T. Scott Dattalo
// Portions of this file were obtained from:
/* intel16.c - read an intel hex file */
/* Copyright (c) 1994 Ian King */
#include <stdio.h>
#include <ctype.h>
#include "picdis.h"
#include "exports.h"
#include "pic-processor.h"
#include "hexutils.h"
#include "program_files.h"
//------------------------------------------------------------------------
// IntelHexProgramFileType -- constructor
//
// When a IntelHexProgramFileType is instantiated, it will get placed
// on to a 'ProgramFileType' list. This list is then used (ultimately)
// by the 'load' command to load files of this type.
IntelHexProgramFileType::IntelHexProgramFileType()
{
RegisterProgramFileType(this);
}
int
IntelHexProgramFileType::getachar (FILE * file)
{
int c;
do
c = fgetc (file);
while (c == '\r'); /* strip LF out of MSDOS files */
return c;
}
unsigned char
IntelHexProgramFileType::getbyte (FILE * file)
{
unsigned char byte;
unsigned int data;
fscanf (file, "%02x", &data);
byte = data & 0xff;
checksum += byte; /* all the bytes are used in the checksum */
/* so here is the best place to update it */
return byte;
}
unsigned int
IntelHexProgramFileType::getword(FILE *file)
{
unsigned char lo = getbyte(file);
return ((getbyte(file) << 8) | lo);
}
#include "cmd_gpsim.h"
int IntelHexProgramFileType::LoadProgramFile(Processor **pProcessor,
const char *pFilename,
FILE *inputfile, const char *pProcessorName)
{
if(verbose)
cout << "load hex\n";
if(*pProcessor == NULL) {
// Need to determine processor from file.
// for now return error.
return ERR_NEED_PROCESSOR_SPECIFIED;
}
// assume no configuration word is in the hex file.
(*pProcessor)->set_config_word((*pProcessor)->config_word_address(),0xffff);
int iReturn;
if ((iReturn = readihex16 (pProcessor, inputfile)) != SUCCESS) {
// No errors were found in the hex file.
(*pProcessor)->set_frequency(10e6);
(*pProcessor)->reset(POR_RESET);
(*pProcessor)->simulation_mode = eSM_STOPPED;
if(verbose)
get_cycles().dump_breakpoints();
return SUCCESS;
}
return iReturn;
}
int IntelHexProgramFileType::readihex16 (Processor **pProcessor, FILE * file)
{
int extended_address = 0;
int address;
int linetype = 0;
int wordsthisline, bytesthisline;
int i;
int lineCount = 1;
int csby;
unsigned char hi, lo;
Processor *& cpu = *pProcessor;
while (1) {
if (getachar (file) != ':') {
printf ("Need a colon as first character in each line\n");
printf ("Colon missing in line %d\n", lineCount);
//exit (1);
return ERR_BAD_FILE;
}
checksum = 0;
bytesthisline = getbyte (file);
wordsthisline = bytesthisline / 2;
hi = getbyte (file);
lo = getbyte (file);
address = (hi << 8 | lo) / 2;
/* wierdness of INHX16! address different */
/* endian-ness and 2x too big */
linetype = getbyte (file); /* 0 for data, 1 for end */
switch (linetype ) {
case 0: // Data record
{
unsigned char buff[256];
bytesthisline &= 0xff;
for (i = 0; i < bytesthisline; i++)
buff[i] = getbyte(file);
cpu->init_program_memory_at_index(address|extended_address,
buff, bytesthisline);
}
break;
case 1: // End of hex file
return SUCCESS;
case 4: // Extended address
{
unsigned char b1, b2;
b1 = getbyte (file); // not sure what these mean
b2 = getbyte (file);
extended_address = (((unsigned int)b1)<<23) | (((unsigned int)b2)<<15);
printf ("Extended linear address %x %x\n",
address, extended_address);
}
break;
default:
printf ("Error! Unknown record type! %d\n", linetype);
return ERR_BAD_FILE;
}
csby = getbyte (file); /* get the checksum byte */
/* this should make the checksum zero */
/* due to side effect of getbyte */
if (checksum) {
printf ("Checksum error in input file.\n");
printf ("Got 0x%02x want 0x%02x at line %d\n",
csby, (0 - checksum) & 0xff, lineCount);
return ERR_BAD_FILE;
}
(void) getachar (file); /* lose <return> */
lineCount++;
}
return SUCCESS;
}
/* ... The End ... */
syntax highlighted by Code2HTML, v. 0.9.1