CPU TURBOTRON HT 0.8


integer cfgdbg=TRUE;    //debug on-off
integer cfgdbgchan=10;  //canal de debug

list memory;            //memoria ram
list paramlist;         //memoria de parametros (interprog data)
list refs;              //combinada con la anterior forman una memoria de pares
list gmemory;           //cache gráfico de línea
list concat;            //memoria concat
list flags;             //memoria solo lectura multiproposito (paso parametros, direcciones de registro)
list internall;         //lista multiproposito de uso interno
string cache_inbus;     //cache bus input
integer lastpos;
integer run=TRUE;

string reg0;            //cpu reg0
string type0;           //cpu tipo0
string reg1;            //cpu reg1
string type1;           //cpu tipo1
string reg2;            //cpu reg2
string type2;           //cpu tipo2
list pilret=[];         //pila de puntero de regreso
integer counter=0;      //cpu contador
vector  cgav;           //puntero vector*3 "color"
integer cgax;           //puntero x modo contador
integer cgay;           //puntero y modo contador
string cgat;            //identificador de textura

integer cga_dbus=9;
integer cga_bus=8;
float clock=0.03;        //delay de procesador
integer clock_mult=200;  //multiplicador de relog 25 166 300
integer over;            //cache de multiplicador
integer lstn;            //cache de handler de escucha
string bios_name;        //nombre de la bios
integer inv_max_prog;    //numero maximo de notecards
integer i;               //puntero de lectura de programa
integer lastProgLine;    //cache última línea

tronchip(string str, integer comnum){
    if (comnum==1){//boton de on 
    debugmsg("bios panel recibido "+str);
        if (str=="on"){
        //bios_name="bios_lab";
        //llGetNotecardLine(bios_name, lastProgLine);
        memload(bios_name);
        }else if (str=="rst"){llResetScript();}
        }
    
    if(comnum==2){ //botones de dirección
        cache_inbus=str;
        debugmsg("bios dirKey recibido cache_inbus="+str);
    }else if(comnum==3){//ftlout
    
    }else if(comnum==4){//eventos internos / interrupciones
        if (str=="mem"){//debug de memoria
        llSay( 0,"[ RAM ]"+llList2CSV(memory));
        llSay( 0,"{REFS }"+llList2CSV(refs));
        llSay( 0,"{PARAM}"+llList2CSV(paramlist));
        
        }else if (str=="cpu"){//debug de cpu
        internall=[];
        internall+="[reg0]"+reg0+" "+type0;
        internall+=" [reg1]"+reg1+" "+type1;
        internall+=" [reg2]"+reg2+" "+type2;
        internall+=" [inbus]"+cache_inbus;
        internall+=" (count)"+counter;
        internall+=" <cgav>"+cgav;
        internall+=" [x/y]"+cgax+"/"+cgay;
        internall+=" %flags% {"+llList2CSV(flags)+"}";
        internall+=" :concat:"+llList2CSV(concat);
        internall+=" :ret:"+getpilret();
        internall+=" :pila ret: {"+llList2CSV(pilret)+"}";
        llSay( 0,llList2CSV(internall));
        }else if(str=="cga"){
        llSay( 0,"[ GRAM cgaline ]"+llList2CSV(gmemory));
        }
    
    }else if(comnum==5){//fsata    in
    
    }else if(comnum==6){//fsata out
    
    }else if(comnum==7){//fsata out
        reg0=str;
        llSetTimerEvent(clock);    
    
    }else if(comnum==8){// COLOR GRAPHIC ADAPTER cga
    
}}      

debugmsg(string msg){
    if (cfgdbg){
        llSay(cfgdbgchan,"dbg::"+(string)msg );
    }
}
 
err(integer li, string s) {
    llOwnerSay("Error de la muerte en linea " + (string)li + ": " + s);
    llResetScript();
}
xerr(integer li, string s) {
    llOwnerSay("Error en ejecucion: " + (string)li + ": " + s);
}
 
save(string val, integer loc) {
    integer add = lastProgLine + (integer)loc;
    if (add < llGetListLength(memory)) {
        memory = llListReplaceList(memory, [val], add, add);
    } else {
        integer i = 0;
        while (i < add-llGetListLength(memory)) {
            memory += "";
            i++;
        }
        memory += val;
    }
}

string getval(string subval){ // comprobar si se trata de un valor puro o de un registro
    string rete;
    integer pos=llListFindList(refs,[(string)subval]);//solo se usa en busqueda de parametros referenciados
    list internalle=llCSV2List(subval);
    string subvalor=llList2String(internalle,0);
    
    if (subval=="reg0"){
    rete = reg0;
    }else if (subval=="reg1"){
    rete = reg1;
    }else if (subval=="reg2"){
    rete = reg2;
    }else if(subvalor=="flag"){
    subvalor=llList2String(internalle,1);
    rete = llList2String(flags,(integer)subvalor);
    }else if(subval=="counter"){
    rete = (string)counter;
    }else if(subval=="pointer"){
    rete = (string)i;
    }else if(pos!=-1){
    rete =llList2String(paramlist, pos) ;
    }else{    
    rete= subvalor;
    }
    if(subval!=rete){
    debugmsg("dinamic-get::val "+(string)subval+"/::name "+(string)rete);}
    return rete;
}

memload(string prog){
    memory=[];
    lastProgLine=-1;
    string data;
    @count;
    data=osGetNotecardLine(prog, (lastProgLine+=1));//cargar nota del programa
    if (data == EOF) {
            lastProgLine=0;
            i=0;
            llSetTimerEvent(clock);//iniciar el programa, ya cargado
        }else{
        //llSay(cfgdbgchan,"dbg::load-data::"+(string)data );
        memory += data;
        if ((string)data=="ERROR!"){
        llSay(cfgdbgchan,"dbg::load-data::NO SE PUEDE CARGAR PROGRAMA");
        llResetScript();
        }else{
        jump count;
        }
    }
}

interpret(string command,string action){
    @interpret;
    if (command == "mode0") {//comando es tipo puntero 0
        debugmsg("CMD::"+command+"::"+(string)action);
            if (!(action == "str" || action == "int" || action == "flo")) {
                err(i,  "Tipo de datos invalido.");
            }
            type0 = action;
            jump next;
        } else if (command == "mode1") {//comando es tipo puntero 1
        debugmsg("CMD::"+command+"::"+(string)action);
            if (!(action == "str" || action == "int")) {
                err(i,  "Tipo de datos invalido.");
            }
            type1 = action;
            jump next;
        } else if (command == "mode2") {//comando es tipo puntero 2
        debugmsg("CMD::"+command+"::"+(string)action);
            err(i,  "Registro dos no se puede asignar");
            jump next;
        } else if (command == "set0") {//comando es store 0
        debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "") {
                err(i, "Tipo de datos no definido.");
            }
            reg0 = getval(action);
            jump next;
        } else if (command == "set1") {//comando es store 1
        debugmsg("CMD::"+command+"::"+(string)action);
            if (type1 == "") {
                err(i, "Tipo de datos no definido.");
            }
            reg1 = getval(action);
            jump next;
        } else if (command == "set2") {//comando es store 2
            debugmsg("CMD::"+command+"::"+(string)action);
            err(i,  "Registro dos no se puede asignar.");
            jump next;
        } else if (command == "jump") {//comando es saltar
            debugmsg("CMP::"+command+"::"+(string)action);
            i = (integer)getval(action) - 1;
        } else if (command == "jif_max") {//comando es saltar si reg0<reg1
            if (type0 == "str" || type1 == "str") {
                err(i,  "No se pueden comparar strings.");
            }
            if ((float)reg0 > (float)reg1){
                debugmsg("JIF::"+command+"::"+(string)action+"::linea="+(string)i);
                i = (integer)getval(action) - 1;
                //jump next;
                }
        } else if (command == "jif_less") {//comando es saltar si reg0<reg1
           if (type0 == "str" || type1 == "str") {
                err(i,  "No se pueden comparar strings.");
            }
            if ((float)reg0 < (float)reg1){
                debugmsg("JIF::"+command+"::"+(string)action+"::linea="+(string)i);
                i = (integer)getval(action) - 1;
                //jump next;
                }
        } else if (command == "jif_match") {//comando es saltar si reg0=reg1
            if (type0 == type1) {
            debugmsg("JIF::"+command+"::"+(string)action+"::linea="+(string)i);
                if (reg0 == reg1){
                i = (integer)getval(action) - 1;
            }}
            //jump next;
        }else if (command == "jif_key"){//comando saltar si cache_input=reg0
            debugmsg("JIF::"+command+"::"+(string)action+"::"+reg0+"::cache="+cache_inbus);
            
            if (cache_inbus==reg0){
            i = (integer)getval(action) - 1;
            cache_inbus="";
            }        
        //jump next;
        } else if (command == "suma") {//suma reg0 a reg1 y lo guarda en reg2
        debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "str" || type1 == "str") {
                type2 = "str";
                reg2 = reg0 + reg1;
            } else if (type0 == "int" && type1 == "int") {
                type2 = "int";
                reg2 = (string)((integer)getval(reg0) + (integer)getval(reg1));
            } else if (type0 == "flo" && type1 == "flo") {
                type2 = "int";
                reg2 = (string)((float)getval(reg0) + (float)getval(reg1));
            } else if (type0 == "flo" && type1 == "int") {
                type2 = "int";
                reg2 = (string)((float)getval(reg0)+  (integer)getval(reg1));
            } else if (type0 == "int" && type1 == "flo") {
                type2 = "int";
                reg2 = (string)((integer)getval(reg0) + (float)getval(reg1));
            } else {
                err(i, "Tipo de registro inválido o erroneo.");
            }
            jump next;
        } else if (command == "resta") {//resta reg0 a reg1 y lo guarda en reg2
        debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "int" && type1 == "int") {
                type2 = "int";
                reg2 = (string)((integer)getval(reg0) - (integer)getval(reg1));
            } else {
                err(i, "Tipo de registro inválido o erroneo.");
            }
            jump next;
            
        } else if (command == "multi") {//multiplica reg0 a reg1 y lo guarda en reg2
            debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "int" && type1 == "int"||type0 == "flo" && type1=="flo") {
                type2 = "flo";
                reg2 = (string)((float)getval(reg0) * (float)getval(reg1));
            } else {
                err(i, "Tipo de registro inválido o erroneo.");
            }
            jump next;
        } else if (command == "divi") {//dividir reg0 a reg1 y lo guarda en reg2
            debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "int" && type1 == "int"||type0 == "flo" && type1=="flo") {
                type2 = "flo";
                reg2 = (string)((float)getval(reg0) / (float)getval(reg1));
                //flags+=(string)((float)getval(reg0) mod (float)getval(reg1));
            } else {
                err(i, "Tipo de registro inválido o erroneo.");
            }
        } else if (command == "load0") {//cargar datos de direccion de memoria dentro de reg0
        debugmsg("CMD::"+command+"::"+(string)getval(action));
            if (type0 == "") {
                err(i, "El tipo de dato no se ha definido.");
            }
            reg0 = llList2String(memory, lastProgLine + (integer)getval(action));
            jump next;
        } else if (command == "load1") {//cargar datos de direccion de memoria dentro de reg1
        debugmsg("CMD::"+command+"::"+(string)getval(action));
            if (type1 == "") {
                err(i, "El tipo de dato no se ha definido.");
            }
            reg1 = llList2String(memory, lastProgLine + (integer)getval(action));
            jump next;
        } else if (command == "load2") {//cargar datos de direccion de memoria dentro de reg2 (es error)
        debugmsg("CMD::"+command+"::"+(string)getval(action));
            err(i, "Registro dos no puede cargar los datos.");
        } else if (command == "save0") {//guarda registro 0 al area de memoria especificada
        debugmsg("CMD::"+command+"::"+(string)action);
            save(reg0, (integer)getval(action));
            jump next;
        } else if (command == "save1") {//guarda registro 1 al araa de memoria especificada
        debugmsg("CMD::"+command+"::"+(string)action);
            save(reg1, (integer)getval(action));
        } else if (command == "save2") {//guarda registro 2 al araa de memoria especificada
        debugmsg("CMD::"+command+"::"+(string)action);
            save(reg2, (integer)getval(action));
        } else if (command == "chat") {//dice el registro uno por el chat
        //debugmsg("CMD::"+command+"::"+(string)action);
            llSay(0, reg0);
        } else if (command == "ftlout") {//envía linea de texto de reg0 por ftl (fake console)
        //debugmsg("CMD::"+command+"::"+(string)action);
         llMessageLinked(LINK_SET,3,reg0,NULL_KEY);//cfg de bus ftlnet
         jump next;
        } else if (command == "input") {//esperar a que el usuario introduzca información
        debugmsg("CMD::"+command+"::"+(string)action);
            llSetTimerEvent(0);
            over=0;
            lstn = llListen(0, "", "", "");
        } else if (command == "rand") {//genera numero aleatorio entre el rango reg0 y reg1
        debugmsg("CMD::"+command+"::"+(string)action);
            if (type0 == "flo" || type1 == "flo") {
                type2 = "flo";
                reg2 = (string)(llFrand((float)reg1-(float)reg0)+(float)reg0);
            } else if (type1 == "int" && type0 == "int") {
                type2 = "int";
                reg2 = (string)((integer)llFrand((float)reg1-(float)reg0+1)+(integer)reg0);
            }
            jump next;
        } else if (command == "//") {//comentario
        jump next;
         } else if (command == "@") {//salto de linea (se ignora porque puede ser buscado)
        jump next;
        
        //kernel x2
        } else if (command == "run_bios") {//carga el ejecutable de nombre reg0 NECESITA SIS DE SEGURIDAD
        debugmsg("CMD::"+command+"::"+(string)action+" [se cargará otro script como bios]");
        llSetObjectDesc(reg0);
        llResetScript();
        
        } else if (command == "inventory.getname2") {//carga el nombre del objeto de inventario especificado en reg0
        debugmsg("CMD::"+command+"::"+(string)action+" ");
            err(i, "No se puede cargar nombre de objeto en reg2.");
        } else if (command == "inventory.getname1") {//carga el nombre del objeto de inventario especificado en reg0
        debugmsg("CMD::"+command+"::"+(string)action+" ");
            if (type0 == "int") {
            type1 = "str";
            reg1 = llGetInventoryName(INVENTORY_NOTECARD,(integer)reg0);
            }else{
            xerr(i, "En las consultas a inventario el puntero debe de ser integer.");
            }    
        } else if (command == "inventory.getname0") {//carga el nombre del objeto de inventario especificado en reg0
        debugmsg("CMD::"+command+"::"+(string)action+" ");
            if (type0 == "int") {
            type0 = "str";
            reg0 = llGetInventoryName(INVENTORY_NOTECARD,(integer)reg0);
            }else{
            xerr(i, "En las consultas a inventario el puntero debe de ser integer.");
            }
            jump next;
        }else if (command == "readline") {    //lee linea de notecard y la situa en reg2
        internall=llCSV2List((string)action);
        string subt=llList2String(internall, 0);
        string subv=llList2String(internall, 1);
        subt=getval(subt);
        subv=getval(subv);
        type2="str";
        reg2=osGetNotecardLine(subt,(integer)subv);
        
        }else if (command == "read") {
        reg2=osGetNotecard(getval(action));
        
        }else if (command == "write") {
        osMakeNotecard((string)getval(action),(string)getval(reg0));
        
        }else if (command == "inventory.delete"){
        llRemoveInventory(getval(action));
        
        } else if (command == "reset") {
        llResetScript();
        } else if (command == "get0") {//cargar datos de registros de cpu dentro de reg0
            string str_val;
            string typ_val;
            reg0=getval(action);
            debugmsg("GET0::"+command+"::"+str_val+","+typ_val);
            jump next;
        } else if (command == "def0") { //definir tipo y valor reg0
        internall=llCSV2List((string)action);
        string subt=llList2String(internall, 0);
        string subv=llList2String(internall, 1);
        type0 = subt;
        reg0 = getval(subv);
        jump next;
        } else if (command == "def1") { //definir tipo y valor reg1
        internall=llCSV2List((string)action);
        string subt=llList2String(internall, 0);
        string subv=llList2String(internall, 1);
        type1 = subt;
        reg1 = getval(subv);
        jump next;
        } else if (command == "def2") { //definir tipo y valor reg2
        internall=llCSV2List((string)action);
        string subt=llList2String(internall, 0);
        string subv=llList2String(internall, 1);
        type2 = subt;
        reg2 = getval(subv);
        jump next;
        }else if (command == "run_lslmod") {//reset script lsl
        debugmsg("RUN::"+command+"::"+(string)action+" [arrancando script lsl]");
        llResetOtherScript((string)reg0);
                
        }else if (command == "memshow") {//muestra el valor de la memoria completa
        debugmsg("debug de memoria");
        llMessageLinked(LINK_SET,4,"mem","");
        
        }else if (command == "cpushow") {//muestra el valor de la cpu completa
        debugmsg("debug de memoria");
        llMessageLinked(LINK_SET,4,"cpu","");
        
        }else if (command == "debug") {//muestra el valor de la cpu completa en flags
        integer cpux=0;
        integer stress=0;
        internall=[];
        if (reg0!=""){
        cpux+=1;    }
        if (reg1!=""){
        cpux+=1;    }
        if (reg2!=""){
        cpux+=1;    }
        if (counter!=0){
        cpux+=1;    }    
        if (cache_inbus!=""){
        cpux+=1;    }
        internall+=(string)cpux;    
        stress=llGetListLength(memory);
        internall+=(string)stress;
        stress=llGetListLength(refs);
        internall+=(string)stress;
        stress=llGetListLength(pilret);
        internall+=(string)stress;
        internall+="-1";
        internall+="-1";
stress=llGetListLength(concat);
internall+=(string)stress;
stress=llGetListLength(flags);
internall+=(string)stress;
        flags=internall;
        
        }else if (command == "run_exe") {//ejecutar el programa indicado en reg0
        debugmsg("RUN::"+command+"::"+(string)reg0+" [cambiando de programa]");
        if (llGetInventoryType(reg0)==INVENTORY_NOTECARD){
        //llSetTimerEvent(0);
        i=0;
        memload(reg0);
        }else{
        debugmsg( "No se ha encontrado el programa especificado > "+(string)reg0);
        }
        }else if (command == "fin"||command =="fin}") {//fin del programa, volver a "bios"
        debugmsg("FIN::"+command+"::"+(string)reg0+" [programa finalizado, carga de bios]");
        //llSetTimerEvent(0);
        i=0;
        memload(bios_name);
        
        }else if (command == "hdd.read") {//pedir datos al disco duro
                llSetTimerEvent(0);
                over=0;
        debugmsg("solicitando datos HDD::time-off");
        llMessageLinked(LINK_SET,6,(string)getval(action),"");
                
        }else if (command == "hdd.write") {//guardar datos en el disco duro
        if (type0=="str"){
        llMessageLinked(LINK_SET,5,(string)getval(action)+","+(string)reg0,"");
        }else{
        err(i, "El dato a guardar en hdd debe de ser string.");
        }
        jump next;
        
        }else if(command == "dinadr"){//buscar la posición y dejarla en reg0
        integer pos=llListFindList(memory,["@ "+getval(action)]);
        reg0=(string)pos;
        type0="int";
        
        }else if (command == "goto"){//saltar a etiqueta
        integer pos=llListFindList(memory,["@ "+getval(action)]);
        if (pos!=-1){
        i=pos;
        }else{
        xerr(i, "ERROR, existe ninguna etiqueta [ @ " + (string)getval(action) + " ]");    
        }
       
        }else if(command == "call"){        //LLAMAR A FUNCIÓN
            list internalle=llCSV2List(action);
            string acta=llList2String(internalle, 0);
            integer pose=llListFindList(memory,["@ "+getval(acta)]);
            if (pose!=-1){
            lastpos=(integer)i;
            addpilret(lastpos);
            setflags(internalle);                
            i = (integer)pose;
            }else{
                xerr(i, "ERROR, existe ninguna etiqueta [ @ " + (string)action + " / "+(string)pose+" ]");
            }
            debugmsg("CALL::"+(string)getval(action)+" / "+(integer)pose);
            
        }else if(command=="return"){        //FIN DE FUNCIÓN
            if(action==""){
                }else{
                reg2 = getval(action);
                }
                lastpos=getpilret();
                rempilret();
                i = lastpos;
                
        //counter
        }else if (command == "counter.start") {//iniciar el counter en valor 0
            counter=0;
            debugmsg("COUNT::counter.start");
        }else if (command == "counter.set") {//forzar valor en el counter
            counter=(integer)reg0;
            debugmsg("COUNT::counter.set "+(string)counter);
        }else if (command == "counter.+") {//contar hacia arriba
            counter+=1;
            debugmsg("COUNT::counter.+1 "+(string)counter);
        }else if (command == "counter.-") {//contar hacia abajo
            counter-=1;
            debugmsg("COUNT::counter.-1 "+(string)counter);
        }else if (command == "counter.save") {//contar hacia abajo
            save((string)counter, (integer)action);
        }else if (command == "counter.get") {//contar hacia abajo
            reg2=(string)counter;
        // counter
        // paramsystem
        }else if (command == "saveparam") {//guardar reg0 como parametro en la referencia indicada
        integer pose=llListFindList(refs,[(string)action]);
            if (pose==-1){
            paramlist+=(string)reg0;//meter el valor en paramlist
            pose=llListFindList(paramlist,[(string)reg0]);//buscar en que posición se guardó
            refs=llListReplaceList(refs,[(string)action],pose,pose);    
            //refs+=(string)action;
            
            }else{
            refs=llListReplaceList(refs,[(string)action],pose,pose);
            paramlist=llListReplaceList(paramlist,[(string)reg0],pose,pose);
            }
        //paramlist=llListReplaceList(paramlist,[(string)reg0],(integer)getval(action),(integer)getval(action));
        debugmsg("PARAM::parametro guardado "+(string)reg0+" como "+(string)getval(action));
        
        // sistema de pila
        
                
        // fin sistema de pila
        }else if(command == "import"){//cargar en memoria una libreria dinamica (dinalib)
        string notecard = getval(action);
        integer tmpint=osGetNumberOfNotecardLines(notecard);
        internall=[];
        
           for(tmpint=0; tmpint<=osGetNumberOfNotecardLines(notecard); tmpint++) {
           // llSay(0, osGetNotecardLine(notecard, i));
           internall+=osGetNotecardLine(notecard, tmpint);
            }
        addtomem(internall);           
        
        
        }else if (command == "loadparamnum") {//cargar en reg0 el parametro indicado por numero
        reg0=llList2String(paramlist,(integer)action);
        
        }else if (command == "loadparam") {//cargar en reg0 el parametro indicado por referencia
        integer pos=llListFindList(refs,[(string)action]);
        reg0=llList2String(paramlist,pos);
            
        }else if (command == "savecsvparam") {//parsear reg0 como csv (valores separados por coma) y guardarlo como parametros multiples
        flags=llCSV2List(reg0);
        debugmsg("PARAM::parseado_CSV "+(string)reg0+"--  se sobreescribiran las banderas --");
        // paramsystem
        // CGA SYSTEM
        
        }else if(command == "cgaout"){//enviar la memoria grafica (una linea)
        string cgaline=llList2CSV(gmemory);
         llMessageLinked(LINK_SET,cga_bus,cgaline,"");
                      
        }else if(command=="cgapixset"){//definir un pixel cga a traves del valor de ACTION (x,y,R,G,B)
        llSetTimerEvent(0);
        over=0;
        internall=llCSV2List(action);    
        string tmpstr="";
        
        tmpstr=llList2String(internall, 0);
        cgax=(integer)tmpstr;   
        tmpstr=llList2String(internall, 1);
        cgay=(integer)tmpstr;
         tmpstr=llList2String(internall, 2);
        cgav.x=(float)tmpstr;
         tmpstr=llList2String(internall, 3);
        cgav.y=(float)tmpstr;
         tmpstr=llList2String(internall, 4);
        cgav.z=(float)tmpstr;
        llSetTimerEvent(clock);
       
        }else if(command=="cgapixsave"){//guardar en cache la info de x,y,R,G,B,txt,null
        internall=[];
        internall+=cgax; 
        internall+=cgay;
        internall+=cgav.x;
        internall+=cgav.y;
        internall+=cgav.z;
        internall+=cgat;
        internall+=" ";
        setpixgmem(internall);
        
        }else if(command=="cgasendpix"){//enviar el cache gráfico a traves de el canal directo
        sendpix();
        
        }else if(command=="cgalinsave"){//repetir cache en todos los casos.
        
        //bucle
        cgax=0;
        @lope;
        cgax+=1;
        setpix();
        if (cgax<16){
        jump lope;
        }   

        }else if(command=="cgacls"){//limpiar memoria grafica
        cleargmem();  
                       
        //CGA SYSTEM
        //kernel x2 fin
        }else if(command=="cgax.set"){//ser valor x modo contador en el mismo valor que reg0
        cgax=(integer)getval(action);
        
        }else if(command=="cgay.set"){//ser valor y modo contador en el mismo valor que reg0
        cgay=(integer)getval(action);
        
        }else if(command=="cgax.+"){//sumar a cgax 1 (limite 16)
        cgax+=1;
        if(cgax>=16){cgax=16;}
        
         }else if(command=="cgax.-"){//restar a cgax 1 (limite 16)
        cgax-=1;
        if(cgax<=1){cgax=1;}
        
        }else if(command=="cgay.+"){//sumar a cgay 1 (limite 16)
        cgay+=1;
        if(cgay>=16){cgay=16;}
        
        }else if(command=="cgay.-"){//restar a cgay 1 (limite 16)
        cgay-=1;
        if(cgay<=1){cgay=1;}
        
        }else if(command=="cgat.set"){//poner valor en cgat
        cgat=getval(action);
        if(action==""){cgat="";}
        
        }else if(command=="cgav.set"){//ser valor x modo contador en el mismo valor que reg0
        cgav=(vector)getval(action);
        // fin cga grafic adapter
        } else if (command == "gtif_match") {//comando es saltar si reg0=reg1
            //if (type0 == type1) {
            debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                if (reg0 == reg1){
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;
                //}
            }}
        } else if (command == "gtif_key") {//comando es saltar si reg0=in_bus
            if (type0 == "str") {
            debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                if (reg0 == cache_inbus){
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;
                }
            }}    

} else if (command == "gtif0") {//comando es saltar si reg0 true
           if (type0 == "str") {
            if (reg0 == "0"||reg0 == "false"){
                debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                }else if(reg0 == "1"||reg0 == "true"){
debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;}
                //jump next;
}
            
  }else if(type0 == "int")
            if ((integer)reg0 == 0){
                debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                }else if((integer)reg0 ==1){
debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;}
                //jump next;
}
            }

        } else if (command == "gtif_less") {//comando es saltar si reg0<reg1
           if (type0 == "str" || type1 == "str") {
                err(i,  "No se pueden comparar strings.");
            }
            if ((float)reg0 < (float)reg1){
                debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;
                //jump next;
                }
            }
            } else if (command == "gtif_max") {//comando es saltar si reg0>reg1
           if (type0 == "str" || type1 == "str") {
                err(i,  "No se pueden comparar strings.");
            }
            if ((float)reg0 > (float)reg1){
                debugmsg("GTIF::"+command+"::"+(string)action+"::linea="+(string)i);
                integer pose=llListFindList(memory,["@ "+action]);
                if (pose!=-1){
                i = (integer)pose - 1;
                //jump next;
                }
            }
            }else if (command == "hardmem"){
            reg2=(string)llGetFreeMemory( );
            type2="str";
            
            }else if (command == "relasemem"){
            memory=llDeleteSubList(memory,(integer)getval(action),llGetListLength(memory));
            
            }else if (command == "concat.cls"){
                concat=[];
            }else if (command == "concat.add"){
                concat+=getval(action);
            }else if (command == "concat.dump"){
                reg2=(string)concat;
            }else if (command == "concat.dumpf"){
                reg2=llDumpList2String(concat,getval(action));
            }else if (command == "concat.csv"){
                reg2=llList2CSV(concat);
            }else if (command == "concat.ssv"){
                reg2=llDumpList2String(concat," ");
            }else if (command == "concat.get"){
                reg2=llList2String(concat,(integer)getval(action));
            }else if (command == "concat.parsecsv") {//parsear reg0 como csv (valores separados por coma) y guardarlo como parametros multiples
                concat=llCSV2List(getval(action));
                debugmsg("PARSER::CSV "+(string)getval(reg0)+"");
                
            }else if (command == "concat.parsessv") {//parsear reg0 como csv (valores separados por coma) y guardarlo como parametros multiples
                concat=llParseString2List(getval(action),[" "],["#"]);
                debugmsg("PARSER::SSV "+(string)getval(reg0)+"");
                
            }else if (command == "concat.parse") {//parsear reg0 como reg0 y guardarlo como parametros multiples
                concat=llParseString2List(getval(action),[getval(reg0)],["#"]);
                debugmsg("PARSER::CUSTOM "+(string)getval(reg0)+"");
                
        }else if(command=="sleep"){
        llSleep((integer)action);
        } else {
            err(i, "ERROR de sintaxis, not found [ " + command + " ]");
        }
        @next;
}

cleargmem(){//vaciar memoria grafica
    gmemory=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
    cgax=1;
    cgay=1; 
    cgav=<1,1,1> ;      
}
clearrefs(){//vaciar tabla de referencias
    refs=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""];//inicio 64 CAMPOS  
}

addtomem(list inputlista){  
            memory+="// $_libreria_$";
            memory+=inputlista;
}

setflags(list flagas){//sobreescribir flags
integer e=0;
internall=[];
integer maxe=llGetListLength(flagas);
string vala;
internall+=llList2String(flagas,0);
@more;
e+=1;
vala=getval(llList2String(flagas,e));
internall+=vala;
if(e<maxe){jump more;}
flags=internall;}

clearpilret(){pilret=[];}//vaciar pilret de regreso

addpilret(integer val){//añadir a la pila de regreso
    pilret+=(string)val;
}
integer getpilret(){//leer la pila de regreso
    string rete;
    integer length = llGetListLength(pilret);
    rete=llList2String(pilret,length-1);
    return (integer)rete;
}
rempilret(){//quitar de la pila de regreso
    integer plast=llGetListLength(pilret);
    internall=[];
    if(plast>=0){
        internall=llDeleteSubList(pilret, plast-1, plast-1);
        pilret=internall;
    }
}

setpix(){
    internall=[];
    internall+=cgax;           //posicion x
    internall+=cgay;           //posicion y
    internall+=cgav.x;         //color R
    internall+=cgav.y;         //color G
    internall+=cgav.z;         //color B
    internall+=1;              //alpha (deshabilitado)
    internall+=" ";            //textura(deshabilitado)
    internall+="%";            //null
    setpixgmem(internall);
}

sendpix(){
    internall=[];
    string pixarray;
    internall+=cgax;           //posicion x
    internall+=cgay;           //posicion y
    internall+=cgav.x;         //color R
    internall+=cgav.y;         //color G
    internall+=cgav.z;         //color B
    internall+=1;              //alpha (deshabilitado)
    internall+=cgat;            //textura(deshabilitado)
    internall+="%";            //null  

    pixarray=llList2CSV(internall);
    llMessageLinked(LINK_SET,cga_dbus,pixarray,"");
}

setpixgmem(list tmplist){
        string tmpx=llList2String(tmplist, 0);
        integer mempos; 
        integer ini;
        integer fini;
        
        mempos=(integer)tmpx;
        ini=(mempos*8)-8;
        fini=ini+8;
        gmemory=llListReplaceList(gmemory,tmplist,ini,fini);

 
default {

    state_entry() {
        clearrefs();
        cleargmem();
        debugmsg("TRONASSEMBLER ALPHA metamachines ");
        inv_max_prog=llGetInventoryNumber(INVENTORY_NOTECARD);
        bios_name=llGetObjectDesc();
    }
    timer() {state run;}
    link_message(integer sender_num, integer num, string str, key id) {
        //se dispara al mandar un mensaje de tipo llMessageLinked, (ver datos)
        string combus=str;
        integer valbus=num;
        tronchip(combus,valbus);//llamamos a la función tronchip
    }
        changed(integer a) { 
        if (a & CHANGED_INVENTORY) {llResetScript();}}
    }
 
state run {
    state_entry() {
        i = 0;
        llSetTimerEvent(clock);
    }
    link_message(integer sender_num, integer num, string str, key id) {
          //se dispara al mandar un mensaje de tipo llMessageLinked, (ver datos)
          string combus=str;
          integer valbus=num;
          tronchip(combus,valbus);//llamamos a la función tronchip
    }
   // changed(integer a) {
    //    if (a & CHANGED_INVENTORY) {llResetScript();}}
    timer() {
        over=clock_mult;
        @initimer;
        if (i >= lastProgLine) {
            //llResetScript();
        }
        string l = llList2String(memory, i);
        string command;
        string action;
        if (llSubStringIndex(l, " ") != -1) {
            list line = [llGetSubString(l, 0, llSubStringIndex(l, " ")-1), llGetSubString(l, llSubStringIndex(l, " ")+1, -1)];
            command = llList2String(line, 0);
            action = llList2String(line, 1);
        } else {
            command = l;
        }
        if(run){
        interpret(command,action );
        }
        i++;
        over-=1;
        if (over>0){
        jump initimer;
        } }
        
    listen(integer i, string n, key id, string m) {
        llListenRemove(lstn);
        type2 = "str";
        reg2 = m;
        llSetTimerEvent(clock);
    }
}