BBC BASIC on the Raspberry Pi Pico and Pico W

Contents

Introduction

PicoBB implements a version of BBC BASIC on the Raspberry Pi Pico and Pico W. 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 chip.

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:

Console Version
This version requires connecting to another computer for programming or any user interaction. The connection may be via a USB port, or may use a serial UART. Either way, a terminal emulator is used on the host computer. The terminal emulator should support VT100 escape codes. With a Linux host picocom is the recommended terminal emulator. One possible application of this version is to have a program that auto-runs without any user interface or host computer, and controls hardware or collects data using the Pico GPIO pins.
GUI Version
Ths version is stand-alone and uses a VGA monitor and a USB keyboard to provide a complete programming environment. It is designed for a Pico attached to a Pimoroni VGA Demonstration Board or similar board wired according to the outline given in Chapter 3 of Hardware design with RP2040. Its primary purpose is to provide a learning experience similar to that of the 8-bit computers of the 19980's. With a custom board design it is possible to free a few GPIO pins for interfacing by either not using the lsb of the video output or omitting either sound or SD card connections.

Either of these major versions may be on either a Pico or a Pico W. The latter 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 Pico or Pico W, although clearly networking will only actually work with a network enabled build on a Pico W.

As well as the four builds 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.

Connecting to the Pico

Console 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.

GUI Builds

The simplest way to use the GUI builds is with a Pico or Pico W mounted on a VGA Demonstration Board.

Program Entry and Editing

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 Picco and run it.

Program and Data Storage

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.

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/.

System Variables & System Identification

The low byte 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. If running on a standard Pico, the other three bytes will be zero. If running on a Pico W, the second byte (bits 8-15) will have one of the following values:

  1. - No Pico W support (LED on Pico W unaccesable).
  2. - Pico W GPIO support only (LED on Pico W accessible).
  3. - Pico W network support using polling.
  4. - Pico W network support using background processing.

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:

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.

Graphics

GUI Builds

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:

ModeColoursTextGraphicsLetterbox
0280 x 32640 x 256Y
1440 x 32320 x 256Y
21620 x 32160 x 256Y
3280 x 25640 x 225
4240 x 32320 x 256Y
5420 x 32160 x 256Y
6240 x 25320 x 225
7840 x 25Teletext
8280 x 30640 x 480
9440 x 30320 x 480
101620 x 30160 x 480
11280 x 25640 x 450
12240 x 30320 x 480
13420 x 30160 x 480
14240 x 25320 x 450
151640 x 30320 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 key will save a file 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.

Console Builds

To be consistent with other BBCSDL console builds, PicoBB console builds define the following ten modes:

ModeColoursText
0280 x 32
1440 x 32
21620 x 32
31680 x 25
4240 x 32
5420 x 32
61640 x 25
7840 x 25
81680 x 32
91640 x 32

In general, PiccoBB 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 two exceptions:

Sound

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.

Serial Input and Output

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).

Network

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 three example programs:

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".

Thumb Assembler

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

BASIC keywords

Almost all of the BASIC keywords documented in section 5 of BBC BASIC for SDL 2.0 are implemented as desccribed. The following sections outline the differences.

ADVAL

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

CALL

If calling a machine code routine from BASIC using the CALL statement:

Other uses are as documented.

GET(x,y) and GET$(x,y)

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".

INKEY and INKEY$

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.

MOUSE

PicoBB does not have a mouse interface. This command will not produce an error, but it will not have much effect either. A command of the form MOUSE x,y,b will create the specified variables, all with value zero.

ON MOUSE, ON MOVE and ON SYS

The events trapped by these statements will never occur in PicoBB.

PLOT

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.

POINT and TINT

These commands will fail with an error message on console builds. On GUI builds they work as documented and (unlike BBCSDL) they are fast.

QUIT

This command causes the Pico to restart.

SYS

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 whicch are used by the PicoBB program itself. If building PicoBB from source, the list of supported functions can be found in "build/sympico.h".

USR

If calling a machine code routine from BASIC using the USR statement:

Other uses are as documented.

VDU

The command behaves as doccumented. See ??? for how the VDU sequences are interpreted.

WIDTH

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.

Star Commands

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:

*display

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.

*float

Only FLOAT 40 or FLOAT 64 are supported.

*input

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.

*lock and *unlock

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 incconsistent.

*output

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):

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:

*run

Although this command is implemented, there is no operation system, and so it always results in "Bad command".

*screensave

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.

*xupload <filename>

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.

*yupload [<filename>|<dirname/>]

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.

*zupload [<filename>|<dirname/>]

As for *yupload but using ZModem protocol.

*xdownload <filename>

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.

*ydownload <filename>

Download a file using YModem protocol. The exact file length is transferred and the name of the file is supplied to the download program.

*zdownload <filename>

As for *ydownload but using ZModem protocol.

VDU commands

The following table sumerises differences from BBCSDL in handling VDU command sequences:

VDU commandConsole BuildGUI Build
1Ignored.Implemented if printer enabled.
2Sends an enable printer escape sequence.Implemented if printer enabled.
3Sends a disable printer escape sequence.Implemented if printer enabled.
4Ignored.Implemented.
5Ignored.Implemented.
7Sends a bell code.Implemented.
16Ignored.Implemented.
17Ignored.Implemented.
23Implements 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).
24Ignored.Implemented.
25Ignored.Implements sub-codes 0 to 167 and 192 to 199.
28Ignored.Implemented.
29Ignored.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: