Ci sono progetti che nascono per risolvere un problema e altri che iniziano semplicemente dalla curiosità. HappyAmigaClock appartiene soprattutto alla seconda categoria: è un piccolo programma nato dal desiderio di tornare a sviluppare per Commodore Amiga, confrontandomi con i limiti e le caratteristiche di una piattaforma che, a distanza di oltre trent’anni, continua a esercitare su di me un fascino particolare.
HappyAmigaClock è un orologio a schermo intero per Amiga, scritto in C utilizzando direttamente le API di AmigaOS. Può mostrare l’ora in modalità digitale oppure attraverso un quadrante analogico e funziona anche su sistemi dotati di Kickstart 1.3.
Non richiede font, librerie aggiuntive o file audio esterni: tutto ciò che serve è contenuto nell’eseguibile.
Perché sviluppare oggi per Amiga?
Sviluppare software per una piattaforma storica non è soltanto un esercizio nostalgico.
Lavorare con risorse limitate costringe a ragionare con maggiore attenzione su memoria, ridisegno dello schermo, gestione degli eventi e costo delle singole operazioni. Molte comodità date per scontate negli ambienti moderni non esistono e ogni scelta progettuale diventa più visibile.
HappyAmigaClock è stato anche una palestra per approfondire la cross-compilazione: il codice viene scritto e compilato su un sistema moderno, ma il risultato deve essere eseguito su hardware e software progettati più di trent’anni fa.
In questo incontro tra epoche diverse ho utilizzato anche strumenti contemporanei, compresa l’intelligenza artificiale, come supporto durante lo sviluppo, la revisione del codice e l’esplorazione delle API. Trovo affascinante impiegare tecnologie di oggi per produrre un eseguibile destinato a una macchina degli anni Ottanta, senza però snaturarne il funzionamento.
L’obiettivo non era simulare un’applicazione Amiga, ma scriverne realmente una.
Le funzioni principali
Nella modalità digitale, HappyAmigaClock mostra l’ora al centro dello schermo e la data, accompagnata dal giorno della settimana abbreviato. È possibile visualizzare anche i secondi oppure usare il formato più essenziale hh:mm, nel quale il separatore lampeggia.
La modalità analogica sostituisce le cifre con un quadrante a tutto schermo, completo delle lancette di ore, minuti e, se desiderato, secondi.
Il programma offre inoltre:
- modalità iniziale chiara o scura;
- inversione automatica dei colori a intervalli configurabili;
- segnale acustico a due note allo scoccare dell’ora;
- animazione opzionale delle cifre in stile split-flap;
- effetto sonoro meccanico associato all’animazione;
- avvio dalla Shell o tramite icona Workbench;
- configurazione attraverso argomenti o ToolTypes;
- occultamento del puntatore dopo dieci secondi di inattività;
- uscita con un clic del mouse, con il tasto Esc o tramite Ctrl+C dalla Shell.
Quando il puntatore viene nascosto scompaiono anche il nome e la versione del programma. La data può seguire lo stesso comportamento oppure rimanere sempre visibile.
Una finestra sopra il Workbench
HappyAmigaClock non apre uno schermo proprietario. Crea invece una finestra Intuition senza bordi, grande quanto lo schermo Workbench attivo.
Questa scelta consente al programma di adattarsi alla modalità video utilizzata, senza imporre una risoluzione specifica. La finestra riceve gli eventi della tastiera e del mouse attraverso IDCMP e copre completamente il Workbench fino alla chiusura dell’applicazione.
Per mantenere la compatibilità con Kickstart 1.3, anche alcuni dettagli apparentemente semplici richiedono attenzione. Il tasto Esc, per esempio, viene intercettato come codice RAWKEY, perché la classe IDCMP_VANILLAKEY appartiene alle versioni successive del sistema operativo.
Dopo dieci secondi senza movimenti, il puntatore viene sostituito con una piccola immagine trasparente allocata in CHIP RAM. Non appena il mouse si muove, il puntatore originale viene ripristinato.
Un font incorporato nell’eseguibile
Uno degli obiettivi era rendere HappyAmigaClock completamente autonomo. Il programma non utilizza quindi i font installati nel sistema.
Le cifre e i caratteri della data sono bitmap monocromatiche incorporate direttamente nell’eseguibile. Esistono tre serie di glifi:
- una per l’ora senza secondi;
- una più compatta per il formato
hh:mm:ss; - una più piccola per la data.
Le bitmap vengono generate in fase di sviluppo a partire da un font vettoriale e convertite in dati C da uno strumento scritto in Python. Non vengono invece ridimensionate durante l’esecuzione: ogni serie è preparata alla sua risoluzione nativa, così il 68000 non deve eseguire costose operazioni di scaling.
All’avvio, i dati necessari vengono trasferiti in CHIP RAM, rendendoli accessibili direttamente al blitter.
Il blitter al lavoro
Il disegno dei caratteri avviene attraverso BltTemplate(), una funzione di graphics.library che usa una maschera monocromatica come sorgente.
In termini semplificati, il processore stabilisce quale carattere disegnare e dove collocarlo; il blitter si occupa del trasferimento effettivo dei pixel.
Questo permette di ottenere un ridisegno rapido anche su un Amiga base. Inoltre, il renderer conserva il testo precedentemente mostrato e confronta i caratteri uno per uno: quando cambia un secondo, non viene cancellato e ridisegnato l’intero orologio, ma soltanto la cifra interessata.
Su uno schermo a buffer singolo questa ottimizzazione riduce sia il lavoro necessario sia il rischio di sfarfallio.
L’animazione split-flap
La modalità digitale può animare il passaggio tra le cifre con un effetto ispirato agli orologi meccanici a palette.
Ogni cifra viene immaginata come due metà separate da una cerniera orizzontale. La transizione è composta da otto fotogrammi:
- la metà superiore della vecchia cifra si comprime progressivamente verso il centro;
- la parte superiore della nuova cifra viene rivelata;
- la metà inferiore della nuova cifra si apre dalla cerniera verso il basso;
- la nuova cifra sostituisce completamente quella precedente.
L’animazione viene applicata soltanto alle posizioni contenenti due cifre differenti. I separatori, la data e i caratteri che non cambiano non vengono animati.
La compressione verticale non è ottenuta modificando tutti i pixel con la CPU. Il renderer seleziona le righe della bitmap sorgente attraverso un accumulatore intero simile a quello usato nell’algoritmo di Bresenham. Nel ciclo più frequente non servono quindi calcoli in virgola mobile, moltiplicazioni o divisioni.
Le righe selezionate vengono poi trasferite dal blitter.
Composizione fuori schermo
Disegnare direttamente tutte le fasi dell’animazione nella finestra renderebbe visibili cancellazioni e aggiornamenti intermedi.
Per evitarlo, ogni fotogramma viene prima composto in una bitmap monocromatica temporanea residente in CHIP RAM. La sequenza è la seguente:
- il fotogramma viene costruito interamente nel buffer;
- il programma attende la conclusione dei blit;
- la visualizzazione viene sincronizzata con il vertical retrace;
- il buffer viene copiato nella finestra con un unico blit;
- il programma attende nuovamente il blitter prima di riutilizzarlo.
Il buffer occupa circa 3,5 KB ed è allocato soltanto quando l’animazione è abilitata.
In questo modo il costo della composizione rimane fuori schermo, mentre ciò che l’utente vede è un singolo aggiornamento sincronizzato per ogni fotogramma.
Tempo reale, senza deriva
Il ciclo principale non usa un ritardo bloccante. HappyAmigaClock apre timer.device e invia richieste asincrone all’unità UNIT_MICROHZ.
Durante il normale funzionamento il programma si risveglia ogni 200 millisecondi. Quando è in corso un’animazione, l’intervallo scende a 40 millisecondi per produrre i fotogrammi intermedi.
Il ciclo attende contemporaneamente:
- il completamento del timer;
- gli eventi della finestra;
- l’eventuale segnale Ctrl+C proveniente dalla Shell.
L’ora mostrata non viene calcolata contando i tick del timer. A ogni aggiornamento viene riletta attraverso DateStamp(). Al termine di un’animazione, il valore viene confrontato nuovamente con quello di sistema: un Amiga particolarmente lento potrebbe impiegare un po’ più di tempo a completare l’effetto, ma l’orologio non accumulerebbe una deriva progressiva.
Poiché alcune funzioni di conversione della data non sono disponibili su Kickstart 1.3, il numero di giorni trascorsi dal primo gennaio 1978 viene trasformato internamente in giorno, mese, anno e giorno della settimana.
Anche il suono è generato dal programma
Il segnale orario e il “clack” dell’animazione non provengono da file esterni.
I campioni vengono generati all’avvio e riprodotti in modo asincrono tramite audio.device, sfruttando l’hardware audio dell’Amiga. Il campione dell’effetto meccanico occupa appena 300 byte di CHIP RAM e contiene due brevi impulsi di rumore con inviluppo decadente.
Il momento della riproduzione è coordinato con la riapertura della cifra, così il secondo impulso termina insieme agli ultimi fotogrammi. Se il cambio della cifra coincide con lo scoccare dell’ora, il segnale orario ha la precedenza.
Configurazione da Workbench e Shell
HappyAmigaClock può essere avviato normalmente dalla sua icona. Le preferenze si impostano nei ToolTypes:
SECONDS=YES
INVERT=720
MODE=LIGHT
DATEALWAYS=NO
CHIME=NO
ANALOG=NO
FLIP=NO
FLIPSOUND=NO
Da AmigaOS 2.0 in poi, le stesse opzioni possono essere passate dalla Shell:
HappyAmigaClock MODE=DARK SECONDS=YES FLIP=YES FLIPSOUND=YES CHIME=YES
Gli argomenti della Shell vengono interpretati con ReadArgs(), mentre i ToolTypes dell’icona sono letti attraverso icon.library.
ReadArgs() non è disponibile su Kickstart 1.3. Su questo sistema HappyAmigaClock si avvia comunque, ignorando gli argomenti della Shell e utilizzando le impostazioni predefinite. La configurazione tramite ToolTypes rimane invece disponibile.
Un progetto C89 per Motorola 68000
Il programma è scritto in C compatibile con lo standard C89 e viene compilato con VBCC usando il target m68k-kick13 e l’opzione specifica per il Motorola 68000.
La toolchain comprende:
- VBCC come compilatore;
- VASM e VLink;
- gli header del Native Developer Kit di AmigaOS;
- GNU Make per automatizzare compilazione e distribuzione;
- FS-UAE per eseguire e verificare rapidamente il risultato.
Il progetto include anche una configurazione dell’emulatore e un floppy di sviluppo. Con un unico comando è possibile compilare l’eseguibile, copiarlo nella directory condivisa e avviare FS-UAE.
Il codice viene inoltre controllato con Clang, abilitando un insieme piuttosto severo di avvisi e trattandoli come errori. È un piccolo esempio di come pratiche di sviluppo attuali possano essere applicate anche a una codebase destinata ad AmigaOS 1.3.
L’applicazione è suddivisa in moduli con responsabilità distinte: configurazione, gestione della finestra, lettura dell’orologio, rendering, font, timer e audio. Anche in un programma compatto, mantenere separati questi aspetti rende più semplice modificare e verificare il comportamento.
Compatibilità prima di tutto
Supportare Kickstart 1.3 ha influenzato molte decisioni.
Ho evitato funzioni introdotte nelle versioni successive di AmigaOS e aperto le librerie di sistema richiedendo la versione 33. Le risorse vengono allocate esplicitamente e rilasciate seguendo l’ordine inverso, anche nei percorsi di errore.
L’eseguibile contiene inoltre il tradizionale tag:
$VER: HappyAmigaClock 1.0 (26.07.2026)
Sui sistemi che supportano il comando AmigaDOS Version, le informazioni possono quindi essere lette senza avviare il programma.
Piccolo, ma autenticamente Amiga
HappyAmigaClock non pretende di rivoluzionare il software per Amiga. Il suo scopo è più semplice: offrire un orologio gradevole e configurabile, ma anche dimostrare che è ancora possibile creare applicazioni native pensando seriamente alle caratteristiche della macchina.
Dietro una schermata apparentemente essenziale convivono Intuition, Exec, graphics.library, il blitter, timer.device, audio.device, la CHIP RAM e numerosi accorgimenti necessari per mantenere la compatibilità con Kickstart 1.3.
È proprio questo il lato più interessante del progetto. HappyAmigaClock mette insieme nostalgia e sperimentazione, strumenti moderni e hardware storico, semplicità visiva e attenzione tecnica.
In fondo, continuare a scrivere software per Amiga significa anche questo: non limitarsi a conservare il passato, ma trovare nuovi modi per mantenerlo vivo.



Il codice sorgente è disponibile sul mio GitHub.





