summaryrefslogtreecommitdiff
path: root/intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'intel.c')
-rw-r--r--intel.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/intel.c b/intel.c
new file mode 100644
index 0000000..3c65adf
--- /dev/null
+++ b/intel.c
@@ -0,0 +1,178 @@
+/*
+
+ int2tap - Convert an Intel segment file to a loadable Spectrum tape file
+
+ Copyright (C) 2004 Ian Cowburn (ianc@noddybox.demon.co.uk)
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ -------------------------------------------------------------------------
+
+*/
+static const char id[]="$Id$";
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "intel.h"
+
+static const char header_id[]=I2T_INTEL_H;
+
+extern const char *progname;
+
+
+/* ---------------------------------------- CONSTANTS
+*/
+#undef TRUE
+#undef FALSE
+
+#define TRUE 1
+#define FALSE 0
+
+
+/* ---------------------------------------- PRIVATE FUNCTIONS
+*/
+static const unsigned ToHex(char c)
+{
+ if (c>='0' && c<='9')
+ {
+ return c-'0';
+ }
+
+ if (c>='A' && c<='F')
+ {
+ return c-'A'+10;
+ }
+
+ if (c>='a' && c<='f')
+ {
+ return c-'a'+10;
+ }
+
+ return 0;
+}
+
+
+
+/* ---------------------------------------- INTERFACES
+*/
+int IntelLoad(const char *filename,
+ unsigned char mem [0x1000],
+ IntelInfo *info)
+{
+ FILE *fp;
+ char buff[1024];
+ int done;
+ int addr_read;
+ int ret;
+
+ if (!(fp=fopen(filename,"r")))
+ {
+ fprintf(stderr,"%s: Failed to open %s\n",progname,filename);
+ return FALSE;
+ }
+
+ addr_read=FALSE;
+ info->low=0xffff;
+ info->high=0x0000;
+
+ done=FALSE;
+ ret=FALSE;
+
+ while(!done)
+ {
+ if (!fgets(buff,sizeof buff,fp))
+ {
+ fprintf(stderr,"%s: Missing EOF record in %s\n",progname,filename);
+ done=TRUE;
+ }
+
+ if (!done && buff[0]!=':')
+ {
+ fprintf(stderr,"%s: Invalid Intel HEX file %s\n",progname,filename);
+ done=TRUE;
+ }
+
+ if (!done && buff[8]=='1')
+ {
+ done=TRUE;
+ ret=TRUE;
+ }
+
+ if (!done && (buff[8]=='2' || buff[8]=='3'))
+ {
+ fprintf(stderr,"%s: Extended address in Intel HEX file %s\n",
+ progname,filename);
+ done=TRUE;
+ }
+
+ if (!done)
+ {
+ unsigned addr;
+ unsigned len;
+ unsigned f;
+
+ len=ToHex(buff[1])<<4|ToHex(buff[2]);
+
+ addr=ToHex(buff[3])<<12|ToHex(buff[4])<<8|
+ ToHex(buff[5])<<4|ToHex(buff[6]);
+
+ if (!addr_read)
+ {
+ info->addr=addr;
+ addr_read=TRUE;
+ }
+
+ for(f=0;f<len && !done;f++)
+ {
+ unsigned char b;
+
+ if (addr<info->low)
+ {
+ info->low=addr;
+ }
+
+ if (addr>info->high)
+ {
+ info->high=addr;
+ }
+
+ b=ToHex(buff[f*2+9])<<4|ToHex(buff[f*2+10]);
+ mem[addr++]=b;
+
+ if (addr==0)
+ {
+ fprintf(stderr,"%s: Intel HEX file %s has "
+ "wrapped from 0xffff to 0x0000\n",
+ progname,filename);
+ done=TRUE;
+ }
+ }
+ }
+ }
+
+ if (info->low!=0xffff)
+ {
+ info->len=(info->high-info->low)+1;
+ }
+
+ fclose(fp);
+
+ return ret;
+}
+
+
+/* END OF FILE */