What BASIC is running
Sometimes a program needs to know what version of BASIC it is running on, for instance so that BASIC V instructions such as SYS, local errors and multi-line IFs can be used where version-neutral or platform-neutral code cannot otherwise be used. This is different from knowing what machine a program is running on which can be found with OSBYTE 0 and INKEY-256. 6502 BASIC II could be running on RISC OS via 65Tube, ARM BASIC V could be running on a BBC B via the ARM CoProcessor. In each of these cases, OSBYTE 0 or INKEY-256 would not give the answer looked for.
The following code allows a program to tell if it is running on BASIC V.
DEFPROCtest IF FALSE THEN PRINT "Not running on BASIC V":ENDPROC ENDIF PRINT "Running on BASIC V" ENDPROC
The above is BASIC V code. As some keywords are tokenised differently, on BASIC I to IV the code must be entered as:
DEFPROCtest IF FALSE THEN PRINT "Not running on BASIC V":ENDPROC SAVE PRINT "Running on BASIC V" ENDPROC
This takes advantage of the fact that pre-BASIC V does not understand multi-line IFs and so will just execute an empty THEN as an empty THEN. BASIC V sees an empty THEN as the start of a multi-line IF/ENDIF structure.
BASIC I does not implement offset assembly. This can be used to distinguish BASIC I from other pre-BASIC Vs with the following code:
DIM P% -1:O%=P%:[OPT 4:NOP:] IF P%<>O% THEN PRINT "BASIC I" ELSE PRINT "BASIC II or later"
OPT 4 selects offset assembly, so if O% has not changed after assembling some code, it must be BASIC I running.
It is difficult to distinguish BASIC IV from other BASICs without generating an error or writing to the screen. A weak test is to read the ROM version number, but this will only work with 6502 BASIC. The following code will do this.
IF HIMEM=&8000 OR HIMEM=&B800 THEN PRINT "BASIC ";?(HIMEM+7)
This is not perfect, as BASIC IV v4.0 will return &40, BASIC IV v4.30 will return &06 and BASIC IV v4.32 will return &07.
These tests can be made into a function as follows, as in the BASIC library:
REM Code if edited on pre-BASIC V DEFFNBASIC_Ver:LOCAL O%,P% IF FALSE THEN DIM P%-1:O%=P%:[OPT 4:NOP:]IFP%<>O%:=1 IFHIMEM=&8000 OR HIMEM=&B800:IF!(HIMEM+9)=&49534142:=?(HIMEM+8) =2 SAVE =5 REM Code if edited on BASIC V DEFFNBASIC_Ver:LOCAL O%,P% IF FALSE THEN DIM P%-1:O%=P%:[OPT 4:NOP:]IFP%<>O%:=1 IFHIMEM=&8000 OR HIMEM=&B800:IF!(HIMEM+9)=&49534142:=?(HIMEM+8) =2 ENDIF =5
This returns the following values:
- 1 if BASIC I or equivalent, offset assembly, OSCLI, OPENUP not available
- >1 if BASIC II or equivalent or later, offset assembly, OSCLI, OPENUP available
- >3 if BASIC IV or equivalent or later, TIME$, ON x PROC available
- >4 if BASIC V or equivalent or later, SYS, WHILE, CASE, multiline IF/ENDIF available
This means you can then use code such as the following:
IF FNBASIC_Ver<5 THEN CHAIN "Exit" ELSE SYS "XOS_CLI","Quit"
IF FALSE THEN CHAIN "Exit" ENDIF SYS "XOS_CLI","Quit"
Jgharston 11:06, 2 September 2008 (BST)