From 8221db255f9cc66af2a9356e5ab68c6fd555ad3a Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 8 May 2024 15:09:16 -0400 Subject: fenders: add -I, -d, -b options. --- atr2xfd.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++----- fenders.1 | 35 +++++++++++++++++++++----------- fenders.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- fenders.rst | 33 ++++++++++++++++++++---------- 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 -- cgit v1.2.3