I miei computer, console e programmi retro
Livecode
Compilatore Z80 VI
02/01/2023 17:10
Un'altra manciata di giorni e ho aggiunto gli Array, per il momento mono-dimesione.
Sia stringhe che numerici e i comandi per usarli sono ANEW, APUT e AGET.
Al momento ogni elemento di un array di numeri occupa due byte perché uso word ma
un array di stringhe occupa 256 byte estremamente esoso per un Amstrad CPC.
Sto pensando, in fase di creazione con ANEW, di poter dichiarare lo spazio massimo in byte
per elemento in maniera da ridurre il consumo di memoria.
Anche perché in questo esempio mi partono 2 interi KByte.
Come anche nel caso di PROC/FUNC il valore viene restituito tramite le variabili
globali _Value e _Value$ come succede per "it" in Livecode.

Sia stringhe che numerici e i comandi per usarli sono ANEW, APUT e AGET.
Al momento ogni elemento di un array di numeri occupa due byte perché uso word ma
un array di stringhe occupa 256 byte estremamente esoso per un Amstrad CPC.
Sto pensando, in fase di creazione con ANEW, di poter dichiarare lo spazio massimo in byte
per elemento in maniera da ridurre il consumo di memoria.
Anche perché in questo esempio mi partono 2 interi KByte.
Come anche nel caso di PROC/FUNC il valore viene restituito tramite le variabili
globali _Value e _Value$ come succede per "it" in Livecode.

Compilatore Z80 V
30/12/2022 12:25
Un'altra manciata di giorni e il compilatore cresce un'altro pochino.
Ora c'è la struttura di controllo IF/ELSE/ENDIF su più righe (alla faccia del Locomotive Basic) e
in più è possibile nidificarli. La parte più complicata, se posso dire così, è stato scrivere il codice Z80
per ogni tipo di confronto usando i salti jr ed ottimizzare il più possibile con le label.
Inoltre nel esempio uso il nuovo comando FUNC/ENDFUNC e il ciclo FOR/NEXT
Tanto per controllare che continua a funzionare tutto hahahahaha

Ora c'è la struttura di controllo IF/ELSE/ENDIF su più righe (alla faccia del Locomotive Basic) e
in più è possibile nidificarli. La parte più complicata, se posso dire così, è stato scrivere il codice Z80
per ogni tipo di confronto usando i salti jr ed ottimizzare il più possibile con le label.
Inoltre nel esempio uso il nuovo comando FUNC/ENDFUNC e il ciclo FOR/NEXT
Tanto per controllare che continua a funzionare tutto hahahahaha

Compilatore Z80 IV
10/12/2022 12:13
Credevo di scrivere molto più codice in Livecode per implementare due nuovi fondamentali comandi PROC/ENDPROC FUNC/ENDFUNC
Invece con una buona analisi, con un pugno di righe, ecco qui due istruzioni fondamentali:
case "PROC"
case "FUNC"
if gaProc[v_Token2]["Nome"] = v_Token2 then
xAbort "[ERROR] PROC/FUNC already declared"
else
put v_Token2 into gaProc[v_Token2]["Nome"] //Aggiungo il nome della procedura all'elenco
put 0 into gaProc[v_Token2]["NParametri"]
put true into gProcedura //Indica al output che si sta generando una procedura
xOutPut v_Token2&":" //Nome_procedura:
repeat for each item tVar in v_RestoTesto2
add 1 to gaProc[v_Token2]["NParametri"] //Incremento il numero di parametri
put (tVar) & comma after gaProc[v_Token2]["Parametri"] //Aggiungo
xSeNonEsisteCrea tVar,,True //Crea una variabile per ogni parametro esistente
end repeat
end if
break
case "ENDFUNC"
case "ENDPROC"
xOutPut "ret"
put false into gProcedura
break
Ovviamente poi nella fase di generazione del codice Z80 ci sono tutte le dichiarazioni delle variabili/parametri
distinguendo tra variabili testo e numeriche. Oltre alla valorizzazione della variabile di ritorno per le variabili.
Come da mia idea iniziale li dati di ritorno delle funzioni sarò contenuto nelle variabili globali _Value e _Value$
come succede per "it" in Livecode.
Invece con una buona analisi, con un pugno di righe, ecco qui due istruzioni fondamentali:
case "PROC"
case "FUNC"
if gaProc[v_Token2]["Nome"] = v_Token2 then
xAbort "[ERROR] PROC/FUNC already declared"
else
put v_Token2 into gaProc[v_Token2]["Nome"] //Aggiungo il nome della procedura all'elenco
put 0 into gaProc[v_Token2]["NParametri"]
put true into gProcedura //Indica al output che si sta generando una procedura
xOutPut v_Token2&":" //Nome_procedura:
repeat for each item tVar in v_RestoTesto2
add 1 to gaProc[v_Token2]["NParametri"] //Incremento il numero di parametri
put (tVar) & comma after gaProc[v_Token2]["Parametri"] //Aggiungo
xSeNonEsisteCrea tVar,,True //Crea una variabile per ogni parametro esistente
end repeat
end if
break
case "ENDFUNC"
case "ENDPROC"
xOutPut "ret"
put false into gProcedura
break
Ovviamente poi nella fase di generazione del codice Z80 ci sono tutte le dichiarazioni delle variabili/parametri
distinguendo tra variabili testo e numeriche. Oltre alla valorizzazione della variabile di ritorno per le variabili.
Come da mia idea iniziale li dati di ritorno delle funzioni sarò contenuto nelle variabili globali _Value e _Value$
come succede per "it" in Livecode.
Compilatore Z80 - III
02/12/2022 18:28
Da qualche giorno, nelle mie ore libere da impegni, ho ripreso il progetto del compilatore Z80.
Il nome provvisorio è NOBasicCompiler e l'unico target, per il momento, è l'Amstrad CPC.
Mancava però una procedura per salvare e ripristinare lo schermo.
Alle volte la semplicità è la strada migliore in 10 righe ecco qui le due funzioni:
_RestoreScreen: di"
ld hl,&4000"
ld de,&c000"
jr EsciSRScreen"
_SaveScreen: di"
ld hl, &c000"
ld de, &4000"
EsciSRScreen: ld bc,#4000"
ldir"
ret"
Certo manca ancora una gestione dell'area superiore ai 64KB nel caso dei modelli
6128, 6128Plus e con la presenza di espansione di memoria. Ma arriverà con il tempo.
E sopratutto mi "mangia" 16KB di memoria per salvare lo schermo, il che riduce lo
spazio dedicato al programma.
Il nome provvisorio è NOBasicCompiler e l'unico target, per il momento, è l'Amstrad CPC.
Mancava però una procedura per salvare e ripristinare lo schermo.
Alle volte la semplicità è la strada migliore in 10 righe ecco qui le due funzioni:
_RestoreScreen: di"
ld hl,&4000"
ld de,&c000"
jr EsciSRScreen"
_SaveScreen: di"
ld hl, &c000"
ld de, &4000"
EsciSRScreen: ld bc,#4000"
ldir"
ret"
Certo manca ancora una gestione dell'area superiore ai 64KB nel caso dei modelli
6128, 6128Plus e con la presenza di espansione di memoria. Ma arriverà con il tempo.
E sopratutto mi "mangia" 16KB di memoria per salvare lo schermo, il che riduce lo
spazio dedicato al programma.
AmigaGuideViewer - II
17/11/2022 17:34
La scrittura del programma è ultimata ma mi sono accorto che visto la quantità di guide scritte negli anni e utilizzando sia un semplice editor di testi che programmi apposta non tutte le guide sono uguali. Alcune i NODE sono ta apici alcuni senza, alcuni separati solo da TAB. Inoltre alcuni fanno un uso molto pesante del comando SYSTEM chiamando programmi esterni, comandi di AmigaOS o immagini. Da qui la decisione di ignorarli e visualizzarli in rosso , se si clicca sopra appare il Token o comando.
AmigaGuideViewer
26/10/2022 19:18
Installando la versione 3.0 di CanDo sul mio Amiga 600 mi sono ritrovato, dopo più di vent'anni di non utilizzo, a consultare continuamente la guida su Amiga. Cosa un poco scomoda ora che ci si è abituati bene con schermi enormi possibilità di collegare più monitor eccetera. Quindi ho cominciato a cercare un visualizzatore di file in formato AmigaGuide per MacOs, deserto quasi assoluto. Soluzione, ho iniziato a scrivere un programma per visualizzare quel formato di file, visto anche la struttura abbastanza semplice.
Compilatore Z80 - II
20/09/2022 19:17
Oggi ho terminato di implementare alcuni comandi base del Basic nel NOBasic Compiler.
Funziona tutto, non credevo
Ora passo al progetto successivo e in futuro ottimizzerò il codice Z80
Funziona tutto, non credevo

Ora passo al progetto successivo e in futuro ottimizzerò il codice Z80

Compilatore Z80
20/08/2022 17:15
Sono passati quasi due mesi da quando ho cominciato a scrivere questo compilatore e visto che il lavoro mi occupa gran parte della giornata e mi dedico solo poche ore alla settimana sta venendo proprio bene.
I registri dello Z80 sono favolosi, Federico Faggin è proprio un genio.
Sono ancora nella fase della scrittura brutale l'ottimizzazione arriverà più avanti.
Partendo dalla sintassi del Basic che ho scritto per l'interprete trasformo il codice in istruzioni Z80 poi compilo con Pasmo e creo il file .DSK direttamente usando iDisk.
Funziona alla grande ed è velocissimo.

I registri dello Z80 sono favolosi, Federico Faggin è proprio un genio.
Sono ancora nella fase della scrittura brutale l'ottimizzazione arriverà più avanti.
Partendo dalla sintassi del Basic che ho scritto per l'interprete trasformo il codice in istruzioni Z80 poi compilo con Pasmo e creo il file .DSK direttamente usando iDisk.
Funziona alla grande ed è velocissimo.

Interprete Basic
30/06/2022 18:19
Dopo molte prove e tentativi di ottimizzare l'interprete a velocità decenti ho deciso di sospendere il progetto.
Utilizzo ora molte delle funzioni scritte e in pratica tutto il tokenizer per un compilatore Z80 / Amstrad CPC
Ecco cosa vuol dire riciclare i byte usati
Utilizzo ora molte delle funzioni scritte e in pratica tutto il tokenizer per un compilatore Z80 / Amstrad CPC
Ecco cosa vuol dire riciclare i byte usati

SECONDS e riflessioni
18/06/2022 17:47
Nuovo giorno e una nuova funzione aggiunta. Mi sono reso conto che lo schermo virtuale è comodo perché mi permetterà più avanti di cambiare quattro funzioni e adattarlo a qualsiasi output ma al costo della lentezza. Infatti la funzione odierna è SECONDS() che restituisce i secondi passati dal 1 gennaio 1970 è stata scritta proprio con lo scopo di cronometrare il tempo impiegato. Ho avuto la triste conferma con questo codice:

se visualizzo il conto alla rovescia da 100 a 1 impiega ben 12 secondi ma se metto il REM davanti a LOCATE e PRINT allora il tempo è 0 secondi ;-O
Per il momento proseguo così e poi si vedrà

se visualizzo il conto alla rovescia da 100 a 1 impiega ben 12 secondi ma se metto il REM davanti a LOCATE e PRINT allora il tempo è 0 secondi ;-O
Per il momento proseguo così e poi si vedrà

For Next e altro
16/06/2022 19:12
Eccoci qui e un'altro poco di codice è stato scritto
Aggiunto i cicli For-Next nidificati con tanto di TO e DOWNTO oltre allo STEP.
Inoltre ho creato uno schermo virtuale per l'output di 80x50 caratteri con gestione del colore tramite comando INK
la paletta di 27 colori è stata ispirata dal Amstrad CPC
ovviamente
Dimenticavo i comandi CENTER e LOCATE per posizionare il testo.
Ho parecchie idee in stile CLIPPER ma per il momento procediamo un passo alla volta.



Aggiunto i cicli For-Next nidificati con tanto di TO e DOWNTO oltre allo STEP.
Inoltre ho creato uno schermo virtuale per l'output di 80x50 caratteri con gestione del colore tramite comando INK
la paletta di 27 colori è stata ispirata dal Amstrad CPC

Dimenticavo i comandi CENTER e LOCATE per posizionare il testo.
Ho parecchie idee in stile CLIPPER ma per il momento procediamo un passo alla volta.


Cicli While
11/06/2022 18:18
Anche oggi un mattone in più nel mio interprete, prima o poi gli darò anche un nome hahaha
Ora i cicli WHILE/ENDWHILE possono essere nidificati, sono arrivato a 24, dopodiche mi sono rotto e poi avevo terminato le lettere del alfabeto per le variabili
Mentre stavo scrivendo il codice ho deciso di aggiungere tre nuovi comandi AUTOINC, AUTODEC e AUTOVAL che servono a incrementare o decrementare con un valore imposto la variabile del ciclo WHILE in maniera automatica.
Così il codice risultante sarà più pulito, forse. Inoltre ho aggiunto la possibilità di formattare automaticamente le variabili numeriche e i numeri.
Ecco un esempio…

Ora i cicli WHILE/ENDWHILE possono essere nidificati, sono arrivato a 24, dopodiche mi sono rotto e poi avevo terminato le lettere del alfabeto per le variabili

Mentre stavo scrivendo il codice ho deciso di aggiungere tre nuovi comandi AUTOINC, AUTODEC e AUTOVAL che servono a incrementare o decrementare con un valore imposto la variabile del ciclo WHILE in maniera automatica.
Così il codice risultante sarà più pulito, forse. Inoltre ho aggiunto la possibilità di formattare automaticamente le variabili numeriche e i numeri.
Ecco un esempio…

Eliminare gli spazi 
08/06/2022 18:55
Sto ampliando e migliorando il mio interprete Basic e oggi mi sono accorto di un problema legato ad una funzione che uso da tanti anni, e mi sono reso conto di essere un pollastro 
La funzione in questione è Trim, siccome in LiveCode non c'era e avevo bisogno di qualcosa minimalista la scrissi così:
function Trim pText
return word 1 to -1 of pText
end Trim
Siccome lo spazio non viene considerato tipo WORD, scrivendo in questa maniera restituisco tutte le WORD dalla prima all'ultima e se ci sono degli spazi all'inizio o alla fine li salta, geniale.
Ma c'è sempre un ma, in Basic per distinguere i tipi di variabili si usa mettere il simbolo $ alla fine del nome della variabile, cosi anche nel mio interprete Basic, se la riga è:
VAR Pollo$ = "Paolo"
PRINT "Ciao ", Pollo$ , " bentornato!"
Nella prima riga tutto bene perché Pollo$ è considerato tipo TOKEN ma se eseguo la funzione Trim nel PRINT, visto che ci sono tre segmenti separati dalla virgola e non voglio trattarli come TOKEN, mi restituisce "Pollo" perché il simbolo $ non appartiene al tipo WORD, in LiveCode il tipo WORD è una parola delimitata da uno o più spazi, tabulazioni, CR, o è racchiusa da doppi apici. Meglio tardi che mai
Così ho riscritto la funzione Trim
function Trim pData
return Ltrim(Rtrim(pData))
end Trim
function Ltrim pData
local v_i
repeat with v_i = 1 to the number of chars in pData
if char v_i of pData <> space then exit repeat
end repeat
return the char v_i to -1 of pData
end Ltrim
function Rtrim pData
local v_i
repeat with v_i = the number of chars in pData down to 1
if char v_i of pData <> space then exit repeat
end repeat
return the char 1 to v_i of pData
end Rtrim
Ovviamente si può scrivere in altri cento modi

La funzione in questione è Trim, siccome in LiveCode non c'era e avevo bisogno di qualcosa minimalista la scrissi così:
function Trim pText
return word 1 to -1 of pText
end Trim
Siccome lo spazio non viene considerato tipo WORD, scrivendo in questa maniera restituisco tutte le WORD dalla prima all'ultima e se ci sono degli spazi all'inizio o alla fine li salta, geniale.
Ma c'è sempre un ma, in Basic per distinguere i tipi di variabili si usa mettere il simbolo $ alla fine del nome della variabile, cosi anche nel mio interprete Basic, se la riga è:
VAR Pollo$ = "Paolo"
PRINT "Ciao ", Pollo$ , " bentornato!"
Nella prima riga tutto bene perché Pollo$ è considerato tipo TOKEN ma se eseguo la funzione Trim nel PRINT, visto che ci sono tre segmenti separati dalla virgola e non voglio trattarli come TOKEN, mi restituisce "Pollo" perché il simbolo $ non appartiene al tipo WORD, in LiveCode il tipo WORD è una parola delimitata da uno o più spazi, tabulazioni, CR, o è racchiusa da doppi apici. Meglio tardi che mai

Così ho riscritto la funzione Trim

function Trim pData
return Ltrim(Rtrim(pData))
end Trim
function Ltrim pData
local v_i
repeat with v_i = 1 to the number of chars in pData
if char v_i of pData <> space then exit repeat
end repeat
return the char v_i to -1 of pData
end Ltrim
function Rtrim pData
local v_i
repeat with v_i = the number of chars in pData down to 1
if char v_i of pData <> space then exit repeat
end repeat
return the char 1 to v_i of pData
end Rtrim
Ovviamente si può scrivere in altri cento modi

Hypertalk
08/06/2022 16:02
Nel mio precedente post ho parlato di HyperTalk, quella sera riflettevo che in oltre quarant'anni di programmazione ho studiato, imparato e approfondito diversi linguaggi di programmazione.Dal Basic al Clipper, passando dal Turbo Pascal al C per scribacchiare in Python ma quello a cui sono più legato, se così si può dire, è HyperTalk . Ovviamente anche la sua ultima incarnazione, Livecode. In tempi passati
in base al progetto da portare avanti si sceglieva il linguaggio più adatto come lo era anche per i computer e i sistemi nelle due ultime decadi del Ventesimo secolo. Nel 1989 circa mi fu richiesta un applicazione che doveva girare su un Mac SE con HyperCard. HyperCard è un applicazione ipertestuale che include un linguaggio di programmazione; HyperTalk. Fu amore a prima vista
Dopo qualche anno accantonai il Turbo Pascal e il Clipper per usare sempre più spesso HyperTalk. Un linguaggio chiaro, semplice e leggibile niente arzigogoli con parentesi graffe, due punti e uguale, e punti e virgole hahahahahaha La particolarità principale è che si scrive in inglese frasi di senso compiuto. Faccio un esempio, se devo prendere la prima parola di un campo è semplicissimo:
put the first word in field "Cognome" into tVariabile
E se volessi mettere la prima lettera del campo in maiuscolo:
put toUpper(the first char of field "Cognome") into the first char of field "Cognome"
Di una semplicità disarmante, e in questi trent'anni si è evoluto in un linguaggio multi piattaforma molto potente, peccato che non ci sia una versione per Z80


put the first word in field "Cognome" into tVariabile
E se volessi mettere la prima lettera del campo in maiuscolo:
put toUpper(the first char of field "Cognome") into the first char of field "Cognome"
Di una semplicità disarmante, e in questi trent'anni si è evoluto in un linguaggio multi piattaforma molto potente, peccato che non ci sia una versione per Z80

Il mio primo interprete
04/06/2022 17:17
Quasi tutti i programmatori della mia generazione, prima o poi si sono cimentati nello sviluppo di un interprete o in un compilatore. Oggi è stata la mia volta
In realtà qualche anno addietro avevo scritto un linguaggio script incluso in una applicazione che avevo sviluppato per un cliente ma questa volta è ispirato al buon vecchio linguaggio Basic. Linguaggio che tutti noi, quando abbiamo mosso i primi passi nell'uso dei nostri amati Home Computers ci siamo impegnati ad imparare, usare e abusarne
Sono alla versione 0.0.1, ho iniziato a scriverlo due ore fa. E' molto rigido e al momento mancano IF e cicli FOR ma funziona. Ho usato il buon vecchio LiveCode, linguaggio che amo, evoluzione del HyperTalk e in meno di 200 linee di codice funziona
Ecco una foto dello schermo dove per provarlo ho scritto il classico generatore dei numeri di Fibonacci.




