Commodore BASIC
El Commodore BASIC, también conocido como PET BASIC o CBM-BASIC, es el dialecto del lenguaje de programación BASIC utilizado en la línea de computadoras domésticas de 8 bits de Commodore International, que se extiende desde el PET de 1977 hasta el C128 de 1985. El núcleo se basa en Microsoft BASIC 6502 y, como tal, comparte muchas características con otros BASIC 6502 de la época, como Applesoft BASIC. Commodore obtuvo la licencia de BASIC de Microsoft en 1977 sobre la base de «un sólo pago, sin regalías» después de que Jack Tramiel rechazara la oferta de Bill Gates de una tarifa de US$3 (equivalente a $15,08 en 2023) por unidad, diciendo: «Yo ya estoy casado», y no pagaría más de US$25 000 (equivalente a $125 700 en 2023) por una licencia perpetua.[1] La versión original del PET era muy similar a la implementación original de Microsoft con pocas modificaciones. El BASIC 2.0 en el C64 también era similar y también se vio en algunos C128 y otros modelos. Los PET posteriores implementaban BASIC 4.0, similar al original pero agregando una serie de comandos para trabajar con disquete. El BASIC 3.5 fue el primero en desviarse realmente, agregando una serie de comandos para soporte de gráficos y sonido en el C16 y Plus/4. El BASIC 7.0 se incluyó con el Commodore 128 e incluía comandos de programación estructurados del BASIC 3.5 del Plus/4, así como palabras clave diseñadas específicamente para aprovechar las nuevas capacidades de la máquina. Se agregaron un editor de sprites y un monitor de lenguaje de máquina. El último, BASIC 10.0, fue parte del Commodore 65, que nunca fue comercializado. HistoriaCommodore tomó el código fuente del BASIC y lo desarrolló internamente para todas sus otras computadoras domésticas de 8 bits. No fue hasta el Commodore 128 (con la V7.0) que se mostró un aviso de derechos de autor de Microsoft. Sin embargo, Microsoft había incorporado un huevo de Pascua en la versión 2 del Commodore Basic que demostró su procedencia: escribiendo el (oscuro) comando El popular Commodore 64 implementaba el BASIC v2.0 en ROM a pesar de que la computadora se lanzó después de la serie PET/CBM que tenía la versión 4.0, porque la 64 estaba pensada como una computadora doméstica, mientras que la serie PET/CBM estaba dirigida a uso comercial y educativo donde se suponía que su lenguaje de programación incorporado se usaba más. Esto ahorró costos de fabricación, ya que el V2 encaja en ROM más pequeñas. Detalles técnicosEdición de programasUna característica conveniente del intérprete BASIC residente en ROM y el KERNAL era el editor de pantalla completa.[3][4] Aunque los teclados Commodore solo tienen dos teclas de cursor que alternan la dirección cuando presiona la tecla mayúsculas, el editor de pantalla permitía a los usuarios ingresar comandos directos o ingresar y editar líneas de programa desde cualquier lugar de la pantalla. Si una línea tenía el prefijo de un número de línea, se «tokenizaba» y se almacenaba en la memoria del programa. Las líneas que no comenzaban con un número se ejecutaban presionando la tecla RETURN cada vez que el cursor estaba en la línea. Esto marcó una mejora significativa en las interfaces de entrada de programas en comparación con otros BASIC de computadoras domésticas comunes en ese momento, que generalmente usaban un editor de línea, invocados por un comando También tenía la capacidad de guardar archivos con nombre en cualquier dispositivo, incluido el casete, un dispositivo de almacenamiento popular en los días del PET y que permaneció en uso durante la vida útil de los Commodores de 8 bits como una forma económica de almacenamiento masivo. La mayoría de los sistemas solo admitían nombres de archivo en disquete, lo que hacía que guardar varios archivos en otros dispositivos fuera más difícil. El usuario de uno de estos otros sistemas tenía que observar la ubicación del archivo en el contador de la grabadora, pero esto era inexacto y propenso a errores. Con el PET (y BASIC 2.0), los archivos de los casetes se podían solicitar por nombre. El dispositivo buscaría el nombre del archivo leyendo datos secuencialmente, ignorando cualquier nombre de archivo que no coincida. El sistema de archivos también estaba respaldado por una poderosa estructura de registro que podía cargarse o guardarse en archivos. Los datos del casete Commodore se grabaron digitalmente, en lugar de métodos analógicos menos costosos (y menos confiables) utilizados por otros fabricantes. Por lo tanto, se requería el Datasette especializado en lugar de una grabadora de cinta estándar. Había adaptadores disponibles que usaban un conversor analógico a digital para permitir el uso de una grabadora estándar, pero estos costaban solo un poco menos que el Datasette. El comando LOAD se puede usar con el parámetro opcional ,1 que cargará un programa en la dirección de memoria contenida en los dos primeros bytes del archivo (estos bytes se descartan y no se retienen en memoria). Si no se utiliza el parámetro ,1, el programa se cargará al inicio del área del programa BASIC, que difiere mucho entre máquinas. Algunas variantes de Commodore BASIC proporcionaron comandos El PET no admite programas reubicables y el comando LOAD siempre se cargará en los primeros dos bytes contenidos en el archivo del programa. Esto creó un problema al intentar cargar programas BASIC guardados en otras máquinas Commodore, ya que se cargarían en una dirección más alta que donde el BASIC de PET esperaba que estuviera el programa, había soluciones para «mover» los programas a la ubicación adecuada. Si un programa se guardaba en una máquina CBM-II, la única forma de cargarlo en un PET era modificando los primeros dos bytes con un editor de sector de disco ya que la serie CBM-II tenía su área de programa BASIC en $0, lo que daría como resultado que el PET intente cargar en la página cero y se bloquee. Las palabras reservadas de Commodore BASIC se podían abreviar ingresando primero una pulsación de tecla sin cambio y luego una pulsación de tecla cambiada de la siguiente letra. Esto establece el bit alto, lo que hace que el intérprete deje de leer y analice la declaración de acuerdo con una tabla de búsqueda. Esto significaba que la declaración hasta donde se estableció el bit alto se aceptó como un sustituto para escribir el comando completo. Sin embargo, dado que todas las palabras clave de BASIC se almacenaron en la memoria como tokens de un solo byte, esto fue una conveniencia para la entrada de declaraciones en lugar de una optimización. En el conjunto de caracteres predeterminado solo en mayúsculas, los caracteres desplazados aparecen como un símbolo gráfico; p.ej. el comando, Este método de tokenización tenía una falla tal que si uno incluía un Al abreviar las palabras clave, era posible incluir más código en una sola línea de programa (lo que podía ocupar dos líneas de pantalla en pantallas de 40 columnas, es decir, C64 o PET, o cuatro líneas en la pantalla de 22 columnas de VIC-20). Esto permitió un ligero ahorro para almacenar líneas de programa, que de otra forma hubieran necesitado líneas adicionales. Todos los comandos BASIC se tokenizaron y ocuparon 1 byte (o dos, en el caso de varios comandos de BASIC 7 o BASIC 10) en la memoria sin importar de qué manera se ingresaron. Las líneas tan largas eran una molestia para editar. El comando RendimientoAl igual que el intérprete de Microsoft BASIC, Commodore BASIC es más lento que el código de máquina nativo. Los resultados de las pruebas han demostrado que copiar 16 kilobytes de ROM a RAM toma menos de un segundo en código de máquina, en comparación con más de un minuto en BASIC.[cita requerida] Para ejecutar más rápido que el intérprete, los programadores comenzaron a usar varias técnicas para acelerar la ejecución. Una era almacenar valores de coma flotante de uso frecuente en variables en lugar de usar valores literales, ya que interpretar un nombre de variable era más rápido que interpretar un número literal. Dado que la coma flotante es el tipo predeterminado para todos los comandos, es más rápido usar números de coma flotante como argumentos, en lugar de números enteros. Cuando la velocidad era importante, algunos programadores convertían secciones de programas BASIC a lenguaje ensamblador del 6502 o 6510 que se cargaba por separado desde un archivo o se metía en la memoria desde instrucciones DATA en el final del programa BASIC, y ejecutado desde BASIC usando el comando Una característica única de Commodore BASIC es el uso de códigos de control para realizar tareas dentro de un programa, como borrar la pantalla o posicionar el cursor; estos se pueden invocar emitiendo un comando Las líneas de programa en Commodore BASIC no requieren espacios en ninguna parte (pero el comando LIST siempre mostrará uno entre el número de línea y la declaración), por ejemplo, Las líneas de programa pueden tener un total de 80 caracteres en la mayoría de las máquinas, pero las máquinas con texto de 40 columnas harían que la línea pasara a la siguiente línea en la pantalla, y en el VIC-20, que tenía una pantalla de 22 columnas, las líneas de programa podían ocupar hasta cuatro. BASIC 7.0 en Commodore 128 aumentó el límite de una línea de programa a 160 caracteres (cuatro líneas de 40 columnas o dos líneas de 80 columnas). Al usar abreviaturas como El orden de ejecución de las líneas de Commodore BASIC no estaba determinado por la numeración de líneas; en cambio, seguían el orden en que las líneas estaban vinculadas en la memoria.[7] Las líneas de programa se almacenaban en la memoria como una lista enlazada simple con un puntero (que contenía la dirección del comienzo de la siguiente línea de programa), un número de línea y luego el código tokenizado para la línea. Mientras se ingresaba un programa, BASIC reordenaba constantemente las líneas del programa en la memoria para que los números de línea y los punteros estuvieran todos en orden ascendente. Sin embargo, después de ingresar un programa, alterar manualmente los números de línea y los punteros con los comandos POKE podría permitir una ejecución desordenada o incluso dar a cada línea el mismo número de línea. En los primeros días, cuando BASIC se usaba comercialmente, esta era una técnica de protección de software para desalentar la modificación casual del programa. Los números de línea pueden variar de 0 a 65520 y toman cinco bytes en almacenarse independientemente de cuántos dígitos haya en el número de línea, aunque la ejecución es más rápida cuantos menos dígitos haya. Poner varias declaraciones en una línea usará menos memoria y se ejecutará más rápido. GOTO y GOSUB buscarán hacia abajo desde la línea actual para encontrar un número de línea si se realiza un salto hacia adelante, pero en caso de un salto hacia atrás, la búsqueda comienza desde el inicio de la programa. Esto ralentizará los programas más grandes, por lo que es preferible colocar las subrutinas de uso común cerca del inicio. Los nombres de variables solo son significativos para 2 caracteres; por lo tanto, los nombres de variable Commodore BASIC también es compatible con los operadores bit a bit AND, OR y XOR; aunque esta característica era parte del código básico de Microsoft BASIC 6502, por lo general se omitió en otros implementaciones como Applesoft BASIC. El formato numérico nativo de Commodore BASIC, como el de su padre MS BASIC, era en coma flotante. La mayoría de las implementaciones BASIC contemporáneas usaban un byte para el exponente y tres bytes para la mantisa. La precisión de un número de coma flotante que utiliza una mantisa de tres bytes es de solo unos 6,5 dígitos decimales, y el error de redondeo es común. Las implementaciones 6502 de Microsoft BASIC utilizaron aritmética de coma flotante de 40 bits, lo que significa que las variables requerían cinco bytes para almacenarse (cuatro bytes para la mantisa y un byte para el exponente) a diferencia de la coma flotante de 32 bits que se encuentra en BASIC-80. Mientras que las implementaciones 8080/Z80 de Microsoft BASIC admitían variables enteras y de doble precisión, las implementaciones 6502 eran solo de coma flotante. Aunque Commodore BASIC admite variables enteras con signo (indicadas con un signo de porcentaje) en el rango de -32768 a 32767, en la práctica solo se usan para variables de matriz y cumplen la función de conservar la memoria al limitar los elementos de la matriz a dos bytes cada uno (una matriz de 2000 elementos ocupará 10 000 bytes si se declara como una matriz de coma flotante, pero solo 4000 si se declara como una matriz de enteros). Denotar cualquier variable como un número entero simplemente hace que BASIC la convierta de nuevo a coma flotante, lo que ralentiza la ejecución del programa y desperdicia memoria, ya que cada signo de porcentaje requiere un byte adicional para almacenarse (ya que esto también se aplica a las matrices de números enteros, el programador debe evitar usarlas a menos que se usen matrices muy grandes que excederían la memoria disponible si se almacenaran como coma flotante). Además, no es posible hacer POKE o PEEK a ubicaciones de memoria por encima de 32767 con la dirección definida como un entero con signo. Se puede usar un punto (.) en lugar del número 0 (por lo tanto, Commodore agregó la declaración SYS, utilizada para iniciar programas en lenguaje de máquina, y no estaba en el código BASIC original de Microsoft, que presentaba solo la función USR para invocar rutinas de lenguaje de máquina. La declaración SYS carga automáticamente los registros de la CPU con los valores en $30C-$30F (C64, varía en otras máquinas); esto se puede usar para pasar datos a rutinas de lenguaje de máquina o como un medio para llamar a funciones del kernel desde BASIC (como ejemplo, Dado que las máquinas Commodore de 8 bits que no sean C128 no pueden iniciar automáticamente el software del disco, la técnica habitual es incluir un código auxiliar BASIC como Al igual que con la mayoría de las otras versiones de Microsoft BASIC, si una matriz no se declara con una instrucción DIM, se establece automáticamente en diez elementos (en la práctica, 11, ya que los elementos de la matriz se cuentan desde 0). Las matrices más grandes deben declararse o BASIC mostrará un error cuando se ejecute el programa y una matriz no se puede volver a dimensionar en un programa a menos que todas las variables se borren mediante una declaración CLR. Las matrices numéricas se llenan automáticamente con ceros cuando se crean, puede haber un retraso momentáneo en la ejecución del programa si se dimensiona una matriz grande. Las variables de cadena se representan etiquetando el nombre de la variable con un signo «$». Por lo tanto, las variables A diferencia de otras máquinas de 8 bits como Apple II, todas las máquinas de Commodore tienen un reloj incorporado que se inicializa en 0 al encenderse y se actualiza con cada marca del temporizador PIA/VIA/TED/CIA, por lo tanto, 60 veces por segundo. Se le asignan dos variables de sistema en BASIC, TI y TI$, que contienen la hora actual. TI es de solo lectura y no se puede modificar; si lo hace, aparecerá un mensaje de error de sintaxis. TI$ se puede usar para establecer la hora a través de una cadena de seis números (se produce un error al usar una cadena que no sea de seis números). El reloj no es un método de cronometraje muy confiable, ya que se detiene cada vez que se desactivan las interrupciones (realizadas por algunas rutinas del kernel) y acceder al puerto IEC (o puerto IEEE en el PET) retrasará la actualización del reloj unos pocos tics. La función RND en Commodore BASIC puede usar el reloj para generar números aleatorios; esto se logra mediante RND(0), sin embargo, tiene un uso relativamente limitado ya que solo se devuelven números entre 0 y 255. De lo contrario, RND funciona igual que otras implementaciones de Microsoft BASIC en el sentido de que se utiliza una secuencia pseudoaleatoria a través de un valor semilla fijo de 5 bytes almacenado al encender en ubicaciones de memoria $8B-$8F en la C64 (la ubicación difiere en otras máquinas). RND con cualquier número superior a 0 generará un número aleatorio amalgamado del valor incluido con la función RND y el valor inicial, que se actualiza en 1 cada vez que se ejecuta una función RND. RND con un número negativo va a un punto en la secuencia del valor semilla actual especificado por el número. Dado que la generación de números aleatorios verdaderos es imposible con la declaración RND, es más común en el C64 y C128 utilizar el canal de ruido blanco del chip SID para números aleatorios. BASIC 2.0 sufría notoriamente de una recolección de cadenas basura extremadamente lenta. La recolección de basura se invoca automáticamente cada vez que se ejecuta una función FRE y si hay muchas variables de cadena y matrices que se han manipulado en el transcurso de un programa, borrarlas puede llevar más de una hora en las peores condiciones. Tampoco es posible cancelar la recolección de basura ya que BASIC no escanea la tecla RUN/STOP mientras realiza esta rutina. BASIC 4.0 introdujo un sistema mejorado de recolección de basura con punteros hacia atrás y todas las implementaciones posteriores de Commodore BASIC también lo tienen. La función FRE en BASIC 2.0 sufría de otra falla técnica en el sentido de que no puede manejar números con signo superiores a 32768, por lo tanto, si la función se invoca en un C64 (38k de memoria BASIC), se mostrará una cantidad negativa de memoria BASIC libre (sumando 65535 al número informado obtendrá la cantidad correcta de memoria libre). El PET y el VIC-20 nunca tuvieron más de 32k de memoria total disponible para BASIC, por lo que esta limitación no se hizo evidente hasta que se desarrolló la C64. La función FRE en BASIC 3.5 y 7.0 corrigió este problema y FRE en BASIC 7.0 también se «dividió» en dos funciones, una para mostrar la memoria de texto de programa BASIC libre y la otra para mostrar memoria de variables libre. AlternativasSe lanzaron muchas extensiones BASIC para Commodore 64, debido a las capacidades relativamente limitadas de su BASIC 2.0 nativo. Una de las extensiones más populares fue DOS Wedge, que se incluyó en el Commodore 1541 Test/Demo Disk. Esta extensión al BASIC de 1 KB agregó una serie de comandos relacionados con el disco, incluida la capacidad de leer un directorio de disco sin destruir el programa en la memoria. Sus funciones se incorporaron posteriormente en varias extensiones de terceros, como el popular cartucho Epyx Fast Load. Otras extensiones de BASIC agregaron palabras clave adicionales para facilitar la codificación de sprites, sonido y gráficos de alta resolución como el Simons' BASIC. Aunque la falta de funciones de sonido o gráficos de BASIC 2.0 fue frustrante para muchos usuarios, algunos críticos argumentaron que, en última instancia, era beneficioso ya que obligaba al usuario a aprender lenguaje de máquina. Las limitaciones de BASIC 2.0 en el C64 llevaron al uso del lenguaje de máquina incorporado en la ROM del BASIC. Para cargar un archivo en una ubicación de memoria designada, una llamada leería el nombre del archivo, la unidad y el número de dispositivo: Una revista en disco para el C64, Loadstar, era un lugar de encuentro para programadores aficionados que compartían colecciones de proto-comandos para BASIC, llamados con el comando Desde el punto de vista de la programación moderna, las versiones anteriores de Commodore BASIC presentaban una serie de artimañas de mala programación para el programador. Como la mayoría de estos problemas derivaban de Microsoft BASIC, prácticamente todos los BASIC de computadoras domésticas de la época sufrían deficiencias similares.[11] El programador asignaba un número de línea a cada línea de un programa Microsoft BASIC. Era una práctica común incrementar los números en algún valor (5, 10 o 100) para facilitar la inserción de líneas durante la edición o depuración del programa, pero una mala planificación significaba que insertar grandes secciones en un programa a menudo requería reestructurar todo el código. Una técnica común era iniciar un programa en algún número de línea bajo con tabla de saltos ON...GOSUB, con el cuerpo del programa estructurado en secciones que comenzaban en un número de línea designado como 1000, 2000, etc. Si fuera necesario agregar una sección grande, simplemente se le podría asignar el siguiente número de línea principal disponible e insertarla en la tabla de salto. Las versiones BASIC posteriores en Commodore y otras plataformas incluían un comando DELETE y RENUMBER, así como un comando de numeración de línea AUTO que seleccionaría e insertaría automáticamente números de línea de acuerdo con un incremento seleccionado. Además, todas las variables se tratan como variables globales. Los bucles claramente definidos son difíciles de crear, lo que a menudo hace que el programador confíe en el comando GOTO (esto se rectificó más tarde en BASIC 3.5 con la adición de DO, LOOP, WHILE, UNTIL y EXIT). Las variables de bandera a menudo debían crearse para realizar ciertas tareas. Los BASIC anteriores de Commodore también carecen de comandos de depuración, lo que significa que los errores y las variables no utilizadas son difíciles de encontrar. Las estructuras IF...THEN...ELSE, una parte estándar de Microsoft BASIC Z80, se agregaron a BASIC 3.5 después de no estar disponibles en versiones anteriores de Commodore BASIC. Usar como interfaz de usuarioAl igual que otras computadoras domésticas, las máquinas de Commodore se iniciaban directamente en el intérprete BASIC. Los comandos de programación y archivo de BASIC se pueden ingresar en modo directo para cargar y ejecutar software. Si la ejecución del programa se detuviera con la tecla RUN/STOP, los valores de las variables se conservarían en la RAM y se podían consultar con el comando PRINT para su depuración. El 128 incluso dedicó su segundo banco de 64k al almacenamiento de variables, lo que permitió que los valores persistieran hasta que se emitiera un comando Si bien algunas versiones de Commodore BASIC incluían comandos Versiones y característicasUna lista de versiones de CBM BASIC en orden cronológico, con características añadidas sucesivamente: Versiones publicadas
Versiones inéditas
Paquetes de extensión notables
Véase tambiénReferencias
Enlaces externos
|