Que aprendí al construir mi propio emulador de CHIP-8 en C++

Que aprendí al construir mi propio emulador de CHIP-8 en C++
Photo by Lorenzo Herrera / Unsplash

Para empezar, hasta hace 1 mes, yo no sabía lo que era CHIP-8, pero soy un gran fan de los videojuegos y el gaming en general, muchos de nosotros tal vez hemos utilizado alguna vez, un emulador para revivir aquellos momentos en el siglo pasado, jugando videojuegos de 8, 16, 32 bits, etc.

Emulador CHIP-8 corriendo Space Invaders

Pero bueno y a todo esto, ¿Qué es un emulador?, bueno, la respuesta tal cual yo no me la sé al 100 pero, Wikipedia dice lo siguiente:

Un emulador es un software que permite ejecutar programas o videojuegos en una plataforma (sea una arquitectura de hardware o un sistema operativo) diferente de aquella para la cual fueron escritos originalmente.
https://es.wikipedia.org/wiki/Emulador

Bien, ahora que todos estamos en el mismo canal, cabe mencionar que en éste punto yo estaba en ceros sobre el tema de la emulación y aún más complicado, no sabía nada de C++ 😩.

🚨
Parte de éste conocimiento adquirido, me ayudará más adelante a crear mis primero juegos y construir un motor gráfico muy básico, pero con esto lograr entender como es que funciona todo éste mundo tanto de la emulación como el desarrollo de videojuegos, 

Pero, ¿Por qué C++?, ¿A caso no se puede escribir un emulador en otro lenguaje como Python o JavaScript que son más sencillos?. Las respuesta corta es si, se puede. La mejor respuesta es, no es el mismo rendimiento, el rendimiento que otorga un lenguaje interpretado de "alto nivel" como Python o JS, no se compara con el otorgado por lenguajes de "medio" nivel como lo son C, C++, Rust o Golang.
Así que me dispuse a aprender un poco de lo básico de C++ para poder arrancar el proyecto. Debo decir que no fue fácil, yo vengo de Python y un poco de Golang (muy parecido a C++) pero, los conceptos y manejos no son para nada los mismos.

Supongo que ahora te estarás preguntando, ok todo cool pero, ¿Qué es esa cosa de CHIP-8?, excelente pregunta.

Aunque esto reside entre un emulador e interprete y para la explicación, nuevamente recurriré a Wikipedia pero, ésta vez te dejaré el enlace para que leas mucho más (si te interesa) a cerca de CHIP-8.

🚨
Éste no es un tutorial de como hacer o contruir su propio CHIP-8, ya que esto se tornaría demasiaaaaaado extenso. Aparte de que ya hay muchos tutoriales buenos en internet 🥴

Algo de lo que también me motivó a realizar y aprender sobre esto, fue que quería entender aún más como es que funciona mi herramienta de trabajo por excelencia, la computadora, y todo lo que conlleva, sistemas operativos, ejecución de programas, manejo de memoria, etc. Así que tuve que investigar demasiado, leer mucho, ver vídeos y tratar de repasar lo aprendido.

CPU

Lo primero que quería entender, era saber como funcionaba al 100 una CPU y, como procesaba el código que yo siempre escribía, cómo es que todo se hacía para que abriera mi navegador favorito, etc.

💭
Cabe recalcar que yo conocía del fncionamiente del procesador y sus tareas a nivel básico, pero quería saber más, para poder construir este proyecto.
Modelo Von Neumann

Así que comencé por lo básico, el modelo Von Neumann (arriba), que es la manera más básica de representar la arquitectura de una CPU, arquitectura sobre la cual casi todos los procesadores de hoy en día están basados.

Un punto también importante es saber como funcionan cada uno de los registros del procesador, algunos tienen más, otros menos, dependiendo del fabricante y la arquitectura. También, como trabaja la Unidad Aritmética Lógica (ALU), la cual se encarga de realzar todas las operaciones aritméticas, tales como suma, resta, multiplicación, división, etc.

De ésta manera, el procesador puede dividir estas operaciones que tiene que realizar, entre el ALU y él, cabe mencionar que el ALU no es un procesador extra ni nada por el éstilo, es simplemente una extensión o ayuda para el procesador, así como los registros.

El motivo de entender ésto, es que así puedo saber de manera más precisa como es que se procesan las instrucciones que llegan justamente al CPU. Para realizar las operaciones que después nosotros podemos observar e incluso mandar.

Memoria RAM

Lo segundo fue entender como es que funciona la Random Access Memory (RAM) y como su nombre lo indica, es un almacenamiento aleatorio, la característica más importante es que es sumamente rápida la lectura y escritura de datos en ella, lo malo es que no es persistente a largo plazo, esto quiere decir que en cuanto se le quite la energia (corriente) o apague la computadora, los datos se perderán y cuando encienda nuevamente, comenzará desde ceros.

CPU <> RAM

Y es por ésta la razón que, a través de un BUS (que en palabras simples son unas pistas o cables que conectan la RAM con el Procesador) el procesador recibe u obtiene las instrucciones de qué es lo que el procesador debe hacer/realizar.

Interacción a grandes rasgos entre el CPU y RAM

En el diagrama de arriba intento ilustrar a muy grandes rasgos como es la interacción entre el CPU y la RAM, así como la manera en que se puede cargar información a la memoria a través de Disco Duro, que bien puede ser un programa, un juego, etc.

👀
OJO, en el diagrama faltan muchas más cosas como los dispositivos de entrada - salida, cachés, registros, etc. Es sólo algo muy básico para darme a entender.

Después de entender toooodo este rollo, y que cada cosa tiene aún más cosas que interactuan unas con otros, ¿Aún quedan ganas de seguir?, a mi sí, y eso me llevó a aprender algo sobre gráficos de computadora.

Gráficos

La herramienta / librería / framework, como quieran llamarle es SDL, la cual en mi elección personal, la encontré un poco díficil de entender (ya que existen otras parecidas que son más intuitivas con el usuario pero SDL es la más usada y completa) pero, con la práctica le fui tomando cariño.

⚠️
Algo a tomar en cuenta es que no necesariamente tienes que utilizar ésta herramienta, todo va a depender del lenguaje de programación que estés utilizando. Ésta se pueda utilizar con C, C++, Rust y Go, aunque claro, existen más.
Si usas Python está PyGame, para JavaScript está el propio canvas.

Lo primero fue aprender a utilizar la herramienta al menos de manera básica, ya que nunca había realizado algo que tuviese que ver con gráficos. Una vez dominado un poco la parte básica, fue revisar las instrucciones de CHIP-8 en las cuáles se generan los gráficos, por ejemplo de las instrucciones más importantes es http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#Dxyn. La cual comienza a llenar el buffer de vídeo que son 32 x 64 píxeles = 2048.

x = V[(opcode & GET_X) >> 8];
y = V[(opcode & GET_Y) >> 4];
h = opcode&GET_4BITS;

V[0xF] = 0;

for (int row = 0; row < h; row++) {
    pixels = Memory[I + row];
    for (int col = 0; col < 8; col++) {
        // If the but (sprite) is not 0, render/erase the pixel
        if ((pixels & (0x80 >> col)) != 0) {
            if (Display[(x + col + (y + row) * 64)] == 1) {
                V[0xF] = 1;
             }
                Display[x + col + ((y + row) * 64)] ^= 1;
             }
        }
   }
shouldDraw = true;

Al llenar el buffer en las píxeles donde debe ir el sprite o parte del sprite, al terminar todo, se le dice al programa que debe pintar con el flag shouldDraw = true, y entonces pinta los sprites en pantalla peeeeeero, no sin antes haber realizado todo lo pertinente con SDL, que es inicializar el sistema, crear una ventana, un lienzo o render donde pintar, actualizar el buffer, etc.
Me encantaría poder describir todo a detalle pero en verdad, ésto se haría ultra mega largo, tal vez en algún momento realiza una serie de tutoriales o vídeos donde todo sea más explicito y a detalle.

Conocimiento valioso

Algo que me llevo sobre lo más importante que aprendí al realizar éste proyecto es, haberme dado cuenta lo poco que sabía y lo mucho que existen por aprender aún. Nunca me había quedado con tantas dudas y con una sensación de buscar cada vez más respuestas.

Yo sé que esto puede verse abrumador, y eso que este emulador/maquina virtual es considerado como el "Hello World" de los desarrolladores de emuladores, ya que es sumamente sencillo, hay mucha documentación, hay muchas personas que ya hicieron este proyecto y por ende tutoriales, vídeos, etc. A partir de éste punto, en adelante sólo siguen proyectos cada vez más y más complejos, si es que decides iniciarte en el desarrollo de videojuegos, emuladores o por simple hobby.

❤️
El mejor consejo que te puedo dar es, no tengas miedo a iniciar algo nuevo, mucho menos a aprender algo nuevo, nunca saber a donde puedes llegar y lo que puede lograr.

Referencias y contenido valioso

La gran mayoría de referencias están en inglés, así que si lo dominas, ya la hiciste y sino, es buen momento para aprenderlo o pulirlo, porque mucha de la mejor documentación está en inglés.

Te recomiendo muchísimo que veas los vídeos de éste chico, son pocos y ya dejó de emitir más pero, son una verdadera joya y están en español.
https://www.youtube.com/watch?v=o3Be2zAF92c

La documentación que yo seguí para realizar mi emulador:
- http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#Dxyn
- https://tobiasvl.github.io/blog/write-a-chip-8-emulator/

¿Cómo funciona el CPU? - Inglés
- https://www.youtube.com/watch?v=cNN_tTXABUA&t
- https://www.youtube.com/watch?v=FZGugFqdr60&t