The home of BBC BASIC

R. T. RUSSELL

Differences between BB4W and BBCSDL



BBC BASIC for Windows (BB4W) and BBC BASIC for SDL 2.0 (BBCSDL) are highly compatible with each other, and many programs will run equally well on both without any modification. The underlying BBC BASIC interpreters are substantially identical (at least, the 32-bit editions are), so when incompatibilities do arise they are usually in respect of platform and Operating System differences not directly connected with BBC BASIC.

However there are inevitably some differences that the programmer may need to be aware of, and this document attempts to list them. It is not intended to be comprehensive, and will from time to time be updated when omissions come to light. If the user wishes to write a program that will run on both BB4W and BBCSDL, and his program is affected by one or more of these differences, it will usually be possible to use a conditional clause as follows:

IF INKEY$(-256) = "W" THEN
  REM BB4W-specific code goes here, for example:
  SYS "SetWindowText", @hwnd%, "My Window Title"
ELSE
  REM BBCSDL-specific code goes here, for example:
  SYS "SDL_SetWindowTitle", @hwnd%, "My Window Title", @memhdc%
ENDIF
If there are many such clauses in your program, you may wish to assign a Boolean variable:
BB4W = INKEY$(-256) == "W"
IF BB4W THEN
...

Here is the current list of known differences between BB4W and BBCSDL:

  1. Graphics

    1. BB4W graphics are drawn using the Windows GDI subsystem; BBCSDL graphics are drawn using the SDL2_gfx subsystem. Whilst the end results should always be quite similar, they will not be 'pixel identical' and special care may be necessary in critical cases, such as when an outline shape is drawn and subsequently flood-filled. Notably, RECTANGLE FILL is exclusive of the right and bottom edges in BB4W but inclusive in BBCSDL.

    2. BBCSDL does not currently support plotting a filled segment (PLOT 168-175).

    3. Flood-fill operations should work correctly, but in BBCSDL a substantial speed improvement may be achievable by first defining a graphics viewport that only just encloses the area to be filled.

    4. The POINT(x,y) and TINT(x,y) functions, and any other operations which involve 'reading back from the screen' (e.g. *GSAVE), are typically very slow in BBCSDL and should be avoided when speed is important.

    5. In BBCSDL the MODE statement (or VDU 23,22...) restores user-defined characters to their default appearance. Therefore it must precede, not follow, any VDU 23... character definitions. A resulting incompatibility can usually be resolved by moving the MODE statement.

    6. BBCSDL currently has no support for hard copy output, i.e. driving a printer, plotter or PDF writer.
  2. Sound

    1. The SOUND and ENVELOPE statements should behave in a fully compatible way, but BBCSDL generates 16-bit stereo 'CD quality' sound (this is achievable in BB4W by using the HQSOUND library).

    2. BBCSDL has new *STEREO and *VOICE commands; see 'Star Commands' below.

    3. BBCSDL does not support the *PLAY command.

    4. MP3 and WAV files may be played using SYS calls to the Operating System, but these are quite different between BB4W and BBCSDL.
  3. File System

    1. To ensure cross-platform compatibility, a forward-slash (/) should always be used as the directory delimiter, not a backslash (\).

    2. In BBCSDL (depending on the platform) path and file names may be case-sensitive. When referencing files be careful always to use the same case as the actual filename.

    3. BBCSDL does not support the ability to change the length of a file using the EXT#chan=newlength syntax.

    4. Android does not support the concept of 'current directory' therefore all files should be specified using an absolute path rather than a relative path. This is most easily achieved by using the @dir$, @lib$, @tmp$ and @usr$ system variables.

    5. When reading or writing text files, remember that the line termination used by Linux and related OSes is a single LF character (CHR$10) rather than the CRLF sequence used by Windows (CHR$13+CHR$10). Further information can be found at the Wiki.

    6. BBCSDL does not display a file selector if an attempt is made to open a file with a name containing wildcard characters. You can use the File selector dialogue library as a substitute.

    7. The syntax for opening (e.g.) a serial port, and for setting its parameters (baud rate etc.) is different.
  4. Star Commands

    1. The following BB4W star commands (and their OSCLI equivalents) are not available in BBCSDL: *HARDCOPY, *MARGINS, *PLAY, *PRINTER and *PRINTERFONT.

    2. The following new star commands are available in BBCSDL:
      *DUMP file [hexstart [+hexlen]] (Dumps the contents of the file, in hexadecimal and ASCII)
      *OSK on|off (for enabling or disabling the on-screen-keyboard in Android and iOS)
      *STEREO channel,pan (where channel is 0-3 and pan is -127 for fully left to +127 for fully right)
      *VOICE channel,voice (where channel is 0-3 and voice is 0-7)
      

    3. The *FONT command behaves differently in BBCSDL, specifically it is necessary to specify the full path to the TTF or OTF file, rather than simply the name of the typeface. Typically the file will be in the @lib$ folder, when the command will be of the form:
      OSCLI "font """ + @lib$ + "DejaVuSans.ttf"", 24"
      
      You may alternatively reference local fonts, but since there is no standardisation this will make your program platform-specific (for example Android fonts are stored in /system/fonts/ and Windows fonts are in C:\Windows\Fonts\).

    4. In BBCSDL the *SYS command supports the additional parameters 2 (to enable interception of the SDL_FINGERDOWN, SDL_FINGERUP and SDL_FINGERMOTION messages with ON MOUSE) and 4 (to enable interception of the SDL_MULTIGESTURE message with ON SYS). Parameters may be combined.

    5. In BBCSDL only, the *DISPLAY and *MDISPLAY commands will accept GIF, JPG and PNG files as well as BMP files. In both BB4W and BBCSDL the image may be flipped by specifying a negative value for the width and/or height; an optional 'transparent colour' may be specified.

    6. In BBCSDL *REFRESH waits for 'vsync', synchronising your program to the display's refresh period. In BB4W it does not (waiting for 'vsync' in BB4W is more difficult).
  5. System Variables

    1. The following BB4W System Variables are not available in BBCSDL: @haccel%, @hcsr%, @hmdi%, @hwacc%, @midi%, @prthdc%.

    2. The following new System Variables are available in BBCSDL:
      @panx% (pans the screen in the horizontal direction)
      @pany% (pans the screen in the vertical direction)
      @zoom% (zooms/scales the output, &8000 corresponds to 1:1)
      @platform% (contains the SDL version number and, in the LS byte, a platform identifier:
      0: Windows, 1: Linux, 2: MacOS, 3: Android, 4: iOS, 5: in-browser; bit 6 set indicates a 64-bit platform)
      

    3. Because of the multi-threaded nature of BBCSDL, System Variables may not reflect the current state unless a 'thread synchronisation' is first performed. This is most easily (and quickly) achieved by reading the POS or VPOS value:
      IF POS REM. SDL thread sync
      REM. System Variables may now be read safely
      

    4. BBCSDL does not (by default) 'capture' the mouse, because on some platforms that can have an undesirable effect on other running applications. As a result coordinates returned by the MOUSE statement or the ON MOUSE interrupt are constrained to remain within the BBCSDL window. You can call the SDL_CaptureMouse API from your own program but you should be careful to note the remarks there. You might also want to consider calling SDL_GetGlobalMouseState instead.
  6. Libraries

    1. The following BB4W libraries are not available in BBCSDL: CALLBACK, COMLIB, HQSOUND (not needed), MDILIB, SORTSALIB, SPRITELIB, SUBCLASS, WINLIB*.

    2. The following BB4W libraries have close equivalents in BBCSDL: D3D*LIB (ogllib is almost 100% compatible), GDIPLIB (aagfxlib is very similar), IMGLIB, MODE7LIB, MULTIWIN, SOCKLIB, TIMERLIB. The correct libraries for the platform concerned must be used.

    3. The following new libraries are available in BBCSDL:
      audiolib.bbc (supports playing music and sound effects)
      dlglib.bbc (provides a 'dialogue box' functionality loosely similar to WINLIB2 and WINLIB5)
      editbox.bbc (extends the dialogue box functionality to include a multi-line edit control)
      filedlg.bbc (provides a 'file selector' loosely similar to Windows' GetOpenFileName API)
      gfxlib.bbc (supports high-performance 2D graphics suitable for games, similar to GFXLIB2)
      gpiolib.bbc (provides access to the General Purpose Input/Output of the Raspberry Pi)
      menulib.bbc (supports a menu bar with drop-down menus, and popup / context menus)
      msgbox.bbc (provides a 'message box' functionality, similar to Windows' MessageBox API)
      

    4. Note that BBCSDL libraries have lowercase filenames and must be specified accordingly in the INSTALL statement.
  7. SYS Statement

    1. In BB4W the SYS statement accesses the Windows API, in BBCSDL the SYS statement accesses the SDL 2.0 API. They are necessarily very different, although there will often be near-equivalent functions available.

    2. In some cases API differences have been encapsulated in libraries, for example D3DLIB (BB4W) and OGLLIB (BBCSDL) are substantially compatible, although the underlying APIs are totally different. Similarly for EVENTLIB, IMGLIB, MODE7LIB, MULTIWIN, SOCKLIB and TIMERLIB.
  8. CPU Differences

    1. The Android, iOS and Raspberry Pi editions of BBCSDL run on an ARM processor (currently 32-bit in the case of Android and Raspberry Pi, and 64-bit in the case of iOS). The Android and Raspberry Pi editions contain an ARM assembler; it does not currently support floating-point or NEON (SIMD) instructions. The iOS edition has no assembler, because Apple do not permit 'arbitrary code execution'.

    2. The ARM CPU does not support the 80-bit (long double) floating-point data type. Therefore 'suffixless' (variant) variables have only a 64-bit precision when running on an ARM CPU compared with the usual 80-bit precision when running on an x86 CPU (both BB4W and BBCSDL).
  9. 64-bit Differences

    1. 64-bit editions of BBCSDL (only the MacOS, iOS and 64-bit Linux & PiOS editions at the time of writing) require that your BASIC program be compatible with 64-bit addresses. This means using 64-bit integer variables (%% suffix) or variant variables (no suffix) whenever they may contain an address or handle.

    2. 64-bit addresses may be obtained from DIM (when used to allocate memory), from the PAGE, TOP, LOMEM, END and HIMEM pseudo-variables, from the address-of operator (^), as the address of a structure (e.g. struct{}), as the address of a string or array (using the PTR() function), as a label in the assembler or as the returned value from a SYS statement.

    3. 64-bit addresses may need to be passed to the indirection operators ($, ?, !, | and ]), to the *SAVE, *LOAD and *MDISPLAY commands (*HEX 64 will be necessary), to the PTR()= statement, as parameters of the SYS statement or as the entry point of a CALL statement or USR function.

    4. The system variables @chrmap%, @fn%(), @hfile%(), @hwnd%, @memhdc% and @vdu% may all return 64-bit values, despite them having only a single % suffix!

    5. The layout of API structures is very likely to be different between 32-bits and 64-bits (members may be a different size, and padding rules may cause other members to move).

    6. When using the assembler, the 64-bit program counter is Q%:P% (most-significant 32 bits in Q%, least-significant in P%) and the 64-bit limit (to detect a memory overrun while assembling) is similarly M%:L%. So you can do (for one-pass assembly):
      DIM ]^P% codesize, ]^L% -1
      [OPT 10
      
      If you are setting bit 2 of OPT, to store the code in memory at an address other than where it will be executed, the 64-bit code origin is M%:O% (note that it shares the MS 32 bits with the limit):
      DIM ]^O% codesize, ]^L% -1
      REM Set Q%:P% to wanted program counter
      [OPT 14
      

    7. When a 64-bit address is returned from SYS, you will probably need to discard the upper 32-bits when running on a 32-bit system otherwise there may be garbage there. This can be achieved as follows:
      SYS "function", parameters TO result%%
      IF @platform% AND &40 ELSE result%% = !^result%%
      

    8. When 64-bit (double) floating-point values are passed as parameters to SYS they must be passed differently on 64-bit platforms. When running in 32-bits they need to be passed as two 32-bit values (LS and MS), but when running in 64-bits they must be passed as a single parameter, with special precautions in the event of the value being zero. Typically one would do this as follows:
      IF @platform% AND &40 THEN
        IF float#=0 THEN ?(^float#+7)=&80
        SYS "function", float# TO result%
      ELSE
        SYS "function", !^float#, !(^float#+4) TO result%
      ENDIF
      

    9. Integer parameters passed in a SYS statement must really be integers; if necessary use the INT() function.

    10. Some interpreter internal variables are moved or absent in the 64-bit editions, notably !336 (pointer to temporary buffer), !368 (temporary storage for ON ERROR LOCAL), !424 (pointer to *KEY storage), !432 (pointer to event queue) and !440 (pointer to user-defined characters). These make way for 64-bit pointers ]332 (pointer to string accumulator), ]364 (pointer to error string), ]420 (pointer to path/filename buffer), ]428 (pointer to keyboard queue) and ]436 (pointer to current *KEY expansion).


Home - Products - Contact us

Best viewed with Any Browser Valid HTML 4.0!
© Richard Russell 2022