aboutsummaryrefslogtreecommitdiff
path: root/whichbas.c
diff options
context:
space:
mode:
Diffstat (limited to 'whichbas.c')
-rw-r--r--whichbas.c63
1 files changed, 55 insertions, 8 deletions
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 */