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...

PHP: Macro operaciones con las funciones array_* (programación funcional)

Quitar todos los espacios de principio y de final de cada elemento en un array (array_map):

$array_trimmed = array_map('trim', $array);

Alternativas:

// Mala idea. PHP tiene leaks desde hace mucho tiempo con foreach + &.  
$array_trimmed = array(); foreach ($array as $v) $array_trimmed[] = trim($v);  
foreach ($array_trimmed as &$v) $v = trim($v);  

Obtener una lista segura de enteros (por ejemplo IDs) para insertar en una query dentro de un IN().

$array_str_list = implode(',', array_map('intval', $array));

Filtrar un array obteniendo únicamente valores numéricos (array_filter):

$array_numbers = array_filter($array, 'is_numeric');

Para creación de valores para un insert con pdo (array_map):

$query_insert_values = implode(",", array_map(array($pdo, 'quote'), $values));

Para creación de asignaciones en un update con pdo (array_map con dos arrays):

$query_set = implode(',', array_map(function($k, $v) use ($pdo) {  
    return '`' . implode('`,`', explode('.', $k)) . '`=' . $pdo->quote($v);  
}, array_keys($array), array_values($array)));

Obtener una lista de elementos únicos usando un array que contiene un número indeterminado de arrays (array_reduce):

$array_unique = array_unique(array_reduce($arrays, 'array_merge', array()));

Leer más...

PHP: Crear “estructuras” en PHP 5.3

En alguna ocasión me ha interesado crear una clase que contendría simplemente unos cuantos atributos y poco más y al final he acabado haciendo un constructor del tipo:

class mystruct {  
    public $a, $b, $c;  
    function __construct($a, $b, $c) {  
        $this->a = $a;  
        $this->b = $b;  
        $this->c = $c;  
    }  
}  
class struct {  
    static public function create() {  
        $obj = new static;  
        $keys = array_keys((array)$obj);  
        foreach (func_get_args() as $k => $v) $obj->{$keys[$k]} = $v;  
        return $obj;  
    }  
}  

Para versiones anteriores de php podemos usar el constructor:

class struct {  
    static function __construct() {  
        $keys = array_keys((array)$obj);  
        foreach (func_get_args() as $k => $v) $this->{$keys[$k]} = $v;  
        return $this;  
    }  
}  

Con lo que podríamos hacer lo siguiente:

class mystruct extends struct { public $a, $b, $c; }  
// PHP 5.3  
mystruct::create(1, 2, 3);  
// Versiones anteriores  
new mystruct(1, 2, 3);  

Leer más...

phpSTE: Novedades

Ahora que vuelvo a tener Internet en plan bien, y ya vuelvo a estar con mis proyectos, he seguido mejorando phpSTE.

He cambiado bastantes cosas desde que lo empecé, y cambiaré bastantes más posiblemente hasta que esté pulido del todo.

Por ahora ocupa unas 550 líneas y ya es bastante funcional.

Además de soportar herencia, he añadido los siguientes tags:

{extends name=""} - extiende un template.  
{include name=""} - incluye un template.  
{block name=""}{/block} - define e imprime/modifica un bloque.  
{addblock name=""}{/addblock} - modifica un bloque añadiendo el contenido al final.  

{blockdef name=""}{/blockdef} - define un bloque sin utilizarlo.  
{putblock name=""} - imprime un bloque existente.  

{t}{/t} - llama a la función de gettext  

{if cond=""}{/if}  
{elseif cond=""}{else}  

{for var="" from="" to="" step=""}{/for}  

{foreach list="" var=""}{/foreach}  

He hecho optimizaciones para que los tags puedan saber si el contenido es un literal, de forma que {t}Texto{/t} se convertiría a mientras que {t}{if cond=1}Texto{/if}{/t} se convertiría a Texto

Leer más...

phpSTE

phpSTE (PHP Simple Template Engine) es un sistema de templates que he empezado a hacer hoy.
Se caracteriza por ser liviano, rápido y sencillo. Actualmente no es 100% funcional, ni lo he testeado lo suficiente, pero ya empieza a hacer cosas.
Además, soporta herencia de templates.
Está programado para PHP5.3 o superior. Hace uso de namespaces, late static binding y alguna otra cosa de esta versión.
http://code.google.com/p/phpste/
La idea es que el engine terminado no supere las 1000 líneas de código comentado y que esté todo en un único archivo para facilitar al máximo su inclusión en otros proyectos.

Leer más...

Suscribirse via RSS