pspemu (IV)

Desde la última vez que escribí sobre el emulador de psp han pasado más de dos meses y he commiteado más de la mitad de las revisiones actuales: r34 -> r77.

Han sido 3 sesiones de varios días muy intensas.

La gente como yo, que estamos enzarzados en varios proyectos, solemos abarcar este tipo de proyectos en “sesiones”.

En mi caso suelo invertir unos cuantos días cada tiempo indeterminado.

Y no es casualidad… La programación requiere concentración. Si estás programando algo y quieres hacerlo bien, intentar hacer “algo” de muchos proyectos todos los días es altamente inviable.

La gente como yo, también busca acabar con esto. Dejar de lado todos estos proyectos de una vez por todas y ser feliz. He estado casi un año sin tocar ciertos proyectos (no me refiero al emulador de psp) y empezaba a ser feliz.

De todas formas, hay veces que parece que ha llegado el momento, pero es una mera ilusión. Todavía hay que esperar un poco más.

Y mientras haya que esperar, yo seguiré con estos proyectos que llenan un poco del vacío de mi interior, que me hacen aprender un montón de cosas y que me hacen ganar experiencia en diferentes ámbitos.

Leer más...

pspemu (III)

Estos días he seguido con el emulador de PSP. Va despacito, pero con buena letra.

Estoy aprovechando mucho la ocasión para experimentar características nuevas de D 2.0 que permitan simplificar el desarrollo y reducir las posibilidades de error y reducir también las dependencias. (Con mixins y CTFE quité la dependencia de PHP para generar los switchs anidados de decodificación).
También he seguido últimamente con algunos scriptcillos en python. Después de estar usando PHP durante muchos años, python es una bendición. Es como D en cuanto a que tiene un montón de características de lenguaje molonas.

En cualquier caso a lo que iba…
Estos días me he encargado de ir completando la implementación de la CPU y de mejorar el ensamblador. Hace un rato he hecho una implementación sencilla del desensamblador. He empezado a comentar y he comentado completamente el cpu.d. Y he hecho más unittesting.

Ahora tocará refactorización, y documentación.

Y como ya puse, lo siguiente con lo que me pondré será la GPU.
La verdad es que tengo unas ganas horribles de poner una ventanita y hacer alguna prueba.
Pero hacer eso sería tan peligroso como tentador, así que tendré paciencia y seguiré como hasta ahora.

Leer más...

pspemu (II)

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.

Leer más...

PHP: Simular static binding en PHP < 5.3

class A {  
    const CONSTANT = 'A';  

    function __construct() {  
        echo constant(get_class($this) . '::CONSTANT');  
        // echo self::CONSTANT; // No static. Would output AA instead of AB.  
        // echo static::CONSTANT; // PHP >= 5.3  
    }  
}  

class B extends A {  
    const CONSTANT = 'B';  
}  

ob_start();  
$a = new A;  
$b = new B;  
var_dump(ob_get_clean() == 'AB');  

Leer más...

pspemu

Hacía mucho tiempo que no tocaba el emulador de PSP que empecé.
Hace relativamente poco (y después de mucho tiempo) me agregó una persona al messenger por el emulador de PSP.
A raíz de eso me enteré que habían un par de emuladores muy prometedores en progreso:

http://www.pcsp-emu.com/
http://www.jpcsp.org/

Uno hecho en C++ y el otro en Java. Los dos parece que avanzan bastante bien.
El caso es que hacía bastante tiempo que quería volverle a meter mano. Últimamente he estado leyendo cosas de TDD. Salió también la versión 2.0 de D. Y tenía en mente varias ideas que quería implementar a la hora de empezarlo de cero de nuevo.

Así que hará cosa de un mes, moví el código viejo a una branch, y creé un repositorio nuevo en trunk.
Ahí empecé los primeros trasteos.
En D 2.0 han trabajado bastante el tema de funciones “pure nothrow”, que permiten ejecutarse en tiempo de compilación (CTFE). Básicamente consiste en metaprogramación. Usando las propias funciones de D generar código D. (Si son “pure nothrow” en tiempo de compilación además de en tiempo de ejecución).
En la primera versión, para hacer el megaswitch/tablas de decodifiación de instrucciones, hice un script en php que con la tabla del prxtool, generaba el switch de ejecución de instrucción. Era un poco molesto depender de una utilidad externa.
Pues he hecho una serie de funciones pure nothrow, que permiten generar switchs recursivos para la decodificación (igual que se hacía en php, pero sin necesidad de herramientas externas).
También he empezado a utilizar mixins y template mixins.
Cada módulo tiene su unittesting que he intentado programar antes, o al menos mientras desarrollo.
Otra de las cosas que he utilizado es el módulo de phobos 2.0 bitmanip que me permite decodificar una instrucción muy fácilmente.
Y lo último que he hecho ha sido empezar la programación de un módulo de ensamblado de mips.
Esto además de permitir en un futuro añadir/modificar bloques de código desde el emulador sin necesidad de herramientras externas, me permite generar instrucciones para el unittesting de la cpu.

unittest {  
    writefln("Unittesting: core.cpu.cpu...");  
    scope cpu = new CPU(); foreach (n; 0..32) cpu.registers[n] = 0;  

    scope assembler = new AllegrexAssembler(cpu.memory);  

    // (v0 = (7 + 11 - 5)) == 13  
    writefln("  (v0 = (7 + 11 - 5)) == 13");  
    {  
        assembler.startSegment("code", Memory.mainMemoryAddress);  

        assembler.assemble("addi a0, zero, 7");  
        assembler.assemble("addi a1, zero, 11");  
        assembler.assemble("add v0, a0, a1  ");  
        assembler.assemble("addi v0, v0, -5 ");  

        cpu.registers.set_pc(Memory.mainMemoryAddress);  
        cpu.execute(4);  
        assert(cpu.registers["v0"] == 13);  
    }  
}  

La página del proyecto en google code:
http://code.google.com/p/pspemu

Leer más...

Suscribirse via RSS