Language interpreter for uC-based systems
Some OpenSource/DIY software projects, containing legacy C code have been rewritten into C++. There is no any reasons to stay on C if C++ available on target platform. It has everything that C has and many "free" features, which cost 0 extra bytes and 0 extra instructions.
But I think Terminal-BASIC must go through a reverse transformation. I'm rewriting core components in pure C.
The 8-bit AVR microcontrollers were primary target at the project starting point. G++ supports this architecture, as well as 32-bit ARM versions of Arduino DUE, etc.
But many interesting architextures do not support C++. I think about running Terminal-BASIC on Z80 with SDCC, PIC uCs and... SEGA Genesis consoles (MC68000 has G++ port, but the popular SDK SGEN does not support C++).
Terminal-BASIC 1.2rc1 finally acquires an important feature of one-line user defined functions with arbitrary number of arguments.
This is a short example:
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|