dev-resources.site
for different kinds of informations.
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
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
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
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
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á...
Featured ones: