MZ-80A RomDisk — Guia del Desarrollador
Guia del Desarrollador del RomDisk
Esta guia es un recorrido detallado por el codigo fuente del firmware del PCB Sharp MZ-80A RomDisk y el entorno de desarrollo. Explica conceptos del lenguaje ensamblador Z80 para desarrolladores que pueden no estar familiarizados con el lenguaje, describe en profundidad el mecanismo de conmutacion de bancos especifico del RomDisk, recorre cada modulo fuente y muestra como anadir nuevos comandos, anadir nuevas variantes de hardware SPI y depurar firmware en hardware real.
El firmware del RomDisk es una variante del Rom Filing System (RFS). Salvo indicacion contraria, todas las descripciones aqui se aplican a compilaciones con
BUILD_ROMDISK EQU 1 en rfs_definitions.asm. Para la arquitectura de hardware y detalles de construccion del PCB, consulte la pagina de hardware del RomDisk. Para el uso de cara al usuario, consulte el Manual de Usuario RFS.
Introduccion al Ensamblador Z80 para No-Programadores de Assembly
Todo el firmware del RomDisk esta escrito en lenguaje ensamblador Z80 -- el lenguaje de instrucciones nativo del procesador Zilog Z80 utilizado en la serie Sharp MZ. A diferencia de los lenguajes de alto nivel, el ensamblador se mapea casi directamente al hardware fisico: cada instruccion se traduce en uno o unos pocos bytes que la CPU ejecuta directamente.
Registros
El Z80 no tiene "variables" -- en su lugar tiene un pequeno conjunto de registros (ubicaciones de almacenamiento rapido dentro de la CPU). Los mas utilizados en 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-- Cargar (copiar) datos.LD A, Bcopia B en A.LD A, (HL)lee el byte en la direccion de memoria contenida en HL hacia A.LD (0x1200), Aescribe A en la direccion de memoria 0x1200.CALL addr-- Llamar a una subrutina. Empuja la direccion de retorno (siguiente instruccion) en la pila y salta aaddr. Equivalente a una llamada de funcion.RET-- Retorno de subrutina. Saca la direccion de retorno de la pila y salta a ella.JP addr-- Salto incondicional aaddr.JP Z, addrsalta solo si el flag Zero esta activado (es decir, la ultima operacion produjo cero).JR offset-- Salto relativo corto (-128 a +127 bytes). Mas rapido y compacto que JP para ramificaciones cercanas.DJNZ offset-- Decrementar B y saltar si No es Zero. La instruccion de bucle canonica del Z80:LD B, 10 / LOOP: ... / DJNZ LOOPrepite 10 veces.ADD A, n-- Sumar n a A.SUB nresta.AND n,OR n,XOR n-- logica bit a bit sobre A.IN A, (port)-- Leer del puerto de E/S hacia A.OUT (port), A-- escribir A al puerto de E/S. Asi es como el Z80 se comunica con el hardware (el controlador de disquetes WD1773, registros de desplazamiento SPI, latch de banco, etc.).PUSH rr / POP rr-- Guardar/restaurar un par de registros de 16 bits en/desde la pila.EI / DI-- Habilitar / Deshabilitar interrupciones. El codigo que no debe ser interrumpido (por ejemplo, operaciones de cinta criticas en tiempo) se envuelve entre DI y EI.
El Z80 ofrece varias formas de especificar de donde provienen o a donde van los datos:
Sintaxis del Ensamblador GLASS
- Inmediato:
LD A, 42-- el valor esta integrado en los propios bytes de la instruccion. - Registro:
LD A, B-- los datos provienen de o van a un registro. - Indirecto (via HL):
LD A, (HL)-- HL contiene una direccion de memoria; los datos se leen de esa direccion. - Extendido (direccion directa):
LD A, (0x1200)-- la direccion es una constante literal de 16 bits en la instruccion. - Indexado:
LD A, (IX+5)-- IX contiene una direccion base; se suma 5 para obtener la direccion efectiva. Se usa en RFS para acceder a campos dentro de estructuras de datos de formato fijo.
RFS utiliza el ensamblador GLASS Z80 (incluido como
tools/glass.jar). Caracteristicas clave de la sintaxis:
- Los comentarios comienzan con
;-- todo a la derecha de un punto y coma se ignora. - Las etiquetas son identificadores seguidos de
:. Una etiqueta al inicio de una linea nombra la direccion de la siguiente instruccion. EQUdefine una constante:BELL EQU 007H-- el ensamblador reemplaza cada ocurrencia de BELL con 0x07.DB(Define Byte) inserta bytes sin procesar:DB 0x41, 0x42emite dos bytes. Se usa para cadenas, tablas de busqueda y entradas de tabla de comandos.DW(Define Word) inserta valores de 16 bits little-endian:DW HANDLERemite la direccion de la etiqueta HANDLER.ORG addrestablece el origen del ensamblaje -- el codigo subsiguiente se ensambla como si residiera enaddr.INCLUDE "file.asm"incluye textualmente otro archivo en la posicion actual.IF / ENDIFensamblaje condicional:IF HW_SPI_ENA = 1 ... ENDIF-- las instrucciones encerradas solo se ensamblan cuando la condicion es verdadera. Asi es como RFS selecciona entre SPI hardware, SPI software y SPI por puerto paralelo desde un unico arbol de fuentes.
Arbol de Fuentes
| 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 |
Los archivos fuente de ensamblador y sus funciones:
| 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 |
Configuracion: rfs_definitions.asm
Este es el archivo de configuracion central, incluido por todos los demas archivos fuente mediante
Flags de Compilacion y SPI
INCLUDE "rfs_definitions.asm". Todas las opciones en tiempo de ensamblaje se controlan aqui. Las secciones clave:
; 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)
Exactamente un flag
Constantes de Direccion
BUILD_* y exactamente un flag SPI deben estar establecidos a 1 a la vez. Establecer mas de uno producira codigo incorrecto o ambiguo -- varios bloques condicionales en rfs_bank2.asm utilizan cadenas IF/ELSE/ENDIF anidadas que asumen exclusion mutua. Cuando FUSIONX_ENA = 1, se ensambla codigo adicional para la gestion de memoria FusionX del tranZPUter en los stubs de conmutacion de banco; es seguro dejarlo habilitado en compilaciones estandar del RomDisk ya que la ruta FusionX solo se toma en tiempo de ejecucion cuando se detecta hardware FusionX.
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)
Notese que BNKCTRLRST a BNKCTRL (0xEFF8-0xEFFF) comparten el mismo espacio de direcciones que los 8 bytes superiores de la ventana de Flash ROM. Al reiniciar, estas direcciones se comportan como lecturas ordinarias de Flash ROM. El circuito de latch codificado -- un contador preseteado 74HCT191 -- debe desbloquearse antes de que las escrituras a BNKSELMROM, BNKSELUSER o BNKCTRL surtan efecto. Consulte la seccion de conmutacion de bancos a continuacion para la secuencia completa de desbloqueo.
Definiciones de Caracteres y Control
Los caracteres de control ASCII estandar se definen como constantes con nombre para hacer el codigo fuente auto-documentado:
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
Conmutacion de Bancos en Detalle
El mecanismo de conmutacion de bancos del RomDisk es fundamentalmente diferente del utilizado por TZFS. TZFS utiliza los modos de gestion de memoria del CPLD del tranZPUter para remapear rangos de direcciones en hardware. El RomDisk en cambio utiliza un latch de banco fisico -- un flip-flop tipo D 74HCT273 -- accedido a traves de registros de E/S mapeados en memoria en la parte superior del espacio de direcciones de la User ROM. Comprender este mecanismo es esencial antes de modificar cualquier archivo fuente.
Por que se Necesita la Conmutacion de Bancos
El Sharp MZ-80A solo otorga 2 KB de espacio de direcciones a la User ROM (0xE800-0xEFFF). 2 KB solo pueden contener unos pocos cientos de instrucciones -- ni de lejos suficiente para un sistema de archivos, controlador de disquetes, driver de tarjeta SD, controlador de cinta y utilidades de memoria. La solucion es conmutar fisicamente que pagina de 2 KB de un chip Flash mas grande es visible en 0xE800-0xEFFF. El PCB del RomDisk contiene un chip Flash de 512 KB dividido en bancos de 2 KB, con hasta 12 bancos accesibles a la vez. Conmutar entre ellos bajo demanda da a RFS efectivamente 24 KB de codigo ROM mientras el monitor SA-1510 solo ve una ventana estatica de 2 KB.
El Latch Codificado (Tarjetas v2.0 y Posteriores)
Los registros de seleccion de banco comparten lineas de direccion con los 8 bytes superiores de la Flash ROM (0xEFF8-0xEFFF). Si el registro de seleccion de banco fuera escribible en todo momento, cualquier escritura perdida a ese rango de direcciones -- o incluso ciclos de refresco del Z80 alcanzando ese rango -- conmutaria silenciosamente los bancos a mitad de ejecucion. El PCB RomDisk v2.0 introdujo un latch codificado para prevenir esto.
El latch codificado esta construido a partir de un contador preseteado 74HCT191. En su estado por defecto (contador no en Terminal Count), la ruta de E/S del registro de control de banco esta deshabilitada -- las escrituras a BNKSELMROM, BNKSELUSER y BNKCTRL no tienen efecto. Para habilitar la ruta, el software debe leer de la direccion BNKCTRLRST (0xEFF8) exactamente 16 veces. Cada lectura incrementa el contador en uno. Cuando el contador alcanza Terminal Count (16), activa la senal de habilitacion que activa la ruta de escritura del registro de control de banco.
Despues de completar la conmutacion de banco, el software lee de BNKCTRLDIS (0xEFF9) una vez. Esto reinicia el 74HCT191 a su valor inicial, desactivando la ruta del registro de control nuevamente. El latch debe desbloquearse de nuevo antes de cada secuencia subsiguiente de conmutacion de banco.
La tarjeta RomDisk v2.1 anadio una puerta AND (denominada D1/D2 en el esquema) para evitar que los ciclos de refresco de DRAM del Z80 incrementen accidentalmente el contador. Sin esta puerta, los ciclos periodicos de refresco del bus que el Z80 genera automaticamente podrian incrementar el contador por si solos, potencialmente alcanzando Terminal Count sin ninguna accion deliberada del software y causando conmutaciones de banco espurias durante el arranque.
La Secuencia de Conmutacion de Banco
Una conmutacion de banco completa para la User ROM requiere los siguientes pasos:
Critico: Nunca Colocar un Bucle que Abarque 0xEFF8-0xEFFF
- Desbloquear el latch codificado: Leer de la direccion BNKCTRLRST (0xEFF8) exactamente 16 veces. Cada lectura es una lectura ficticia -- el dato devuelto es el byte de la Flash ROM en esa direccion y puede descartarse. Use un contador de bucle en el registro B (establecido a 16), pero vea la advertencia critica a continuacion sobre la ubicacion del DJNZ.
- Escribir el numero de banco: Escribir el numero de banco deseado (0-7 para bancos de User ROM) en BNKSELUSER (0xEFFE). El 74HCT273 captura el valor en el flanco ascendente del strobe de escritura. Para la seleccion de banco de Monitor ROM, escribir en BNKSELMROM (0xEFFD) en su lugar.
- Re-bloquear el latch: Leer de BNKCTRLDIS (0xEFF9) una vez. Esto reinicia el contador 74HCT191 y deshabilita la ruta de escritura del registro de control hasta la proxima secuencia de 16 lecturas.
UROMBSTBL -- incluso si nunca ha visto las direcciones internas del banco 3.
Esta es la restriccion de implementacion mas importante en toda la base de codigo del RomDisk. El Z80 obtiene bytes de instruccion leyendo de la direccion del Program Counter. Si cualquier busqueda de instruccion o lectura de datos ocurre dentro del rango 0xEFF8-0xEFFF, incrementa el contador 74HCT191. Una instruccion
Conmutacion de Banco FusionX (FUSIONX_ENA = 1)
DJNZ en, digamos, 0xEFF7 buscara su opcode de 0xEFF7 (sin efecto), luego su byte de offset de 0xEFF8 (incrementa el contador), y en iteraciones subsiguientes del bucle continuara incrementando el contador en cada pasada. Si el bucle se ejecuta 16 o mas veces antes de cualquier conmutacion de banco intencional, el contador alcanza Terminal Count, los registros de control se activan, y la proxima escritura a cualquier direccion en 0xEFF8-0xEFFF realizara una conmutacion de banco no intencionada -- reemplazando instantaneamente el codigo en ejecucion con un banco diferente.
La regla es simple: ninguna instruccion de bucle (DJNZ, JR, JP) puede tener su destino de salto o sus propios bytes de opcode/operando dentro de 0xEFF8-0xEFFF. El ensamblador GLASS no detecta ni advierte automaticamente sobre esto; es responsabilidad del programador. Al anadir codigo a cualquier banco, verifique que el binario ensamblado no coloque ninguna instruccion de bucle cerca de la parte superior de la ventana de 2 KB.
Cuando
Formato de Tabla de Comandos (rfs.asm)
FUSIONX_ENA = 1, los stubs de conmutacion de banco incluyen bloques de ensamblaje condicional que sustituyen las direcciones del puerto de gestion de memoria FusionX por los registros de latch codificado. En una tarjeta tranZPUter FusionX, el mecanismo de paginacion de Flash ROM es reemplazado por la gestion de memoria del CPLD FusionX, que acepta numeros de banco a traves de un esquema de puerto de E/S diferente sin la secuencia de desbloqueo de 16 lecturas. El conjunto de comandos RFS, el sistema de archivos SDCFS y todo el comportamiento visible para el usuario permanecen identicos en FusionX -- solo difieren las escrituras de seleccion de banco de bajo nivel.
El despachador de comandos del monitor en
rfs.asm utiliza una tabla de comandos compacta. Cada entrada describe un comando y se estructura de la siguiente manera:
; 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
El despachador lee la linea de entrada del monitor, recorre la tabla, y para cada entrada:
- Compara los primeros SIZE caracteres de la entrada con la cadena del comando.
- Si el flag EXACT esta activado, verifica tambien que no hay mas caracteres no-espacio a continuacion.
- Si coincide, extrae el numero de banco y la direccion del manejador de la entrada de la tabla.
- Realiza la conmutacion de banco al banco destino a traves del stub en UROMBSTBL.
- Llama al manejador con la entrada restante (parametros) disponible en el buffer de entrada del monitor.
LTNX debe preceder a LT, que debe preceder a L, de lo contrario la entrada mas corta coincidira primero y el comando mas largo nunca sera alcanzado.
Recorrido por los Modulos
rfs.asm -- Despachador de Comandos (User ROM Bank 0)
Funcion: El punto de entrada para toda la funcionalidad RFS. Cuando el monitor SA-1510 no reconoce un comando, pasa el control al punto de entrada de la User ROM en UROMADDR (0xE800). Esta direccion es siempre el banco 0.
Secciones clave:
rfs_bank1.asm -- Controlador de Disquetes (User ROM Bank 1)
- Entrada ROM (ROMFS, 0xE800): Un NOP seguido de una llamada a macro que selecciona el Monitor ROM banco 0, luego un JP para saltar sobre el area de la tabla de conmutacion de bancos. En arranque en frio (detectado verificando si ROMBK1 tiene un valor ilegal >= 8), se realiza la secuencia de configuracion del latch codificado de 16 lecturas y se pone a cero el area inferior de la pila. Los bancos iniciales de MROM y UROM se seleccionan entonces del estado guardado en ROMBK1/ROMBK2.
- Stub de conmutacion de banco (UROMBSTBL, 0xE820): Dieciseis pasarelas de llamada entre bancos -- BKSW0to0 a BKSW0to7 -- una para cada transicion banco 0->N. Cada pasarela empuja el numero de banco de llamada y el numero de banco destino en la pila, luego llama a la secuencia comun BKSW0_0 que realiza el desbloqueo del latch codificado, escribe el nuevo banco en BNKSELUSER y salta a la direccion del manejador destino. Al retornar (BKSWRET0), el banco original se restaura mediante la misma secuencia.
- Tabla de saltos (RFSJMPTABLE, 0xE8B0): Instrucciones JP de direccion fija para funciones que el Monitor ROM o los ganchos de interceptacion del SA-1510 necesitan llamar: PRTMZF, PRTDBG, CMT_RDINF, CMT_RDDATA, CMT_WRINF, CMT_WRDATA, CMT_VERIFY, CMT_DIR, CNV_ATOS.
- Tabla de comandos (CMDTABLE): La lista de comandos de compilacion RomDisk/picoZ80. Los comandos incluyen: seleccion de unidad (0-9), modo 40/80 columnas, B (campana), BASIC, C (limpiar), CP, CPM, D (volcado), EC (borrar), F (arranque disquete), f (AFI ROM), H (ayuda), IR/IC (directorio), J (salto), LC/LR/LT y sus variantes NX (cargar SD/ROM/cinta), M (editar), P (prueba impresora), R (prueba DRAM), SD2T, SC/ST (guardar), T (prueba temporizador), T2SD, V (verificar).
- Inicializacion (MONITOR -> SIGNON): Verifica la presencia de la tarjeta tranZPUter a traves del puerto de E/S CPLDINFO. Establece el numero de unidad SD inicial a 0. Detecta el banco activo del Monitor ROM para determinar el modo de visualizacion de 40 o 80 columnas y configura la pantalla en consecuencia. En compilaciones con modulo de video, escribe el modo de visualizacion en el latch DSPCTL.
- Despachador de comandos (ST1X): Lee el buffer de entrada del monitor, recorre CMDTABLE, extrae banco y direccion del manejador ante una coincidencia, llama al stub de conmutacion de banco, y al retornar vuelve al bucle para esperar el siguiente comando. Si ninguna entrada coincide, devuelve el control al monitor SA-1510 para que pueda imprimir su error "?".
Funcion: Implementa los comandos de arranque desde disquete. En la compilacion RomDisk este banco proporciona los comandos completos F (arranque con seleccion de unidad) y f (salto directo a AFI ROM).
Funciones clave:
rfs_bank2.asm -- Controlador de Tarjeta SD (User ROM Bank 2)
- FLOPPY (comando F): Solicita un numero de unidad si no se proporciona en la linea de comandos. Escribe los bytes de seleccion de unidad y habilitacion del motor en el puerto de E/S 0xDC (el puerto de control del FDC WD1773). Espera a que el motor del eje alcance la velocidad de operacion (tipicamente 300-500 ms, medido por un bucle de retardo contado por ciclos de CPU). Lee el sector de arranque, verifica el byte de firma de disco arrancable y pasa el control al codigo del cargador de arranque encontrado en el sector.
- FDCK (comando f): Lee el byte en FDCROMADDR (0xF000) para verificar que la AFI ROM esta presente y no es cero. Si se encuentra, llama a 0xF000 directamente, entregando el control a la ROM original de arranque de disquetes del SA-1510. Es util como respaldo cuando la logica de seleccion de unidad WD1773 en FLOPPY no es necesaria.
Funcion: El subsistema completo de tarjeta SD -- inicializacion del driver SPI, protocolo de comandos de tarjeta SD y las rutinas de directorio y E/S de archivos del SDCFS. El codigo del driver SPI se selecciona en tiempo de ensamblaje por los flags HW_SPI_ENA, SW_SPI_ENA y PP_SPI_ENA.
Funciones clave:
rfs_bank3.asm -- Utilidades de Memoria (User ROM Bank 3)
- SDINIT: Implementa la secuencia de inicializacion SPI de la tarjeta SD. Desactiva chip select, llama a SPIINIT para entrenar la tarjeta al reloj SPI, luego activa chip select y envia CMD0 (GO_IDLE_STATE) con hasta SD_RETRIES intentos. En caso de exito, envia CMD8 (SEND_IF_COND) para detectar tarjetas SD v2, luego ACMD41 (SD_SEND_OP_COND) para transicionar fuera del estado idle. Maneja tarjetas SD v1, SD v2, SDHC, SDXC y MMC v3 verificando la respuesta OCR de CMD58.
- SDREAD / SDWRITE: Lectura (CMD17, READ_SINGLE_BLOCK) y escritura (CMD24, WRITE_BLOCK) a nivel de sector. SDREAD espera el token de inicio de datos (0xFE) luego lee 512 bytes al buffer RAM SDBUF. SDWRITE envia el token de inicio de datos, 512 bytes de datos y un CRC ficticio, luego espera a que se libere la senal de ocupado.
- SDDIR: Lee el directorio de los primeros 8 KB de la imagen de la unidad SD activa en una cache de directorio residente en RAM. Cada entrada de directorio tiene formato de cabecera MZF (128 bytes): tipo de archivo, nombre de archivo (17 bytes, codificacion Sharp), tamano de datos, direccion de carga, direccion de ejecucion.
- SDLOAD: Dado un numero de archivo de la cache de directorio, calcula la direccion de sector alineada a 64 KB del bloque de datos del archivo, lee los bytes del tamano de datos del archivo y los carga directamente en la direccion Z80 almacenada en el campo de direccion de carga de la entrada del directorio.
- SDSAVE: Asigna una nueva ranura de directorio o encuentra una entrada existente con el mismo nombre para sobrescribir. Escribe los campos de cabecera MZF (sector de inicio, tamano, direccion de carga, direccion de ejecucion), luego escribe los datos del archivo en el bloque de 64 KB correspondiente en la tarjeta SD.
- SPIINIT: Entrena la tarjeta SD al reloj SPI. Bajo HW_SPI_ENA, escribe 0xFF a HWSPIDATA y dispara HWSPISTART 10 veces (enviando 80 bits '1'). Bajo PP_SPI_ENA (bit-bang por puerto paralelo), conmuta la linea de reloj 80 veces con los datos en alto.
- SPICS: Establece la linea de chip select de la tarjeta SD. A = 0 activa CS (bajo), A = 0xFF desactiva CS (alto). Bajo HW_SPI_ENA, modifica los bits SDCS y BBCLK de BNKCTRL y escribe de vuelta al registro de hardware.
- SPIOUT: Envia un byte A a la tarjeta SD. Bajo HW_SPI_ENA: escribe A a HWSPIDATA y dispara HWSPISTART -- dos escrituras de memoria, aproximadamente 1 us por byte a 8 MHz de reloj SPI. Bajo PP_SPI_ENA: envio bit a bit del byte MSB-primero conmutando las lineas de reloj y datos en el puerto paralelo, 3 instrucciones OUT por bit.
- SPIIN: Recibe un byte de la tarjeta SD. Bajo HW_SPI_ENA: dispara HWSPISTART para recibir 8 bits, luego lee HWSPIDATA. Bajo PP_SPI_ENA: recibe cada bit leyendo el registro de entrada del puerto paralelo.
Funcion: Implementa los comandos D (volcado hexadecimal), M (edicion de memoria) y CP (copia de memoria), disponibles en todas las compilaciones. Los comandos T2SD (cinta a SD) y SD2T (SD a cinta) tambien estan en este banco.
DUMPX (comando D): Lee hasta 20 lineas de 16 bytes cada una del rango de direcciones destino. Para cada linea, imprime la direccion hexadecimal de 4 digitos, 16 valores hexadecimales de bytes con un espacio cada 4 bytes, y los 16 caracteres ASCII correspondientes (punto para bytes no imprimibles). El Sharp MZ utiliza una codificacion de caracteres propietaria -- el banco 6 proporciona la tabla de conversion Sharp-a-ASCII utilizada aqui.
MCORX (comando M): Editor de memoria interactivo. Presenta cada byte en secuencia mostrando la direccion y el valor hexadecimal actual. El usuario escribe un nuevo valor hexadecimal de 1 o 2 digitos y presiona Enter para escribirlo, o presiona Enter solo para dejar el byte sin cambios. Ctrl+C o la tecla de escape sale.
MCOPY (comando CP): Copia de bloque de memoria. Acepta direccion de origen, direccion de destino y conteo de bytes desde la linea de comandos como valores hexadecimales de 4 digitos. Realiza una copia hacia adelante o hacia atras segun sea necesario para manejar correctamente regiones superpuestas.
T2SD y SD2T: Copia bidireccional cinta<->SD. T2SD llama a la rutina de carga CMT del banco 4 para leer un archivo de cinta (incluyendo su cabecera MZF) en RAM, luego llama a la rutina SDSAVE del banco 2 para escribirlo en la unidad SD activa. SD2T llama a SDLOAD del banco 2 para cargar un archivo en RAM, luego llama a la rutina de guardado CMT del banco 4 para escribirlo en cinta. Ambos comandos usan los campos de la cabecera MZF (nombre de archivo, tamano, direccion de carga, direccion de ejecucion) para mantener el directorio consistente entre medios.
rfs_bank4.asm -- Controlador CMT (User ROM Bank 4)
Funcion: Implementa los comandos LT/LTNX (carga de cinta), ST (guardado en cinta) y V (verificacion de cinta).
El Sharp MZ-80A utiliza una interfaz de casete Kansas City Standard a 1200 baudios. Los bytes se codifican como rafagas de tono de 1200 Hz (bit 0) o 2400 Hz (bit 1). Las rutinas de cinta son criticas en tiempo -- deben medir la frecuencia del tono entrante y generar la forma de onda saliente con precision de microsegundos. Utilizan el Temporizador de Intervalos Programable 8253 (o bucles de retardo contados por ciclos de CPU en plataformas sin el temporizador) para medir periodos de bits. Las interrupciones se deshabilitan (
rfs_bank5.asm -- Reservado (User ROM Bank 5)
DI) durante todas las operaciones de cinta para prevenir interrupciones de temporizado.
LOADTAPE / LOADTAPENX: Lee la cabecera MZF de la cinta (128 bytes: tipo de archivo, nombre de archivo, tamano de datos, direccion de carga, direccion de ejecucion), muestra el nombre del archivo, luego lee los bytes de datos a la direccion de carga. LOADTAPE auto-ejecuta saltando a la direccion de ejecucion tras una carga exitosa; LOADTAPENX retorna al prompt de comandos RFS en su lugar.
SAVEX (comando ST): Escribe la cabecera MZF seguida de los bytes de datos en cinta. Acepta direccion de inicio, direccion de fin y direccion de ejecucion desde la linea de comandos, o solicita si no se proporcionan.
VERIFYX (comando V): Lee un archivo de cinta y lo compara byte a byte contra la RAM en la direccion de carga original. Informa cualquier discrepancia con su direccion y valores esperado/real.
El formato de cabecera MZF utilizado por las rutinas de cinta es identico al formato de entrada de directorio del SDCFS. Esto no es accidental -- es la razon por la que la copia cinta-a-SD es completamente transparente y por la que los programas cargados con LT pueden re-guardarse en tarjeta SD con SC sin ninguna conversion de cabecera.
Funcion: Actualmente reservado y sin uso en la compilacion RomDisk. La ranura del banco existe en la imagen de la Flash ROM y contiene el stub de conmutacion de banco en el offset estandar, pero no hay comandos accesibles por el usuario mapeados aqui. Este banco esta disponible para expansion futura -- por ejemplo, anadir un protocolo de transferencia XModem, un cargador hexadecimal o drivers de hardware adicionales mapeados en memoria.
rfs_bank6.asm -- Mensajes y Tablas de Caracteres (User ROM Bank 6)
Funcion: Almacena el texto de la pantalla de ayuda, todas las cadenas de mensajes de error y estado, y la tabla de conversion del juego de caracteres Sharp MZ a ASCII.
HELPSCR (comando H, aproximadamente linea 282): Una secuencia de cadenas terminadas en CR, una por linea de la pantalla de ayuda. La variante BUILD_ROMDISK lista todos los comandos del RomDisk incluyendo T2SD, SD2T, F[X], f, LC, SC, EC, IR/IC y los digitos de seleccion de unidad 0-9. La lista termina con un unico byte 000H. El comando H recorre esta lista, imprimiendo cada cadena hasta encontrar el terminador.
PRINTMSG / PRTFN: Utilidades de impresion de cadenas. PRINTMSG maneja bytes marcadores incrustados (por ejemplo, 0xFF para insertar un valor de la pila) para mensajes de diagnostico formateados. PRTFN imprime un nombre de archivo Sharp MZ (17 bytes en codificacion Sharp) como texto ASCII usando la tabla de conversion ATBL.
ATBL (tabla de conversion ASCII-a-Sharp): Una tabla de busqueda de 256 bytes que mapea codigos de caracteres ASCII a sus equivalentes Sharp MZ y viceversa. La serie Sharp MZ utiliza una codificacion de caracteres propietaria de 8 bits donde los caracteres imprimibles tienen puntos de codigo diferentes a ASCII -- muchos caracteres comunes (letras, digitos, puntuacion) estan desplazados o reordenados. Cualquier codigo que muestre un nombre de archivo almacenado en codificacion Sharp en el terminal debe pasar cada byte a traves de esta tabla.
rfs_bank7.asm -- Comandos de Diagnostico (User ROM Bank 7)
Funcion: Implementa los comandos R (prueba de DRAM) y T (prueba de temporizador) en la compilacion RomDisk.
MEMTEST (comando R): Realiza una prueba de patron de bit ambulante de escritura/verificacion a traves de todo el espacio de RAM del usuario (0x1200-0xCFFF). Escribe cada uno de los 8 patrones de un solo bit (0x01, 0x02, 0x04, ..., 0x80) en cada byte del rango, luego lee y verifica cada byte. Cualquier discrepancia se reporta con su direccion y los valores esperado/real. Ejecute este comando despues de anadir cualquier estructura de datos nueva residente en RAM para verificar que el direccionamiento es correcto antes de que las nuevas estructuras sean usadas por otro codigo.
TIMERTST (comando T): Ejerce el Temporizador de Intervalos Programable 8253 programandolo en varios modos y verificando que cuenta y expira como se espera. Util para diagnosticar maquinas donde las operaciones de cinta son poco fiables -- un comportamiento incorrecto del 8253 se manifiesta como errores sistematicos de temporizado en las mediciones de tasa de bits del CMT.
rfs_mrom.asm -- Utilidades de Monitor ROM (Monitor ROM Bank 3)
Funcion: Proporciona las rutinas de escaneo de ROM y carga de archivos MZF que deben ejecutarse desde el espacio de Monitor ROM en lugar del espacio de User ROM.
Por que un banco de Monitor ROM separado? Los comandos IR y LR enumeran imagenes de programas MZF almacenados en los bancos superiores de la Flash de User ROM (los bancos de User ROM por encima de 11 contienen programas MZF empaquetados). Para escanear uno de estos bancos, el firmware debe conmutar la ventana de User ROM para apuntar a ese banco. Pero el codigo de escaneo en si reside en la User ROM -- si conmuta el banco de User ROM, reemplaza instantaneamente su propio codigo con un banco diferente y se cuelga.
La solucion es colocar el bucle de escaneo en el Monitor ROM banco 3. La conmutacion de banco del Monitor ROM (via BNKSELMROM) es completamente independiente de la conmutacion de banco de la User ROM (via BNKSELUSER). El codigo ejecutandose en el Monitor ROM banco 3 puede ciclar libremente a traves de los bancos de User ROM 12, 13, 14... para enumerar sus cabeceras MZF sin perturbar jamas el codigo del Monitor ROM que realmente se esta ejecutando.
Funciones clave:
- ROMDIR: Escanea todos los bancos de User ROM por encima de 11, lee cada cabecera MZF de 128 bytes desde el inicio de cada banco y construye un directorio ROM residente en RAM. El directorio es usado por el comando IR para mostrar una lista de programas residentes en ROM.
- ROMLOAD: Dado un numero de archivo del directorio ROM, conmuta la ventana de User ROM al banco apropiado, lee la cabecera MZF para encontrar la direccion de carga y el tamano de datos, copia los datos del programa desde la User ROM a la direccion de carga destino en RAM, y opcionalmente salta a la direccion de ejecucion. La variante LRNX retorna al prompt de comandos RFS en lugar de auto-ejecutar.
Driver SPI: Hardware vs Software
El driver SPI en
rfs_bank2.asm esta implementado de tres formas, seleccionadas completamente en tiempo de ensamblaje. La seleccion se controla mediante los tres flags mutuamente exclusivos en 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 portSPI Hardware (HW_SPI_ENA = 1)
Disponible en PCB RomDisk v2.0 y posteriores. El PCB lleva un registro de desplazamiento de salida serie 74HCT595 (MOSI/CLK) y un registro de desplazamiento de entrada paralela 74HCT165 (MISO/CLK) cronometrados por logica de hardware dedicada funcionando a 8 MHz -- ocho veces el reloj de bus de 2 MHz del Z80.
Enviar un byte son dos escrituras de memoria: escribir el byte en HWSPIDATA (0xEFFB), luego escribir cualquier valor en HWSPISTART (0xEFFC). El hardware envia los 8 bits automaticamente en aproximadamente 1 us. Recibir un byte es similar: escribir en HWSPISTART para recibir 8 bits, luego leer HWSPIDATA. El Z80 solo necesita el tiempo para ejecutar dos instrucciones de escritura de memoria entre bytes -- los registros de desplazamiento de hardware operan concurrentemente.
Como HWSPIDATA y HWSPISTART residen dentro del rango del latch codificado 0xEFF8-0xEFFF, solo son accesibles mientras los registros de control estan desbloqueados (es decir, despues de la secuencia de 16 lecturas). Las rutinas SDINIT, SDREAD y SDWRITE en el banco 2 asumen que los registros de control ya estan desbloqueados cuando son llamadas, lo cual siempre es el caso dentro del entorno de ejecucion RFS.
SPI Software (SW_SPI_ENA = 1)
Disponible en PCB RomDisk v2.0 y posteriores como alternativa de menor costo a los registros de desplazamiento de hardware. El firmware conmuta manualmente bits individuales del registro BNKCTRL (0xEFFF) para controlar las lineas de reloj SPI (BBCLK) y datos MOSI (BBMOSI), y lee el bit MISO de BNKCTRL para los datos entrantes. Cada bit requiere multiples escrituras a BNKCTRL -- conmutar reloj alto, conmutar reloj bajo -- dando aproximadamente 20-40 us por byte a 2 MHz de reloj Z80, aproximadamente 40x mas lento que el SPI hardware.
El bloque de codigo SW_SPI_ENA en SPIOUT envio bit a bit cada byte MSB-primero usando un bucle que lee el estado actual de BBMOSI y BBCLK, modifica el bit relevante y escribe de vuelta a BNKCTRL. Aplica el mismo requisito de desbloqueo del latch codificado -- BNKCTRL solo es escribible despues de la secuencia de 16 lecturas.
SPI por Puerto Paralelo (PP_SPI_ENA = 1)
La implementacion original del RomDisk v1, utilizando el puerto de impresora paralelo Centronics del Sharp MZ-80A como un bus SPI improvisado. Las lineas de datos del puerto de impresora (D0-D7) se reasignan: un bit controla el reloj SPI (CLOCK), un bit controla los datos MOSI (DOUT), un bit controla el chip select (CS), y un bit lee los datos MISO (DIN) del registro de estado del puerto.
Enviar un byte en SPIOUT (ruta PP_SPI_ENA): el byte se rota a la izquierda tres veces para alinear el bit 7 con la posicion del pin DOUT, luego un bucle de 8 iteraciones controla DOUT y el reloj alto/bajo usando tres instrucciones
Elegir una Variante SPI
OUT (SPI_OUT), A por bit. SPIINIT envia 80 bits '1' conmutando las lineas de reloj y datos 80 veces con DJNZ. Todos los accesos al puerto paralelo usan instrucciones de puerto de E/S (IN / OUT) en lugar de registros mapeados en memoria.
PP_SPI_ENA no requiere el desbloqueo del latch codificado -- el puerto paralelo reside en el espacio de direcciones de E/S del Z80, no en el espacio de direcciones de memoria, asi que siempre es accesible. Esto fue intencional para el diseno v1 donde el circuito del latch codificado aun no existia.
| 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 |
Anadir un Nuevo Comando de Monitor
El siguiente ejemplo anade un comando PEEK que lee e imprime un unico byte de una direccion dada. El manejador pertenece al banco 3 (utilidades de memoria).
Paso 1: Escribir el manejador en 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
Los parametros estan disponibles en el buffer de entrada del monitor inmediatamente despues de la cadena del comando. HLHEX es una rutina de utilidad (disponible en el banco 5 o via la tabla de saltos) que lee 4 digitos hexadecimales del buffer de entrada y devuelve el valor de 16 bits en HL. PRTHX imprime el acumulador como dos digitos hexadecimales en mayusculas.
Paso 2: Anadir una entrada en la tabla de comandos en rfs.asm
; In rfs.asm, within the CMDTABLE block (inside IF BUILD_ROMDISK+BUILD_PICOZ80 = 1):
;
; Flags byte: not-end (bit7=0), not-exact (bit6=0),
; bank 3 (bits5:3 = 011 = 0x18), length 4 (bits2:0 = 100 = 0x04)
DB 000H | 000H | 018H | 004H
DB "PEEK"
DW PEEK
Coloque esta entrada antes de cualquier entrada mas corta que comparta los mismos caracteres iniciales para evitar que la entrada mas corta coincida primero. El byte de flags se construye como:
000H (no fin de tabla) OR 000H (no coincidencia exacta) OR 018H (banco 3: 0b011 desplazado a la izquierda 3 = 0x18) OR 004H (longitud de cadena de comando 4).
Paso 3: Anadir texto de ayuda en rfs_bank6.asm
; In rfs_bank6.asm, within the HELPSCR block (before the 000H terminator):
DB "PEEKXXXX - read byte at XXXX", 00DH
La pantalla de ayuda usa mayusculas en todo momento (los caracteres en minuscula son dificiles de incrustar en la codificacion de caracteres Sharp sin calcular manualmente los valores de byte).
Paso 4: Compilar
cd /dvlp/Projects/MZ80A_RFS/software/RFS ./build.sh
El ensamblador reportara un error si el banco 3 ahora excede los 2 KB. Si eso ocurre, busque codigo muerto, cadenas de mensajes no utilizadas o rutinas de utilidad duplicadas que puedan eliminarse de ese banco o moverse al banco 5 (actualmente vacio).
Anadir Soporte de Nuevo Hardware
Anadir una Nueva Variante SPI
Para anadir una nueva variante de hardware SPI -- por ejemplo, un segundo diseno de puerto paralelo con asignaciones de bits diferentes (PP2_SPI_ENA):
- Anadir el flag a rfs_definitions.asm:
PP2_SPI_ENA EQU 0 ; Second parallel port SPI variant (custom hardware)
- Anadir una asercion al inicio de rfs_bank2.asm para detectar la habilitacion dual accidental:
; Guard: only one SPI flag may be set at a time. ; GLASS does not have a built-in ASSERT directive, so encode this as a build-time ; value check. If more than one flag is set, the total sum exceeds 1 and the error ; manifests as wrong code being assembled into the SPI driver functions. ; (Document this constraint prominently in the comment block above SDINIT.)
- Anadir bloques de ensamblaje condicional en rfs_bank2.asm para cada funcion SPI (SPIINIT, SPICS, SPIOUT, SPIIN). Siga el patron IF/ELSE/ENDIF anidado existente:
SPIOUT: IF HW_SPI_ENA = 1
; Hardware SPI path (existing code)
LD (HWSPIDATA),A
LD (HWSPISTART),A
RET
ELSE
IF SW_SPI_ENA = 1
; Software bit-bang path (existing code)
ELSE
IF PP2_SPI_ENA = 1
; New PP2 path:
; (implement bit-bang for the new port layout here)
RET
ELSE
; Original PP_SPI_ENA (centronics) path (existing code)
ENDIF
ENDIF
ENDIF
- Definir las nuevas constantes de puerto en rfs_definitions.asm junto con las constantes existentes SPI_OUT, DOUT_MASK, CLOCK_HIGH etc., protegidas con
IF PP2_SPI_ENA = 1 ... ENDIFpara evitar conflictos de simbolos. - Actualizar build.sh si la nueva variante requiere un diseno de imagen Flash diferente o un nombre de archivo de salida diferente.
Para portar RFS a una nueva plataforma de hardware (por ejemplo, una nueva reimplementacion basada en FPGA del MZ-80A):
- Anadir un flag BUILD_* en rfs_definitions.asm:
BUILD_NEWBOARD EQU 0. - Anadir constantes de direccion si la nueva tarjeta mapea ventanas de ROM en direcciones diferentes. La variacion mas comun es la direccion base de la User ROM y las direcciones de los registros de control de bancos.
- Anadir bloques de ensamblaje condicional a lo largo del codigo fuente para cada punto donde el comportamiento del hardware difiere: direcciones de E/S del latch de banco, registros del controlador SPI, deteccion de presencia de tarjeta SD, conmutacion del modo de visualizacion y el codigo de deteccion de plataforma del punto de entrada MONITOR en rfs.asm.
- Anadir una nueva variante de stub de conmutacion de banco en cada archivo de banco si el mecanismo de seleccion de banco de la nueva plataforma difiere tanto del latch codificado como del esquema de puertos FusionX. El stub en UROMBSTBL debe funcionar correctamente en arranque en frio antes de que se haya ejecutado cualquier inicializacion.
- Actualizar build.sh con una nueva seccion de compilacion que establezca
BUILD_NEWBOARD=1y produzca la imagen ROM apropiada para el diseno del nuevo chip Flash.
Consejos de Depuracion
Habilitar salida de depuracion: Establezca
ENADEBUG EQU 1 en rfs_definitions.asm antes de compilar. Esto incluye instrucciones de impresion de diagnostico adicionales en puntos estrategicos de la secuencia de inicializacion de la tarjeta SD, respuestas de SDCMD y analisis del directorio SDCFS. El codigo extra es condicional y no tiene efecto en el tamano de la imagen ROM del RomDisk cuando esta deshabilitado.
Volcar el area de entrada del User ROM banco 0: Escriba D E800 para volcar los primeros 320 bytes del banco actual de User ROM. Los primeros bytes deberian mostrar el NOP en 0xE800, seguido por los bytes de la macro HWSELROM, seguido por una instruccion JP. El stub de conmutacion de banco en 0xE820 deberia contener patrones reconocibles de secuencias PUSH AF / LD A, n. Si el volcado parece datos aleatorios, el latch codificado puede no haberse inicializado correctamente y se esta seleccionando el banco incorrecto.
Verificar el registro de control de banco: Escriba D EFF8 para volcar el area del registro de control de banco. Despues de realizar una conmutacion de banco manual, el byte en 0xEFFF deberia reflejar el numero de banco que escribio. Si no cambia, verifique que la secuencia de desbloqueo del latch codificado de 16 lecturas se esta ejecutando antes de la escritura.
Verificar el conteo de desbloqueo del latch codificado: Si las escrituras al registro de control de banco parecen no tener efecto, la causa mas comun es que la secuencia de 16 lecturas no se esta completando. Esto puede ocurrir si una instruccion de bucle en el banco realiza lecturas de 0xEFF8-0xEFFF durante la ejecucion normal (vea la advertencia sobre DJNZ en la seccion de conmutacion de bancos). Cuente los ciclos de lectura en la secuencia de desbloqueo y verifique que el contador del bucle esta establecido exactamente a 16.
v2.1 arranca al monitor SA-1510 sin el prompt + RFS: Si la maquina arranca en el monitor nativo SA-1510 y la linea de inicio + RFS de RFS no aparece, el punto de entrada de la User ROM en 0xE800 no se esta llamando. Verifique que el latch codificado no esta siendo disparado inadvertidamente por ciclos de refresco de DRAM -- la puerta AND (D1/D2) en v2.1 fue anadida especificamente para prevenir que los ciclos de refresco incrementen el contador 74HCT191. En tarjetas v2.0 sin esta puerta, los ciclos de refresco pueden alcanzar Terminal Count antes de que se ejecute el punto de entrada de la ROM.
Ejecutar MEMTEST despues de anadir datos residentes en RAM: Escriba R inmediatamente despues de anadir nuevas estructuras de datos o variables residentes en RAM para detectar errores de direccionamiento tempranamente. Una direccion fallida en el rango 0x1200-0xCFFF que se correlaciona con el tamano de una nueva estructura indica un error de uno en el calculo de la direccion en lugar de un chip de RAM defectuoso.
Fallos de inicializacion de tarjeta SD: Si los comandos SD devuelven codigos de respuesta inesperados con ENADEBUG habilitado, verifique que el temporizado del chip select SPI es correcto -- CS debe estar activado (bajo) antes de CMD0 y mantenido durante todo el intercambio de comando/respuesta. Bajo HW_SPI_ENA, verifique que el bit SDCS en BNKCTRL se esta estableciendo y limpiando correctamente por SPICS. Bajo PP_SPI_ENA, verifique que el registro de salida del puerto paralelo esta inicializado antes de la primera llamada a SPIINIT.
Fallos de llamada entre bancos: Si una llamada entre bancos parece ejecutar codigo incorrecto o retorna con corrupcion de registros, verifique que el stub de conmutacion de banco en el banco destino coincide byte a byte con el del banco 0. Cada banco debe tener una copia identica del stub en UROMBSTBL. Use D E820 para volcar el stub del banco 0, luego conmute al banco destino manualmente y vuelque el mismo rango de direcciones para comparar.
Sitios de Referencia
| 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 |