VIC-veinte...ando con un ZX Spectrum o del Basic 2.0 al Basic Sinclair (PARTE 3) A manera de introducción. Ya he tratado primero sobre el emulador del VIC-20 para el Spectrum llamdo "TWENTY COMMODES" y las sentencias y funciones así como mensajes de error del VIC-20. En la segunda parte traté sobre los gráficos, color y sonido del VIC-20. En esta tercera parte paso a comparar el TWENTY COMMODES con las versiones creadas por Simon Owen para el SAM Coupe y el +3 exclusivamente. Este artículo se divide en tres partes. La primera es referente al emulador para el SAM, por fines comparativos; la segunda es sobre los gráficos en alta resolución del VIC aun no tratados con detenimiento, además de aquellas funciones y sentencias del VIC que aun no han sido (o podido ser) emuladas. Y la tercera ya trata sobre la versión exclusiva para +3. Y por último mis conclusiones al respecto. I - VIC-20 Emulator versión SAM Vic20emu es un emulador de VIC-20 para el SAM Coupé y el ZX Spectrum. Emula al procesador 6502-y a este micro basado en dicho procesador, producido en 1980 por Commodore Business Machines (CBM). Características: Plena emulación del 65C02. Memoria base + 3K RAM de expansión. Modo gráfico de alta resolución. La paleta de 16 colores del VIC. Sonido a 4 canales (bajo/alto/soprano/ruido). Joystick y teclado. La velocidad es de cerca de 1/7 de la del micro original, pero eso también depende de cuanto se está escribiendo en la pantalla y de la mescla de modos de direcciones usadas. Un SAM normal corre un Z80B a 6MHz. Usando el acelerador Quazar Mayhem (a 20MHz) nos acercamos a la velocidad original. Además del incremento de la velocidad del procesador, se beneficia de la contención reducida de memoria y del uso fuerte de registros de la emulación. El redimensionado de la pantalla está posibilitado, pero los caracteres a doble alto no. El modo multi-color posiblemente nunca sea implementado ya que requiere del modo 4 del SAM, lo que lo volvería considerablemente más lento. La version para descargar es la 1.3, siendo su última actualización: Setiembre 4 del 2008. El programa VIC-20 Emulator está en formato .DSK zipeado y es de 38K. El código fuente se puede descargar de GitHub. Controles --------- Tecla Acción Numpad-0 sale al menú de Snapshots Teclas de Cursor Joystick Cntrl botón de disparo NumPad-1/3/5/7 F1 / F3 / F5 / F7 NumPad-2/4/6/8 Cursor abajo/ izquierda/ derecha/ arriba Esc RUN/STOP (sostener y presionar Shift para el NMI) Edit Shift derecho Tab Control Inv tecla CBM ~ π (Pi) Todos los símbolos de las otras teclas han sido mapeados al teclado normal del SAM. Nota: hasta aquí mi traducción de la info encontrada en la página original en inglés de su autor y que uno puede encontrar en la WEB: "https://simonowen.com/sam/vic20emu/". Y ahora paso a mis observaciones... Sobre la versión para SAM Tras descargar y dezipear el archivo, me doy con el "vic20emu.dsk" el cual decidí que lo renombraría como "vic20emu.sam.dsk" para diferenciarlo de otros DSK. Para ejecutarlo solo me queda probar ya sea SimCoupe o ASCD. Una vez elegido el emulador del SAM, debo estar en la pantalla inicial con las franjas de color, Ir al menú FILE y cargar el DSK, solamente entonces autobutea y nos muestra lo sigte.: VIC-20 Emulator v1.3 --------------- Escrito por Simon Owen https://simonowen.com Presione F0 estando en el emulador para ir al menú. Para el control del joystick, use los cursores y CNTRL para disparar Pulse una tecla para empezar. Una vez hecho eso, ya estamos en la pantalla típica del VIC-20 que nos muestra: **** CBM BASIC V2 **** 6655 BYTES FREE READY [] Si ahora pulsamos le tecla 0 en el teclado numérico, vamos al menú: Seleccione un snapshot: 1) GridRunner 2) Deflex 3) Blitzkreig 0) Resetea VIC-20 Seleccione opción o pulse RETURN para volver al emulador Y eso es todo lo más que podemos hacer, podemos tipear algo para probar, pero no hay modo de salvar nada al disco o de cargar algo aparte de los juegos del menú. En el estado en el que está la versión 1.3 más parece un "demo" de la versión final si es que el autor la llegara a sacar un día. Es decir, una versión que permita no solo tipear un programa sino también guardarlo a disco para poder recuperarlo después. Y sin más para decir sobre dicho emulador, paso a... II - ALTA RESOLUCION EN EL VIC-20 II.a - Con Super Expander Para solventar la falta de comandos gráficos en el Basic del Vic-20, a los de Commodore no se les ocurrió mejor solución que un cartucho llamado "VIC-1211 Super Expander with 3k RAM cartridge". A continuación una lista de las nuevas sentencias y funciones que el S.E. ofrecía: SENTENCIAS EFECTO GRAPHIC n Prepara la pantalla para el modo gráfico donde n = 0(texto)/1(mult.col.)/2(hi-res)/3(mixto)/4(vuelve a texto) COLOR s,b,c,a Selecciona el color de la pantalla, borde, texto, y col. auxiliares donde: s = 0 - 15 b = 0 - 7 c = 0 - 7 normal, 8 - 15 multi-color a = 0 - 15 SCNCLR por Screen Clear - borra una pantalla gráfica REGION c Seleccciona el color de los caracteres POINT c,x1,y1,[x2,Y2, ..., xn,yn] Traza un solo punto en la pantalla gráfica donde: x,y = 0 - 1023 DRAW c[,x1,y1] TO x2,y2 [TO x3,y3... TO xn,yn] Traza una linea entre dos puntos donde: c High-res Multi-color 0 pantalla pantalla 1 caracter borde 2 caracter caracter 3 caracter auxiliary CIRCLE c,x,y,rx,ry[,as,ae] Dibuja un circulo, elipse o arco donde: x,y = coordenadas del centro del circulo o elipse rx,ry = anchura y altura del circulo as,ae = opcionales: inicio y fin del arco en gradianes (0 to 100) PAINT c,x,y Llena un área encerrada con un color CHAR r,c,"txt" Imprime textos en la pantalla gráfica donde: r,c = fila y columna en pantalla del texto a imprimir FUNCIONES RGR(x) devuelve el modo gráfico en el que estamos RCOLR(X) da el valor de un registro de color RDOT(x,y) el color de un punto en la pantalla RPOT(X) la posición del paddle (si hay uno conectado y en uso) RPEN(X) la posición del light pen RJOY(x) la posición del joystick RSND(x) el valor de un registro de sonido Otras sentencias: SOUND s1,s2,s3,s4,v Fija los 4 tonos y el volumen todo a la vez donde: s1-s4 = las voces con valores de 0-255 (sin voz si s < 128) v = volumen: 0 (apagado) - 15 PRINT "{CONTROL + flecha izq.} car"[;] Equivale a la sentencia PLAY de otros BASICs. donde: Caracter Efecto p activa eco en la pantalla Q desactiva el eco Vn selecciona el volumen n = 0-9 Sn selecc. registro de sonido n = 1-4 On selecc. la octava n = 1-3 Tn selecc. el tempo n = 0-9 Rn pausa por 1 beat C,D,E,F,G,A,B toca una nota según la letra # toca una nota aguda $ toca una ota plana RETURN finaliza la música ; prosigue la música en la sigte. línea del listado El tempo es seleccionado de acuerdo a esta carta: Tempo Beats x min. Duración de la nota (1/60 de segundos) 0 900 4 1 600 6 2 450 8 3 300 12 4 225 16 5 150 24 6 112.5 32 7 56.25 64 8 28. 128 9 14. 255 KEY [n,"str$"] modifica las instrucciones asignadas a las 8 teclas de funciones donde: n = 1 - 8 str$ = una sentencia BASIC o texto al gusto del usuario sin parámetros - muestra la lista de funciones y sus contenidos Sin modificar muestra lo sigte.: Tecla Texto fl GRAPHIC f2 COLOR f3 DRAW f4 SOUND f5 CIRCLE f6 RUN + RETURN f7 POINT f8 LIST + RETURN Mientras que GRAPHICS es inexistente en el Spectrum, COLOR y REGION tienen su equivalente en BORDER, PAPER e INK. SCNCLR es CLS. POINT es PLOT. DRAW y CIRCLE tienen sus similes en el Basic Sinclair y con el mismo nombre. CHAR es PRINT AT. PAINT es inexistente en el ZX Spectrum pero puede ser simulado o usar BETABASIC el cual posee FILL en su lugar. PRINT "musica" no tiene equivalente en el Spectrum 48k, pero el 128k tiene PLAY en su lugar. En cuanto a KEY, este puede ser reemplazado en el Spectrum por el DEFKEY del Beta Basic. SOUND tiene su simil en el SOUND de Timex o el BEEP! del Beta Basic 4 para 128k. El manual del S.E. advierte que si se van a usar los comandos gráficos, hay que añadir al comienzo de dichas rutinas las sentencias GRAPHICS y COLOR. Bien, con el VIC 1211 S.E. ya no se necesita más POKEar para acceder a gráficos, color y sonido, ni PEEKear ya que hay funciones que suplen eso mismo. El problema fue que era más lento que el VIC sin expandir, lo cual lo hacía poco óptimo para escribir juegos. Otro detalle: no tenían forma breve a diferencia de las demás sentencias básicas del VIC. Encima no todos los usuarios lo tenían. Por lo mismo hubo muy pocos libros y revistas que publicasen listados BASIC con los comandos gráficos del S.E. Es decir que los programas solamente podían intercambiarse entre usuarios con ese cartucho ya que sin ello no había modo de que corrieran. II.b - Sin Super Expander Así que, ¿qué hacía un usuario del VIC sin el cartucho para acceder a la alta resolución? A continuación un extracto del libro "Guía de referencia del programador del VIC-20": Un caracter se puede mover un espacio a la vez, eso es 8 filas o columnas de puntos. Para un movimiento más suave, los caracteres deben moverse una fila de puntos a la vez, usando los gráficos de alta resolución. Se pueden mezclar la alta resolución, caracteres programables y los gráficos regulares. La alta resolución tiene algunos inconvenientes, razón por la que no se usa todo el tiempo. Requiere mucha más memoria mapear a bits toda la pantalla. Ya que cada caracter es de 8x8, y hay 23 lineas de 22 caracteres, la resolución es de 176x184 toda la pantalla. Eso nos da 32384 puntos separados, cada uno de los cuales requiere un bit en memoria, o 4048 bytes de memoria necesaria para mapear toda la pantalla. No es necesario mapear todos los bits de la pantalla. Solo se hace con tanto como memoria se posea, y usar el resto de la pantalla como borde, o para textos. Una sección de 54x64 puede ser más facil de trabajar. ¿Recuerdan los caracteres programables? Pues, el mapeado es casi del mismo modo. Cuando se crea un caracter programable se puede ver su forma al instante, incluso si el caracter ya está en la pantalla mientras lo modificas. Para ver eso, basta con tipear el sigte. programa y ejecutarlo: 100 POKE 36869,255 110 FOR I=7168 TO 7679:POKE I,PEEK(I+25600):NEXT 120 PRINT CHR$(147)"A" 130 FOR I=7176 TO 7183 140 FOR L=1 TO 1000:NEXT 150 READ A:POKE I,A:NEXT 160 DATA 60,36,36,36,36,36,255,255 ¡El caracter A se transforma en un sombrero de copa mientras uno observa! Este es el truco detras de los gráficos HI-RES en el VIC — hacer cambios directamente en la memoria de caracteres. Cuando el caracter está en la pantalla, ¡se ven los cambios ahi mismo! La mejor forma de fijar la pantalla HI-RES de 64x64 es imprimiendo 64 caracteres en una caja o matriz cuadrada. Hacer eso es solo el primer paso. El sigte. programa nos lo muestra: 10 POKE 36879,8:PRINT CHR$(147) 20 FOR L=0 TO 7:FOR M=0 TO 7 30 POKE 7680+M*22+L,L*8+M 40 NEXT:NEXT Ahora corre el programa... y ya tenemos 64 caracteres en la pantalla; pero no se pueden cambiar en modo alguno, ya que los códigos para las letras estan en la ROM. Añade ahora la sigte. linea al programa: 5 POKE 36869,255 Eso nos da los 64 caracteres programables, que se podrán modificar como una matriz de caracteres de 8x8, la cual la pantalla HI-RES de 64x64. Añade ahora la sigte. linea al programa para limpiar la pantalla HI-RES: 6 FOR I=7168 TO 7679:POKE I,0:NEXT Hay unos calculos simples para decidir qué puntos de cual caracter será alterado. Y ese numero es... CHAR =INT{X/8)*3+INT(Y/8) el que nos da el codigo del caracter que queremos modificar. Par encontrar la fila apropiada dentro del caracter, debemos usar esta formula: ROW =(Y/8-INT(Y/8))*8 Entonces, el byte en el que el punto(X,Y) de la memoria de caracteres se localiza, es calculado por: BYTE =7168+CHAR*8-ROW Lo último que debemos calcular es cual bit debe ser modificado. Eso se consigue con: BIT =7-(X-(INT(X/8)*8) Para convertir cualquier bit de la rejilla a coordenadas(X,Y), usamos esta linea: POKE BYTE,PEEK(BYTE)OR(2^BIT) Ahora hay que incluir todos estos calculos al programa. El sigte. ejemplo nos muestra al VIC trazando una curva de seno: 50 FOR X=0 TO 63 60 Y=INT(32+31*SIN(X/10)) 70 CH=INT(X/8)*8-INT(Y/8) 80 RO=(Y/8-INT(Y/8))*8 90 BY=7168+8*CH-RO 100 BI=7-(X-INT(X/8}*8) 110 POKE BY,PEEK(BY)OR(2^BI) 120 NEXT 130 GOTO 130 El calculo de la linea 60 cambia los valores de la función seno del rango -1 a -1 a otro de 0 a 63. Las lineas del 70 al 100 calculan el caracter, fila, byte y bit afectados con las formulas antes mostradas. La linea 130 congela el programa al ponerlo en un bucle infinito. Una vez se ha terminado de ver la pantalla, basta con dar RUN+STOP y RESTORE. Como último ejemplo, podemos modificar la curva de seno para dibujar un círculo: 55 Y1=32+SQR(64*X-X*X) 56 Y2=32-SQR(64*X-X*X) 60 FOR Y=Y1 TO Y2 STEP Y2-Y1 125 NEXT Notaremos que el resto de la pantalla se llena de un patrón de tiras. Es es porque los espacios vacios de la pantalla son llenados con el codigo 32, normalmente un espacio, y ahora es parte de los patrones de la rejilla. La sigte. linea limpia el resto de la pantalla: 11 FOR I=7680 TO 8185:POKE I,160:NEXT Nota: aunque el emulador de VIC para Spectrum no soporta el modo multicolor, vamos a ver como es de todos modos. Apaguemos primero el VIC y volvemos a encenderlo, y tipeamos este programa demonstración: 100 C=3788B+4*(PEEK(36866)AND128) 110 POKE 36878,11*16:REM FIJA EL COLOR AUXILIAR 120 PRINT CHR$(147)"AAAAAAAAAA" 130 FOR L=0 TO 9 140 POKE C+L,8 150 NEXT La pantalla está en blanco, el borde es cyan, los caracteres están en negro, el auxiliar es cyan claro. Aquí no estamos fijando los colores de pantalla, borde o los auxiliares, sino referencias a los registros asociados con dichos colores. Esto conserva memoria, ya que 2 bits pueden ser usados para coger 16 colores (pantalla y auxiliares) u 8 colores (caracteres y borde), lo que hace posible algunos buenos trucos. Con solo cambiar uno de los registros indirectamente cambia cada punto dibujado en ese color. Así, todo dibujo en pantalla, borde o auxiliar, puede cambiar en la pantalla al instante. Ejemplo: 100 PRINT CHR$(147)CHR$(18); 110 POKE 646,8 115 FOR L=1 TO 22:PRINT CHR$(32);:NEXT 120 POKE 646,6 130 PRINT "HIT A KEY" 140 GET A$: IF A$=""THEN 140 150 X=INT(RND(1)*18) 160 POKE 36878,X*16 170 GOTO 140 POKEando esa locación, los caracteres a imprimir pueden ser cambiados a cualquier color, incluso los caracteres multi-color. Por ejemplo, tipee este comando: POKE 646.10. Ya vimos el método elegido por los diseñadores del VIC-20 para manejar los gráficos de alta resolución y texto, y podemos compararlo con las soluciones de Sinclair para el Spectrum y ZX81 en ese campo. III - VIC-20 Emulator versión +3 Este es el port para Spectrum del VIC-20 Emu del SAM. Requiere de un +2A o +3 para correr correctamente ya que esos son los únicos Spectrum que permiten paginar la ROM, dejando 64K de RAM libres. Características: Plena emulación del 65C02. Memoria base + 3K RAM de expansión. Modo gráfico de alta resolución. Mapa de colores aproximado a la paleta del VIC. Sonido a 4 canales (bajo/alto/soprano/ruido). Joystick y teclado. La velocidad es de cerca de 1/10 comparado con el VIC original. Las limitaciones del chip AY-3-8912 del Spectrum provocan que la emulación del ruido no sea una fiel representación del generador de ruido del VIC. Particularmente notable en GridRunner, donde los disparos suenan como un "hiss" antes que como un "roar". La versión para descargar es la 1.3, al igual que la versión del SAM. Solo que en este caso el VIC-20 Emulator es un snapshot de 96K y no un DSK como el de SAM. Controles --------- SS = symbol shift Tecla Acción SS + 1/3/5/7 F1 / F3 / F5 / F7 SS + Space RUN/STOP (mantener presionado SS para hacer un NMI) SS + Enter tecla CBM SS + A π (Pi) SS + D | Kempston Joystick Cursores Joystick SS botón de disparo Muchos de los símbolos de las otras teclas han sido mapeados al teclado normal del ZX Spectrum. Pero no todos los emuladores de Spectrum permiten tipear símbolos normalmente, así que dependerá de la versión de Spectrum para poder tipear (como SS + X para £, etc.) CONCLUSIONES Sobre la versión para +3 En este caso ni siquiera hay una imagen de disco. Al deszipear el archivo, nos damos con dos ficheros en formato SZX, contieniendo uno el emulador para +3 y el otro un snap del juego GridRunner. Y eso es aparentemente todo. ¿Por qué un snapshot del programa en vez de un DSK? Cosas del autor. Así que para abrirlo elijo Spectaculator. Curiosamente aquí sí puedo hacer un poco más que con la versión del SAM. Puedo pasarlo a un disco mediante el MULTIFACE 3, o simplemente tipear listados del VIC y salvar snapshots en otros formatos como SNA o Z80. O incluso extraer el código del programa tipeado como binario. Comparándolo con el TWENTY COMMODES Así que sí, tenemos dos emuladores del VIC-20 para el Spectrum, uno en formato snapshot y el otro en formato TAP. El primero solamente es para +3 y nos ofrece 6655k de RAM a disposición del usuario, sin posibilidad de elegir otras configuraciones. El segundo en cambio es para cualquier Spectrum con más de una configuración de RAM siendo las cuatro últimas exclusivamente para +3 y +2a. Sobre el modo de intercambiar información entre ambos emuladores y estos con Win Vice, lo traté con más detalle en la parte 2 de esta serie de artículos. Y si no hay editor haxadecimal a la mano.... Ahora, ¿qué pasa si no tenemos un editor hexadecimal para quitar los dos bytes de la cabecera de los archivos creados por Win Vice? Sabiendo que la mayoría de programas del VIC son por lo general de casi 3k en un VIC-20 sin expandir, Podemos cargar el BINario directamente a la RAM del Spectrum. Si por ejemplo, lo cargamos en la dirección 32000 y su largo es de 2802, entonces lo salvamos de nuevo a partir de 32002 con largo 2800 y eso es todo, eso debería funcionar al volverlo a cargar con el VIC emulado. El mismo método se aplicaría inclusive con los BINarios de 8 a 16k. Y la inversa también es posible, si queremos devolverle los valores eliminados al BINario, lo cargamos de nuevo en la RAM misma del Spectrum, si por ejemplo elegimos la dirección 32002, entonces hacemos POKE 32000,1: POKE 32001,10 y volvemos a salvarlo como 32000,2802. Y para cerrar... Hasta este punto, ya sabemos todo cuanto necesitamos saber respecto a la memoria, gráficos y sonido del VIC. Lo único que ya nos faltaría por tratar sería sobre sus funciones de disco y el manejo de ficheros. Sería interesante pero aun no hay emulación de esto último en lo que a Twenty Commodoes para Spectrum se refiere. Paso entonces a los ejemplos prácticos para probar en el VIC emulado y si tiene o no su correspondiente en el Spectrum. Un pequeño listado ejemplo: 10 PRINT CHR$(147): REM USA ASCII PARA CLR/HOME 20 QU$=CHR$<34): REM USA ASCII PARA LAS COMILLAS 30 FOR I=1 TO 20:PRINT:NEXT:PRINT CHR$(1B)"PULSE UNA TECLA" 40 PRINT CHR$(18)"PARA CONTINUAR O ":PRINT QU$;"Q";QU$;" PARA SALIR "; 50 GET AN$:IF AN$="" THEN 50 60 IF AN$="Q" THEN END 70 GOTO 10 Y su conversión a Spectrum: 10 CLS 20 LET Q$=CHR$ 34 30 PRINT AT 20,0; INVERSE 1;"PULSE UNA TECLA" 40 PRINT INVERSE 1;"PARA CONTINUAR O ";:PRINT Q$;"Q";Q$;" PARA SALIR" 50 LET A$=INKEY$:IF A$="" THEN GOTO 50 60 IF A$="Q" THEN STOP 70 GOTO 10 Pero el sigte ejemplo: 1FORH=1TO505: REM LLENA LAS 505 POSICIONES DE LA PANTALLA DEL VIC 2PRINT"W"; : REM UN CORAZON EN EL LISTADO ORIGINAL 3NEXT 4FORC=8TO255STEP17 : REM C = EL COLOR DEL BORDE Y PAPEL 5POKE36879,C 6FORT=1TO500:NEXT: REM BUCLE DE RETARDO 7NEXT 8GOTO4 No tiene equivalente en el Spectrum, excepto el borde que cambia instantaneamente, el papel y la tinta de la pantalla no, a menos que se use una rutina en código máquina para replicar tal efecto. En cambio con Betabasic: 1 FOR H=1 TO 505 2 PRINT "W"; 3 NEXT H 4 FOR C=0 TO 7 5 BORDER C: ALTER TO INK INT(RND*C);PAPER INT(RND*C) 6 PAUSE 20 7 NEXT C 8 GOTO 4 Un ejemplo de sonido: 10 POKE 36878,15 : REM - volumen en alto (15). 20 S2=36875 : REM - S2 o cualquier variable para voz 2 30 READ N,D : REM - lee duracion y nota de lista DATA. 40 IF N=—1 THEN POKE S2,0:END : REM - apaga la voz y termina programa con - 1. 50 POKE S2,N : REM - toca nota N en S2. 60 FOR T=1 TO D:NEXT : REM - bucle con la duración de la nota. 70 GOTO30 : REM - vuelve a leer la lista DATA. 80 DATA 225,250,226,250,227,250,228,250,229,250,230,250,231,250,232,250,233,250,234,250, 235,250,-1,-1 : REM - DATAs... el 1er. número es la nota y el 2do. número es la duración de la nota. Y su equivalente Spectrum: 20 RESTORE 30 READ N,D 40 IF N=—1 THEN STOP 50 BEEP D,N 70 GOTO 30 80 DATA 0,1,2,1,4,1,5,1,7,1,9,1,11,1,12,1,14,1,16,1,17,1,-1,-1 Y con esto cierro esta tercera parte sobre el VIC en comparación con el Spectrum. (c)2021 zx_if1@hotmail.com