01. Hello NES!

Ahora que ya configuramos nuestro entorno de desarrollo, llego el momento de realizar nuestro primer programa de NES. Me base en el ejemplo de Wolfcoder, pero para ser realizado en Ubuntu en lugar de Windows, y definiendo algunos macros para hacer el código más legible.

Usando el editor de texto de nuestra preferencia, crearemos un solo archivo 01.c, y en este archivo escribiremos nuestro código en C:

Primero, incluiremos los headers de NES que vienen con cc65:

#include <nes.h>

Luego definiremos algunos macros para acceder a ciertos registros de la PPU que usaremos en este ejemplo:


#define PPU_MASK *((unsigned char*)0x2001)
#define PPU_SCROLL *((unsigned char*)0x2005)
#define PPU_ADDRESS *((unsigned char*)0x2006)
#define PPU_DATA *((unsigned char*)0x2007)

Ahora, definiremos una función que escribirá texto a la pantalla:

void write_string(char *str) {

El registro 0x2006 corresponde al “PPU address register”, que definimos como PPU_ADDRESS, acá indicaremos donde posicionaremos el cursor para comenzar a dibujar:

PPU_ADDRESS = 0x25; //Y
PPU_ADDRESS = 0x41; //X

Luego mientras el puntero apunte a un espacio donde exista un carácter, pondremos un carácter en el registro PPU_DATA, y moveremos el puntero un espacio:

while(*str) {
PPU_DATA = *str;
str++;
}

Un efecto interesante que podemos observar, es que la PPU, desplazará automáticamente el cursor de PPU_ADDRESS un espacio por cada vez que pongamos datos en PPU_DATA

Luego definiremos nuestra función principal:

int main() {

Acá, nuevamente nos toparemos con una idiosincrasia del NES, debemos esperar a que termine el VBLANK, o no podremos usar la PPU, acá utilizaremos una función de nes.h:

waitvblank();

Ahora, seleccionaremos el registro donde está el fondo, y le asignaremos un color:

PPU_ADDRESS = 0x3F; 
PPU_ADDRESS = 0x00;
PPU_DATA = 0x25;

Después haremos lo mismo para la fuente del texto:

PPU_ADDRESS = 0x3F;
PPU_ADDRESS = 0x03;
PPU_DATA = 0x30;

Y llamaremos a la función para escribir strings que definimos antes:

write_string(“Hello NES!”);

Ahora definimos la posición de la pantalla, en X e Y:

PPU_SCROLL = 0x00; //X
PPU_SCROLL = 0x00; //Y

Activamos la pantalla:

PPU_MASK = 0x08;

Y finalmente dejamos nuestro programa corriendo:

while(1);
return 0;
}

Para compilar, abrimos la terminal en la misma carpeta que está 01.c y escribimos:

cl65 -t nes 01.c -0 01.nes

Luego podemos probar nuestro ROM con FCEUX:

fceux 01.nes

Esto abrirá una pequeña ventana donde veremos “Hello Nes!” escrito sobre un fondo rosado, y el siguiente output en el terminal:


PRG ROM: 2 x 16KiB
CHR ROM: 1 x 8KiB
ROM CRC32: 0xb8fe1ecf
ROM MD5: 0x9a7027194f98594098d65ea8a382c60e
Mapper #: 0
Mapper name: NROM
Mirroring: Vertical
Battery-backed: Yes
Trained: No