_______________________________________________________________________ /* ATDT MAGAZINE :::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[0x03-12]: NUMERO 0x03::::::::::::::::::::::::::::::::::::::::::::::::::::::::: "Retrotem: Term multimedia para C64"por pastbytes */ ======================================================================== Introduccion Hace poco mas de 1 año, mas precisamente en febrero de 2020, comenzaba un pequeño experimento que se convirtio en un proyecto que tuvo varios logros tecnicos interesantes. Retroterm es una terminal para Commodore 64, pero es una terminal muy particular. Conectandose a un BBS estandar es una terminal muy simple, que solo tiene envio y recepcion de texto. Pero cuando se conecta a un BBS especial, es capaz de hacer streaming de audio PCM (digitalizado) con una calidad de 4 bits y un muestreo de 11520 Hz, mostrar imagenes en 16 colores, o recibir bloques de datos a maxima velocidad, para por ejemplo descargar programas directamente a memoria RAM. Todo esto es posible gracias a que Retroterm funciona siempre a una velocidad de 57600 bps, y a un protocolo propio que llamamos TURBO56K. .oooooo. .ooo .o d8P' `Y8b .88' .d88 888 d88' .d'888 888 d888P"Ybo. .d' 888 888 Y88[ ]88 88ooo888oo `88b ooo `Y88 88P 888 `Y8bood8P' `88bod8' o888o Commodore 64, procesadores y RS232 Pero volvamos al inicio. Cuatro años antes de la primera version, en 2016, habiamos logrado enviar y recibir por RS232 a 57600 bps, y enviar a 115200 bps. Para poner esto en contexto, la Commodore 64 es una computadora de 1982, con 64K de memoria RAM y un procesador compatible con el MOS 6502, corriendo a una velocidad de 1 MHz. Analicemos esto. Un procesador hace todo al ritmo de una señal de reloj que le marca la velocidad de ejecucion. Cada operacion que realiza el procesador esta sincronizada con ese reloj, y tener un reloj de 1 MHZ implica que hay 1 millon de ciclos de reloj por segundo. La mayoria de las instrucciones de este procesador se ejecutan entre 2 y 4 ciclos de reloj. Suponiendo que las instrucciones usaran 3 ciclos de reloj, esto significaria que en 1 segundo podriamos ejecutar 1000000 de ciclos / 3, esto es 333333 instrucciones. Y por que es importante esto? Veamos. 57600 bits por segundo no parece mucho, uno pensaria que con un procesador de 1 MHz podria manejarlo sin problemas. Pero resulta que la Commodore 64 no tiene un chip encargado del puerto RS232, entonces debe hacer tanto el envio como la recepcion por software. En RS232 se envian bytes en serie, un bit tras otro, donde cada bit tiene una duracion exacta. Para recibir este byte, el procesador debe detectar la llegada del dato, y empezar a temporizar la duracion de cada bit, leyendo desde el puerto cada uno de los bits en el momento exacto, y almacenandolos en memoria hasta completar el byte. Esto significa que el procesador debe estar dedicado a leer los bits desde el puerto serie, mientras se mantiene sincronizado con esos datos, por lo que en principio no puede hacer nada mas. Ahora volviendo a la velocidad, a 57600 bits por segundo cada bit dura 17 ciclos de reloj, lo cual deja ejecutar al procesador un promedio de casi 6 instrucciones por bit. Este numero sale de dividir 1 millon de ciclos de reloj que hay en 1 segundo, por 57600 bits que se pueden enviar en ese mismo tiempo, esto es 1000000 / 57600 = 17,361 ciclos de reloj por bit. Ahora 1 MHz ya no parece tanto. Sin embargo, a pesar de que el procesador tiene el tiempo justo para recibir los datos, todavia puede manejarlo sin problemas. La dificultad esta en que los datos pueden llegar en cualquier momento, y esto impide que el procesador pueda hacer otras tareas, ya que siempre debe estar atento a la llegada de un byte. Terminales, velocidad y recepcion Ademas de enviar y recibir datos por el puerto serie, una terminal debe como minimo leer el teclado e imprimir en pantalla. Es necesario encontrar una manera de poder realizar todas esas tareas repartiendo el tiempo de procesador disponible. Algunas terminales realizan el envio y recepcion "en simultaneo" con el resto de las funciones, pero esto limita la comunicacion a un maximo de 1200 o 2400 bps, ya que por encima de estas velocidades la perdida de precision es muy grande. Otro metodo consiste en modificar ligeramente el cableado de los modems para usar asistencia de hardware tanto en envio como en recepcion, pero esto solo funciona a 9600 bps y debe tener soporte especifico tanto del modem como de la terminal. El metodo que elegimos para Retroterm es el de la dedicacion exclusiva a la comunicacion, esto es, que durante el envio y la recepcion el procesador no hara otra cosa, lo que nos permite alcanzar los 57600 bps. Pero para lograr esto, tenemos que poder elegir el momento en que enviamos y recibimos, y la solucion es usar las lineas RTS y CTS del RS232. La funcion original de RTS y CTS no era la misma que en la actualidad, ya que eran señales pensadas para la comunicacion entre DTE (computadora) y DCE (modem). Desde la decada de 1990 estas lineas se usan para la comunicacion entre terminales. Hoy RTS es usada por la terminal para indicar a la otra parte que esta lista para recibir datos, y en caso de no poder recibir, simplemente desactiva RTS. De esta manera, ya tenemos el mecanismo para controlar cuando llegan los datos, pero ahora debemos decidir cuando nos conviene recibirlos. Muchas de las computadoras de la decada de 1980 estaban diseñadas especificamente para un sistema de television, ya que se pensaron para conectarse a un televisor en la mayoria de los casos. De estas maquinas, algunas tenian memoria de pantalla independiente de la RAM principal, y otras tenian la memoria de video compartida con la RAM del procesador. La Commodore 64 pertenece a estas ultimas, tiene un chip de video que puede acceder a 16K de memoria principal para almacenar los datos de pantalla, sean graficos o texto. Si bien esto tiene algunas ventajas, tambien tiene la desventaja de que el procesador y el chip de video compiten por el uso de la memoria. Cuando el chip de video debe generar una imagen, algo que hace 50 o 60 veces por segundo dependiendo del sistema de TV, debe detener al procesador para poder leer los datos de texto o graficos, ya que no pueden acceder ambos simultaneamente. Esto ocurre varias veces durante la generacion de la imagen, excepto cuando se esta dibujando alguno de los bordes de la pantalla, o cuando se deshabilita la generacion de video. Ya que durante los bordes el procesador puede estar seguro de no tener interrupciones por parte del chip de video, elegimos comenzar la recepcion de datos apenas empieza a dibujarse el borde inferior de la pantalla. De esta manera, ya tenemos como indicar que estamos listos para recibir datos, y tenemos decidido cuando recibirlos. Primeras versiones y velocidad en modo normal La primera version de Retroterm fue un ejecutable de 626 bytes, de los cuales los dos primeros bytes son la direccion de carga, y del resto, 122 estan sin usar, ya que corresponden al codigo de streaming de audio PCM que aun no estaba habilitado. En esta version se definio la estructura basica del programa, que con algunas variaciones aun se mantiene. Una parte del codigo se ejecuta sincronizado con el chip de video, el cual permite disparar una interrupcion en una linea de video determinada. Ya vimos que nos convenia comenzar la recepcion cuando se empieza a dibujar el borde inferior de la pantalla, por lo que configuramos el chip para dispararla en la linea 251. En esta rutina de interrupcion, se recibe 1 byte, se envia 1 byte, se ingresa cualquier byte recibido a un buffer de impresion, se envia cualquier caracter leido desde el teclado, se procesa el parpadeo del cursor, y se termina llamando a la rutina de la ROM encargada de leer el teclado. En el programa principal, un bucle infinito se encarga de imprimir cualquier caracter ingresado al buffer. Tanto la lectura del teclado como la impresion en pantalla se hacian con codigo propio de la ROM del sistema. Una caracteristica distintiva de Retroterm que tambien se ejecuta durante la interrupcion es el sonido de impresion en pantalla, que es un homenaje a la pelicula War Games. En este punto, ya teniamos una terminal basica capaz de comunicarse a 57600 bps usando RTS/CTS, pero enviando y recibiendo solo 1 caracter por cuadro de video, es decir 50 o 60 caracteres por segundo dependiendo del sistema de TV de la maquina. Si tenemos en cuenta que cada byte se compone de 10 bits (start, 8 bits de datos, stop), 50 caracteres por segundo seria equivalente a una velocidad constante de 500 bits por segundo. Ya que la velocidad mas usada en la Commodore 64 para modems modernos es de 1200 bps, elegimos recibir 3 caracteres por cuadro, lo que nos da una velocidad equivalente a 1500 bps en PAL y 1800 bps en NTSC, suficiente para superar los 1200 bps. Estos numeros salen de multiplicar 3 caracteres por cuadro x 50 cuadros por segundo en PAL x 10 bits por byte, que nos da 1500 bps. En NTSC el calculo seria: 3 x 60 x 10 = 1800 bps. Como Retroterm se penso como un cliente donde en principio no se envian grandes cantidades de datos, la transferencia no es simetrica, siendo menor la velocidad de envio, que sigue siendo de 50 caracteres por segundo en PAL (equivalente a 500 bps) y de 60 cps en NTSC (equivalente a 600 bps). El protocolo TURBO56K entra en escena Como ya explicamos, en la Commodore 64 tenemos la desventaja de que el procesador sea interrumpido por el chip de video durante la generacion de la imagen, lo cual nos obliga a tener que hacer la recepcion durante el dibujado del borde. Pero que pasaria si pudieramos evitar esto? Podriamos disponer del 100% del tiempo del procesador para recibir bytes en una transferencia continua. Y que tan alta podria ser esta transferencia? Veamos. A 57600 bps estariamos recibiendo 5760 bytes por segundo, si quisieramos recibir 64 Kbytes de datos (la cantidad total de memoria RAM que tiene la Commodore 64), podriamos hacerlo en 65536/5760 = 11,37 segundos. Esta seria la velocidad maxima teorica, sin pausas entre bytes. Ahora empiezan a verse las ventajas de trabajar siempre a 57600 bps, pero para lograr esto deberiamos eliminar la interferencia del chip de video, y esto solo es posible deshabilitando la generacion de la imagen, es decir, tendriamos que quedarnos sin video. La primera decision que se tomo fue que Retroterm tuviera dos modos de operacion, el que vimos hasta ahora seria el modo normal, con 1 caracter enviado y 3 caracteres recibidos por cuadro. El otro modo de operacion seria el modo turbo, donde se apagaria la pantalla y se alcanzaria una transferencia maxima. Habia que encontrar una manera de seleccionar el modo de operacion, y la solucion fue crear un protocolo que permitiera la navegacion en BBS PETSCII (con el juego de caracteres de la Commodore 64) y a la vez posibilitara activar funciones especiales de la terminal. Despues de analizar el juego de caracteres, se eligio reservar el codigo 255 para entrar a modo comando, por ser un caracter duplicado y por lo tanto no utilizado. Si la terminal recibe un caracter con ese valor, automaticamente entra en modo comando, y comienza a interpretar los bytes como comandos y parametros. Si estando en este modo recibe un byte de valor 254, volvera al modo normal, y comenzara a imprimir en pantalla el texto recibido. Comandos, parametros y modos de video El primer comando implementado fue la transferencia de un bloque de bytes directo a memoria, en principio para poder mostrar pantallas graficas (bitmaps), ya que Retroterm no iba a ser una terminal, sino un programa para hacer presentaciones controladas remotamente. Ese es el origen de la orientacion multimedia de la terminal. Para mostrar una imagen son necesarias 2 o 3 transferencias dependiendo del modo bitmap elegido, que puede ser multicolor (3 transferencias) o alta resolucion (2 transferencias), y luego configurar el chip de video para activar el modo de video correspondiente. Esto llevo a agregar 3 nuevos comandos, uno para activar la pantalla de alta resolucion, otro para activar la pantalla multicolor, y otro para volver al modo texto. El comando de transferencia originalmente requeria 4 bytes de parametros indicando la direccion de inicio en la memoria donde se almacenaria el bloque de bytes transferido, y otros dos bytes indicando la cantidad de bytes a recibir. Con el tiempo esta operacion se dividio en etapas, un comando que indicaria la direccion inicial, que quedaria almacenada como un puntero interno de la terminal, y otro comando que indicaria la cantidad de bytes a transferir e iniciaria la transferencia. Durante la transferencia se apaga automaticamente la pantalla, y se vuelve a habilitar al finalizar. De esta manera pueden convivir un modo de texto con una transferencia razonable, y un modo de transferencia rapida con la pantalla apagada por unos segundos. Los comandos que seleccionan el modo de video tienen como parametros los colores de fondo y borde de la pantalla, por lo que no estamos limitados a una terminal con texto sobre fondo negro. Pensando en el futuro, se agregaron comandos alternativos para ajustar el puntero a memoria para las transfencias, sin especificar direcciones absolutas. Esto se hizo para apuntar a las 3 areas de memoria que maneja el chip de video: la memoria de texto, la memoria de color, y la memoria de bitmap. De esta manera nos independizamos de la implementacion de la terminal, ya que la pantalla puede tener una direccion diferente en distintas maquinas (una Commodore 128 en modo nativo, por ejemplo), y nos abre la posibilidad de implementar varias paginas de texto en el futuro. Y por supuesto, el uso mas evidente de los comandos de transferencias es la descarga de programas directamente a memoria. Esto tiene la ventaja de poder ejecutar el programa descargado simplemente saliendo de la terminal, siempre que el programa no haya sobreescrito el espacio de la misma. Streaming de audio PCM, la transferencia llevada al limite Originalmente las transferencias de datos se hacian con la maxima transferencia posible, pero esto apenas dejaba tiempo para procesar el byte recibido, almacenarlo en memoria, incrementar el puntero y decidir si se habia transferido la cantidad de bytes especificada. Todas esas tareas debian realizarse entre la recepcion del ultimo bit y el comienzo del siguiente byte. Recordemos que no habia pausas entre bytes. Debido a esta dificultad y a algunos errores de recepcion ocasionales se decidio hacer una transferencia byte por byte activando y desactivando RTS. Esto hizo muy seguras las transferencias pero tambien ligeramente mas lentas que el maximo teorico. La maxima transferencia posible de 5760 bytes por segundo hizo que surgiera la pregunta: y si transferimos audio digitalizado directamente al chip de sonido? 5760 bytes por segundo nos daria una calidad de 5760 Hz, insuficiente para musica pero suficiente para representar la voz. Si pudieramos recibir un byte y colocarlo inmediatamente en la salida de sonido antes de que llegue el siguiente, tendriamos una transmision en vivo de audio digitalizado. En poco tiempo, luego de crear una rutina de recepcion especifica para esa funcion, se logro ajustar la temporizacion para recibir el audio correctamente. El audio PCM es el que conocemos como audio digitalizado, donde se representa el sonido con muestras de determinada calidad. Por ejemplo el audio de un CD tiene una calidad de 16 bits, con un muestreo de 44100 Hz, es decir que en un segundo de audio hay 44100 muestras, cada una representada por 2 bytes. El metodo mas comun que usa la Commodore 64 para reproducir audio PCM es colocar cada muestra en el control de volumen, que tiene 16 niveles, esto es, un volumen de 4 bits. Si enviamos 5670 bytes por segundo, cada una de esas muestras debe colocarse en el volumen luego de recibidas. Pero si el volumen es de 4 bits, estamos desperdiciando la mitad de cada byte. El siguiente experimento fue compactar el audio de manera de almacenar 2 muestras de 4 bits por byte, lo cual duplicaba la transferencia, ya que ahora transferiamos el doble de datos. Esto hizo que la cantidad de muestras por segundo aumentara a 5760 x 2 = 11520. Que significa esto? Que ahora podiamos enviar audio en vivo a una calidad de 4 bits y con un muestreo de 11,5 KHz, exagerado para la voz y suficientemente razonable para que la musica sea reconocible. Ahora no solo habia que lograr recibir un byte, sino que durante la propia recepcion habia que colocar 2 muestras en la salida de sonido, una al empezar el byte y otra por la mitad, de manera de tener un muestreo mas o menos estable. Si bien requirio muchas pruebas y ajustes, esto tambien se logro sin detener en ningun momento la recepcion, que ocurre con la maxima transferencia posible, sin pausas entre bytes. Conclusion Retroterm, como dije varias veces, fue un pequeño experimento que se salio de control. Hoy es un proyecto que genero una terminal multimedia, un nuevo tipo de BBS para aprovechar esas caracteristicas, y un protocolo que continuamente se sigue actualizando. Al momento de escribir esto tenemos en las etapas finales de desarrollo una nueva version de la terminal y otra del BBS, con su correspondiente ampliacion del protocolo TURBO56K. La nueva version abandona las rutinas de impresion del sistema, implementando codigo propio. Esto se hizo para poder definir una ventana de texto que limite la region de pantalla donde se puede imprimir. Hay comandos para definir estas ventanas, y ahora la terminal tiene la capacidad de trabajar en pantalla dividida, mostrando en la parte superior una imagen grafica y en la inferior un texto, con el limite divisorio definible por comando. Tambien se agrego un comando para un nuevo tipo de streaming que envia en vivo los valores a colocar en los registros del chip de sonido, para poder reproducir musica ".sid" sin tener que descargarla a memoria. Cuando comence esto como un simple experimento, pense que no pasaria mucho tiempo antes de perder el interes y pasar a otro proyecto, pero un año despues todavia surgen ideas interesantes para probar. Tambien hay que decir que las cosas podian haber salido mal desde el principio, y tal vez este proyecto no habria llegado muy lejos. En el camino se fue sumando gente para las pruebas, para poner los BBS en linea, y para la programacion, tanto de la terminal como del BBS. Hace mucho tiempo que este proyecto dejo de ser el trabajo de una sola persona. Y en el futuro, cuando no haya mucho mas que explorar en una C64, puede que haya versiones para otras plataformas, muy probablemente Commodore 128, y puede que hasta maquinas tan diferentes como las MSX. ======================================================================== FILES: -> bin/RTERM011-MDM.prg (para MODEM WIFI en C64) -> bin/RTERM011-CART-VICE.prg (para TURBO232 o VICE) ======================================================================== Pagina del proyecto: www.pastbytes.com/retroterm Email de contacto: info@pastbytes.com Pastbytes > Usuario y programador de computadoras desde 1986 / Usuario de Amiga desde 1992 / Retrocomputacion ______________________________________________________________________________ !EOF -> atdt-zine-0x03-12.txt