# Commodore BASIC

Il Commodore BASIC (nelle prime versioni PET BASIC) è il dialetto del linguaggio BASIC usato nella linea a 8 bit degli home computer della Commodore International, a partire dal PET del 1977 fino al C128 del 1985.
Il suo nucleo era basato sul Microsoft BASIC adattato per il processore MOS 6502. Date le sue origini, condivideva gran parte del codice con altri BASIC per 6502 del periodo, come l'Applesoft BASIC.

## Storia

Bill Gates offrì inizialmente una licenza basata sul pagamento di una royalty di 3 dollari per ogni installazione del suo interprete ma Jack Tramiel, il capo di Commodore, rifiutò la proposta con la frase "Sono già sposato", e proponendo un accordo sulla base di un esborso unico di 25.000 dollari per una licenza perpetua ed illimitata (circolano differenti versioni sull'importo pagato, che oscilla a seconda delle fonti tra 10.000 e 30.000 dollari). Microsoft era allora una società ancora piccola ed alla ricerca perpetua di fondi, per cui Gates accettò la proposta e concesse a Commodore l'utilizzo del suo Microsoft BASIC con la licenza senza royalty; parallelamente come la Apple era riuscita ad ottenere una licenza perpetua senza ulteriori royalties per l'Applesoft BASIC.

## Caratteristiche
### L'interprete dei comandi ed il controllo degli errori

L'interprete BASIC residente in ROM e del KERNAL era una buona implementazione dell'editor a tutto schermo, che permetteva agli utenti di inserire e modificare comandi diretti o righe di programma ovunque sullo schermo — semplicemente premendo il tasto RETURN ogni volta che il cursore si trovava su una riga contenente una istruzione BASIC valida. Ciò segnava un enorme passo avanti nelle interfacce di inserimento programmi in confronto ai BASIC presenti sugli home computer dell'epoca, che in genere utilizzavano degli editor di riga, richiamati da comandi EDIT o similari.
Il BASIC del C64 implementa anche un sistema di controllo degli errori che però non sempre risultava efficace, che permetteva di controllare la correttezza del caricamento in memoria dei programmi da nastro tramite datassette. Questo avveniva esclusivamente con i salvataggi effettuati normalmente senza utilizzare programmi turbo: il programma tramite il comando "SAVE" veniva salvato due volte consecutivamente e, durante la fase di lettura del programma e in maniera totalmente invisibile all'utente, venivano lette entrambe le registrazioni e successivamente confrontate tra loro. Se le due copie non corrispondevano tra di loro veniva generato il "LOAD ERROR". Era inoltre possibile l'uso di loader/saver alternativi a quelli del sistema operativo, che permettevano dei caricamenti e salvataggi su cassetta più veloci. Un particolare segnale identificava l'inizio di un blocco dati (generalmente, un programma), e per poterlo trovare l'utente era generalmente costretto a scorrere lentamente la cassetta avviandola col tasto "Play".

### Velocità nell'esecuzione

Era tuttavia estremamente lento in confronto al linguaggio macchina. Test hanno dimostrato che per copiare 16 kilobyte di memoria dalla ROM alla RAM ci vuole meno di un secondo in linguaggio macchina, ma più di 2 minuti in BASIC. Per cercare di far fronte alla lentezza dell'interprete, i programmatori cominciarono ad usare vari trucchi per velocizzare l'esecuzione. Uno era quello di memorizzare valori interi usati frequentemente all'interno di variabili piuttosto che usarli direttamente, dal momento che interpretare il nome di una variabile portava via meno tempo rispetto all'estrapolazione del numero dal listato sorgente. Nonostante le righe di codice fossero numerate, l'ordine di esecuzione delle stesse non seguiva l'ordine numerico ma piuttosto l'ordine con cui erano immagazzinate in memoria. All'atto dell'inserimento del codice, le righe venivano automaticamente riordinate per seguire l'ordine numerico, ma andando a modificare (tramite le istruzioni POKE) la memoria in cui veniva memorizzato il programma, si poteva rovinare la numerazione, ribaltandola o anche dando la stessa numerazione a tutte le righe, senza che ciò interferisse con l'esecuzione del programma (a parte le istruzioni di salto, come ad esempio GOSUB, che necessitano di un numero riga come parametro). La stessa caratteristica, comunque, poteva essere usata per rinumerare le righe di programma, in modo da far spazio a nuove istruzioni, nel caso si fosse utilizzato un incremento unitario tra una riga e l'altra non lasciando spazio per ulteriori linee di codice.

### I token

I token del Commodore BASIC potevano essere abbreviati inserendo la prima lettera (oppure le prime nel caso di token simili), seguite da una lettera shiftata, ottenuta premendo contemporaneamente al tasto della lettera il tasto "SHIFT" (la lettera shiftata appariva sotto forma di un simbolo grafico). Il token abbreviato era riconosciuto allo stesso modo di quello completo; così si poteva immettere un numero maggiore di comandi nella linea Basic (il buffer di input accettava al massimo 88 caratteri). Una volta concluso l'input mediante Return, ogni token della linea Basic veniva quindi automaticamente convertito in un codice di un solo byte e così salvato in memoria. Il comando LIST provvedeva a fare rivedere i token, convertendo al volo i codici da 1 byte con i token. Il formato numerico nativo del Commodore BASIC, così come nel caso del suo progenitore Microsoft BASIC, era la virgola mobile. Tutte le operazioni aritmetiche venivano eseguite usando numeri in questo formato; le operazioni tra interi implicavano la conversione degli operandi avanti e indietro dal formato a virgola mobile. Molte implementazioni di BASIC del periodo usavano 1 byte per l'esponente e 3 per la mantissa. Questo causava problemi nelle applicazioni gestionali in quanto l'accuratezza della virgola mobile con 3 byte di mantissa è di circa 6,5 cifre decimali, e gli errori di arrotondamento erano comuni. Commodore, invece, optò per una mantissa di 4 byte, che rese il suo BASIC molto più preciso, e quindi più adatto al mondo degli affari rispetto a molti altri BASIC del periodo.

### Le variabili

I nomi delle variabili erano limitati a due caratteri di lunghezza: i caratteri che eccedevano questo limite venivano ignorati. Questo significa che i nomi "AREA" ed "ARENA" si riferivano alla stessa variabile "AR". Era disponibile tuttavia la funzione di individuazione automatica delle parole chiave del linguaggio senza bisogno di spazi che separano i vari elementi grammaticali. Ad esempio è possibile scrivere
Usando gli spazi si otterrebbe invece:
Questa caratteristica, pur rendendo il codice meno leggibile, permette di risparmiare la (poca) memoria a disposizione a quei tempi (la RAM necessaria per memorizzare gli spazi).
Nonostante riduca la leggibilità, questa caratteristica può rendere il codice ambiguo per il sistema:
contiene diverse "combinazioni" di token validi (alcune semanticamente significative ed altre no):
tuttavia, l'individuazione dei token da parte del sistema riconoscerà un'unica forma, la prima nell'esempio precedente, perché vengono individuati tutti i token presenti nell'ordine della scrittura: IF, TAN, THEN e STOP (ST è una variabile riservata, ma non ha un token ed è gestita dalla routine di gestione delle variabili come un'eccezione).

## Estensioni

* Super Expander (VIC-20, cartuccia) (prodotto da Commodore)
* Simons' BASIC (C64, cartuccia) (prodotto da Commodore)
* Super Expander 64 (C64, cartuccia) (prodotto da Commodore)
* Graphics BASIC (C64, floppy disk) (Hesware)
* BASIC 8.0 (C128, floppy disk o Special Function ROM) (WalrusSoft)

## Cronologia delle versioni
### BASIC 1.0

Implementato nel PET 2001
* bug: array limitati a 256 elementi
* bug: il comando PEEK falliva per locazioni di memoria superiori a $C000

### BASIC 2.0

Utilizzato nel PET 2001 con una tastiera e ROM aggiornate, nel VIC-20 e nel C64
* corretti la maggior parte degli errori della 1.0
* Easter egg del PET – inserire WAIT 6502,1

### BASIC 4.0

Implementato nel PET/CBM 4000/8000 (e ultime versioni del PET 2001)
* nuove operazioni su floppy disk: DLOAD,DSAVE,COPY,SCRATCH, etc (15 in tutto)
* variabili di stato per gli errori su disco: DS,DS$

### BASIC 4+

Utilizzato nel CBM-II (Modelli B e P).
* aggiunti i comandi DCLEAR,BANK,BLOAD,BSAVE,DISPOSE. Questi comandi verranno poi implementati tutti sul C128 (successore della serie CBM-II che fu un disastro e venne ritirata quasi subito dal mercato) tranne DISPOSE in quanto non più necessario a causa di una diversa gestione dello stack. I token dei comandi sono però diversi tra CBM-II e C128 limitando la portabilità binaria dei sorgenti.

### BASIC 3.5

Utilizzato sul C16/116 e sul Plus/4
* comandi grafici e sonori: GRAPHIC, CIRCLE, PAINT, DRAW, BOX, SOUND, VOL, etc.
* gestione porta joystick: JOY
* conversione esadecimale: DEC,HEX$
* lettura flessibile dati DATA: RESTORE [numeroriga]
* funzione di ricerca stringhe: INSTR
* formattazione della stampa: PRINT USING,PUDEF
* supporto all'esecuzione codice per condizioni (IF) che risultano false: ELSE
* cicli strutturati: DO,LOOP,WHILE,UNTIL,EXIT
* assegnazione funzioni ai tasti funzione: KEY (anche modalità diretta)
* inserimento/editazione programmi: AUTO,DELETE,RENUMBER
* gestione dinamica degli errori: TRAP,RESUME,ERR$
* istruzioni di debug (tracing): TRON,TROFF
* Monitor di sistema: MONITOR
* Easter egg sul C(1)16 e Plus/4 – SYS 52650

### BASIC 7.0

Adoperato nel C128
* ulteriori comandi grafici e sonori, inclusa la gestione degli sprite
* gestione paddle e penna ottica: POT,PEN
* funzione di or esclusivo: XOR
* recupero indirizzo delle variabili: POINTER
* gestione finestre in modalità testo: WINDOW
* istruzione di attesa temporizzata: SLEEP
* gestione della memoria: BANK,SWAP,FETCH,STASH
* ulteriori operazioni su disco: BOOT,BLOAD,BSAVE,DVERIFY,DCLEAR
* regolazione della velocità della CPU: FAST,SLOW (2 e 1 MHz rispettivamente)
* comando non documentato: RREG (legge i registri della CPU dopo l'esecuzione di un comando SYS)
* comandi non documentati e non funzionanti: OFF,QUIT
* Easter egg su C128 – SYS 32800,123,45,6

### BASIC 10

Versione progettata per il Commodore 65, ma che non venne mai pubblicata. Tra le caratteristiche vi erano:
* comandi grafici e video: PALETTE,GENLOCK
* gestione mouse: MOUSE,RMOUSE
* gestione file testuali sequenziali: TYPE
* editazione programmi: FIND,CHANGE
* gestione della memoria: DMA, FRE(0|1|2)
* comandi non implementati: PAINT,LOCATE,SCALE,WIDTH,SET,VIEWPORT PASTE,CUT