aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-07-11 05:34:30 -0400
committerB. Watson <urchlay@slackware.uk>2024-07-11 05:34:30 -0400
commit7405217ad5ad2889de4c997dc346a70cb1e31897 (patch)
tree01c09c5ba6331baa35c5e00b562dc89f1fdeef08
parenta493bd91d6366113178633b86dfd4703f73b520d (diff)
downloadbw-atari8-tools-7405217ad5ad2889de4c997dc346a70cb1e31897.tar.gz
whichbas: much fancier BASIC/A+ detection (maybe too fancy?)
-rw-r--r--whichbas.c120
1 files 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 <args>, 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 <num> ... */
+ /* 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) {