Convirtiendo listados del ZX80 y ZX81 al ZX Spectrum zx-80 integer basic | zx-81 fp basic | ________zx spectrum basic________ | | ________|________________ | | | | | |____etc,etc | | | | | | | | ts 2068 | | | | | basic | | ys megabasic | | | | | ql superbasic | | | | | | tk 90 basic | | | | betabasic |___128K basic | | sam coupe basic | |___sea change | | |___open se basic Cuando el se desarrolló el basic del ZX Spectrum, se decidió que sería una versión mejorada del basic del ZX-81, convirtiendo a este último en un subconjunto del Spectrum basic. Debido a ello, los listados de programas del ZX-81 se pueden teclear en el ZX Spectrum con muy pocos cambios, además de poderlos mejorar de modo considerable aprovechando las ventajas graficas y de sonido propias del Spectrum. A continuación, mi colección de notas sobre las palabras reservadas del ZX-81 que deben ser modificadas o ignoradas para que el listado Basic se pueda ejecutar en un Spectrum: NEWLINE / RUBOUT equivalen a las teclas ENTER y DELETE en el ZX80 y 81. En el TS-1000 y TS-1500 fueron renombradas justamente como "enter" y "delete" que es como figuran en el ZX Spectrum. ** (to power) es el signo de elevación a potencia, debe ser reemplazado por ^. Ejemplo: 2**4 (zx-80 y 81) <-> 2^4 (spectrum) "" (quote image) no confundir con el signo de cadena vacía o nula. Es un signo especial del ZX-81 que permite imprimir una " dentro de una cadena de texto. Inexistente en el Spectrum, se debe tipear dos veces el signo ". Ejemplo del manual del Spectrum: PRINT " No has acabado ""el Quijote"" todavia? " RAND en el ZX-81 equivale a RANDOMIZE en el Spectrum (en el ZX-80 es RAND en la tecla y RANDOMISE en la pantalla). CONT breve por CONTINUE (en el ZX-80 es CONT en el teclado pero aparece completo en pantalla). GOTO / GOSUB sin espacios en el ZX-81, (solo se ven así en el teclado del ZX-80 pero imprime GO TO y GO SUB igual que su sucesor el Spectrum). INPUT solo acepta una variable por linea ya sea numérica o de cadena igual que su antecesor el ZX80, de modo similar al INPUT del Basic del Camputers Lynx. FAST / SLOW No existen en el Spectrum, ya que éste funciona a la velocidad del ZX-81 en modo rápido (FAST) con la visualización fija en modo lento (SLOW), deben ser simplemente ignoradas. Nota: Aunque el ZX-81 carece de sonido, SLOW y FAST pueden ser usadas para generar curiosos efectos de sonido. En caso de que FAST fue usada para evitar que el usuario vea la pantalla, se usa CLS. SCROLL esta orden desplaza la pantalla una línea hacia arriba y dejando una línea vacía al fondo. El Spectrum, en vez de tener esta instrucción, hace la pregunta SCROLL? cada vez que se llena la pantalla, pero, si se desea convertirla cada vez que se la encuentre en un listado, debe hacerse lo sigte: RANDOMlZE USR 3582 (no se aconseja si el programa requiere de números aleatorios) LET scroll = USR 3582 (es más claro de usar) Otro modo de hacer scroll en el Spectrum es con POKE 23692,255. Para desactivarlo hay que hacer POKE 23692,4. Este POKE es preferible commo reemplazo al USR anterior. Tambien se la puede reemplazar por una sentencia INPUT ;. SAVE En el ZX81 para salvar un programa con autorun, bastaba con que la sentencia SAVE estuviera dentro del listado, de este modo al cargar con LOAD se autoejecutaba la instruccion de la linea sigte. a SAVE. Ejemplo del manual original: 5 REM "USELESS" 10 PRINT "THIS IS ALL IT DOES" 20 STOP 100 SAVE "USELESS" 110 GOTO 10 poner a funcionar la cinta en mdo grabacion, luego RUN 100 - y listo, salvado el programa en modo autorun tras esto la última letra de la sentencia SAVE se ponia en modo INV. en el listado. Las lineas 100 y 110 de este listado ZX81 se reemplazarian por 100 SAVE "USELESS" LINE 10 en el Spectrum y ejecutandola igual con RUN 100. Otro ejemplo: 740 SAVE "CUBOS" 750 RUN las dos lineas se reemplazan en el Spectrum como: 740 SAVE "CUBOS" LINE 1 Nota: El manual del ZX81 advierte que SAVE genera error si se usa dentro de una subrutina. Los programas en cinta de zx81 no pueden ser leidos por el spectrum a menos que se use un emulador o programa cargador conversor como el AM zxsp. PLOT / UNPLOT Inexistentes en el ZX-80. El ZX-81 puede trabajar con píxeles (picture elements), siendo la pantalla de 22 lineas por 32 columnas, lo cual nos da 704 posiciones de caracteres y cada una de estas contiene a su vez 4 pixeles, dándonos la resolución de pantalla de 64x44. PLOT x,y dibuja un punto en las coordenadas de x (0-63), y (0-43). UNPLOT x,y deshace el trazado por PLOT. Tanto PLOT como UNPLOT afectan la posición de PRINT. Ejemplo (del manual del ZX-81): 10 PLOT 21,21 20 PRINT "HEAVY QUOTES" 30 PLOT 46,21 El Spectrum trabaja con una resolución mayor de 256x192 y el PLOT ya no afecta a PRINT. En lugar de UNPLOT existe PLOT OVER 1;x,y. En ningun caso hay equivalencia real. Una solución ofrecida por algunas revistas(**) era: PRINT AT 2l-Y/2,31-X/2;x$ donde x$=CHR$ 136 o del 129 al 146 (para PLOT) y x$=" " o CHR$ 128 (para UNPLOT). En la práctica es mucho mejor otra alternativa que use PLOT y DRAW, así que... Para ello basta con definir la subrutina sigte: 8900 REM zx81 plot 8902 PLOT x*4,y*4: DRAW 3,0: DRAW 0,3: DRAW -3,0: DRAW 0,-3: DRAW 3,3: DRAW -3,0: DRAW 3,-3 8904 RETURN Ejemplo de su uso: 10 PLOT 0,0: PLOT 63,43 (en zx-81) - reemplazar por: 10 let x=0: let y=0: gosub 8900: let x=63: let y=43: gosub 8900 para replicar unplot basta con añadir OVER 1 o INVERSE 1 de este modo: 8910 REM zx81 unplot 8912 INVERSE 1: gosub 8900: INVERSE 0 8914 RETURN Ejemplo: 10 let x=0: let y=0: gosub 8910 Nota: la eleccion de OVER o INVERSE dependera de cual tiene mejor efecto en el programa. En caso de tener BetaBasic 1.8, se reemplaza todo por un procedimiento: 8900 DEFPROC plot81 8902 PLOT x*4,y*4: DRAW 3,0: DRAW 0,3: DRAW -3,0: DRAW 0,-3: DRAW 3,3: DRAW -3,0: DRAW 3,-3 8904 ENDPROC con eso la línea 10 se convierte en: 10 let x=0: let y=0: proc plot81: let x=63: let y=43: proc plot81 Si se tiene BetaBasic 3.xx o el 4: 9600 DEFPROC zx,n 9601 if n=81 then keywords 0: else keywords 3 9602 ENDPROC 9603 DEFPROC zplot,x,y 9604 PLOT x*4,(y+.7)*4;CHR$ 130 9605 ENDPROC 9606 DEFPROC unplot,x,y 9607 PLOT OVER 1;x*4,(y+.7)*4;CHR$ 130 9608 ENDPROC Para probar esta librería, hacer: 10 zx 81: zplot 0,0: zplot 63,43: pause 0 Con BetaBasic 3.xx y 4 podemos modificar las subrutinas originales para que se lean así: 8900 DEFPROC zplot,x,y,o: DEFAULT o=0 8902 PLOT OVER o;x*4,y*4: DRAW 3,0: DRAW 0,3: DRAW -3,0: DRAW 0,-3: DRAW 3,3: DRAW -3,0: DRAW 3,-3 8904 ENDPROC 8906 DEFPROC unplot,x,y 8908 zplot x,y,1 8904 ENDPROC Debido a que el PLOT del Spectrum no afecta a la posición de PRINT, si se desea replicar el efecto del zx81, habría que añadir al listado: IF x<>63 and y<>0 THEN PRINT AT 2l-Y/2,31-X/2; OVER 1;"(2 espacios)"; El IF es porque en el zx81, PLOT 63,0 seguido de PRINT genera un error si no se hace previamente SCROLL, mientras que en el Spectrum se desplazaría automáticamente una línea. POKE 16418,0 permite imprimir en las dos últimas líneas de la pantalla del zx-81, modificando la variable del sistema DF SZ. De este modo en vez del límite de 22 lineas, se llega a 24, permitiéndole a uno hacer PRINT AT 23,0. Es mejor usar INKEY$ en vez de INPUT para leer datos del teclado, ya que de lo contrario se debe pokear de vuelta a su valor original 2, o la maquina se cuelga. Si se la encuentra en un listado, debe ser omitida, ya que en el Spectrum su equivalente es 23659, pero cualquier intento de pokearlo causa un crash del sistema. Esto es debido a la rutina de AT, que limita a 22 como maximo, asi que hacer print at 23,0 como lo hace el zx81 causa el cuelgue, en cambio: 10 POKE 23659,0 20 PRINT AT 22,0;"Line 23"'"Line 24" 30 POKE 23659,2 40 PAUSE 0 funciona correctamente. Normalmente uno siempre usa PRIN #0;AT 0,0...;y #0;AT 1,0... con PAUSE 0, para imprimir en esas lineas e INPUT; para borrarlas. En el caso de listados conteniendo código máquina es más dificil, ya que habría que buscar si las llamadas a la ROM del ZX-81 tienen o no, su equivalente en la ROM del Spectrum. Por ejemplo la sigtes. líneas en ensamblador (*): 16514 6 ld b, N 16515 n 16516 205 call 0a2c llamada a CLS en el zx-81 16517 44 es 68 y 16518 10 14 en el Spectrum Para usarla hacer POKE 16514,24-n y ejecutarla con RAND USR 16514. En el Spectrum se la debe relocalizar a cualquier parte de la RAM o primera línea 1 REM. (*) publicada en COMPUTE jun.83 ed.37 vol.5 n.6 p.234 POKE Y*33+X+1+PEEK(16396)+PEEK(16397)*256,n (**) donde: Y = linea, X = columna, n= códigos 0-63 y 128-192 El zx80 y 81 pueden imprimir pokeando directamente en la pantalla de modo similar a como lo hace el VIC-20. Ya que no se puede replicar este pokeo en Spectrum, debe ser reemplazada por PRINT AT y,x;n$. Para leer la pantalla en el zx80 y 81, se teclea: PEEK(PEEK 16396+256*PEEK 16397+1+x+33*y) otro modo de leer la pantalla en el zx81 es: PEEK(PEEK 16398+PEEK 16399*256) - devuelve el codigo de la ultima posicion AT en el Spectrum se debe reemplazar con SCREEN$ (y,x). POKE 16388,x-256*INT(x/256): POKE 16389,INT(x/256) (**) Crea un área de seguridad RAMTOP en el zx81 a partir de "x" y equivale al Spectrum CLEAR x. POKE 16510,0 (**) Crea línea 0 en el zx81 y su equivalente es 23756 en un Spectrum sin IF1/Microdrive. Variable Frames zx81 (**): POKE 16436,255 LET t=(65535-PEEK 16436+256*PEEK 16437)/50 en el Spectrum teclear: POKE 23672,0:POKE 23673,0 LET t=(PEEK 23672+256*PEEK 232673)/50 en ambos, la primera línea inicializa el reloj y t = tiempo en segundos luego del inicio. El contador solo es por 10 min. (**) Nota: estos POKEs fueron publicados en la revista ZX año II 15 feb.1985 y K64 n.14 mayo 1986, pero ambas revistas lo hicieron con errores de tipeo. Caracteres graficos El ZX81 tiene caracteres gráficos que se pueden tipear en el Spectrum tal cual se ven en los listados, excepto 6, los cuales deben ser reemplazados por cualquiera otros signos o usar UDGs si se desea replicar cada uno de los gráficos del ZX81. En ese caso, bastaria con modificar los primeros 5 UDGs "ABCDE" y usarlos en lugar de los graficos 8,9,10,137 y 138 respectivamente; salvándolos con SAVE CODE USR "a",40 y cargarlos con LOAD CODE. caracter zx81 zx80 spectrum caracter zx81 zx80 spectrum ████ ████ ████ 128 143 3 131 131 ██ ██ ████ 130 133 129 2 5 129 ██ ██ ████ 129 132 141 1 4 130 ████ ██ 7 135 139 ██ 135 7 132 ████ ██ 132 134 135 ██ 4 6 136 ██ ██ 5 2 138 ████ 131 3 140 ██ ██ ██ 133 130 133 ██ 134 136 134 ██ ▒▒▒▒ ██ 6 8 137 ▒▒▒▒ 8 9 sin equivalente ████ ▒▒▒▒ 137 138 sin equiv. ▒▒▒▒ 9 10 sin equiv. ▒▒▒▒ ▒▒▒▒ ████ 138 139 sin equiv. 10 11 sin equiv. ▒▒▒▒ ▒▒▒▒ 136 137 sin equiv. - es la inversa del car. 8 Si se desea definir los ultimos graficos no equivalenmtes con UDGs: ZX-8I Spectrum UDGs (++) 8 170.85,170.85,170,85,170,85 9 0.0,0,0.170.85,170,85 10 170.85,1 70.85,0,0.0,0 116 85,170,85.170,85,170.85,170 137 255,255,255,255,85,170,85,170 138 85.170,85,170.255.255,255,255 CHR$ (***) Mientras el Spectrum usa un codigo ASCII mas estandar, el ZX81 no. Si en el listado se encuentra esta funcion, habra que buscar sus equivalencias de codigo: zx81 spectrum zx81 spectrum espacio 0 32 / 128 0 - 9 28-37 48-57 " 11 34 A - Z 38-63 65-90 £ 12 96 RND 64 165 $ 13 36 INKEY$ 65 166 : 14 58 PI 66 167 ? 15 63 cursor arriba 112 11 ( 16 40 " abajo 113 10 ) 17 41 " izq. 114 8 > 18 62 " der. 115 9 < 19 60 [GRAPHICS] 116 15 = 20 61 [EDIT] 117 7 + 21 43 [newline] 118 13 [enter] - 22 45 [RUBOUT] 119 12 [DELETE] * 23 42 AT 193 22 / 24 47 TAB 194 23 ; 25 59 ** 216 94 ^ , 26 44 THEN 222 203 . 27 46 TO 223 204 196-211 175-190 LPRINT 225 224 212-215 192-195 LLIST 226 225 232-251 232-251 STOP 227 226 253-255 253-255 NEW 230 230 STEP 224 205 Los sigtes codigos del Zx81 no tienen equivalente en Spectrum: FAST - SLOW 228-229 SCROLL 231 modos K/L 120 [FUNCTION] 121 car. inversos 139-191 "" 192 UNPLOT 251 Modo inverso El ZX80 y el ZX81 al igual que el Atari poseen un segundo juego de caracteres en modo inverso. Para tipear textos en inverso, hay que entrar en modo G(ráfico). El Spectrum, en cambio carece de un segundo juego de caracteres inverso, pero lo suple con el comando Basic INVERSE, o entrando en modo INV(erso) directamente en el teclado. Tambien se puede usar CHR$ 20 + CHR$1, para imprimir en inverso y CHR$ 20 + CHR$ 0, para desactivarlo. Nota: La mayoria de emuladores no permiten tipear en modo INV, cuando se selecciona el 128k, +2 y +3, lo cual obliga al usuario a usar la sentencia INVERSE o el código de control CHR$ 20. FOR - NEXT (***) usados para generar retardos en el ZX81, deben hacerse 4 veces mayores para el Spectrum, si se desea obtener el mismo retraso. En algunos programas este bucle es preferible como retardo a PAUSE, debido a que este último es afectado por las pulsaciones de teclas. 16k (***) si un programa ZX81 llega a tener cerca de 16k mediante expansion de RAM, solo puede correr en un Spectrum 48k, ya que en el modelo de 16k, solo hay 9k de memoria libre para el usuario. (***) Nota: seccion trucos del Ordenador Personal 22 de 1984. Pasamos a ver ahora el ZX-80, su basic, el Sinclair Basic original que lo empezó todo, fue diseñado en base al Basic mínimo estandar 1978 de ANSI. El Basic del zx80 es un caso especial, ya que usa BASIC de enteros (de modo muy similar al APPLE I), en vez de con coma flotante para fines aritmeticos. Otra característica es que solamente sus comandos y sentencias se obtienen directamente pulsando una sola tecla, pero las funciones conforman una librería a la que se accede tipeando letra a letra. Por ejemplo PRINT se obtiene tecleando solo la "O", mientras que RND(5) se teclea letra por letra más los paréntesis. A continuación apuntes extraidos del artículo CONVERSION publicado en SINCLAIR USER #1: LET X= RND(10) en el ZX-81 y Spectrum se debe reemplazar por: LET X= INT(RND*10)+ 1 RND siempre da un entero desde 1 hasta n en el ZX80(++). TL$ (truncate left) la única función de cadena del zx80, devuelve el texto menos su primer caracter. En el zx81 y Spectrum usar: c$ (2 TO). Ejemplo: 10 LET A$="HELLO" 20 Print A$ 30 LET A$=TL$(A$) 40 IF A$ > "" THEN GO T0 20 SO PRINT "GOODBYE" Se debe reescribir: 10 LET A$="HELLO" 20 PRINT A$ 30 LET A$=A$(2 TO) 40 IF A$ > "" THEN GOT0 20 50 PRINT "GOODBYE" POKE 16414, n genera una pausa de espera 'n', pero en el zx81 y Spectrum es: PAUSE 255-n DIM (++) en el ZX80 el primer subindice de una matriz es 0 en vez de 1 como sucede en el ZX81 y Spectrum. Por ejemplo: DIM A(5): PRINT A(0) es valido solamente en el ZX80. (++)nota: mencionado en sinclair user 25 p.122 sobre mas equivalencias zx. Direcciones equivalentes PEEK/POKE en una linea 1 REMxxxx... zxz80 zx81 Spectrum (sin IF1/MDR) 16426 - 16457 <-> 16513 - 16544 <-> 23758 - ... variables del sistema: zx80 zx81 Spectrum 18384 16384 ERR NR 23610 16385 16385 FLAGS 23611 16386 16391 PPC 23621 16387 16392 23622 16388 sin equivalente 16389 sin equivalente 16390 16394 E PPC 23625 16391 16395 23626 16392 16400 VARS 23627 16393 16401 23628 16394 16404 E LINE 23641 16395 16405 23642 16396 16396 D FILE sin equivalente 16397 16397 16398 sin equivalente 16399 sin equivalente 16400 16412 STKEND 23653 16401 16413 23654 16402 16418 DF SZ 23659 16403 16419 S TOP 23660 16404 16420 23661 16405 16408 X PTR 23647 16406 16409 23648 16407 16427 OLDPPC 23662 16408 16428 23663 16409 16429 FLAGX 23665 16410 16432 T ADDR 23668 16411 16433 23669 16412 16434 SEED 23670 16413 16435 23671 16414 16436 FRAMES 23672 16415 16437 23673 16416 sin equivalente 16417 sin equivalente 16418 sin equivalente 16419 sin equivalente 16420 sin equivalente 16421 sin equivalente 16422 16406 CH ADD 23645 16423 16407 23646 16424 16409 16425 16410 16426 16413 16427 16414 16393 VERSN sin equivalente 16398 DF CC 23684 16399 23685 16402 DEST 23629 16403 23630 16410 STKBOT 23651 16411 23652 16414 BREG 23655 16415 MEM 23656 16416 23657 16417 no usada 16421 LAST K 23560 16422 23561 16423 (bota el estado del teclado del zx81) 16424 MARGIN sin equivalente 16425 NXTLIN 23637 16426 23638 16430 STRLEN 23666 16431 23667 16438 COORDS 23677 16439 23678 16440 PR CC 23680 16441 S POSN 23688 (col.PRINT) 16442 23689 (lin.PRINT) 16443 CDFLAG sin equivalente 16444 PRBUFF (S33 = 32 car. + newline) 23296 - 23552 16477 MEMBOT (area del calculador N30) 23698 (N30) 16507 no usada 16508 no usada (c)2014 - actualizado (c)2017 zx_if1@hotmail.com