From a099543f2193948ba604165d2824ac3b9dbd8d4d Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 9 Jul 2024 20:07:56 -0400 Subject: whichbas: add BASIC/A+ detection. --- whichbas.1 | 5 ++++- whichbas.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- whichbas.rst | 5 ++++- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/whichbas.1 b/whichbas.1 index baead4f..7f422c3 100644 --- a/whichbas.1 +++ b/whichbas.1 @@ -36,7 +36,7 @@ whichbas [\-v] \fIinput\-file\fP .SH DESCRIPTION .sp \fBwhichbas\fP reads a tokenized Atari 8\-bit BASIC, Turbo BASIC, -BASIC XL, BASIC XE, or Atari Microsoft BASIC program and attempts to +BASIC XL, BASIC XE, BASIC/A+, or Atari Microsoft BASIC program and attempts to discover which BASIC is required to run it. .sp \fIinput\-file\fP must be an actual file. \fBwhichbas\fP can\(aqt read from @@ -186,6 +186,9 @@ EXTENDed OSS BASIC XE detected. .B \fB13\fP Compiled Turbo BASIC detected. .TP +.B \fB14\fP +OSS BASIC/A+ detected. +.TP .B \fB64\fP None of the above; not BASIC. .UNINDENT diff --git a/whichbas.c b/whichbas.c index 3b74415..13289f0 100644 --- a/whichbas.c +++ b/whichbas.c @@ -28,6 +28,7 @@ int bas_type = 0x0f; /* start out with all enabled */ #define SRET_AMSB 11 #define SRET_EXTENDED_BXE 12 #define SRET_COMPILED_TURBO 13 +#define SRET_APLUS 14 #define SRET_NOT_BASIC 64 int script_mode = 0; /* -s flag */ @@ -712,7 +713,7 @@ int detect_amsb(void) { } void foreign(const char *name, int srval) { - fclose(input_file); + if(input_file) fclose(input_file); if(script_mode) { exit(srval); } else { @@ -806,6 +807,57 @@ void check_variables(void) { to disk. Too bad. */ } +/* BASIC/A+ support is *very* simple. It's similar to BASIC XL (no + surprise there)... but unlike Turbo, BXL, and BXE, it's *not* + token-compatible with original Atari BASIC. Rather than add + their new tokens to the end of the lists, they're mixed in with + the others. So A+ can't even LOAD or RUN Atari BASIC files. I + suppose the manual told you to LIST in BASIC, reboot, ENTER in + A+, to "port" your BASIC programs to A+. + + While this was probably a PITA for BASIC/A+ users back in the day, + it makes it *really* easy to detect A+ here. The last line of + every SAVEed program is the direct-mode command, and contains either + a SAVE or CSAVE cmd token. Which is the same token in Atari, Turbo, + BXL, and BXE... but *different* in A+. */ +CALLBACK(check_aplus_cmd) { + unsigned char nexttok; + int aplus_found = 0; + + nexttok = program[pos + 1]; + + if(tok == 0x1d) { + /* SAVE in A+ (OP_STRCONST next). + XIO in anything else (OP_HASH next). */ + /* Note that A+ still uses the same tokens as BASIC for OP_STRCONST, + OP_EOS, and OP_EOL. */ + aplus_found = (nexttok == OP_STRCONST); + } else if(tok == 0x48) { + /* CSAVE in A+ (no arg). + RND in anything else (OP_FUNC_LPAR next). */ + aplus_found = (nexttok == OP_EOS || nexttok == OP_EOL); + } + + if(aplus_found) { + foreign("OSS BASIC/A+", SRET_APLUS); + } +} + +void check_aplus(void) { + on_cmd_token = check_aplus_cmd; + walk_code(32768, 32768); +} + +void check_atari_turbo_oss(void) { + allow_hex_const = 1; + + on_cmd_token = handle_cmd; + on_exp_token = handle_op; + on_end_stmt = handle_end_stmt; + + walk_all_code(); +} + int main(int argc, char **argv) { set_self(*argv); parse_general_args(argc, argv, print_help); @@ -817,13 +869,8 @@ int main(int argc, char **argv) { parse_header(); check_variables(); - - allow_hex_const = 1; - on_cmd_token = handle_cmd; - on_exp_token = handle_op; - on_end_stmt = handle_end_stmt; - - walk_all_code(); + check_aplus(); + check_atari_turbo_oss(); print_result(); /* always exits */ return 0; /* never happens, shuts up gcc's warning though */ diff --git a/whichbas.rst b/whichbas.rst index 327e8dc..497b0ff 100644 --- a/whichbas.rst +++ b/whichbas.rst @@ -15,7 +15,7 @@ whichbas [-v] *input-file* DESCRIPTION =========== **whichbas** reads a tokenized Atari 8-bit BASIC, Turbo BASIC, -BASIC XL, BASIC XE, or Atari Microsoft BASIC program and attempts to +BASIC XL, BASIC XE, BASIC/A+, or Atari Microsoft BASIC program and attempts to discover which BASIC is required to run it. *input-file* must be an actual file. **whichbas** can't read from @@ -154,6 +154,9 @@ With the **-s** option, the exit status is: **13** Compiled Turbo BASIC detected. +**14** + OSS BASIC/A+ detected. + **64** None of the above; not BASIC. -- cgit v1.2.3