Sinclair ZX81 : helloWorld in Assembly

di | Marzo 13, 2026

In questo articolo viene riportato come implementare il classico helloWorld su macchina Sinclair ZX81, utilizzando il linguaggio assembler.

Normalmente, gli sviluppatori di software per cosidette macchine retrò, implementano il software su normali PC o Workstation moderne equipaggiati di relativi sistemi operativi altrettanto moderno. Una volta che il software è terminato, può essere trasferito sulla macchina target ed eseguito.

E’ necessario quindi installare sulla propria macchina di sviluppo : un Assembler che generi linguaggio macchina per l’architettura target, di un emulatore e di un editor di testo per poter editare il codice. Tutti i sistemi operativo maggiormente utilizzati dispongono di un’ampia scelta di software per poter assemblare il proprio ambiente di sviluppo. Di seguito alcuni di questi :

Sistema OperativoNome SoftwareTipologiaUltima VersioneLicenzaAnnotazione
1DOS/WindowsTASMAssembler3.2Valutazione 30 giorniUtilizzato dai nerd storici. Probabilmente è stato il primo cross-assembler liberamente utilizzabile per DOS/Windows.
2DOS/WindowseightyoneEmulatore 1.0aSoftware Libero (GNU GPL)Probabilmente il piu’ utilizzato.

Installazione di TASM Cross Assembler

In stile nerd (old-school) l’installazione di TASM (da *non* confondere con il Borland Turbo Assembler) si concretizza semplicemente nell’unzippare il file compresso.

Come riportato nella tabellina riepilogativa, il TASM CROSS Assembler non è un software libero, ma un trial che può essere utilizzato per soli 30 giorni, dopodichè la licenza (leggi README) ne vieterebbe il suo utilizzo anche continua regolarmente a funzionare. Per usufruire del diritto all’uso è necessario acquistare una licenza tramite preventiva registrazione (compilazione del modulo ORDERFRM.txt) per un costo di 40 Euro. Con l’acquisto della licenza d’uso verrà fornita il sorgente C di TASM Cross Assembler, il manuale d’uso ed un riferimento telefonico per il supporto, oltre a riceverne l’ultima versione.

TASM Cross Assembler, lo dico per completezza, supporta anche altri processori target, oltre allo Zilog Z80, di seguito una lista completa :

CPUFile con tabelle delle istruzioniDescrizione
1Zilog Z80TASM80.TABProcessore della ZILOG a 8 bit (e relativi Cloni, essendo coperto da una licenza d’uso che ne permetteva ed invogliava la replicabilità). E’ il cuore di molti computer 8 bit sin dalla fine degli anni 70 dello scorso secolo.
28048TASM48.TABMicrocontrollore di Intel delle serie MCS-48, prodotti a partire dall’anno 1976, prima dei microprocessori (CPU) a 8 bit. Appartengono a tale famiglia : 8048, 8035, 8748 Inizialmente tali microcontrollori utilizzavano tecnologia NMOS, e solo dopo il 1980 rimpiazzata da CMOS. Montavano ROM intern o esterna di pochi byte su cui risiedeva il software. Per il basso costo non scomparvero nemmeno dopo l’avvento delle CPU ad 8 bit, ma continuarono ad avere un loro mercato, ad esempio all’interno di elettrodomestici, tastiere di computer e terminali per la comunicazione seriale. Gli MCS-48 furono soppiantati da MCS-51.
38051TASM51.TABMicrocontrollore della famiglia MCS-51. Inizialmente utilizzatavo tecnologia NMOS, subito dopo rimpiazzata da CMOS (80C51). La famiglia Intel MCS-51 prodotta a partire dal 1980 migliora gli MCS-48, rendendo utilizzabili tali microcontrollori anche in elettrodomestici e macchine molto piu’ complesse. L’8051 implementa un set di istruzioni molto piu’ amplio del precedente e la possibilità di leggere e scrivere su memorie RAM, su un bus a 8 bit. L’architetto del 8051 è John H. Wharton 
46502TASM65.TABIl MOS Technology 6502 è un microprocessore a 8 bit prodotto con tecnologia NMOS, al momento conosciuta a partire dal mese di settembre del 1975 da un piccolo gruppo di persone guidate da Chuck Peddle che aveva lavorato già a Motorola sul 6800. Il 6502 semplifica, il risultato fu che era piu veloce e sei volte piu’ economico dei concorrenti (Motorola 6800, Intel 8080). Assieme allo Zilog Z80 diede vita alla rivoluzione degli Home Computer ad 8 bit. Molti console di videogiochi dagli anni 70 fino al 1990 montavano una CPU 6502, ad esempio Atari 2600, Atari a 8 bit e Lynx, Commodore 64, Apple, BBC Micro, Nintendo Entertainment System ed altri.
58085TASM85.TABL’Intel 8085 è uscito nel marzo del 1976, ed è compativole a libello di binari con Intel 8080. A differenza di questo richiede una sola alimentazione di +5V rendendolo piu’ facilmente integrabilenelle circuiterie dell’epoca, rispetto alle 2 alimentazioni 5V/12V del predecessore. Come microprocessore l’Intel 8085 fu superato dallo Zilog Z80, nonostante questo continuò ad essere prodotto e venne utilizzato come microcontrollore ad esempio nei terminali.
66805TASM05.TABIl Motorola 6805 venne prodotto nel 1975 ed è una delle variante del 6800 il cui progetto inizia nel 1971, molti di questa famiglia di microprocessori fu clonata da Hitachi. Anch’esso utilizzato come microcontrollore, in alcune varianti riportanto RAM/ROM internamente. Anche per i Motorola 68xx non ci margine in ambito prettamente informatico, negli home computer dell’epoca a 8 bit.
7TMS32010TASM3210.TABIl Texas Instruments TMS32010 è un microprocessore prodotto nel 1983. E’ una variante del TMS320, il primo della famiglia a poter utilizzare una RAM esterna, ed indirizzava a 16bit. Puoò essere programmato in C/C++ ed in linguaggio Assembler.
8TMS32025TASM3225.TABIl Texas Instruments TMS32025 è un evoluzione del TMS32010.
96800/6801TASM68.TABIl Motorola 6800/1 sono le prime versioni di un progetto che inizia nel 1971. Usato come microcontrollore, molto costoso complesso.
10TMS7000TASM7000.TABIl Texas Instruments TMS7000 è un’evoluzione del TAMS prodotto nel 2020.
118096TASM8096.TABl’Intel 8096 appartiene alla famiglia MCS-96, microcontrollori a 12MHz e 16bit

L’autore di TASM Cross Assembler è Thomas N. Anderson.

Nonostante io sia piu’ orientato ad utilizzare e ad invogliare l’uso di Software Livero (ossia coperto da licenze quali GNU GPLv3 o BSD e simili), invoglio a cui fosse interessato a questo software di acquistarne una licenza, per ripagare Thomas del lavoro fatto, riceverete i dono il codice sorgente se vorrete studiarlo. Resta il fatto che esistono altri Assembler con la licenza che piu’ vi aggrada.

Installazione di EightOne (emulatore ZX81)

Il secondo software necessario per avere un ambiente di sviluppo e run-time completo per il nostro ZX81, è l’emulatore, ossia quel software che ci permetterà di emulare a run-time al 100% la macchina target. Ho deciso di utilizzare EightOne, su suggerimento di Paul Farrow, persona che stimo molto, per il grosso lavoro fatto per questa macchina, sia dal punto di vista software che hardware.

Per installare l’emulatore eightyone (81) sarà necessario semplicemente unzipparlo

Primo Esempio : HelloClive.asm ed editor

Di seguito il listato di un primo esempio in assembler che ho creato nella directory zx81Dev/tasm/. Il programma si limita a visualizzare la scritta “hello Clive!”. E’ possibile utilizzarre un qualsiasi editor di testo, nel mio caso ho utilizzato il “vi”.

Appare un pò lunghetto perchè ho preferito commentarlo molto, essendo anche per me ad uso didattico. E’ consuetudine per gli sviluppatori assembler che sviluppano per Sinclair ZX81 utilizzare degli header standard, questo gli agevola la vita. Gli header normalmente utilizzati sono: zx81defs.asm, zx81roms.asm, charcodes.asm, zx81sys.asm, line1.asm, vars.asm, line2.asm, screen.asm ed endbasic.asm. Ne parlerò successivamente di questi header successivamente, ed in dettaglio. Nel codice di helloClive.asm ho preferito commentarli ed estrapolare da essi esclusivamente ciò che era necessario, mantenendo tutto il codice in un unico file, per una questione di leggibilità.

$ cat helloClive.asm
;/*
;.--------------------------------------------------------------------------.
;|                                                                          |
;|                                                                          |
;|     PROGRAM : HelloClive                                                 |
;|                                                                          |
;|     AUTHOR  : jack0e                                                     |
;|                                                                          |
;|     REMARK  ; My first software for Sinclair ZX81                        |
;|               Written in Assembly Language                               |
;|                                                                          |
;|     DATE    : 09/03/2026                                                 |
;|                                                                          |
;|     COMPILE : tasm -80 -b -s helloClive.asm helloClive.p                 |
;|                                                                          |
;|                                                                          |
;'--------------------------------------------------------------------------'

;               ============================================================
;               name   : zx81defs.asm
;               remark : defines to make us feel more at home
;               ------------------------------------------------------------
;               #include "zx81defs.asm"
;               ============================================================


;               ============================================================
;               name   : zx81rom.asm
;               remark : EQUs for ZX81 ROM routines
;               ------------------------------------------------------------
;               #include "zx81rom.asm"
;               ============================================================


;               ============================================================
;               name    : charcodes.asm
;               remarks : ZX81 Character code / How to survive whith ASCII
;               ------------------------------------------------------------
;
;               Sinclair Code.
;
;               Char  Code    |   Char  Code    |   Char  Code    |   Char  Code    |
;               ----- -----   |   ----- -----   |   ----- -----   |   ----- -----   |
;               blank $00     |   0     $1C     |   A     $26     |   CR    $76     |
;               "     $0B     |   1     $1D     |   B     $27     |   NULL  $FF     |
;               funt  $0C     |   2     $1E     |   C     $28     |
;               $     $0D     |   3     $1F     |   D     $29     |
;               :     $0E     |   4     $20     |   E     $2A     |
;               ?     $0F     |   5     $21     |   F     $2B     |
;               (     $10     |   6     $22     |   G     $2C     |
;               )     $11     |   7     $23     |   H     $2D     |
;               >     $12     |   8     $24     |   I     $2E     |
;               <     $13     |   9     $25     |   J     $2F     |
;               =     $14     |                 |   K     $30     |
;               +     $15                       |   L     $31     |
;               -     $16                       |   M     $32     |
;               *     $17                       |   N     $33     |
;               /     $18                       |   O     $34     |
;               ;     $19                       |   P     $35     |
;               ,     $1A                       |   Q     $36     |
;               .     $1B                       |   R     $37     |
;                                               |   S     $38
;                                               |   T     $39
;                                               |   U     $3A
;                                               |   V     $3B
;                                               |   W     $3C
;                                               |   X     $3D
;                                               |   Y     $3E
;                                               |   Z     $3F
;
;               ------------------------------------------------------------
;               #include "charcodes.asm"
;               ============================================================


;               =============================================================
;               Name   ; zx81sys.asm
;               Remark : Definition System variables
;               -------------------------------------------------------------
;               #include "zx81sys.asm"
;               =============================================================
                .ORG  16393                      ; Origin of a ZX81 file is always 16393

;               /*
;               .-----------------------------------------------------------.
;               |           SYSTEM VARIABLE of the Sinclair ZX81            |
;               |             memory byte from 16384 to 16508               |
;               '-----------------------------------------------------------' */
;ERROR_NR
;FLAGS
;ERR_SP
;RAMTOP
;MODE
;PPC
VERSN:          .BYTE 0
E_PPC:          .WORD 2
D_FILE:         .WORD Display
DF_CC:          .WORD Display+1                  ; First character of display
VARS:           .WORD Variables
DEST:           .WORD 0
E_LINE:         .WORD BasicEnd
CH_ADD:         .WORD BasicEnd+4                 ; Simulate SAVE "X"
X_PTR:          .WORD 0
STKBOT:         .WORD BasicEnd+5
STKEND:         .WORD BasicEnd+5                 ; Empty stack
BREG:           .BYTE 0
MEM:            .WORD MEMBOT
UNUSED1:        .BYTE 0
DF_SZ:          .BYTE 2
S_TOP:          .WORD $0002                      ; Top program line number
LAST_K:         .WORD $fdbf
DEBOUN:         .BYTE 15
MARGIN:         .BYTE 55
NXTLIN:         .WORD Line2                      ; Next line address
OLDPPC:         .WORD 0
FLAGX:          .BYTE 0
STRLEN:         .WORD 0
T_ADDR:         .WORD $0c8d
SEED:           .WORD 0
FRAMES:         .WORD $f5a3
COORDS:         .WORD 0
PR_CC:          .BYTE $bc
S_POSN:         .WORD $1821
CDFLAG:         .BYTE $40
PRBUFF:         .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$76  ; 32 Spaces + Newline
MEMBOT:         .BYTE 0,0,0,0,0,0,0,0,0,0,$84,$20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0      ; 30 zeros
UNUNSED2:       .WORD 0


;.===========================================================.
;|                       MAIN Function                       |
;'==========================================================='
;main()
;{
;               =============================================
;               name   : line1.asm
;               remark : Standard REM statement will
;                        contain our 'hex' code.
;                        line1 | This is the REM statement.
;                        example statement :
;                        00 00 39 00 EA
;                                    XX
;                              X===X  ^
;                        X===X   ^    '---- REM
;                          ^     '--------- Lenght Code
;                          '--------------- 00 00
;
;               ---------------------------------------------
;               #include "line1.asm
;               =============================================
Line1:          .BYTE $00,$00               ; Line 1
                .WORD Line1End-Line1Text    ; Line 1 length
Line1Text:      .BYTE $ea                   ; REM


;               +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;               The UserCode starts here and gets added to the end of the REM
;               +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                ld   bc,1
                ld   de,helloClive   ; load helloString to DE register
                call printf          ; print helloString

                ld   bc,64           ;
                ld   de,author       ; load autorString to DE register
                call printf          ; print authorString

;               /*
;               .-----------------.
;               | Return to BASIC |
;               '-----------------' */
                ret
;}

;.===========================================================.
;|                      The my function                      |
;'==========================================================='

;/*
;.-----------------------------------------------------------.
;| name   : printf ;)                                        |
;| remark : display a string. Write directly to the screen.  |
;| input  ; register bc :                                    |
;|          register de : string                             |
;'-----------------------------------------------------------' */
printf

;               /*
;               .------------------------------.
;               | write directly to the screen |
;               '------------------------------' */
                ld hl,(D_FILE)
                add hl,bc
printfLoop
                ld a,(de)              ; Load in Accumulator (A) the address of string
                cp $ff                 ; Compare character for verify the endString ($ff=\0|null)
                jp z,printfEnd         ; If the character is null, goto end function
                ld (hl),a              ; If the character is *not* null load accumulator (A) to hl (hight/low) register -- string pointer
                inc hl                 ; inc hl (so display memory pointer)
                inc de                 ; inc de (so string pointer)
                jr printfLoop          ; repeat while
printfEnd
                ret


;               ================================================================
;               name   : vars.asm
;               remark : my variable
;               ----------------------------------------------------------------
;               #include "vars.asm"
;               ================================================================
;                     H   E   L   L   O   _   C   L   I   V   E   \0
helloClive      .BYTE $2D,$2A,$31,$31,$34,$00,$28,$31,$2E,$3B,$2A,$FF
;                     \CR J   A   C   K   0   E   \0
author          .BYTE $76,$2F,$26,$28,$30,$1C,$2A,$FF


;               ============================================================
;               code ends
;               ============================================================
;               name   : line2.asm
;               remark : end the REM line and put in the RAND USR line
;                        to call our 'hex code'
;               ------------------------------------------------------------
;               #include "line2.asm"
;               ------------------------------------------------------------

;               /*
;               .---------------------------------------.
;               | This is the end of line 1 - the REM   |
;               '---------------------------------------' */
                .BYTE $76                        ; Newline

;               /*
;               .---------------------------------------.
;               | Followed by the the RAND USR line.    |
;               '---------------------------------------' */
Line1End



Line2           .BYTE $00,$0a
                .WORD Line2End-Line2Text
Line2Text       .BYTE $F9,$D4                    ; RAND USR
                .BYTE $1D,$22,$21,$1D,$20        ; 16514
                .BYTE $7E                        ; Number
                .BYTE $8F,$01,$04,$00,$00        ; Numeric encoding
                .BYTE $76                        ; Newline
Line2End


;               ============================================================
;               ZX81 Screen Definition
;               ============================================================
;               name   : screen.asm
;               remark : Display file definition (24x32+CR) - lowres
;               ------------------------------------------------------------
;               #include "screen.asm"
;               ------------------------------------------------------------
Display         .BYTE $76
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 0
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 1
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 2
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 3
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 4
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 5
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 6
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 7
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 8
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 9
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 10
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 11
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 12
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 13
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 14
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 15
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 16
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 17
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 18
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 19
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 20
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 21
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 22
                .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76 ; Line 23

;               ============================================================
;               ZX81 Screen Definition
;               ============================================================
;               name   : endbasic.asm
;               remark : Close out the basic program structure
;                        BASIC Variable Area
;               ------------------------------------------------------------
;               #include "endbasic.asm"
;               ------------------------------------------------------------
Variables:
VariablesEnd:   .BYTE $80
BasicEnd:

#END


Compilazione del codice.

Per la compilazione del codice ho usato i seguente script :

a cui bisogna dar i permessi di esecuzione, dopodichè eseguirlo :

Se la compilazione termina correttamente, nel mio caso si, viene creato l’eseguibile, ma vediamo nel dettaglio i 3 file generati dal TASM Cross Assembler (.sym, .p, .lst) nella fase di compilazione,

Il file helloClive.P è l’eseguibile per ZX81, che andremo successivamente ad eseguire nell’emulatore.

Esecuzione di helloClive con EightyOne (hardware virtuale)

Per eseguire helloClive.p su macchina virtuale, è estremamente semplice :

Va avviato l’emulatore, tramite l’esecuzione di EightyOne.exe

Tramite la funzione File > OpenTape selezionato il file da eseguire (helloClive.p)

Ottenere in output, il nostro helloWord!

Verificato che tutto funzioni come previsto, possiamo eseguire il nostro codice su hardware reale.

Esecuzione di helloClive su ZX81 (hardware reale)

Il file helloClive.p è un formato audio, lo stesso utilizzato per i nastri magnetici utilizzati negli anni 80, prima dell’avvento delle unità di memorizzazione di massa diffuso dopo la metà degli anni 80 con i primi home computer a 16bit. Non avendoci un registratore a nastri su cui riversare l’eseguibile (helloClive.p), ho deciso di utilizzare un software che legge tali file e genera un output sonoro come farebbe un normale registratore di nastri musicali. Quindi per prima cosa ho trasferito il file helloClive.p sul mio cellullare Android. Nel mio caso il trasferimento l’ho eseguito tramite posta elettronica, ma sarebbe stato possibile farlo anche tramite bluetooth o altro metodo.

Ho installato sullo smartphone un lettore di file .P, ad esempio PlayZX, che trovate sullo store ufficiale di Android. L’omino che saluta, che vedete come icona di PlayZX è lui, il caro zio Clive.

Nella sezione local è possibile selezionare il nostro file helloClive.P e suonarlo tramite il tringolo, che simboleggia il PLAY. Se lo fate sentirete il sonoro del nostro helloWorld, che vi farà riassaporare l’informatica casalinga negli anni 80.

Ora, non ci resta che posizionare sul banco da lavoro lo ZX81, e collegare a computer spento l’uscita cuffie del cellulare all’ingresso audio dello ZX81 (denominato qui sempre come EAR), tramite un cavo mono. Nel mio caso il cavo era mono ad etrambi i capi, quindi anche sull’uscita del player (smartphone o chromebook) nativamente stereo.

Dopo dopo aver fatto collegato tutto, ho alimentato il Sinclair ZX81, ed inserito il comando :

LOAD ""

A quel punto ho dato il PLAY. In quel preciso momento lo ZX81 ho smesso di inviare il segnale al monitor. Dopo un 20 secondi, a fine riproduzione audio, lo ZX81 eseguito il codice ricevuto, visualizzando nella TV/Monitor il messaggio di helloWorld.

Premendo INVIO (NewLine) + qualcosa altro, che non ho ben capito, forse BREAK o LIST, mi ha presentato il pseudo listato BASIC che esegue al termine il mio codice macchina, tramite l’esecuzione della riga :

10 RAND USR 16514

La riga 0, invece, non è facilmente interpretabile. Di sicuro è generata (nel sorgente assembler) dai blocchi LINE1 e LINE2, che avvolgono il mio BODY in cui è contenuto il codice applicativo. Rappresentano la modalità fornita dagli ingegneri Sinclair per eseguire con codice assembler da SO/Basic.

Un altro aspetto da approndire è il seguente : nella versione attuale di helloClive, non faccio uso di Routine di SO (Contenute nella ROM), ma ad esempio per scrivere il messaggio a video, vado direttamente a puntare alla memoria video, e non invocando la PRINT o la PRINT-AT del Sinclair Basic. Questo slega un pò il proprio codice dal tipo di macchina, ma nello stesso tempo rende piu’ laborioso lo sviluppo. Se rendessi parametrizzabile la posizione dell’aria video, potrei far girare probabilmente helloClive su qualsiasi macchina con CPU Z80, ad esempio su Acorn-1, ZX Spectrum o macchine giapponesi MSX. Chissà!

C’è molto ancora da approfondire ! …ed è tutto molto divertente 😉

Seguiranno aggiornamenti.