ZX Spectrum – Cargando BASIC de manera personalizada (V): Inception

Siguiendo con nuestras manipulaciones del BASIC, ahora nos vamos a por un método bastante original de cargar y ocultar el BASIC. Vamos a esconder BASIC dentro del BASIC.

Empecemos por lo básico. Todos conocemos las sentencias REM, que contienen los comentarios del programa. Ahí dentro se puede poner cualquier cosa… incluso código máquina. Para los que gustan de ocultar cosas, sería muy interesante poder hacer una sentencia REM de una longitud determinada… y eso es lo que pregunté y me contestaron en World Of Spectrum. Aquí va un pequeño programa que puede hacer eso:

1 INPUT "Longitud ";rl: RANDOMIZE rl:
  CLEAR: DIM r$(FN p(23670)):
  LET rl=FN p(23670): LET VARS=FN p(23627):
  RANDOMIZE VARS+6+rl: POKE 23627,PEEK 23670:
  POKE 23628,PEEK 23671: INPUT "Linea ";rn:
  LET rv=VARS+4: LET rl=FN p(rv):
  RANDOMIZE rn: POKE VARS,PEEK 23671:
  POKE VARS+1,PEEK 23670: RANDOMIZE rl+2:
  POKE VARS+2,PEEK 23670: POKE VARS+3,PEEK 23671:
  POKE rv,234: POKE rv+1,CODE "<":
  POKE rv+rl,CODE ">": POKE rv+rl+1,13:
  DEF FN p(a)=PEEK a+256*PEEK (a+1)

Al ejecutar este programa (es increíblemente útil, grabadlo a cinta pero YA), nos pedirá la longitud en bytes del REM y el número de línea (que no sea la 1) y creará un REM de esa longitud. Ahora ¿cómo lo aprovechamos?

Cuando jugamos con el compresor ZX7, creamos un bloque comprimido que contenía el BASIC. Dicho bloque se cargaba en la dirección 53500 y medía 7375 bytes. Así que creo una rutina que va a mover 7375 bytes a la dirección 53500.

org 23760
ld hl,datos
ld de,53500
ld bc,7375
ldir
jp 53500
datos:

Cuando la ensamblemos, esta rutina nos va a medir 14 bytes. Si sumamos 7375 bytes de los datos y 14 bytes de la rutina, nos encontramos con que vamos a necesitar un REM de 7389 bytes para esconder todo eso.

Corremos nuestro pequeño creador de REMs, le indicamos la longitud y 10 como número de línea y comprobamos que tenemos un REM hermosote. Quitamos la línea 1, que ya no necesitaremos para nada.

Ahora creamos una línea que diga 20 PRINT USR 23760 y ya tenemos nuestro esqueleto BASIC para rellenar.

Ensamblamos la rutina y después cargamos el bloque comprimido en la dirección 23774 (23760 + 14). Ahora tenemos un BASIC que oculta otro BASIC en el REM de la línea 10. Salvamos nuestro programa con un SAVE … LINE 0 y ya tenemos una manera original de ahorrar tiempo en la carga del programa.

Nota: En todo lo que he hecho, la dirección 23760 es muy importante. En un Spectrum sin expansiones raras, el BASIC empieza en la dirección 23755. Los dos siguientes bytes son el número de la primera línea, los dos siguientes la longitud y el siguiente es el token de la primera instrucción de dicha línea (el REM). Por tanto, el primer byte tras el REM será el 23760.

Todo esto funcionará si la línea REM es la primera línea del programa y si no hay expansiones raras instaladas (como un interface 1 o un disciple). En otro caso, habría que juguetear con las variables del sistema PROG (23635, el primer byte tras el REM es PROG+5) y el hecho de que cuando se usa USR, el registro BC indica la dirección de la rutina.

Enlaces interesantes:

  • Almacén Lunar: Todas las versiones de este programa.
  • ZX Spin: Mi emulador favorito, el que uso para todos los parcheos.
  • ZX7: Compresor para Spectrum. Hay descargas del compresor para PC y código fuente para las rutinas en ensamblador para descomprimir. Hay unhilo dedicado a este compresor en World of Spectrum.
  • ZX Block Editor: Completo programa para manipular ficheros de Spectrum.
Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s