aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rom2cart.c43
-rw-r--r--rom2cart.rst29
2 files changed, 55 insertions, 17 deletions
diff --git a/rom2cart.c b/rom2cart.c
index 7eaaa06..4126c81 100644
--- a/rom2cart.c
+++ b/rom2cart.c
@@ -70,6 +70,7 @@ char *usage =
" -T type Like -t, but forces the type. Numeric type only.\n"
" -C sum Force the checksum to sum. Not very useful.\n"
" -U data Set 'unused' bytes in CART header to data.\n"
+ " -H Test code heuristics (developer option).\n"
"\n"
"infile may be either a raw dump or a CART image, and may be '-' to read\n"
"from standard input. outfile may be omitted, in which case output will\n"
@@ -77,7 +78,7 @@ char *usage =
".car (or .rom, if -r given). outfile may be '-' to write to standard\n"
"output.\n";
-#define OPTIONS "vchlm:nT:t:C:rU:"
+#define OPTIONS "vchlm:nT:t:C:rU:H"
void print_type_table(int *set) {
/* print a nicely-formatted type table. If set is NULL, print all types,
@@ -87,7 +88,7 @@ void print_type_table(int *set) {
"Type", "Machine", "SizeKB", "Name");
fprintf(stderr, "------|----------|--------|------------------------\n");
for(i=1; i<=MAX_CART_TYPE; i++) {
- if(set == NULL || set[i])
+ if(cart_types[i].machine != M_INVALID && (set == NULL || set[i]))
fprintf(stderr, "%5d | %8s | %6d | %s\n",
i,
(cart_types[i].machine == M_5200 ? "5200" : "8-bit"),
@@ -184,10 +185,15 @@ machine_t code_heuristics(unsigned char *rom, int size, int verbose) {
SELF ": found %d probable 5200 POKEY writes\n", a52);
}
- if(a8 >= 3 && a52 <= 1)
+ if(a8 >= 3 && a52 <= 1) {
machine = M_ATARI8;
- else if(a52 >= 3 && a8 <= 1)
+ fprintf(stderr, SELF ": code_heuristics() returning M_ATARI8\n");
+ } else if(a52 >= 3 && a8 <= 1) {
machine = M_5200;
+ fprintf(stderr, SELF ": code_heuristics() returning M_5200\n");
+ } else {
+ fprintf(stderr, SELF ": code_heuristics() returning M_INVALID\n");
+ }
return machine;
}
@@ -277,7 +283,7 @@ int determine_type(
else
return 0; /* bogus -T */
} else {
- if(!type || type > MAX_CART_TYPE) {
+ if(!type || type > MAX_CART_TYPE || cart_types[type].machine == M_INVALID) {
fprintf(stderr, "Invalid numeric type '%d' for -t (valid types "
"are 1 to %d; use -l for list)\n", type, MAX_CART_TYPE);
return 0;
@@ -307,7 +313,7 @@ int determine_type(
fprintf(stderr, SELF ": trying to match '%s'\n", type_param);
for(i=1; i<=MAX_CART_TYPE; i++) {
- if(string_match(cart_types[i].name, type_param)) {
+ if(cart_types[i].machine != M_INVALID && string_match(cart_types[i].name, type_param)) {
if(verbose > 1)
fprintf(stderr, SELF ": matched type %d (%s)\n",
i, cart_types[i].name);
@@ -439,7 +445,7 @@ int main(int argc, char **argv) {
int check_only = 0, type = 0, type_override = 0, allow_guess = 1,
verbose = 0, raw_output = 0;
machine_t machine = M_INVALID;
- int c, size;
+ int c, size, test_heuristics = 0, raw_input = 0;
unsigned int cksum = 0, cksum_override = 0, unused_data = 0;
unsigned char *buffer;
unsigned char **bufp = &buffer;
@@ -508,6 +514,11 @@ int main(int argc, char **argv) {
raw_output++;
break;
+ case 'H':
+ test_heuristics++;
+ verbose = 2;
+ break;
+
default:
fputs(BANNER, stderr);
fprintf(stderr, usage);
@@ -555,6 +566,7 @@ int main(int argc, char **argv) {
} else {
rom = buffer;
if(verbose) fprintf(stderr, SELF ": input is raw dump, %d bytes\n", size);
+ raw_input++;
}
if(size <= 0) {
@@ -587,12 +599,25 @@ int main(int argc, char **argv) {
when there's only 8K of actual ROM. */
memcpy(cart, CART_SIGNATURE, 4);
set_cart_type(cart, type);
- if(!cksum_override)
+ if(!cksum_override) {
cksum = calc_rom_checksum(buffer, size);
+ if(!raw_input) {
+ int oldsum = get_cart_checksum(buffer);
+ if(oldsum != cksum) {
+ fprintf(stderr, SELF ": stored checksum %08x doesn't match calculated %08x, fixing.\n", oldsum, cksum);
+ }
+ }
+ }
set_cart_checksum(cart, cksum);
set_cart_unused(cart, unused_data);
- if(verbose > 1) cart_dump_header(cart, 0);
+ if(verbose > 1 && !(check_only && raw_input)) cart_dump_header(cart, 0);
+
+ if(test_heuristics) {
+ fprintf(stderr, SELF ": testing code_heuristics() and exiting.\n");
+ (void)code_heuristics(buffer, size, verbose);
+ exit(0);
+ }
if(!check_only) {
if(optind < argc) {
diff --git a/rom2cart.rst b/rom2cart.rst
index 0edc57d..580d77b 100644
--- a/rom2cart.rst
+++ b/rom2cart.rst
@@ -22,7 +22,7 @@ SYNOPSIS
DESCRIPTION
===========
-**rom2cart** converts between raw ROM dumps and Atari800 **.CAR**
+**rom2cart** converts between raw ROM dumps and Atari800 **.CAR**
images. Despite the name, conversion can be done in either direction.
**cart2rom** is equivalent to **rom2cart -r**.
@@ -36,7 +36,7 @@ content), and (optional) user-supplied type number or name (**-t**).
If **rom2cart** is unable to narrow the selection down to one
image type, it will "guess" by choosing the lowest-numbered type
that matches the given parameters (unless **-n** is given to prevent
-this behavior).
+this behavior, in which case it will exit with an error message).
When writing a **.CAR** file, **rom2cart** will calculate the checksum
automatically and store it in the **CART** header (unless **-C** is
@@ -121,6 +121,13 @@ useful for debugging **rom2cart** or Atari800 itself.
(prefixed with $ or 0x) or decimal (no prefix). This option has no
effect if the output is a raw dump (**-r** option).
+-H
+ Test the code-detection heuristics: examine the first 8K of the ROM and
+ look for writes to $D2xx (8-bit computer) or $E8xx (5200) to guess the
+ machine type for the ROM. This option exists only for testing: normally,
+ the machine type gets guessed by the cartridge option bytes, and the
+ code-detection is only done if the option byte tests are inconclusive.
+
NOTES
=====
@@ -134,7 +141,7 @@ be constructed from *infile* by replacing the filename extension with
is no extension.
**rom2cart** contains an internal database of image types. The current
-version uses the list from Atari800 v2.0.3 (types 1-43). If you
+version uses the list from Atari800 v5.2.0 (types 1-103 and 160). If you
need to create a **.CAR** image of a type not supported in this
version of **rom2cart**, you can use the **-T** option. Alternatively, look
for a newer version of **rom2cart**. If no new version exists, bug the
@@ -158,15 +165,21 @@ A **.CAR** image consists of a 16-byte header followed by the ROM data.
The first 4 bytes contain 'C' 'A' 'R' 'T' in ASCII.
-The next 4 bytes contain the cartridge type in MSB (aka
-*big-endian*) format.
+The next 4 bytes contain the cartridge type in MSB (aka *big-endian*)
+32-bit integer format.
-The next 4 bytes contain cartridge checksum in MSB format (ROM only).
+The next 4 bytes contain cartridge checksum in MSB format (ROM only;
+the header is not checksummed).
The next 4 bytes are currently unused (zero).
-The rest of the file contains the ROM data: 4, 8, 16, 32, 40, 64, 128,
-256, 512 or 1024 kilobytes.
+The rest of the file contains the ROM data, up to 32Mbytes as of
+Atari800 5.2.0. The cartridge type determines the amount of data; see
+*cart.txt* or the output of **rom2cart -l**.
+
+The latest version of *cart.txt* can be found at:
+
+ https://raw.githubusercontent.com/atari800/atari800/master/DOC/cart.txt
HEURISTICS
==========