CP/M v2.23
Descripcion general
Linux y Windows son ahora los sistemas operativos estandar, pero hace anos todo comenzo cuando Digital Research creo el Control Program/Monitor (CP/M). CP/M fue uno de los primeros sistemas operativos reales para microcomputadoras, proporcionando medios comunes para ejecutar aplicaciones en diverso hardware. Desarrolle la placa de actualizacion de 80 columnas a color y el Rom Filing System con el objetivo primario de realizar CP/M en el MZ80A.
Finalmente decidi escribir mi propia version ROM del CBIOS y combinarla con el BDOS+CCP de CP/M v2.23.
Finalmente decidi escribir mi propia version ROM del CBIOS y combinarla con el BDOS+CCP de CP/M v2.23.
Proceso de arranque CP/M
El arranque de CP/M ocurre en dos fases:
- Lectura de un sector de arranque invertido con el software de control AFI, verificacion del codigo 0x02 + “IPLPRO” en 0x0000
- Carga de CCP, BDOS y CBIOS a partir de 0x9C00
Arranque de CP/M de disquete desde TZFS (v1.8.3)
A partir de TZFS v1.8.3 ya no es necesario cambiar el firmware para arrancar un sistema operativo basado en disquete: los sistemas operativos de disquete originales de Sharp -- incluido MZ-800 CP/M asi como los sistemas de disquete del MZ-80A y el MZ-700 -- ahora pueden arrancarse directamente desde TZFS, y la maquina regresa a TZFS automaticamente cuando se pulsa el interruptor RESET de hardware tras un sistema operativo arrancado desde disquete.
La rutina
Arrancar un sistema operativo de disquete vuelve a habilitar las interrupciones de forma temprana, por lo que TZFS domestica el reloj 8253 antes del
En el MZ-800, el video GDG integrado y la fuente PCG se gestionan de forma transparente: un sistema operativo en modo MZ-800 que carga una fuente PCG ahora alcanza la CG-ROM/CG-RAM real bajo TZFS (corrigiendo el texto ilegible bajo el BASIC de disco), mientras que los juegos nativos no se ven afectados. Cuando se pulsa RESET tras un sistema operativo arrancado desde disquete, TZFS recarga el monitor prístino del bloque 0 y su propia UROM (ambos pueden haber sido sobrescritos por el sistema operativo arrancado, ya que la ROM y la RAM del bloque 0 comparten la misma PSRAM en el picoZ80) y realiza su propio arranque en frio, de modo que el interruptor de reset le devuelve a TZFS en lugar del monitor 1Z-013A básico.
La rutina
GETBOOTDSK de TZFS ahora acepta cualquiera de los identificadores de maquina de Sharp (01 MZ-2000, 02 MZ-80A/MZ-80K, 03 MZ-700/MZ-800) junto con la firma IPLPRO del sector de arranque. Fundamentalmente, para sistemas operativos que se cargan por debajo de 1000H -- siendo MZ-800 CP/M el caso mas destacado -- pagina previamente el bloque 7 de DRAM en 0000H–0FFFH antes de ceder el control, y pasa el control al programa cargado con BC=0200H exactamente como lo hace el IPL nativo 9Z-504M, de modo que un cargador de segunda fase puede realizar su propia lectura de directorio sin cambios.
Arrancar un sistema operativo de disquete vuelve a habilitar las interrupciones de forma temprana, por lo que TZFS domestica el reloj 8253 antes del
JP (HL) final: el contador 2 se reprograma a aproximadamente 1 Hz y la linea PC2 del 8255 se enmascara, reflejando la propia rutina SORES del IPL. Sin esto, un contador de marcha libre inunda el Z80 con interrupciones RST 38H y aborta un cargador que acaba de rehabilitar las interrupciones — esta era la causa del fallo "P-CP/M80 → No system file", ahora corregido.
En el MZ-800, el video GDG integrado y la fuente PCG se gestionan de forma transparente: un sistema operativo en modo MZ-800 que carga una fuente PCG ahora alcanza la CG-ROM/CG-RAM real bajo TZFS (corrigiendo el texto ilegible bajo el BASIC de disco), mientras que los juegos nativos no se ven afectados. Cuando se pulsa RESET tras un sistema operativo arrancado desde disquete, TZFS recarga el monitor prístino del bloque 0 y su propia UROM (ambos pueden haber sido sobrescritos por el sistema operativo arrancado, ya que la ROM y la RAM del bloque 0 comparten la misma PSRAM en el picoZ80) y realiza su propio arranque en frio, de modo que el interruptor de reset le devuelve a TZFS en lugar del monitor 1Z-013A básico.
CBIOS
CP/M se compone de 3 modulos distintos: CCP, BDOS y CBIOS. El CBIOS se personaliza segun el hardware subyacente.
| Metodo API | Descripcion |
|---|---|
| BOOT | Arranque en frio, inicializar todo el hardware. |
| WBOOT | Arranque en caliente, recargar CCP+BDOS. |
| CONST | Estado de la consola. |
| CONIN | Entrada de consola. |
| CONOUT | Salida de consola. |
| HOME | Mover el cabezal del disco a la pista 0. |
| SELDSK | Seleccionar un disco. |
| READ | Leer un sector. |
| WRITE | Escribir un sector. |
| SECTRN | Traduccion de sector (logico a fisico). |
| ROM | Direccion | Descripcion |
|---|---|---|
| 4K MROM | 0xC000 - 0xCFFF | CBIOS con API CP/M, rutinas de inicializacion, controlador ROM Disk. |
| 2K Paged ROM | Bank 8 | Sonido, RTC, teclado. |
| 2K Paged ROM | Bank 9 | E/S de pantalla y parser terminal ANSI. |
| 2K Paged ROM | Bank 10 | Funcionalidad controlador de tarjeta SD. |
| 2K Paged ROM | Bank 11 | Funcionalidad controlador de disquete. |
*Caracteristicas*
- Reloj en tiempo real con granularidad de 50ms
- Teclado por interrupciones con buffer y repeticion automatica
- Funcionalidad de terminal ANSI
- Unidades de disquete configurables (1.44M, 720K, 320K)
- Discos duros SD Card de 16MB configurables
- Salida al monitor via SHIFT+GRAPH+BREAK
Instalacion y compilacion automatizadas (recomendado)
CP/M para el tranZPUter se ensambla y empaqueta como parte de la compilacion normal de TZFS, por lo que la forma mas facil de producir el CBIOS, la aplicacion MZF de CP/M y las imagenes de disco CP/M es el script de instalacion automatizada para su plataforma. Cada script es autocontenido -- copie unicamente el archivo correspondiente a su sistema operativo y ejecutelo. Instala los requisitos previos, clona el repositorio TZFS, descarga el paquete de contenido de ~110 MB (
TZFS_Files.zip, que incluye el software CP/M) y puede ejecutar la compilacion por usted, sin necesidad de un conocimiento profundo de la cadena de herramientas. Los pasos manuales, herramienta por herramienta, mas abajo son para usuarios avanzados y recompilaciones parciales.
| Script | Plataforma | Notas |
|---|---|---|
setup_TZFS.sh |
macOS / Linux / WSL | Instala un JRE de Java (ensamblador GLASS), una cadena de herramientas C + make (para compilar el submodulo cpmtools incluido), perl, git, y (en macOS) GNU coreutils y bash 4 mediante un tzfs_env.sh generado. |
setup_TZFS_windows.ps1 |
Windows 10 / 11 – Git Bash nativo, sin WSL | Usa winget para instalar Git for Windows y un JRE Temurin 17, y luego compila a traves de Git Bash. No se necesita compilador de C – se incluye un tools\cpmcp.exe precompilado. |
macOS / Linux / WSL – setup_TZFS.sh
chmod +x setup_TZFS.sh
./setup_TZFS.sh
Windows 10 / 11 (Git Bash nativo) – setup_TZFS_windows.ps1, desde un prompt de PowerShell:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\setup_TZFS_windows.ps1
Los scripts respetan las variables de entorno TZFS_REPO_URL (por defecto https://git.eaw.app/eaw/TZFS.git) y TZFS_FILES_URL (ubicacion del paquete de contenido) para anular los avisos interactivos. La compilacion escribe la ROM de TZFS, el CBIOS/MZF de CP/M y las imagenes de disco CP/M en el directorio roms/; copielos a una tarjeta SD formateada en FAT32 con tools/copytosd.sh. Para el recorrido completo paso a paso, vea la Guia tecnica TZFS – Sistema de compilacion.
Compilacion de CPM
cd <software>
tools/assemble_cpm.sh
Formatos de disco
diskdef MZ80A-A
seclen 256
tracks 40
sectrk 32
blocksize 2048
maxdir 64
boottrk 1
os 2.2
end
diskdef MZ80A-1440
seclen 512
tracks 80
sectrk 36
blocksize 2048
maxdir 128
boottrk 0
os 2.2
end
diskdef MZ80A-SDC16M
seclen 512
tracks 1024
sectrk 32
blocksize 8192
maxdir 512
boottrk 0
os 2.2
end
Extraer discos CP/M MZ80A
El Sharp MZ-80A almacena datos en formato invertido -- cada byte es el complemento bit a bit. Los datos brutos deben invertirse antes de que CPMTools pueda leerlos.
samdisk copy <MZ80A DISK NAME>.DSK <MZ80A DISK NAME>.RAW --cyls=40 --head=2 --sectors=16 --size=256
python3 -c "import sys; sys.stdout.buffer.write(bytes(~b & 0xFF for b in open('<MZ80A DISK NAME>.RAW','rb').read()))" > <MZ80A DISK NAME>_normal.RAW
cpmls -f MZ80A-A <MZ80A DISK NAME>_normal.RAW
Guia del desarrollador
Una Guia del desarrollador CP/M completa esta disponible.
Licencias
Este diseno esta licenciado bajo la GNU Public Licence v3.