.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "WHICHBAS" 1 "2024-07-24" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME whichbas \- Determine BASIC variant of a tokenized Atari 8-bit program .SH SYNOPSIS .sp whichbas [\-v] \fIinput\-file\fP [\fIinput\-file\fP ...] .SH DESCRIPTION .sp \fBwhichbas\fP reads tokenized Atari 8\-bit BASIC, Turbo BASIC, BASIC XL, BASIC XE, BASIC/A+, or Atari Microsoft BASIC programs and attempts to discover which BASIC is required to run each one. .sp \fIinput\-file\fPs must be actual files. \fBwhichbas\fP can\(aqt read from standard input, because it seeks in the input file. .sp With multiple \fIinput\-file\fPs, the output is one line per file, with the filename, a tab, and the detected BASIC. With only one \fIinput\-file\fP, the filename and tab are not printed. .SH OPTIONS .sp \fINote\fP: none of the options \fB\-s\fP \fB\-k\fP \fB\-v\fP are allowed when checking multiple files; they only work if there\(aqs just one \fIinput\-file\fP argument. .SS Detection Options .INDENT 0.0 .TP .B \fB\-s\fP Script (or silent) mode. Instead of printing a human\-readable name like "Turbo BASIC XL" or "OSS BASIC XE" to stdout, \fBwhichbas\fP will print nothing on standard output, but will exit with a status indicating what it detected. The caller can check the return status (e.g. the \fB$?\fP variable in Bourne/POSIX shells, or \fBERRORLEVEL\fP in MS\-DOS or Windows). See \fBEXIT STATUS\fP, below. .TP .B \fB\-k\fP Keep going. The default is to stop looking at the program if the BASIC type gets narrowed down to either Turbo BASIC or BASIC XE. This option also enables \fB\-v\fP (verbose). It\(aqs really only useful for testing, if you\(aqre hacking on \fBwhichbas\fP itself. .UNINDENT .SS General Options .INDENT 0.0 .TP .B \fB\-\-help\fP Print usage message and exit. .TP .B \fB\-\-version\fP Print version number and exit. .TP .B \fB\-v\fP Verbose operation. When displaying a number in verbose mode, it will be prefixed with \fI$\fP if it\(aqs in hex, or no prefix for decimal. .UNINDENT .SH NOTES .sp Atari BASIC programs are detected \fIalmost\fP 100% reliably. See \fBBUGS\fP, below, for the gory details. .sp Turbo BASIC, BASIC XL, and BASIC XE are all supersets of Atari BASIC. If you wrote a program using one of them, but didn\(aqt use any of the extra commands or functions, the result is still an Atari BASIC program. Likewise, if you wrote a program using BASIC XE, but only used the commands/functions it has in common with BASIC XL, it would be detected as BASIC XL. .sp There are two types of BASIC XE programs: regular and \fIEXTEND\fPed. The extended type is detected 100% reliably, because the first byte of the file changes from \fB$00\fP to \fB$DD\fP\&. Non\-extended programs are only identified as BASIC XE if they use any of the extra commands BASIC XE adds to those found in BASIC XL. .sp Detection of Turbo vs. BXL/BXE isn\(aqt 100% reliable, and probably never will be. There\(aqs too much overlap between the sets of extra tokens added by each. Programs that don\(aqt use very many of the extra functions provided by Turbo/BXL/BXE may show up as "Either Turbo BASIC XL or OSS BASIC XL". .sp Atari Microsoft BASIC is detected by checking that: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 the first byte of the file is \fB$00\fP\&. .IP \(bu 2 the next 2 bytes (LSB/MSB) are the same as the actual file length minus 3. .IP \(bu 2 the last 3 bytes of the file are zero. .UNINDENT .UNINDENT .UNINDENT .sp This may result in false positives (files that aren\(aqt BASIC programs at all might show up as Microsoft). Also, no distinction is made between Atari MS BASIC 1.0 and 2.0. .sp OSS BASIC/A+ is an extended form of Atari BASIC. It\(aqs source compatible with Atari BASIC, but not token\-compatible because it uses different token numbers for the regular BASIC commands and operators. Example: SAVE is token \fB$19\fP in Atari BASIC (also Turbo/BXL/BXE), but in A+ it\(aqs token \fB$1D\fP\&. Detection should be 100% reliable, but since there aren\(aqt many BASIC/A+ programs in the wild, it hasn\(aqt been thoroughly tested. .sp Various non\-BASIC files are detected (including Mac/65 source, ELF binaries, etc) as a convenience, but I wouldn\(aqt rely on \fBwhichbas\fP\(aqs non\-BASIC file type detection if I were you. If you need the \fBfile\fP(1) command, use it. .sp \fBwhichbas\fP knows nothing about other BASICs such as Frost BASIC or Altirra BASIC. .sp When using multiple \fIinput\-file\fP arguments, a separate instance of \fBwhichbas\fP is spawned for each file. This isn\(aqt the most efficient approach, but it shouldn\(aqt cause problems on reasonably modern systems. .SH BUGS .SS Misdetection .sp It\(aqs possible to get a BASIC XL/XE program to misdetect as Atari BASIC by writing a program that does these things: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Dimension a string array with a number of elements that isn\(aqt just a numeric constant or numeric variable (e.g. \fIDIM A$(2+2,10)\fP or \fIDIM A$(I*2,10)\fP). The code that detects a string array \fIDIM\fP command can only handle simple cases like \fIDIM A$(10,10)\fP or \fIDIM A$(I,10)\fP\&. It doesn\(aqt actually matter if the 2nd argument is a fancy expression, though. .IP \(bu 2 Does \fInot\fP actually \fIuse\fP the string array variable by assigning to it or reading a value from it. String array accesses in BASIC XL/XE are reliably detected because they require a semicolon after the first number, even if there isn\(aqt a 2nd number. Example: \fI? A$(2;)\fP prints the 2nd element of the \fIA$\fP string array. If it were written as \fI? A$(2)\fP, but \fIA$\fP is a string array (not a regular string), BASIC XL/XE would give an \fIError 40\fP (string type mismatch) at runtime. .UNINDENT .UNINDENT .UNINDENT .sp The good news is, such a program will still work fine in Atari BASIC. Atari BASIC will dimension it as a regular string variable and ignore the 2nd dimension. Since it\(aqs not actually used elsewhere in the program, it doesn\(aqt hurt anything. .SH EXIT STATUS .sp Without the \fB\-s\fP option, exit status is 0 for success, non\-zero for failure. .sp With the \fB\-s\fP option, the exit status is: .INDENT 0.0 .TP .B \fB0\fP Not used with \fB\-s\fP\&. .TP .B \fB1\fP or \fB2\fP Error reading file. Error message will be printed on standard error. .TP .B \fB3\fP Atari BASIC detected. .TP .B \fB4\fP Turbo BASIC detected. .TP .B \fB5\fP OSS BASIC XL detected. .TP .B \fB6\fP Non\-EXTENDed OSS BASIC XE detected. .TP .B \fB7\fP Turbo BASIC or BASIC XL (undecided which). .TP .B \fB8\fP Turbo BASIC or non\-EXTENDed BASIC XE (undecided which). .TP .B \fB9\fP Turbo BASIC, BASIC XL, or non\-EXTENDed BASIC XE (undecided which). .TP .B \fB10\fP Unknown Atari BASIC derivative (not Atari BASIC, but not Turbo/BXL/BXE/A+ either). .TP .B \fB11\fP Atari Microsoft BASIC detected. .TP .B \fB12\fP EXTENDed OSS BASIC XE detected. .TP .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 .sp In the future, more exit codes may be defined (in the range \fB15\fP to \fB63\fP), but the existing ones will not change. .SH COPYRIGHT .sp WTFPL. See \fI\%http://www.wtfpl.net/txt/copying/\fP for details. .SH AUTHOR .INDENT 0.0 .IP B. 3 Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\&. .UNINDENT .SH SEE ALSO .sp \fBa8cat\fP(1), \fBa8eol\fP(1), \fBa8xd\fP(1), \fBatr2xfd\fP(1), \fBatrsize\fP(1), \fBaxe\fP(1), \fBbas2aplus\fP(1), \fBblob2c\fP(1), \fBblob2xex\fP(1), \fBcart2xex\fP(1), \fBcxrefbas\fP(1), \fBdasm2atasm\fP(1), \fBdiffbas\fP(1), \fBdumpbas\fP(1), \fBf2toxex\fP(1), \fBfenders\fP(1), \fBlistbas\fP(1), \fBprotbas\fP(1), \fBrenumbas\fP(1), \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), \fBvxrefbas\fP(1), \fBwhichbas\fP(1), \fBxex1to2\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), \fBxfd2atr\fP(1), \fBxex\fP(5), \fBatascii\fP(7), \fBfauxtari\fP(7). .sp Any good Atari 8\-bit book: \fIDe Re Atari\fP, \fIThe Atari BASIC Reference Manual\fP, the \fIOS Users\(aq Guide\fP, \fIMapping the Atari\fP, etc. .\" Generated by docutils manpage writer. .