DEV Community

Cover image for Hackeando en 8 bits
Baltasar García Perez-Schofield
Baltasar García Perez-Schofield

Posted on • Edited on

Hackeando en 8 bits

El Sinclair Spectrum

El Spectrum 128k fue el que hizo que al final me dedicara a la informática, sin duda alguna. Y ese fue el regalo que, no sin cierto esfuerzo, nuestros padres nos hicieron en las navidades de 1985. El speccy, como se le conoce cariñosamente, era un ordenador diseñado con el objetivo de que en un hogar normal y corriente pudiese haber un ordenador. De hecho, el teclado era pésimo, y los chips de memoria muchas veces eran del doble de la capacidad necesaria... porque eran chips defectuosos (y por tanto, más baratos), en los que la memoria alta (o la baja), no funcionaba.

Este ordenador creado por Sir Clive Sinclair tenía el objetivo de poder ser vendido por debajo de las 100 libras, y para ello había que hacer recortes. Antes de la versión de la fotografía, el modelo vendido era el llamado gomas, con un tacto descrito muchas veces como de "carne muerta" o dead flesh.

Pero lo importante es que te lo podías comprar y tener un ordenador en casa, algo impensable tan solo un lustro antes.

Las especificaciones eran: un procesador Z80 a 3,5Mhz con 128KB de RAM, y una unidad de cassette como memoria secundaria (es decir, de donde guardar y cargar los programas, y especialmente, de donde cargar los juegos). El Z80 era un procesador de 8 bits, muy utilizado en entornos industriales, con un bus de direcciones de 16 bits. Podía direccionar hasta 64KB (655536 bytes) directamente. De estos 64KB, el Spectrum original (comercializado como de 48KB), reservaba 16KB para acceder a la ROM (donde se encontraban la BIOS y el intérprete BASIC, el sistema operativo de la máquina), y otros 8KB para la memoria de pantalla. Eso dejaba 48KB libres, de ahí el nombre comercial de la máquina.

Hubo un modelo de 16KB en los que los 32KB superiores simplemente no existían.

Quitando cierto espacio para variables del sistema, el BASIC tenía disponibles unos 40KB. Esto podía consultarse con una llamada a la ROM:

print 65536 - usr 7962
Enter fullscreen mode Exit fullscreen mode

Recién arrancado el BASIC, el resultado de este comando era 41471, algo menos de 40.5KB. Esta cifra era inusualmente alta, comparada con los ordenadores (competidores), de la época. El Commodore 64 fue una máquina contemporánea, super ventas en EEUU. Dejaba libres unos 37KB, a pesar de disponer de más memoria RAM. El Dragon 32, otra máquina proveniente del Reino Unido (aunque posteriormente se asentaría en España), dejaba libres unos 30KB para el BASIC.

La forma de cargar y guardar programas en el ordenador era el cassette de audio. Este se reproducía o se grababa en un magnetófono, y se conectaba a los enchufes EAR (para cargar un programa) o MIC (para grabar un programa).

Cargando un juego

Antes de nada, el significado de las instrucciones de BASIC PEEK y POKE:

10 let x = PEEK 40000: REM lee el valor (0-255) en posición 40000
20 POKE 40000, 201: REM escribe 201 en la posición 40000
Enter fullscreen mode Exit fullscreen mode

PEEK y POKE podrían describirse como la forma más directa de escribir a memoria, o incluso de programar en código máquina, desde BASIC. Claro está que era muy limitado (solo 1 byte de cada vez), pero al menos existía.

Así, la mayor parte de los programas estaban escritos en código máquina. Sin embargo, el ordenador arrancaba en el intérprete de BASIC, y no entendía este código máquina directamente. Así que o bien se cargaban con load "" code, o bien se escribía un cargador, la opción más extendida con diferencia, pues permitía cambiar muchos detalles (dirección de memoria de carga del código máquina, por ejemplo), o también mostrar una pantalla de carga.

10 cls
20 print "Juego Impresionante!!!"
20 load "" screen$
30 load "" code 40000
40 randomize usr 40000
Enter fullscreen mode Exit fullscreen mode

El significado es bastante simple: se carga una pantalla de presentación (línea 20) para mantener al usuario entretenido mientras se carga el programa en código máquina (el juego en sí), lo carga (línea 30), y finalmente lo ejecuta (línea 40).
Acerca de la línea 40, usr 40000 es la expresión que realiza la ejecución, llamando al código en la posición 40000. La instrucción randomize simplemente inicializa la semilla aleatoria utilizada por rnd (por ejemplo print int(rnd * 5) + 1 visualiza un número pseudoaleatorio entre 1 y 5), aunque en realidad en este cargador nunca retornará y la semilla no se verá afectada.

Por cierto, cualquier instrucción es válida aquí, como por ejemplo print usr 40000, lo único importante es que alguna de las expresiones contenga usr 4000 lanzando el programa.

Un ejemplo: Abu Simbel Profanation

Un posible ejemplo es Abu Simbel Profanation, de la marca de software española Dinamic. Podemos encontrar Abu Simbel Profanation en worldofspectrum.org.

Si cargamos el código con merge "", nos encontraremos con el cargador:

10 border 0:paper 0: ink 0: cls: clear 26000: print at 21, 0; paper 2; ink 7; "DINAMIC PRESENTA......"; flash 1; "ABU SIMBEL"
15 print at 0, 0: poke 23633 + 256 * peek 23634, 111
20 load "" screen$: load "" code: randomize usr 26100
Enter fullscreen mode Exit fullscreen mode

La línea 10 se dedica a cambios cosméticos antes de cargar el juego: el 0 es el código de color negro, por lo que toda la pantalla se pone en negro. La tinta o color de primer plano se pone también a 0, lo que hace que en un principio, si accedes al cargador parando el programa tras empezar a cargarlo con load "", no veas nada. Se solucionaría con ink 7, claro, pues 7 es el código de color blanco. El atributo flash 1 hace que lo impreso a continuación (el nombre del juego), parpadee.

La línea 10 incluye también clear 26000, protegiendo el programa cargador BASIC de ser sobreescrito por el código máquina a cargar.

La línea 15 modifica el canal de entrada/salida (la dirección de memoria en las posiciones 23633 y 2364), con el valor 111, para impedir la posibilidad de pulsar break y detener la carga.

La línea importante es la 20. En ella, se carga la pantalla de presentación. A continuación, el juego en sí en código máquina (load "" code), y entonces se ejecuta el juego con randomize usr 26100.

Continuará...

Top comments (2)

Collapse
 
hsicilia profile image
hsicilia

Esperando las siguientes partes ;)

Collapse
 
baltasarq profile image
Baltasar García Perez-Schofield

¡Claro! Queda lo más importante, que es el hackeo... o pockeo... :-D
Gracias.