diff options
author | B. Watson <urchlay@slackware.uk> | 2024-07-08 05:44:34 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-07-08 05:44:34 -0400 |
commit | b557e87b4b4a543f71579327ea64c9f62ee2c642 (patch) | |
tree | 8b4d46eac73b4b759b5f1b1a64f51157f92058ba | |
parent | dd2b3e2f8109c81b11cb040c455fdff9089ae40f (diff) | |
download | bw-atari8-tools-b557e87b4b4a543f71579327ea64c9f62ee2c642.tar.gz |
whichbas: detect Turbo argument-less CLOSE, SOUND; IOCB-less GET, PUT; RESTORE # and TRAP #; detection for cmds GO#/SORTUP and #/SORTDOWN.
-rw-r--r-- | whichbas.c | 75 |
1 files changed, 59 insertions, 16 deletions
@@ -100,6 +100,43 @@ CALLBACK(handle_cmd) { if(verbose) fprintf(stderr, "handle_cmd: lineno %d, tok $%02x, bas_type was %02x\n", lineno, tok, bas_type); + nexttok = program[pos + 1]; + has_args = !(nexttok == OP_EOS || nexttok == OP_EOL); + + /* this switch is for tokens that are the same in Atari/Turbo/BXL/BXE, but with + different semantics. non-Atari-BASIC tokens go in the switch below, not + this one. */ + switch(tok) { + /* TB uses the same token for CLOSE as Atari and BXL/BXE, but it allows + it to have no argument (meaning, close all IOCBs). SOUND is the same + (no args = silence all POKEY channels). */ + case CMD_CLOSE: + case CMD_SOUND: + if(!has_args) { + bas_type = BT_TURBO; + print_result(); + } + break; + case CMD_GET: + case CMD_PUT: + /* TB uses the same tokens for GET and PUT as Atari/BXL/BXE, but it allows + the argument to be a variable without a # in front of it. */ + if(nexttok != OP_HASH) { + bas_type = BT_TURBO; + print_result(); + } + break; + case CMD_RESTORE: + case CMD_TRAP: + /* TB allows RESTORE #LABEL and TRAP #LABEL */ + if(nexttok == OP_HASH) { + bas_type = BT_TURBO; + print_result(); + } + break; + default: break; + } + if(tok <= CMD_ERROR) return; /* legal in BASIC, ignore */ remove_type(BT_ATARI); if(tok >= 0x59) remove_type(BT_BXL); @@ -110,30 +147,25 @@ CALLBACK(handle_cmd) { print_result(); } - nexttok = program[pos + 1]; - has_args = !(nexttok == OP_EOS || nexttok == OP_EOL); - /* we have tokens 0x3a to 0x68 in both TB and BXE, or 47 of them. Some tokens can't be determined, because they take the same argument (or lack of) in both Turbo and BXL/XE. These are: 0x3c: REPEAT or ELSE (no args either way) - 0x42: Maybe: BPUT or RGET (take the same args... but not quite!) - 0x43: Maybe: BGET or BPUT (take the same args... but not quite!) 0x46: LOOP or CP (no args either way) 0x49: LOCK or UNPROTECT (take the same args) 0x4B: RENAME in both Turbo and BXL/XE (take the same args) 0x60: CLS or HITCLR (no args either way) This leaves 40 we can check. - Covered so far: 34 (85%) + Covered so far: 36 (90%) TODO: Unknown tokens: 0x54: ??? in TB (find out what), LVAR in BXL/BXE. 0x5A: BLOAD or... what? (Jindroush lists it as ?5A?) TODO: + 0x42: Maybe: BPUT or RGET (take the same args... but not quite!) + 0x43: Maybe: BGET or BPUT (take the same args... but not quite!) 0x5B: BRUN or CALL (both take a string, CALL allows "USING" though) - 0x5C: GO# (1 arg only) or SORTUP (optional 2nd arg of USING, but no comma) - 0x5D: # (1 arg only) or SORTDOWN (optional 2nd arg of USING, but no comma) 0x5F: PAINT (req 2 args) or NUM (optional 2 args, probly not appear in program) */ switch(tok) { @@ -204,7 +236,7 @@ CALLBACK(handle_cmd) { } break; case 0x4e: /* TIME$= (1 string arg) or PMCLR (1 num arg) */ - /* XXX: this doesn't do anything if the arg is a variable; we + /* partial: this doesn't do anything if the arg is a variable; we could examine the type, but we don't yet */ if(nexttok == OP_STRCONST) { remove_type(BT_BXL_BXE); @@ -220,9 +252,19 @@ CALLBACK(handle_cmd) { case 0x57: /* DUMP (1 optional string arg) or LOCAL (1 variable arg) */ if(!has_args || (nexttok == OP_STRCONST)) { /* if there's no arg, or one string constant arg... */ - /* XXX: DUMP A$ not detected */ + /* partial: DUMP A$ not detected */ remove_type(BT_BXL_BXE); } + case 0x5c: /* GO# (1 arg only) or SORTUP (optional 2nd arg of USING, but no comma) */ + case 0x5d: /* # (1 arg only) or SORTDOWN (optional 2nd arg of USING, but no comma) */ + /* Turbo BASIC labels have the high 2 bits set to 11, which is illegal + in Atari/BXL/BXE. */ + if(get_vartype(nexttok) == 3) { + remove_type(BT_BXL_BXE); + } else { + remove_type(BT_TURBO); + } + break; default: break; } if(verbose) fprintf(stderr, " bas_type now %02x\n", bas_type); @@ -262,15 +304,11 @@ CALLBACK(handle_op) { } /* There are 25 extra operators in Turbo, and 20 of them are shared with - BXL/BXE. Of the 20, 6 of them are undecidable, and the rest are - covered here, which means 70% coverage of the shared ops. + BXL/BXE. Of the 20, 4 of them are undecidable, and the rest are + covered here, which means 80% coverage of the shared ops. Undecidables are: 0x56 & (logical AND) or % (XOR), both infix numeric ops; can't tell apart 0x57 ! (logical OR) in both Turbo and BXL/BXE, can't tell apart - 0x5e FRAC (num func, 1 arg) or DPEEK (num func, 1 arg in BXL... BXE - can take an optional 2nd arg, but it'd be a lot of effort - to detect, and I suspect it's a rarely used construct anyway. - 0x63 RND (func, 1 num arg) or ERR (func, 1 num arg), can't tell apart 0x64 RAND (func, 1 num arg) or TAB (func, 1 num arg), can't tell apart 0x65 TRUNC (func, 1 num arg) or PEN (func, 1 num arg), can't tell apart */ @@ -348,6 +386,11 @@ CALLBACK(handle_op) { remove_type(BT_BXL_BXE); } break; + case 0x63: /* RND (pseudo-func, no arg) or ERR (func, 1 num arg) */ + if(nexttok != OP_FUNC_LPAR) { + bas_type = BT_TURBO; + print_result(); + } case 0x66: /* %0 in TB, LEFT$( (pseudo-func, takes string) in BXL/BXE */ case 0x67: /* %1 in TB, RIGHT$( (pseudo-func, takes string) in BXL/BXE */ case 0x68: /* %2 in TB, MID$( (pseudo-func, takes string) in BXL/BXE */ |