top of page

ZX Spectrum è arrivato su Hacker News, ma la modalità testo rivela i compromessi della sua ROM

4 ago
Tempo di lettura: 13 min

Lo ZX Spectrum è tornato su Hacker News grazie a un tour del sistema del 2026 che mette in luce un conflitto nascosto nella sua ROM da 16K. Stampare un singolo carattere può essere semplice. Realizzare un output testuale affidabile in codice macchina richiede invece di comprendere assunzioni non documentate, variabili di sistema mutabili, attributi persistenti e percorsi di input specifici dell'hardware.

Michael Martin ha pubblicato il tour in codice macchina il 30 maggio 2026. Il post riprende una precedente esplorazione in BASIC, ma fa ben più che tradurre comandi familiari in assembly Z80. Mostra dove finisce il pratico ambiente di programmazione di Sinclair e dove inizia il suo firmware dalla struttura poco rigorosa.

Questa distinzione rende il post rilevante anche oltre il retrocomputing. Le macchine Commodore offrivano tabelle di salto KERNAL stabili, mentre MSX definiva chiamate firmware comuni a più produttori. Lo Spectrum, invece, incoraggiava i programmatori a combinare pochi punti di ingresso ROM con l'accesso diretto allo stato di sistema. Questo approccio risparmiava livelli di astrazione, ma trasferiva agli sviluppatori il lavoro di compatibilità e debugging.

Il risultato non è una funzione appena scoperta né l'annuncio di un prodotto moderno. È un'analisi ravvicinata di un vecchio compromesso ingegneristico. Lo Spectrum rendeva disponibili primitive utili con poca memoria, senza però trasformarle in una piattaforma pulita per il codice macchina.

Cosa ha effettivamente cambiato il System Tour dello ZX Spectrum

Il nuovo contributo è un percorso coerente in codice macchina, dall'output testuale alla grafica, all'input e a un display completo in esecuzione.

Lo Spectrum non ha improvvisamente acquisito una modalità testo. Il post di Martin migliora la spiegazione disponibile riunendo vari meccanismi sparsi in un'unica sequenza pratica. Parte da una compatta routine Hello World, poi passa attraverso codici carattere, controlli del colore, grafica personalizzata, pulizia dello schermo, scansione della tastiera e input del joystick.

Il primo passaggio usa RST $10, un punto di ingresso restart della ROM che stampa il carattere contenuto nel registro A dello Z80. Un restart è una chiamata compatta a un indirizzo fisso nella memoria bassa. Prima di utilizzarlo, l'esempio scrive zero in TVFLAG a IY+2, indirizzando l'output verso l'area principale dello schermo.

Questa sequenza rende l'operazione di base quasi moderna. Un programma carica un puntatore a un messaggio, recupera un byte, chiama la routine di stampa e ripete. Martin colloca il codice all'indirizzo $7000, lasciando spazio sotto di esso per BASIC e mantenendo memoria utilizzabile su una macchina da 16K.

La semplicità dura finché il testo non richiede stato. Lo schermo dello Spectrum presenta normalmente 24 righe di 32 caratteri. Il firmware divide queste righe in una finestra superiore di 22 righe e una finestra inferiore di due righe, usata per modifiche e messaggi di stato. Le originali specifiche del display di Sinclair confermano questa suddivisione e descrivono un display da 256 per 192 pixel.

La macchina non dispone di hardware per caratteri separato, paragonabile a quello di un terminale convenzionale. La sua ROM disegna invece un glifo da 8 per 8 nella memoria bitmap, quindi scrive le informazioni sul colore per la cella corrispondente. Ciò significa che l'output testuale dipende già dal layout grafico, dagli attributi correnti, dalla posizione del cursore e dal canale di output selezionato.

Martin amplia poi il percorso con 16 caratteri semigrafici predefiniti e grafica definita dall'utente. I semigrafici dividono una cella carattere in blocchi, consentendo a forme semplici di passare attraverso la normale stampante di testo. La grafica definita dall'utente occupa codici carattere a partire da $90, con i dati bitmap localizzati tramite il puntatore di sistema UDG.

L'esempio finale del post combina queste funzionalità in un banner colorato con un'immagine personalizzata di un ombrello. Carica quattro definizioni di caratteri, emette byte di controllo in linea, attende l'input e ripristina lo schermo. Martin riferisce che il pacchetto in codice macchina è meno della metà della dimensione della sua precedente versione BASIC, anche includendo loader e intestazione del nastro.

Questo confronto è il vero risultato dell'evento. Il post non si limita a presentare indirizzi isolati. Dimostra che la ROM dello Spectrum può fungere da framework applicativo compatto, purché il programmatore accetti la responsabilità del suo stato nascosto.

Perché il pubblico di Hacker News si interessa ancora a questa ROM

Lo Spectrum concentra un problema di sistemi familiare in una macchina abbastanza piccola da poter essere compresa quasi completamente.

L'articolo è arrivato su Hacker News perché tratta l'hardware rétro come un sistema software ispezionabile. Ogni operazione principale segue un percorso visibile. Un carattere passa attraverso un ingresso ROM fisso, legge un glifo, tocca la memoria bitmap, applica un byte di attributo e avanza un cursore rappresentato nello stato di sistema.

Gli sviluppatori moderni incontrano le stesse categorie di problemi dietro interfacce molto più grandi. Le librerie mantengono configurazioni. I flussi di output hanno stato. La compatibilità dipende da comportamenti che la documentazione potrebbe non promettere. Le astrazioni hardware espongono vie di fuga quando le interfacce normali risultano troppo limitate.

Sul Spectrum, questi problemi rientrano in uno spazio di indirizzamento Z80. Il modello originale utilizzava un processore Z80A a 3,5 MHz, una ROM da 16K e 16K o 48K di RAM. Questi vincoli rendono ogni astrazione visibile nella mappa di memoria.

Il display è particolarmente istruttivo. Uno schermo Spectrum standard occupa 6.912 byte, composti da una bitmap monocromatica di 6.144 byte e 768 byte di attributi. Ogni byte di attributo fornisce colori di primo piano e sfondo, luminosità e lampeggio per una cella da 8 per 8.

Questo design risparmiava memoria, ma legava pixel vicini a un'unica scelta di colore. Il risultato noto è l'attribute clash, in cui oggetti di colori diversi non possono attraversare la stessa cella senza influenzarsi a vicenda. La stampa del testo eredita questa architettura perché ogni glifo finisce in una di quelle celle.

La guida di Martin aggiunge una seconda lezione. Una piccola interfaccia documentata non crea necessariamente una piattaforma di programmazione stabile. Lo Spectrum espone una stampante di caratteri efficace, ma i programmi sofisticati devono conoscere anche gli indirizzi di variabili quali ATTR-T, MASK-T, P-FLAG, SCR-CT e UDG.

La documentazione ufficiale delle variabili di sistema descrive la memoria condivisa usata da BASIC e dalle routine ROM. Chiamare il firmware modificando direttamente questi valori è efficiente, ma crea un forte accoppiamento. Un programma dipende sia dalla routine richiamabile sia dallo stato interno atteso da quella routine.

Qui lo Spectrum si differenzia dalle macchine progettate attorno a confini firmware più formali. Il KERNAL di Commodore usava vettori di salto fissi per i servizi comuni. MSX standardizzava le chiamate affinché il software potesse puntare a macchine di produttori diversi. Anche il BIOS dell'IBM PC stabiliva servizi richiamabili al di sopra dell'hardware, pur quando gli sviluppatori in seguito lo aggiravano per ottenere velocità.

L'approccio di Sinclair era meno formale. Funzionava bene per BASIC perché Sinclair controllava sia l'interprete sia la ROM. I programmatori assembly ricevevano dettagli utili dell'implementazione anziché un ampio contratto di compatibilità.

Questo compromesso spiega l'interesse continuo. Lo Spectrum offre un caso di studio insolitamente chiaro su come un'implementazione interna diventi un'interfaccia pubblica. Quando i programmatori realizzano software basandosi su indirizzi e peculiarità, tali dettagli diventano difficili da cambiare, indipendentemente dall'intenzione del loro progettista.

Il vero avversario è la comodità contro la stabilità

La ROM dello Spectrum rende semplici i programmi semplici, ma ogni scorciatoia aumenta la dipendenza da comportamenti specifici della macchina.

Il conflitto centrale non è quello tra ZX Spectrum e Commodore 64. È quello tra comodità e stabilità all'interno dello Spectrum stesso. L'accesso diretto al sistema riduce la dimensione del codice ed espone capacità utili. Rende però anche il software responsabile di assunzioni che un contratto firmware più solido avrebbe contenuto.

Si considerino gli attributi del testo. I codici carattere da $10 a $17 controllano INK, PAPER, FLASH, BRIGHT, INVERSE, OVER, il posizionamento del cursore e la tabulazione. Un programma può incorporare questi byte all'interno di una stringa, quindi inviare l'intera sequenza tramite RST $10.

È un meccanismo compatto. Ricorda le sequenze di escape dei terminali, in cui byte non stampabili modificano l'interpretazione del testo successivo. Consente ai messaggi di includere la formattazione senza chiamate di disegno separate.

L'aspetto sorprendente è la persistenza. Questi controlli in codice macchina non si reimpostano dopo l'equivalente di un'istruzione BASIC PRINT. Nemmeno un ritorno a capo ripristina lo stato precedente. Un helper che presuma che la formattazione termini con una stringa può quindi modificare ogni operazione di stampa successiva.

La ROM tiene traccia degli attributi temporanei e permanenti tramite diverse variabili di sistema. ATTR-T contiene le impostazioni correnti di colore, luminosità e lampeggio. MASK-T determina quali bit devono restare invariati. Le controparti permanenti influenzano la pulizia dello schermo e stabiliscono i valori predefiniti.

Questa divisione funziona perché BASIC la gestisce come parte di un'operazione linguistica più ampia. Il codice assembly entra al di sotto di quel livello. Deve riprodurre il comportamento di impostazione e pulizia normalmente fornito da BASIC.

La pulizia dello schermo rivela la stessa tensione. Chiamare la routine CLS della ROM pulisce il display, ma Martin osserva che reindirizza anche l'output successivo verso la finestra inferiore. Non coordina completamente il bordo dello schermo con le aree superiore e inferiore.

Il suo helper clrto corregge questo comportamento. Imposta gli attributi permanenti, ricava il colore del bordo, cancella maschere e flag di modalità, invoca CLS, quindi apre il canale due per lo schermo superiore. Un'operazione apparentemente basilare diventa un piccolo protocollo di ripristino dello stato.

La routine CHAN-OPEN a $1601 dimostra perché la ROM resta utile. Aprire un canale è più chiaro che limitarsi a modificare un flag. Tuttavia, il programma necessita ancora di scritture dirette nelle variabili e di un'istruzione di output verso la porta $FE. Firmware e accesso hardware rimangono intrecciati.

Questa combinazione può essere produttiva su un target fisso. Evita di duplicare il rasterizzatore di caratteri e la gestione del cursore della ROM. Uno sviluppatore ottiene testo leggibile, controlli del colore, comportamento delle finestre e glifi personalizzati senza scrivere ogni routine per pixel.

Il costo emerge quando cambia il target. Martin evidenzia il Timex Sinclair 2068, la cui ROM incompatibile ha danneggiato la compatibilità con il software Spectrum negli Stati Uniti. I programmi che dipendevano da routine fisse o layout di sistema non potevano presumere un comportamento equivalente.

Un'interfaccia di programmazione delle applicazioni convenzionale separa il comportamento supportato dall'organizzazione interna. L'ambiente assembly dello Spectrum offre solo una versione parziale di tale confine. Le sue chiamate ROM sono interessanti perché già presenti, ma il contratto circostante viene in parte ricostruito dagli sviluppatori.

Ecco perché questa guida conta più di un altro esempio Hello World. Rende esplicito il contratto nascosto. Il codice documenta quale stato deve essere impostato, quali routine lo modificano e quali valori devono essere ripristinati in seguito.

La modalità testo è in realtà una bitmap e una macchina a stati

Definirla modalità testo è una comoda abbreviazione, ma l'implementazione è un renderer bitmap governato da stato condiviso e mutabile.

L'espressione “modalità testo” suggerisce di solito celle carattere dedicate, memorizzate come codici carattere. L'hardware recupera un glifo per ciascun codice e lo disegna automaticamente. Modificare una cella significa scrivere un valore di carattere e forse un valore di colore.

Lo Spectrum originale funziona in modo diverso. Il software richiama la stampante ROM, che disegna i pixel dei glifi nella stessa bitmap usata dalla grafica. Un’area degli attributi separata fornisce il colore alla risoluzione delle celle di caratteri. La griglia visiva esiste come convenzione di programmazione, non come buffer hardware di testo completo.

Questa distinzione spiega diversi meccanismi del tour di Martin. La ROM può stampare caratteri normali, grafica a blocchi e glifi definiti dall’utente attraverso un unico percorso, perché tutti diventano schemi di pixel da 8 per 8. La stampante non deve sapere se un glifo rappresenta una lettera o una parte di un ombrello.

La parte alta del set di caratteri dello Spectrum supporta questo approccio. I codici da $80 a $8F rappresentano 16 combinazioni di blocchi. I codici che iniziano con $90 indirizzano la grafica definita dall’utente. I codici successivi codificano le parole chiave BASIC, consentendo all’interprete di memorizzare i comandi in modo compatto.

La grafica personalizzata dipende dall’indirezione. La variabile di sistema UDG punta alle bitmap definite dall’utente correnti. Ogni carattere occupa otto byte, un byte per ciascuna riga. L’esempio di Martin copia 32 byte in quell’area per definire quattro parti adiacenti dell’ombrello.

Quell’indirezione è un’astrazione modesta ma importante. La routine di disegno non richiede un unico indirizzo grafico codificato rigidamente. Un programma può individuare l’area attiva tramite il puntatore, quindi sostituire le forme. Il comportamento ricorda un atlante di font configurabile, su una scala molto più piccola.

Il colore rimane basato sulle celle. Un byte di attributo assegna un colore di inchiostro, un colore di sfondo, un bit di luminosità e un bit di lampeggiamento. I singoli pixel determinano se la cella mostra inchiostro o sfondo, ma non possono scegliere colori indipendenti.

Questo progetto pensato per risparmiare memoria trasforma i controlli di formattazione in operazioni sia sullo stato sia sulla memoria dello schermo. Quando la ROM stampa un carattere, consulta ATTR-T e MASK-T, scrive i pixel e aggiorna la cella degli attributi. Le opzioni di inchiostro o sfondo trasparenti funzionano mascherando campi selezionati invece di sostituire l’intero byte.

La disassemblazione della ROM resta preziosa perché espone i percorsi dietro questi effetti. Quel materiale può verificare cosa modifica effettivamente un punto d’ingresso, soprattutto quando un programma dipende da comportamenti che vanno oltre la descrizione superficiale di un manuale.

Lo stato condiviso crea anche guasti sottili. Il primo ciclo di stampa di Martin usa zero come terminatore della stringa. Funziona finché zero non diventa un dato significativo. Il banner completato deve stampare argomenti di controllo con valore zero, comprese le impostazioni per sfondo e luminosità.

Il ciclo rivisto usa quindi $FF come sentinella. Quel byte rappresenta la parola chiave BASIC COPY, che il banner non stamperà. La modifica è piccola, ma illustra un problema di protocollo generale: un terminatore in banda fallisce quando il formato dei dati si espande fino a includere quel valore.

Lo stesso problema compare nei protocolli di rete, nei formati di file, nei flussi di comandi e nelle librerie di serializzazione. Un byte è sicuro come delimitatore solo finché il payload lo esclude. Quando dati di controllo e dati di visualizzazione condividono un unico flusso, l’incorniciatura merita una progettazione esplicita.

Questa è la lezione moderna più forte del post. I limiti della macchina sono antichi, ma le sue modalità di guasto sono attuali. Stato condiviso, effetti collaterali non documentati, valori di byte sovraccarichi e ipotesi ristrette di compatibilità continuano a modellare i sistemi software.

L’input completa il compromesso del firmware

La gestione di tastiera e joystick mostra lo stesso schema dell’output testuale: usare il firmware quando la sua politica è utile, quindi aggirarlo quando conta il controllo diretto.

Il tour di Martin passa dall’output su schermo all’input da tastiera perché un sistema di testo utilizzabile richiede interazione. Lo Spectrum offre ancora una volta due percorsi. I programmi possono usare lo stato della tastiera preparato dalla ROM oppure leggere direttamente le porte hardware.

Il percorso firmware si basa sull’interrupt di frame della macchina. Un interrupt è un trasferimento attivato dall’hardware verso una routine di servizio. A ogni frame video, il gestore dello Spectrum aggiorna il timer FRAMES e scandisce la matrice della tastiera.

Quando trova un tasto, il gestore decodifica quell’input e memorizza un carattere in LAST-K. Imposta inoltre il bit cinque della variabile di sistema FLAGS. La routine getkey di Martin attende con l’istruzione Z80 HALT, verifica il flag, recupera il carattere, cancella il flag e restituisce il controllo.

L’uso di HALT è importante. Il ciclo non ha nulla di utile da fare finché il gestore degli interrupt non esegue un’altra scansione della tastiera. Attendere quell’interrupt evita di leggere ripetutamente un flag invariato alla massima velocità del processore.

Questo percorso offre interpretazione anziché stato elettrico grezzo. La ROM comprende le combinazioni di tasti e le mappa in caratteri. Un programma può accettare testo senza riprodurre il decodificatore della tastiera.

L’input diretto scambia quella comodità con l’immediatezza. La tastiera dello Spectrum è organizzata come una matrice accessibile tramite porte I/O. Selezionando una riga e controllando i bit restituiti si scopre quali tasti sono attualmente premuti.

Lo Z80 introduce una particolarità storica. Alcune istruzioni di input e output sembrano esporre un indirizzo di porta a otto bit, ma IN A,(C) e OUT (C),A collocano l’intero registro BC sul bus degli indirizzi. Sinclair sfruttò quel comportamento nella progettazione della sua interfaccia hardware.

L’esempio di Martin controlla il tasto A tramite il valore di porta $FDFE. Quel codice non attende che la ROM traduca una pressione. Interroga l’hardware su una posizione nella matrice, rendendolo utile per i giochi che richiedono uno stato direzionale continuo.

Il joystick Kempston è più semplice. Usa la porta $1F, in cui i bit rappresentano direzioni e pulsante di fuoco. Il lettore di Martin traduce quel campo di bit in delta orizzontali e verticali più un valore di fuoco.

Queste opzioni mostrano perché i programmatori aggirano le astrazioni anche quando un’astrazione esiste. L’input da tastiera del firmware è adatto all’inserimento di testo o all’attesa di un comando. Le letture dirette dalle porte sono migliori per il movimento simultaneo, la bassa latenza e i controlli ripetuti dello stato.

Il costo è la portabilità. Una routine legata alla matrice della tastiera dello Spectrum presuppone la disposizione elettrica della macchina. Un lettore Kempston presuppone quella particolare interfaccia. Gli emulatori devono riprodurre questi comportamenti, mentre hardware alternativi o standard joystick diversi richiedono codice differente.

Martin nota anche incoerenze che coinvolgono tasti Shift sintetici negli emulatori. È un’utile prospettiva scettica. Una routine tecnicamente accurata può comunque comportarsi diversamente quando l’implementazione circostante interpreta l’input dell’host in un altro modo.

L’apparizione su Hacker News non dovrebbe essere scambiata per un’ampia verifica di ogni emulatore o variante dello Spectrum. La segnalazione collegata ha ricevuto una risposta modesta e nessuna discussione registrata nello snapshot fornito. Il valore tecnico deriva dal percorso di codice riproducibile, non dal consenso della folla.

I lettori dovrebbero quindi separare tre livelli di affermazione. La documentazione originale Sinclair stabilisce le funzionalità previste della macchina. L’analisi della ROM rivela il comportamento dell’implementazione. Gli esempi di Martin dimostrano un percorso di sviluppo funzionante, ma non garantiscono risultati identici su ogni clone, revisione ROM, interfaccia o emulatore.

Cosa dovrebbero osservare gli sviluppatori dopo il picco su Hacker News

La prossima prova è capire se questo tour diventerà un’infrastruttura tecnica durevole anziché un link effimero.

Il primo segnale è la continuazione del tour del sistema. Martin termina con una lacuna chiara: gli esempi possono riprodurre il principale display, input e animazione necessari per una versione in codice macchina del gioco precedente, ma il suono e la schermata del titolo restano irrisolti. Un seguito che affronti grafica o audio mostrerebbe se lo stesso metodo scala oltre l’output orientato ai caratteri.

Il secondo segnale è la riproducibilità tra piattaforme di destinazione. Gli sviluppatori dovrebbero testare gli esempi su hardware originale 48K, modelli Spectrum successivi, emulatori comuni e varianti ROM. Un output corrispondente rafforzerebbe l’argomento per trattare queste routine come un livello pratico di compatibilità. Le divergenze identificherebbero invece dove l’accesso diretto allo stato supera la stabilità delle chiamate ROM.

Il terzo segnale è se il codice diventa più facile da ispezionare e riutilizzare. Un esempio scaricabile, un processo di build documentato, un’immagine di test fissa o l’automazione dell’emulatore trasformerebbero l’articolo in un riferimento eseguibile. Martin nomina già l’assembler, lo strumento di confezionamento su nastro e l’emulatore FUSE usati per il flusso iniziale Hello World. Preservare tali dipendenze conta quanto preservare l’elenco assembly.

C’è anche una questione più ampia di documentazione. Le piattaforme retro dispongono spesso di molte informazioni, ma di un’autorità frammentata. I manuali descrivono il comportamento previsto, le disassemblazioni espongono gli interni, i riferimenti della comunità correggono gli errori e i tutorial moderni collegano i pezzi. Un’utile guida alla piattaforma può ridurre quella frammentazione se distingue chiaramente tra contratti documentati e peculiarità osservate.

Gli sviluppatori che seguono questa storia dovrebbero resistere alla tentazione di trasformare un singolo esempio elegante in una regola universale. Le chiamate ROM dirette possono risparmiare memoria e lavoro di sviluppo. L’accesso diretto all’hardware può migliorare la reattività. Nessuno dei due garantisce compatibilità al di fuori dell’ambiente esatto in cui è stato testato.

Quell’incertezza è parte del valore. Lo ZX Spectrum rende possibile tracciare i guasti attraverso uno stack completo, da un byte di stringa a una routine ROM, una variabile di sistema, un indirizzo di memoria e una cella di visualizzazione. Pochi sistemi moderni consentono quel livello di ispezione.

La prossima azione più utile è semplice: riprodurre il banner, cambiare un’ipotesi e osservare cosa si rompe. Spostare il codice, modificare il terminatore, lasciare attivo un attributo, selezionare il canale sbagliato o testare un’altra ROM. Il momento su Hacker News passerà, ma quegli esperimenti preservano la vera lezione: un’interfaccia è definita tanto dal suo stato e dai suoi effetti collaterali quanto dal punto d’ingresso che un programmatore richiama.

 
 

Inizia gratis

Un assistente IA local-first con gestione della conoscenza personale

Per una migliore esperienza con l’IA,

al momento remio supporta solo Windows 10+ (x64) e M-Chip Macs.

Il tuo partner AI al lavoro
Fai di più con remio

Pianifica. Crea. Consegna.
Tutto in un unico posto.

bottom of page