MZ-80A RomDisk — Guide du Developpeur

Guide du Developpeur RomDisk

Ce guide est une presentation detaillee du code source du firmware du PCB Sharp MZ-80A RomDisk et de l'environnement de developpement. Il explique les concepts du langage assembleur Z80 pour les developpeurs qui ne connaissent pas necessairement ce langage, decrit en detail le mecanisme de commutation de banques specifique au RomDisk, parcourt chaque module source et montre comment ajouter de nouvelles commandes, ajouter de nouvelles variantes SPI materielles et deboguer le firmware sur du materiel reel.
Le firmware du RomDisk est une variante du Rom Filing System (RFS). Sauf indication contraire, toutes les descriptions ici s'appliquent aux compilations avec BUILD_ROMDISK EQU 1 dans rfs_definitions.asm. Pour l'architecture materielle et les details de construction du PCB, consultez la page materielle du RomDisk. Pour l'utilisation cote utilisateur, consultez le Manuel Utilisateur RFS.

Introduction a l'Assembleur Z80 pour les Non-Assembleurs

L'ensemble du firmware RomDisk est ecrit en langage assembleur Z80 -- le langage d'instruction natif du processeur Zilog Z80 utilise dans la serie Sharp MZ. Contrairement aux langages de haut niveau, l'assembleur correspond presque directement au materiel physique : chaque instruction est traduite en un ou quelques octets que le CPU execute directement.

Registres
Le Z80 n'a pas de "variables" -- a la place, il dispose d'un petit ensemble de registres (emplacements de stockage rapides a l'interieur du CPU). Les plus couramment utilises dans 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).

Instructions Cles
  • LD dest, src -- Charger (copier) des donnees. LD A, B copie B dans A. LD A, (HL) lit l'octet a l'adresse memoire contenue dans HL dans A. LD (0x1200), A ecrit A a l'adresse memoire 0x1200.
  • CALL addr -- Appeler un sous-programme. Empile l'adresse de retour (instruction suivante) sur la pile et saute a addr. Equivalent a un appel de fonction.
  • RET -- Retour de sous-programme. Depile l'adresse de retour de la pile et y saute.
  • JP addr -- Saut inconditionnel a addr. JP Z, addr saute uniquement si le drapeau Zero est mis (c'est-a-dire que la derniere operation a produit zero).
  • JR offset -- Saut relatif court (-128 a +127 octets). Plus rapide et plus compact que JP pour les branchements proches.
  • DJNZ offset -- Decrementer B et sauter si non zero. L'instruction de boucle canonique du Z80 : LD B, 10 / LOOP: ... / DJNZ LOOP repete 10 fois.
  • ADD A, n -- Ajouter n a A. SUB n soustrait. AND n, OR n, XOR n -- logique bit a bit sur A.
  • IN A, (port) -- Lire depuis un port I/O dans A. OUT (port), A -- ecrire A vers un port I/O. C'est ainsi que le Z80 communique avec le materiel (le controleur de disquette WD1773, les registres a decalage SPI, le latch de banque, etc.).
  • PUSH rr / POP rr -- Sauvegarder/restaurer une paire de registres 16 bits vers/depuis la pile.
  • EI / DI -- Activer / Desactiver les interruptions. Le code qui ne doit pas etre interrompu (par ex. les operations de bande temporellement critiques) est encadre entre DI et EI.

Modes d'Adressage
Le Z80 offre plusieurs facons de specifier d'ou viennent les donnees ou ou elles vont :
  • Immediat : LD A, 42 -- la valeur est integree dans les octets d'instruction eux-memes.
  • Registre : LD A, B -- les donnees viennent d'un registre ou vont dans un registre.
  • Indirect (via HL) : LD A, (HL) -- HL contient une adresse memoire ; les donnees sont lues depuis cette adresse.
  • Etendu (adresse directe) : LD A, (0x1200) -- l'adresse est une constante litterale 16 bits dans l'instruction.
  • Indexe : LD A, (IX+5) -- IX contient une adresse de base ; 5 est ajoute pour obtenir l'adresse effective. Utilise dans RFS pour acceder aux champs dans des structures de donnees a format fixe.

Syntaxe de l'Assembleur GLASS
RFS utilise l'assembleur GLASS Z80 (fourni en tant que tools/glass.jar). Principales caracteristiques syntaxiques :
  • Les commentaires commencent par ; -- tout a droite d'un point-virgule est ignore.
  • Les labels sont des identificateurs suivis de :. Un label au debut d'une ligne nomme l'adresse de l'instruction suivante.
  • EQU definit une constante : BELL EQU 007H -- l'assembleur remplace chaque occurrence de BELL par 0x07.
  • DB (Define Byte) insere des octets bruts : DB 0x41, 0x42 emet deux octets. Utilise pour les chaines, les tables de recherche et les entrees de la table de commandes.
  • DW (Define Word) insere des valeurs 16 bits en little-endian : DW HANDLER emet l'adresse du label HANDLER.
  • ORG addr definit l'origine de l'assemblage -- le code suivant est assemble comme s'il se trouvait a addr.
  • INCLUDE "file.asm" inclut textuellement un autre fichier a la position courante.
  • IF / ENDIF assemblage conditionnel : IF HW_SPI_ENA = 1 ... ENDIF -- les instructions incluses ne sont assemblees que lorsque la condition est vraie. C'est ainsi que RFS selectionne entre SPI materiel, SPI logiciel et SPI par port parallele a partir d'un seul arbre source.

Arborescence des Sources

Path Contents
README.md Top-level project overview
README_CPM.md CP/M-specific notes
schematics/ KiCad schematics for PCB v1.1, v2.0, v2.1
pcb/ KiCad PCB layout files
software/RFS/ RFS firmware submodule (also at /dvlp/Projects/RFS)
software/RFS/asm/ All Z80 assembly source files
software/RFS/asm/include/ Shared configuration and utility includes
software/RFS/tools/ Build scripts and GLASS assembler (glass.jar)
software/RFS/build.sh Top-level build script

Les fichiers source assembleur et leurs roles :

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
monitor_sa1510.asm SA-1510 Monitor ROM reference
monitor_80c_sa1510.asm SA-1510 Monitor ROM (80-column variant)
ipl.asm Initial Program Loader
include/rfs_definitions.asm All configuration constants
include/rfs_utilities.asm Shared utility macros
include/macros.asm Assembler macro definitions
include/cpm_definitions.asm CP/M CBIOS constants

Configuration : rfs_definitions.asm

C'est le fichier de configuration central, inclus par chaque autre fichier source via INCLUDE "rfs_definitions.asm". Chaque option au moment de l'assemblage est controlee ici. Les sections cles :

Cible de Compilation et Drapeaux SPI
; 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)

; Platform options:
FUSIONX_ENA   EQU 1    ; Include tranZPUter FusionX support
KUMA80_ENA    EQU 0    ; Target has Kuma 40/80 upgrade installed
VIDEOMODULE_ENA EQU 0  ; Target has 40/80 column colour video module

; 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

; Debugging:
ENADEBUG      EQU 0    ; Enable debug output during assembly (1 = enable)
Exactement un drapeau BUILD_* et exactement un drapeau SPI doivent etre mis a 1 a la fois. En activer plus d'un produira un code incorrect ou ambigu -- plusieurs blocs conditionnels dans rfs_bank2.asm utilisent des chaines IF/ELSE/ENDIF imbriquees qui supposent l'exclusion mutuelle. Lorsque FUSIONX_ENA = 1, du code supplementaire pour la gestion memoire tranZPUter FusionX est assemble dans les stubs de commutation de banque ; cela peut rester active en toute securite sur les compilations RomDisk standard car le chemin FusionX n'est pris a l'execution que lorsque du materiel FusionX est detecte.

Constantes d'Adresses
UROMADDR     EQU 0E800H          ; Base of User ROM window
UROMBSTBL    EQU UROMADDR + 020H ; Bank-switch table entry point (0xE820)
RFSJMPTABLE  EQU UROMADDR + 0B0H ; Jump table start (0xE8B0)
FDCROMADDR   EQU 0F000H          ; Floppy AFI ROM address

; Bank control registers (only accessible after coded latch unlock):
BNKCTRLRST   EQU 0EFF8H    ; Read here 16 times to unlock control registers
BNKCTRLDIS   EQU 0EFF9H    ; Read here once to re-lock (disable) control registers
HWSPIDATA    EQU 0EFFBH    ; Hardware SPI data register (read/write)
HWSPISTART   EQU 0EFFCH    ; Hardware SPI start trigger (write to begin transfer)
BNKSELMROM   EQU 0EFFDh    ; Monitor ROM bank select register
BNKSELUSER   EQU 0EFFEh    ; User ROM bank select register
BNKCTRL      EQU 0EFFFH    ; Bank control register (read/write)
Notez que BNKCTRLRST a BNKCTRL (0xEFF8-0xEFFF) partagent le meme espace d'adressage que les 8 octets superieurs de la fenetre Flash ROM. Lors de la reinitialisation, ces adresses se comportent comme des lectures Flash ROM ordinaires. Le circuit de latch code -- un compteur preselectif 74HCT191 -- doit etre deverrouille avant que les ecritures vers BNKSELMROM, BNKSELUSER ou BNKCTRL ne prennent effet. Voir la section commutation de banque ci-dessous pour la sequence de deverrouillage complete.

Definitions de Caracteres et de Controle
Les caracteres de controle ASCII standard sont definis comme des constantes nommees pour rendre le source auto-documente :
BELL    EQU 007H    ; Terminal bell
CR      EQU 00DH    ; Carriage return
LF      EQU 00AH    ; Line feed
CS      EQU 00CH    ; Clear screen (FF)
SPACE   EQU 020H    ; ASCII space
DELETE  EQU 07FH    ; Delete key

Commutation de Banques en Detail

Le mecanisme de commutation de banques du RomDisk est fondamentalement different de celui utilise par TZFS. TZFS utilise les modes de gestion memoire du CPLD tranZPUter pour remapper les plages d'adresses en materiel. Le RomDisk utilise a la place un latch de banque physique -- une bascule D 74HCT273 -- accessible via des registres I/O mappes en memoire en haut de l'espace d'adresses User ROM. La comprehension de ce mecanisme est essentielle avant de modifier tout fichier source.

Pourquoi le Banking est Necessaire
Le Sharp MZ-80A ne donne au User ROM que 2 Ko d'espace d'adressage (0xE800-0xEFFF). 2 Ko ne peuvent contenir que quelques centaines d'instructions -- loin d'etre suffisant pour un systeme de fichiers, un controleur de disquette, un pilote de carte SD, un controleur de bande et des utilitaires memoire. La solution consiste a commuter physiquement quelle page de 2 Ko d'une puce Flash plus grande est visible a 0xE800-0xEFFF. Le PCB RomDisk contient une puce Flash de 512 Ko divisee en banques de 2 Ko, avec jusqu'a 12 banques accessibles simultanement. La commutation entre elles a la demande donne effectivement a RFS 24 Ko de code ROM alors que le moniteur SA-1510 ne voit qu'une fenetre statique de 2 Ko.

Le Latch Code (Cartes v2.0 et ulterieures)
Les registres de selection de banque partagent des lignes d'adresse avec les 8 octets superieurs de la Flash ROM (0xEFF8-0xEFFF). Si le registre de selection de banque etait inscriptible en permanence, toute ecriture parasite a cette plage d'adresses -- ou meme des cycles de rafraichissement Z80 touchant cette plage -- commuterait silencieusement les banques en cours d'execution. Le PCB RomDisk v2.0 a introduit un latch code pour empecher cela.
Le latch code est construit a partir d'un compteur preselectif 74HCT191. Dans son etat par defaut (compteur pas au Terminal Count), le chemin I/O du registre de controle de banque est desactive -- les ecritures vers BNKSELMROM, BNKSELUSER et BNKCTRL n'ont aucun effet. Pour activer le chemin, le logiciel doit lire depuis l'adresse BNKCTRLRST (0xEFF8) exactement 16 fois. Chaque lecture incremente le compteur d'un. Lorsque le compteur atteint le Terminal Count (16), il active le signal d'autorisation qui active le chemin d'ecriture du registre de controle de banque.
Une fois la commutation de banque terminee, le logiciel lit une fois depuis BNKCTRLDIS (0xEFF9). Cela reinitialise le 74HCT191 a sa valeur initiale, desactivant a nouveau le chemin du registre de controle. Le latch doit etre re-deverrouille avant chaque sequence de commutation de banque subsequente.
La carte RomDisk v2.1 a ajoute une porte AND (designee D1/D2 dans le schema) pour empecher les cycles de rafraichissement DRAM du Z80 d'incrementer accidentellement le compteur. Sans cette porte, les cycles de rafraichissement periodiques du bus que le Z80 genere automatiquement pourraient incrementer le compteur par eux-memes, atteignant potentiellement le Terminal Count sans aucune action logicielle deliberee et causant des commutations de banque intempestives au demarrage.

La Sequence de Commutation de Banque
Une commutation de banque complete pour le User ROM necessite les etapes suivantes :
  1. Deverrouiller le latch code : Lire exactement 16 fois depuis l'adresse BNKCTRLRST (0xEFF8). Chaque lecture est une lecture fictive -- les donnees renvoyees sont l'octet Flash ROM a cette adresse et peuvent etre ignorees. Utilisez un compteur de boucle dans le registre B (mis a 16), mais consultez l'avertissement critique ci-dessous concernant le placement de DJNZ.
  2. Ecrire le numero de banque : Ecrire le numero de banque desire (0-7 pour les banques User ROM) dans BNKSELUSER (0xEFFE). Le 74HCT273 memorise la valeur sur le front montant du signal d'ecriture. Pour la selection de banque Monitor ROM, ecrire dans BNKSELMROM (0xEFFD) a la place.
  3. Reverrouiller le latch : Lire une fois depuis BNKCTRLDIS (0xEFF9). Cela reinitialise le compteur 74HCT191 et desactive le chemin d'ecriture du registre de controle jusqu'a la prochaine sequence de 16 lectures.
Le stub de commutation de banque dans chaque banque (commencant a UROMBSTBL, 0xE820) execute cette sequence automatiquement. Le stub sauvegarde et restaure egalement le numero de banque appelant de sorte qu'apres le retour de la routine cible, le stub puisse revenir a la banque d'origine. Comme le stub est a un decalage fixe dans chaque banque, la banque 0 peut toujours trouver le stub dans la banque 3 (ou toute autre banque) en calculant UROMBSTBL -- meme si elle n'a jamais vu les adresses internes de la banque 3.

Critique : Ne Jamais Placer de Boucle Couvrant 0xEFF8-0xEFFF
C'est la contrainte d'implementation la plus importante dans tout le code RomDisk. Le Z80 recupere les octets d'instruction en lisant depuis l'adresse du compteur de programme. Si une recuperation d'instruction ou une lecture de donnees se produit dans la plage 0xEFF8-0xEFFF, elle incremente le compteur 74HCT191. Une instruction DJNZ a, par exemple, 0xEFF7 recuperera son opcode depuis 0xEFF7 (sans effet), puis son octet de decalage depuis 0xEFF8 (incremente le compteur), et lors des iterations de boucle suivantes continuera d'incrementer le compteur a chaque passage. Si la boucle s'execute 16 fois ou plus avant toute commutation de banque intentionnelle, le compteur atteint le Terminal Count, les registres de controle deviennent actifs, et la prochaine ecriture a toute adresse dans 0xEFF8-0xEFFF effectuera une commutation de banque non intentionnelle -- remplacant instantanement le code en cours d'execution par une banque differente.
La regle est simple : aucune instruction de boucle (DJNZ, JR, JP) ne doit avoir sa cible de branchement ou ses propres octets d'opcode/operande dans 0xEFF8-0xEFFF. L'assembleur GLASS ne detecte pas et ne signale pas automatiquement cela ; c'est la responsabilite du programmeur. Lors de l'ajout de code a une banque, verifiez que le binaire assemble ne place pas d'instructions de boucle pres du haut de la fenetre de 2 Ko.

Commutation de Banque FusionX (FUSIONX_ENA = 1)
Lorsque FUSIONX_ENA = 1, les stubs de commutation de banque incluent des blocs d'assemblage conditionnel qui substituent les adresses de port de gestion memoire FusionX aux registres du latch code. Sur une carte tranZPUter FusionX, le mecanisme de pagination Flash ROM est remplace par la gestion memoire du CPLD FusionX, qui accepte les numeros de banque via un schema de port I/O different sans la sequence de deverrouillage a 16 lectures. Le jeu de commandes RFS, le systeme de fichiers SDCFS et tout le comportement visible par l'utilisateur restent identiques sur FusionX -- seules les ecritures de selection de banque de bas niveau different.

Format de la Table de Commandes (rfs.asm)
Le repartiteur de commandes du moniteur dans rfs.asm utilise une table de commandes compacte. Chaque entree decrit une commande et est structuree comme suit :
; One command table entry:
;
;   DB  FLAGS          ; 1 byte: END|MATCH|BANK[5:3]|SIZE[2:0]
;   DB  "COMMAND"      ; SIZE bytes: the command string (no null terminator)
;   DW  HANDLER_ADDR   ; 2 bytes: address of the handler routine in the named bank
;
; Flags byte bit fields:
;   Bit 7 = 1: End of table marker (last entry).
;   Bit 6 = 1: Exact match required (entire input must match; no trailing characters).
;   Bits 5:3   Bank number where HANDLER_ADDR lives (0–7 maps to User ROM banks 0–7).
;   Bits 2:0   Length of the command string in bytes (1–7).
;
; Example — the 'D' (dump) command, handler in bank 3, 1-character string:
    DB  000H | 000H | 018H | 001H    ; not-end, not-exact, bank 3 (011<<3=0x18), length 1
    DB  "D"
    DW  DUMPX
Le repartiteur lit la ligne d'entree du moniteur, parcourt la table, et pour chaque entree :
  1. Compare les premiers SIZE caracteres de l'entree avec la chaine de commande.
  2. Si le drapeau EXACT est mis, verifie egalement qu'aucun caractere non-espace ne suit.
  3. En cas de correspondance, extrait le numero de banque et l'adresse du gestionnaire de l'entree de la table.
  4. Effectue la commutation de banque vers la banque cible via le stub a UROMBSTBL.
  5. Appelle le gestionnaire avec le reste de l'entree (parametres) disponible dans le tampon d'entree du moniteur.
Notez que les entrees sont verifiees dans l'ordre -- les chaines de commandes plus longues doivent apparaitre avant leurs prefixes plus courts dans la table. Par exemple, LTNX doit preceder LT, qui doit preceder L, sinon l'entree plus courte correspondra en premier et la commande plus longue ne sera jamais atteinte.

Parcours des Modules

rfs.asm -- Repartiteur de Commandes (User ROM Bank 0)
Role : Le point d'entree pour toutes les fonctionnalites RFS. Lorsque le moniteur SA-1510 ne reconnait pas une commande, il passe le controle au point d'entree User ROM a UROMADDR (0xE800). Cette adresse est toujours la banque 0.
Sections cles :
  • Entree ROM (ROMFS, 0xE800) : Un NOP suivi d'un appel de macro qui selectionne la banque Monitor ROM 0, puis un JP pour sauter la zone de la table de commutation de banque. Au demarrage a froid (detecte en verifiant si ROMBK1 a une valeur illegale >= 8), la sequence de configuration du latch code a 16 lectures est effectuee et la zone de pile inferieure est mise a zero. Les banques MROM et UROM initiales sont ensuite selectionnees a partir de l'etat sauvegarde dans ROMBK1/ROMBK2.
  • Stub de commutation de banque (UROMBSTBL, 0xE820) : Seize passerelles d'appel inter-banques -- BKSW0to0 a BKSW0to7 -- une pour chaque transition Banque 0→N.
  • Table de sauts (RFSJMPTABLE, 0xE8B0) : Instructions JP a adresses fixes pour les fonctions que le Monitor ROM ou les hooks d'interception SA-1510 doivent appeler.
  • Table de commandes (CMDTABLE) : La liste des commandes de compilation RomDisk/picoZ80.
  • Initialisation (MONITOR → SIGNON) : Verifie la presence de la carte tranZPUter via le port I/O CPLDINFO. Definit le numero de lecteur SD initial a 0. Detecte la banque Monitor ROM active pour determiner le mode d'affichage 40 ou 80 colonnes et configure l'affichage en consequence.
  • Repartiteur de commandes (ST1X) : Lit le tampon d'entree du moniteur, parcourt CMDTABLE, extrait la banque et l'adresse du gestionnaire en cas de correspondance, appelle le stub de commutation de banque, et au retour boucle pour attendre la commande suivante. Si aucune entree ne correspond, rend le controle au moniteur SA-1510 pour qu'il affiche son erreur "?".

rfs_bank1.asm -- Controleur de Disquette (User ROM Bank 1)
Role : Implemente les commandes de demarrage par disquette. Dans la compilation RomDisk, cette banque fournit les commandes completes F (demarrage avec selection de lecteur) et f (saut direct au ROM AFI).
Fonctions cles :
  • FLOPPY (commande F) : Demande un numero de lecteur s'il n'est pas fourni sur la ligne de commande. Ecrit les octets de selection de lecteur et d'activation du moteur sur le port I/O 0xDC. Attend que le moteur de broche atteigne la vitesse de fonctionnement. Lit le secteur de demarrage, verifie l'octet de signature de disque amorcable et passe le controle au code du chargeur de demarrage.
  • FDCK (commande f) : Lit l'octet a FDCROMADDR (0xF000) pour verifier que le ROM AFI est present et non nul. S'il est trouve, appelle directement 0xF000, passant le controle au ROM de demarrage disquette SA-1510 original.

rfs_bank2.asm -- Controleur de Carte SD (User ROM Bank 2)
Role : Le sous-systeme complet de la carte SD -- initialisation du pilote SPI, protocole de commande de carte SD, et les routines de repertoire et d'I/O de fichiers SDCFS. Le code du pilote SPI est selectionne au moment de l'assemblage par les drapeaux HW_SPI_ENA, SW_SPI_ENA et PP_SPI_ENA.
Fonctions cles :
  • SDINIT : Implemente la sequence d'initialisation SPI de la carte SD.
  • SDREAD / SDWRITE : Lecture (CMD17) et ecriture (CMD24) au niveau secteur.
  • SDDIR : Lit le repertoire des premiers 8 Ko de l'image du lecteur SD actif dans un cache de repertoire resident en RAM.
  • SDLOAD : Charge les donnees d'un fichier directement a l'adresse Z80 stockee dans le champ d'adresse de chargement de l'entree du repertoire.
  • SDSAVE : Alloue un nouvel emplacement de repertoire ou trouve une entree existante avec le meme nom pour ecraser.
  • SPIINIT : Entraine la carte SD au rythme du SPI.
  • SPICS : Definit la ligne chip select de la carte SD.
  • SPIOUT : Envoie un octet A a la carte SD.
  • SPIIN : Recoit un octet de la carte SD.

rfs_bank3.asm -- Utilitaires Memoire (User ROM Bank 3)
Role : Implemente les commandes D (dump hexadecimal), M (edition memoire) et CP (copie memoire), disponibles dans toutes les compilations. Les commandes T2SD (bande vers SD) et SD2T (SD vers bande) sont egalement dans cette banque.
DUMPX (commande D) : Lit jusqu'a 20 lignes de 16 octets chacune depuis la plage d'adresses cible.
MCORX (commande M) : Editeur memoire interactif.
MCOPY (commande CP) : Copie de bloc memoire.
T2SD et SD2T : Copie bidirectionnelle bande↔SD. T2SD appelle la routine de chargement CMT de la banque 4 pour lire un fichier bande dans la RAM, puis appelle la routine SDSAVE de la banque 2 pour l'ecrire sur le lecteur SD actif. SD2T appelle SDLOAD de la banque 2 pour charger un fichier en RAM, puis appelle la routine de sauvegarde CMT de la banque 4 pour l'ecrire sur bande.

rfs_bank4.asm -- Controleur CMT (User ROM Bank 4)
Role : Implemente les commandes LT/LTNX (chargement bande), ST (sauvegarde bande) et V (verification bande).
Le Sharp MZ-80A utilise une interface cassette Kansas City Standard a 1200 bauds. Les routines de bande sont critiques en temps -- elles doivent mesurer la frequence du ton entrant et generer la forme d'onde sortante avec une precision a la microseconde.

rfs_bank5.asm -- Reserve (User ROM Bank 5)
Role : Actuellement reserve et non utilise dans la compilation RomDisk. Cet emplacement de banque est disponible pour une expansion future.

rfs_bank6.asm -- Messages et Tables de Caracteres (User ROM Bank 6)
Role : Stocke le texte de l'ecran d'aide, toutes les chaines de messages d'erreur et de statut, et la table de conversion du jeu de caracteres Sharp MZ vers ASCII.

rfs_bank7.asm -- Commandes de Diagnostic (User ROM Bank 7)
Role : Implemente les commandes R (test DRAM) et T (test temporisateur) dans la compilation RomDisk.

rfs_mrom.asm -- Utilitaires Monitor ROM (Monitor ROM Bank 3)
Role : Fournit les routines de scan ROM et de chargement de fichiers MZF qui doivent s'executer depuis l'espace Monitor ROM plutot que l'espace User ROM.
Pourquoi une banque Monitor ROM separee ? Les commandes IR et LR enumerent les images de programme MZF stockees dans les banques Flash User ROM superieures. Pour scanner l'une de ces banques, le firmware doit commuter la fenetre User ROM pour pointer vers cette banque. Mais le code de scan lui-meme reside dans le User ROM -- s'il commute la banque User ROM, il remplace instantanement son propre code par une banque differente et plante.
La solution est de placer la boucle de scan dans la banque Monitor ROM 3. La commutation de banque Monitor ROM (via BNKSELMROM) est entierement independante de la commutation de banque User ROM (via BNKSELUSER).

Pilote SPI : Materiel vs. Logiciel

Le pilote SPI dans rfs_bank2.asm est implemente de trois facons, selectionnees entierement au moment de l'assemblage. La selection est controlee par les trois drapeaux mutuellement exclusifs dans 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

SPI Materiel (HW_SPI_ENA = 1)
Disponible sur le PCB RomDisk v2.0 et ulterieur. Le PCB porte un registre a decalage serie-sortie 74HCT595 (MOSI/CLK) et un registre a decalage parallele-entree 74HCT165 (MISO/CLK) cadences par une logique materielle dediee fonctionnant a 8 MHz.

SPI Logiciel (SW_SPI_ENA = 1)
Disponible sur le PCB RomDisk v2.0 et ulterieur comme alternative a moindre cout aux registres a decalage materiels. Le firmware commute manuellement des bits individuels du registre BNKCTRL (0xEFFF).

SPI Port Parallele (PP_SPI_ENA = 1)
L'implementation originale du RomDisk v1, utilisant le port parallele Centronics de l'imprimante du Sharp MZ-80A comme bus SPI improvise.

Choix d'une Variante SPI
  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

Ajouter une Nouvelle Commande du Moniteur

L'exemple suivant ajoute une commande PEEK qui lit et affiche un seul octet depuis une adresse donnee. Le gestionnaire appartient a la banque 3 (utilitaires memoire).

Etape 1 : Ecrire le gestionnaire dans 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

Etape 2 : Ajouter une entree dans la table de commandes dans rfs.asm

; In rfs.asm, within the CMDTABLE block (inside IF BUILD_ROMDISK+BUILD_PICOZ80 = 1):
    DB  000H | 000H | 018H | 004H
    DB  "PEEK"
    DW  PEEK

Etape 3 : Ajouter le texte d’aide dans rfs_bank6.asm

; In rfs_bank6.asm, within the HELPSCR block (before the 000H terminator):
    DB  "PEEKXXXX - read byte at XXXX",    00DH

Etape 4 : Compiler

cd /dvlp/Projects/MZ80A_RFS/software/RFS
./build.sh
L'assembleur signalera une erreur si la banque 3 depasse maintenant 2 Ko. Si cela se produit, recherchez du code mort, des chaines de messages inutilisees ou des routines utilitaires dupliquees qui peuvent etre supprimees de cette banque ou deplacees vers la banque 5 (actuellement vide).

Ajouter un Nouveau Support Materiel

Ajouter une Nouvelle Variante SPI
Pour ajouter une nouvelle variante SPI materielle -- par exemple, un second design de port parallele avec des affectations de bits differentes (PP2_SPI_ENA) :
  1. Ajouter le drapeau a rfs_definitions.asm.
  2. Ajouter une assertion au debut de rfs_bank2.asm pour detecter une double activation accidentelle.
  3. Ajouter des blocs d'assemblage conditionnel dans rfs_bank2.asm pour chaque fonction SPI.
  4. Definir les nouvelles constantes de port dans rfs_definitions.asm.
  5. Mettre a jour build.sh si la nouvelle variante necessite un layout d'image Flash different.

Ajouter une Nouvelle Compilation de Plateforme
Pour porter RFS sur une nouvelle plateforme materielle :
  1. Ajouter un drapeau BUILD_* dans rfs_definitions.asm.
  2. Ajouter des constantes d'adresses si la nouvelle carte mappe les fenetres ROM a des adresses differentes.
  3. Ajouter des blocs d'assemblage conditionnel dans tout le source pour chaque point ou le comportement materiel differe.
  4. Ajouter une nouvelle variante de stub de commutation de banque dans chaque fichier de banque.
  5. Mettre a jour build.sh avec une nouvelle section de compilation.

Conseils de Debogage

Activer la sortie de debogage : Mettez ENADEBUG EQU 1 dans rfs_definitions.asm avant la compilation. Cela inclut des instructions d'impression diagnostiques supplementaires a des points strategiques.
Dumper la zone d'entree de la banque User ROM 0 : Tapez D E800 pour dumper les 320 premiers octets de la banque User ROM courante.
Verifier le registre de controle de banque : Tapez D EFF8 pour dumper la zone du registre de controle de banque.
Verifier le comptage de deverrouillage du latch code : Si les ecritures au registre de controle de banque semblent n'avoir aucun effet, la cause la plus courante est que la sequence de 16 lectures ne se termine pas.
Demarrage v2.1 vers le moniteur SA-1510 sans invite + RFS : Si la machine demarre dans le moniteur SA-1510 natif et que la ligne d'inscription RFS + RFS n'apparait pas, le point d'entree User ROM a 0xE800 n'est pas appele.
Executer MEMTEST apres l'ajout de donnees residentes en RAM : Tapez R immediatement apres l'ajout de nouvelles structures de donnees ou variables residentes en RAM.
Echecs d'initialisation de la carte SD : Si les commandes SD renvoient des codes de reponse inattendus avec ENADEBUG active, verifiez que le timing du chip select SPI est correct.
Echecs d'appels inter-banques : Si un appel inter-banque semble executer le mauvais code ou retourne avec une corruption de registres, verifiez que le stub de commutation de banque dans la banque cible correspond octet pour octet a celui de la banque 0.

Sites de Reference

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