aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atr2xfd.c57
-rw-r--r--fenders.135
-rw-r--r--fenders.c67
-rw-r--r--fenders.rst33
4 files changed, 152 insertions, 40 deletions
diff --git a/atr2xfd.c b/atr2xfd.c
index bed24fe..5929433 100644
--- a/atr2xfd.c
+++ b/atr2xfd.c
@@ -255,12 +255,23 @@ int main(int argc, char **argv) {
unsigned char dos1_sig[] = "\x00\x01\x00\x07\x00\x13\x4c\x12";
unsigned char dos2_sig[] = "\x00\x03\x00\x07\x40\x15\x4c\x14";
unsigned char dos3_sig[] = "\x01\x09\x00\x32\x06\x32";
-unsigned char mydos3_sig[] = "\x00\x03\x00\x07\xe0\x07\x4c\x14";
+unsigned char dos4_sig[] = "\x00\x21\x01\x07\xf8\x07\x4c\xd9";
+unsigned char dos4_noboot_sig[] = "\x00\x00\x00\x01\x00\x01\x01\x01";
+unsigned char mydos30_sig[] = "\x00\x03\x00\x07\xd8\x17\x4c\x14";
+unsigned char mydos31_sig[] = "\x00\x03\x00\x07\xe0\x07\x4c\x14";
unsigned char mydos4_sig[] = "\x4d\x03\x00\x07\xe0\x07\x4c\x14";
unsigned char topdos11_sig[] = "\xc0\x03\x00\x07\x40\x15\x4c\x24";
unsigned char topdos15_sig[] = "\x80\x03\x00\x07\x40\x15\x4c\x24";
unsigned char blank_sig[] = "\x00\x00\x00\x00\x00\x00\x00\x00";
unsigned char pico_sig[] = "\x00\x03\x00\x10\x10\x4c";
+unsigned char superdos2_sig[] = "\x29\x03\x00\x07\x40\x15\xa0";
+unsigned char superdos5_sig[] = "\x64\x03\x00\x07\x40\x15\xa9\x07";
+unsigned char smartdos_sig[] = "\x00\x03\x00\x07\xd4\x15\x4c\x14";
+unsigned char dosxe_sig[] = "\x58\x03\x00\x07\xca\x0c\x4c\x30";
+
+/* both of these claim to be "Turbo DOS XE version 2.1" */
+unsigned char turbodos_sig[] = "\x04\x03\x00\x07\x40\x15\x4c\x16";
+unsigned char turbodosxe_sig[] = "\x01\x03\x00\x07\x40\x15\x4c\x16";
/* these signatures are for offset $18 of sector 1. */
unsigned char dos2_code_sig[] = "\x36\xad\x12\x07";
@@ -272,7 +283,7 @@ void classify_boot_sector(FILE *f) {
unsigned char buf[128];
char *dos_type = "Unknown", *boot_text = "";
int bootable = -1; /* -1 = unknown, 0 = no, 1 = yes */
- int i;
+ int dos2_bootable, i;
/* read 1st sector... */
if( (fread(buf, 1, 128, f) < 128) ) {
@@ -285,11 +296,22 @@ void classify_boot_sector(FILE *f) {
fputc('\n', stderr);
#endif
+ dos2_bootable = (buf[14] != 0);
+
/* now figure out what kind of boot sector this is */
if(SIG_MATCH(buf, dos1_sig)) {
dos_type = "DOS 1.0";
+ bootable = dos2_bootable;
} else if(SIG_MATCH(buf, dos3_sig)) {
dos_type = "DOS 3.0";
+ /* can't tell if bootable from just the boot sector, would have
+ to search for FMS.SYS */
+ } else if(SIG_MATCH(buf, dos4_sig)) {
+ dos_type = "DOS 4.0";
+ bootable = 1;
+ } else if(SIG_MATCH(buf, dos4_noboot_sig)) {
+ dos_type = "DOS 4.0";
+ bootable = 0;
} else if(SIG_MATCH(buf, dos2_sig)) {
if(SIG_MATCH(buf + 0x18, dos2_code_sig))
dos_type = "DOS 2.0";
@@ -297,7 +319,7 @@ void classify_boot_sector(FILE *f) {
dos_type = "DOS 2.5";
else
dos_type = "DOS 2.0 compatible";
- bootable = (buf[14] != 0);
+ bootable = dos2_bootable;
} else if(buf[0] == 0x00 && buf[1] == 0x03 &&
(buf[32] == 0x11 || buf[32] == 0x20) &&
buf[6] == 0x4c && buf[7] == 0x80) {
@@ -305,12 +327,37 @@ void classify_boot_sector(FILE *f) {
dos_type = "SpartaDOS 1.1";
else
dos_type = "SpartaDOS >= 2";
- } else if(SIG_MATCH(buf, mydos3_sig)) {
- dos_type = "MyDOS 3.x";
+ } else if(SIG_MATCH(buf, mydos30_sig)) {
+ dos_type = "MyDOS 3.0x";
+ bootable = dos2_bootable;
+ } else if(SIG_MATCH(buf, mydos31_sig)) {
+ dos_type = "MyDOS 3.1x";
+ bootable = dos2_bootable;
} else if(SIG_MATCH(buf, mydos4_sig)) {
dos_type = "MyDOS 4.x";
+ bootable = dos2_bootable;
} else if(SIG_MATCH(buf, pico_sig)) {
dos_type = "MyPicoDOS 4.x";
+ } else if(SIG_MATCH(buf, topdos11_sig)) {
+ dos_type = "Top DOS 1.1";
+ bootable = !(buf[15] == 0 && buf[16] == 0);
+ } else if(SIG_MATCH(buf, topdos15_sig)) {
+ dos_type = "Top DOS 1.5";
+ bootable = dos2_bootable;
+ } else if(SIG_MATCH(buf, superdos2_sig)) {
+ dos_type = "SuperDOS 2.9";
+ bootable = (buf[7] != 0);
+ } else if(SIG_MATCH(buf, superdos5_sig)) {
+ dos_type = "SuperDOS 5.1";
+ } else if(SIG_MATCH(buf, turbodos_sig)) {
+ dos_type = "Turbo DOS XE";
+ } else if(SIG_MATCH(buf, turbodosxe_sig)) {
+ dos_type = "Turbo DOS XE";
+ } else if(SIG_MATCH(buf, dosxe_sig)) {
+ dos_type = "DOS XE";
+ } else if(SIG_MATCH(buf, smartdos_sig)) {
+ dos_type = "Smart DOS";
+ bootable = dos2_bootable;
} else if(SIG_MATCH(buf, blank_sig)) {
dos_type = "None (empty boot sector)";
bootable = 0;
diff --git a/fenders.1 b/fenders.1
index 04a867d..56c82d7 100644
--- a/fenders.1
+++ b/fenders.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.TH "FENDERS" 1 "2024-05-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "FENDERS" 1 "2024-05-08" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
fenders \- Install Fenders 3-sector loader in boot sectors of an ATR image
.\" RST source for fenders(1) man page. Convert with:
@@ -38,7 +38,7 @@ fenders \- Install Fenders 3-sector loader in boot sectors of an ATR image
.
.SH SYNOPSIS
.sp
-\fIfenders\fP [\fI\-hrcsiv\fP] [\-t \fItitle\fP] \fIinfile.atr\fP [\fIoutfile.atr\fP]
+\fIfenders\fP [\fI\-hrcsiIv\fP] [\-t \fItitle\fP] \fIinfile.atr\fP [\fIoutfile.atr\fP]
.SH DESCRIPTION
.sp
\fBfenders\fP replaces the boot sectors of an ATR image with a menu\-driven
@@ -62,17 +62,30 @@ Print this help message.
.B \-r
DON\(aqT reboot (coldstart) the Atari if Reset is pressed. The default is to coldstart.
.TP
+.B \-b
+Create \fBinfile\fP as a blank ATR image and update it
+in\-place. This option requires \fBaxe\fP to be present on
+\fIPATH\fP\&. May not be used when reading standard input.
+.TP
.B \-c
Rotate colors during load. May cause problems with some games.
.TP
+.B \-d
+Delete \fIDOS.SYS\fP, \fIDUP.SYS\fP, and \fIAUTORUN.SYS\fP, if they
+exist. This option requires \fBaxe\fP to be present on
+\fIPATH\fP\&. May not be used when writing standard output.
+.TP
.B \-s
Screen off after load. May cause problems with some games, but
may fix graphics corruption for other games. YMMV.
.TP
.B \-i
-In\-place update. The input file is renamed to end in \fB~\fP (tilde),
-and the output is written to the original filename. May not be
-used when reading from standard input.
+In\-place update, with backup. The input file is renamed to end
+in \fB~\fP (tilde), and the output is written to the original
+filename. May not be used when reading from standard input.
+.TP
+.B \-I
+In\-place update, without backup. Use with caution.
.TP
.B \-v
Set inverse video bit in title. This causes the title text to
@@ -80,10 +93,11 @@ appear in red and/or blue on the Atari, instead of the default
orange and green colors.
.TP
.B \-t
-Set the menu title. May up to 20 characters; default is \fIatari
-arcade\fP\&. Will be truncated to 20 characters if a longer title is
-given. See MENU TITLE, below. Note that you\(aqll have to quote the
-title if it contains spaces or other characters that have meaning to your shell.
+Set the menu title. May up to 20 characters; default is \fIatari
+arcade\fP\&. Will be truncated to 20 characters if a longer title
+is given. See MENU TITLE, below. Note that you\(aqll have to quote
+the title if it contains spaces or other characters that have
+meaning to your shell.
.UNINDENT
.INDENT 0.0
.TP
@@ -239,9 +253,6 @@ only way to make it support high\-speed SIO is to use the APE Warp OS
(or some other high\-speed patched OS) on the Atari.
.SH BUGS
.sp
-There should be an option to delete DOS.SYS and DUP.SYS from the image,
-but there isn\(aqt. The original Fenders installer has this option.
-.sp
When used with an image whose size according to the ATR header
doesn\(aqt match the actual image file size, \fBfenders\fP may produce
a broken or zero\-length output file. If in doubt, use \fBatrcheck\fP to
diff --git a/fenders.c b/fenders.c
index 55ad709..fc44754 100644
--- a/fenders.c
+++ b/fenders.c
@@ -20,17 +20,20 @@ extern int optind, opterr, optopt;
#define SELF "fenders"
#define BANNER SELF " v" VERSION " by B. Watson (WTFPL)\n"
#define DEFAULT_TITLE "atari arcade"
-#define OPTIONS "hrscit:v"
+#define OPTIONS "hrsbcdiIt:v"
char *usage =
BANNER
"Install Fenders 3-sector loader in boot sectors of an ATR image\n"
"Usage: " SELF " -[hrcsiv] [-t title] infile.atr [outfile.atr]\n"
" -h Print this help message\n"
+ " -b Create infile as a blank ATR, update it in-place.\n"
" -r DON'T reboot (coldstart) the Atari if Reset is pressed\n"
" -c Rotate colors during load\n"
- " -s Screen off after load\n"
+ " -d Delete DOS.SYS and DUP.SYS\n"
+ " -s Screen off after load\n"
" -i In-place update (original renamed to end in ~)\n"
+ " -I In-place update (NO backup)\n"
" -v Set inverse video bit in title (blue/red text)\n"
" -t title Set title (up to 20 chars, default: '" DEFAULT_TITLE "')\n";
@@ -130,11 +133,19 @@ void set_screen_off(density dens) {
fendersdbl_bin[OFFSET_SCREENOFF_DD] = 0x8d;
}
+/* TODO: error checking */
+void call_axe(const char *args, const char *fname) {
+ char cmd[8192];
+ sprintf(cmd, "axe %s %s", args, fname);
+ fprintf(stderr, SELF ": calling axe, cmd is: %s\n", cmd);
+ system(cmd);
+}
+
int main(int argc, char **argv) {
int coldstart = 1, rot_color = 0, screen_off = 0;
int c, res, size, inverse = 0;
char title[21];
- int in_place = 0;
+ int in_place = 0, rm_backup = 0, rm_dos_dup = 0, create_blank = 0;
char rename_to[4096];
unsigned char buf[384], *bin;
char *infile = "-", *outfile = "-";
@@ -156,10 +167,18 @@ int main(int argc, char **argv) {
coldstart = 0;
break;
+ case 'b':
+ create_blank = 1;
+ in_place = 1;
+ rm_backup = 1;
+
case 'c':
rot_color = 1;
break;
+ case 'd':
+ rm_dos_dup = 1;
+
case 's':
screen_off = 1;
break;
@@ -172,6 +191,11 @@ int main(int argc, char **argv) {
in_place = 1;
break;
+ case 'I':
+ in_place = 1;
+ rm_backup = 1;
+ break;
+
case 'v':
inverse = 1;
break;
@@ -211,7 +235,13 @@ int main(int argc, char **argv) {
rename_to[len] = '~';
rename_to[len + 1] = '\0';
- fprintf(stderr, SELF ": Backing up %s to %s\n", infile, rename_to);
+ if(!rm_backup)
+ fprintf(stderr, SELF ": Backing up %s to %s\n", infile, rename_to);
+
+ if(create_blank) {
+ call_axe("-b", infile);
+ }
+
if(link(infile, rename_to)) {
perror("link()");
exit(1);
@@ -233,6 +263,7 @@ int main(int argc, char **argv) {
perror(infile);
exit(1);
}
+ if(rm_backup) unlink(infile);
}
/* read ATR header */
@@ -384,14 +415,6 @@ int main(int argc, char **argv) {
DOS 3 or 4).
*/
- /* TODO: add option to delete DOS.SYS and DUP.SYS (or more likely,
- delete them by default, and add option to allow user to keep them).
- */
-
- /* TODO: option that creates a new, blank image, with bootloader
- already on it? There's already "atrsize -b" for creating a blank
- image... */
-
/* write the rest of the loader code code to sector 720.
The code in the boot sectors will load sector 720. */
if(fwrite(bin+384, 1, 256, out) < 256) {
@@ -413,6 +436,26 @@ int main(int argc, char **argv) {
c = 1;
}
+ fclose(in);
+ fclose(out);
+
+ if(rm_dos_dup) {
+ /* TODO: check for enhanced density! */
+ if(dens != SD) {
+ fprintf(stderr, SELF
+ ": -d option only works on single-density.\n");
+ exit(2);
+ }
+ if(strcmp(outfile, "-") == 0) {
+ fprintf(stderr, SELF
+ ": Can't use -d option with standard output.\n");
+ exit(2);
+ }
+ call_axe("-D DOS.SYS", outfile);
+ call_axe("-D DUP.SYS", outfile);
+ call_axe("-D AUTORUN.SYS", outfile);
+ }
+
/* ...and I'm spent! */
return c;
}
diff --git a/fenders.rst b/fenders.rst
index 9c4f1c7..fc46798 100644
--- a/fenders.rst
+++ b/fenders.rst
@@ -15,7 +15,7 @@ Install Fenders 3-sector loader in boot sectors of an ATR image
SYNOPSIS
========
-*fenders* [*-hrcsiv*] [-t *title*] *infile.atr* [*outfile.atr*]
+*fenders* [*-hrcsiIv*] [-t *title*] *infile.atr* [*outfile.atr*]
DESCRIPTION
===========
@@ -43,17 +43,30 @@ OPTIONS
-r
DON'T reboot (coldstart) the Atari if Reset is pressed. The default is to coldstart.
+-b
+ Create **infile** as a blank ATR image and update it
+ in-place. This option requires **axe** to be present on
+ *PATH*. May not be used when reading standard input.
+
-c
Rotate colors during load. May cause problems with some games.
+-d
+ Delete *DOS.SYS*, *DUP.SYS*, and *AUTORUN.SYS*, if they
+ exist. This option requires **axe** to be present on
+ *PATH*. May not be used when writing standard output.
+
-s
Screen off after load. May cause problems with some games, but
may fix graphics corruption for other games. YMMV.
-i
- In-place update. The input file is renamed to end in **~** (tilde),
- and the output is written to the original filename. May not be
- used when reading from standard input.
+ In-place update, with backup. The input file is renamed to end
+ in **~** (tilde), and the output is written to the original
+ filename. May not be used when reading from standard input.
+
+-I
+ In-place update, without backup. Use with caution.
-v
Set inverse video bit in title. This causes the title text to
@@ -61,10 +74,11 @@ OPTIONS
orange and green colors.
-t
- Set the menu title. May up to 20 characters; default is *atari
- arcade*. Will be truncated to 20 characters if a longer title is
- given. See MENU TITLE, below. Note that you'll have to quote the
- title if it contains spaces or other characters that have meaning to your shell.
+ Set the menu title. May up to 20 characters; default is *atari
+ arcade*. Will be truncated to 20 characters if a longer title
+ is given. See MENU TITLE, below. Note that you'll have to quote
+ the title if it contains spaces or other characters that have
+ meaning to your shell.
infile
The ATR image to read from. It must be either single-density
@@ -223,9 +237,6 @@ only way to make it support high-speed SIO is to use the APE Warp OS
BUGS
====
-There should be an option to delete DOS.SYS and DUP.SYS from the image,
-but there isn't. The original Fenders installer has this option.
-
When used with an image whose size according to the ATR header
doesn't match the actual image file size, **fenders** may produce
a broken or zero-length output file. If in doubt, use **atrcheck** to