Antes que nada, recomiendo que si nunca has programado para la NDS o PC (graficos) no empiezes con esto, mejor haz pruebas con los modos de pantalla que tenga la NDS (toca tiles, bitmap, etc.).
Bien, empezemos:
Para empezar a programar un emulador, primero tendremos que elegir qué sistema queremos emular. En este tutorial lo haremos como si quisieramos emular Chip8, un sistema muy simple que todos recomiendan para empezar.
¿Como funciona un emulador?Lo que basicamente es emular una consola (estos son los que nos interesan). Pero que exactamente hace para emularlo?
Hablando de un emulador sencillo de un sistema sencillo, lo que necesitaremos para hacer un emulador sera:
-
Informacion de la CPU: docs (documentos), ... informacion basicamente-
Preparar registros necsarios para poder ejecutar las instrucciones (PC, SP, v0-v15...)-
Preparar contador de ciclos para que no vaya demasiado deprisa/despacio.
-
Ejecutar las instrucciones de la ROM.-
Renderizar graficos.
Informacion de la CPUPara saber que debemos emular de Chip8, necesitaremos saber que ensamblador utiliza, registros, velocidad, ... vamos, todo o "casi todo".
Tratandose de un tutorial, os facilito las paginas donde tendreis que ir:
-Docs:
http://www.pdc.kth.se/~lfo/chip8/CHIP8.htm Leeros un poco esto antes de empezar-Emuladores:
http://www.zophar.net/chip8.html (Como supongo que no teneis un Chip8, tendreis que utilizar un emulador para comprobar que todo va correcto).
-Roms (son PD/homebrew !):
http://www.zophar.net/pdroms/chip8/chip-8-games-pack.htmlEntentiendo los Docs:
En el apartado 1.2 veremos "CHIP8 programs and memory". Nos dice, basicamente, que esta estructurada de la sigueinte forma:
-0x000-0x1FF: Sector de Memoria del Intérprete (cosas en memoria de la consola, que no han de tocarse. En chip8 contiene los graficos de los valores 0x0 al 0xF, para mostrar la puntuación en pantalla, etc.)
-0x200: Donde empiezan las instrucciones de la ROM
-0xFFF: Fin de la memoria, suponiendo que la rom ocupa ~4KB.
1.3: registrosSi no habeis programado en ensamblador antes, hacedlo ahora o olvidaos de seguir con esto
. (Para los que no sepan, lo iré explicando un poco)
Los registros son como las variables en C/C++/java/loquesea, pero claro: solo
hay 16, y no todas las podemos utilizar. (Los compiladores en realidad traducen todo lo escrito i se las manejan para poder usar esas 16 variables solamente).
-
Los registros son de 8 bits, habiendo 16 de ellos. Llamados V0-VF.
El registro VF se utiliza especialmente para el Carry i Detector de Colisiones (MUY simple, si dibuja un pixel blanco encima de otro, se pone VF a 1, tambien se pone a 1 si hay Carry en una operacion).
Si no sabeis que es un Carry:
-
El registro de direccion: Hay uno, y se le llama
I. Sirve para aseñalar una dirección de la memoria. Lo utilizamos ya que para acceder a cualquier punto de memoria se necesitan 16 bits y con los 8bits de los registros no se podria.
Ejemplo:
I = 0x200 (I apunta al inicio de la ROM)
V0 = 0xFF (un numero cualquiera, no puede ser 0x1FF o 0x2FF ya que superaria los 8 bits permitidos)
-
Los temporizadores:
-DT (Delay Timer): Mientras tenga un valor mas grande que 0, se decrementará hasta llegar a 0. No continuará ejecutandose ninguna instruccion de la ROM mientras este temporizador no termine. (Decrementa por 1 unas 60 veces por segundo)
-ST (Sound Timer): Mientras tenga un valor mas grande que 0, sonará un "beep". (Decrementa por 1 unas 60 veces por segundo)
-
The stack: Sirve para llamar a subrutinas (como si llamaras a una funcion, para que sepa a que parte de la ROM ha de volver al acabar).
por ejemplo:
022E: LD V0, 0x05;
0230: CALL 0x250; //al ejecutar esta instruccion, se añade un valor a la lista de SP con el valor 0x230. Y continua ejecutando con PC = 250
...
0250: ADD V0, V0, 0x01;
0252: RET; //PC = ultimo valor en la lista de SP
Nota: Si no sabeis lo que es PC:
Graficos:Como por ahora no lo utilizaremos, pasamos de ello (leeroslo vosotros! xD)
Instrucciones:La lista de instrucciones y su correspondiente OPCODE.
OPCODE: OPeration CODE (Codigo de Operacion).
Lo veremos mejor con un ejemplo, observemos este:
8XY2 VX = VX AND VYEsto nos indica que, despues de leer nuestro opcode de la ROM, si el valor tiene la forma 8XY2 (siendo X i Y un número cualquiera), significa que tendrá que realizar la operacion "Vx = Vx AND Vy".
Ejemplo de codigo, para que os hagais una idea de un emulador de Chip8 que entiende la isntruccion 8xy2:
//(Todas las variables de registros, etc.. ya estan declaradas)
int opcode = 0x8375
int B0 = opcode%16; //B0 = 5
...
int B4 = opcode%16; //B4 = 8
if (B4 == 8 and B0 == 5) V[B1] = V[B1] AND V[B2];
Acabad de miraros los documentos y a buscar un poco mas de informacion si no habeis entendido algo, porque esto es lo BASICO (no se ni si llega a eso)
Por ahora aqui acaba la primera parte, en unos dias escribiré la 2a y empezaremos de verdad a ejecutar las instrucciones.