Sviluppare in C per il Commodore 64 – parte 1

La retro programmazione, al pari del retro computing e del retro gaming, ultimamente si sta diffondendo sempre più anche tra i più giovani. Certo, non si è mai smesso di sviluppare nuovi software, in particolare giochi, per piattaforme come il Commodore 64, ma di recente la platea sia di sviluppatore che di giocatori è aumentata enormemente.

Questo fenomeno sta attirando quindi molti verso lo sviluppo su hardware del passato, in particolare i computer ad 8 bit, per i quali normalmente esistono due possibilità: il BASIC, facile da imparare, ma limitato; o il linguaggio macchina, potente ma molto più complicato. A dire il vero, questa scelta è ancora più complicata per chi è già programmatore, magari da tempo, e vuole avvicinarsi a questo mondo. Perché imparare da zero il linguaggio macchina, ma anche il dialetto BASIC di uno specifico computer insieme a tutti i trucchetti necessari per produrre qualcosa di valido, può essere molto oneroso in termini di tempo, un onere che molti non si sentiranno di affrontare: io sono tra quelli.
Inoltre, se – come me – avete l’età per aver vissuto l’epoca degli 8 bit – o siete veramente veramente appassionati – l’idea di concentrarsi su un solo hardware può apparire riduttiva, e quella di imparare BASIC o linguaggio macchina per più macchine assolutamente improponibile.

Il sempreverde: il linguaggio C

Quindi, come risolvere il problema? Sono partito dal ragionamento che il linguaggio C, per quanto non lo usi da almeno 25 anni, è comunque come sintassi talmente simile ai tanti linguaggi venuti dopo di lui – da Java a PHP – e che uso giornalmente per sviluppare, che non dovrebbe essere eccessivamente complicato recuperarne l’uso. E che, essendo un linguaggio anche lui antico come e più degli 8 bit, magari qualcuno aveva pensato ad un cross compiler non solo per sviluppare in C per Commodore 64 – la mia prima scelta come piattaforma – ma magari anche per altre.

CC65 Super Hero

E così, cercando su Google qualcosa che facesse per me, trovo questo bellissimo progetto: CC65 (https://cc65.github.io/), un compilatore C per Windows e sistemi Unix-like che produce eseguibili per qualunque piattaforma basata su processore 65(C)02, ed infatti supporta i seguenti target1:

  • Vic20, C16, C116, Plus/4, Commodore 128, Commodore 64, CBM510/P500, Commodore 600/700 (tutta la famiglia) e alcuni PET più recenti, oltre che GEOS;
  • Apple II+ e successori e GEOS su Apple IIe;
  • Atari 8 bit, 2600, 5200 e Lynx;
  • La console Gamate della Bit Corporation;
  • Il NEC PC Engine (noto anche come TurboGrafx16);
  • Nintendo NES;
  • La console Watara Supervision;
  • La console Creativision della VTech;
  • Oric Atmos e Telestrat;
  • Il Challenger 1P della Ohio Scientific.

Impressionante vero? Ho pensato la stessa cosa, ma ho anche pensato: sarà complicatissimo configurare tutto questo. E invece no! In particolare il pensiero mi è venuto per sistemi non Windows (io lavoro su Linux e MacOS), questo perché per Windows esiste la possibilità di scaricare uno Snapshot precompilato.

Prepariamo l’ambiente

Di seguito quindi vi mostrerò i semplicissimi passi necessari per avere l’ambiente CC65 funzionante e compilare il nostro primo programma, per chiunque preferisca compilare da sorgente perché costretto, come nel caso di Linux e MacOS, o per piacere personale anche su Windows, nel qual caso avrete bisogno di un ambiente CygWin (https://www.cygwin.com/)2 completo.

Per prima cosa accedete alla vostra macchina e scaricate il sorgente aggiornato3:

sudo git clone https://github.com/cc65/cc65.git

Verrà creata una directory cc65 contenente il sorgente. Entriamoci e lanciamo la compilazione:

cd cc65
sudo make

Il comando make esegue uno script contenente nel file Makefile, e si tratta nel mondo Unix del sistema primigenio di gestione della compilazione di progetti software, più primitivo dei sistemi esistenti oggi per Java ed altri, ma comunque molto potente.
Completiamo con:

sudo make avail

che crea dei link simbolici4 nel path di esecuzione standard (/usr/local/bin su Linux e MacOS) agli eseguibili creati, per essere più comodi nel loro utilizzo. Questi link permetteranno di eseguire i comandi di compilazione mantenendo la configurazione esistente nella cartella cc65 e quindi l’accesso a tutte le librerie necessaria per la cross compilazione. Fate attenzione che se volete spostare la cartella cc65 da un altra parte, perché tutto funzioni a dovere dovete eliminare i link simbolici create precedentemente e ripetere l’ultimo comando che abbiamo visto.

Il nostro primo programma

A questo punto, siamo pronto a vedere se la magia funziona. Creiamo una cartella dove vogliamo creare il nostro sorgente (consiglio di creare sempre una cartella dedicata per ogni progetto), e creiamo un file di nome halloworld.c con il seguente contenuto:

#include <stdio.h>
void main(void) {
    printf("Hello, world!\n");
}

e passiamo a compilarlo eseguendo:

cl65 halloworld.c

Il comando cl65 invoca da solo la catena di programmi che tipicamente compongono un compilatore C e permettono di creare un eseguibile, e cioè il preprocessore, il compilatore, il convertitore del file object ed il linker, che nel nostro caso sono cc65, ca65, co65 e ld655. Non specifichiamo un target perché quello di default è Commodore 64 e per i fini del nostro articolo ci va bene così.

Se guardate nella cartella troverete un file di nome halloworld.o che è il prodotto intermedio quando si lavora in C tra il sorgente e l’eseguibile, ed un file halloworld che è l’eseguibile vero e proprio.

La magia

Proviamo ad eseguire un normale emulatore Commodore 64 e ad eseguire il nostro programma, avendo prima l’accortezza di rinominare halloworld in halloworld.prg. Ta-da! La magia si avvera, avete scritto un programma in C, cross compilate per il target Commodore 64 ed eseguito senza problemi!

Ma non finisce qui

Nel prossimo articolo vedremo come usare anche noi un Makefile per poter affrontare progetti più complessi e come definire un target diverso per la compilazione.

Note

[1] Nel gergo dei compilatori il ‘target’ è l’hardware di riferimento per cui si deve produrre l’eseguibile finale.

[2] CygWin è un sottosistema BSD per Windows facilmente installabile che rende il prompt di comandi DOS praticamente una macchina Linux.

[3] Useremo per l’articolo la sintassi per MacOS, che è praticamente identica a quella che serve su Linux e su Windows con CygWin.

[4] I link simbolici sono praticamente paragonabili alle scorciatoie di Windows od agli alias di Mac.

[5] Se siete curiosi e volete meglio capire cosa sono questi programmi, vi consiglio questa breve introduzione: https://courses.cs.washington.edu/courses/cse378/97au/help/compilation.html

Fabrizio Lodi:
Related Post
Leave a Comment