From 7405217ad5ad2889de4c997dc346a70cb1e31897 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 11 Jul 2024 05:34:30 -0400 Subject: whichbas: much fancier BASIC/A+ detection (maybe too fancy?) --- whichbas.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 20 deletions(-) diff --git a/whichbas.c b/whichbas.c index ec997cb..3a86c94 100644 --- a/whichbas.c +++ b/whichbas.c @@ -1045,41 +1045,121 @@ void check_variables(void) { 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+. + the others. So A+ can't even LOAD or RUN Atari BASIC files. + Appendix J of the BASIC/A+ manual tells you to LIST in BASIC, + reboot, ENTER in A+, to "port" your BASIC programs to A+. I + suppose if you upgraded from A+ to BASIC XL or XE, you'd have + to do the same thing to use A+ programs in XL/XE. 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+. */ + BXL, and BXE... but *different* in A+. + + However... I've run into at least one BASIC program in the Holmes + Archive that was missing its line 32768 (wish I could remember which). + And it's possible for files to get truncated... so I'll check a few + other command tokens, to deal with cases like this. + */ +void found_aplus(void) { + foreign("OSS BASIC/A+", SRET_APLUS); +} + CALLBACK(check_aplus_cmd) { - unsigned char nexttok; - int aplus_found = 0; + int has_args; + unsigned char nexttok, nexttok2; nexttok = program[pos + 1]; + nexttok2 = program[pos + 2]; + has_args = !(nexttok == OP_EOS || nexttok == OP_EOL); + if(verbose) fprintf(stderr, "check_aplus_cmd: line %d, pos $%04x, tok $%02x, nexttok $%02x, nexttok2 $%02x\n", lineno, pos, tok, nexttok, nexttok2); - 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); - } + switch(tok) { + case CMD_POP: /* A+ READ */ + case CMD_DOS: /* A+ GET */ + case CMD_DEG: /* A+ WHILE */ + case CMD_CLR: /* A+ DIM */ + case 0x46: /* A+ SOUND , Turbo LOOP, BXL/XE CP */ + if(has_args) + found_aplus(); + break; + + case CMD_SAVE: /* A+ END */ + case CMD_GRAPHICS: /* A+ STOP */ + case CMD_DIM: /* A+ ENDWHILE */ + case CMD_GET: /* A+ RETURN */ + case 0x38: /* A+ DOS, Turbo DPOKE, BXL/XE WHILE */ + if(!has_args) + found_aplus(); + break; - if(aplus_found) { - foreign("OSS BASIC/A+", SRET_APLUS); + case CMD_POSITION: /* A+ ? */ + /* PARTIAL: does nothing if 1st arg is numeric. */ + if(!has_args) + /* POSITION can't have 0 args. */ + found_aplus(); + else if(is_string_rval(nexttok)) + /* ? "STRING" or ? A$, e.g., can't be POSITION */ + found_aplus(); + else if(nexttok == OP_NUM_LE) /* numeric <= in BASIC, # in A+ */ + found_aplus(); + break; + + case CMD_RUN: /* A+ PRINT */ + /* PARTIAL: only detects PRINT # or PRINT ... */ + /* A+'s # token is BASIC's OP_NUM_LE! */ + if(nexttok == OP_NUM_LE) + found_aplus(); + else if(is_numconst_op(nexttok) || is_numeric_var(nexttok)) + found_aplus(); + break; + + case CMD_XIO: /* A+ SAVE */ + /* most programs, this is enough, because they'll end with + 32768 SAVE "D:BLAH" */ + if(is_string_rval(nexttok)) + found_aplus(); + break; + + case CMD_OPEN: /* A+ ELSE */ + /* case CMD_CLOSE: */ /* A+ DEG */ /* can't check, Turbo allows no args */ + case CMD_STATUS: /* A+ NEW */ + case CMD_POINT: /* A+ LOAD */ + case 0x42: /* A+ POSITION, Turbo BPUT, BXL RGET */ + case 0x43: /* A+ DRAWTO, Turbo BGET, BXL BPUT */ + if(nexttok != OP_HASH) /* # in BASIC, USING in A+ */ + found_aplus(); + break; + + /* case 0x48: */ /* A+ CSAVE, Turbo DIR, BXL/BXE PROTECT */ + /* DIR without arg is OK, so we can't really check this. */ + /* break; */ + + case CMD_DRAWTO: /* A+ PUT */ + case CMD_SOUND: /* A+ RPUT */ + case CMD_LPRINT: /* A+ RGET */ + case CMD_CSAVE: /* A+ BPUT */ + case CMD_CLOAD: /* A+ BGET */ + case CMD_ON: /* A+ STATUS */ + case CMD_NOTE: /* A+ OPEN */ + case CMD_CONT: /* A+ CLOSE */ + case CMD_RAD: /* A+ XIO */ + if(nexttok == OP_NUM_LE) /* numeric <= in BASIC, # in A+ */ + found_aplus(); + break; + + default: break; } + + last_cmd = tok; } void check_aplus(void) { + allow_hex_const = 1; + on_cmd_token = check_aplus_cmd; - walk_code(32768, 32768); + walk_all_code(); } void check_atari_turbo_oss(void) { -- cgit v1.2.3