KERNAL [1] es el nombre que da Commodore al núcleo del sistema operativo residente en ROM en sus computadoras hogareñas de 8 bits ; del PET original de 1977, seguido por las versiones extendidas pero relacionadas utilizadas en sus sucesores: VIC-20 , Commodore 64 , Plus/4 , Commodore 16 y Commodore 128 .
El KERNAL de las máquinas Commodore de 8 bits consiste en rutinas de sistema operativo de bajo nivel, cercanas al hardware, aproximadamente equivalentes a la BIOS en los IBM PC compatibles (en contraste con las rutinas del intérprete BASIC , también ubicadas en la ROM), así como funcionalidad de E/S de nivel superior e independiente del dispositivo. El usuario puede llamarlo a través de una tabla de saltos en la RAM cuya parte central (la más antigua), por razones de compatibilidad con versiones anteriores , [2] permanece en gran parte idéntica a lo largo de toda la serie de 8 bits. La ROM KERNAL ocupa los últimos 8 KB del espacio de direcciones de 64 KB de la CPU de 8 bits ($E000–$FFFF).
La tabla de saltos se puede modificar para que apunte a rutinas escritas por el usuario, por ejemplo, para integrar un cargador rápido de modo que sus rutinas de reemplazo rápido se utilicen en todo el sistema o para reemplazar la rutina de salida de texto del sistema por una que funcione en modo de mapa de bits en lugar de modo de caracteres. Este uso de una tabla de saltos era nuevo para las computadoras pequeñas en ese entonces. [3]
Los juegos de Adventure International publicados para el VIC-20 en cartucho son un ejemplo de software que utiliza el KERNAL. Como solo utilizan la tabla de saltos, los juegos se pueden volcar de memoria a un disco, cargar en un Commodore 64 y ejecutar sin modificaciones. [4]
El KERNAL fue escrito inicialmente para el Commodore PET por John Feagans, quien introdujo la idea de separar las rutinas BASIC del sistema operativo. Fue desarrollado posteriormente por varias personas, en particular Robert Russell, quien agregó muchas de las características para el VIC-20 y el C64.
Un ejemplo simple, pero característico, del uso de KERNAL lo proporciona la siguiente subrutina de lenguaje ensamblador 6502 [5] (escrita en formato/sintaxis de ensamblador ca65 ):
CHROUT = $ffd2 ; CHROUT es la dirección de la rutina de salida de caracteres CR = $0d ; Código PETSCII para retorno de carro ; Hola: ldx #0; comienza con el carácter 0 cargando 0 en el registro de índice x próximo: lda mensaje,x; carga el byte de la dirección mensaje+x en el acumulador beq hecho; si el acumulador tiene cero, hemos terminado y queremos salir del bucle jsr CHROUT; llama a CHROUT para enviar un carácter al dispositivo de salida actual (predeterminado a pantalla) inx ; incrementa x para pasar al siguiente carácter bne next; retrocede mientras el último carácter no sea cero (longitud máxima de cadena 255 bytes) hecho: rts ; volver de la subrutina ; mensaje: .byte " Hola, mundo! " .byte CR, 0; Retorno de carro y cero que marca el final de la cadena
Este código auxiliar emplea la CHROUT
rutina, cuya dirección se encuentra en la dirección $FFD2
(65490), para enviar una cadena de texto al dispositivo de salida predeterminado (por ejemplo, la pantalla de visualización).
El KERNAL se conocía como kernel [6] dentro de Commodore desde los días de PET, pero en 1980 Robert Russell escribió mal la palabra kernal en sus cuadernos. Cuando los redactores técnicos de Commodore Neil Harris y Andy Finkel recopilaron las notas de Russell y las usaron como base para el manual del programador de VIC-20, el error de ortografía los siguió y se quedó. [7]
Según un mito temprano de Commodore, y reportado por el escritor/programador Jim Butterfield entre otros, la "palabra" KERNAL es un acrónimo (o, más probablemente, un acrónimo inverso ) que significa Keyboard Entry Read , Network, And Link (Lectura de entrada de teclado , red y enlace ) , lo que de hecho tiene mucho sentido considerando su función. Berkeley Softworks lo usó más tarde para nombrar las rutinas centrales de su sistema operativo GUI para computadoras domésticas de 8 bits: GEOS KERNAL.
Sorprendentemente, el KERNAL implementó una API de E/S independiente del dispositivo que no es muy distinta de la de Unix o Plan-9 , que nadie aprovechó, hasta donde se sabe públicamente. Mientras que uno podría argumentar razonablemente que "todo es un archivo" en estos últimos sistemas, otros podrían afirmar fácilmente que "todo es un dispositivo GPIB " en los primeros.
Debido a las limitaciones de la arquitectura 6502 en ese momento, abrir un canal de E/S requiere tres llamadas al sistema . La primera generalmente establece el nombre de archivo lógico a través de la SETNAM
llamada al sistema. La segunda llamada, , establece la dirección del "dispositivo" SETLFS
GPIB/ IEEE-488OPEN
con el que comunicarse. Finalmente , se llama a para realizar la transacción real. Luego, la aplicación usa CHKIN
y CHKOUT
llamadas al sistema para establecer los canales de entrada y salida actuales de la aplicación, respectivamente. Las aplicaciones pueden tener cualquier cantidad de archivos abiertos simultáneamente (hasta un límite que depende del sistema; por ejemplo, el C64 permite que se abran diez archivos a la vez). A partir de entonces, CHRIN
y CHROUT
resultan útiles para realizar la entrada y la salida, respectivamente. CLOSE
luego cierra un canal.
Obsérvese que no existe ninguna llamada al sistema para "crear" un canal de E/S, ya que los dispositivos no se pueden crear ni destruir dinámicamente en circunstancias normales. Asimismo, no existe ningún medio para buscar ni para realizar funciones de "control de E/S" como ioctl () en Unix. De hecho, el KERNAL resulta mucho más cercano a la filosofía de Plan-9 en este caso, donde una aplicación abriría un canal de "comando" especial al dispositivo indicado para realizar dichas transacciones "meta" o "fuera de banda". Por ejemplo, para eliminar ("borrar") un archivo de un disco, el usuario normalmente "abrirá" el recurso llamado S0:THE-FILE-TO-RMV
en el dispositivo 8 o 9, canal 15. Según la convención establecida en el mundo de Commodore de 8 bits, el canal 15 representa el "canal de comando" para los periféricos, que se basa en técnicas de paso de mensajes para comunicar tanto comandos como resultados, incluidos casos excepcionales. Por ejemplo, en Commodore BASIC , podrían encontrar software no muy diferente al siguiente:
70 ... 80 REM GIRA LOS REGISTROS ACTUALMENTE ABIERTOS EN EL CANAL LÓGICO N.º 1. 90 CERRAR 1 100 ABRIR 15 , 8 , 15 , "R0:ERROR.1=0:ERROR.0" : REM RENOMBRAR ARCHIVO ERROR.0 A ERROR.1 110 ENTRADA N.º 15 , A , B$ , C , D : REM LEER CANAL DE ERROR 120 CERRAR 15 130 SI A = 0 ENTONCES IR A 200 140 IMPRIMIR "ERROR AL RENOMBRAR ARCHIVO DE REGISTRO:" 150 IMPRIMIR "CÓDIGO: " + A 160 IMPRIMIR "MENSAJE: " + B$ 170 FIN 200 REM CONTINUAR PROCESANDO AQUÍ, CREANDO UN NUEVO ARCHIVO DE REGISTRO A MEDIDA QUE AVANZAMOS... 210 ABRIR 1 , 8 , 1 , "0:ERROR.0,S,W" 220 ...
Los números de dispositivo, según la documentación establecida, están restringidos al rango [0,16]. Sin embargo, esta limitación proviene de la adaptación específica del protocolo IEEE-488 y, en efecto, se aplica solo a los periféricos externos. Con todas las llamadas al sistema KERNAL relevantes vectorizadas, los programadores pueden interceptar llamadas al sistema para implementar dispositivos virtuales con cualquier dirección en el rango de [32,256]. Es posible que se pueda cargar un binario de controlador de dispositivo en la memoria, aplicar parches a los vectores de E/S de KERNAL y, a partir de ese momento, se pueda direccionar un nuevo dispositivo (virtual). Hasta ahora, esta capacidad nunca se ha conocido públicamente como utilizada, presumiblemente por dos razones: (1) KERNAL no proporciona medios para asignar dinámicamente los identificadores de dispositivo y (2) KERNAL no proporciona medios para cargar una imagen binaria reubicable. Por lo tanto, la carga de las colisiones tanto en el espacio de E/S como en el espacio de memoria recae sobre el usuario, mientras que la compatibilidad de la plataforma en una amplia gama de máquinas recae sobre el autor del software. No obstante, se podría implementar fácilmente un software de soporte para estas funciones si se desea.
Los formatos de nombres de archivos lógicos tienden a depender del dispositivo específico al que se dirige. El dispositivo más común utilizado, por supuesto, es el sistema de disquetes, que utiliza un formato similar a MD:NAME,ATTRS
, donde M es una especie de indicador ($ para lista de directorios, @ para indicar el deseo de sobrescribir un archivo si ya existe, sin usar en caso contrario), D es el número de unidad de disco físico (opcional) (0: o 1: para sistemas de doble unidad, solo 0: para unidades de un solo disco como el 1541, et al., que por defecto es 0: si no se especifica), NAME
es un nombre de recurso de hasta 16 caracteres de longitud (se permiten la mayoría de los caracteres excepto ciertos caracteres especiales), y ATTRS
es una lista opcional separada por comas de atributos o indicadores. Por ejemplo, si el usuario desea sobrescribir un archivo de programa llamado PRGFILE
, podría ver un nombre de archivo como @0:PRGFILE,P
utilizado junto con el dispositivo 8 o 9. Mientras tanto, un nombre de archivo para el controlador RS-232 (dispositivo 2) consta simplemente de cuatro caracteres, codificados en formato binario. [8]
Otros dispositivos, como el teclado (dispositivo 0), el casete (dispositivo 1), la interfaz de pantalla (dispositivo 3) y la impresora (dispositivo 4 y 5), no requieren nombres de archivo para funcionar, ya sea asumiendo valores predeterminados razonables o simplemente no necesitándolos en absoluto.