Programación #7: Creando una ROM de Spectrum con z88dk

Buenas. Lo siguiente dentro de la lista de hitos para conseguir hacer un juego para Interface 2 usando z88dk + splib2 viene a ser conseguir generar un archivo de ROM. Antes de meternos en verea, vamos a explicar unas cosillas. z88dk es un compilador multi-plataforma. El +zx que especificamos al compilar simplemente sirve para que se lea un archivos de configuración con código y parámetros específicos para el ZX Spectrum. Este archivo es lib/config/zx.cfg (lib/config/zx.lnx en linux). En este archivo, además de definirse qué reglas de optimización se emplearán y qué parámetros específicos necesita el compilador para generar un binario para Spectrum, se especifica el crt0 que se empleará. Un crt0 no es más que código de inicio. Básicamente se suele colocar la pila, preparar el sistema un poco, establecer el punto de entrada para ejecutar (dónde está main, vamos) y cosas así. El tema es que el crt0 para Spectrum no nos sirve ya que está preparado para programas que se ejecuten en RAM. En este capítulo crearemos nuestro propio archivo de configuración y nuestro propio crt0 para juegos en ROM, y al final escribiremos un programa pocho para probar que funciona todo. En el próximo capítulo veremos cómo colocar variables globales e intentaremos linkar contra splib2 (¡¡espero que no emplee código automodificable ni variables ni nada!!).

Preparando un nuevo “target”

En efecto, lo que vamos a hacer es crear un nuevo target para z88dk. Para ello, escribiremos un nuevo archivo cfg (lnx) basándonos en el que hay para ZX Spectrum (lib/config/zx.cfg y lib/config/zx.lnx). Lo primero que haremos será copiar lib/config/zx.cfg a un nuevo archivo que llamaremos lib/config/zxrom.cfg. Una vez hecho esto lo editaremos para que quede como sigue, y cuando terminemos lo copiamos a zx.lnx y cambiamos todos las rutas de los archivos a las correctas por si queremos usar esto desde linux alguna vez (o si usamos esto desde linux siempre, claro):

Z80EXE      z80asm
MPMEXE      mpm
CPP         zcpp
LINKER      z80asm
COMPILER    sccz80
COPTEXE     copt
COPYCMD     copy
APPMAKER    appmake

Z88MATHFLG  -D__NATIVE_MATH__

STYLECPP 2
INCPATH     -Ic:\z88dk\include

ASMOPTS     -Mo
COPTRULES1  c:\z88dk\lib\z80rules.1
COPTRULES2  c:\z88dk\lib\z80rules.2
COPTRULES3  c:\z88dk\lib\z80rules.0

CRT0        c:\z88dk\lib\no_crt0

LIBPATH     -ic:\z88dk\lib\clibs\
LINKOPTS    -a -m -Mo
Z88MATHLIB  zx_math
STARTUPLIB  z80_crt0
GENMATHLIB  gen_math

OPTIONS     -\\ -v -O2 -I. -lzx_clib -DZ80 -DSMALL_C -DSPECTRUM -D__SPECTRUM__ -M -DSCCZ80 -Cz+zxrom

Si te fijas, sólo hemos hecho algunos cambios en OPTIONS y en CTR0. Estamos diciéndole que nuestro archivo CRT0 será lib/no_crt0.asm. Este archivo no existe, ya que tendremos que crearlo nosotros con nuestro código de inicialización. Tras hacer un par de pruebas, he dado con el código mínimo que hará lo que queremos. Crea un nuevo archivo lib/no_crt0.asm que contenga el siguiente código de ensamblador:

; no crt0

MODULE no_crt0
INCLUDE "zcc_opt.def"
XREF _main
    org 0

.start
    jp _main

.l_dcal
    jp (hl)

(Acuérdate de dejar una linea en blanco al final de todos los archivos, es una paranoia del compilador) . Una vez hecho esto, tendremos listo nuestro nuevo target y podremos empezar a compilar archivos de ROM.

Ejemplo tontorrón para ir probando

En nuestro ejemplo tontorrón símplemente ponemos la pantalla a negro y luego nos liamos a cambiar el borde a toda velocidad. El código es tontísimo, pero lo necesitamos sólo para probar. Créate un archivo test1.c con este código:

void todo_a_negro () {
    unsigned char *origin;

    origin = (unsigned char *) 22528;
    while (origin < 23296) {
        *origin = 0;
        origin ++;
    }
}

main () {
    todo_a_negro ();

    while (1) {
        #asm
            inc a
            out (254),a
        #endasm
    }
}

Y ahora viene como lo compilamos. Vamos a especificar nuestro nuevo target, o sea, zxrom. Llamamos, pues, al compilador, con esto:

zcc +zxrom -vn test1.c -o test1.rom -lndos -lsplib2 -zorg=0

Con lo que obtendremos un archivo test1.rom que ocupará unos cuantos bytes. Esto es un problema: casi todos los emus (por ejemplo Spectaculator) necesitan un archivo de 16K (16384 bytes) y rechazarán cualquier otra cosa. Sin problema: he echo un pequeño programoncio en BASIC que se encarga de abrir el archivo que le pases y meterle ceros al final hasta que ocupe 16K justos. Para obtenerlo sigue el enlace al final del artículo. Sólo ejecuta

bloat test1.rom

y test1.rom pasará a ocupar 16K. Ahora sólo tienes que pillar el emu y configurarlo para que use esa ROM en vez de la de siempre y ver cómo cambia el borde con la banderita gay (En Spectaculator símplemente vete a Tools->Options->Advanced->Custom Roms y cambia la del Spectrum 16/48).

gayer.png

Bájate aquí todos los tiestos mencionados (el archivo zxrom.cfg va a lib/config y el archivo no_crt0.asm va a lib). Nos vemos en el próximo🙂

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

A %d blogueros les gusta esto: