# Nuestro primer programa Bien, ya sabemos como ensamblar nuestro programa y estamos ansiosos por saber programar. En otros cursos se frenaría al alumno y se le daría unas nociones de álgebra digital, arquitectura del Z80, o fabricación de cócteles Molotov. Pero aquí no, vamos al grano. Vamos a describir como se realiza lo básico, el esqueleto de un programa en ensamblador: ; Nuestro primer programa ORG 32768 RET Ya está, así de simple, si lo ensambla verá que el ZX Spectrum retornará a BASIC sin haber hecho ABSOLUTAMENTE NADA. ¿No es genial? ¡¡NADAAAAAAAAAAAAA!! ¿Y el ORG 32768 ese? ¿para qué sirve? si se hace esta pregunta le daremos una respuesta muy sencilla: es la posición de memoria donde el programa va a estar y es requerida por el programa ensamblador. De momento no cambie dicha dirección, si lo hace verá que su programa puede que no funcione, deje esas cosas para otro día. ¿Y el RET? eso es ensamblador, de hecho la única línea de código que hay en el programa. Su función es muy simple: retornar. En este caso, como es la última línea, retornará al BASIC. Es más, nuestro programa es una subrutina que llamamos desde BASIC con randomize usr 32768 (no hace falta que recuerde esto). # Estructura de la memoria Vamos a ver como es la estructura básica de la memoria de un ZX Spectrum: 00000 - Inicio de la ROM (sistema operativo BASIC) 16383 - Fin de la ROM 16384 - Inicio de la memoria de pantalla 23295 - Fin de la memoria de pantalla 23296 - Comienzo de la memoria libre 65535 - Fin de la memoria libre Con esto tenemos lo básico para trabajar. Como puede ver la ROM está entre 0 y 16383, ahí estan alojadas todas las subrutinas que BASIC usa, entre otras cosas. Poco a poco le iremos mostrando cuales son las subrutinas más interesantes y cómo se usan. La pantalla está entre 16384 y 23295. Su estructura no la vamos a explicar poque no vamos a necesitarlo, le proporcionaremos directamente las rutinas para manejar gráficos y punto. La memoria libre empieza a partir de 23296, pero nuestros programas no los comenzaremos hasta bastante después. ¿por qué? porque si lo hacemos ya no podemos usar las subrutinas de la ROM y volver al BASIC, puesto que el comienzo de este espacio se usa para datos del BASIC (y por ende de subrutinas de la ROM). Hemos escogido 32768 para empezar, lo que nos da 32K de espacio para nuestro programa, más que suficiente para un juego sencillo. ¿Y los 128K? nos olvidamos de ellos de momento, si consigue realizar un juego para 48K nos damos por satisfechos. Una buena idea es plasmar el mapa de memoria en un papel. Dibuje un rectángulo alargado verticalmente, el cual debe dividir en 4 partes iguales. Cada parte se corresponden con 16K de memoria, haciendo 64K en total: - El primer bloque sería la ROM - El segundo la pantalla, los datos de la ROM, y el programa BASIC - El tercer y cuarto bloque sería nuestro programa # Nuestro segundo programa ; Nuestro segundo programa ORG 32768 ld a, 15 ; papel azul y tinta en blanco ld (23693),a ; actualizamos la variable de atributos en pantalla ld (23624),a ; actualizamos la variable de atributos en pantalla (parte baja) call 3503 RET ¿Y esto? ¿pero que co%$? tranquilo, vamos a ir poco a poco. Si lo ensambla y ejecuta verá que el fondo de la pantalla cambia a color azul, así de simple. Ahora se lo explicamos: ld a,15 A esto llamamos una instrucción de carga, coje un valor (en este caso 15) y lo introduce en el registro A. Y usted se acaba de perder, no sabe lo que son los registros. No nos hace falta aún, imagine que ha metido el valor 15 en una hoja de papel que hay dentro del ordenador, y que dicha hoja la usa para lo que usted quiera. ld (23693),a Esto es otra instrucción de carga, pero más rara todavia, lo que hace es introducir esa hoja de papel que hemos escrito (a) en la posición de memoria 23693. Por un casual dicha dirección es la que usa el ordenador para almacenar los colores con que se escribe en BASIC en pantalla. ld (23624),a Otra vez lo mismo, pero en esta ocasión hemos actualizado la parte inferior de la pantalla. BASIC es así de latazo, divide la pantalla en dos partes: programa y editor. Observe una cosa curiosa, lo que vamos a utilizar siempre está a la derecha de la instrucción en ensamblador, y el destino a la izquierda. call 3503 ¡Ajá! ¡eso es para llamar por teléfono a una línea erótica! no, pero casi. call realiza una llamada, si, pero a una subrutina (un programita que hace algo y tiene al final un RET). 3503 es la dirección de memoria donde está la subrutina que vamos a llamar, es decir estamos llamando a una rutina de la ROM, que corresponde en este caso a un "borrar pantalla" (CLS en BASIC). Como hemos cambiado los colores con los que escribe el BASIC y hemos llamado a la instrucción CLS... pues la pantalla cambia de color. Este programa en BASIC equivale a: 20 ink 7 30 paper 1 40 cls Pero como podemos ver no se corresponde el valor del código de color, ¿el motivo? pues que estamos metiendo el valor de tinta y papel en un sólo número mediante la siguiente tabla: - TINTA - NEGRO 0 00000000 AZUL 1 00000001 ROJO 2 00000010 MAGENTA 3 00000011 VERDE 4 00000100 AZULADO 5 00000101 AMARILLO 6 00000110 BLANCO 7 00000111 - PAPEL - NEGRO 0 00000000 AZUL 8 00001000 ROJO 16 00010000 MAGENTA 24 00011000 VERDE 32 00100000 AZULADO 40 00101000 AMARILLO 48 00110000 BLANCO 56 00111000 Ej. queremos tinta azul y papel amarillo: 1 + 48 = 49, que es el valor a introducir en "a" # Nuestro tercer programa Ahora escriba esto: ; Nuestro tercer programa ORG 32768 ld a, 1 ; borde azul, para actualización inmediata out (254), a RET ¡Alaaaaaa! ¡no hemos usado ninguna subrutina y hace algo! Pues si, si ensambla y ejecuta este programa verá que el borde la pantalla se vuelve azul, como puede ver de pequeño me gustaban mucho Los Pitufos. Hemos cargado en "a" el valor 1, que en esta ocasión si se corresponde con el código de colores del BASIC... ¿el motivo? que aquí sólo estamos cambiando un color y no dos, en el anterior ejemplo teníamos que meter en un sólo número dos valores. La novedad es la sentencia out (254), a. out sirve para sacar por un puerto de comunicación un valor determinado, en este caso introduce en el puerto 254 el valor de "a". Dicho puerto se corresponde con el borde la pantalla, sólo tiene que saber eso. # Nuestro cuarto programa ; nuestro cuarto programa ORG 32768 ld a, 15 ; papel azul y tinta en blanco ld (23693),a ; actualizamos la variable de atributos en pantalla ld (23624),a ; actualizamos la variable de atributos en pantalla (parte baja) call 3503 ld a, 1 ; borde azul, para actualización inmediata out (254), a RET Bien, hemos unido todos los programas anteriores y ya tenemos algo "tangible", el fruto de nuestros esfuerzos. Con esto ya podemos preparar la pantalla con los colores que queramos. Y esto es todo por ahora, hasta el próximo capítulo.