1 Stella2 Stelle3 Stelle4 Stelle5 Stelle (No Ratings Yet)

Come simulare la “PRINT AT” sul C64 con il BASIC V2:

(articolo dell’utente Attilio Capuozzo)

Nessuna descrizione della foto disponibile.

Un modo veloce per muovere il Cursore in una specifica posizione dello schermo identificata da Riga e Colonna è il ricorso a una specifica Routine del KERNAL, il Sistema Operativo (SO) del C64, denominata PLOT.
Le Routine del KERNAL sono realizzate in Linguaggio Macchina (LM).
Per chiamare in modo sicuro la suddetta Routine di Sistema, la chiamata dovrebbe avvenire saltando a un entry point della cosiddetta JUMP TABLE che contiene a sua volta un JMP all’indirizzo effettivo della Routine richiamata; ogni entry point della JUMP TABLE occupa quindi 3 Byte tra l’Opcode del salto e l’indirizzo assoluto a 16 bit (=2 Byte=1 Word) della Routine richiamata.

Gli ultimi 8K ROM della Memoria del C64, da 57344/$E000 a 65535/$FFFF, ospitano il KERNAL.
La KERNAL JUMP TABLE occupa gli indirizzi che vanno da 65409/$FF81 a 65525/$FFF5.
La JUMP TABLE serviva a rendere le chiamate alle Routine di Sistema indipendenti da eventuali aggiornamenti del Sistema Operativo (e dunque da eventuali modifiche degli Indirizzi Effettivi delle Routine del KERNAL).

La PLOT è allocata nella JUMP TABLE all’indirizzo 65520/$FFF0.
I Parametri da passare prima della chiamata tramite la SYS, sono il numero della Riga (0 – 24) nel Registro Indice X e il numero della Colonna del Cursore (tra 0 e 39) nel Registro Indice Y. Inoltre la Routine prevede, prima della chiamata, l’azzeramento del Registro di Stato P (Status Register).
Le 3 locazioni di memoria utilizzate dal BASIC per salvare i contenuti dei suddetti 3 Registri sono rispettivamente le segg.: 781, 782 e 783.
Per stampare, ad esempio, una stringa alla Riga 2, Colonna 10, scriveremo le seguenti istruzioni:

POKE781,2:POKE782,10:POKE783,0:SYS65520:PRINT”8BRPI”

In alcuni testi è riportato che il Registro da azzerare, come parametro di input della chiamata alla Routine KERNAL, è l’Accumulatore (A) il cui contenuto è memorizzato dal BASIC V2 nella locazione 780.

Pertanto le istruzioni precedenti diverranno:

POKE780,0:POKE781,2:POKE782,10:SYS65520:PRINT”8BRPI”

A ogni modo nella pratica entrambe le forme sembrano funzionare in maniera equivalente senza problemi.

Un altro modo documentato per posizionare il Cursore fa uso della locazione 214 (Numero di Riga Fisica del Cursore), seguita da una PRINT “a vuoto” (ossia non seguita da Parametri) necessaria per l’aggiornamento effettivo dello Screen Editor e dunque per il posizionamento del Cursore sulla Riga indicata, nonché della locazione 211 che contiene il numero della Colonna del Cursore nell’ambito della Linea Logica dello Screen Editor (corrispondente a 2 Linee Fisiche da 40 Colonne l’una per un totale di 80 Colonne):

POKE214,2:PRINT:POKE211,10:PRINT”8BRPI”

Questa tecnica ha però lo svantaggio di NON riuscire mai a posizionare il Cursore nella Riga 0 (la Prima Riga dello Schermo) a causa della PRINT senza Parametri.

Per ovviare a questo inconveniente si può ricorrere nuovamente alla Routine PLOT questa volta tramite una chiamata “diretta” alla Routine di Sistema senza passare per il relativo entry point della JUMP TABLE (uno stile di programmazione poco consigliato dalla C64 PROGRAMMER’S REFERENCE GUIDE a causa della perdita di compatibilità con altri 8 bit Commodore e/o eventuali versioni aggiornate/modificate del KERNAL):

POKE214,2:POKE211,10:SYS58640:PRINT”8BRPI”

Sebbene la SYS 58640 corrisponda ad un salto ad un entry point “non garantito”, di fatto non sussistono in linea di massima particolari problemi di sorta trattandosi di RetroComputing – e RetroProgramming – e dunque di un Firmware (come si direbbe oggi) ormai da decenni ovviamente non più aggiornato e supportato.

Per completezza è bene aggiungere che lo stesso risultato è ottenibile utilizzando un metodo che non fa uso di alcuna routine di sistema e che si appoggia unicamente alle istruzioni BASIC comuni e ad alcuni caratteri di controllo. Tra l’altro il metodo raggiunge anche un buon livello di prestazioni se ci serve disegnare su schermo varie sequenze di caratteri in differenti posizioni sullo schermo.

Riportiamo qui sotto il codice dove applichiamo questo metodo:

10 D$="{CRSR DOWN * 24}"
20 X=8 : Y=3 : REM POSIZIONE DELLA SCRITTA
30 PRINT "{HOME}" ; LEFT$(D$,Y) ; TAB (X) ; "HELLO, WORLD!"

Analizzandolo ci accorgiamo come alla linea 10 viene semplicemente inizializzata una variabile stringa che contiene una sequenza di 24 caratteri {CRSR DOWN} (cursore giù). La linea 20 inizializza le variabili che individuano le coordinate del primo carattere della scritta sullo schermo. La linea 30 invece è quella che si occupa di posizionare la scritta correttamente. Vediamo infatti come il carattere {HOME} setti il cursore nella parte in altro a sinistra dello schermo, mentre l’istruzione LEFT\$(D\$,Y) si occupi di prelevare Y caratteri “cursore giù” dalla stringa e quindi spostare il cursore di Y caratteri in basso; TAB(X) è l’istruzione che colloca il cursore alla posizione orizzontale X sullo schermo e infine la stringa “Hello, world!” è quella che noi vogliamo visualizzare. Possiamo riutilizzare la stessa sequenza di istruzioni per disegnare un’altra scritta da un’altra parte dello schermo, prendendoci cura di modificarne la stringa finale.

Lascia un commento