Language interpreter for uC-based systems
This example uses 2 arduino DUE as h/w platform for TB.
First arduino board with SD card reader (host) runs TB with 64kb available BASIC memory.
Second one makes VGA output using modified DUE VGA library, implementing part of the ANSI terminal control protocol and custom graphics binary protocol.
It suffers from minor bugs and incompatabilities, but Terminal-BASIC TETRIS from SD card runs much more acceptable.
I'v implement the ON .. GOTO control structure and fixed FOR .. LOOP details, and Terminal-BASIC made one more step towards the ANSI Minimal BASIC standart.
BTW last features allow to run many old games from "BASIC Computer games":
If the hardware platform supports multiple UARTs, like Atmega 1284/128/2560, terminal-basic can function as simple time-sharing system.
It doesn't use any OS, even FreeRTOS. The main interpreting context object is designed as finite state machine instead, which state-chart looks like this:
The FSM has very short step method and main loop executes many interpreters in order, thus implementing primitive non-preemptive Round-Robin scheduling algorithm.
This time-sharing mode can be enabled by the BASIC_MULTITERMINAL option in the config_arduino.hpp or config_linux.hpp, depending on the version, being built.
Terminal-BASIC 1.1 (link) has working implementation of this mode.
It seems Terminal-BASIC is ready to be used on Arduino DUE with SPI SD Card interface.
I'v decided to write a short HOWTO about that.
I use an Arduino DUE compatible board with SPI SD module and old 128M SD card:
2.1 Let's download last version of Terminal-BASIC sketch and libraries from sorceforge.
Go to "Files" page, select latest version and download the archive. Now I'am using https://sourceforge.net/projects/terminal-basic/files/r1.1/r1.1rc1/terminal-basic-1.1-rc1-937-arduino-sketch.tar.gz/download.
2.2 Unpack the archive. We'll have some folders: terminal-basic-<VERSION> is a main project sketch directory, others are libraries. FOr now only libsdcard needs to be installed. It is slightly modified version of standard SD library. I removed the dependency of heap management functions. On 8-bit AVR this helps to save reasonable amount of flash. Let's copy libsdcard/SDCard to ~/Arduino/libraries.
THen open sketch in Arduino IDE, select Arduino DUE Programming port board.
Select "config.hpp" file. It contains a list of condition compilation flags of different terminal-basic features. To enable option set it's value to 1, to disable - define as 0.
Default options set is targeted against small 8-bit boards and on DUE we can enable some extra abilities.
I will enable next options:
USE_MATRIX (Darthmouth BASIC-like matrix operations)
SET_PRINTZNES (On ANSI compatible terminals it will set print zones width)
USESD (SD card commands)
Option USE_SAVE_LOAD (SAVE, LOAD CHAIN commands which use internal EEPROM on 8-bit AVR's) should be disabled on Arduino DUE.
On ARduino DUE default BASIC memory size is 65535 bytes (it must be less then 65536). This size can be set in file "config_arduino.hpp" under the "__SAM3X8E__" ifdef branch.
Compile and program the board. After some warnings it should takeoff.
2.4 SD Card preparation.
Here you can download ANSI minimal BASIC test programs and some others.
Copy *.BAS files in root directory under FAT16/32 formatted card.
Insert card and plug the board to PC using Programming port. Connect terminal emulator program, using 115200 baudrate, disable local echo and local line editing - terminal-basic do it for us.
The terminal shopuld look like this upon success:
Let's test it.
Type in a simple program:
10 FOR I%=1 TO 9 : FOR J%=1 TO 9 20 PRINT I%;J%;I%*J% 30 NEXT J%:NEXT I% 40 END
Input LIST to see it's source and RUN to test. Program can be saved using DSAVE "filename w/o extension" and loaded by DLOAD "filename w/o extension". SD contents list printed on DIRECTORY command. DCHAIN "filename w/o extendion" loads new program, saving old variables.
Terminal-BASIC solved a little challenge of DATA/READ/RESTORE commands.
The MAT READ <name> construct from Darthmouth BASIC is also implemented.
Terminal-BASIC becomes stable and functional enough to run the program like classic tetris game. It's quite compact and runnable not only on Arduino MEGA microcomputer but even on Single chip BASIC computer. But it simply is TOO slow!.. As shown on the videos below, SDL TVout emulation is ok, but on real device with TVoutEx output it's fail.
Arduino MEGA with 32 Kb shield:
Very disappointing. I will try output through the dedicated VDC, such as NGT20. After all, TVout library forms interrupt overloaded environment.
SDL-based emulator helps to debug non-interrupt and non-avr specific part of the TVoutEx library
My friend Dylan Brophy inspired me to investigate the ability to output the cyrillic text using different output devices, supported by Terminal-BASIC.
1. Using symbols others then capital latin in identifiers not possible and unnecessary.
2. USART output.
The job is done by the terminal or (terminal emulator) as long as you use a 1-byte cyrillic encoding (CP-866, KOI8-R, KOI8-U, Windows-1251 ...);
The character set either raster or vector should be extended. The memory resources in this case is main restriction. I think the encodings, which were mentioned above, are not suitable for this case because they define full cyrillic letters set for only 1-2 language and doubles the letters with same llok as latine ones. There was interesting encoding Код УПП (punch card device code) which was used on БЭСМ-6 mainframes, defines single latin-cyrillic charset. But it has only capital letters and was incompatible with ASCII.
So I decided to define the encoding, contains all cyrillic symbols without doubling the same-looking latin.
I gather cyrillic letters from 8 alphabets (6 modern and 2 dead). The second part of ASCII will be formed from symbols, differs from latin, with the order ascending by the "points" of this letter in the following rating. This will allow to reduce the number of supported symbols, cutting the tail of the table.
|Symbol||Early Cyrillic||Modern russian||Russian before 1917||Belorussian||Ukrainian||Serbian||Bulgarian||Macedonian||All|
One of the amazing features of the World's first BASIC implementation from the Dartmouth College
was the ability to manipulate arrays as matricies. The 1960's are going farther and farther, at the age of Scilab, Octave and other mature numerical computations packages who can be impressed by the matrix-able BASIC. But isn't it fun when small 8-bit uC board can do what mainframes from 1960's can?
Terminal-BASIC supports these matrix operations. Main difference is that Darthmouth BASIC ignores 0-row and 0-column, making array definition more informative. DIM(3,3) defines 4x4 array, but it was used as 3x3 matrix in matrix operations. Terminal-BASIC uses all rows and columns, so DIM(3,3) defines 4x4 array, which can be used as 4x4 matrix.