Cómo crear tu propio RAM tester para Nintendo 64
Si estás empezando con Libdragon y quieres pasar del clásico «Hello World» a algo que interactúe de verdad con el hardware, aquí tienes un proyecto sencillo: un testador de memoria que detecta si tienes el Expansion Pak (8MB) o el Jumper Pak (4MB) y realiza pruebas de escritura/lectura.
1. El Makefile (Configuración del Proyecto)
Sustituye el contenido de tu Makefile por este. Está configurado para organizar los archivos y generar el archivo .z64 correctamente.
Makefile
V=1
SOURCE_DIR=src
BUILD_DIR=build
PROG_NAME=dashboard
include $(N64_INST)/include/n64.mk
all: $(PROG_NAME).z64
OBJS = $(BUILD_DIR)/main.o
$(PROG_NAME).z64: N64_ROM_TITLE="N64 RAM TESTER"
$(BUILD_DIR)/$(PROG_NAME).elf: $(OBJS)
clean:
rm -rf $(BUILD_DIR) *.z64 *.elf
.PHONY: all clean
-include $(wildcard $(BUILD_DIR)/*.d)
2. Organiza tu espacio de trabajo
El Makefile ahora busca el código en una carpeta llamada src. Si tienes tu archivo en la raíz, muévelo con estos comandos:
Bash
mkdir -p src
mv main.c src/main.c
3. El Código: RAM & Expansion Test
Copia este código en src/main.c. Este programa detecta la capacidad de la consola y permite escribir el valor «1996» en una dirección física de la memoria para luego rescatarlo.
C
#include <stdio.h>
#include <libdragon.h>
#include <malloc.h>
#include <stdint.h>
int main(void) {
timer_init();
display_init(RESOLUTION_320x240, DEPTH_16_BPP, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE);
joypad_init();
int *puntero_secreto = NULL;
int valor_recuperado = 0;
uint32_t addr_fisica = 0;
bool dato_en_memoria = false;
while (1) {
joypad_poll();
joypad_buttons_t btn = joypad_get_buttons_pressed(JOYPAD_PORT_1);
surface_t *disp = display_get();
graphics_fill_screen(disp, 0);
graphics_draw_text(disp, 20, 20, "== N64 RAM & EXPANSION TEST ==");
// Detección de memoria
int mb = get_memory_size() / (1024 * 1024);
char txt_cap[64];
sprintf(txt_cap, "RAM Detectada: %d MB", mb);
graphics_draw_text(disp, 40, 50, txt_cap);
if (mb == 8) {
graphics_draw_text(disp, 40, 65, "Hardware: EXPANSION PAK OK");
} else {
graphics_draw_text(disp, 40, 65, "Hardware: JUMPER PAK (4MB)");
}
// Acción [A]: Escribir en RAM
if (btn.a) {
if (!puntero_secreto) puntero_secreto = (int*)malloc(sizeof(int));
*puntero_secreto = 1996;
addr_fisica = (uint32_t)puntero_secreto;
dato_en_memoria = true;
valor_recuperado = 0;
graphics_draw_text(disp, 20, 150, "ESCRIBIENDO EN RAM...");
display_show(disp);
wait_ms(500);
disp = display_get();
}
// Acción [B]: Rescatar dato
if (btn.b && dato_en_memoria) {
valor_recuperado = *puntero_secreto;
}
if (dato_en_memoria) {
char txt_addr[64];
sprintf(txt_addr, "Dir: 0x%08X", (unsigned int)addr_fisica);
graphics_draw_text(disp, 40, 110, txt_addr);
}
if (valor_recuperado != 0) {
char txt_res[64];
sprintf(txt_res, "RECUPERADO: %d (EXITO)", valor_recuperado);
graphics_draw_text(disp, 40, 130, txt_res);
}
graphics_draw_text(disp, 20, 190, "[A] Escribir en RAM [B] Rescatar");
display_show(disp);
}
return 0;
}
4. Compilación Final
Para evitar errores de caché o archivos antiguos de otros ejemplos, usa siempre una compilación limpia:
Bash
libdragon make clean
libdragon make
¡Listo! Ya tienes tu archivo dashboard.z64 listo para probar en un emulador o en hardware real. 🎮