Difference between revisions of "What BASIC is running"

From BeebWiki
Jump to: navigation, search
m (1 revision)
(update)
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 ";?&8007
+
   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 14:03, 8 March 2015

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)