edivc/ediv/src/stub/inte.c

450 lines
9.3 KiB
C

/*
* eDiv Compiler
* Copyleft (C) 2000-2002 Sion Entertainment
* http://www.sion-e.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Este fichero contien el codigo del interprete del eDiv
* by Riseven
*
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>
#include "extern.h"
#include "edivfont.h"
#include "kernel.h"
#include "inte.h"
#include "main.h"
#include "dll.h"
#include "varindex.h"
int first_loaded ;
int ini_interprete()
{
int i ;
first_loaded = 1 ;
pila_max = 1024 ;
if ((pila=(int*)malloc(4*pila_max))==NULL)
critical_error(4); // no se pudo reservar memoria para la pila
sp = 0 ; //por si acaso
// Posicion de inicio del code
iloc=mem[2]; // Inicio de la imagen de las variables locales
iloc_len=mem[6]+mem[5]; // Longitud de las locales (p£blicas y privadas)
iloc_pub_len=mem[6]; // Longitud de las variables locales p£blicas
inicio_privadas=iloc_pub_len;
imem=mem[1]; // Principio del codigo
/*
for ( i = 0 ; i < 10 ; i++ )
printf( " : %i \n" , mem[i] ) ;
*/
procs_s[1].imem = imem ;
procs_s[1].tipo = 0 ;
lista_mete( 1 ) ;
// Preparamos la estructura de parametros
fp.Call_Entrypoint = Call_Entrypoint ;
fp.mem = mem ;
fp.pila = pila ;
fp.procs_s = &procs_s ;
fp.sp = &sp ;
fp.varindex = varindex ;
fp.num_procs = &num_proc_orden ;
fp.proc_orden = proc_orden ;
fp.proceso_actual = &proceso_actual ;
fp.existe.regions = 0 ;
fp.existe.dibuja = 0 ;
fp.Runtime_Error=error;
fp.Critical_Error=critical_error;
fp.GetVarOffset=GetVarOffset;
return 1 ;
}
int busca_proc_libre()
{
int i ;
for ( i = 1 ; i < 4096 ; i++ )
{
if ( procs_s[i].tipo == 0 )
return i ;
}
return -1 ;
}
int lista_mete( int num )
{
// Esto esta mal, habra que buscar su posicion segun priority
procs_s[num].orden = num_proc_orden ;
proc_orden[ num_proc_orden++ ] = num ;
return num_proc_orden-1 ;
}
int lista_quita( int num )
{
int i ;
for ( i = procs_s[num].orden+1 ; i < num_proc_orden ; i++ )
{
procs_s[ proc_orden[ i ] ].orden-- ;
proc_orden[ i - 1 ] = proc_orden[ i ] ;
}
num_proc_orden-- ;
return 1 ;
}
int interprete()
{
int i ;
// PROVISIONAL. Se tendra que cambiar para k soporte frame(int) y prioritys
if ( num_proc_orden > 0 )
{
for ( proceso_actual = 0 ; proceso_actual < num_proc_orden ; proceso_actual++ )
{
proceso( proc_orden[ proceso_actual ] ) ;
}
Call_Entrypoint(EDIV_frame);
}else
{
stub_quit() ;
}
return 1 ;
}
int proceso( int num )
{
int v1 ;
int retcode = 0;
int no_devuelve = 0 ;
int (*externa)(struct _fun_params*);
int temp ;
num_proc = num ;
imem = procs_s[num_proc].imem ;
//assert(0);
while( retcode == 0 )
{
//printf("imem: %i\tnum_proc: %i\tsp: %i\tpila[sp]: %i \n" , imem , num_proc , sp , pila[sp]) ;
switch ( mem[ imem++ ] )
{
case lnop://0
break;
case lcar://1
pila[++sp]=mem[imem++] ;
break;
case lasi://2
mem[ pila[sp-1] ] = pila[sp--] ;
//printf("Cargado %i en %i\n" , pila[sp+1], pila[sp] ) ;
break ;
case lori://3
pila[sp-1]|=pila[sp];
sp--;
break;
case lxor://4
pila[sp-1]^=pila[sp];
sp--;
break;
case land://5
pila[sp-1]&=pila[sp];
sp--;
break;
case ligu://6
pila[sp-1] = ( pila[sp-1] == pila[sp] ) ;
sp--;
break;
case ldis://7
pila[sp-1] = ( pila[sp-1] != pila[sp] ) ;
sp--;
break;
case lmay://8
pila[sp-1] = ( pila[sp-1] > pila[sp] ) ;
sp--;
break;
case lmen://9
pila[sp-1] = ( pila[sp-1] < pila[sp] ) ;
sp--;
break;
case lmei://10
pila[sp-1] = ( pila[sp-1] <= pila[sp] ) ;
sp--;
break;
case lmai://11
pila[sp-1] = ( pila[sp-1] >= pila[sp] ) ;
sp--;
break;
case ladd://12
pila[sp-1] += pila[sp] ;
sp--;
break;
case lsub://13
pila[sp-1] -= pila[sp] ;
sp--;
break;
case lmul://14
pila[sp-1] *= pila[sp] ;
sp--;
break;
case ldiv://15
if(pila[sp]==0) error(145); // división entre cero
pila[sp-1] /= pila[sp] ;
sp--;
break;
case lmod://16
if(pila[sp]==0) error(145); // división entre cero
pila[sp-1] %= pila[sp] ;
sp--;
break;
case lneg://17
pila[sp] = -pila[sp] ;
break ;
case lptr://18
pila[sp] = mem[ pila[sp] ] ;
break ;
case lnot://19
pila[sp]^=-1;
break ;
case laid://20
pila[sp]+= procs_s[num_proc].id ;
break ;
case lcid://21
pila[++sp] = procs_s[num_proc].id ;
break ;
case lrng://22
imem++;
break ;
case ljmp://23
imem = mem[ imem ] ;
//printf("Nueva posicion: %i\n", imem ) ;
break ;
case ljpf://24
if (!(pila[sp]&1))
imem = mem[ imem ] ;
sp--;
break ;
case lfun://25 NO USADO
break ;
case lcal://26
assert(num_proc_orden<153);
devolver++ ;
v1 = busca_proc_libre() ;
procs_s[v1].imem = mem[imem++] ;
temp = proceso_actual ;
proceso_actual = lista_mete(v1) ;
procs_s[num_proc].imem = imem ;
proceso(v1) ;
proceso_actual = temp ;
num_proc = num ;
imem = procs_s[num_proc].imem ;
break ;
case lret://27
lista_quita(num_proc) ;
//printf("Ret: %i\n" , num_proc) ;
retcode = 1 ;
break ;
case lasp://28
sp--;
break;
case lfrm://29
procs_s[num_proc].imem = imem ;
if ( first_loaded )
{
Call_Entrypoint(EDIV_first_load);
first_loaded = 0 ;
}
//printf("Frame en: %i\n" , imem ) ;
retcode = 1 ;
break ;
case lcbp://30
reserved("parameters",procs_s[num_proc].id)=mem[imem++];
reserved("param_offset",procs_s[num_proc].id)=sp-reserved("parameters",procs_s[num_proc].id)+1;
/**/procs_s[num_proc].num_params = mem[ imem-1 ] ;
break;
case lcpa://31 POR HACER #-#
mem[pila[sp--]]=pila[reserved("param_offset",procs_s[num_proc].id)++];
break;
case ltyp://32
procs_s[num_proc].id = mem[2] + ( num_proc * iloc_len ) ;
if ( procs_s[num_proc].tipo != 0 )
critical_error(3); // redefinición del tipo de proceso
procs_s[num_proc].tipo = mem[ imem++ ] ;
reserved("process_type",procs_s[num_proc].id) = procs_s[num_proc].tipo ;
inicio_privadas=mem[6];
break ;
case lpri://33 POR HACER
memcpy(&mem[procs_s[num_proc].id+inicio_privadas],&mem[imem+1],(mem[imem]-imem-1)<<2);
inicio_privadas+=(mem[imem]-imem-1); imem=mem[imem];
break ;
case lcse://34
if ( pila[sp-1] == pila[sp] )
imem++;
else
imem=mem[imem];
sp--;
break ;
case lcsr://35
if ( pila[sp-2] >= pila[sp-1] && pila[sp-2] <= pila[sp] )
imem++ ;
else
imem = mem[imem];
sp-=2;
break ;
case lshr://36
pila[sp-1] >>= pila[sp] ;
sp-- ;
break ;
case lshl://37
pila[sp-1] <<= pila[sp] ;
sp-- ;
break ;
case lipt://38
pila[sp] = ++mem[ pila[sp] ] ;
break ;
case lpti://39 COMPORTAMIENTO EXTRAÑO SI SE PONE EN UNA LINEA
mem[ pila[sp] ]++;
pila[sp] = mem[ pila[sp] ]-1 ;
break ;
case ldpt://40
pila[sp] = --mem[ pila[sp] ] ;
break ;
case lptd://41 COMPORTAMIENTO EXTRAÑO SI SE PONE EN UNA LINEA
mem[ pila[sp] ]--;
pila[sp] = mem[ pila[sp] ]+1 ;
break ;
case lada://42
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] += pila[sp] ;
sp--;
break;
case lsua://43
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] -= pila[sp] ;
sp--;
break;
case lmua://44
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] *= pila[sp] ;
sp--;
break;
case ldia://45
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] /= pila[sp] ;
sp--;
break;
case lmoa://46
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] %= pila[sp] ;
sp--;
break;
case lana://47
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] &= pila[sp] ;
sp--;
break;
case lora://48
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] |= pila[sp] ;
sp--;
break;
case lxoa://49
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] ^= pila[sp] ;
sp--;
break;
case lsra://50
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] >>= pila[sp] ;
sp--;
break;
case lsla://51
pila[ sp-1 ] = mem[ pila[ sp-1 ] ] <<= pila[sp] ;
sp--;
break;
case lpar://52 POR HACER
//imem++;
inicio_privadas+=mem[imem++];
break;
case lrtf://53
lista_quita(num_proc) ;
no_devuelve = 1 ;
//printf("Return: %i\n" , num_proc) ;
retcode = 1 ;
break ;
case lclo://54 POR HACER
break ;
case lfrf://55 POR HACER
sp--;
break ;
case limp://56
carga_dll((char*)&mem[mem[imem++]]);
break ;
case lext://57
//assert(0);
externa=extfuncs[mem[imem++]];
// corresponder con FUNCTION_PARAMS
//temp = externa(pila,&sp,mem,varindex,&procs_s,Call_Entrypoint);
temp = externa(&fp) ;
pila[++sp]= temp ;
break ;
case ldbg://58
#ifdef DBG
//Call_Entrypoint(EDIV_debug,imem,nombreprg,lin,0);
#endif
break ;
}
#ifdef DBG
//Call_Entrypoint(EDIV_trace,imem,nombreprg,lin,0);
#endif
}
if ( devolver > 0 && no_devuelve == 0 )
{
pila[++sp] = 0 ;// AQUI SE DEBERA DEVOLVER EL ID
devolver-- ;
}
Call_Entrypoint(EDIV_post_process);
return 1 ;
}