Programmazione della grafica con il C64, uno sguardo ad alcuni miei semplici programmi [ITALIAN]

Mi presento oggi con un post in italiano per riassumere i miei recenti esperimenti sulla programmazione della grafica con il Commodore 64. Solitamente posto in inglese per raggiungere un maggior numero di utenti, tuttavia ho deciso di pubblicare ogni tanto dei “riassunti” in italiano di alcuni contenuti proposti.

Ultimamente mi sono concentrato molto sulla grafica bitmap, cercando di capire come risolvere semplici ma importanti problemi quali il plot di un punto sullo schermo ad “alta” risoluzione, il tracciamento di linee ed ellissi, nonché l’animazione in tempo reale di semplici figure tridimensionali usando i vettori. I programmi sono stati realizzati in BASIC e in linguaggio macchina.

E’ nota l’assenza nel BASIC residente del Commodore 64 di comandi specifici per la gestione della grafica. Ciò comporta non pochi disagi, a meno che non si disponga di un BASIC esteso o di un’opportuna utility. In particolare, la cancellazione dello schermo bitmap utilizzando il BASIC 2.0 risulta normalmente molto lenta.

Seppure la soluzione comunemente proposta sia quella di utilizzare estensioni del BASIC o comunque utility in linguaggio macchina, l’azzeramento dello schermo bitmap può essere eseguito velocemente anche in BASIC 2.0.

Una classica soluzione, proposta ad esempio nel testo “Mapping the Commodore 64” di Sheldon Leemon, consiste nell’utilizzare l’istruzione PRINT per scrivere nella memoria utilizzata dallo schermo bitmap, in modo da cancellarlo rapidamente. La locazione 648 decimale consente di impostare la pagina di memoria dalla quale deve partire per il sistema operativo la memoria dello schermo in modalità testo. Modificando il valore di questa locazione il gioco è fatto. Tuttavia, esiste un’altra soluzione un po’ più veloce e probabilmente anche più semplice da implementare.

E’ noto il “bug” della garbage collection lenta, presente nel BASIC 2.0. In breve, l’assegnazione di variabili stringa può rapidamente riempire la memoria, richiedendo un’operazione di “ripulitura” che, così come è stata implementata, è davvero molto lenta. Questa capacità di riempire la memoria con l’assegnazione di stringhe può tuttavia essere usata per risolvere il nostro problema: cancellare velocemente lo schermo ad alta risoluzione.

Questo programma, scritto interamente in BASIC, cancella velocemente lo schermo bitmap – addirittura con una velocità non particolarmente lontana da quella che si può conseguire con una routine in linguaggio macchina.

La routine di cancellazione è presente nelle linee 23, 24 e 30. Anzitutto, il puntatore alle stringhe viene modificato in modo da puntare alla memoria grafica. Dopo di che, nell’ambito di un’iterazione enumerativa, viene creata una variabile stringa che cresce di carattere in carattere. Ciò comporta la creazione in memoria di numerose stringhe temporanee tutte contenenti il carattere CHR$(0). Alla fine del ciclo, la memoria video risulta così azzerata. Alla linea 30, il puntatore alle stringhe viene riportato al valore originale.

Pertanto, con tre semplici linee (riducibili a sole due con un minimo di compattazione) è possibile cancellare rapidamente lo schermo bitmap anche per chi non ha conoscenza del linguaggio macchina.

Il programma poi dimostra come sia semplice, tramite una breve formula, tracciare delle funzioni sinusoidali anche senza un comando “PLOT”.

Pur nella sua basilarità, il programma dimostra come gestire la grafica bitmap anche ostinandosi ad utilizzare il BASIC 2.0 non sia in fondo così complicato e lento.

Con l’occasione ne approfitto per condividere un programma di prova che avevo realizzato qualche mese fa: “Stella Parabolica”.  Avevo realizzato il programma per sperimentare l’uso di tabelle per il plotting rapido (tecnica che consente un effettivo miglioramento delle prestazioni mediante un’implementazione in linguaggio macchina). Il programma quindi si prende qualche secondo per creare le tabelle, in realtà non necessarie in BASIC.

Comunque, come si può vedere listando il programma, una semplice equazione della retta, così come ci è stata insegnata a scuola, permette di tracciare delle linee facilmente, senza il bisogno di dover ricorrere ad un libro di computer grafica o inventarsi un algoritmo in stile Bresenham.

Seguendo questa stessa logica ho anche realizzato la versione in linguaggio macchina del programma. Sebbene con un codice piuttosto lungo, è stato comunque possibile implementare una routine di tracciamento delle rette utilizzando l’equazione scolastica, semplicemente facendo uso di numeri interi senza segno. L’uso della moltiplicazione è stato ridotto al minimo onde favorire discrete prestazioni. La divisione intera necessaria per calcolare il coefficiente angolare m è stata effettuata utilizzando una routine di mia ideazione che sfrutta le potenze di due. Il codice è anche qui piuttosto lungo, la routine non è il massimo dell’efficienza ma funziona bene per quello che deve fare qui (è ovviamente necessaria una sola divisione per ogni linea tracciata).

Pur nella sua macchinosità (il programma è stato infatti pensato come banco di prova per le mie routine di matematica intera), il software permette comunque di tracciare linee superando le prestazioni del Simons’ BASIC e pure quelle del BASIC 7.0 del Commodore 128. Ovviamente, le routine di questi ultimi sebbene più lente sono molto più compatte.

Un algoritmo in stile Bresenham consente comunque di ottenere prestazioni migliori. Delle routine più veloci per il tracciamento delle linee si sono ad un certo punto rese necessarie per i miei semplici programmi di grafica 3D, quali ad esempio il programma che effettua la rotazione di un cubo eliminando le facce nascoste in tempo reale. La routine di tracciamento delle linee usata in questi programmi non calcola il coefficiente angolare ma usa una semplice variabile di accumulo per tenere conto della pendenza della linea.

Un requisito importante per fare rotazioni è senza dubbio riuscire a calcolare rapidamente le funzioni trigonometriche. Ciò viene fatto comunemente, in assembly, utilizzando delle tavole di look-up, come avviene in questo programma che disegna una sfera utilizzando più ellissi. I punti delle ellissi sono calcolati utilizzando delle semplici relazioni trigonometriche.

Tornando al BASIC 2.0, nel blog ho proposto vari programmi che effettuano lo scrolling di una scacchiera. Ad esempio, questo programma effettua lo scrolling verticale di una scacchiera di 4 x 4 caratteri.

Un programma del genere dimostra come anche con il semplice BASIC 2.0 il Commodore 64 possa raggiungere risultati che in altre macchine contemporanee ad 8 bit possono essere invece ottenuti soltanto con il linguaggio macchina. Un ulteriore esempio in questo stile è senz’altro questo mio semplice programma che simula un effetto 3D (provate a dare un’occhiata al terzo programma contenuto nel .d64, “skyscrapers”).

Potete trovare tutti i sorgenti e maggiori spiegazioni (in inglese) nella sezione “Programming” di questo blog.

Previous Entries Another look at 3D graphics: fast hidden faces removal (back-face culling) Next Entries Taking the square of a 16 bit number, a simple technique using 6502 assembly

8 thoughts on “Programmazione della grafica con il C64, uno sguardo ad alcuni miei semplici programmi [ITALIAN]

  1. KickOff on said:

    Wow post decisamente interessante almeno per me, visto che vorrei cimentarmi nella costruzione di un disegno raffigurante una ellisse e al suo interno una pallina che raffigura un atomo. Naturalmente il codice lo vorrei scrivere sia in basic 2.0 che in routine per linguaggio macchina da introdurre in un programma basic . Quali funzioni devo usare e come procedere?

    • KickOff on said:

      Ciao retro64, scusa ma ci terrei ad avere una tua opinione in merito, spero che mi scriverai se vuoi ti do una mail dove raggiungermi.

      • retro64 on said:

        Ciao KickOff, ti ho risposto nel commento dell’altro articolo, comunque ti incollo la risposta anche qua 🙂
        Ciao Kick Off, anzitutto ti ringrazio per le belle parole!
        Quello che vuoi realizzare è molto interessante. Dobbiamo anzitutto disegnare un’ellisse con gli assi inclinati che rappresenta l’orbita. Ricordo che avevo letto recentemente in un libro come disegnare le orbite, appena ho tempo ci do un’occhiata L’elettrone lo realizzerei sicuramente con uno sprite. Il nucleo, dato che sta fermo, può essere anche realizzato in grafica bitmap.
        Appena ho un po’ di tempo, vedrò di fare un esempio su come disegnare un’ellisse con assi inclinati in BASIC.
        Ciao e grazie!

        • KickOff on said:

          Ciao grazie per avermi risposto, grazie per l’aiuto, domanda veloce posterai qui sul blog l’esempio? Ti sembrerà strano ma sono interessato al tuo aiuto la tua mail é ***? Magari ci “sentiamo” per email? Ciao grazie

          • retro64 on said:

            Ciao! In questi giorni sono molto impegnato con il lavoro, ma appena ho tempo penso che farò un post in merito 🙂 L’indirizzo è corretto, infatti mi è arrivata una tua mail alla quale ho risposto inviandoti delle formule che ho trovato in rete, le quali però devo ancora testare.
            Ciao e grazie per l’interesse.

  2. KickOff on said:

    Ciao grazie per la mail che di certo andrò a leggere fra poco, nel frattempo aspetterò tue nuove riguardo al mio programma che ti ho mandato, accennato poco più sopra. Grazie ancora.

Leave a Reply

*