MZ-80A RomDisk — Guida per Sviluppatori
Guida per Sviluppatori del RomDisk
Questa guida e' una presentazione dettagliata del codice sorgente del firmware del PCB Sharp MZ-80A RomDisk e dell'ambiente di sviluppo. Spiega i concetti del linguaggio assemblativo Z80 per sviluppatori che potrebbero non avere familiarita' con il linguaggio, descrive in dettaglio il meccanismo di commutazione banchi specifico del RomDisk, attraversa ogni modulo sorgente e mostra come aggiungere nuovi comandi, aggiungere nuove varianti hardware SPI e fare il debug del firmware su hardware reale.
Il firmware RomDisk e' una variante del Rom Filing System (RFS). Salvo diversa indicazione, tutte le descrizioni qui si applicano a compilazioni con
BUILD_ROMDISK EQU 1 in rfs_definitions.asm. Per l'architettura hardware e i dettagli di costruzione del PCB vedere la pagina hardware del RomDisk. Per l'uso lato utente vedere il Manuale Utente RFS.
Introduzione all'Assemblatore Z80 per Non-Programmatori Assembly
L'intero firmware RomDisk e' scritto in linguaggio assemblativo Z80 -- il linguaggio nativo del processore Zilog Z80 utilizzato nella serie Sharp MZ. A differenza dei linguaggi ad alto livello, l'assembly si mappa quasi direttamente sull'hardware fisico: ogni istruzione viene tradotta in uno o pochi byte che la CPU esegue direttamente.
Registri
Lo Z80 non ha "variabili" -- invece ha un piccolo insieme di registri (locazioni di memoria veloce all'interno della CPU). I piu' comunemente usati in RFS:
| Register | Size | Role |
|---|---|---|
| A | 8-bit | Accumulator — the primary register for arithmetic, logic, and I/O operations. Almost every instruction involves A. |
| B, C | 8-bit | General purpose. BC together forms a 16-bit pair, commonly used as a loop counter or byte count. |
| D, E | 8-bit | General purpose. DE together is a 16-bit pair, commonly used as a source or destination pointer. |
| H, L | 8-bit | General purpose. HL together is the main 16-bit memory pointer — most memory read/write instructions use HL. |
| IX, IY | 16-bit | Index registers — used for base+offset memory addressing. Slower than HL but convenient for structured data. |
| SP | 16-bit | Stack Pointer — points to the top of the call stack. PUSH and POP use SP automatically. |
| PC | 16-bit | Program Counter — the address of the current instruction. Incremented automatically; modified by jumps and calls. |
| F | 8-bit | Flags register — individual bits set by arithmetic operations: Z (zero), C (carry), S (sign), P/V (parity/overflow). |
LD dest, src-- Caricare (copiare) dati.LD A, Bcopia B in A.LD A, (HL)legge il byte all'indirizzo di memoria contenuto in HL in A.LD (0x1200), Ascrive A all'indirizzo di memoria 0x1200.CALL addr-- Chiamare una subroutine. Mette l'indirizzo di ritorno sullo stack e salta aaddr. Equivalente a una chiamata di funzione.RET-- Ritorno dalla subroutine. Preleva l'indirizzo di ritorno dallo stack e vi salta.JP addr-- Salto incondizionato aaddr.JP Z, addrsalta solo se il flag Zero e' impostato.JR offset-- Salto relativo breve (-128 a +127 byte). Piu' veloce e compatto di JP per salti vicini.DJNZ offset-- Decrementare B e saltare se non zero. L'istruzione di loop canonica dello Z80.ADD A, n-- Aggiungere n ad A.SUB nsottrae.AND n,OR n,XOR n-- logica bit a bit su A.IN A, (port)-- Leggere dalla porta I/O in A.OUT (port), A-- scrivere A sulla porta I/O.PUSH rr / POP rr-- Salvare/ripristinare una coppia di registri 16 bit sullo/dallo stack.EI / DI-- Abilitare / Disabilitare gli interrupt.
Lo Z80 offre diversi modi per specificare da dove vengono o dove vanno i dati:
Sintassi dell'Assemblatore GLASS
- Immediato:
LD A, 42-- il valore e' incorporato nei byte dell'istruzione stessa. - Registro:
LD A, B-- i dati vengono da o vanno in un registro. - Indiretto (tramite HL):
LD A, (HL)-- HL contiene un indirizzo di memoria; i dati vengono letti da quell'indirizzo. - Esteso (indirizzo diretto):
LD A, (0x1200)-- l'indirizzo e' una costante letterale 16 bit nell'istruzione. - Indicizzato:
LD A, (IX+5)-- IX contiene un indirizzo base; 5 viene aggiunto per ottenere l'indirizzo effettivo.
RFS utilizza l'assemblatore GLASS Z80 (incluso come
tools/glass.jar). Principali caratteristiche sintattiche:
- I commenti iniziano con
;-- tutto a destra del punto e virgola viene ignorato. - Le etichette sono identificatori seguiti da
:. EQUdefinisce una costante:BELL EQU 007H.DB(Define Byte) inserisce byte grezzi.DW(Define Word) inserisce valori 16 bit little-endian.ORG addrimposta l'origine dell'assemblaggio.INCLUDE "file.asm"include testualmente un altro file.IF / ENDIFassemblaggio condizionale.
Albero dei Sorgenti
| Path | Contents |
|---|---|
README.md |
Top-level project overview |
schematics/ |
KiCad schematics for PCB v1.1, v2.0, v2.1 |
pcb/ |
KiCad PCB layout files |
software/RFS/ |
RFS firmware submodule |
software/RFS/asm/ |
All Z80 assembly source files |
software/RFS/tools/ |
Build scripts and GLASS assembler (glass.jar) |
software/RFS/build.sh |
Top-level build script |
I file sorgente assemblatore e i loro ruoli:
| File | Bank | Role |
|---|---|---|
rfs.asm |
User ROM Bank 0 | Entry point, command table, bank-switch stubs, jump table |
rfs_bank1.asm |
User ROM Bank 1 | Floppy disk controller |
rfs_bank2.asm |
User ROM Bank 2 | SD card controller (SPI driver, SDCFS) |
rfs_bank3.asm |
User ROM Bank 3 | Memory utilities (D, M, CP, T2SD, SD2T) |
rfs_bank4.asm |
User ROM Bank 4 | CMT (cassette tape) controller |
rfs_bank5.asm |
User ROM Bank 5 | Reserved / unused |
rfs_bank6.asm |
User ROM Bank 6 | Messages, help screen, ASCII↔Sharp character conversion |
rfs_bank7.asm |
User ROM Bank 7 | Memory test (R command), timer test (T command) |
rfs_mrom.asm |
Monitor ROM Bank 3 | MZF ROM scanning and loading (ROMDIR, ROMLOAD) |
cbios.asm |
Monitor ROM Bank 2 | CP/M CBIOS entry point table and ROM disk controller |
cbios_bank1–4.asm |
User ROM Banks 8–11 | CP/M CBIOS subsystems |
include/rfs_definitions.asm |
— | All configuration constants |
Configurazione: rfs_definitions.asm
Questo e' il file di configurazione centrale, incluso da ogni altro file sorgente tramite
Target di Compilazione e Flag SPI
INCLUDE "rfs_definitions.asm". Ogni opzione al momento dell'assemblaggio e' controllata qui.
; SPI hardware selection — exactly ONE must be 1: HW_SPI_ENA EQU 1 ; Hardware SPI on RomDisk v2+ PCB (74HCT595/165 shift registers) SW_SPI_ENA EQU 0 ; Software bit-bang SPI via Z80 I/O port bits PP_SPI_ENA EQU 0 ; Parallel printer port SPI (v1 boards only) ; Build target — exactly ONE must be 1: BUILD_ROMDISK EQU 1 ; Build for the MZ-80A RomDisk card BUILD_SFD700 EQU 0 ; Build for the SFD-700 floppy interface BUILD_PICOZ80 EQU 0 ; Build for the picoZ80 board
Esattamente un flag
BUILD_* ed esattamente un flag SPI devono essere impostati a 1 contemporaneamente. Impostarne piu' di uno produrra' codice errato o ambiguo -- diversi blocchi condizionali in rfs_bank2.asm utilizzano catene IF/ELSE/ENDIF annidate che presuppongono l'esclusione reciproca.
Commutazione Banchi in Dettaglio
Il meccanismo di commutazione banchi del RomDisk e' fondamentalmente diverso da quello usato da TZFS. TZFS usa le modalita' di gestione memoria del CPLD tranZPUter per rimappare i range di indirizzi nell'hardware. Il RomDisk usa invece un latch fisico di banco -- un flip-flop tipo D 74HCT273 -- accessibile tramite registri I/O mappati in memoria nella parte superiore dello spazio indirizzi User ROM.
Perche' il Banking e' Necessario
Lo Sharp MZ-80A concede allo User ROM solo 2 KB di spazio indirizzi (0xE800-0xEFFF). 2 KB possono contenere solo alcune centinaia di istruzioni -- molto meno di quanto necessario per un file system, un controller floppy, un driver per scheda SD, un controller per nastro e utilita' di memoria. La soluzione consiste nel commutare fisicamente quale pagina da 2 KB di un chip Flash piu' grande e' visibile a 0xE800-0xEFFF.
Il Latch Codificato (Schede v2.0 e Successive)
I registri di selezione banco condividono linee di indirizzo con gli 8 byte superiori della Flash ROM (0xEFF8-0xEFFF). Il PCB RomDisk v2.0 ha introdotto un latch codificato per impedire commutazioni accidentali. Il latch codificato e' costruito da un contatore presettabile 74HCT191. Il software deve leggere dall'indirizzo BNKCTRLRST (0xEFF8) esattamente 16 volte per sbloccare i registri di controllo.
La Sequenza di Commutazione Banco
Una commutazione di banco completa per lo User ROM richiede i seguenti passi:
Critico: Mai Posizionare un Loop che Copra 0xEFF8-0xEFFF
- Sbloccare il latch codificato: Leggere esattamente 16 volte dall'indirizzo BNKCTRLRST (0xEFF8).
- Scrivere il numero di banco: Scrivere il numero di banco desiderato in BNKSELUSER (0xEFFE).
- Ribloccare il latch: Leggere una volta da BNKCTRLDIS (0xEFF9).
Questo e' il vincolo di implementazione piu' importante nell'intero codice RomDisk. La regola e' semplice: nessuna istruzione di loop (
Formato della Tabella dei Comandi (rfs.asm)
DJNZ, JR, JP) deve avere il suo target di salto o i propri byte di opcode/operando all'interno di 0xEFF8-0xEFFF.
Il dispatcher dei comandi del monitor in
rfs.asm utilizza una tabella di comandi compatta. Ogni voce descrive un comando ed e' strutturata come segue:
; One command table entry: ; DB FLAGS ; 1 byte: END|MATCH|BANK[5:3]|SIZE[2:0] ; DB "COMMAND" ; SIZE bytes: the command string ; DW HANDLER_ADDR ; 2 bytes: address of the handler routine
Percorso dei Moduli
rfs.asm -- Dispatcher dei Comandi (User ROM Bank 0)
Ruolo: Il punto di ingresso per tutte le funzionalita' RFS. Quando il monitor SA-1510 non riconosce un comando, passa il controllo al punto di ingresso User ROM a UROMADDR (0xE800).
rfs_bank1.asm -- Controller Floppy Disk (User ROM Bank 1)
Ruolo: Implementa i comandi di avvio da floppy disk.
rfs_bank2.asm -- Controller Scheda SD (User ROM Bank 2)
Ruolo: Il sottosistema completo della scheda SD -- inizializzazione del driver SPI, protocollo di comando della scheda SD e le routine di directory e I/O file SDCFS.
rfs_bank3.asm -- Utilita' di Memoria (User ROM Bank 3)
Ruolo: Implementa i comandi D (dump esadecimale), M (modifica memoria), CP (copia memoria), T2SD (nastro a SD) e SD2T (SD a nastro).
rfs_bank4.asm -- Controller CMT (User ROM Bank 4)
Ruolo: Implementa i comandi LT/LTNX (caricamento nastro), ST (salvataggio nastro) e V (verifica nastro).
rfs_bank5.asm -- Riservato (User ROM Bank 5)
Ruolo: Attualmente riservato e non utilizzato nella compilazione RomDisk.
rfs_bank6.asm -- Messaggi e Tabelle Caratteri (User ROM Bank 6)
Ruolo: Memorizza il testo della schermata di aiuto, tutte le stringhe di messaggi di errore e stato, e la tabella di conversione del set di caratteri Sharp MZ in ASCII.
rfs_bank7.asm -- Comandi Diagnostici (User ROM Bank 7)
Ruolo: Implementa i comandi R (test DRAM) e T (test timer) nella compilazione RomDisk.
rfs_mrom.asm -- Utilita' Monitor ROM (Monitor ROM Bank 3)
Ruolo: Fornisce le routine di scansione ROM e caricamento file MZF che devono essere eseguite dallo spazio Monitor ROM piuttosto che dallo spazio User ROM.
Driver SPI: Hardware vs. Software
Il driver SPI in
rfs_bank2.asm e' implementato in tre modi, selezionati interamente al momento dell'assemblaggio. La selezione e' controllata dai tre flag mutuamente esclusivi in rfs_definitions.asm.
HW_SPI_ENA EQU 1 ; 74HCT595/74HCT165 hardware shift registers on RomDisk v2+ PCB SW_SPI_ENA EQU 0 ; Software bit-bang SPI using the RomDisk v2+ I/O port bits PP_SPI_ENA EQU 0 ; Software bit-bang SPI via the Sharp MZ-80A parallel printer port
| HW_SPI_ENA | SW_SPI_ENA | PP_SPI_ENA | |
|---|---|---|---|
| PCB required | v2.0+ | v2.0+ | v1.x |
| Approx. byte rate | ~1 µs/byte | ~30 µs/byte | ~50 µs/byte |
| Coded latch required | Yes | Yes | No |
| Additional ICs | 74HCT595, 74HCT165 | None | None |
| Suitable for | All current builds | Low-cost v2 variant | Legacy v1 boards |
Aggiungere un Nuovo Comando del Monitor
L'esempio seguente aggiunge un comando PEEK che legge e visualizza un singolo byte da un dato indirizzo. L'handler appartiene al banco 3 (utilita' di memoria).
Passo 1: Scrivere l’handler in rfs_bank3.asm
; In rfs_bank3.asm (bank 3, memory utilities):
PEEK: CALL HLHEX ; Parse 4-digit hex address from input buffer into HL
LD A,(HL) ; Read the byte at that address
CALL PRTHX ; Print A as 2 hex digits
RET
Passo 2: Aggiungere una voce nella tabella comandi in rfs.asm
DB 000H | 000H | 018H | 004H
DB "PEEK"
DW PEEK
Passo 3: Aggiungere testo di aiuto in rfs_bank6.asm
DB "PEEKXXXX - read byte at XXXX", 00DH
Passo 4: Compilare
cd /dvlp/Projects/MZ80A_RFS/software/RFS ./build.sh
Aggiungere Nuovo Supporto Hardware
Per aggiungere una nuova variante SPI hardware o portare RFS su una nuova piattaforma, seguire le istruzioni dettagliate nel file sorgente inglese originale, modificando
rfs_definitions.asm, aggiungendo blocchi di assemblaggio condizionale e aggiornando build.sh secondo necessita'.
Suggerimenti per il Debug
Abilitare l'output di debug: Impostare
ENADEBUG EQU 1 in rfs_definitions.asm prima della compilazione.
Dump dell'area di ingresso del banco User ROM 0: Digitare D E800 per fare il dump dei primi 320 byte del banco User ROM corrente.
Controllare il registro di controllo banco: Digitare D EFF8 per fare il dump dell'area del registro di controllo banco.
Verificare il conteggio di sblocco del latch codificato: Se le scritture al registro di controllo banco sembrano non avere effetto, la causa piu' comune e' che la sequenza di 16 letture non si completa.
Avvio v2.1 al monitor SA-1510 senza prompt + RFS: Se la macchina si avvia nel monitor SA-1510 nativo e la riga di accesso RFS + RFS non appare, il punto di ingresso User ROM a 0xE800 non viene chiamato.
Eseguire MEMTEST dopo l'aggiunta di dati residenti in RAM: Digitare R immediatamente dopo l'aggiunta di nuove strutture dati o variabili residenti in RAM.
Fallimenti dell'inizializzazione della scheda SD: Se i comandi SD restituiscono codici di risposta inattesi con ENADEBUG abilitato, verificare che il timing del chip select SPI sia corretto.
Fallimenti di chiamate inter-banco: Se una chiamata inter-banco sembra eseguire il codice sbagliato o ritorna con corruzione dei registri, verificare che lo stub di commutazione banco nel banco target corrisponda byte per byte a quello nel banco 0.
Siti di Riferimento
| Resource | Link |
|---|---|
| RomDisk hardware page | /sharpmz-upgrades-romdisk/ |
| RFS project page | /sharpmz-upgrades-rfs/ |
| RFS User Manual | /sharpmz-upgrades-rfs-usermanual/ |
| RFS Technical Guide | /sharpmz-upgrades-rfs-technicalguide/ |
| RFS Developer’s Guide (RFS) | /rfs-developersguide/ |
| TZFS Developer’s Guide | /tzfs-developersguide/ |
| tranZPUter FusionX page | /tranzputer-fusionx/ |
| GLASS Z80 Assembler | Bundled in software/RFS/tools/glass.jar |
| Zilog Z80 CPU User Manual | Standard datasheet — bus timing, instruction set, register reference |
| WD1773 FDC Datasheet | Western Digital — floppy disk controller I/O port reference |
| SD Card Physical Layer Spec | SD Association — CMD0/CMD8/ACMD41/CMD17/CMD24 protocol |
| Sharp MZ-80A Service Manual | Hardware schematics, SA-1510 ROM listing, memory map |