pspemu

Published at Mon, 18 Jan 2010 00:00:00 UTC by soywiz

It has been a while since I updated the PSP emulator I started. Not so much time ago (and after a lot of time) somone added me to the messenger due to the PSP emulator. After that I was aware that there was a couple of emulators pretty promising in progress: [http://www.pcsp-emu.com/](http://www.pcsp-emu.com/) [http://www.jpcsp.org/](http://www.jpcsp.org/) One was done in C++ and the other one in Java. Both of them seems to advance pretty well. And it happened that I have been waiting to continue the emulator for a while. Lately I have been reading about TDD. Also D 2.0 was released, and I had in mind a few ideas I wanted to apply to start it from scratch. So, the last month I moved the old code into a branch and I created a new repository in trunk. I started to prototype there. In D 2.0 they have worked a lot in `pure nothrow` functions, that allow to execute at compilation time (CTFE). That's basically metaprogramming. Using the owm D functions to generate D code. (You can use "pure nothrow" both at compiling time as well as at executing time). The first version, in order to make a megaswitch/tables to decode instructions, I made a PHP script that used the prxtool table to generate the switch for instruction extension. And it was a bit annoying to depend on an external tool for that. I have made a few `pure nothrow` functions, that allow to generate recursive switches to decoding (as well as I did in PHP), but without the need of external tools. Also I have started to use `mixings` and `template mixins`. Each module has its own unittesting that I have coded before actually programming, or at least while I was developing it. The other things I have used was the phobos 2.0 module `bitmanip` that allows to decode instructions easily. The last thing I have done is to start the programming of an mips assembler module. In addition to allowing to add or modify code blocks in the future from the emulator without the need of external tools, allows me to generate instructions to do CPU unittesting. ```d 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); } } ``` The project's website at google code: [http://code.google.com/p/pspemu](http://code.google.com/p/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.pcsp-emu.com/) [http://www.jpcsp.org/](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. ```d 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](http://code.google.com/p/pspemu)