Difference between revisions of "What BASIC is running"
m (Added inline test.) |
m |
||
Line 1: | Line 1: | ||
[[Category:BASIC]] | [[Category:BASIC]] | ||
[[Category:Programming]] | [[Category:Programming]] | ||
− | 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. | + | 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. | The following code allows a program to tell if it is running on BASIC V. | ||
Line 12: | Line 19: | ||
ENDPROC | ENDPROC | ||
− | The above is BASIC V code. As some keywords are tokenised differently, on BASIC I to IV the code must be entered as: | + | The above is BASIC V code. As some keywords are tokenised differently, on |
+ | BASIC I to IV the code must be entered as: | ||
DEFPROCtest | DEFPROCtest | ||
Line 21: | Line 29: | ||
ENDPROC | 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. | + | 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: | + | 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:] | DIM P% -1:O%=P%:[OPT 4:NOP:] | ||
IF P%<>O% THEN PRINT "BASIC I" ELSE PRINT "BASIC II or later" | 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. | + | 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. | + | 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 ";? | + | 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. | + | 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 [http://mdfs.net/System/Library/BLib BASIC] library: | + | These tests can be made into a function as follows, as in the |
+ | [http://mdfs.net/System/Library/BLib BASIC] library: | ||
REM Code if edited on pre-BASIC V | REM Code if edited on pre-BASIC V |
Revision as of 00:31, 22 December 2013
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"
or
IF FALSE THEN CHAIN "Exit" ENDIF SYS "XOS_CLI","Quit"
Jgharston 11:06, 2 September 2008 (BST)