209 lines
4.9 KiB
C
209 lines
4.9 KiB
C
/*
|
|
* mkimg.c - Make an image or .h file from a binary
|
|
*
|
|
* Copyright (C) 1995-1998 David Firth
|
|
* Copyright (C) 1998-2005 Atari800 development team (see DOC/CREDITS)
|
|
*
|
|
* This file is part of the Atari800 emulator project which emulates
|
|
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
|
*
|
|
* Atari800 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.
|
|
*
|
|
* Atari800 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 Atari800; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/*
|
|
* Usage: mkimg -input filename
|
|
* -image filename
|
|
* -header filename
|
|
* hexaddr1
|
|
* hexaddr2
|
|
*
|
|
* Loads the input file into a 64K area of memory. The
|
|
* input file is in standard Atari Binary load format.
|
|
* The memory is initially filled with zeros. After the
|
|
* memory has been loaded the program creates either an
|
|
* image file or a standard C header file that contains
|
|
* the memory starting with hexaddr1 at going up to,
|
|
* but not including, hexaddr2.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
typedef enum {
|
|
Expect_Header1,
|
|
Expect_Header2,
|
|
Expect_StartLo,
|
|
Expect_StartHi,
|
|
Expect_FinishLo,
|
|
Expect_FinishHi,
|
|
Expect_Data
|
|
} State;
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
unsigned char image[65536];
|
|
char *in_filename = NULL;
|
|
char *image_filename = NULL;
|
|
char *header_filename = NULL;
|
|
int error = 0;
|
|
int start_addr = 0;
|
|
int finish_addr = 0;
|
|
int addr1 = -1;
|
|
int addr2 = -1;
|
|
int addr;
|
|
FILE *f;
|
|
int i;
|
|
|
|
State state = Expect_Header1;
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
if (strcmp(argv[i], "-input") == 0)
|
|
in_filename = argv[++i];
|
|
else if (strcmp(argv[i], "-image") == 0)
|
|
image_filename = argv[++i];
|
|
else if (strcmp(argv[i], "-header") == 0)
|
|
header_filename = argv[++i];
|
|
else if (addr1 == -1)
|
|
sscanf(argv[i], "%x", &addr1);
|
|
else if (addr2 == -1)
|
|
sscanf(argv[i], "%x", &addr2);
|
|
else
|
|
error = 1;
|
|
}
|
|
|
|
if (!in_filename || (!image_filename && !header_filename) ||
|
|
error || (addr1 == -1) || (addr2 == -1)) {
|
|
printf("Usage: %s -input in_fname {-image image_fname|-header header_fname} hexaddr1 hexaddr2\n",
|
|
argv[0]);
|
|
return 0;
|
|
}
|
|
memset(image, 0, 65536);
|
|
|
|
f = fopen(in_filename, "rb");
|
|
if (!f) {
|
|
perror(in_filename);
|
|
return 1;
|
|
}
|
|
while (1) {
|
|
unsigned char byte;
|
|
|
|
if (fread(&byte, 1, 1, f) != 1)
|
|
break;
|
|
|
|
switch (state) {
|
|
case Expect_Header1:
|
|
if (byte == 0xff)
|
|
state = Expect_Header2;
|
|
else
|
|
printf("Error: Expecting Header1\n");
|
|
break;
|
|
case Expect_Header2:
|
|
if (byte == 0xff)
|
|
state = Expect_StartLo;
|
|
else
|
|
printf("Error: Expecting Header2\n");
|
|
break;
|
|
case Expect_StartLo:
|
|
start_addr = (start_addr & 0xff00) | byte;
|
|
state = Expect_StartHi;
|
|
break;
|
|
case Expect_StartHi:
|
|
start_addr = (start_addr & 0x00ff) | (byte << 8);
|
|
state = Expect_FinishLo;
|
|
printf("StartAddr = %x\n", start_addr);
|
|
if (start_addr == 0xffff) {
|
|
printf("Oops thats a header\n");
|
|
state = Expect_StartLo;
|
|
}
|
|
break;
|
|
case Expect_FinishLo:
|
|
finish_addr = (finish_addr & 0xff00) | byte;
|
|
state = Expect_FinishHi;
|
|
break;
|
|
case Expect_FinishHi:
|
|
finish_addr = (finish_addr & 0x00ff) | (byte << 8);
|
|
state = Expect_Data;
|
|
addr = start_addr;
|
|
printf("FinishAddr = %x\n", finish_addr);
|
|
break;
|
|
case Expect_Data:
|
|
image[addr++] = byte;
|
|
if (addr > finish_addr)
|
|
state = Expect_StartLo;
|
|
break;
|
|
default:
|
|
printf("Error: Invalid State\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
/*
|
|
* Write image to file
|
|
*/
|
|
|
|
if (image_filename) {
|
|
f = fopen(image_filename, "wb");
|
|
if (!f) {
|
|
perror(image_filename);
|
|
return 1;
|
|
}
|
|
fwrite(&image[addr1], 1, addr2 - addr1 + 1, f);
|
|
|
|
fclose(f);
|
|
}
|
|
if (header_filename) {
|
|
FILE *fp;
|
|
char *ptr;
|
|
int j;
|
|
|
|
fp = fopen(header_filename, "wb");
|
|
if (!fp) {
|
|
perror(header_filename);
|
|
return 1;
|
|
}
|
|
|
|
for (ptr = header_filename; *ptr; ptr++) {
|
|
if (!( (*ptr >= 'a' && *ptr <= 'z')
|
|
|| (*ptr >= 'A' && *ptr <= 'Z')
|
|
|| (*ptr >= '0' && *ptr <= '9') ))
|
|
*ptr = '_';
|
|
}
|
|
|
|
fprintf(fp, "#ifndef _%s_\n", header_filename);
|
|
fprintf(fp, "#define _%s_\n\n", header_filename);
|
|
|
|
fprintf(fp, "static unsigned char %s[] =\n{\n\t", header_filename);
|
|
|
|
for (i = addr1, j = 0; i < addr2; i++) {
|
|
fprintf(fp, "0x%02x,", image[i]);
|
|
|
|
if (++j == 8) {
|
|
fprintf(fp, "\n\t");
|
|
j = 0;
|
|
}
|
|
}
|
|
|
|
fprintf(fp, "0x%02x\n", image[addr2]);
|
|
fprintf(fp, "};\n");
|
|
|
|
fprintf(fp, "\n#endif\n");
|
|
|
|
fclose(fp);
|
|
}
|
|
return 0;
|
|
}
|