He seguido avanzando con el emulador. La verdad es que la otra vez a las alturas de emulación de la cpu que llevo, el emulador ya estaba ejecutando homebrew, y tenía una interfaz bien bonita. Sin embargo, la ausencia completa de una conceción inicial de testeo, hizo que la primera versión fracasara estrepitosamente.

¿Por qué?

La emulación tenía bugs. Bugs que no estaban del todo claro por qué pasaba, y que localizaba ejecutando programas demasiado largos. Además los ejecutaba con el debugger que traía el emulador. Que sí, que era muy bonito, pero ir paso a paso depurando algo que no sabes lo que es, es de lejos muy improductivo.
Cada pequeño problema suponía dedicar un montón de tiempo. Por aquel entonces tenía mucho más tiempo, pero seguía siendo una única persona.
El problema adicional era que aunque localizase el problema, nada impedía que en un futuro, reestructurando código, se volviese a producir. Porque iba probando de vez en cuando conforme hacía cambios.
Recuerdo que muchas veces cambiaba algo, probaba un par de homebrews y pensaba que no habían afectado negativamente. Luego, más tarde, me daba cuenta que sí cuando probaba otros y me tocaba revisar todos los cambios que había hecho entre las revisiones que “creía” que habían causado el problema.

Esto ya no va a volver a pasar pese a seguir siendo una persona, al menos no tan pronunciadamente.

¿Por qué?

Porque estoy haciendo TDD.
Desde el principio. Y no voy a dar ningún paso más sin preparar y pensar seriamente el testing, sin implementarlo inicialmente y sin ir mejorándolo poco a poco.
Esto me permitirá no diseñar nada sin el testing en mente. La primera versión no tenía testing en mente, y hacerlo a esas alturas era prácticamente imposible.
Me está permitiendo detectar regresiones al instante. Me ha pasado ya varias veces de hacer un cambio incluso pequeño pensando en que no iba a afectar para mal, y el unittesting avisarme de que había malinterpretado algo o de que algo había fallado en la concepción.

Creo que ya lo comenté, pero ahora mismo el testing más difícil conceptualmente era la prueba de la cpu.
Fue un enorme acierto la creación de un módulo de ensamblado.
El testing debe ser claro y ser mantenible, y esto me lo está permitiendo.

Roadmapa teórico:

Aunque es difícil saber cómo evolucionará el asunto y es fácil que acabe cambiando los pasos a seguir ligeramente; tener una visión inicial es algo positivo.

Ya tengo casi todas las instrucciones de enteros del mips R4000 (más algunas extensiones de allegrex) implementadas y aunque reconozco que no con todo el unittesting, sí con bastante. Y ahora trabajaré en completarlo antes de seguir.

Los siguientes pasos serán crear un desensamblador y mejorar todo lo posible el ensamblador.

Cuando estas dos cosas estén hechas, haré lo mismo con la GPU. Veré cómo lo implemento, pero creo que ahí ya me tocará “mockear” de alguna forma las llamadas a opengl. Quizá con “alias” de D por rendimiento.
También haré pruebas de renderizado offscreen para el testing. Renderizar en una pantalla invisible y luego comprobar los píxeles de la salida; parcial o totalmente.
La idea es diseñar la GPU de forma que sea posible ver un frame de GPU e identificar en pantalla las diferentes texturas y rasterizados. Muy a lo no$gba.

De HLE implementé ya un par de contenedores de archivos. PBP y PSF.
Posiblemente implemente el modelo de ELF y cree un loader sencillo.
Ahí posiblemente ya haga alguna prueba real con una pantalla simple.

A nivel técnico imagino que acabaré usando DSSS para compilar y DWT como gestor de ventanas (que también es compatible con linux).

Cuando tenga todo claro, me pondré con implementación de threading y librerías de sistema.
A la par posiblemente haga ya un debugger gráfico como el que hice inicialmente. Pero mejorando todo con algunas ideas que tengo en mente. El resaltado de registros del jpscp es un gran acierto por ejemplo. La posibilidad de resaltar ciertas claves a lo IDA o a lo notepad++ también. Y ver el estado de la GPU es algo que considero altamente importante también.
Imagino que usaré shaders para implementar toda la parte gráfica. Y quizá pruebe también opencl o cuda.