17 octubre, 2010

El proyecto TurboTron

TurboTron es el nombre que he dado al proyecto de construcción de una serie de ordenadores virtuales escritos en lsl y ossl específicamente para OpenSim (en honor de la película de 1982 de Steven Lisberger). La idea vino tras varias pruebas en un servidor StandAlone con modificaciones del script "Assembly-Like Programming Language" de "Xaviar Czervik" el cual me ha servido de soporte para mi versión. Éstas máquinas virtuales son capaces de interpretar su propio lenguaje ensamblador (TURBOTRONasm) de diseño simple y versatil, compatible con direccionamiento dinámico para crear macros y funciones. La complejidad de la cpu ha sido aumentada para simular funciones comunes como un contador, una pila (utilizada para el regreso despues de macros), un acumulador de entrada (para el teclado numérico) y una memoria solo lectura para la recepción de parámetros y flags. En lugar de una memoria existen tres, la ram, desde donde se leen los programas y se puede escribir temporalmente, la memoria gráfica que acumula información de una línea de píxeles* y una memoria de pares, donde guardar la información referenciada con un nombre. También hay una memoria externa y no volátil en la que se escribe a través de interrupciones.




El cpu llega a ser alrededor de 300 veces más rápido que la versión de Xaviar Czervik gracias a un hack que multiplica el número de lecturas por cada ciclo, dispone de más memoria y un lenguaje mejorado para funcionar con datos dinámicos. La velocidad ha sido calculada con un bucle de 5 líneas de código y puede llegar a los 550 ciclos por segundo (con un multiplicador de 300). La ram guarda los datos en modo texto (string por celda) por lo que queda legible "en caliente", lo que permite un seguimiento completo de los procesos. La capacidad de la memoria ram es la misma de la clase array en C#.

Arquitectura de cpu:

reg0, reg1, reg2: Los registros de uso general, los he mantenido desde la versión de Xaviar Czervik.
counter: El contador, con llamadas especiales para sumar, restar y poner a cero.
pilret: la pila de regreso, funciona automáticamente para dar soporte a "return" tras una llamada a macro/función "call".
flags: la memoria de banderas, se usa para leer información adicional tras un mandato (parámetros de funciones, debug, mod tras una división etc...)
inbus: El acumulador del bus para las entradas de teclas (no botones de panel).
pointer: Indica la posición del cabezal lector sobre la memoria ram, (puede ser cambiado con goto, jump o call)

-parte gráfica (no se usa actualmente):
cgav: vector caché para guardar información de un color.
cgax, cgay: puntero caché de posición bidimensional.
cgat: minimemoria caché para guardar información sobre una textura
gmemory: memoria gráfica sobre la cual se puede escribir la información completa de una línea de píxeles para enviarla de una vez.

Periféricos: Hasta ahora he diseñado varios periféricos funcionales de entrada y salida para la máquina:

Panel: Con leds de actividad y botones de encendido y reset, era necesario.
Debug: Botones para mandar interrupciones a la cpu que fuerzan el vuelco de las memorias al chat.
Dirkeys: un pequeño panel de botones (arriba, abajo, izquierda, derecha y ok)
pad numérico: un pad numérico de 15 teclas.
Consola: una consola de texto plano (hover text) de alta velocidad.
Tcga: una pantalla de 16*12 celdas capaz de cambiar de textura cada una de éstas independientemente. (versión alpha, es increíblemente lenta)
Ftlht: utiliza el mismo protocolo de la consola, pero dibuja una página de hipertexto sobre un prim. (solo para navegadores 2.0)
Hd0: un método simple de guardar información de manera persistente.

lenguaje de programación hasta hoy:

// comentario y primera linea
mode0 set tipo puntero 0
mode1 set tipo puntero 1
mode2 set tipo puntero 2
set0 guardar valor en puntero 0
set1 guardar valor en puntero 1
set2 guardar valor en puntero 2
def0 definir tipo y datos de reg0 en csv (coma separated values tipo,valor)
def1 definir tipo y datos de reg1 en csv (coma separated values tipo,valor)
def2 definir tipo y datos de reg2 en csv (coma separated values tipo,valor)
jump saltar a línea definida
fin finaliza el programa y vuelve a bios
jif_max saltar si reg0 es mayor que reg1*
jif_less saltar si reg0 es menor que reg1*
jif_match saltar si reg0 es identico a reg1*
jif_key saltar si reg0 es igual a cache_inbus*_
suma suma reg0 a reg1 y lo guarda en reg2 
resta resta reg0 a reg1 y lo guarda en reg2 
rand genera número aleatorio entre reg0 y reg1
load0 cargar dato de dirección dentro de reg0
load1 cargar dato de dirección dentro de reg1
load2 cargar dato de dirección dentro de reg2 (deshabilitado)
save0 guardar dato de reg0 en dirección de memoria
save1 guardar dato de reg1 en dirección de memoria 
save2 guardar dato de reg2 en dirección de memoria
chat decir por el chat en el canal 0
ftlout enviar información a través de bus ftl (texto plano, $cls limpia)
input pedir información al usuario a través de chat y guardarla en reg2
hdd.read pide y espera el dato y lo carga en reg0
hdd.write manda guardar reg0 en la posición indicada
reset resetea la máquina virtual
run_bios cambia la imágen de bios y reinicia la máquina
run_exe carga el programa de nombre reg0 y lo ejecuta
run_lslmod arranca el script de nivel bajo* indicado (lsl)
memshow muestra a traves del chat el contenido de la memoria
cpushow muestra a traves del chat el contenido de todos los registros de cpu
inventory.getname0 carga en reg0 el nombre del programa solicitado con reg0
inventory.getname1 carga en reg1 el nombre del programa solicitado con reg1
inventory.getname2 carga en reg2 el nombre del programa solicitado con reg2 (deshabilitado)
readline carga el texto de la línea indicada en reg2 (csv: texto,linea)
write escribe una nota en el inventario principal con el nombre indicado en parametro y el valor de reg0
counter.start inicializa el contador en valor 0
counter.set copia el valor int de reg0 en counter
counter.+ sumar uno a counter
counter.- restar uno a counter
counter.save guarda el valor de contador en el sector de memoria especificado
counter.get lee el valor de counter y lo situa en reg2
@ definir etiqueta de dirección dinámica (@[espacio]nombreetiqueta)
get0 copia a reg0 el valor de casillero-cpu indicado (reg1,reg2,counter,inbus,param)
guardar reg0 como parametro en la posicion indicada
saveparam guardar reg0 como parametro en la posicion dinámica indicada
loadparam cargar en reg0 el parametro dinámico indicado
saveparamnum guardar reg0 como parametro en la posicion absoluta indicada
loadparamnum cargar en reg0 el parametro absoluto indicado
savecsvparam parsear reg0 como csv (valores separados por coma) y guardarlo en paramlist
gtif_max saltar a etiqueta @ si reg0 es mayor que reg1*
gtif_less saltar a etiqueta @ si reg0 es menor que reg1*
gtif_match saltar a etiqueta @ si reg0 es identico a reg1*
gtif_key saltar a etiqueta @ si reg0 es igual a cache_inbus*
import carga el programa indicado en ram manteniendo la memoria actual.
debug guarda una imagen del estado actual del hardware en flags de 0 a 5 (cpu,ram,ref,prof,gmem,gpu)
cgasendpix enviar el cache gráfico como píxel no cacheado en gmemory.
cgapixset definir un pixel cgi en cache a traves del valor de action (x,y,R,G,B)
cgalinsave guardar la cache en todos los casilleros de memoria gráfica (linea)
cgapixsave guardar la cache a la memoria grafica 
cgaout envia la memoria grafica actual a traves del bus adecuado
cgacls limpiar la memoria grafica
cgat.set pone valor txt en el mismo valor que action
cgax.set pone valor x en el mismo valor que action
cgay.set pone valor y en el mismo valor que action
cgax.+ suma 1 al valor cgax
cgax.- resta 1 al valor cgax
cgay.+ suma 1 al valor cgay
cgay.- resta 1 al valor cgay
cgav.set definir el valor de vector-color (cache R,G,B)

Por otro lado también estoy trabajando en una especie de minikernel con funciones recurrentes con la idea de preparar un pequeño sistema operativo primitivo que gestione la máquina, más por investigar que por cualquier otra cosa. Esta versión aun no está acabada al 100% y no me gustaría que existieran cientos de versiones incompatibles entre ellas, por lo que por ahora no se puede copiar, pero existen dos versiones de muestra disponibles, una de ellas (tronassembler 1700) es una versión muy parecida a la de Xaviar Czervik pero que no depende del evento database, el otro dispone de un multiplicador de cpu y varias optimizaciones en el código y el pad numérico. Éstas versiones no son compatibles con el nuevo lenguaje ni con las referencias dinámicas, pero es también muy didáctico por su simplicidad.

Puedes copiarlas, encontrar información y software o probar la versión nueva en el metaverso en mi hacklab en OsGrid:
http://slurl.com/secondlife/ABDERRAMAH/113/94/26
Publicar un comentario