PicoBB implements a version of BBC BASIC on the Raspberry Pi Pico family. It is derived (with permission) from Richard Russell's BBCSDL. It should be noted that PicoBB is not an emulation of the BBC Micro, it is a native implementation of the BBC BASIC language on the ARM cores of the RP2040 or RP2350 chips.
Richard has produced extensive documentation for BBC BASIC as implemented by BBCSDL. No attempt is made to replace or reproduce that documentation. Instead this document attempts to sumerise how BBC BASIC on the Pico differs from that implemented by BBCSDL on other platforms.
Perhaps the biggest difference between PicoBB and BBCSDL is that the Pico is a much smaller and less powerful processer than anything else used to run BBCSDL. As a consequence there is much less memory available for the BASIC program, and the program will be significantly slower than on other versions of BBCSDL.
There are two major versions of PicoBB with rather different properties:
Either of these major versions may be on boards with or without a CYW43 wirless chip. The CYW43 introduces the possibility of providing wireless networking. The builds which include network support have slightly less memory available to BASIC. It is possible to run either a with or without networking build on either a board with or without the CYW43 chip, although clearly networking will only actually work if the CYW43 is presentW.
As well as the four build options resulting from Console / GUI and with / without networking there a a number of compilation options to enable or disable features giving a large number of potentially different builds. For build instructions see the README.md file in the repository. This documentaition mostly assumes using one of the four major builds.
Programming the PicoBB console builds requires a connection from a host computer. This may be over USB, in which case the Pico appears on the host as a USB serial port. Alternately a 3.3v serial UART connection may be used, in which case the Pico transmits on pin 1 (GPIO 0) and receives on pin 2 (GPIO 1). It is important that an RS232 or 5v serial connection is NOT used, as the higher voltages will damage the Pico.
A terminal emulator program should be used to connect to the serial port. The connection should be configured as:
If the host computer is running Linux, then picocom is the recommended terminal emulator.
If a Raspberry Pi is used as host computer (and perhaps other Linux machines) the device name
of the Pico USB serial port can be variable (/dev/ttyACM0
, /dev/ttyACM1
,
etc.). To resolve this a
UDEV rule may be
used to give a fixed device name (/dev/pico
) to the Pico.
The simplest way to use the GUI builds is with a Pico or Pico W mounted on a VGA Demonstration Board.
Normally when you start BBCSDL on Microsoft Windows, Apple IOS or Linux, you are not interacting directly with the BASIC interpreter, but instead you are using an Integrated Development Environment (IDE) to edit and run your programs. This IDE is itself written in BBC BASIC and runs automatically when you start BBCSDL.
The IDE program is far too large to run on a Pico, and it also relies upon GUI features provided by the host operating system. Thus none of section 2 of the BBCSDL documentation which describes the IDE is applicable.
If entering a program directly on the Pico it is necessary to use line numbers to order the lines making up a program. Lines are deleted by entering just the line number with nothing following. To correct a line, enter the new (corrected) line with the same line number as the line to be replaced.
Alternately the program can be created in a text editior off the Pico then either use the upload capability of the Console version to upload the file, or copy it onto a FAT formatted SD card for the GUI version of PicoBB. In this case the program does not require line numbers, the order is determined by the position of the line in the file. A BBC BASIC program yupload.bas to run on a host computer has been provided which will automatically upload a program from the host to a Pico and run it.
The default builds of PicoBB use the upper half of the Pico's flash memory (1MB) to provide storage for programs and data which is retained when power is removed. The filesystem supports folders and long file names, although the maximum path length is restricted to 260 characters. A forward slash (/) is used as the path seperator. The standard BBC BASIC commands are used to access the files. Storeage in the flash is implemented using littlefs.
A program named /autorun.bbc will be run automatically when the Pico is started.
Additional storeage may be provided by an SD card reader attached to some of the Pico GPIO pins (this is default for the GUI builds). SD and SDHC cards are supported and the first FAT partition on the card is used. The contents of the SD card will appear under the folder /sdcard/.
If both flash and SD card storage are implemented, then a program stored on the SD card will not auto-run by default. However a one line /autorun.bbc on the flash storage could CHAIN to /sdcard/autorun.bbc (or another file name).
The low byte (bits 0-7) of the system variable @platform%
identifies the
system on which a program is running. For any of the Pico builds this will have the
value 6. Bits 12-15 of @platform%
identify the processor:
Bits 8-11 of @platform%
specify the support for the CYW43 network chip:
The same information can be obtained using SYS to call the C function is_pico_w
.
The standard builds nominally for the Pico actually have Pico W GPIO support as that will also run on a Pico, and does not change the amount of RAM available to BASIC. As a result they have a value of 2 in the second byte. The standard Pico W builds have network support using background processing and therefore have a value of 4 in the second byte.
The Pico build also supplies a new (read only) system variable @picocfg&()
which
provides more details of the specific configuration:
@picocfg&(0)
- User interface:@picocfg&(1)
- File systems:@picocfg&(2)
- Sound implementation:@picocfg&(3)
- Number of serial devices:/dev/uart
).dev/uart0
, /dev/uart1
)./dev/serial
), used by VDU printer commands.@picocfg&(4)
- Processor and CYW43 support:This may be extended in the future if more capabilities are added.
All the other system variables from BBCSDL should exist although some of them are meaningless on the Pico.
The GUI builds support almost all of the graphics capability of BBC BASIC. The graphics modes supported are restricted by the amount of memory available on the Pico. The following 16 modes are supported:
Mode | Colours | Text | Graphics | Letterbox |
---|---|---|---|---|
0 | 2 | 80 x 32 | 640 x 256 | Y |
1 | 4 | 40 x 32 | 320 x 256 | Y |
2 | 16 | 20 x 32 | 160 x 256 | Y |
3 | 2 | 80 x 25 | 640 x 225 | |
4 | 2 | 40 x 32 | 320 x 256 | Y |
5 | 4 | 20 x 32 | 160 x 256 | Y |
6 | 2 | 40 x 25 | 320 x 225 | |
7 | 8 | 40 x 25 | Teletext | |
8 | 2 | 80 x 30 | 640 x 480 | |
9 | 4 | 40 x 30 | 320 x 480 | |
10 | 16 | 20 x 30 | 160 x 480 | |
11 | 2 | 80 x 25 | 640 x 450 | |
12 | 2 | 40 x 30 | 320 x 480 | |
13 | 4 | 20 x 30 | 160 x 480 | |
14 | 2 | 40 x 25 | 320 x 450 | |
15 | 16 | 40 x 30 | 320 x 240 |
Modes 0-7 reproduce those from the BBC Micro:
The generally most useful modes are mode 8, which is a monochrome display with the highest resolution, and mode 15, which is a 16 colour mode with square pixels. The default mode on startup is mode 8.
The Pico display is paletted, with the number of colours displayed at any one time limitted by the graphics mode. The VGA output generated by PicoBB uses five bits for each of red, green and blue, giving 32k possible physical colours. These are all available if using the Pimoroni VGA demonstration board. Custom boards may choose not to connect some of the colour lsb in order to provide some available GPIO pins. This will reduce the number of physical colours available.
A screen capture facility is provided. Pressing the prtscrxx.bmp
where xx goes from 01 to 99. The number is reset to 01 if the Pico is restarted or more than 99
captures are made. Existing captures are overwritten without warning. For reasons of file size
the captures are stored in the sdcard/
folder if that exists, otherwise they are
stored in the top folder.
To be consistent with other BBCSDL console builds, PicoBB console builds define the following ten modes:
Mode | Colours | Text |
---|---|---|
0 | 2 | 80 x 32 |
1 | 4 | 40 x 32 |
2 | 16 | 20 x 32 |
3 | 16 | 80 x 25 |
4 | 2 | 40 x 32 |
5 | 4 | 20 x 32 |
6 | 16 | 40 x 25 |
7 | 8 | 40 x 25 |
8 | 16 | 80 x 32 |
9 | 16 | 40 x 32 |
In general, PicoBB console builds do not support graphical output. Issuing graphics drawing commands from a program running in console mode will not produce an error, they just do not produce any output. However commands that attempt to interrogate the screen will generally fail.
There are three exceptions:
There is a compilation option to support the Waveshare Pico-ResTouch-LCD-3.5 display board. This board is designed to take a Raspberry Pi Pico or Pico 2, and provides:
The board does not have an independent power input, so unless the hardware is modified, power has to be supplied via the Pico USB connector. Thus a typical build will be with a USB console, with the LCD screen forming a second dispay, rather than having a keyboard attached to form a stand-alone computer.
The LCD display supports the following modes:
Mode | Colours | Text | Graphics | Letterbox | Landscape |
---|---|---|---|---|---|
0 | 2 | 40 x 32 | 320 x 256 | Y | N |
1 | 4 | 40 x 32 | 320 x 256 | Y | N |
2 | 16 | 20 x 32 | 160 x 256 | Y | N |
3 | 2 | 40 x 25 | 320 x 225 | N | |
4 | 2 | 40 x 32 | 320 x 256 | Y | N |
5 | 4 | 20 x 32 | 160 x 256 | Y | N |
6 | 2 | 40 x 25 | 320 x 225 | N | |
7 | 8 | 40 x 25 | Teletext | N | |
8 | 2 | 40 x 30 | 320 x 480 | N | |
9 | 4 | 40 x 30 | 320 x 480 | N | |
10 | 16 | 20 x 30 | 160 x 480 | N | |
11 | 2 | 40 x 25 | 320 x 450 | N | |
12 | 2 | 40 x 30 | 320 x 480 | N | |
13 | 4 | 20 x 30 | 160 x 480 | N | |
14 | 2 | 40 x 25 | 320 x 450 | N | |
15 | 16 | 40 x 30 | 320 x 240 | N | |
16 | 2 | 60 x 20 | 480 x 320 | Y | Y |
17 | 4 | 60 x 20 | 480 x 320 | Y | Y |
18 | 16 | 30 x 20 | 240 x 320 | Y | Y |
19 | 2 | 60 x 40 | 480 x 320 | Y | |
20 | 4 | 60 x 40 | 480 x 320 | Y | Y |
21 | 16 | 30 x 40 | 240 x 320 | Y | Y |
Modes 0-15 are for the LCD display in portrait orientation, and are as close as possible to those for the VGA display given the limitation of half the number of horizontal pixels.
Modes 0-7 approximate those from the BBC Micro:
Modes 17-21 are for the display in landscape orientation.
The generally most useful modes are mode 9, which is a four colour display with the highest resolution, and mode 17, which the corrisponding mode in landscape orientation. The default mode on startup is mode 9.
The Pico display is paletted, with the number of colours displayed at any one time limited by the graphics mode. The LCD output generated by the Waveshare board uses five bits for red and blue, and six bits for green, giving 64k possible physical colours. The COLOUR command can be used to map any of the possible colours onto the palette.
The touchpad on this board is supported by the MOUSE and ON MOUSE commands. Before using the touchpad, it should be calibrated using the tp_setup program. The calibration is stored in the file /mouse.cfg. This calibration will automatically be used whenever the /mouse.cfg file is present. If it is absent, then a very approximate default configuration will be used.
The console builds usually use the second ARM core on the Pico to produce high quality sound, equivalent to that produced by BBCSDL on other platforrms. The GUI builds, however, use the second ARM core for video generation. As a consequence a simpler sound generation is used which emulates the sound chip in the original BBC micro.
All sound implementations use the BBC BASIC SOUND and ENVELOPE commands. *STEREO and *VOICE are also implemented for high quality (SDL) sound.
For the console builds it will be necessary to attach low-pass filters to the sound output pins (pins 32 & 34, GPIOs 27 & 28) and then connect the output from these to an amplifier.
For the GUI builds, the VGA demo board includes the necessary post-processing, and an amplifier (or high impedance headphones) can be connected directly to the output sockets.
Depending upon the build used, serial devices may appear as as single /dev/uart
or the pair /dev/uart0
and /dev/uart1
. A serial port may be opened
using a command of the form:
port% = OPENUP("/dev/uart.baud=9600 parity=N data=8 stop=1 tx=0 rx=1 cts=2 rts=3")
Any of the pin numbers (tx, rx, cts, rts) may be omitted in which case that pin will not be connected. This enables transmit only, or receive only connections, and connections without flow control. The pin numbers selected must be valid Pico pin numbers for the relevent UART and function.
If not specified, the following defaults are assumed: parity=N data=8 stop=1.
The baud rate must be specified.
If keyword=value format is used then the parameters may be given in any order. Alternately the keyword and equals sign may be omitted in which case the parameters must be in the order shown above.
Note: Contrary to the BBC Basic documentation commas must not be used between the parameters.
If the BBC Basic user interface is connected via USB, then either serial interface may be used.
If the user interface is connected via a serial connection, then do not open that interface
(/dev/uart0
for a bare Pico, /dev/uart1
for a Pico on VGA Demo board).
The WiFi network is accessed using a Pico specific version of the BBC BASIC "socklib" library. See the BBC BASIC manual for details. This library is included in the filesystem images for the network builds.
The first time the library is used you will be prompted for the WiFi details (SSID, password and two letter country code). These will then be stored in the file "wifi.cfg" for subsequent use. To change the access point used, delete this file.
The filesystem images also include four example programs:
sudo apt install tftp
.It is generally not practical to directly use the LWIP network routines provided by the Pico C SDK as these rely heavily on callbacks into user supplied C (or assembler) routines. Therefore some higher level routines have been written in C to provide the functions needed to implement "socklib". If required, these routines may be accessed directly using SYS. They are documented in the file "include/network.h".
The original implementation of the network code utilised a large static allocation of a memory pool for network buffers, which substantially reduced the memory available to BASIC for the Pico W build, even if networking is not used (the static memory pool is the default for the pico-sdk when using background CYW43 network support). Following a discussion with Richard Russel, this has been revised. Calling PROC_initsockets reserves space for the network buffers by moving HIMEM down. Providing that nothing else changes HIMEM, this space is reclaimed when PROC_exitsockets is called.
There is a built-in assembler for the ARM v6M instruction set as supported by the Pico. By default the assembler uses "Unified" syntax. However including the following pseudo-op
syntax d
enables the following extensions to the allowed syntax:
The extensions may be disabled again by specifying:
syntax u
Almost all of the BASIC keywords documented in section 5 of BBC BASIC for SDL 2.0 are implemented as described. The following sections outline the differences.
The Pico has a 12-bit analogue to digital converter with a five input multiplexer. This can be read using the BASIC ADVAL function with positive arguments. The returned value is an integer in the range 0 to 4095, representing voltages in the range 0v to 3.3v. ADVAL can return the following values:
ADVAL(5) | Voltage on the Pico internal temperature sensor. |
ADVAL(4) | Voltage on GPIO 29 (not routed on Pico). |
ADVAL(3) | Voltage on GPIO 28 (pin 34 on Pico). |
ADVAL(2) | Voltage on GPIO 27 (pin 32 on Pico). |
ADVAL(1) | Voltage on GPIO 26 (pin 31 on Pico). |
ADVAL(-1) | Number of bytes free in the keyboard buffer. |
ADVAL(-5) | Number of bytes free in the channel 0 sound queue. |
ADVAL(-6) | Number of bytes free in the channel 1 sound queue. |
ADVAL(-7) | Number of bytes free in the channel 2 sound queue. |
ADVAL(-8) | Number of bytes free in the channel 3 sound queue. |
The reading of the internal temperature sensor (in Centigrade) may be approximated by:
Temperature = 27 - (3.3 * ADVAL(5) / 4096 - 0.706) / 0.001721
If calling a machine code routine from BASIC using the CALL statement:
Other uses are as documented.
Using GET or GET$ to attempt to return the character at a screen location will fail on console builds with the message "Sorry, GETXY not implemented".
For all versions of PicoBB, INKEY (or INKEY$) with a zero or positive argument works as documented. INKEY(-256) returns 115 (ASCII code for lower case "s").
Console versions of PicoBB will return zero for other negative arguments. For the GUI versions, INKEY works as documented for negative values corresponding to keyboard keys. Mouse support is not implemented, so testing for mouse button status will always return zero.
For a build with LCD plus Touchpad the command MOUSE x,y,b
will give the
current touch position, if any. If the panel is being touched, then b will be
1 and x and y will give the touch position in graphics units. If
not being touched then b will be 0 and x and y will be -1.
Before using the touchpad, it should be calibrated by running the program tp_setup.
For builds without a touchpad a command of the form MOUSE x,y,b
will create
the specified variables, all with value zero.
For builds with a touchpad this event will be triggered each time the pad is first touched. For other builds this event will never be triggered.
The events trapped by these statements will never occur in PicoBB.
With GUI builds, plotting modes 0 to 167 and 192 to 199 are implemented. Modes 168 to 191 and 200 to 255 will result in an error. It should be noted that the flood fill algorithm used in PicoBB ( "Space-efficient Region Filling in Raster Graphics", Dominik Henrich) to limit stack usage is different to that used in BBCSDL. It will have different results in some cases. In particular the fill will never cross a boundary that is already the fill colour.
These commands will fail with an error message on console builds. On GUI builds they work as documented and (unlike BBCSDL) they are fast.
This command causes the Pico to restart.
The Pico does not support DLLs. Instead a compiled in list of functions are supported. The list consists of most of the functions in the Pico C SDK (currently excluding the Bluetoot functions) plus those functions from the C runtime library which are used by the PicoBB program itself. If building PicoBB from source, the list of supported functions can be found in "build/sympico.h".
If calling a machine code routine from BASIC using the USR statement:
Other uses are as documented.
The command behaves as documented. See ??? for how the VDU sequences are interpreted.
On console builds attempting to obtain the width of a string will fail with an error message. On GUI builds it will work as documented, but since there is only a single, fixed pitch font, the result is always eight times the number of characters in the string.
The Pico has no operating system, so there are no star commands other than those explicitly implemented and documented.
The following BBCSDL star commands are not implemented on the Pico:
*display *ega *font *gsave *hardcopy |
*margins *mdisplay *noega *osk *play |
*printer *printerfont *screensave *sys |
The following star commands differ from BBCSDL or are unique to PicoBB:
Only for builds with an LCD panel, controls the brightness of the backlight. Values between 0 and 100 may be selected.
Only a limited implementation of this command is provided. A bitmap file can be loaded to
fill the entire screen. The size and bit depth of the file must match the currently selected
graphics mode. The easiest way to assure that is to use *screensave
to create
the file.
Only FLOAT 40
or FLOAT 64
are supported.
This command only accepts valid channel numbers 1 to 12, or zero to revert to normal input. The "special" values 13 to 15 used by BBCSDL for "non-overlapped I/O" will cause an error.
These commands don't do anything. The Little File System used for storage in Pico flash memory does not have any file attributes for recording Read-Only or Read-Write status. It would be possible to implement the functions for the FAT filesystem on an external SD card, but that would be inconsistent.
This command works as documented for valid channel numbers 1 to 12, or zero to restore normal output.
The "special" values 13 to 15 used by BBCSDL for "non-overlapped I/O" will usually cause an error. However for console builds which also have VGA output (not a standard build):
*output 0
- directs output to the console host computer.*output 14
- directs output to the VGA display.*output 15
- directs output to both the host computer and VGA display.In order to draw graphics on the VGA display *output 14 or 15 must be selected so that the graphics VDU sequences are processed by the VGA driver.
In addition, all console builds support:
*output 32
- send VT100 escape sequences to the host computer (this is the default).*output 48
- Send BBC BASIC VDU sequences to the host computer.Although this command is implemented, there is no operation system, and so it always results in "Bad command".
Only a limited implementation of this command is provided. Saves the entire screen to the specified file name. An extension of ".bmp" is assumed if not specified.
Note that four-colour modes will create a BMP file with a 2-bit colour depth. While this is a legal BMP format, many graphics utilities do not support it.
Receive an uploaded file using XModem protocol. The name of the file must be specified, as it is not sent by the upload program. Note that the length of the file will be padded out to the next multiple of 128 bytes.
Receive an uploaded file using YModem protocol. The filename is optional, but if given will override the name sent by the upload program. If a directory name (ending in '/') is given, the uploaded file will be placed in that directory. The exact file length will be preserved.
As for *yupload
but using ZModem protocol.
Download a file using XModem protocol. It will be necessary to specify a filename at the receiving end. Note that the length of the file will be padded out to the next multiple of 128 bytes.
Download a file using YModem protocol. The exact file length is transferred and the name of the file is supplied to the download program.
As for *ydownload
but using ZModem protocol.
The following table sumerises differences from BBCSDL in handling VDU command sequences:
VDU command | Console Build | GUI Build |
---|---|---|
1 | Ignored. | Implemented if printer enabled. |
2 | Sends an enable printer escape sequence. | Implemented if printer enabled. |
3 | Sends a disable printer escape sequence. | Implemented if printer enabled. |
4 | Ignored. | Implemented. |
5 | Ignored. | Implemented. |
7 | Sends a bell code. | Implemented. |
16 | Ignored. | Implemented. |
17 | Ignored. | Implemented. |
23 | Implements the following sub-codes: 1 - Cursor on / off. 16 - Line wrap on / off. 22 - User defined mode. |
Implements the following sub-codes: 0 - Cursor start and end line. 1 - Cursor on / off. 16 - Line wrap on / off. 32+ - User defined characters (see note below). |
24 | Ignored. | Implemented. |
25 | Ignored. | Implements sub-codes 0 to 167 and 192 to 199. |
28 | Ignored. | Implemented. |
29 | Ignored. | Implemented. |
The standard GUI builds do not support a printer, but there exists a compilation option to enable a printer on a serial port. If using a Pimoroni demonstration board using this requires soldering in the "SD card jumper" pins, and cutting the tracks linking GPIO 20 & 21 to SDD1 & SDD2.
The command VDU 23,...
may be used to define user character shapes. The following points should be
noted: