CP/M y Spectrums A modo de introducción Estaba buscando algo más de información sobre los modelos LEC y su CP/M cuando me topé con el artículo de un BLOG en polaco, originalmente pensaba extraer algunos datos, principalmente los referentes al teclado y codigos ESCape, pero luego me decidí por hacer una traducción del texto completo, el cual ofrezco a continuación: SinDiKat Sinclair y Didaktik - Club de técnicos activos Implementación de CP/M para el ZX Spectrum Escrito por Daniel Meca el 7 de abril de 2019 En la serie retro del domingo continuamos con la descripción de la versión CP/M de Jiri Lamac según AR 9/88 (*). El ZX Spectrum es con mucho, la computadora más extendida en nuestro país hoy en día, no solo entre los aficionados. Pero lo cierto es que la gran mayoría de usuarios solo quieren juegos diversos o escriben programas simples en BASIC. Esto se debe a la falta de imaginación, la ausencia total de literatura profesional y también al hecho de que entre la avalancha de programas profesionales de muchas compañías, los juegos son los que predominan más. No hay tantos sistemas y programas para el usuario que sean de calidad. Además, se difunden de manera insidiosa, a menudo en versiones muy malas y lo más importante, rara vez con instrucciones. Y así, aquellos que quisieran hacer algo "mejor" no tienen otras opciones. Aunque hay PASCAL, ensamblador y compiladores de C, no alcanzan el nivel habitual como los programas para sistemas "profesionales". Y sobre todo, están diseñados principalmente para funcionar con una grabadora de casete, un dispositivo que ya pertenece al pasado. El sistema operativo CP/M resuelve por completo todas estas deficiencias. Es posible accesar facilmente a los archivos, se pueden utilizar programas de calidad de casas conocidas, como WordStar, TURBO-Pascal, MACRO 80, dBASE II, Fortran y otras. También es importante que el Spectrum gane compatibilidad total con otras computadoras de 8 bits que hay en nuestro país, como TNS, SAPI 1, ROBOTRON 1715, pero también el Commodore 128, Schneider - Amstrad 664 y 6128, Sharp MZ 821 y otras más. Información básica sobre el sistema. El sistema operativo CP/M para Spectrum se crea sobre la base del sistema operativo que utilizan otros MICROS, que es básicamente el clásico CP/M versión 2.2. Debido a la mayor longitud del BIOS, el sistema se genera para que la RAM de 60k se adapte a la memoria (el BIOS V3.2 tiene aproximadamente 5k de largo, para la versión 4.0 se calcula aproximadamente 6.5k). Puede usar de una a tres unidades Microdrive, o incluso un disco RAM. Todos los programas que funcionan con el CP/M son portables sin restricciones para el Spectrum. Las únicas excepciones son los programas del sistema que ya asumen ciertos parámetros de disco dados, como el tamaño del directorio, el número de pistas del sistema, etc., y no los obtienen leyendo las tablas de disco del sistema. Esto solo parece aplicarse a MOVCPM, SYSGEN y DOCTOR, que estamos finalizando para Spectrum. Recientemente se publicó una descripción del diseño y la función del CP/M en las páginas de la revista AR. Prerrequisitos técnicos Desafortunadamente, el uso de CP/M en Spectrum no es posible sin interferir con los circuitos de la máquina. Esto se debe a que la RAM debe comenzar en la dirección 0000h. Por lo tanto, se ha propuesto una modificación muy simple, que puede ser manejada fácilmente incluso por aficionados, que consiste en reemplazar las ocho RAM originales 4532 con los circuitos 4164 o 41256. El cambio al modo CP/M se realiza desactivando la selección de ROM y VRAM (RAM de video), que todavía no necesitamos para nada, y la memoria RAM recién conectada (dirección 0000h a 7FFFh) se encuentra en su lugar. Se puede usar el puerto de paginación para seleccionar qué página de memoria extra estará activa. Cuando se usa la memoria 4164, se crea el conocido Spectrum 80K, que además de 48K, tiene una página adicional de memoria (página = 32k), la memoria 41256 permite obtener 7 páginas adicionales (Spectrum 272k). Es posible conectar dos conjuntos de memorias del mismo tipo, y así tener una memoria con una capacidad de 528kB. La selección de memoria es proporcionada por el puerto en la dirección FDh, que tiene la siguiente función: * bit 7 .. 0 - modo Spectrum 48K, * .. 1 - modo CP/M, * bits 6, 5, 4 y opcionalmente 3 - especifican la página RAM activa. Como se puede ver, incluso después de eso, el Spectrum seguirá siendo totalmente compatible con todos los programas diseñados para él, y pueden seguir utilizándose sin cambios. Sin embargo, es necesario mencionar aquí las modificaciones publicadas previamente de la memoria del Spectrum. Puede parecer que nuestra modificación propuesta es otra variantr de un viejo tema. Este no es el caso. Las modificaciones más antiguas consistían principalmente en permitir la paginación de memoria en la mitad superior del espacio direccionado, es decir, en las direcciones 8000h a FFFFh, lo que no es adecuado para nuestro propósito. La modificación descrita en Communication Technology No. 11/1987, pagina la memoria extra, pero causa colisión de datos en el bus al conectar periféricos estándar para el Spectrum, ya sea el ZX Interface 1, Opus Discovery, Beta-disco, ZX Interface 3, Kempston E, Lprint 4 y otros, lo cual genera muchas sorpresas desagradables a los usuarios. Al hacer el ajuste, es necesario garantizar la actualización correcta de las memorias recién conectadas, las cualess requieren de una dirección de 8 bits en el ciclo de actualización. Sin embargo, el Z80A proporciona solo refrescados de 7 bits. Por lo tanto, una parte de la placa agregada con varias E/S, también es un circuito que garantiza la generación del octavo bit de la dirección de refrescado. Software El requisito básico para el CP/M para ZX Spectrum fue el uso de periféricos estándar para el registro de datos, como el ZX Interface 1 y Microdrives. Por supuesto, también hemos diseñado el CP/M con unidades de disquete para el Spectrum, lo que, sin embargo, no fue un problema especial con la operación de programas muy simple del controlador de discos. Esta versión se basa en el Betadisco muy poco difundido, que utiliza el controlador FD-1793 y que puede fabricarlo fácilmente un aficionado. Pero, la condición es obtener los circuitos integrados y las unidades de disco necesarios. Sin embargo, los Microdrives son mucho más accesibles y absolutamente los más conocidos. Los importó hace algún tiempo PZO Tuzex. Es por eso que el ZX Microdrive fue elegido, pese a ser un dispositivo algo específico que no ha sido fácil de adaptar a los requisitos de CP/M, pues requiere la posibilidad de acceso directo al disco. Eso nos lleva a nuestro propio bloque del sistema operativo dependiente del sistema, el BIOS. El programa principal aquí es un simulador de discos con el Microdrive. Si el Microdrive funcionara de la misma manera que un disco, todo el sistema funcionaría increíblemente lento (probado y comprobado). Era necesario recurrir a cosas tales como el tiempo compartido, la prioridad de las operaciones de disco, el funcionamiento continuo del teclado, incluso cuando el Microdrive estaba funcionando y el acceso a los archivos a través de grandes memorias intermedias. Sabemos más de estas cosas por computadoras de mayor poder, como la IBM PC. Como sea, el resultado es un sistema plenamente funcional. La versión 3.2 del BIOS, propia para un rango de memoria total de 80K y 272K, controla el Microdrive de modo significativamente más rápido que la ROM original de la ZX interfaz 1 de Sinclair. La última versión del BIOS V 4.0, diseñada para 272K o más, funciona con el Microdrive mucho más rápido, que sistemas similares con unidades de disco. Cuando se usa una RAM de al menos 272K, es posible trabajar con CP/M en el Spectrum, incluso con una grabadora de casete. Tras la carga de todos los programas y datos de la cinta, pasa a trabajar solo con el disco RAM y finalmente volverá a cargar los datos en la cinta. Esto también ha sido probado con éxito. Y es probable que sirva para un trabajo más serio. Como sea, es algo muy interesante, especialmente con fines educativos. Rutinas de la BIOS Arranque frío y cáliente. El arranque en frío del sistema se resuelve de la única manera posible. El cartucho del sistema se inserta en la unidad 1 y se ingresa el comando RUN. El cargador detecta la cantidad de RAM, lo prueba, arranca el sistema y lo inicializa. En cambio, un inicio en cáliente funciona un poco diferente. En otras computadoras, el sistema se reinicia desde el disco. Pero aquí el sistema no está instalado en cartuchos comunes, por lo que no ocupa un espacio valioso. Por lo tanto, la primera vez que se carga el sistema, éste se mueve a la VRAM no utilizada, desde donde pasa a la ubicación definitiva durante el inicio en caliente bajo las instrucciones LDDR. Teclado La acción del teclado también ha cambiado. Sobre todo, el número de teclas que no es suficiente. Por eso, la nueva rutina del teclado maneja tres teclas presionadas simultáneamente. Por lo tanto, es posible tipear todos los caracteres ASCII de CHR$(0) a CHR$(127). Algunas teclas tienen diferente significado, como se ve en la siguiente tabla: Tecla Función Tecla Función MODO EXTENDIDO CTRL EDIT ESCAPE GRAPH TAB BREAK CTRL S VIDEO VERD. CTRL C VIDEO INV. CTRL R CURSOR IZQ. BS CURSOR DER. CTRL D CURSOR ARRIBA CTRL E CURSOR ABAJO CTRL X Tecla Símbolo + SPACE + B hace una interrupción de programa con retorno al sistema. Esta es una función ventajosa, por ejemplo, si un programa se atasca en un ciclo sin fin. Las otras teclas funcionan como en otras computadoras, es decir, CTRL + letra proporciona el carácter de control correspondiente. El teclado se lee continuamente, independientemente de otras actividades de la máquina. Si el programa en ejecución no puede procesar caracteres desde el teclado, éste funcionará con un búfer de 128 caracteres. Por lo tanto, es posible, por ejemplo, al compilar un archivo con ensamblador, escribir comandos adicionales, que se ejecutarán más tarde, una vez que se complete la conversión. Terminal de Salida Como es bien sabido, CP/M requiere de una pantalla con 80 caracteres por línea. Pero también funciona con ciertas limitaciones en sistemas con menos caracteres. En el ZX Spectrum, esto se resuelve imprimiendo con un formato de 64 caracteres por 24 líneas. El programa de salida también incluye subrutinas para desplazar la pantalla hacia arriba y hacia abajo y para eliminar una línea, lo que aumenta significativamente la comodidad en la edición de textos. Los caracteres ASCII, CHR$(20) a CHR$(126), BEL, BS, LF y CR se muestran de la manera habitual, los otros códigos de control se encuentran en la siguiente tabla: Código Función Código Función ESC = Y x CURSOR (posicionado) ESC T BORRAR HASTA EOLN (final de la línea) ESC R BORRAR LÍNEA ESC E INSERTAR LÍNEA ESC ( FINALIZAR RESALTAR ESC ) INICIAR RESALTAR CTRL Z CLS + HOME El BIOS no puede manejar los caracteres TAB, FF y DEL. Los caracteres de control fueron elegidos en un esfuerzo por estandarizar el BIOS tanto como sea posible y son idénticos a los terminales Televideo 925 y 950. La rutina de salida también incluye una subrutina de impresión de cursor que se ejecuta sobre la interrupción y, por lo tanto, todavía es visible para el cursor. Algunos programas requieren un cursor visible incluso cuando no están esperando del teclado. El cursor parpadea, incluso mientras el Microdrive está funcionando. Impresora y cinta perforada Suele haber diferencia en estos dispositivos que cada usuario pueda tener. Por lo tanto las utilidades de impresión y cinta no están incluidas en el BIOS. Trás su vector de entrada hay cuatro vectores más, que están en el orden sigte.: Llamada Subrutina BIOS + 33H Salida de caracteres a la impresora BIOS + 36H Estado de la impresora BIOS + 39H Perforar algo en una cinta BIOS + 3CH Leer algo de una cinta El parámetro de entrada está en el registro C, la salida en A. El usuario coloca una instrucción de salto en el lugar adecuado del BIOS (vectores añadidos) en su subrutina que escribe, traduce de la dirección 'BASIC RAMTOP' + 1 y asigna al sistema la dirección CCP-800h, desde donde el sistema se mueve al destino y llama. Hay 300h de bytes libres para las rutinas de usuario. Al llamar, el modo 48K está paginado, la interrupción está habilitada y el SP está configurado en una dirección por debajo de la cual al menos 20h bytes están libres. El usuario puede usar los registros AF, BC, DE y HL y no debe desactivar las interrupciones (¡mucho cuidado con los bucles de temporización!). Tampoco es posible llamar a rutinas de la ROM o a una ROM adicional, como la que tiene por ejemplo, el ZX Interface 1. Operaciones de disco Las operaciones de disco a nivel Microdrive son, con mucho, las operaciones de BIOS más complejas. Se basan en compartir el tiempo de CPU entre la operación de Microdrive y el programa en ejecución. Esto se hace a través de interrupciones y tiene lugar en dos prioridades diferentes. Se da prioridad inmediata a las solicitudes inmediatas de los programas en ejecución. El acceso al disco del BIOS tiene una prioridad más baja cuando se realizan solicitudes de lectura y escritura secuenciales anteriores. El programa se comunica con los archivos a través de buffers de acceso. Su tamaño es de 2K para BIOS V3.2, o de 32 a 64K para 4.0. Formato de registros CP/M para Microdrive utiliza un formato de grabación diferente al de la ROM original, por dos razones. Por un lado, la capacidad del cartucho se incrementa a 96K y por otro lado, el formato original del registro no es posible, porque no tiene en cuenta la existencia del directorio. El cartucho se implementa como un disco de una sola pista con 192 sectores de 0.5K. Cada sector tiene un encabezado de 4 bytes con un indicador nulo, un número de cartucho (2 bytes), un número de sector y una suma de verificación. El encabezado es seguido por 512 bytes de datos, que están marcados con el valor FFh y terminados por una suma de verificación. El número de cartucho es un número aleatorio que se genera durante el formateado y es utilizado por el BIOS para reconocer el reemplazo del cartucho sin contar las sumas de verificación del directorio por el BDOS. Debido a la mayor optimización posible de los tiempos de acceso durante las operaciones secuenciales, el parámetro de renumeración del sector no es fijo. El BIOS no se renumera en absoluto, se genera una secuencia de números de sector consecutivos cuando se formatea el cartucho y el parámetro de renumeración es opcional. Así, el usuario puede optimizar los tiempos de acceso al mínimo, teniendo en cuenta el tipo de trabajo realizado y las constantes de tiempo específicas del mecanismo del Microdrive. Desafortunadamente, difieren de una unidad a otra. La numeración dos en el caso de los cartuchos destinados a la grabación de programas y doce para los archivos secuenciales, que se adapta a todas las unidades, resultó ser la más ventajosa. Un cartucho es un medio en el cual, después del formateo, casi siempre surgen algunos sectores defectuosos, causados ​​al menos por el bucle sin fin de la cinta. Por lo tanto, la escritura en estos sectores defectuosos se evita creando un archivo protegido por el sistema que contenga todos los sectores defectuosos en el directorio después de varias pruebas de cartuchos. Este archivo se registra con un número de usuario que no existe, el 31, al cual el sistema por lo tanto, no accede. Idealmente, se pueden grabar hasta 95k de datos en el cartucho, de los cuales el directorio tiene un tamaño de 1k (2 sectores). Esto limita el número máximo de los archivos grabados en un cartucho a 32, lo cual suele ser suficiente. Operaciones de lectura La lectura secuencial de sectores es la acción más comúnmente efectuada. Por lo tanto debe operar lo más rápido posible. Eso se realiza probando primero si un sector dado ya no existe en el búfer de acceso cuando se realiza una solicitud de lectura (se dá en la gran mayoría de casos). Si es así, el sector se pasa al programa de llamada y por supuesto, el Microdrive no se manipula de ninguna manera. Solo durante la operación de abrir y cerrar el archivo (acceso al directorio) se verifica si alguien no ha reemplazado el cartucho mientras. Si se realizara una suma de comprobación de directorio, como con un CP/M estándar, se necesitaría al menos una ejecución de cinta. Por lo tanto, esta comprobación consiste en leer el encabezado del primer sector y comparar el número de cartucho aleatorio con el número almacenado en la memoria. Si el número no coincide, se vacían las memorias intermedias de acceso correspondientes de la unidad dada y la lectura se realiza directamente desde el cartucho. La prueba de intercambio completa no dura más de aproximadamente 150 ms. Sin embargo, para evitar retrasos innecesarios, esta prueba no siempre se realiza. Su operación se omite si la última operación de lectura o escritura en la unidad no tuvo lugar hace más de dos segundos. Resulta que no es posible reemplazar el cartucho antes de los dos segundos mencionados. Otra situación ocurre cuando el sector no se encuentra en el búfer, entonces se libera la parte del búfer que es relativamente menos necesaria en este momento, y el sector del cartucho se lee en el espacio creado de este modo, para que pueda pasar al programa de llamada. Además, en el sistema de memoria extendida 4.0, cada operación de lectura es seguida por procedimientos lógicos diseñados para minimizar el tiempo asociado con la lectura del archivo tanto como sea posible. Incluso si no se requiere una operación de lectura adicional y el programa principal se está ejecutando, el BIOS llena el búfer de acceso con sectores adicionales del archivo abierto a través de una interrupción hasta que el búfer esté completamente lleno o hasta que el número de sectores exceda los 16. Esto asegura que leer el archivo desde la unidad sea en 8k, "precede" con sus propias solicitudes de lectura, y la respuesta del BIOS a una solicitud de lectura es muy rápida. Es solo cuestión de mover datos en RAM. Operación de escritura Escribir es similarmente lento, como leer. Por lo general, se realiza de tal manera que se libera la parte menos necesaria del búfer y el sector escrito se almacena en esta parte. Las tablas pertinentes indicarán que el sector se registrará y el control se transferirá al programa principal como si el registro ya se hubiera completado. El BIOS escribe el sector en sí más tarde, con mayor frecuencia a través de una interrupción. Sin embargo, a veces una operación de escritura también se realiza como un efecto secundario de una operación de lectura cuando se encuentra un sector a escribir durante una lectura. Sin embargo, nadie tiene que preocuparse de que, por ejemplo, en el caso de una falla de la red, los últimos datos no se registren, porque el sistema por lo general, realizará todas las entradas requeridas de inmediato, pero a más tardar 30 segundos después de la solicitud. Trabajando con búferes de acceso Como ya se explicó, la lectura y escritura de un sector no tiene lugar directamente, sino a través de memorias intermedias de acceso de longitudes generalmente diferentes, que el sistema cambia según sea necesario. Después de arrancar el sistema y de unos minutos de funcionamiento del sistema, por supuesto, todos los búferes están completamente llenos y el sistema debe comenzar a administrar el espacio del búfer con cuidado. Esta estrategia fue cambiada y probada varias veces antes de encontrar su forma final. Si se requiere una operación de lectura o escritura y no se encuentra un sector determinado en el búfer, el BIOS buscará qué sector del búfer se necesita menos. Todo el procedimiento difiere dependiendo de si el sector para el que estamos liberando espacio pertenece o no a un directorio. Si el sector tiene el número 0 o 1, entonces pertenece al directorio y el sector se descartará para obtener el espacio requerido: 1- Un sector que no es de directorio que ya ha sido leído o escrito en su totalidad por el programa de llamada (es decir, los cuatro subsectores de ese sector han sido leídos o escritos, porque el sector físico tiene una longitud de 512 bytes y el sector lógico tiene solo 128). 2- Un sector que no es de directorio de solo lectura. 3- Cualquier sector del que acabas de leer. 4- Si ninguna de las actividades anteriores tuvo éxito, una operación se llamará aparentemente "selección de tiempo activa". ¿Que es todo esto? En este caso, significa detener el trabajo del programa principal, y es necesario borrar una parte del búfer lo antes posible. Debido a que todos los sectores en el búfer han sido escritos por el programa principal, pero aún no están en el cartucho, es necesario registrar rápidamente un sector. Por lo tanto se inicia el motor de un Microdrive (si aún no se está ejecutando uno) y se busca un sector para escribir. Si se encuentra, la escritura se realiza y el espacio libre se usa para otro sector. Claro que al seleccionar una unidad a la que se elimina el sector en exceso, la unidad que ya se está ejecutando tiene prioridad. Si es necesario obtener espacio para un sector que forma parte de un archivo, los criterios se consideran en el siguiente orden: 1- El sector anterior, del cual solo se leyó y se lee en su totalidad por el programa de llamada, es el sector más común que precedió al nuevo sector en el archivo y, por lo tanto, lo más probable es que ya no se lea. 2- Un sector del que solo se ha leído y se lee en su totalidad. 3- Cualquier sector del que acabas de leer 4- Selección de tiempo activo. Debido a que el BIOS debe operar con los Microdrives al nivel más bajo posible, se encarga también de encender y apagar los motores de las unidades. Como esta operación dura aproximadamente 18 ms, es imposible manipular el motor después de cada operación de lectura o escritura. Por lo tanto, los motores se encienden inmediatamente si es necesario, pero su apagado se retrasa, como lo hacen los controladores de disco. Es por eso que los Microdrives ya no parpadean con tanta frecuencia y no graban y leen con las unidades encendidas y apagadas nuevamente como cuando se trabaja con la ROM original, pero generalmente con la lectura o escritura completa parece que la unidad se iniciará y detendrá después de un tiempo. Entre otras cosas, también prolonga la vida útil (no muy larga) del mecanismo. Jiří Lamač, autor de la BIOS (*)El artículo fue publicado originalmente en Amateur Radio 9/1988 en las p. 339-341 Para cerrar El artículo es del año 1988, originalmente publicado por el mismo Jiří Lamač, autor de las expansiones de RAM y ROMs LEC así como del CP/M para Microdrive y Betadisco. Publicado en la internet por Daniel Meca el 2019 en el blog SinDiKat. Actualmente es posible descargar la cinta de instalación del CP/M desde diversas WEBs, entre las que se halla World of Spectrum. Lo que es más raro de hallar es la versión en formato cartucho de Microdrive, pero se puede copiar los datos de la cinta a un cartucho. En cambio la versión de disco como ya se ha mencionado en otras ocasiones está hoy en día desaparecida. Otra cosa que menciona Lamač, es que planeaba adaptar MOVCPM, SYSGEN y DOCTOR al CP/M para Spectrum, aunque no dice si para la versión Microdrive o solo para la versión Betadisco. Nuevamente esa versión de dichos comandos externos se pueden considerar desaparecidos de haber sido implementadas. (c)2020 zx_if1@hotmail.com