G80 Lab — Manuale d'uso
Simulatore ed ambiente di sviluppo per il processore G80 (compatibile Z80), pensato per imparare il linguaggio assembly e l’interfacciamento con le periferiche.
1. Come si apre
Sezione intitolata “1. Come si apre”| Modalità | Come | Note |
|---|---|---|
| File singolo (consigliata) | doppio clic su G80Lab.html | funziona offline, non serve installare nulla |
| Intranet / PWA | apri web/index.html da un indirizzo http(s):// | si può installare come app e resta offline |
| Server del docente | node servi.mjs → http://localhost:8080/web/index.html | per la classe, stessa rete |
Serve solo un browser moderno (Chrome, Edge, Firefox). Nessuna installazione.
2. La schermata
Sezione intitolata “2. La schermata”Colonna sinistra
- Programma (assembly): l’editor dove scrivi il programma. Sopra ci sono gli esempi preimpostati, Apri .asm… per caricare un file dal disco e Salva .asm… per scaricare il sorgente sull’ultimo file (o su un nome nuovo).
- Esecuzione: pulsanti Reset / Passo / ⌁ ciclo / Esegui-Pausa, la velocità (istruzioni per fotogramma, con i preset 🐢 lenta / ▶ normale / ⚡ veloce) e il prescaler del CTC. Sotto: registri e flag (clic su un registro per modificarne il valore, come il menu Registers del G80Sim).
- Memoria: vista a pagine da 256 byte con ◀ / ▶, Vai al PC e clic su un byte per modificarlo. Sotto, tre linguette: Dis-assembly (16 istruzioni), Instruction Trace (istruzioni eseguite, con dettaglio a scelta) e Listing (.lst) (il listato dell’assembler, come View assembly listing).
Colonna destra
- CPU — vista a blocchi: i registri interni (IR, A + flag, coppie BC/DE/HL,
IX/IY/SP/PC, MAR) e i segnali di bus dell’ultima operazione
(
MEMRQ/RD/WR/IORQ). Pulsante ⛶ modalità LIM per proiettare a schermo intero. - Micro-operazioni: la sequenza di trasferimenti che la CPU esegue per l’ultima istruzione (fetch, ALU, memoria, I/O) con il messaggio in stile simulatore originale; ▶ micro-passo scorre la sequenza, ↻ riparte.
- Periferiche: LED, display 7 segmenti, LCD, chart recorder, potenziometro, interruttori, tastiera, keypad, motore, kiln, beeper.
- Porte (port monitor): per ogni porta usata dal programma, ultima direzione, ultimo valore letto/scritto e conteggi.
- Log I/O: messaggi (breakpoint, interrupt, link, porte non standard).
3. Primo programma (5 minuti)
Sezione intitolata “3. Primo programma (5 minuti)”- Cancella l’editor e scrivi:
ld a, 0x55 ; A = 0101 0101ciclo: out (0x20), a ; mostra A sugli 8 LED inc a ; A = A + 1 jp ciclo ; ripeti- Premi Assembla & Carica (se ci sono errori, compaiono sotto i pulsanti con il numero di riga).
- Premi Esegui ▶ → i LED contano in binario.
- Premi Pausa, poi Passo per avanzare una istruzione alla volta e osservare i registri.
Suggerimento: usa Passo con la velocità al minimo per vedere come cambiano i registri.
4. Scrivere programmi (sintassi)
Sezione intitolata “4. Scrivere programmi (sintassi)”Commenti, etichette, costanti
Sezione intitolata “Commenti, etichette, costanti”; commento fino a fine rigaLEDS = 0x20 ; costante (equate)inizio: ; etichetta (indirizzo) out (LEDS), aNumeri ed espressioni
Sezione intitolata “Numeri ed espressioni”127 (decimale) · 0x1F (esadecimale) · "a" (carattere) · -1
Espressioni: + - * / & | ^ << >> ~ ( ) e differenze fra etichette (fine - inizio = lunghezza).
Direttive
Sezione intitolata “Direttive”| Direttiva | Uso | Esempio |
|---|---|---|
.org | indirizzo di partenza | .org 0x0100 |
.seg NOME (abs|rel) | segmento assoluto o rilocabile | .seg CODE (rel) |
.db | byte | .db 0x0A |
.dw | parola a 16 bit (indirizzo) | .dw servizio |
.ds | riserva N byte | .ds 6 |
.ascii | stringa | .ascii /Ciao/ oppure .ascii "a" |
.globl | esporta un simbolo (per il linking) | .globl valore |
.if / .else / .endif | assembly condizionale | .if VERSIONE |
Istruzioni
Sezione intitolata “Istruzioni”Tutte le istruzioni Z80 documentate (LD, ADD, JP, CALL, RST, IN/OUT, LDIR, …) e i prefissi
CB/ED/DD/FD (indici IX/IY, indirizzamento (IX+5)).
5. Eseguire e controllare
Sezione intitolata “5. Eseguire e controllare”| Comando | Cosa fa |
|---|---|
| Reset | ricarica il programma dall’inizio |
| Passo ▶︎| | esegue una istruzione |
| ⌁ ciclo | avanza di una micro-operazione (pannello Micro-operazioni); a fine sequenza esegue la prossima istruzione |
| Esegui ▶ / Pausa ⏸ | esegue in continuazione |
| velocità | quante istruzioni per fotogramma (più alto = più veloce); preset 🐢 300 / ▶ 5000 / ⚡ 20000, la scelta viene ricordata |
| breakpoint | campo indirizzo + Imposta/Rimuovi, oppure clic su una riga del disassemblaggio |
Il programma si ferma quando: arriva a HALT, incontra un breakpoint, o esegue un’istruzione
illegale per il G80 (compare un messaggio nel log).
Per togliere un breakpoint: clic di nuovo sulla riga rossa, oppure ✕ Togli breakpoint, oppure rimetti lo stesso indirizzo e premi Imposta/Rimuovi. C’è un solo breakpoint alla volta.
6. Registri e flag
Sezione intitolata “6. Registri e flag”| Registro | Significato |
|---|---|
A | accumulatore (risultati, I/O) |
F | flag |
B C D E H L | registri generali (a coppie: BC, DE, HL) |
PC | prossima istruzione |
SP | puntatore allo stack |
IX, IY | registri indice |
I | byte alto dei vettori di interrupt (IM2) |
R | contatore di refresh (solo in modalità Z80) |
Flag mostrati come S Z 5 H 3 V N C:
S segno · Z zero · H half-carry · V overflow/parità · N sottrazione · C carry.
(Verde = flag attivo.)
7. Memoria, disassemblaggio, trace e vista CPU
Sezione intitolata “7. Memoria, disassemblaggio, trace e vista CPU”- Pagine da 256 byte:
◀ 256/256 ▶; scrivi un indirizzo nel campo per saltare; Vai al PC. - Clic su un byte → inserisci il nuovo valore esadecimale (utile per modificare dati a runtime).
- Il byte del PC è evidenziato in verde, il breakpoint in rosso.
- Dis-assembly (linguetta): il disassemblaggio delle istruzioni a partire dall’indirizzo visualizzato — clic su una riga = imposta/togli breakpoint.
- Instruction Trace (linguetta): registro delle istruzioni eseguite, una riga per
istruzione: indirizzo, byte, disassemblaggio, registri (
A,BC,DE,HL,F) e T-state consumati. Per capire come funziona un’istruzione: mettila in un programma, premi Passo e leggi la riga. Il trace si riempie usando Passo o quando la linguetta è attiva; pulisci trace lo svuota (massimo 500 righe, le più vecchie escono). Con messaggi si sceglie il dettaglio: solo istruzioni, + fetch, + micro-operazioni. - Listing (.lst) (linguetta): il listato completo dell’assembler (indirizzi, byte, sorgente), come View assembly listing del G80Sim; con il multi-file mostra la link map.
- CPU — vista a blocchi (pannello a destra): mostra il “dentro” del processore, come la
plancia del simulatore originale:
- IR = opcode dell’istruzione in esecuzione; A e i flag; le coppie BC/DE/HL; IX/IY/SP/PC; MAR = ultimo indirizzo comparso sul bus;
- i segnali di bus (
MEMRQ,RD,WR,IORQ) si accendono secondo l’ultima operazione: fetch istruzione, lettura/scrittura memoria, IN/OUT; - sotto il riquadro: l’ultima operazione di bus, la prossima istruzione (a
PC) e lo stato (IM,IFF1,R,HALT); - ⛶ modalità LIM: ingrandisce il pannello a tutto schermo (per proiettare) e mostra una barra di comandi integrata: Reset, Passo, ⌁ ciclo, Esegui/Pausa, micro-passo, chiudi. Scorciatoie da tastiera in modalità LIM: Spazio = Passo, C = ciclo, R = Esegui/Pausa, Esc = chiudi.
- Micro-operazioni (pannello sotto la vista CPU): per l’ultima istruzione eseguita mostra
il messaggio
Execute instruction with op code 3E: LD A, ne la sequenza delle micro-operazioni: fetch (PC → MAR,M[MAR] → MDR,MDR → IR,PC + 1 → PC) seguita dai passi di esecuzione (operando, ALU, scritture in memoria, I/O). Con ▶ micro-passo si evidenzia una micro-operazione per volta; ↻ torna all’inizio. È la vista per spiegare come la CPU decodifica ed esegue una singola istruzione.
8. Periferiche (porte di I/O)
Sezione intitolata “8. Periferiche (porte di I/O)”| Porta | Periferica | Direzione | Note |
|---|---|---|---|
0x20 | 8 LED | OUT | 1 bit = 1 LED |
0x30 | Chart recorder (canale 0) | OUT | una scrittura = un campione |
0x31 | Chart — marker rosso | OUT | |
0x32, 0x33 | Chart — marker verde/blu | OUT | |
0x40 | Potenziometro | IN | slider (0‑255) |
0x60 | Beeper | OUT | segnala un beep |
0x70 | Timer (CTC): costante | OUT | |
0x71 | Timer: vettore/controllo | OUT | vettore (<0x80) poi 0x83 |
0x80 | Keypad: lettura | IN | bit7 = dato pronto, bit0‑3 = tasto 0‑F |
0x81 | Keypad: vettore/controllo | OUT | vettore poi 0x83 |
0x90 | 8 interruttori | IN | |
0xA0, 0xA1 | 2 display 7 segmenti | OUT | |
0xB0 | Motore stepper | OUT | impulso 0→1 = un passo |
0xC0 | Tastiera ASCII | IN | 0 = nessun tasto |
0xD0 | LCD 20×10 | OUT | 0x0A = nuova riga |
0xE0 | Counter/nastro: costante | OUT | |
0xE1 | Counter: vettore/controllo | OUT | vettore poi 0x83 |
0xF0 | Kiln: temperatura | IN | |
0xF1 | Kiln: controllo/stato | OUT/IN | OUT: bit0 = riscaldatore · IN: bit7 = dato pronto |
0x01, 0x03 | vettori device A/B | OUT | per gli interrupt |
Esempi rapidi
Sezione intitolata “Esempi rapidi” out (0x20), a ; accendi i LED secondo A in a, (0x90) ; leggi gli interruttori out (0xD0), a ; scrivi un carattere sul LCD in a, (0x40) ; leggi il potenziometroTempi delle periferiche
Sezione intitolata “Tempi delle periferiche”- Nastro (counter) e kiln: avanzano con il tempo reale (un passo / una lettura ogni 500 ms, come il simulatore originale).
- Timer CTC: conta i cicli della CPU; il periodo è
costante × prescaler, dove il prescaler si sceglie dalla tendina CTC (16/64/256).
9. Interrupt (IM2)
Sezione intitolata “9. Interrupt (IM2)”Schema tipico (usato dal timer, dal counter e dal keypad):
.org 0x0010VTab: .dw servizio ; tabella dei vettori (indirizzo pari)
.org 0x0100inizio: ld a, 0x08 out (0x70), a ; costante del timer ld a, VTab out (0x71), a ; byte basso del vettore ld a, 0x83 out (0x71), a ; abilita (bit0 run, bit1 interrupt) ld a, 0 ld i, a ; byte alto della tabella im 2 eiciclo: jp ciclo ; programma principale
servizio: push af ; ... fai qualcosa ... pop af ei retiRegole utili:
- il vettore si scrive prima (valore
< 0x80), poi0x83per abilitare; Ifornisce il byte alto dell’indirizzo della tabella;- nel servizio: salva i registri, esegui,
EIeRETI.
10. Più file e linking
Sezione intitolata “10. Più file e linking”Nell’editor puoi scrivere più file separati da una riga marcatore:
;=== FILE: main.asm === .globl valore .seg CODE (rel) ld a, 7 ld (valore), a .seg RAM (rel)valore: .ds 1
;=== FILE: extra.asm === .globl valore .seg CODE (rel) ld a, (valore) add a, 2 ld (valore), a haltPremendo Assembla & Carica l’app assembla ogni file e poi linka: i segmenti con lo stesso
nome vengono uniti, i simboli .globl risolti (la link map compare nel log).
11. Modalità G80 e differenze dallo Z80
Sezione intitolata “11. Modalità G80 e differenze dallo Z80”Il G80 è compatibile Z80, ma non implementa:
DAALD R,AeLD A,R- i registri half-index
IXH/IXL/IYH/IYL - l’istruzione non documentata
SLL(CB 00110xxx)
Se usi queste istruzioni, il programma si ferma con “opcode illegale” (nel log). L’hardware di interrupt dei device supporta solo IM1 e IM2.
12. Esempi ed esercizi
Sezione intitolata “12. Esempi ed esercizi”esempi/— 12 programmi commentati (LED, LCD, tastiera, keypad, timer+interrupt, motore, kiln, multi-file, progetti di riferimento del finale) +esempi/README.md.esercizi/— 6 esercizi con consegna, file di partenza (TODO) e soluzioni; leggiesercizi/README.md.
13. Problemi frequenti
Sezione intitolata “13. Problemi frequenti”| Sintomo | Causa / soluzione |
|---|---|
| ”Errori: N (riga X: …)“ | errore di sintassi a quella riga: controlla mnemonic e virgole |
| Il programma non fa nulla | manca un ciclo o un HALT; verifica con Passo |
| ”Opcode illegale” | hai usato un’istruzione non supportata dal G80 (vedi §11) |
| I LED non cambiano | controlla di aver scritto sulla porta 0x20 |
| Il LCD resta vuoto | scrivi sulla porta 0xD0; la stringa deve arrivare lì (OTIR) |
| Il programma è lentissimo | aumenta la velocità (istruzioni per fotogramma, preset ⚡ veloce) |
| I LED (o un conteggio) cambiano troppo in fretta | non è un difetto: a ⚡ 20000 il programma avanza di milioni di istruzioni al secondo. Usa 🐢 lenta (300) oppure Passo |
| Il breakpoint non si toglie | clic sulla riga rossa oppure ✕ Togli breakpoint |
| Non vedo il mio programma dopo il riavvio | il sorgente si salva in automatico; se hai aperto un altro file, ricaricalo con Apri .asm… |
| Non si installa come app | l’installazione (PWA) funziona solo aprendo da http/https, non da file |
| L’app installata mostra una versione vecchia | apri l’app con la rete attiva e ricarica: il service worker è network-first e si aggiorna da solo (al massimo riapri una volta). In casi ostinati: ricarica forzata (Ctrl+F5) o reinstalla la PWA |
14. Glossario
Sezione intitolata “14. Glossario”- Assembly: linguaggio a basso livello, una riga ≈ una istruzione della CPU.
- Assembler: traduce il sorgente in codice macchina (qui:
.ihx). - Linker: unisce più file oggetto e risolve i simboli.
- Registro: piccola memoria dentro la CPU (A, B, C, …).
- Flag: bit che descrivono l’ultimo risultato (zero, carry, …).
- Porta di I/O: indirizzo con cui si parla alle periferiche (
IN/OUT). - Interrupt: richiesta di attenzione alla CPU (qui IM2 con tabella di vettori).
- Breakpoint: indirizzo dove l’esecuzione si ferma per controllare lo stato.
- Segmento: blocco di codice/dati, assoluto (
abs) o rilocabile (rel).
G80 Lab — manuale per studenti. Aggiornato al 27/09/2026.