Successione di Fibonacci in Tiny BASIC

Ho appena aggiunto un nuovo programmino di esempio a TinyBASICBlazor, il mio ambiente web Tiny BASIC interattivo sperimentale: si tratta del classico calcolo della successione di Fibonacci.

Il programma è una versione semplificata (l’implementazione originale determina anche se gli elementi della successione siano numeri primi) e adattata per Tiny BASIC dell’esempio 4.18 del libro Programmare in BASIC (seconda edizione) di Byron S. Gottfried:

01  REM BASED ON EXAMPLE 4.18 FROM PROGRAMMING WITH BASIC BOOK BY BYRON S. GOTTFRIED
02  REM ADAPTED TO TINY BASIC BY MARCO'S RETROBITS
03  REM HTTPS://RETROBITS.ALTERVISTA.ORG    (ENGLISH)
04  REM HTTPS://SOMEBITSOFME.ALTERVISTA.ORG (ITALIAN)
05  REM HTTPS://RETROBITS.ITCH.IO
10  REM GENERATION OF FIBONACCI NUMBERS
20  PRINT "N= (3<=N<=23)";
30  INPUT N
35  IF N < 3 THEN GOTO 20
36  IF N > 23 THEN GOTO 20
40  PRINT
50  PRINT "GENERATION OF FIBONACCI NUMBERS"
60  PRINT
70  LET G=1
80  LET H=1
90  PRINT "I= ";1,"F= ";1
100 PRINT "I= ";2,"F= ";1
110 LET I=3
120   LET F=G+H
200   PRINT "I= ";I,"F= ";F
210   LET H=G
220   LET G=F
230 LET I=I+1
235 IF I<=N THEN GOTO 120
240 END

Nel listato è evidente l’assenza del ciclo FOR, sostituito da meno eleganti IF e GOTO. Inoltre, la serie generata è limitata a un massimo di 23 elementi a causa della precisione limitata (16 bit) del tipo di dato numerico in questa implementazione dell’interprete.

Riporto di seguito l’output della generazione dei primi 20 numeri di Fibonacci:

N= (3<=N<=23)? 20

GENERATION OF FIBONACCI NUMBERS

I= 1    F= 1
I= 2    F= 1
I= 3    F= 2
I= 4    F= 3
I= 5    F= 5
I= 6    F= 8
I= 7    F= 13
I= 8    F= 21
I= 9    F= 34
I= 10   F= 55
I= 11   F= 89
I= 12   F= 144
I= 13   F= 233
I= 14   F= 377
I= 15   F= 610
I= 16   F= 987
I= 17   F= 1597
I= 18   F= 2584
I= 19   F= 4181
I= 20   F= 6765
:

Ho deciso di aggiungere questo programma per puro sentimento nostalgico, in quanto mi ricorda con piacere le esercitazioni di informatica ai tempi della scuola, tanti anni fa.

Puoi eseguire il programma “Fibonacci” in TinyBASICBlazor semplicementa navigando a questo indirizzo: retrobits.altervista.org/tinybasicblazor?p=fibonacci.

Versione in Inglese di: Successione di Fibonacci in Tiny BASIC

Mele, pere e forza bruta in Tiny BASIC

Alcuni giorni fa, mi sono imbattuto in un post, pubblicato sul gruppo facebook dedicato al linguaggio di programmazione BASIC, in cui si fa riferimento a una challenge indetta sul forum della community di Liberty BASIC. L’obiettivo della sfida consiste nella realizzazione di un programma per risolvere il seguente “rompicapo” matematico:

C'è una cassetta di mele e pere.
Alcune sono grandi, altre piccole; alcune sono gialle, le altre sono verdi.
Non ci sono pere piccole né mele piccole e verdi.
Sono resi noti alcuni numeri: 25 mele, 17 pere, 32 frutti grandi, 28 gialli.
Ci sono due mele verdi in più rispetto alle pere verdi.
Trova il numero di mele grandi gialle.

Il problema è riconducibile a un sistema lineare di 5 equazioni in 5 incognite, per la cui risoluzione sono disponibili strumenti matematici ben noti (forse ne ho anche implementato qualcuno, quando ero studente), ma in questo caso ho deciso di divertirmi un po’ implementando in Tiny BASIC un algoritmo di forza bruta per verificare tutte le soluzioni teoricamente possibili, fino a che si trova quella effettivamente corretta. Il listato del programma è riportato di seguito:

1 REM ********************
2 REM * APPLES AND PEARS *
3 REM ********************
4 REM BRUTE FORCE TINYBASIC IMPLEMENTATION
5 REM BY MARCO'S RETROBITS
6 REM RETROBITS.ALTERVISTA.ORG
7 REM PLEASE TAKE A SEAT, THIS COULD BE SLOW
8 REM ********************
10 REM THERE WAS A BOX OF APPLES AND PEARS
11 REM SOME ARE BIG, SOME ARE SMALL;
12 REM SOME ARE YELLOW, REST ARE GREEN
13 REM THERE ARE NO SMALL PEARS
14 REM AND NO SMALL GREEN APPLES.
15 REM SOME NUMBERS ARE GIVEN:
16 REM 25 APPLES, 17 PEARS
17 REM 32 BIG FRUITS
18 REM 28 YELLOW ONES.
19 REM THERE ARE TWO MORE GREEN APPLES THAN GREEN PEARS.
20 REM FIND THE NUMBER OF BIG YELLOW APPLES.
30 REM C: SMALL YELLOW APPLES
40 REM D: BIG YELLOW APPLES
50 REM E: BIG GREEN APPLES
60 REM F: BIG YELLOW PEARS
70 REM G: BIG GREEN PEARS
80 REM A: APPLES; P: PEARS
90 REM B: BIG FRUITS; Y: YELLOW ONES
100 LET A = 25
110 LET P = 17
120 LET B = 32
130 LET Y = 28
200 REM FOR C = 1 TO A
201 LET C=1
210   REM FOR D = 1 TO A-C
211   LET D = 1
220     REM FOR E = 1 TO A-C-D
221     LET E = 1
230       REM FOR F = 1 TO P
231       LET F = 1
240         REM FOR G = 1 TO P-F
241         LET G = 1
250           GOSUB 2000
260           IF S = 0 THEN GOTO 460
270           PRINT "SOLVED!"
280           PRINT "SMALL YELLOW APPLES:", C
290           PRINT "BIG YELLOW APPLES:", D, "*"
300           PRINT "BIG GREEN APPLES:", E
310           PRINT "BIG YELLOW PEARS:", F
320           PRINT "BIG GREEN PEARS:", G
400           END
460         REM NEXT G
461         LET G = G+1
462         IF G <= P-F THEN GOTO 250
470       REM NEXT F
471       LET F = F+1
472       IF F <= P THEN GOTO 240
480     REM NEXT E
481     LET E = E+1
482     IF E <= A-C-D THEN GOTO 230 
490   REM NEXT D
491   LET D = D+1
492   IF D <= A-C THEN GOTO 220
500 REM NEXT C
501 LET C = C+1
502 IF C <= A THEN GOTO 210
510 PRINT "NO SOLUTION!"
520 END
1990 REM ** CHECK ROUTINE **
2000 LET S = 0
2001 REM PRINT C, D, E, F, G
2010 REM 25 APPLES, 17 PEARS
2020 IF C + D + E <> A THEN RETURN
2030 IF F + G <> P THEN RETURN
2040 REM 32 BIG FRUITS
2050 IF D + E + F + G <> B THEN RETURN
2060 REM 28 YELLOW ONES
2070 IF C + D + F <> Y THEN RETURN
2080 REM THERE ARE TWO MORE GREEN APPLES THAN GREEN PEARS
2090 IF E <> G + 2 THEN RETURN
2100 REM ** SOLVED! **
2110 LET S = 1
2990 RETURN

Ogni volta che ho a che fare con Tiny BASIC, inizialmente mi stupisco del fatto che questo dialetto non preveda i cicli FOR…NEXT. Questo in realtà non è un grosso problema, in quanto si può ovviare con le (meno eleganti) istruzioni di IF e GOTO. Un’altra limitazione è data dai nomi delle variabili, che possono essere costituiti da un’unica lettera maiuscola.

Ho eseguito il programma “Mele e Pere” su TinyBasicBlazor, l’ambiente TinyBASIC interattivo per web browser da me realizzato a partire da TinyBasic.NET e descritto in questo post. La soluzione ha richiesto più di mezz’ora (devo verificare il motivo), mentre con TinyBasic.NET in versione console, sono necessari pochi secondi.

Ah, quasi dimenticavo: ci sono 7 mele grandi e gialle!

SMALL YELLOW APPLES: 10
BIG YELLOW APPLES: 7 *
BIG GREEN APPLES: 8
BIG YELLOW PEARS: 11
BIG GREEN PEARS: 6
Read in English

Internet Explorer va in pensione

Come annunciato da Microsoft, lo scorso 15 giugno il web browser Internet Explorer (abbr. IE) è andato in pensione, cedendo il passo a Edge.

Internet Explorer 3/Windows 95
Internet Explorer 3 su Windows 95 (Emulatore Virtual x86)
Internet Explorer 5/Windows 98
Internet Explorer 5 su Windows 98 (Emulatore Virtual x86)
Internet Explore 8 su Windows Server 2008 R2
Internet Explore 8 su Windows Server 2008 R2
Internet Explorer 11 su Windows 10
Internet Explorer 11 su Windows 10
Internet Explorer è andato in pensione (fonte: Microsoft)

Nonostante il pensionamento, la presenza di Internet Explorer si farà ancora sentire. Per qualche tempo, infatti, sarà attiva in Edge la modalità Internet Explorer, che consentirà la corretta visualizzazione di siti e applicazioni legacy durante la fase di transizione. Moltissime organizzazioni, infatti, fino ad ora hanno richiesto come requisito imprescindibile il supporto a IE!

Abilitazione della modalità Internet Explorer in Microsoft Edge.
Il mio sito web rm-rf, aperto in Microsoft Edge utilizzando la modalità Internet Explorer.

Sebbene IE sia stato ultimamente oggetto di molti meme scherzosi, che ironizzano soprattutto sulla la sua lentezza nei confronti dei browser moderni, è innegabile che, nel bene e nel male, con esso finisca una parte della storia di Internet e del World Wide Web.

E: il browser più utilizzato... per scaricare gli altri browser!
IE: il browser più utilizzato… per scaricare gli altri browser! (fonte: web)
Cosa siamo? Browser!!! (fonte: web)
Internet Explorer non risponde (fonte: web)

Se da una parte IE ha vinto la prima guerra dei browser (Netscape fu annienteto), anche grazie alle politiche monopoliste di Microsoft, è anche vero che nei primi anni 2000 è stato praticamente l’unico strumento in grado di visualizzare qualsiasi sito web (soprattutto quelli non conformi agli standard), non solo su sistemi Windows. Ricordo che quando ero studente universitario, per poter consultare alcuni siti dovetti installare IE5 per Solaris/Sparc, suscitando l’indignazione dei puristi di Unix e occupando buona parte della mia quota disco disponibile! Infine, proprio grazie alla scelta da parte di Microsoft di includerlo nel sistema operativo Windows 95 e superiori, Internet Explorer ebbe il “merito” di traghettare nel web milioni di utenti nel mondo.

Forse, ora gli sviluppatori web frontend tireranno finalmente un sospiro di sollievo, in quanto non saranno più costretti a supportare un browser che, benché onnipresente, era ormai universalmente ritenuto obsoleto!

EVAS10N.RAS.DOT: il mio contributo alla DotJam

EVAS10N.RAS.DOT è un gioco estremamente semplice per Sinclair ZX Spectrum Next, simile a Breakout, realizzato per la DotJam utilizzando TRSE (Turbo Rascal Syntax Error).
Il file di progetto TRSE e il codice sorgente sono inclusi nell’archivio scaricabile sulla pagina del progetto.

Screenshot di EVAS10N.RAS.DOT.
Schermata di EVAS10N.RAS.DOT.

Nota importante: EVAS10N.RAS.DOT attualmente supporta solo la modalità video a 32 colonne!

TL; DR

Sono un utente Sinclair ZX Spectrum dal 1988 e un appassionato di ZX Spectrum Next da quando ne ho sentito parlare per la prima volta, nel 2017. Adoro i (retro)computer e soprattutto amo sviluppare applicazioni (principalmente videogiochi) per essi. Ho iniziato a programmare in BASIC da bambino e poi ho studiato Pascal , C , Java , C++ e C# , tra gli altri. Attualmente, il mio linguaggio di programmazione preferito per lo sviluppo retro è il C e la mia toolchain preferita è z88dk . Uno dei primi programmi che ho realizzato per ZX Spectrum Next è il comando more (precedentemente noto come readme), incluso nella distribuzione software ufficiale . Ho anche effettuato il port per ZX Spectrum Next di una semplice versione del programma scherzoso cowsay.

Cowsay in esecuzione su ZX Spectrum Next (emulatore ZEsarUX)
Dot command “Cowsay” in esecuzione su ZX Spectrum Next (emulatore ZEsarUX).

Nel 2019 ho realizzato BreakIn, un clone del gioco arcade Breakout, scritto in 20 righe di linguaggio BASIC per la Breakout Basic Challenge. L’anno successivo, ho scritto una versione ancora più piccola, chiamata Evas10n, per l’ edizione 2020 del BASIC 10Liner Contest.

Schermata di Evas10n (Basic 10 Liner).
Schermata di Evas10n (Basic 10 Liner).

Nell’aprile 2020, mi è stato finalmente consegnato il tanto atteso ZX Spectrum Next e ho immediatamente configurato l’ambiente CP/M e installato il compilatore Turbo Pascal 3.

Turbo Pascal (versione CP/M) in esecuzione su ZX Spectrum Next.
Turbo Pascal (versione CP/M) in esecuzione su ZX Spectrum Next (scusate per la pessima qualità dell’immagine).

Mi sono quindi divertito a riscrivere Evas10n in Pascal; il risultato è EVAS10N.PAS.

EVAS10N.PAS su ZX Spectrum Next
EVAS10N.PAS su ZX Spectrum Next emulato con #CSpect.

Recentemente, EVAS10N.PAS è stato migliorato e ottimizzato per CRISS CP/M, un interessante computer basato su microcontroller AVR e in grado di emulare la CPU Z80 e di eseguire il sistema operativo CP/M.

Video di Igor Reshetnikov che mostra la versione di EVAS10N.PAS modificata per CRISS CP/M.

Negli ultimi anni, ho sentito spesso parlare di TRSE (Turbo Rascal Syntax Error), una suite completa che include un moderno IDE e un cross-compiler Pascal e che supporta molti computer a 8 e 16 bit, basati su microprocessori come il MOS 6502, lo Zilog Z80, il Motorola 6800 o la linea X86. Penso che sia una suite eccellente e non vedevo l’ora di provarla!

Alcuni giorni fa è stata annunciata la DotJam. Lo scopo è provare a creare un gioco, una demo o un tool interessante sotto forma di file .dot. Pur desiderando partecipare alla DotJam, non sarei riuscito a trovare il tempo per ideare e realizzare qualcosa di nuovo. Poiché, tecnicamente parlando, qualsiasi file binario con estensione “.dot” e contenente fino a 8K di codice macchina che può essere eseguito dall’indirizzo $2000 (8192 in decimale) può essere un dot command e TRSE consente di specificare l’indirizzo di inizio del programma (menu Progetto => Impostazioni progetto = > scheda Target Settings), ho pensato di partecipare, convertendo EVAS10N.PAS da Turbo Pascal a TRSE, facendone un dot command!

Essendo il port di un programma per CP/M, EVAS10N.RAS.DOT non utilizza (ancora?) alcuna delle funzionalità di ZX Spectrum/Next, come colori, suono, grafica ad alta risoluzione, sprite, ecc… Sarebbe quindi interessante evolverlo per sfruttare appieno le capacità dello ZX Spectrum Next, magari mediante una unit dedicata (vedi file: next.tru).

Video di EVAS10N.RAS.DOT in azione.

Note di conversione

La conversione in TRSE non è stata così semplice e lineare come avrei inizialmente immaginato, a causa di alcune differenze tra TRSE e il dialetto Pascal che conosco, quindi annoterò alcune osservazioni. Per maggiori informazioni, potresti consultare la documentazione della sintassi TRSE .

Preciso inoltre che, avendo appena iniziato ad utilizzare TRSE, alcune delle mie ipotesi e considerazioni potrebbero essere sbagliate!

Cicli for

Il valore finale in un ciclo for non è incluso.

Quindi, ad esempio, questo ciclo:

for i := 0 to 10 do
begin
    txt::put_ch(48 + i);
end;

produce il seguente risultato: 0123456789 e questo ciclo:

for i := 2 to 5 do
begin
    txt::put_ch(48 + i);
end;

produce questo output: 234.

No array bidimensionali

Gli array di array non sono consentiti.

Quindi ho semplicemente sostituito:

var bricks: array[1..6] of array[1..32] of Boolean;
...
bricks[r, c] := true;

con:

var bricks: array[6*32] of Boolean;
...
bricks[(r * 32) + c] := True;

Condizioni annidate

Le condizioni annidate devono essere racchiuse tra parentesi, altrimenti accadranno cose terribili! si faccia riferimento alla sintassi TRSE per i dettagli.

Nomi di variabili locali

Il compilatore non consente lo stesso nome per più variabili, anche se il loro scope è diverso. Forse questo può essere risolto con il modificatore global… devo indagare ulteriormente!

Ecco un esempio in cui il compilatore segnalerà errori:

program Test;

function Square(val: Integer): Integer; // Fatal error: Variable 'val' is already defined! 
var newval: Integer; // Fatal error: variable 'newval' is already defined! 
begin
	newval := val * val;
	Square := newval;
end;

var  
	val, newval: Integer;

begin

	val := 5;
	newval := Square(val);

end.

Altre note

  • Prestare attenzione ai tipi di parametri di funzioni/procedure e alle variabili passate: passare un Integer dove è previsto un Byte o viceversa apparentemente può causare problemi.
  • Integer e Byte sono tipi senza segno!

Considerazioni finali

EVAS10N.RAS.DOT è stato realizzato in maniera spiccia, senza troppi test; pertanto il programma contiene sicuramente alcuni bug e può essere migliorato in molti modi.
Sono comunque felice di essermici dedicato, in quanto mi ha dato la possibilità di conoscere TRSE, un ottimo strumento di sviluppo!

Read in English

Lotus 1-2-3 in esecuzione su Linux (WSL)!

Negli ultimi giorni, il lavoro di Tavis Ormandy ha suscitato parecchio interesse nel mondo del retrocomputing. Lo sviluppatore è infatti riuscito ad effettuare il port della versione per UNIX System V di Lotus 1-2-3, rilasciata 32 anni fa, in modo da eseguirla nativamente su Linux, senza emulazione! Tutti gli aspetti di questa impresa sono dettagliati nell’ articolo redatto da Tavis stesso; l’autore ha anche reso disponibile il risultato del suo lavoro in un repository dedicato.

Per chi non lo conoscesse, Lotus 1-2-3 è un foglio elettronico che integra anche funzionalità di database e la possibilità di generare grafici. Sviluppato da Lotus a partire dal 1983, presto divenne lo standard de facto per questo genere di applicazioni in ambiente PC/DOS, per poi essere soppiantato da Microsoft Excel su Windows.

I manuali in Italiano della versione 2.4 di Lotus 1-2-3 per DOS
I manuali in Italiano della versione 2.4 di Lotus 1-2-3 per DOS

Ricordo con piacere di aver utilizzato Lotus 1-2-3 per DOS in ambito scolastico, alla fine delle medie e durante le superiori. In particolare, sebbene in modo un po’ improprio, lo adoperai come word processor per scrivere la tesina a tema scientifico dell’esame di terza media. Fino a qualche giorno fa ero ignaro dell’esistenza di una versione per UNIX. Proprio per questi motivi, ho accolto la notizia del port su Linux con entusiasmo e mi sono cimentato con la build. La procedura è ben descritta nel file readme del repository; tuttavia mi sono imbattuto in un paio di problemi, fortunatamente sormontabili abbastanza facilmente.

Avendo a disposizione un PC con Windows, ho deciso di eseguire la procedura di build sulla distribuzione Debian 10 che ho installato tempo fa in ambiente WSL (Windows Subsystem for Linux) 2 . Purtroppo, su questa distro la toolchain è piuttosto vecchia e non è stato possibile completare la build. Tavis mi ha gentilmente suggerito di provare con la versione testing di Debian oppure con Ubuntu; ho optato per quest’ultima opzione.

Lotus 1-2-3 su Linux (WSL): la procedura step-by-step

Utilizzando il prompt dei comandi di windows, ho installato la distribuzione Ubuntu attualmente disponibile in WSL (20.04 LTS Focal Fossa) col comando:

wsl --install -d Ubuntu

Dopo aver configurato user name e password ed effettuato il login, ho aggiornato il sistema con:

sudo apt-get update

In seguito, ho installato i prerequisiti con:

sudo apt-get install build-essential
sudo apt-get install gcc-multilib
sudo apt-get install lib32ncurses-dev

Ho poi scaricato il repository 123elf da GitHub:

git clone https://github.com/taviso/123elf.git

Sono quindi entrato nella directory del progetto e ho scaricato le immagini dei floppy disk di Lotus 1-2-3 per UNIX:

cd 123elf/
wget https://archive.org/download/123-unix/123UNIX1.IMG
wget https://archive.org/download/123-unix/123UNIX2.IMG
wget https://archive.org/download/123-unix/123UNIX3.IMG
wget https://archive.org/download/123-unix/123UNIX4.IMG
wget https://archive.org/download/123-unix/123UNIX5.IMG

A questo punto, ho provato ad eseguire lo script per installare il pacchetto binutils, ma la compilazione di quest’ultimo inizialmente non è andata a buon fine, in quanto manca makeinfo. Il problema si risolve installando texinfo:

sudo apt install texinfo

Dopodiché, è possibile scaricare e compilare il pacchetto binutils:

./binutils.sh

Occorre quindi copiare i tool objcopy, objdump e ld-new (nota: quest’ultimo deve essere rinominato in ld) appena compilati nella directory del progetto (corrente):

cp binutils-2.38/binutils/objcopy .
cp binutils-2.38/binutils/objdump .
cp binutils-2.38/ld/ld-new .
mv ld-new ld

Prima di poter lanciare la build, è necessario estrarre i file dalle immagini disco precedentemente scaricate:

./extract.sh

Finalmente, è possibile avviare la build:

make

Se tutto va per il verso giusto, sarà possibile avviare Lotus 1-2-3 con:

./123
Lotus 1-2-3 in esecuzione su Linux Ubuntu in WSL (Windows 10)
Lotus 1-2-3 in esecuzione su Linux Ubuntu in WSL (Windows 10)

Dato che per alcuni utenti risultava fastidioso, lo splash screen presentato all’avvio dell’applicazione è stato disabilitato di default. Per visualizzarlo, è possibile lanciare l’applicazione specificando il parametro “-b“:

./123 -b
La mia tesina dell'esame di terza media
La mia tesina dell’esame di terza media, recuperata da floppy disk da 5.25 pollici e caricata in Lotus 1-2-3 per UNIX.
Gli accenti si sono persi da qualche parte…
Read in English