Dopo alcune settimane di duro lavoro sono finalmente riuscito a far funzionare il mio LM80C come un home computer ad 8 bit dei tempi d’oro. Può stampare sullo schermo, muovere il cursore e scorrere lo schermo quando scrivo. Sembra proprio un computer degli anni ’80.
Ma come ci sono riuscito? Con un po’ di codice…
L’ultima volta che ho pubblicato quando avevo scritto dei miei test con gli sprite. Ho provato a muovere qualche sprite a giro per lo schermo con qualche riga di BSIC. E’ stato divertente ma ho dovuto digitare i comandi sul terminale e vedere gli effetti sullo schermo TV. Volevo qualcosa di più. Volevo scrivere e vedere cosa digitavo direttamente sullo schermo, come in un vero home computer degli anni ’80. Il limite che avevo era l’interprete BASIC che stavo usando: era stato sviluppato per lavorare su un terminale di computer. Un terminale di computer è una macchina che riceve dei comandi da una postazione remota, di solito composta da uno schermo e una tastiera (il “terminale”). Questo tipo di sistema era molto comune negli anni ’70 dello scorso secolo perché permetteva ad un computer centrale di essere condiviso tra innumerevelo terminali dove gli utenti scrivevano il loro codice e ricevevano i loro dati. I personal computer hanno fatto la loro prima apparizione durante la seconda metà degli anni ’70: un utente poteva avere a casa sua un computer completo per le proprie necessità, e per questo erano spesso chiamati anche “home computer”. Un home computer veniva collegato ad un TV ed i programmi potevano essere inseriti attraverso la tastiera integrata: il testo appariva direttamente sullo schermo e così anche l’output della macchina. Non serviva un monitor dedicato. Ma il BASIC di NASCOM che sto usando sul mio LM80C fu adattato per lavorare su un terminale di computer. Perciò esso riceve l’input da una linea seriale e invia dati sullo stesso canale di comunicazione. Non si può fare una maschera a video con testo e caratteri semi-grafici, ad esempio, perché non si può posizionare il cursore o leggere i caratteri già stampati in qualche locazione. Perciò ho pensato ad un metodo che potesse essere adattato all’interprete. Il modo più semplice che ho trovato è stato aggiungere del codice alla routine che re-invia come un’eco i caratteri al computer remoto: infatti, tutti i caratteri che vengono ricevuti dal computer remoto e che devono essere rispediti ad esso oppure che sono inviati al sistema remoto dall’interprete passano sempre attraverso un buffer seriale da cui una routine li preleva uno alla volta. Ogni volta che c’è un carattere che deve essere spedito al computer remoto esso viene prelevato e spedito allo Z80 SIO: la mia modifica semplicemente prende questo carattere e lo stampa anche a video. Sembra facile ma non lo è. Dato che il TMS9918A non supporta in HW il “cursore” (la posizione dove il prossimo carattere verrà stampato sullo schermo), ho anche dovuto scrivere altre porzioni di codice per tenere traccia di uno speciale carattere che ho suato come cursore. Un altro problema è stato lo scorrimento: quando il cursore raggiunge l’ultima cella in basso a destra dello schermo e l’utente scrive un altro carattere lo schermo deve scorrere di una riga verso l’alto. Lo stesso se viene premuto il tasto ENTER ed il cursore è all’ultima riga. Risolti questi problemi ho anche aggiunto alcuni aiuti. Dato che mentre stavo digitando un listato potevo commettere un errore, ho aggiunto il supporto per il “backspacw”: quando premo questo tasto il cursore si sposterà indietro a sinistra di una posizione cancellando il carattere precedente. Infine, adesso possiamo cancellare l’intero schermo inserendo il comando “CLS” (CLear Screen). Ecco un breve video di queste aggiunte in azione:
Il codice è sul mio repository Github. Con quest’ultima modifica ho iniziato a suddividere il codice del firmware in diversi moduli per tenere separate le porzioni che sono diverse e per raggruppare in un unico file le routine di una specifica cosa. In questo modo posso modificare un modulo e riusarlo in future versioni del firmware senza la necessità di fare gli stessi cambiamenti ogni volta che sviluppo una nuova versione del firmware.