INTCODE and BCPL #
BCPL is a programming language designed in the 1960’s by Martin Richards at the University of Cambridge. The C programming language has its roots in B, which in turn was derived from BCPL. Being such a close relative of C, the BCPL language still has a familiar look and feel, half a century later.
INTRODUCTION #
The original (“classic”) BCPL system was implemented with a very simple 16-bit interpreter called INTCODE. Porting BCPL to another machine was a matter of adapting the INTCODE interpreter to run on the new hardware. An easy task, even for different word lengths, because INTCODE and BCPL were word-oriented: an int was whatever the machine supported.
I learned and used BCPL on a PDP-11 and on a CDC-6400 (“Cyber”). The language was a breath of fresh air for systems programming, after languages such as FORmula TRANslator. The BCPL compiler is itself written in BCPL, astonishingly small and simple, and portable - a nice illustration of what you gain when making language tools “self-hosted”.
Hardware #
For the hardware to run BCPL on, I am using a WeAct STM32F412 board (link), which has enough internal RAM to hold a 64 kiloword memory area - the maximum possible in a non-banked system with 16-bit word addressing.
There is a µSD card socket on the back and 512 KB of internal flash, enough to implement a variety of storage options.
SOFTWARE #
The software starts out simple: an INTCODE interpreter, implemented in C++ with
just character input and output over the serial port. To verify the basic setup,
a small BCPL test program has been pre-compiled and included as hello16.h
header with binary data in the source code:
GET "LIBHDR"
LET START() BE
$( LET A, B, C, SUM = 1, 2, 3, 0
SUM := A + B + C
WRITES("*NSum of 1 + 2 + 3 is ")
WRITEN(SUM)
WRITES("*NHello, World*N")
$)
Sample output:
hello: STM32F41x @ 100 MHz (v7.0.2-66-ge2b87b88)
Sum of 1 + 2 + 3 is 6
Hello, World
If you read “GET
” as “#include
” and “START()
” as “main()
”, you can see
the similarity with C …
Running natively #
The same code will also run on a “host” build of the interpreter (a 2020 MacBook Air in this case):
$ cd retro/host && make ic16
pio run -e ic16 -s && .pio/build/ic16/program
Sum of 1 + 2 + 3 is 6
Hello, World
$
Voilá … this is portability at the (interpreted) machine code level.