ITALIA  
 
Commodore 64 vs. Sinclair Spectrum :: Linguaggio BASIC
 
 
 
Cos'è il BASIC?
BASIC è l'acronimo di Beginner's All-purpose Symbolic Instruction Code, un linguaggio sviluppato al Darthmouth College nel 1963 per fornire un linguaggio didattico agli studenti. Il BASIC [1] doveva essere un linguaggio semplice, facile da apprendere, essere di utilità generale, interattivo, veloce, espandibile dagli utenti più esperti. Il BASIC è forse più vicino al linguaggio macchina che ai linguaggi ad alto livello, con la sua struttura sequenziale, il massiccio uso di salti (GOTO), l'accesso diretto alla memoria in lettura e scrittura (POKE, PEEK) il supporto ridotto di programmazione strutturata, funzioni e procedure (prevede solo subroutine tramite GOSUB e RETURN, e le variabili sono di norma sempre globali). Per questo motivo il BASIC è stato più volte criticato, specie l'uso dell'istruzione GOTO, come fuorviante nell'apprendimento della programmazione ad alto livello. Nonostante ciò il BASIC conobbe un incredibile successo nei piccoli computer, differenziandosi in un sterminata serie di dialetti (tanto che ogni macchina ne aveva la sua brava implementazione), perché rappresentava una pratica e semplice interfaccia tra l'utente e la macchina. Oggi il BASIC si è evoluto in un vero e proprio linguaggio strutturato dove non sono più neppure previsti i classici numeri di linea e poco rimane dello spirito originario.
 
T. Kurtz e J.Kemeny
ideatori del BASIC
 
I bug
Nessun programma complesso è perfetto ed esente da errori ed essendo gli interpreti BASIC e le routine in ROM essi stessi dei programmi non fanno eccezione. Nel Commodore 64 sono noti un paio di bug che mandano in crash l'interprete. Il primo si può verificare digitando la riga PRINT 0 + "" +- 0 mentre, per il secondo, digitando 35072121 dal prompt si ottiene un comportamento anomalo. Non che queste due linee abbiano molto senso ma mostrano come strani bug possano annidarsi anche nel software di base di una macchina. Le ROM dello Spectrum tuttavia, costituiscono un caso a parte. Esse erano note per presentare una serie di piccoli problemi, non sempre tutti fixati con le revisioni successive [9]. E' il risultato di una corsa contro il tempo per il rilascio e di eventi interno alla Sinclair che determinarono un frettoloso debugging e l'uscita dello Spectrum con il sistema operativo non completato (la parte mancante è quella che troverà posto nella Interface 1). Esempi di tali bug sono riportati in questa tabella. Ci sono molti altri piccoli bug che affliggono le ROM dello Spectrum anche se alcuni sono poco significativi. Questi bug riguardano non solo l'interprete BASIC ma anche alcune delle routine nella ROM del computer ed anche in quella della Interface 1.

Il Sinclair BASIC

Il Sinclair BASIC è un dialetto BASIC che caratterizza tutte le macchine prodotte dalla casa inglese, fino dallo ZX80, inizialmente basato sullo standard minimo ANSI X3.60-1978. Lo sviluppo delle varie versione del Sinclair Basic venne curata dai programmatori della Nine Tiles, segnatamente John Grant e Steven Vickers, espandendo il nucleo della versione originaria con l'arrivo di ogni nuova macchina. All'uscita dello Spectrum il Sinclair Basic era stato notevolmente ampliato ed includeva un buon numero di istruzioni tra cui comandi per la gestione diretta della grafica, manipolazione del testo e degli attributi, emissione del beep, gestione delle stringhe che lo rendevano assai versatile rispetto a molti concorrenti del 1982. Peculiare delle macchine Sinclair erano l'editor e la modalità di immissione dei comandi. Il Sinclair Basic si adatta bene al principiante, svolgendo una buona funzione didattica. Curiosamente, la versione implementata nello Spectrum è incompleta. La parte dei comandi relativi all'I/O e gestione dei microdrive è contenuta in una ROM esterna fornita con l'Interface 1.

Il CBM BASIC 2.0

Il Commodore 64 dispone del BASIC 2.0 su ROM. Si tratta del linguaggio originariamente sviluppato dalla Microsoft per i PET serie 2001 e 3000 e adattato per il Commodore 64. E' un BASIC compatto e veloce ma una delle principali critiche che gli vengono mosse è la sostanziale scarsità di comandi. Sembra che all'epoca la Commodore disponesse già del BASIC 4.0 ma che optasse per il vecchio 2.0 per timore che il C64 finisse per competere nella fascia business riservata agli elaboratori CBM serie 4000 e 8000, assai più costosi. Un'altro possibile motivo è che la macchina richiedesse una ROM più grande, aumentando i costi. Il BASIC 4.0 fu in seguito reso disponibile per il C64 come add-on software. Il 2.0 contiene tutti i principali comandi e feature per realizzare programmi di calcolo e gestionali ma manca quasi completamente di comandi dedicati a sfruttare tutto l'hardware della macchina. In particolare mancano comandi avanzati per la gestione dei dischi, comandi per la grafica e comandi per il sonoro. Alla grafica e al sonoro si accede scrivendo direttamente in memoria mediante POKE.

Schermata di avvio dello Spectrum
Schermata di avvio del Commodore 64

Caratteristiche a confronto

Dal punto di vista del numero dei comandi e della versatilità di programmazione, il Sinclair Basic è sicuramente superiore. Sebbene la maggior parte dei comandi dello Spectrum trovino una corrispondenza nei comandi o nei caratteri di controllo del C64 (si pensi all' INVERSE realizzato semplicemente con CTRL-9) il gruppo di comandi per disegnare linee, cerchi, effetti sul testo ecc... permettono al principiante di sperimentare fin da subito con tali caratteristiche. Questi comandi sono principalmente POINT, BRIGHT, CIRCLE, DRAW, PLOT, OVER, BEEP, FLASH, ATTR. Un'altra peculiarità che distingue i dui BASIC è l'editor. In verità l'editor dello Spectrum è tipico della famiglia dei computer Sinclair. L'idea che ben pochi dei suoi acquirenti sarebbero stati dei dattilografi, l'impostazione didattica della macchina e non ultime le soluzioni adottate per la tastiera, indussero la Sinclair ad implementare un editor non standard dove ogni comando appare con la semplice pressione di un singolo tasto e viene implementato un controllo della sintassi al volo. Sebbene da un lato ciò possa facilitare l'introduzione dei comandi, nasconde una serie di svantaggi che hanno fatto si che nessun altro produttore abbia adottato questo approccio. Non è possibile infatti digitare normalmente un comando, ad esempio se non ci ricordiamo con quale tasto farlo apparire, poiché questo non verrebbe riconosciuto. Ciò comporta la necessità di un periodo di "addestramento" per sviluppare un ottimo feeling con la tastiera in modo da associare instintivamente le keyword al tasto da premere, salvo poi ritrovarsi spaesati quando ci si sposta su una qualsiasi altra piattaforma. Il tutto è peggiorato dal fatto che nello Spectrum i tasti sono solo 47 e ad ognuno possono corrispondere anche fino a 4 tra keyword e simboli del BASIC, con un continuo uso degli shift e passaggi da una modalità all'altra tra quelle disponibili (nominate a seconda del cursore K,L,E,C,G). Ad esempio per ottenere CIRCLE INK 2;20,20,10 Bisogna battere la sequenza CAPS SHIFT+SYMBOL SHIFT , SYMBOL SHIFT+H , CAPS SHIFT+SYMBOL SHIFT , SYMBOL SHIFT+X , 2 , SYMBOL SHIFT+O , 20 , SYMBOL SHIFT+N , 20 , SYMBOL SHIFT+N , 10 Si può anche arrivare ad assurdi dove il numero di tasti da premere per ottenere il comando è maggiore del numero di caratteri del comando stesso. Il check della sintassi è sicuramente un bonus ma non un aspetto determinante. In tutti i BASIC infatti la segnalazione di errori a run-time riporta sempre la linea di occorrenza per cui il programmatore dovrà ricontrollare solamente tale linea. La Sinclair abbandonerà questo tipo di editor per uno più standard con lo Spectrum 128, prima macchina della ditta inglese (e forse non è un caso) ad avere una tastiera standard. L'editor del C64 è un editor standard, con piena libertà di movimento e di rieditazione delle linee BASIC al volo. L'area a disposizione del programmatore è di 40 colonne per 25 righe (rispetto alla 32x24 dello Spectrum) sulla quale si ha il pieno controllo del movimento tramite tasti cursore facilmente accessibili, clear, home ed insert. Il check della sintassi avviene al momento dell'esecuzione come sulla maggior parte dei BASIC. Nonostante la sua ricchezza, il Sinclair Basic soffre di alcuni gravi problemi derivanti da una scomoda eredità. Mentre nel passaggio dallo ZX80 allo ZX81 Vickers riscrisse buona parte del codice, pur cercando di mantenere la massima compatibilità con lo ZX80, e migliorò ampiamente il package matematico, nel passaggio dallo ZX81 allo Spectrum Sinclair impose che venisse conservata la maggior parte possibile del codice già realizzato per lo ZX81. Mentre i programmatori insistevano per riscrivere da zero le ROM, Sinclair era piuttosto deciso a dotare la macchina del maggior numero di feature con la minima spesa, e quindi toccando il meno possibile le ROM dello ZX81 [2]; non importava se poi queste si sarebbero rivelate inadatte alla struttura dello Spectrum [3] [4]. Ed infatti le ROM dello ZX81 che erano state progettate per una macchina con 1K di memoria si rivelarono completamente inadeguate al nuovo computer, che montava 48K di memoria, utilizzava strutture dati assai più grandi, forniva nuove capacità grafiche. In particolare il metodo di gestire le variabili che si era rivelato efficiente sui piccolo predecessori cominciò a mostrare i suoi limiti sullo Spectrum. Il risultato fu un computer dalla buone capacità castrato da un BASIC assai lento [5][6][7] tanto che tra i computer in voga all'epoca l'unica macchina più lenta era forse lo ZX81 in modalità SLOW [8]. In tabella vengono riportati alcuni esempi di comandi BASIC abbastanza comuni. Il ciclo base consta di 5000 iterazioni. Al suo interno viene di volta in volta eseguita una linea diversa. Oltre al tempo totale viene riportato anche l'overtime ovvero il tempo totale meno il tempo per l'esecuzione del ciclo per fornire una stima più attendibile della velocità dell'istruzione sotto esame, depurata dall'iterazione. In generale il C64 fornisce risultati migliori ed in diversi casi termina in circa metà tempo. Si noti che lo Z80 nello Spectrum è clockato a 3.54 MHz rispetto ai 2 MHz della versione originale. Il 6502 nel C64 ha un clock di 1 MHz.

Tempi di esecuzione di semplici comandi BASIC
Istruzioni
ZX Spectrum
Commodore 64
Ciclo base
22
+0
7
+0
PRINT AT 0,0;"ciao"
56
+34
24
+17
LET a=a+1
39
+17
22
+15
LET a$=STR$(i)
103
+81
52
+45
LET a(i)=i (1)
44
+22
25
+18
LET a$(i)="ciao" (2)
46
+24
25
+18
LET a=SIN(i)
250
+228
148
+141
LET a=PEEK i
39
+17
19
+12
GOSUB...RETURN (3)
37
+15
15
+8
GOTO (4)
33
+11
12
+5
IF a=i THEN STOP (5)
40
+18
19
+12
IF a<>i THEN REM (6)
41
+19
21
+14
         
(1) riempimento di un vettore di interi preventivamente dimensionato.
(2) riempimento di un vettore di stringhe preventivamente dimensionato.
(3) salto ad una linea esterna al ciclo e ritorno.
(4) salto ad una linea immediatamente successiva contenente una REM.

(5) la condizione non è mai verificata.

(6) la condizione è sempre verificata
   

La gestione di stringhe e numeri

Il BASIC standard, almeno nelle intenzioni dei suoi ideatori, dovrebbe gestire le stringhe in maniera dinamica. La gestione dinamica ha diversi vantaggi: è veloce, molto versatile e permette di risparmiare memoria in molte situazioni. Con questo approccio la lunghezza delle stringhe non è fissa. esse possono allargarsi e restringersi dinamicamente a seconda di ciò che viene loro assegnato, al prezzo di alcuni byte che servono ad indicare posizione ed occupazione di ogni singola stringa. Un semplice esempio è il dimensionamento di un array che dovrà contenere dati di diversa lunghezza, ad esempio nominativi di clienti o un vocabolario tematico, diciamo di 2000 parole. Appena dimensionato l'array occupa 6k, 3 bytes per ogni elemento, ma è completamente vuoto. La sua occupazione di memoria aumenterà solo in base a quanto lo riempiremo e come. Un stringa di 15 byte aumenterà l'occupazione di 15 byte esatti, una stringa di 3 la aumenterà di 3 e di tutti i campi vuoti non ci dovremo preoccupare. Se assegnamo una diversa parola ad una medesima stringa, la sua grandezza aumenterà o diminuirà di conseguenza, e così anche la memoria occupata. Può accadere che delle stringhe usate in precedenza diventino inutilizzate. Per velocizzare le operazioni il sistema non recupera immediatamente la memoria che ora si è liberata, ma lo fa automaticamente quando la memoria disponibile si esaurisce, richiamando un'apposita routine. Il processo va sotto il nome di garbage collection. La routine può anche essere chiamata direttamente dall'utente utilizzando la parola chiave FRE(). Lo svantaggio della gestione dinamica è dunque quello che ogni tanto può partire la FRE() a fare pulizia. Questa operazione tuttavia, se ben implementata, richiede solo pochi secondi ed è un piccolissimo prezzo da pagare in confronto ai vantaggi della gestione dinamica. Il Commodore 64 utilizza questa gestione, come la quasi totalità degli altri micro. Sfortunatamente nei basic di derivazione Microsoft per gli 8 bit, compreso il BASIC 2.0 del C64, questa routine è lentissima e può portare ad attese intollerabili. Nel Commodore BASIC 4.0, nel BASIC del C128 o nel COMAL invece ci sono routine fulminee che riordinano il pool delle stringhe in pochi secondi. Ci sono diversi modi per aggirare questo problema. Un buon programmatore non dovrebbe mai portare il sistema a saturarsi ed avere cura di eseguire la FRE() a tempo debito. Se si passa a programmare in assembler il problema non si presenta. Un'altro modo è quello di usare un compilatore BASIC. Una volta terminato il programma e fattolo compilare, il risultato è un eseguibile in linguaggio macchina, che quindi non soffre i problemi della FRE(). Infine si può sostituire la FRE() con una routine alternativa sfruttando le caratteristiche del C64. La routine può andare a sostituire direttamente la FRE() o accodarsi nello spezzone da 4K successivo all'interprete BASIC. Routine di questo tipo eseguivano il riordino dell'intera memoria BASIC in pochi secondi. Nello Spectrum la gestione delle strighe è portata avanti in maniera diversa. Infatti, nel dimensionamento di un array, in genere deve essere dichiarata la lunghezza degli elementi. Questo obbliga il programmatore a stabilire prima un limite alla lunghezza degli elementi. Alla sua creazione l'array viene riempito di spazi, per cui il vocabolario di cui prima, ipotizzando una lunghezza massima di parola di 15 lettere, occuperebbe 30K pur essendo completamente vuoto. Un'altro problema è che l'assegnamento delle stringhe è di tipo procrusteano, ovvero se gli elementi sono più corti della lunghezza dichiarata vengono allungati con degli spazi, se sono più lunghi vengono troncati. E se ad un certo punto c'è bisogno in un unico campo di 16 lettere invece che di 15 è necessario ridimensionare tutto l'array, aggiungendo un ulteriore byte ad ogni campo e sprecando così altri 2K. L'unico vantaggio di questa gestione è che non deve attendere che la FRE() faccia pulizia, ma, come abbiamo visto, una FRE() ben scritta impiega solo pochi secondi. Gli svantaggi di una gestione statica diventano quindi evidenti. Per quanto riguarda le gestione dei numeri, notiamo che sullo Spectrum tutte le operazioni vengono fatte su numeri reali. Il numero 1 ad esempio è in realtà rappresentato da 1.0000... Un'array di interi risulta essere in effetti un array di reali, con un conseguente spreco di memoria (i reali richiedono più byte per essere rappresentati). Nel C64 invece esiste anche il tipo intero per cui gli array di interi sono effettivamente tali e permettono di risparmiare memoria. Un vettore di 4000 interi ad esempio occupa sul C64 solo 8K contro 20K sullo Spectrum.

I BASIC extender

La popolarità degli home computer non tardò a far rendere disponibili per loro diversi altri linguaggi, oltre al BASIC fornito con la macchina. Molti di questi nuovi linguaggi erano essi stessi dei BASIC estesi. Essi miravano ad espandere le capacità dei calcolatori proponendo interpreti con nuovi comandi e funzioni, in grado di rimpiazzare gli interpreti in ROM o, caso più comune, di integrarsi con loro ed arricchirli. Sebbene tali programmi fossero disponibili un po' per tutti i computer, compreso lo Spectrum, è nel Commodore 64 che essi trovarono il filone più prolifico. Date le potenzialità e la popolarità della macchina, unitamente alle ristrettezze del BASIC 2.0 che faceva avvertire l'esigenza di un passo avanti, essi rappresentavano il naturale complemento per quegli utenti interessati ad avere un interprete più ricco che permettesse loro un più facile accesso alle risorse disponibili e superasse in maniera rapida ed indolore, semplicemente via software, i limiti dell'interprete su ROM. Il più famoso e diffuso era sicuramente il Simons' BASIC, che aggiungeva 114 nuovi comandi comprese istruzioni per disegnare punti, cerchi, linee, poligoni, comandi sonori, ausilii per la programmazione strutturata e quant'altro si poteva desiderare. Esso si integrava con l'interprete BASIC originale, mantenendo la compatibilità e lasciando disponibili 30K per permettere all'utente di sbizzarrirsi nella creazione dei propri programmi. Distribuito dalla stessa Commodore, il Simons' BASIC finì per rappresentare un po' lo standard tra tutti gli extender disponibili per il C64. Esso non fu tuttavia l'unico. La stessa Commodore rese disponibile il suo BASIC 4.0, ma anche Epyx, Abacus, Richvale ed altre compagnie misero in campo le loro proposte. Alcuni di questi tool erano veramente avanzati e finivano per far assomigliare il BASIC a ben altri linguaggi. Grazie alla sua struttura, alla possibilità di scaricare, modificare o espandere le ROM il C64 ben si prestava a questi upgrade e senza eccessivi sacrifici. Spesso le tecniche per l'implementazione di comandi addizionali costituivano argomento di articoli e rubriche sulle riviste del settore e persino l'oggetto di programmi inviati dai lettori. Il problema del ridotto BASIC 2.0 veniva così elegantemente risolto, come già il problema del garbage collection, semplicemente in software, permettendo ad ogni utente che lo volesse di usufruire di un interprete più potente ed adatto alle sue esigenze selezionato tra un'ampia scelta. Nel 1985 La Whitby Computer giunse persino a rilasciare uno Spectrum Simulator che riproduceva sul Commodore 64 un perfetto ambiente BASIC Sinclair. Il programma simulava uno Spectrum con 20K di RAM, 6.5K di display file e la possibilità di eseguire tutti i programmi scritti per tale computer che non facessero uso di linguaggio macchina né accedessero alle locazioni interne (ovviamente). Implementava inoltre gli UDG (caratteri ridefinibili dall'utente), l'emulazione dei microdrive tramite il 1541 e l'accesso diretto al display file tramite istruzioni poke, oltre che con i ben noti comandi grafici. Per quanto potesse apparire incredibile questo programma non faceva altro che disattivare il BASIC residente e sostituirlo con una versione per C64 dell'interprete Sinclair, a testimonianza della versatilità della macchina.

Due schermate dello Spectrum Simulator della Whitby Computers
Anche per lo Spectrum vennero prodotti un certo numero di BASIC extender, anche se inizialmente l'esigenza era meno sentita. Alcuni erano prodotti di ottima fattura come ad esempio la serie dei Beta Basic, specialmente nella versione 3.0, che tuttavia occupava oltre 18K di memoria, ed era quindi inutilizzabile sullo Spectrum 16K mentre sul 48K finiva quasi per dimezzare la quantità di memoria disponibile, o l' YS Megabasic che soffriva dello stesso problema.

Riferimenti
[1] BASIC programming language, Wikipedia
[2] Intervista a John Grant, settembre 1985, in Sinclair and the Sunrise Technology, I.Adamson, R.Kennedy 1986
[3][5] The History of Sinclair Basic
[4] The Spectrum of Success, in Sinclair and the Sunrise Technology, I.Adamson, R.Kennedy 1986

[6] Computing Today, agosto 1982
[7][8] Electronics & Computer Monthly, dicembre 1982
[9] Bugs in the ROM