// C Source File
// Created 11/01/2004; 17:26:31

#define USE_TI89              // Compile for TI-89
#define USE_TI92PLUS          // Compile for TI-92 Plus
#define USE_V200              // Compile for V200

// #define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization

#define MIN_AMS 200           // Compile for AMS 1.01 or higher

//#define SAVE_SCREEN           // Save/Restore LCD Contents

#include <tigcclib.h>         // Include All Header Files

#include "Qbasic_asmheader.h"


//#include "preproc.h"

#define getuc ((*(fonc[*(argptr)]))()).uc
#define getui ((*(fonc[*(argptr)]))()).ui
#define getul ((*(fonc[*(argptr)]))()).ul
#define getsc ((*(fonc[*(argptr)]))()).sc
#define getsi ((*(fonc[*(argptr)]))()).si
#define getsl ((*(fonc[*(argptr)]))()).sl
#define getpuc ((*(fonc[*(argptr)]))()).puc
#define getpui ((*(fonc[*(argptr)]))()).pui
#define getpul ((*(fonc[*(argptr)]))()).pul
#define getpsc ((*(fonc[*(argptr)]))()).psc
#define getpsi ((*(fonc[*(argptr)]))()).psi
#define getpsl ((*(fonc[*(argptr)]))()).psl
#define geth		((*(fonc[*(argptr)]))()).h
#define getpfile		((*(fonc[*(argptr)]))()).pfile
#define getpfiles		((*(fonc[*(argptr)]))()).pfiles
#define rul return (ans)(unsigned long)
#define rsl return (ans)(signed long)
#define rui return (ans)(unsigned int)
#define rsi return (ans)(signed int)
#define ruc return (ans)(unsigned char)
#define rsc return (ans)(signed char)
#define rpul return (ans)(unsigned long*)
#define rpsl return (ans)(signed long*)
#define rpui return (ans)(unsigned int*)
#define rpsi return (ans)(signed int*)
#define rpuc return (ans)(unsigned char*)
#define rpsc return (ans)(signed char*)
#define resi return (ans)(ESI)
#define rh return (ans)(h)
#define rpfile return (ans)(FILE*)
#define rpfiles return (ans)(Files*)
//#define rpans return (ans)(ans*)

#define PASS_BLOCK argptr=argyblock[*(argptr+2)]	//permet de passer un block x y quand on pointe sur le x

#define NB_FOR 100		//be sure to have the same value in the compilator
#define NB_WHILE 30		//be sure to have the same value in the compilator

INT_HANDLER OldInt5 = NULL;
INT_HANDLER save_int_1,save_int_5;
WINDOW wind;

volatile int Counter = 0;

unsigned int srcsize,nintr,sintr,iintr,byte_width_ilist[256],iiii;
unsigned char *srcptr,/**ptr,*/int5_allowed,sv_scr_on,*screen_buffer,nbvar_main,*GLOBAL_data,disp_err,disp_err_old;
long /*rtnf[255],*/argin[200]; //retour des fonctions inlines : imbrication max de 200 appels . Entrée fonction inline
unsigned char /*i_rtnf,*/i_intr,varnfor[50],user_func_nb_arg[256];
unsigned long inc,speedintr[21],rtn_value;



//ESI argptr,argdep,tmpesi,argintr[21],intrdeb,argfunc[255],argendfunc[255],arglbl[256],argwhile[NB_WHILE],argendwhile[NB_WHILE],argfor[NB_FOR],argendfor[NB_FOR],argelse[257],argendif[257],argyblock[50];
ESI argptr,argdep,tmpesi,argintr[21],intrdeb,*argfunc/*[255]*/,*argendfunc/*[255]*/,*arglbl/*[256]*/,argwhile[NB_WHILE],argendwhile[NB_WHILE],*argfor/*[NB_FOR]*/,*argendfor/*[NB_FOR]*/,*argelse/*[257]*/,*argendif/*[257]*/,argyblock[50];

/* Tous non pas été mis sous cette forme pour le moment. Cela permet d'économiser de la place sur le stack (limité à 16ko).
	argendif=GLOBAL_data+0;		//260
	argelse=GLOBAL_data+260*4*1;		//260
	arglbl=GLOBAL_data+260*4*2;		//260
	argfunc=GLOBAL_data+260*4*3;		//260
	argendfunc=GLOBAL_data+260*4*4;		//260
	
	argendfor=GLOBAL_data+260*4*5;	//NB_FOR
	argfor=GLOBAL_data+260*4*5+4*NB_FOR*1;	//NB_FOR
*/

	



void *kbq;		//For the function gkey()

unsigned int sprt2_return[2];



typedef struct 
{
	unsigned char f_name[20];		//is usefull just for opening an existing file (in aim to replace it later)
	unsigned char *fptr;		//pointer that is used just for closening the file
	unsigned char *cptr;		//pointer on the first byte of the used memory block
	unsigned int i;		//index : position on the file for loading
  unsigned char iw;		//index position for writing
	unsigned short plen;		//length in byte of the memory blok of the file ; plen=*(unsigned int*)fptr
	unsigned char *last_byte;	//Points to the ESI = fptr+plen+1;
  HANDLE h;				//handle à déreférencer si il y a eu compression du Heap (HeapDeref) pour obtenir fptr
  unsigned char oc;	//if oc=1 so the filed has been open with OpenFile, if oc=0 so the file has been created with CreateFile_Files	; Made by me
  unsigned char ftype;	// =*(last_byte) c'est la valeur décimale du type du fichier (ESI) STR_TAG etc	; made by me
  unsigned char is_archived; //=1 if archived else 0
  unsigned char is_modified;	//=1 if the user has used writing functions like fputc, =0 if not
} Files ;

void print_Files(Files *f)
{
	printf("fptr=%ld\n cptr=%ld\nindex=%d\n plen=%d\n last_byte=%ld\n Handle=%ld\n",f->fptr,f->cptr,f->i,f->plen,f->last_byte,f->h);
	printf("oc=%x\n ftype=%x",f->oc,f->ftype); ngetchx();
}
							//0				1					2					3					4					5					6					7					8					9

unsigned char
 *foncs[]={		""		,"GUCHAR"	,	"GSLVAR",		""		,		"FLBL",	"FGOTO"	,"keywait",		"isz"	,		"dsz"	,		"iff"	, //0
						"freeh"	,	"basich",	"exech"	,		""		,	"INDIR"	,"printf1","printf2","newline","prints",	"elsee"	, //1
					"svscroff","fedwhil",	"finish",	"when"	,"strlen"	,	"printc","sprintf",	"char"	,	"strcat","atol"		, //2
					"execnpp"	,"GUINT"	,	"GINT"	,	"gsprt8","gsprt16","printld","printxy",	"GLONG"	,"GULONG"	,	"inter"	, //3
						"dline"	,"dmline"	,	"gmode"	,"sprt8"	,"sprt16"	,		""		,	"ord"		,"sprt82"	,"sprt162","sprt322", //4
						"setlcd",	"dpix"	,"gpix"		,"sprt32","fillrect","clrlcd"	,"keytest","keyclear","keydisp","ifthen", //5
						"getlcd",	"fwhile",		"off"	,"gsprt32","realloc","isover16","strcat2","next"	,	"break" ,	"elsee"	, //6
					"grayon"	,"grayoff","light"	,	"dark"	,		""		,"drawstr","setfont","freet"	,"settimer","endiff", //7
					"gotopos"	,	"pos"		,		"jsr" ,	"rts"		,"pause"	,"unsigb"	,	"unsigw","timerexp","timerval",	""		, //8
					"lscroll"	,"rscroll","uscroll","bscroll",		"lrol",	"rrol"	,		""		,  "idle" ,	"memcpy",		""		, //9
						"clrscr",	"rand"	,	"gsprt"	,"lscroll2","rscroll2","uscroll2","bscroll2",""		,"memmove",		""		, //10
					"fopen"		,		""		,	"fcreate",	""		,	"files"	,		"reps",		""		,	"gets"	,		""		,		""		, //11
							"nott",		"orb"	,		"neg"	,	"notb"	,"dcircle","fillcirc",	""		,		""		,		"sto"	,		""		, //12
							"xorr",		"orl"	,		"andl",		"inf"	,	"infeq"	,		"eq"	,	"supeq"	,	"sup"		,	"noteq"	,		"add", //13
							""		,		"sub"	,	"andb"	,		"mul"	,		""		,		"div"	,		"eqs"	,	"esc"		,		"up"	,	"second", //14
							"def"	,	"enddef",		""		,		"fc"	,"sprt8x"	,		"rtn"	,	"group"	,		""		,		"down",	"shiftt", //15
						"repeat",		""		,"savescr","loadscr",	"mod"		,		"lb"	,		"lw"	,		"ll"	,	"leftt"	,"diamond", //16
						"moveto",	"os"		,		"toos",	"newstr","gsprt8x",		"wb"	,		"ww"	,		"wl"	,	"rightt",	"alpha"	, //17
						"strcmp","strcpy"	,	"gkey","keydelay"	,"keyspeed","FFORR"	,"ENDFFOR",		""		,		""		,		""		, //18
					"pokeb"		,	"pokew"	,	"pokel"	,"lscroll4","archi","unarchi"	,	"i"			,		"b"		,		"w"		,		"l"		, //19
					"peekb"		,	"peekw"	,	"peekl"	,"isarchi","loadasm",		""		,		"x"		,		"y"		,		""		,		""		, //20
					"newstr"	,		"expr",	"string",		""		,"execasm",		""		,"nilist"	,	"mklist",		""		,		""		, //21
							"map"	,	"multi"	,		"two"	,		""		,"closeasm",	""		,"catalog",	"open"	,		""		,"ENDTAG"	, //22
							""		,		""		,"settype",	"finish",	"seqb"	,	"lcdup"	,"lcddown","drawpic","getpic"	,		""		, //23
					"debugon"	,"debugoff",	"seqs",	"seqe"	,	"seqw"	,"prettyxy","getwbt",	"cwidth",		""		,		""		, //24
							"nop"	,	"malloc",		"free","memset"	,	"seql" 	,"asmcall",	"enddef",		""		,		""		,	"enddef"}; //25



typedef union 
  {
    unsigned char uc;
    unsigned int ui;
    unsigned long ul;
    signed char sc;
    signed int si;
    signed long sl;
    unsigned char *puc;
    unsigned int *pui;
    unsigned long *pul;
    signed char *psc;
    signed int *psi;
    signed long *psl;
    HANDLE h;
    ESI esi;
    FILE *pfile;
    Files *pfiles;
    //ans *pans;
  } ans;


typedef struct 
{
	char *fptr, *cptr;
	unsigned short plen;
  HANDLE h;
} File ;

SCR_RECT scr_rect;
char gmode/*,gmode2*/,nswitch;		//gmode = mode graphique & or xor pour fonction sprt8,16,32 ; gmode2 pour les autres
char strchars[2];
void *lcdad;
ans /*varlist[256],*/*varlist,varlist_array[256];
long var_user_func_backup[200];
unsigned char var_user_func_varnum_backup[200],nsubfonc;
unsigned int i_var_user_func_backup;
ESI lbl[256];
ESI subfonc[255];
ans (*fonc[])(void);
long *scr_copy[4];
index_in_c_str=0;
unsigned char *ptr_execbas; //init_bkm
unsigned int dim_max;	//init_bkm

unsigned char mod_uchar(unsigned char a, unsigned char b)
{
	if(b==0) return a;
	else return a%b;
}

DEFINE_INT_HANDLER(MyInt5)
{
  unsigned char i;
  unsigned long tempp;
  inc++;
  //printf(" inc=%d",inc);
  intrdeb=argptr;
	for(i=0;i<20;i++)
	{
		
		tempp=speedintr[i];
		if(speedintr[i]==0) tempp=inc;
		else tempp=(inc%tempp);
		
		if(/*(inc%tempp)==0 && tempp!=0*//*tempp==0*/!tempp && speedintr[i])
		{
			//printf("speed=%ld inc=%ld\n",speedintr[i],inc);
			argptr=argintr[i]; //on pointe maintenant sur le tag de la nilist a exécuter
			if(*argptr==216)		//nilist {}
			{
				//printf(" inc=%d",inc);
				argptr++;
				sintr=getsl;
				nintr=getsl;
				for(iintr=0;iintr<nintr;iintr++)	//Exécute les instructions de l'interruption (de la nilist)
				{
					(*(fonc[*(argptr)]))();
					//getsl;
				}
			}
			else		//x:y execute the block
			{
				(*(fonc[*(argptr)]))();
			}
			
		}
	}

  argptr=intrdeb;
  ExecuteHandler (OldInt5);
  
}

char *ptr;
HANDLE handle, handle_execbas;

CALLBACK void Handler(EVENT *ev)
{
  if (ev->Type == CM_STRING)
    ptr = ev->extra.pasteText;
  else if (ev->Type == CM_HSTRING)
    handle = ev->extra.hPasteText;
  ER_throw (1);
}
ans finish(void)
{
	int ii;
	SetIntVec (AUTO_INT_5, OldInt5);
	OSInitKeyInitDelay(336);
	OSInitBetweenKeyDelay (48);
	if(sv_scr_on==1) {memcpy (LCD_MEM, screen_buffer, LCD_SIZE); free(screen_buffer);}
	if(GLOBAL_data) free(GLOBAL_data);
	for(ii=0;ii<4;ii++)			//free the saved screen
	{
		if(scr_copy[ii]!=NULL) free(scr_copy[ii]);
	}
	if(argdep) free(argdep);
	if(handle_execbas) HeapFree (handle_execbas);
	WinClose (&wind);	//for prettyxy function
	exit(4);
}
void exec_none_stop_secured(void)	//fonction avoiding to exiting from the prgm
{
	unsigned char *arg_enddd;
	arg_enddd=argdep+srcsize;
	while(argptr<arg_enddd)
	{
		(*(fonc[*(argptr)]))();
	}
//	printf("Avant finish()"); ngetchx();
	finish();
}
/*
void exec_none_stop(void)
{
	//Before : while(*argptr!=0xE9)
	while(1)
	{
		(*(fonc[*(argptr)]))();
		(*(fonc[*(argptr)]))();
		(*(fonc[*(argptr)]))();
		
		(*(fonc[*(argptr)]))();
	}
}*/
unsigned char *memcpy2(unsigned char *destt,unsigned char *srcc,unsigned long lenn)	//n'est plus rapide que sur Ti ému mais pas en réalité sur une calculatrice :bug de Tiému
{
	unsigned char quotient;
	if((quotient=((lenn-1)/384)))		//Is lenn>=385 ?
	{
		if((!((unsigned long)(srcc)%2) && (!((unsigned long)(destt)%2))))  //Are they both even address ?
		{	//Yes
			Fastmemcpy(srcc,destt,quotient-1);		//Fast copy assembly routine
			if(lenn%2) *(destt+lenn-1)=*(srcc+lenn-1);
			return destt;
		}
		//printf("Here memcpy"); ngetchx();
	}
	return memcpy(destt,srcc,lenn);

}

void msgg(char *str)
{
	printf(str); ngetchx();
}
void skip_str(void)	//argptr doit pointé sur le prem char de la string
{
	while(*(argptr)!=0) argptr++;
	argptr++;
}
ESI foundarg(unsigned char val)
{
	ESI argptrori,argptrf;;
	argptrori=argptr;
	while(*argptr!=val)
	{
		if(*argptr==0xE9) { return NULL; }
		skip_arg();
		/*if(*argptr==STR_TAG) skip_str();
		else 
		{
			if(*argptr==1 || *argptr==POSINT_TAG || *argptr==NEGINT_TAG || *argptr==IM_TAG || *argptr==2) getsl;
			else
			{
				if(*argptr==0xE9) { argptr=argptrori; return argptrori; }
				argptr++;
			}
		}*/
	}
	argptrf=argptr;
	argptr=argptrori;
	return argptrf;
}
ans gstr(void)
{
	unsigned int dim;
	unsigned char *p;
	argptr++;
	dim=getul;
	p=argptr;
	argptr+=dim+1;
	rpuc(p);
}
void skip_arg(void)
{
	if(*argptr==STR_TAG) /*skip_str();*/ gstr();
		else 
		{
			if(*argptr==1 || *argptr==POSINT_TAG || *argptr==NEGINT_TAG || *argptr==IM_TAG || *argptr==2) getsl;
			else
			{
				if(*argptr==0xE9) { return; }
				argptr++;
			}
		}
}
void init_bkm(void)
{
	ESI argptrori;
	char has_worked;	//Cette variable permet d'éviter de passer une fonction avec skip_arg si l'on vient de repérer une fonction inclue dans le switch
	int cmd,var,i;
	unsigned int nbelemm,dim;
	for(i=0;i<=256;i++) argelse[i]=NULL;	//Initialise les else (utile car ils ne sont pas obligatoires)
	dim_max=0;
	handle_execbas=H_NULL;
	argptrori=argptr;
	cmd=*argptr;
	while(cmd!=0xE9)
	{
		has_worked=0;
		switch(cmd)
		{
			case OTH_TAG:	//basic endbasic execbas()
			argptr++;
			dim=((*argptr)*256+*(argptr+1));
			if(dim>dim_max) dim_max=dim;	//pour créér l'handle pour les basic:endbasic, il ne sera pas recréér à chaque instruction Tibasic, on gagnera ainsi en vitesse d'exécution
			argptr+=dim;
			has_worked=1;
			break;
			case 11:	//basich() endbasic
			argptr+=2;
			dim=((*argptr)*256+*(argptr+1));
			if(dim>dim_max) dim_max=dim;
			argptr+=dim;
			has_worked=1;
			break;
			case 150:		//def(func_id,nbarg)	. Keep the number of args of the user functions.
			argptr++;
			var=*(argptr+1);
			argptr+=2;	//pointe maintenant sur le nombre d'arguments
			user_func_nb_arg[var]=*(argptr+1);
			argptr+=2;	//pointe sur le premier argument (si il y a)
			argfunc[var]=argptr;
			has_worked=1;
			break;
			case 151:	//enddef
			argptr++;
			argendfunc[*(argptr+1)]=argptr+2;
			has_worked=1;
			break;
			case 196:	//i test condition, is assume to be a x y block
			case 206:	//x start block
			argptr++;
			has_worked=1;
			//printf("X num=%d",*(argptr+1));
			break;
			case 207:	//y end block
			argptr++;
			var=*(argptr+1);
			//printf("Y num=%d",var);
			argptr+=2;
			argyblock[var]=argptr;	//pointe juste après la fonction y et son identifiant
			has_worked=1;
			break;
			case 24:			//LOOP
			argptr++;
			has_worked=1;
			/*var=*(argptr+1);
			argloop[var]=argptr+2;*/
			break;
			case 34:			//ENDLOOP
			argptr++;
			has_worked=1;
			break;
			case 0x04:	//label
			argptr++;
			//printf("LBL num=%d",*(argptr+1)); ngetchx();
			var=*(argptr+1);
			arglbl[var]=argptr+2;
			has_worked=1;
			break;
			case 0x3D:	//while
			argptr++;
			var=*(argptr+1);
			argwhile[var]=argptr-1;	//pointe sur le début de while pour tester la condition
			has_worked=1;
			break;
			case 0x15:	//endwhile
			argptr++;
			var=*(argptr+1);
			argendwhile[var]=argptr+2;
			has_worked=1;
			break;
			case 185:	//	FOR			"for varna,strt,end,step"		En tag : 185,value_tag,identifiant_boucle,...
			argptr++;
			var=*(argptr+1);		//identifiant de la boucle
			//printf("Y num=%d",var);
			//argptr+=2;
			argptr+=2;	//passe le numéro de for
			varnfor[var]=*(argptr+1);	//enregistre la variable à faire évoluer
			//printf("Numéro de la fonction à faire évoluer %d", varnfor[var]);
			argptr+=2; //passe la variable à faire évoluée
			if(*argptr!=213 && *argptr!=165 && *argptr!=166 && *argptr!=167 && *argptr!=200 && *argptr!=201 && *argptr!=202) getsl;	//il y a un risque ici si la valeur de départ est une fonction mémoire (en écriture ou lecture si sur adresse nulle //skip_arg();	//passe la valeur de départ
			else exit2("In for : start value shall not be [],lb,lw,ll,peek");
			argfor[var]=argptr;	//pointe à la borne limite à ne pas dépasser
			//printf("pointeur valeur limite %lp",argfor[var]); ngetchx();
			has_worked=1;
			//var=*(argptr+1);   EST initialisé directement dans la fonction
			//argfor[var]=argptr-1;
			break;
			case 186:		//ENDFOR
			argptr++;
			var=*(argptr+1);
			argptr+=2;
			argendfor[var]=argptr;
			//printf("pointeur valeur limite %lp",argfor[var]); ngetchx();
			has_worked=1;
			break;
			case 0x45:	//else
			argptr++;
			var=*(argptr+1);
			has_worked=1;
			//printf("var else=%d",var);
			/*if(*(argptr+2)==0x4F && *(argptr+4)==var)	//Si il est suivi de son endif, alors on passe le endif(optimisation)
			{
				argelse[var]=argptr+5;
			}*/
			/*else*/ argelse[var]=argptr+2;
			break;
			case 0x4F:	//endif
			argptr++;
			var=*(argptr+1);
			//if(argelse[var]==NULL) argelse[var]=argptr+2-3;
			//printf("var endif=%d",var);
			if(argelse[var]==NULL) argelse[var]=argptr+2;
			argendif[var]=argptr+2;
		//	if(var==8) {printf("var=8 argptr=%ld,\nargendif[8]=%ld",argptr,argendif[var]); ngetchx();}
		//	if(var==9) {printf("var=9 argptr=%ld,\nargendif[9]=%ld",argptr,argendif[var]); ngetchx();}
			has_worked=1;
			break;
			case 89: 	//IF cond:i_true
			argptr+=2;	//passe le tag et la taille de l'instruction à sauter éventuellement
			has_worked=1;
			break;
			case 197:	//b block
			argptr++;
			var=*(argptr+1);
			//printf("\nvarn=%d\n%ld",var,var); ngetchx();
			argptr+=2;
			nbelemm=getsl;
			if(((unsigned long)argptr%2)==1) argptr++;	//in the case of an not even adress
			varlist[var].sl=argptr;
			byte_width_ilist[var]=1;
			argptr+=nbelemm*1;	//skip the y
			has_worked=1;
			break;
			case 198:		//w
			argptr++;
			var=*(argptr+1);
			argptr+=2;
			nbelemm=getsl;
			if(((unsigned long)argptr%2)==1) argptr++;	//in the case of an not even adress
			varlist[var].sl=argptr;
			byte_width_ilist[var]=2;
			argptr+=nbelemm*2;	//skip the y
			has_worked=1;
			break;
			case 199:		//l
			argptr++;
			var=*(argptr+1);
			argptr+=2;
			nbelemm=getsl;
			if(((unsigned long)argptr%2)==1) argptr++;	//in the case of an not even adress
			//printf("argptr=%ld",argptr); ngetchx();
			varlist[var].sl=argptr;
			byte_width_ilist[var]=4;
			argptr+=nbelemm*4;	//skip the y
			has_worked=1;
			break;
		}
		if(has_worked==0) skip_arg();		//ce test permet d'éviter de sauter des fonctions à repérer si elles se suivent.
		cmd=*argptr;
		//printf(" %x",cmd);
	}
	if(!(handle_execbas=HeapAllocHigh (dim_max+2+4+1))) exit2("Not enough memory");	//+4 pour le stockage du pointeur (unique) +2 pour la taille du handle +1 pour placer un 0xE9 car les instructions Tibasic devront s'arrêter avant d'avoir d'avoir atteint la fin du HANDLE, servant d'identifiant
	ptr_execbas=HeapDeref(handle_execbas); 
//	ptr_execbas=malloc(dim_max+2+4+1);
	//handle_execbas=*(unsigned int*)(ptr_execbas-2);
	//HeapLock(handle_execbas);
	*(unsigned int*)ptr_execbas=dim_max+4+1;	//inscrit la taille de l'espace mémoire - 2, pour compatibilité avec NG_execute()
  argptr=argptrori;
}	



HANDLE CreateFile (const char *FileName)
// Returns a handle, H_NULL in case of error
{
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if (!(h = HeapAlloc (HeapMax ()))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      //printf("nom non valid dan create file"); ngetchx();
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;
  return h;
}

HANDLE CreateFile_with_specified_size (const char *FileName, unsigned int size)
// Returns a handle, H_NULL in case of error
{
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if(size>HeapMax ()) return H_NULL;
  if (!(h = HeapAlloc (size))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      //printf("nom non valid dan create file"); ngetchx();
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;
  return h;
}

unsigned char* OpenFile(const char *FileName)
{
	char *fptr, *cptr;
	unsigned char *filecontent;
	unsigned short plen;
	SYM_ENTRY *SymPtr;
	HANDLE h;
	
	
	//if(!(filecontent=malloc((unsigned long)32000))) exit2("Memory error in fopen.");
	
	SymPtr = DerefSym (SymFind (SYMSTR (FileName)));
	if (!SymPtr) {return 0;}
	h = SymPtr->handle;
  if (HeapGetLock (h))
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }
	  plen = *(short*)(cptr) + 3;
		if(!(filecontent=malloc(plen))) exit2("Memory error in fopen.");
		//Malloc a pu modifier le pointeur sur le fichier, alors récupère à nouveau le pointeur sur le block mémoire
		SymPtr = DerefSym (SymFind (SYMSTR (FileName)));
		if (!SymPtr) {return 0;}
		h = SymPtr->handle;
		if (HeapGetLock (h))
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }
    memcpy(filecontent,fptr,plen);
    //if(plen<32000) memcpy(filecontent,fptr,plen);
    //else exit2("The file to open is too big");
    
    //if(!(filecontent=realloc(filecontent,(unsigned long)plen))) exit2("Can't realloc memory in fopen.");
    
    //Close the file
    if (h) HeapUnlock (h);
    return filecontent;
}

void AppendCharToFile (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h) - 10) return;
  *(unsigned short*)base = len + 1;
  base[len+2] = c;
}
unsigned char AppendCharToFile2 (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h)-10) {/*printf("AppendChartofile2 %ld",HeapSize(h)); ngetchx();*/ return 0;}
  *(unsigned short*)base = len + 1;
  base[len+1] = c;
  return 1;
}
void AppendBlockToFile (HANDLE h, void *addr, unsigned short len)
{
  unsigned short i;
  for (i = len; i; i--) {AppendCharToFile (h, *((char*)addr)++); /*printf("c=%c ",*(char*)addr);*/}
}
unsigned char AppendBlockToFile2 (HANDLE h, void *addr, unsigned short len)
{
	unsigned char rr;
  unsigned short i;
  rr=1;
  for (i = len; i; i--) {rr*=AppendCharToFile2 (h, *((char*)addr)++); /*printf("c=%c ",*(char*)addr);*/}
  return rr;	//if rr=1, ok else if rr=0 an error occured (memroy error)
}
/*
void CloseOpenedFile(Files *fileptr)
{
	if (fileptr->h) HeapUnlock (fileptr->h);
  if (fileptr->cptr != fileptr->fptr) free (fileptr->cptr);
  if(fileptr) free(fileptr);
}
*/

void CloseFile (HANDLE h)
{
  AppendCharToFile (h,0); AppendCharToFile (h,0x2D);
  HeapUnlock (h);
  HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
}

void CloseFile_type (HANDLE h,int type)
{
  //if(type==STR_TAG) AppendCharToFile (h,0);

  AppendCharToFile (h,type);
  if(h) HeapUnlock (h);
  if(h) HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
}

void AppendStrToFile (HANDLE handle, void *str)
{
	AppendBlockToFile (handle, str, strlen(str));
}

ans guchar(void)
{
	argptr+=2;
	rul(*(argptr-1));
	//return (ans)(*(argptr-1));
}
ans gchar(void)
{
	argptr+=2;
	rsl(*(argptr-1));
	//return (ans)(*(argptr-1));
}
ans guint(void)
{
	unsigned int ui;
	unsigned char *p;
	p=&ui;
	*p=*(argptr+1); *(p+1)=*(argptr+2);
	argptr+=3;
	rul(ui);
}
ans gint(void)
{
	int vi;
	unsigned char *p;
	p=&vi;
	*p=*(argptr+1); *(p+1)=*(argptr+2);
	argptr+=3;
	rsl(vi);
}
ans gulong(void)
{
	unsigned long ul;
	unsigned char *p;
	p=&ul;
	*p=*(argptr+1); *(p+1)=*(argptr+2); *(p+2)=*(argptr+3); *(p+3)=*(argptr+4);
	argptr+=5;
	rul(ul);
	//return (ans)(ul);
}
ans glong(void)
{
	signed long ul;
	unsigned char *p;
	p=&ul;
	*p=*(argptr+1); *(p+1)=*(argptr+2); *(p+2)=*(argptr+3); *(p+3)=*(argptr+4);
	argptr+=5;
	rsl(ul);
	//return (ans)(ul);
}
ans setgmod(void)
{
	char old_gmode;
	argptr++;
	old_gmode=gmode;
	gmode=getsl;
	rsl(old_gmode);
}

void exec_cmd(unsigned char *cmd)
{
	HANDLE handle;
	int err;
	TRY
	push_parse_text (cmd);
	handle = HS_popEStack ();
	HeapLock (handle);		//car je ne suis pas sur à 100% que HS_popEstack locks le handle (contradiction avec HeapAllocHigh).
  NG_execute (handle, FALSE);
	ONERR
	err=errCode;
	if(disp_err)
	{
		if(ERD_dialog (err, TRUE))
		{
			if(handle) HeapFree (handle); exit2("Exit by pressing ENTER");
		}
	}
	ENDTRY
	if(handle) HeapFree (handle);
	
	
	//ans = GetIntArg (top_estack);
}
ans clscr(void)
{
	//clrscr();
	argptr++;
	FastClearScreen_R(lcdad);
	MoveTo (0,0); 
}
//(*(fonc[*(argptr)]))();
ans a(void)
{
	printf("\n=========>*arg=%x &%x",*argptr,(int)(argptr-argdep+2)); ngetchx();
	exit2("Unknown instruction\nProgram lost.");
	return (ans)0;
}
ans lusfunc(void)
{
	argptr+=1;
	//printf("\nexec:%s",foncs[*argptr]);
	//rsl((*(fonc[*(argptr)])()).sl);
	//return (ans)0;
}

/*
ans gpvar(void)
{
	argptr+=2;
	rpul(&(varlist[*(argptr-1)]));
}
*/
ans neg(void) //correspond au minus_tag
{
	argptr++;
	rsl(-(getsl));
}
ans gslvar(void)		//equivalent à rsl(*ptrvar)
{
	argptr+=2;
	rsl((varlist[*(argptr-1)]).sl);
}
ans printf1(void)
{
	unsigned char *s;
	argptr+=1;
	s=getpuc;
	printf(s,getsl);
	rpuc(s);
}
ans printf2(void)
{
	unsigned char *s;
	long vaaa,vbbb;
	argptr+=1;
	s=getpuc;
	vaaa=getsl;
	vbbb=getsl;
	//printf("\n%lp",&varlist);
	printf(s,vaaa,vbbb);
	rpuc(s);
}

ans LBL(void)
{
	argptr+=3;
}
ans GOTO(void)
{
	int var;
	var=*(argptr+2);
	argptr=arglbl[var];
	/*int num_var;
	argptr++;
	
	num_var=*(argptr+1);
	while(*argptr!=0xE9)
	{
		foundarg(0x4);//label
		printf("Valeur de argptr=%d",*argptr);
		if(*(argptr+2)==num_var) break;
	}
	if(*argptr==0xE9) return;
	argptr+=3;*/
}
ans endtag(void)
{
argptr++;
rsl(1);
}

ans isz(void)
{
	argptr+=3;
	rsl((++(varlist[*(argptr-1)]).sl));
}
ans dsz(void)
{
	argptr+=3;
	rsl((--(varlist[*(argptr-1)]).sl));
}
ans iff(void)
{
	//unsigned int delta;
	argptr++;
	if(getsl) {(*(fonc[*(argptr)]))(); }
	else { 
	argptr+=(*(unsigned char*)(argptr+2)+255*(*(unsigned char*)(argptr+1))+1);
	}
}
ans addd(void)
{
	argptr++;
	return (ans)((getsl)+(getsl));
}
ans sub(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)((getsl)-l1);
}
ans mul(void)
{
	argptr++;
	return (ans)((getsl)*(getsl));
}
ans divv(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)((getsl)/l1);
}
ans tohandl(void)
{
	unsigned char hnum;
	ESI arg;
	HANDLE handle;																				
	delete_between (bottom_estack, top_estack); 
	hnum=*(++argptr/*+1*/);  //num de la variable
	argptr+=3;
	for(arg=argptr/*3*/;arg<argptr/*+3*/+*(argptr-2)*256+*(argptr-1);arg++)
		{
			push_quantum (*arg);
		}
		if((handle = HS_popEStack ())==NULL) exit2("Mem error in basich()");
	HeapLock (handle);
	(varlist[hnum]).h=handle;
	argptr=arg;
	rsl(0);
}
ans freeh(void)
{
	argptr+=3;
	HeapFree ((varlist[*(argptr-1)]).h);
	rsl(0);
}
ans execbas(void) //pas tres rapide
{
//	ESI arg,argendd/*,argmin,argmax*/;
	HANDLE handle;
	int err;
	unsigned int dim;

	argptr++;	//new

	err=0;																					//HEXA:F8 IP1 IP2 DATA
	handle=handle_execbas;
	dim=*(argptr+1)+(*(argptr))*256;
	//delete_between (bottom_estack, top_estack); 
	ptr_execbas=HeapDeref(handle_execbas); 	//D'après la doc, ne devrait pas être nécessaire car le pointeur est censé toujours être valide var Handle bloqué, cependant, j'ai constaté le contraire
	//printf("argptr=%ld! *(*)=%lX",argptr,*(unsigned long*)(ptr_execbas+2)); ngetchx();
	if((*(unsigned long*)(ptr_execbas+2))!=(unsigned long)argptr)	//si le bloc précédant n'était pas le même qui celui ci, alors on le copie en mémoire, aussion ne le copie pas.
	{
		//printf("NOUVEAU"); ngetchx();
		*(unsigned long*)(ptr_execbas+2)=argptr;
		//argmin=argptr+3;
		argptr+=(2+dim);
		//memset(ptr_execbas+2+4,0xE9,dim_max+1);
		memcpy(ptr_execbas+dim_max+2+4+1-dim,argptr-dim,dim);	
		*(ptr_execbas+dim_max+2+4+1-dim-1)=0xE9;	//pour terminer l'exécution même avant la fin de l'HANDLE
		//printf("\nici %X",*(unsigned char*)HToESI(handle_execbas)); ngetchx();
		//printf("\nici %X %X %X %X",*(ptr_execbas+dim_max+4-4),*(ptr_execbas+dim_max+4-3),*(ptr_execbas+dim_max+4-2),*(ptr_execbas+dim_max+4-1)); ngetchx();
		//argptr+=dim;
	}
	else argptr+=(2+dim);
	 
	/*delete_between (bottom_estack, top_estack); 
	argendd=argptr+3+*(argptr+2)+(*(argptr+1))*256;
	for(arg=argptr+3;arg<argendd;arg++)
		{
			push_quantum (*arg);
		}
		if((handle = HS_popEStack ())==NULL) exit2("Tibasic execution error");
	HeapLock (handle);*/
	TRY
	//printf("exec9");
	NG_execute (handle, FALSE);
	ONERR
	err=errCode;
	if(disp_err)
	{
		if(ERD_dialog (err, TRUE))
		{
			if(handle) HeapFree (handle); exit2("Exit by pressing ENTER");
		}
	}
	ENDTRY

	//if(handle) HeapFree (handle);	
	//argptr=arg;
	rsl(err);
}
ans exech(void)
{
	int err;
	argptr+=3;
	TRY
	NG_execute ((varlist[*(argptr-1)]).h, FALSE);
	ONERR
	err=errCode;
	if(disp_err)
	{
		if(ERD_dialog (err, TRUE))
		{
			if((varlist[*(argptr-1)]).h) HeapFree ((varlist[*(argptr-1)]).h); exit2("Exech():Exit by pressing ENTER");
		}
	}
	rsl(err);
	ENDTRY
	rsl(0);
}
ans finl(void)  //E8
{
	argptr++;
}
ans kwait(void)
{
	argptr++;
	if(save_int_1)		//for avoiding crash with keyclear()=>Restore auto int1
	{
		SetIntVec (AUTO_INT_1, save_int_1);
		save_int_1=NULL;		//is useful later	
		//SetIntVec (save_int_1,AUTO_INT_1s);
	}
	rsl((long)ngetchx());
}

ans xorr(void)
{
	argptr++;
	return (ans)((getsl)^(getsl));
}
ans orl(void)
{
	argptr++;
	return (ans)((getsl)||(getsl));
}
ans orb(void)
{
	argptr++;
	return (ans)((getsl)|(getsl));
}
ans notb(void)
{
	argptr++;
	rsl(~(getsl));
}
ans andl(void)
{
	argptr++;
	return (ans)((getsl)&&(getsl));
}
ans andb(void)
{
	argptr++;
	return (ans)((getsl)&(getsl));
}
ans inf(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)(l1<(getsl));
}
ans infeq(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)(l1<=(getsl));
}
ans eq(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)(l1==(getsl));
}
ans eqs(void)	//comparaison de string
{
	unsigned char *s1;
	argptr++;
	s1=getpuc;
	if(strcmp(s1,getpuc)==0) rsl(1);
	else rsl(0);
}
ans supeq(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)(l1>=(getsl));
}
ans sup(void)
{
	long l1;
	argptr++;
	l1=getsl;
	return (ans)(l1>(getsl));
}
ans noteq(void)
{
	long l1,l2;
	argptr++;
	l1=getsl;
	l2=getsl;
	return (ans)(l1!=l2);
}
ans nott(void)
{
	//long l1;
	argptr++;
	//if(getsl==0) rsl(1);
	//else rsl(0);
	//return (ans)(!(getsl));
	rsl(!getsl);
}
/*
ans exitt(void)
{
	argptr++;
	brkvar=0;
}*/
ans ifthen(void)
{
	int var;
	argptr++;
	var=*(argptr+1);
//	if(var==9) {printf("var=9 argptr=%ld,\nargendif[9]=%ld\nargelse[9]=%ld",argptr,argendif[var],argelse[var]); ngetchx();}
	argptr+=2;
	if(!(getsl)) argptr=argelse[var];
}
ans elsee(void)
{
//	int var;
//	argptr++;
//	var=*(argptr+1);
	argptr=argendif[*(argptr+2)];
//		argptr=argendif[var];
}
ans endif(void)
{
	argptr+=3;
}
ans GOTOL(void)
{
	argptr+=*(argptr+1)*255+*(argptr+2)+1;
}
ans WHILE(void)	//while_tag char_num_while condition
{
	int var;
	argptr+=3;
	var=*(argptr-1);	//numero du while
	if(!(getsl))
	{
		argptr=argendwhile[var];
	}
}
ans EDWHILE(void)
{
	int var;
	ESI tmpesi;
	argptr+=3;
	var=*(argptr-1);
	tmpesi=argptr;
	argptr=argwhile[var]+3;
	if(!(getsl))
	{
		argptr=tmpesi;
	}
}
ans nop(void)
{
	argptr++;
}
ans mallo(void)
{
	//unsigned int l;
	unsigned char *ptr;
	argptr++;
	//l=getsl;
	ptr=(unsigned char*)malloc(getsl);
	if(ptr==0)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Malloc():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	rpuc(ptr);
}
ans fre(void)
{
	unsigned char *p;
	argptr++;
	p=getpuc;
	//p=getsl;
	if(p==0) exit2("Error: free(ptr)\nptr shall be not NULL");
	//printf("Avant free"); ngetchx();
	free(p);
	//printf("Apres free"); ngetchx();
}
ans pokb(void)	//pokb(address,val)
{
	char *p;
	//char b;
	argptr++;
	p=getpuc;
	*(p)=getsl;
	rsl(*p);
}
ans pokw(void)
{
	int *p;
	//int b;
	argptr++;
	p=getpui;
	*(p)=getsl;
	rsl(*p);
}
ans pokl(void)
{
	long *p;
	//long b;
	argptr++;
	p=getpul;
	*(p)=getsl;
	rsl(*p);
}
ans pekb(void)
{
	char *p;
	argptr++;
	p=getpuc;
	rsl(*p);
}
ans pekw(void)
{
	int *p;
	argptr++;
	p=getpui;
	rsl(*p);
}
ans pekl(void)
{
	long *p;
	argptr++;
	p=getpul;
	rsl(*p);
}
ans repeat(void)
{
	register long i,nb;
	ESI arg;
	argptr++;
	nb=getsl;
	arg=argptr;
	for(i=0;i<nb;i++)
	{
		argptr=arg;
		(*(fonc[*(argptr)]))();
	}
}
ans gotopos(void)
{
	argptr++;
	argptr=getsl;
}
ans pos(void)
{
	argptr++;
	rsl(argptr);
}
ans rts(void)
{
	if(nsubfonc==0) {argptr++; return;}
	nsubfonc--;
	argptr=subfonc[nsubfonc];
//printf("\nrts *argptr=%x &=%x %s",*argptr,(int)(argptr-argdep+2),foncs[*argptr]); ngetchx();
}
ans jsr(void)
{
	argptr++;
	subfonc[nsubfonc++]=argptr+2;
	argptr=arglbl[*(argptr+1)];
	//exec_none_stop();
}
ans belm(void)
{
	unsigned char* address;
	unsigned int row;
	argptr++;
	address=getsl;	//address de la liste
	row=getsl;
	rsl(((char*)address)[row]);
}
ans welm(void)
{
	int* address;
	unsigned int row;
	argptr++;
	address=getsl;	//address de la liste
	row=getsl;
	rsl(address[row]);
}
ans lelm(void)
{
	long* address;
	unsigned int row;
	argptr++;
	address=getpuc;	//address de la liste
	row=getsl;
	rsl(address[row]);
}
ans rwky(void)	//row de 0 à 8 et mask de 0 à 255
{
	int row,mask;
	argptr++;
	row=getsl;
	mask=getsl;
//	rsl(_rowread(0xffff-1<<row)&mask); 
	rsl(_rowread_inverted(row)&_rowread_inverted(row)&mask);
}

ans mklist(void)	//num_of_var,nbelem,size_of_elem
{
	unsigned char varn;
	unsigned int dimelem,nbelemm,i;
	argptr++;
	varn=*argptr;
	argptr++;
	//printf("num of var = %d",varn);
	//dimelem=getsl;
	nbelemm=getsl;
	//printf("nbelem = %d",nbelemm);
	
	//nbelemm=getsl;		//Has been retired from the compilator because not useful for the programmer point of view
	dimelem=getsl;
	//printf("dimelem = %d",dimelem);
	
	//printf("Size of elem = %d",varn);
	varlist[varn]=(ans)((unsigned char*)malloc(dimelem*nbelemm));
	if(!varlist[varn].puc)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("{} ilist:Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	byte_width_ilist[varn]=dimelem;
	//printf("\nvarn=%d dimelem=%d nbelem=%d\n",varn,dimelem,nbelemm); ngetchx();
	for(i=0;i<nbelemm;i++)
	{
			/*if(*argptr==MINUS_TAG)
			{
				printf("C'est un MINUS_TAG"); ngetchx();
				argptr++;
			}*/
			switch(dimelem)
		{
			case 1:
			if(*argptr==MINUS_TAG)
			{
				//printf("C'est un MINUS_TAG"); //ngetchx();
				argptr++; poke(varlist[varn].puc+i,-getsl);
			} else poke(varlist[varn].puc+i,getsl);
			break;
			case 2:
			if(*argptr==MINUS_TAG)
			{
				//printf("C'est un MINUS_TAG"); //ngetchx();
				argptr++; poke_w(varlist[varn].puc+i*2,-getsl);
			} else poke_w(varlist[varn].puc+i*2,getsl);
			break;
			case 4:
			if(*argptr==MINUS_TAG)
			{
				//printf("C'est un MINUS_TAG"); //ngetchx();
				argptr++; poke_l(varlist[varn].puc+i*4,-getsl);
			} else poke_l(varlist[varn].puc+i*4,getsl);
			break;
		}	
	}
	rsl(varlist[varn].puc);
	
}
ans dline(void)	// dline(xa,ya,xb,yb)
{
	unsigned char xa,ya,xb,yb;
	argptr++;
	xa=getsl;
	ya=getsl;
	xb=getsl;
	yb=getsl;
	switch(gmode)
	{
		case 0:
		//FastLine_Draw_R(lcdad,xa,ya,xb,yb); return;
		FastDrawLine(lcdad,xa,ya,xb,yb,1); return;
		break;
		case 1:
		FastDrawLine(lcdad,xa,ya,xb,yb,0); return;
		break;
		case 2:
		FastDrawLine(lcdad,xa,ya,xb,yb,2); return;
		break;
	}
//	DrawLine(xa,ya,xb,yb,gmode);
}
ans dmline(void)		//syntax : dmline(liste_de_chars_abscisse,liste_de_chars_ordonnés,nombre_de_points)
{
	unsigned char *xa,*ya,xi,yi,xf,yf,gmode2;
	//short *xa,*ya,xi,yi,xf,yf;
	unsigned int nbpoints,ii;
	argptr++;
	xa=getsl;
	ya=getsl;
	nbpoints=getsl;
	xi=xa[0];
	yi=ya[0];
	switch(gmode)
	{
		case 0:
		gmode2=1;
		break;
		case 1:
		gmode2=0;
		break;
		case 2:
		gmode2=2;
		break;
	}
	
	for(ii=1;ii<nbpoints;ii++)
	{
		xf=xa[ii];
		yf=ya[ii];
		FastDrawLine(lcdad,xi,yi,xf,yf,gmode2);
		//DrawLine(xi,yi,xf,yf,gmode);
		xi=xf;
		yi=yf;
	}
	
}
ans fopenn(void)	//Return a pointer
{
	
	Files *f;
	argptr++;
	f=OpenFile(getpuc);

	rpfiles(f);
}


ans fcreatee(void)
{
  unsigned char *blockptr,*FileName,rr;
  HANDLE h;

	argptr++;
	blockptr=getpuc;	//the block to be stored in the file
	FileName=getpuc;
	
//	printf("taille du bloc %d",(*(unsigned int*)(blockptr))); ngetchx();
	
	h=CreateFile_with_specified_size (FileName,(*(unsigned int*)(blockptr))+2+10);
	if(h==H_NULL) 
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Toos():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	//if(h==H_NULL) rsl(0);
	
	rr=AppendBlockToFile2 (h, blockptr+2, (*(unsigned int*)(blockptr)));

	(*(unsigned int*)(HeapDeref(h)))--;		//Bidouille

	HeapUnlock (h);
  HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
	rsl(rr);	//return 1 if ok, else 0
}

char AppendCharToFile3 (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h) - 10) { clrscr(); printf("Error when writing a char in a file."); return 0;}
  *(unsigned short*)base = len + 1;
  return base[len+2] = c;
}



ans printc(void)
{
	unsigned char c;
	argptr++;
	c=getsl;
	printf("%c",c);
}
ans gts(void)
{
	char *buff;
	argptr++;
	buff=getpuc;
	rpuc(gets(buff));
}
ans sprntf(void)
{
	char *buff,*strr;
	long arg;
	argptr++;
	buff=getpuc;
	strr=getpuc;
	arg=getsl;
	rpuc(sprintf(buff,strr,arg));
}
ans chars(void)
{
	static unsigned char c_str[]={0,0,0,0,0,0,0,0,0,0},index_in_c_str;	//jusqu'à 5 string possible de retour
	//ESI argptrr;
	argptr++;
	if(index_in_c_str!=8) index_in_c_str+=2;
	else index_in_c_str=0;
	//argptrr=argptr;
	//argptr+=2;
	c_str[index_in_c_str]=getsl;
	//c_str[index_in_c_str+1]=0;
	rpuc(&c_str[index_in_c_str]);
}
ans strct(void)
{
	char *d,*s;
	argptr++;
	d=getpuc;
	s=getpuc;
	rpuc(strcat(d,s));
}
void __attribute__((__stkparm__)) ScaleSprite8_OR(unsigned char *sprite,void *dest,short x0,short y0,short sizex,short sizey)
{
	short dx,dy;
	unsigned char maskorig,mask;
	unsigned char masksrc;
	char *tmpdest;

	(unsigned char *)dest+=((((y0)+(y0))<<4)-((y0)+(y0)))+((x0)>>3);
	maskorig=(0x80)>>(x0&7);

	dy=8/1-sizey;

	for(y0=sizey;y0--;)
	{
		if(dy>=0) {
			do
			{
				dy-=sizey, sprite++;
			} while(dy>0);
                }

		tmpdest=dest;
		masksrc=0x80;
		mask=maskorig;
		dx=8/1-sizex;
		for(x0=sizex;x0--;)
		{
			if(dx>=0) {
				do
				{
					dx-=sizex;
					masksrc>>=1;
				} while(dx>0);
                        }

			if(*sprite & masksrc) {
				*tmpdest |= mask;
                        }
			asm("ror.b #1,%0;bcc.s 0f;addq.l #1,%1;0:":"=d" (mask),"=g" (tmpdest):"0"(mask),"1"(tmpdest));
			dx+=8;
		}
		(unsigned char *)dest+=30;
		dy+=8;
	}
}


ans sprt8(void)		//Transformed in clipped
{
	signed int x,y,h;
	unsigned char *sprite/*,i,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;
	switch(gmode)
	{
		case 2:	//xor
		ClipSprite8_XOR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 3:		//AND
		ClipSprite8_AND_R(x,y,h,sprite,lcdad);	return;
		break;
		case 0:	//or
		ClipSprite8_OR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 1:	//blank
		ClipSprite8_RPLC_R(x,y,h,sprite,lcdad);	return;
		break;
		
	}	
}


/*void Sprite8_extgraph(unsigned char x,unsigned char y,unsigned int h,unsigned char *sprite,unsigned char mode)
{
	switch(mode)
	{
		case 0:	//or
		Sprite8_OR(x,y,h,sprite,lcdad);	return;
		break;
		case 1:	//blank
		Sprite8_RPLC_R(x,y,h,sprite,lcdad);	return;
		break;
		case 2:	//xor
		Sprite8_XOR(x,y,h,sprite,lcdad);	return;
		break;
		case 3:		//AND
		Sprite8_AND(x,y,h,sprite,lcdad);	return;
		break;
}*/
ans gsprt8(void)
{
	signed int x,y,h;
	unsigned char *sprite/*,i,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;
	ClipSprite8Get_R(x,y,h,sprite,lcdad);

}
ans sprt16(void)
{
	short x,y,h;
//	unsigned char i;
	unsigned int *sprite/*,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;
	//video_mem=getsl;
	
	switch(gmode)
	{
		case 2:	//xor
		ClipSprite16_XOR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 3:		//AND
		ClipSprite16_AND_R(x,y,h,sprite,lcdad);	return;
		break;
		case 0:	//or
		ClipSprite16_OR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 1:	//blank
		ClipSprite16_RPLC_R(x,y,h,sprite,lcdad);	return;
		break;
	}
	rpuc(sprite);
}
ans gsprt16(void)
{
	short x,y,h;
//	unsigned char i;
	unsigned int *sprite/*,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;
	
	ClipSprite16Get_R(x,y,h,sprite,lcdad);
	rpuc(sprite);

}
ans sprt32(void)
{
	short x,y,h;
//	unsigned char i;
	unsigned long *sprite/*,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;
	//video_mem=getsl;

	switch(gmode)
	{
		case 2:	//xor
		ClipSprite32_XOR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 3:		//AND
		ClipSprite32_AND_R(x,y,h,sprite,lcdad);	return;
		break;
		case 0:	//or
		ClipSprite32_OR_R(x,y,h,sprite,lcdad);	return;
		break;
		case 1:	//blank
		ClipSprite32_RPLC_R(x,y,h,sprite,lcdad);	return;
		break;
		
	}
	rpuc(sprite);
}
ans gsprt32(void)
{
	short x,y,h;
//	unsigned char i;
	unsigned long *sprite/*,shiftsprt[1]*/;
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	sprite=getpuc;

	ClipSprite32Get_R(x,y,h,sprite,lcdad);
}
ans mmset(void)
{
	char *buff;
	short val;
	unsigned int num;
	argptr++;
	buff=getpuc;
	val=getsl;
	num=getsl;
	rpuc(memset(buff,val,num));
}
ans map(void)
{
	unsigned char varnum;
	long st,en,ste,*p;
	ESI argdeb;
	argptr++;
	varnum=*(argptr+1);
	p=&varlist[varnum];
	argptr+=2;
	st=getsl;
	en=getsl;
	ste=getsl;
	//printf("DANS MAP st=%ld en=%ld ste=%ld ",st,en,ste);
	argdeb=argptr;
	for(*p=st;*p!=en;*p+=ste)
	{
		(*(fonc[*(argptr)]))();
		//printf("\ncoucou");
		argptr=argdeb;
	}
	  return ((*(fonc[*(argptr)]))());
}
ans multi(void)
{
	int n,i;	//nombre de lignes
	argptr++;
	n=getsl;
	for(i=1;i<n;i++)
	{
		(*(fonc[*(argptr)]))();
	}
	return (*(fonc[*(argptr)]))();
}
ans two(void)
{
	argptr++;
	(*(fonc[*(argptr)]))();
	return (*(fonc[*(argptr)]))();
}
ans setlcd(void)
{
	void *vmemori;
	argptr++;
	vmemori=lcdad;
	PortSet ((lcdad=getpuc), 239, 127); // redirect drawing routines to buffer
	rsl(vmemori);
}
ans getlcd(void)
{
	argptr++;
	rsl(lcdad);
}
ans dpix(void)
{
	int x,y;
	argptr++;
	x=getsl; y=getsl;
	switch(gmode)
	{
		case 2:	//xor
		EXT_XORPIX(lcdad, x, y); return;
		break;
		case 3:		//AND
		return;
		break;
		case 0:	//or
		EXT_SETPIX(lcdad, x, y);	return;
		break;
		case 1:	//blank
		EXT_CLRPIX(lcdad, x, y);	return;
		break;
	}
//	DrawPix (x,y,gmode);
}
ans gpix(void)
{
	int x,y;
	argptr++;
	x=getsl; y=getsl;
	rsl(EXT_GETPIX(lcdad, x, y));		//about 30% faster than Tios routine
	//rsl(GetPix (x,y));
}
ans gryon(void)
{
	argptr++;
	disp_err_old=disp_err;
	disp_err=0;	//désactive the error displaying because can crash the calculator
	rsl(GrayOn());
}
ans gryoff(void)
{
	argptr++;
	disp_err=disp_err_old;	//restore the previous error displaying mod
	GrayOff();
}
ans ligh(void)
{
	argptr++;
  //lcdad=GrayGetPlane(LIGHT_PLANE);
  PortSet((lcdad=GrayGetPlane(LIGHT_PLANE)),239,127); 
	rpuc(lcdad);
}
ans dar(void)
{
	argptr++;
	//lcdad=GrayGetPlane(DARK_PLANE);
	PortSet((lcdad=GrayGetPlane(DARK_PLANE)),239,127); 
	rpuc(lcdad);
}
ans fillrec(void)
{
	//static SCR_RECT rect;
	unsigned char xa,xb,ya,yb,ii,modev;
	argptr++;
	/*rect.xy.x0=*/(xa=getsl);
	/*rect.xy.y0=*/(ya=getsl);
	/*rect.xy.x1=*/(xb=getsl);
	/*rect.xy.y1=*/(yb=getsl);
	
	//FastFilledRect(lcdad,xa,ya,xb,yb,gmode);
	
	switch(gmode)
	{
		case 0:
		modev=A_NORMAL;	//or
		break;
		case 1:	//efface gerase
		modev=A_REVERSE;	//efface
	/*	rect.xy.x0=xa;
		rect.xy.y0=ya;
		rect.xy.x1=xb;
		rect.xy.y1=yb;
		ScrRectFill (&rect, &scr_rect, A_REVERSE); return;*/
		break;
		case 2:
		modev=A_XOR;
		break;
		case 3:
		modev=A_NORMAL;	//normalement AND
		break;
	}
	
	FastFilledRect(lcdad,xa,ya,xb,yb,modev);

}
ans clrdrw(void)
{
	argptr++;
	FastClearScreen_R(lcdad);
}
ans scrleft(void)
{
	register short* tmpbuffer;
  register short  tmplines;
	argptr++;
	
	tmpbuffer=lcdad;
	tmplines=getsl;
  tmpbuffer += (tmplines<<4) - (tmplines);
  
  tmplines--;
    asm volatile ("0:\n"
        "lea -10(%0),%0\n"
        "lsl.w  -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n"
        "roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n"
        "dbf %1,0b"
        : "=a" (tmpbuffer), "=d" (tmplines)
        : "0"  (tmpbuffer), "1"  (tmplines));
}
ans scrleft2(void)
{
	register short* tmpbuffer;
  register short  tmplines;
	argptr++;
	
	tmpbuffer=lcdad;
	tmplines=getsl;

    tmpbuffer += (tmplines<<4) - (tmplines);
    tmplines--;

    asm volatile ("0:\n"
        "lsl.w  -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n"
        "roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n"
        "roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n"
        "dbf %1,0b"
        : "=a" (tmpbuffer), "=d" (tmplines)
        : "0"  (tmpbuffer), "1"  (tmplines));
}
ans scrrigh(void)
{
	register short* tmpbuffer;
  register short  tmplines;
	argptr++;
	tmpbuffer=lcdad;
	tmplines=getsl;

    tmplines--;

    asm volatile ("0:\n"
        "lsr.w  (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n"
        "roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n"
        "lea 10(%0),%0\n"
        "dbf %1,0b"
        : "=a" (tmpbuffer), "=d" (tmplines)
        : "0"  (tmpbuffer), "1"  (tmplines));
}

ans scrrigh2(void)
{
	register short* tmpbuffer;
  register short  tmplines;
	argptr++;
	tmpbuffer=lcdad;
	tmplines=getsl;

    tmplines--;

    asm volatile ("0:\n"
        "lsr.w  (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n"
        "roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n"
        "roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n"
        "dbf %1,0b"
        : "=a" (tmpbuffer), "=d" (tmplines)
        : "0"  (tmpbuffer), "1"  (tmplines));
}

ans scrup(void)
{
	register short* dest;
  register short* src;
  register short  tmplines;
	argptr++;
	dest=lcdad;
	src=dest+15;
	tmplines=getsl;

  tmplines -= 2;

    asm volatile ("0:\n"
        "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n"
        "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n"
        "lea 10(%0),%0\n"
        "lea 10(%1),%1\n"
        "dbf %2,0b\n"
        "clr.l (%1)+;clr.l (%1)+;clr.l (%1)+;clr.l (%1)+;clr.l (%1)+"
        : "=a" (src), "=a" (dest), "=d" (tmplines)
        : "0"  (src),  "1" (dest), "2"  (tmplines));
}
ans scrup2(void)
{
	register short* dest;
  register short* src;
  register short  tmplines;
	argptr++;
	dest=lcdad;
	src=dest+15;
	tmplines=getsl;

  tmplines -= 2;

    asm volatile ("0:\n"
        "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n"
        "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n"
        "move.l (%0)+,(%1)+;move.w (%0)+,(%1)+\n"
        "dbf %2,0b\n"
        "clr.l (%1)+;clr.l (%1)+;clr.l (%1)+;clr.l (%1)+\n"
        "clr.l (%1)+;clr.l (%1)+;clr.l (%1)+;clr.w (%1)+"
        : "=a" (src), "=a" (dest), "=d" (tmplines)
        : "0"  (src),  "1" (dest), "2"  (tmplines));
}
ans scrbot(void)
{
	register short* dest;
  register short* src;
  register short  tmplines;
	argptr++;
	dest=lcdad;
	src=dest+15;
	tmplines=getsl;

  dest += (tmplines<<4) - (tmplines) - 5;
    src   = dest - 15;

    tmplines -= 2;

    asm volatile ("0:\n"
        "move.l -(%0),-(%1);move.l -(%0),-(%1);move.l -(%0),-(%1)\n"
        "move.l -(%0),-(%1);move.l -(%0),-(%1)\n"
        "lea -10(%0),%0\n"
        "lea -10(%1),%1\n"
        "dbf %2,0b\n"
        "clr.l -(%1);clr.l -(%1);clr.l -(%1);clr.l -(%1);clr.l -(%1)"
        : "=a" (src), "=a" (dest), "=d" (tmplines)
        : "0"  (src), "1"  (dest), "2"  (tmplines));
}
ans scrbot2(void)
{
	register short* dest;
  register short* src;
  register short  tmplines;
	argptr++;
	dest=lcdad;
	src=dest+15;
	tmplines=getsl;

  dest += (tmplines<<4) - (tmplines);
    src   = dest - 15;

    tmplines -= 2;

    asm volatile ("0:\n"
        "move.l -(%0),-(%1);move.l -(%0),-(%1);move.l -(%0),-(%1)\n"
        "move.l -(%0),-(%1);move.l -(%0),-(%1);move.l -(%0),-(%1)\n"
        "move.l -(%0),-(%1);move.w -(%0),-(%1)\n"
        "dbf %2,0b\n"
        "clr.l -(%1);clr.l -(%1);clr.l -(%1);clr.l -(%1)\n"
        "clr.l -(%1);clr.l -(%1);clr.l -(%1);clr.w -(%1)"
        : "=a" (src), "=a" (dest), "=d" (tmplines)
        : "0"  (src), "1"  (dest), "2"  (tmplines));
}
ans drwstr(void)
{
	unsigned char x,y,*pstr;
	argptr++;
	x=getsl;
	y=getsl;
	pstr=getpuc;
	switch(gmode)
	{
		case 2:	//xor
		DrawStr(x,y,pstr,A_XOR);	return;
		break;
		case 3:		//AND
		DrawStr(x,y,pstr,A_AND);	return;
		break;
		case 0:	//or
		DrawStr(x,y,pstr,A_NORMAL);	return;
		break;
		case 1:	//blank
		DrawStr(x,y,pstr,A_REVERSE);	return;
		break;
	}
	DrawStr(x,y,pstr,gmode);
}
ans setfontt(void)
{
	argptr++;
	rsl(FontSetSys (getsl));
}
ans lrol(void)
{
	long val;
	char n;
	argptr++;
	val=getsl;
	n=getsl;
	rsl(val<<n);
}
ans rrol(void)
{
	long val;
	char n;
	argptr++;
	val=getsl;
	n=getsl;
	rsl(val>>n);
}
ans tios(void)
{
	HANDLE handle;
	unsigned char *str;
	int err;
	argptr++;
	str=getpuc;
	push_parse_text (str);
	TRY
	handle = HS_popEStack ();
	ONERR
	if(disp_err)
	{
		if(ERD_dialog (ER_MEMORY, TRUE))
		{
			if(handle) HeapFree (handle); exit2("os():Exit by pressing ENTER");
		}
	}
	rsl(0);
	ENDTRY
	TRY
	NG_execute (handle, FALSE);
	ONERR
	err=errCode;
	if(disp_err)
	{
		if(ERD_dialog (err, TRUE))
		{
			if(handle) HeapFree (handle); exit2("os():Exit by pressing ENTER");
		}
	}
	rsl(0);
	ENDTRY
	if(handle) HeapFree (handle);
	switch(GetArgType(top_estack))
	{
		case NEGINT_TAG:
		rsl(-GetIntArg(top_estack));
		break;
		case POSINT_TAG:
		rsl(GetIntArg(top_estack));
		break;
		case STR_TAG:
		rsl(GetStrnArg(top_estack));
		break;
		case LIST_TAG:
		exit2("\nos() cannot return list");
		break;
		case FLOAT_TAG:
		rsl((signed long)GetFloatArg (top_estack)); 
		break;
		//en supposant ci dessous que c'est un négatif (MINUS -)
		}
		
}
ans fc_debug(void) //execute une fonction : f(nom_var_fonction,arg1,arg2,...)		TAG: 0d153,getsl : nb arg , newprog_function_id, arg1,arg2,... en mode debug
{
	unsigned char nf/*,nbarg*/,ii,nb_arg;
	ESI argptrf,argptr_return,argptr_temp;
	argptr++;

	nf=*(argptr+1);
	argptr+=2;	//pointe sur la valeur à évaluer du premier argument

	//Backup global variables
	nb_arg=user_func_nb_arg[nf];
	for(ii=0;ii<nb_arg;ii++)
	{
		var_user_func_varnum_backup[i_var_user_func_backup]=*(argfunc[nf]+1+ii*2);		//retrieve the number of the destination var 
		var_user_func_backup[i_var_user_func_backup]=varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl;		//sto the value of the main variables before overlapping them
		varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl=getsl;		//Affecte les variables passées en argument avec leur valeurs
		//printf("Varnum =%d ii=%d\nold value=%ld\nnew value=%ld\nmanual varlist[varnum]=%ld",var_user_func_varnum_backup[i_var_user_func_backup],ii,var_user_func_backup[var_user_func_varnum_backup[i_var_user_func_backup]],varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl,varlist[0].sl); ngetchx();
		i_var_user_func_backup++;
	}
	
	argptr_return=argptr;		//sauvegarde le PC de retour
	argptr=argfunc[nf]+nb_arg*2;	//pointe à la première instruction de la fonction
	argptrf=argendfunc[nf]-3;

	while(argptr<argptrf)
	{
		printf("\n*argptr=%x &=%x %s",*argptr,(int)(argptr-argdep+2),foncs[*argptr]); ngetchx();
		if(*argptr==241) {argptr++; continue;}	//on passe les debugoff, ils ne sont autorisés que dans le flux principal
		(*(fonc[*(argptr)]))();
	}		//execute the instructions
	argptr=argptr_return;

	//Restore global variables
	for(ii=0;ii<nb_arg;ii++)
	{
		--i_var_user_func_backup;
		varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl=var_user_func_backup[i_var_user_func_backup];		//Affecte les variables passées en argument avec leur valeurs
	}
	
	rsl(rtn_value);
}

ans debugon(void)
{
	argptr++;
	printf("\nDEBUG ON :");
	while(*argptr!=0xE9 && *argptr!=241)	//0xf1=241=debugoff
	{
		printf("\n*argptr=%x &=%x %s",*argptr,(int)(argptr-argdep+2),foncs[*argptr]); ngetchx();
		if(*argptr==153) fc_debug();
		else (*(fonc[*(argptr)]))();
	}
	(*(fonc[*(argptr)]))();
	printf("\nDEBUG OFF\n");
	rsl(0);
}
ans DEBUGOF(void)
{
	argptr++;
}
ans nilist(void)	//pass a nilist
{
	long d/*,i*/,s;
	ESI argdeb;
	argdeb=argptr;
	argptr++;
	s=getsl;	//size of data
	d=getsl;	//number of data
	//printf("\ntaille : %d\nNombre d'elements : %d",(int)s,(int)d);
	//for(i=0;i<d;i++) (*(fonc[*(argptr)]))();
	argptr+=s;
	rsl(argdeb);
}
long toos_nilist_process(HANDLE handle)		//transforme une niliste en liste, le fichier avec CreateFile doit avoir été préalablement créé, dont le Handle est envoyé en argument de cette fonction
{
	unsigned int ii,nbelem,data_dim;
	unsigned char *p_eval;
	long value;
	ESI st_bot,st_temp,st_top;
	//argptr : pointe sur le nilist tag(=216)
	argptr++;	
	data_dim=4;	//calculated dimension of the final output file. Must not be bigger than LCD_SIZE+100
	getsl;	//passe la taille
	nbelem=getsl;
	
	//on commence par mettre tous les composants de la nilist sur le stack. J'ai choisie cette méthode car elle permettra d'avoir une liste dans l'ordre (non inversée)
	//st_bot=top_estack;
	for(ii=0;ii<nbelem;ii++)
	{
		switch(*argptr)
		{
			case 14:	//indirection, alors ça ne peut être que considéré comme un pointeur sur string (une liste de liste étant interdite car trop complexe)
			argptr++;
			p_eval=getpuc;
			data_dim+=(strlen(p_eval)+3);
			if(*p_eval==216 && *(p_eval+1)==31 && *(p_eval+4)==1) exit2("toos({#nilist_ptr}) forbiden");
			push_zstr (p_eval);
			continue;
			case STR_TAG:
			p_eval=getpuc;
			data_dim+=strlen(p_eval)+3;
			push_zstr (p_eval);
			continue;
		}
		//si pas indirection ou STR_TAG, alors enregistre en tant que nombre
		value=getsl;
		data_dim+=6;		//maximum une taille de 6 pour un nombre Tibasic long négatif
		push_longint (value);
	}
	
	if(data_dim>(LCD_SIZE+100)) {CloseFile_type (handle,STR_TAG); exit2("Toos():destination file size >3940");}
	//On met le contenu du stack dans le fichier de destination, la liste sera dans le bon ordre:
	AppendCharToFile(handle,END_TAG);
	for(ii=0;ii<nbelem;ii++)
	{
		st_bot=next_expression_index(top_estack)+1;
		while(st_bot!=(top_estack+1))
		{
			AppendCharToFile(handle,*st_bot);
				st_bot++;
		}
		delete_expression (top_estack);		//repostionne top_estack après avoir supprimer l'élément du stack
	}
	CloseFile_type (handle,LIST_TAG);
	return nbelem;
}
ans toos(void)
{
	unsigned char *p_eval,*dest_file,varn,*argptr_temp;
	unsigned int nbelem,ii,str_len_temp;
	long value;
	HANDLE handle;
	ESI st_bot,st_temp,st_top;
	argptr++;
	if(*argptr==96) argptr++;	//pas indispensable, permet d'utiliser la fonction toos avec osvar(). La différence entre toos et -> peut alors paraitre seulement comme une simple différence d'écriture
	dest_file=getpuc;
	
	//printf("Dans toos, Heapmax()=%ld",HeapMax ()); ngetchx();
	
	//handle = CreateFile (dest_file);
	handle=CreateFile_with_specified_size(dest_file,LCD_SIZE+100);	//taille max pour toos() qui est arbitraire mais qui devrait convenir dans la majorité des cas
	if(handle==H_NULL)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Toos():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	
	switch(*argptr)
	{
		case 14:	//indirection
		argptr++;
		p_eval=getpuc;
		if(*p_eval==216 && *(p_eval+1)==31 && *(p_eval+4)==1)	//alors c'est un pointeur de nilist
		{
			argptr_temp=argptr;
			argptr=p_eval;	//saute à la nilist
			value=toos_nilist_process(handle);
			argptr=argptr_temp;	//retourne au PC intial
			rsl(value);
		}
		//si pas pointeur sur nilist, alors c'est un pointeur sur string
		AppendCharToFile(handle,0);
		AppendBlockToFile (handle, p_eval, strlen(p_eval)+1);
		CloseFile_type (handle,STR_TAG);
		rsl(1);
		break;
		case STR_TAG:
		p_eval=getpuc;
		str_len_temp=strlen(p_eval);
		if(str_len_temp>(LCD_SIZE+100-4)) {CloseFile_type (handle,STR_TAG); exit2("Toos():destination file size >3940");}
		AppendCharToFile(handle,0);
		AppendBlockToFile (handle, p_eval, strlen(p_eval)+1);
		CloseFile_type (handle,STR_TAG);
		rsl(1);
		break;
		//CAS DES NILIST
		case 216: //nilist
		rsl(toos_nilist_process(handle));
		break;
		//FIN DU CAS DES NILIST
	}
	//Si ce n'est pas une string ou une nilist ou une indirection, alors ça ne peut être que des nombres de diverses natures
	value=getsl;
	st_bot=top_estack+1;
	push_longint (value);
	while(st_bot!=(top_estack+1))
	{				
		AppendCharToFile(handle,*st_bot);
		st_bot++;
	}
	delete_expression (top_estack);	//supprime l'élément rajouté sur le stack, ne servant plus
	//Effectue un closefile simple:
	if(handle) HeapUnlock (handle);
  if(handle) HeapRealloc (handle, *(unsigned short*)HeapDeref(handle) + 3);
	rsl(1);
}
ans sto(void)
{
	char nvarr;
	long f;
	unsigned int elem_index;
	argptr++;
	switch(*argptr)
	{
		case 0x02: //gslvar tag. The destination is a var
		argptr+=2;	//point to the value to store
		//nvarr=*(argptr-1);
		//printf("dim elem array%d",byte_width_ilist[nvarr]); //ngetchx();
	//	f=getsl;
		varlist[/*nvarr*/*(argptr-1)].sl=getsl;
		rsl(f);
		break;
		case SUBSCRIPT_TAG:	//the destination in an element of a list
		argptr+=3;
		nvarr=*(argptr-1);	//number of the list/var
		elem_index=getsl;		//elem_index of the list
		f=getsl;		//value to store

		switch(byte_width_ilist[nvarr])
		{
			case 4:
			if(varlist[nvarr].sl!=0) (varlist[nvarr].psl)[elem_index]=f;
			rsl(f);
			break;
			case 1:
			if(varlist[nvarr].sl!=0) (varlist[nvarr].psc)[elem_index]=f;
			rsl(f);
			break;
			case 2:
			if(varlist[nvarr].sl!=0) (varlist[nvarr].psi)[elem_index]=f;
			rsl(f);
			break;
		}

		if(varlist[nvarr].sl!=0) memcpy((varlist[nvarr].psc)+elem_index*byte_width_ilist[nvarr],f,byte_width_ilist[nvarr]);
		rsl(f);
		break;
		case 96:		//osvar() : the destination is a Tios var ; revient à faire un toos()
		return toos();
		break;
	}
	rsl(f);
}
ans prints(void)
{
	argptr++;
	printf("%s",getpuc);
}
ans when(void)
{
	long /*cond,*/num;
	int i;
	ans anss;
	argptr++;
	if(getsl)
	{
		if(*argptr!=216) exit2("Syntax : \nwhen(condition,\n{instructions if true},\n{instructions if false})");
		argptr++;		//ce if ne doit pas contenir une instruction d'une taille supérieure à 255 octets
		getsl;
		num=getsl;
		for(i=0;i<num;i++) anss=((*(fonc[*(argptr)]))());
		nilist();
		//(*(fonc[*(argptr)]))();
	}
	else 
	{
		nilist();	//pass the nilist
		//(*(fonc[*(argptr)]))();
		if(*argptr!=216) exit2("pas une nilist");
		argptr++;			//arrive au deuxieme nilist ; passe le tag de nilist
		getsl;			//passe la taille
		num=getsl;
		for(i=0;i<num;i++) anss=((*(fonc[*(argptr)]))());
	}
	return anss;
}
ans indir(void)	//exécute une nilist pointée par le contenu de la variable
{
	unsigned char varn;
	long s,n,i;
	ans r;
	ESI argptrr,argptr_end;
	argptr++;
	//printf("Nilist"); ngetchx();
	//argptrr=argptr+1;	
	argptr+=2;	//passe la variable, mémorise le pointeur de retour
	argptrr=argptr;
	//printf("*argptr fin =06?=%d",*argptrr); ngetchx();
	//varn=*argptr;		//numéro de la variable
	varn=*(argptr-1);
	//printf("varn=%d",(int)varn); ngetchx();
	argptr=(varlist[varn]).sl;	//maintenant argptr pointe sur la donnée
	switch(*argptr)
	{
		case 216: //nilist
		//printf("C'est une nilist"); ngetchx();
		argptr++;
		s=getsl;
		n=getsl;
		argptr_end=argptr+s;
		/*for(i=0;i<n;i++)
		{
			r=((*(fonc[*(argptr)]))());
		}*/
		while(argptr<argptr_end) r=((*(fonc[*(argptr)]))());
		break;
	}
	argptr=argptrr;							//retourne au PC initial
	return r;										//renvoie le résultat de l'instruction exécutée
}
ans atoll(void)
{
	argptr++;
	rsl(atol(getsl));
}
ans def(void)
{
	argptr++;
	argptr=argendfunc[*(argptr+1)];	//saute la fonction
}
ans enddef(void) //This function is not usually executed
{
	argptr+=3;
}
ans fc(void) //execute une fonction : f(nom_var_fonction,arg1,arg2,...)		TAG: 0d153,getsl : nb arg , newprog_function_id, arg1,arg2,...
{
	unsigned char nf/*,nbarg*/,ii,nb_arg;
	ESI argptrf,argptr_return,argptr_temp;
	argptr++;

	nf=*(argptr+1);
	argptr+=2;	//pointe sur la valeur à évaluer du premier argument

	//Backup global variables
	nb_arg=user_func_nb_arg[nf];
	for(ii=0;ii<nb_arg;ii++)
	{
		var_user_func_varnum_backup[i_var_user_func_backup]=*(argfunc[nf]+1+ii*2);		//retrieve the number of the destination var 
		var_user_func_backup[i_var_user_func_backup]=varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl;		//sto the value of the main variables before overlapping them
		varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl=getsl;		//Affecte les variables passées en argument avec leur valeurs
		//printf("Varnum =%d ii=%d\nold value=%ld\nnew value=%ld\nmanual varlist[varnum]=%ld",var_user_func_varnum_backup[i_var_user_func_backup],ii,var_user_func_backup[var_user_func_varnum_backup[i_var_user_func_backup]],varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl,varlist[0].sl); ngetchx();
		i_var_user_func_backup++;
	}
	
	argptr_return=argptr;		//sauvegarde le PC de retour
	argptr=argfunc[nf]+nb_arg*2;	//pointe à la première instruction de la fonction
	argptrf=argendfunc[nf]-3;

	while(argptr<argptrf) {(*(fonc[*(argptr)]))();}		//execute the instructions
	argptr=argptr_return;

	//Restore global variables
	for(ii=0;ii<nb_arg;ii++)
	{
		--i_var_user_func_backup;
		varlist[var_user_func_varnum_backup[i_var_user_func_backup]].sl=var_user_func_backup[i_var_user_func_backup];		//Affecte les variables passées en argument avec leur valeurs
	}
	
	rsl(rtn_value);
}

ans rtn(void)
{
	argptr++;
	rtn_value=getsl;
	argptr=999999;	//big number enough to force the loop breaking in fc()
}
/*
ans arg(void)
{
	argptr++;
//	rsl(argin[i_rtnf]);
}*/
ans group(void) //instancie une nilist et alloue un espace mémoire {long_nb_elem,long_elem1,long_elem2...}
{
	unsigned int num,i;
	long *mem;
	argptr++;
	if(*argptr!=216) exit2("Group expecting for nilist {}");
	argptr++;		//passe le tag nilist
	getsl;	//passe la taille
	num=getsl; //prend le nombre d'éléments de la nilist
	mem=malloc(num*4+4);
	if(!mem)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Group():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	mem[0]=num;
	for(i=0;i<num;i++)
	{
		mem[i+1]=getsl;
	}
	rpsl(mem);
}
ans ordd(void)
{
	unsigned char *strr;
	argptr++;
	strr=getpuc;
	rsl(strr[0]);
}
ans wb(void) //adress,elem,val
{
	char *a;
	int elem;
	long val;
	argptr++;
	a=getpuc;
	elem=getsl;
	val=getsl;
	*(a+elem)=val;
	rsl(val);
}
ans ww(void)
{
	int *a;
	int elem;
	long val;
	argptr++;
	a=getpuc;
	elem=getsl;
	val=getsl;
	*(a+elem)=val;
	rsl(val);
}
ans wl(void)
{
	long *a;
	int elem;
	long val;
	argptr++;
	a=getpuc;
	elem=getsl;
	val=getsl;
	*(a+elem)=val;
	rsl(val);
}

ans inter(void)  //format : inter(interupt_identificiator,speed(1=Max speed, 18:one time per second), {instruction1,instruction2,...}
{
	unsigned char id;
	unsigned long speed;
	argptr++;
	id=getsl; id++;
	if(id==1) //disable all newprog interupts
	{
		for(speed=1;speed<=21;speed++) {speedintr[speed]=0; /*argintr[id]=0;*/}
		getsl;
		if(*argptr==206) argptr=argyblock[*(argptr+2)];	//pass the x:y block
		else getsl;	//pass nilist or 0
	}
	else
	{
		speed=getsl;
		if(speed==0)		//Put in pause the interrupt
		{
			speedintr[id]=0;	 
		}
		else		//define/redefine the interrupt
		{
			speedintr[id]=speed;
			if(*argptr!=1 && *(argptr+1)!=0) 	//si !=0, pointe sur la nilist ou au x:y a executé, défini/redéfini la séquence d'instruction					
			{
				//printf("\ndans inter, id=%d speed=%d",id,speed);
				if(*argptr!=216 /*nilist*/&& *argptr!=206/*xb*/) exit2("Syntax:\nCase1:Assign an interrupt\ninter(Id!=0,tick!=0,X)\nX= {} or x::y\nCase2:Disable an interrupt\ninter(Id!=0,tick=0,X)\nX= Any types\nCase3:Disable all interrupts\ninter(Id=0,X,Y)\nX and Y = Any types.");						
				argintr[id]=argptr;
			}
			
		}
		//Pass the last argument
		if(*argptr==206/*xb*/) argptr=argyblock[*(argptr+2)];	//pass the block
		else (*(fonc[*(argptr)]))();		//pass the nilist or the 0
		
	}
	
}
/*
ans introff(void)
{
	argptr++;
	
	//Under, for grayscale purpose
	if(save_int_5==NULL)	//If the auto int1 has not been previously stopped by the user, stops it now
	{
		save_int_5 = GetIntVec (AUTO_INT_5);
		SetIntVec (AUTO_INT_5, DUMMY_HANDLER);   // redirect auto-int 1 to "nothing"	
	}	
	if(save_int_1==NULL)	//If the auto int1 has not been previously stopped by the user, stops it now
	{
		save_int_1 = GetIntVec (AUTO_INT_1);
		SetIntVec (AUTO_INT_1, DUMMY_HANDLER);   // redirect auto-int 1 to "nothing"	
	}
	
	//
	
	OSSetSR (0x0700);
}*/
/*
ans intron(void)
{
	argptr++;
	//Under, for grayscale purpose
	if(save_int_5)
	{
		SetIntVec (AUTO_INT_5, save_int_5);
		save_int_5=NULL;		//is useful later
	}
	if(save_int_1)
	{
		SetIntVec (AUTO_INT_1, save_int_1);
		save_int_1=NULL;		//is useful later
	}
	//
	
	OSSetSR (0x0000);
}*/

ans keyclear(void)
{
	argptr++;
	//printf("deb int1off");
	if(save_int_1==NULL)
	{
		save_int_1 = GetIntVec (AUTO_INT_1);
		SetIntVec (AUTO_INT_1, DUMMY_HANDLER);   // redirect auto-int 1 to "nothing"
		//printf("fin int1off");
	}
	
}
ans keydisp(void)
{
	argptr++;
	//printf("deb int1on");
	if(save_int_1)
	{
		SetIntVec (AUTO_INT_1, save_int_1);
		save_int_1=NULL;		//is useful later	
	}
	
	//printf("fin int1on");
}
ans freet(void)
{
	argptr++;
	rsl(OSFreeTimer (getsl));
}
ans sett(void)
{
	char timer_no;
	unsigned long init_val;
	argptr++;
	timer_no=getsl;
	init_val=getsl;
	OSFreeTimer (timer_no);
	rsl(OSRegisterTimer (timer_no, init_val));
}
ans texp(void)
{
	short timer_no;
	argptr++;
	timer_no=getsl;
	if(OSTimerExpired (timer_no)) rsl(1);
	else rsl(0);
}
ans tval(void)
{
	argptr++;
	rsl(OSTimerCurVal (getsl));
}
/*
ans int5off(void)
{
	argptr++;
	int5_allowed=0;
}
ans int5on(void)
{
	argptr++;
	int5_allowed=1;
}
*/
ans asm_cal(void)
{
	argptr++;
	ASM_call (getpuc);
}

/*ans setrate(void) //compilé mais elle n'avait pas d'influence sur la rapidité du int 5 !?!
{
	argptr++;
	EnablePRG();
	PRG_setRate (getsl);
}*/
ans lcdup(void)
{
	argptr++;
	OSContrastUp();
	rsl(OSContrastValue);
}
ans lcddown(void)
{
	argptr++;
	OSContrastDn();
	rsl(OSContrastValue);
}
ans printd(void)
{
	//long vv;
	argptr++;
	//vv=getsl;
	//printf("Valeur a afficher %ld\n",vv); ngetchx();
	printf("%ld",getsl);
}
ans printxy(void)
{
	short x,y;
	unsigned char *cptr;
	argptr++;
	x=getsl; y=getsl; cptr=getpuc;
	printf_xy (x, y, cptr, getsl);
}
ans idlee(void)
{
	argptr++;
	idle();
}
/*
ans scrrect(void)
{
	argptr++;
	scr_rect.xy.x0=getsl;
	scr_rect.xy.y0=getsl;
	scr_rect.xy.x1=getsl;
	scr_rect.xy.y1=getsl;
}*/
ans strlenn(void)
{
	argptr++;
	rsl(strlen(getpuc));
}
ans newstr(void)
{
	unsigned char *strr,*buff,varn;
	//unsigned long i,l;
	argptr++;
	strr=getpuc;
	varn=*(argptr+1);
	argptr+=2;
	//l=strlen(strr);
	buff=malloc(strlen(strr)+1);
	if(!buff)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Newstr():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	//for(i=0;i<(l+1);i++) *(buff+i)=*(strr+i);
	strcpy(buff,strr);
	varlist[varn].puc=buff;
	rpuc(buff);
}
ans seql(void)	//mapl(var,start,end,step,var_dest,instruction)
{
	unsigned char varnum,vardest;
	long st,en,ste,*p,*ptemp,i;
	ESI argdeb;
	argptr++;
	varnum=*(argptr+1);
	p=&varlist[varnum];
	byte_width_ilist[varnum]=4;	//Not very useful for seql because already initialise to 4 in main()
	argptr+=2;
	st=getsl;
	en=getsl;
	ste=getsl;
	vardest=*(argptr+1);
	byte_width_ilist[vardest]=4;
	argptr+=2;
	argdeb=argptr;
	i=0;
	if(((en-st)%ste)!=0) exit2("Seql error\n (end-start)/step\nis not an integer");
	if(((en-st)/ste)<0) return (ans)0;
	ptemp=malloc(4*((en-st)/ste+1)); //+1 for memory security : i.e. bad programmation, laught
	(varlist[vardest].puc)=ptemp;
	if(!ptemp)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seql():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	for(*p=st;*p!=en;*p+=ste)
	{
		*(ptemp+i)=(*(fonc[*(argptr)]))().sl;
		i++;
		argptr=argdeb;
	}
	rpuc (ptemp);
}
ans seqw(void)
{
	unsigned char varnum,vardest;
	long st,en,ste,*p,i;
	int *ptemp;
	ESI argdeb;
	argptr++;
	varnum=*(argptr+1);
	p=&varlist[varnum];
	argptr+=2;
	st=getsl;
	en=getsl;
	ste=getsl;
	vardest=*(argptr+1);
	byte_width_ilist[vardest]=2;
	argptr+=2;
		argdeb=argptr;
	i=0;
	if(((en-st)%ste)!=0) exit2("Seqw error\n (end-start)/step\nis not an integer");
	if(((en-st)/ste)<0) return (ans)0;
	ptemp=malloc(2*((en-st+1)/ste)+1); //+1 for memory security : i.e. bad programmation, laught
	(varlist[vardest].puc)=ptemp;
	if(!ptemp)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seqw():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	for(*p=st;*p!=en;*p+=ste)
	{
		*(ptemp+i)=(*(fonc[*(argptr)]))().sl;
		i++;
		argptr=argdeb;
	}
	rpuc (ptemp);
}
ans seqb(void)	//mapl(var,start,end,step,var_dest,instruction)
{
	unsigned char varnum,vardest;
	long st,en,ste,*p,i;
	char *ptemp;
	ESI argdeb;
	argptr++;
	varnum=*(argptr+1);
	p=&varlist[varnum];
	argptr+=2;
	st=getsl;
	en=getsl;
	ste=getsl;
	vardest=*(argptr+1);
	byte_width_ilist[vardest]=1;
	argptr+=2;
	argdeb=argptr;
	i=0;
	if(((en-st)%ste)!=0) exit2("seqb error\n (end-start)/step\nis not an integer");
	if(((en-st)/ste)<0) return (ans)0;
	ptemp=malloc((en-st)/ste+1);  //+1 for memory security : i.e. bad programmation, laught
	(varlist[vardest].puc)=ptemp;
	if(!ptemp)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seqb():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	for(*p=st;*p!=en;*p+=ste)
	{
		*(ptemp+i)=(*(fonc[*(argptr)]))().sl;
		i++;
		argptr=argdeb;
	}
	rpuc (ptemp);
}

ans loadasm(void)
{
	char *fptr, *cptr,file[18];
  unsigned short plen;
  File *fileptr;
  SYM_ENTRY *SymPtr;
  HANDLE h;
  argptr++;
  strcpy(file,getpuc);
  SymPtr = DerefSym (SymFind (SYMSTR (file)));
  if (!SymPtr) exit2("Asm file not found");
  h = SymPtr->handle;
  if (HeapGetLock (h))
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }
  plen = *(short*)(cptr) + 3;
  if (SymPtr->flags.bits.archived)
    {
      if (!(cptr = malloc (plen)))
        {
          if (h) HeapUnlock (h);
          exit2("Out of memory to load asm");
        }
      memcpy (cptr, fptr, plen);
    }
  
  if(!(fileptr=malloc(sizeof(File))))
  {
  	if (h) HeapUnlock (h);
  	if (cptr != fptr) free (cptr);
  	exit2("Memory error in loadasm");
  }
  enter_ghost_space ();
  EX_patch (cptr + 0x40002, cptr + plen + 0x3FFFE);
  fileptr->fptr=fptr;
  fileptr->cptr=cptr;
  fileptr->plen=plen;
  fileptr->h=h;
  rsl(fileptr);
}
ans execasm(void)
{
	File *fileptr;
	argptr++;
	fileptr=getpuc;
	//printf("\nDans execasm = %ld",(unsigned long)fileptr); ngetchx();
	ASM_call (fileptr->cptr + 0x40002);
}
ans closeasm(void)
{
	File *fileptr;
	argptr++;
	fileptr=getpuc;
	if (fileptr->h) HeapUnlock (fileptr->h);
  if (fileptr->cptr != fileptr->fptr) free (fileptr->cptr);
  free(fileptr);
}
ans strcmpp(void)
{
	char *s1,*s2;
	argptr++;
	s1=getpuc;
	s2=getpuc;
	rsl(strcmp(s1,s2));
}
ans strcpyy(void)
{
	char *dest,*source;
	argptr++;
	dest=getpuc;
	source=getpuc;
	rsl(strcpy(dest,source));
}


 
ans svscroff(void)
{
	argptr++;
	sv_scr_on=0;
	if(screen_buffer!=NULL) free(screen_buffer);
	//printf("Coucoulléllé"); ngetchx();
}



ans memcpyy(void)
{
	unsigned char *destt,*srcc,quotient;
	unsigned int lenn;
	argptr++;
	destt=getpuc;
	srcc=getpuc;
	lenn=getsl;
/*	if((quotient=((lenn-1)/384)))		//Is lenn>=385 ?
	{
		if((!((unsigned long)(srcc)%2) && (!((unsigned long)(destt)%2))))  //Are they both even address ?
		{	//Yes
			Fastmemcpy(srcc,destt,quotient-1);		//Fast copy assembly routine
			if(lenn%2) *(destt+lenn-1)=*(srcc+lenn-1);
			rpuc(destt);
		}
		//printf("Here memcpy"); ngetchx();
	}*/
	rpuc(memcpy(destt,srcc,lenn));		//if lenn<385, common memcpy function will be used

//	Fastmemcpy(src,dest,nbloop) __attribute__((__stkparm__));  // C prototype	Function written by me
	//memcpy(destt,srcc,lenn);
	//printf("Premiers bytes\norigine : %d\ncopier : %d",*srcc,*destt); ngetchx();
}
ans memmov(void)
{
	unsigned char *destt,*srcc;
	unsigned int lenn;
	argptr++;
	destt=getpuc;
	srcc=getpuc;
	lenn=getsl;
	rsl(memmove(destt,srcc,lenn));
}
ans randd(void)
{
	unsigned int rangee,rr;
	argptr++;
	rangee=getsl;
	rr=random(rangee);
	rsl(rr);
}
ans escc(void)
{
	argptr++;
	if(_keytest(RR_ESC)&_keytest(RR_ESC))
	{
		rsl(1);	
	}
	 else rsl(0);
	 //rsl((_rowread(~0b1000000) & _rowread(~0b1000000) & 0b1));
}
ans up(void)
{
	argptr++;
	if(_keytest(RR_UP)&_keytest(RR_UP))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans down(void)
{
	argptr++;
	if(_keytest(RR_DOWN)&_keytest(RR_DOWN))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans left(void)
{
	argptr++;
	if(_keytest(RR_LEFT)&_keytest(RR_LEFT))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans right(void)
{
	argptr++;
	if(_keytest(RR_RIGHT)&_keytest(RR_RIGHT))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans second(void)
{
	argptr++;
	if(_keytest(RR_2ND)&_keytest(RR_2ND))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans majj(void)
{
	argptr++;
	if(_keytest(RR_SHIFT)&_keytest(RR_SHIFT))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans diamond(void)
{
	argptr++;
	if(_keytest(RR_DIAMOND)&_keytest(RR_DIAMOND))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans alpha(void)
{
	argptr++;
	if(_keytest(RR_ALPHA)&_keytest(RR_ALPHA))
	{
		rsl(1);	
	}
	 else rsl(0);
}
ans gkey(void)
{
	unsigned short key;
	argptr++;
	if (!OSdequeue (&key, kbq))
	{
  	rsl(key);
	}
	rsl(0);
}
ans keydlay(void)
{
	unsigned int vv;
	argptr++;
	vv=getsl;
	rsl(OSInitKeyInitDelay (vv));
}
ans keysped(void)
{
	unsigned int vv;
	argptr++;
	vv=getsl;
	rsl(OSInitBetweenKeyDelay (vv));
}
ans llelem(void)		//load a list element
{
	unsigned char varnnn;
	unsigned int nelemm;
	argptr+=2;
	varnnn=*argptr;
	argptr++;
	nelemm=getsl;
	//printf("Byte width%d\nvarnn %d ; elem=%d",byte_width_ilist[varnnn],varnnn,nelemm); ngetchx();
	switch(byte_width_ilist[varnnn])
	{
		case 1:
		rsl(((varlist[varnnn]).psc)[nelemm]);
		break;
		case 2:
		rsl(((varlist[varnnn]).psi)[nelemm]);
		break;
		case 4:
		//printf("val[]=%ld",((varlist[varnnn]).psl)[nelemm]); ngetchx();
		rsl(((varlist[varnnn]).psl)[nelemm]);
		break;
		//case 10:		//for file and rep list, functions files and reps. Return a pointer.
		//rpuc(((varlist[varnnn]).puc)+nelemm*10);
		//break;
		//exit2("\nError in var[] function");
	}
	rpuc(((varlist[varnnn]).puc)+nelemm*byte_width_ilist[varnnn]);
	
	//printf("Dans llelem%d",nelemm); ngetchx();
}
ans gsprt(void)		//syntax : gsprt(pixel_width,num_line,"pic_var",sprt_var)
{
	unsigned char rval,cval,sprt_dest,iii;
	char *picvar;
	unsigned char *sprtt;
	//Files *fpic;
	unsigned char *pic_cptr;
	argptr++;
	cval=getsl;		//number of columns in byte (8,16 ot 32 only)
	rval=getsl;		//number of rows from 1 to TBD
	sprtt=malloc(cval*rval);
	if(!sprtt)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("gsprt():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	//if(sprtt==NULL) exit2("\nMemory Error in gsprt()");	
	if(*argptr!=STR_TAG) exit2("\ngsprt() syntax :\ngsprt(pixel_width,num_line,\n\"pic_var\",sprt_var)");
	picvar=getpuc;
	if(*argptr!=2) exit2("\ngsprt() syntax :\ngsprt(pixel_width,num_line,\n\"pic_var\",sprt_var)");
	sprt_dest=*(argptr+1);
	argptr+=2;
	varlist[sprt_dest]=(ans)sprtt;
	if(sprtt==0) rsl(0);
	//fpic=OpenFile(picvar);
	pic_cptr=OpenFile(picvar);
	if(pic_cptr==0) exit2("\ngsprt() syntax :\ngsprt(pixel_width,num_line,\n\"pic_var\",sprt_var)");

	switch(cval)		//Allow the user to use the []
	{
		case 1:
		case 8:
		byte_width_ilist[sprt_dest]=1;
		for(iii=0;iii<rval;iii++)
		{
			((char*)sprtt)[iii]=*((char*)((pic_cptr)+6)+iii);
		}
		break;
		case 2:
		case 16:
		byte_width_ilist[sprt_dest]=2;
		for(iii=0;iii<rval;iii++)
		{
			((int*)sprtt)[iii]=*((int*)((pic_cptr)+6)+iii);
		}
		break;
		case 4:
		case 32:
		byte_width_ilist[sprt_dest]=4;
		for(iii=0;iii<rval;iii++)
		{
			((long*)sprtt)[iii]=*((long*)((pic_cptr)+6)+iii);
		}
		break;
		printf("\ngsprt() syntax :\ngsprt(pixel_width,num_line,\n\"pic_var\",sprt_var)"); ngetchx();
	}
	//CloseOpenedFile(fpic);
	free(pic_cptr);	//ferme l'espace créé lors de OpenFile
	
	rsl(sprtt);	
}

ans savescr(void)
{
	unsigned char indexx;
//	int ii;
	long *ptrrr/*,*lcdaddd*/;
	argptr++;
	indexx=getsl;
	if(scr_copy[indexx]!=NULL)
	{
		if(indexx>4) goto savescr_error;
		ptrrr=scr_copy[indexx];
	}
	else
	{
		if(indexx>4) goto savescr_error;
		scr_copy[indexx]=(ptrrr=malloc(LCD_SIZE));		//If there is not yet a saved screen is this slot
		//if(!ptrrr) exit2("\nNot enough memory\n for saving screen.");
		if(!ptrrr)
		{
			if(disp_err)
			{
				if(ERD_dialog (ER_MEMORY, TRUE))
				{
					exit2("Savescr():Exit by pressing ENTER");
				}
			}
			rsl(0);
		}
	}
	
	FastCopyScreen(lcdad,ptrrr);
	rsl(ptrrr);
savescr_error:
	exit2("\nsavescr function,\nMaximum of 4 saved screens\nare allowed.\nOut of range : [0,3].");
/*
	for(ii=0;ii<(LCD_SIZE/4);ii++)		//copy l'écran
	{
		ptrrr[ii]=lcdaddd[ii];
	}
*/
}

ans loadscr(void)
{
	unsigned char indexx;
//	int ii;
	long *ptrrr/*,*lcdaddd*/;
	argptr++;
	//lcdaddd=lcdad;
	indexx=getsl;
	if(indexx>4) exit2("\nsavescr function,\nMaximum of 4 saved screens\nare allowed.\nOut of range : [0,3].");
	ptrrr=scr_copy[indexx];
	
	if(ptrrr)
	{
		FastCopyScreen(ptrrr,lcdad);
	}
	rsl(ptrrr);
}
ans newline(void)
{
	argptr++;
	printf("\n");
}
ans files(void)
{
	int counter;
	SYM_ENTRY *SymPtr;
	unsigned char *rep,*names,vardest;
	argptr++;
	rep=getpuc;
	if(*argptr!=2) exit2("Format error : files(rep_str,var_dest)");
	vardest=*(argptr+1);
	byte_width_ilist[vardest]=10;	
	names=malloc(500);
	if(!names)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Reps():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	counter=0; 
	//*(unsigned int*)names=counter;		
	SymPtr = SymFindFirst (SYMSTR (rep), FO_SINGLE_FOLDER);
	while (SymPtr)
	{
 	 /**(unsigned int*)names=*/++counter;	//les 4 premiers octets indique le nombre de fichiers
 	 if(counter>=98) {exit2("Too much files in repertory (98 max)"); break;}
 	 //printf(" %s",SymPtr->name);
 	 strcpy (names + (counter-1)*10, SymPtr->name);
 	 SymPtr = SymFindNext ();
	}
	strcpy (names + (counter)*10, "0"); //A termination tag, not necessary because this function returns the number of fille contained in the rep
	names=realloc(names, (counter+1)*10);
	(varlist[vardest].puc)=names;
	rsl(counter);
}
ans reps(void)
{
	int counter;
	SYM_ENTRY *SymPtr;
	unsigned char *rep,*names,vardest;
	argptr++;
	//rep=getpuc;
	if(*argptr!=2) exit2("Format error : reps(rep_str,var_dest)");
	vardest=*(argptr+1);
	byte_width_ilist[vardest]=10;	
	names=malloc(500);
	if(!names)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Reps():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	counter=0; 
	//*(unsigned int*)names=counter;		
	SymPtr = SymFindFirst (NULL, 0);
	while (SymPtr)
	{
 	 /**(unsigned int*)names=*/++counter;	//les 4 premiers octets indique le nombre de fichiers
 	 if(counter>=98) {exit2("Too much reps (98 max)"); break;}
 	 //printf(" %s",SymPtr->name);
 	 if(strcmp(SymPtr->name,"0001")==0) SymPtr = SymFindNext ();
 	 strcpy (names + (counter-1)*10, SymPtr->name);
 	 SymPtr = SymFindNext ();
	}
	//names=realloc(names, 2 + (counter-1)*10 + 10);
	strcpy (names + (counter)*10, "0"); //A termination tag, not necessary because this function returns the number of fille contained in the rep
	names=realloc(names, (counter+1)*10);	//ne devrait pas retourner d'erreur car sera plus petit que l'original
	(varlist[vardest].puc)=names;
	rsl(counter);
}
void pass_block(void)	//De préférence, utiliser la macro PASS_BLOCK car plus rapide en macro qu'en fonction
{
	/*ESI argptrend;
	argptr++;
	argptrend=argyblock[*(argptr+1)]-4;
	while(argptr<=argptrend) (*(fonc[*(argptr)]))();*/
	argptr=argyblock[*(argptr+2)];	//passe le block
}
ans xb(void)
{
	ESI argptrend,esi_deb;
	ans rr;
	argptr+=3;
	esi_deb=argptr;	//nécessaire pour vérifier que l'on est toujours dans le bloc. Préviens des problèmes avec des sauts avec goto par exemple.
	argptrend=argyblock[*(argptr-1)]-3;
			//	printf("Y num=%d",*(argptr+2));
	while(argptr>= esi_deb && argptr<argptrend) rr=(*(fonc[*(argptr)]))();		//De cette manière, si un goto est exécuté et qui fait sortir argptr du block, alors l'exécution du block s'achève de lui même
	rsl(rr.sl);	//return the value of the last executed instruction
}
ans yb(void)		//In normal use, this function should be never called
{
	argptr+=3;
}
ans i(void)
{
	ESI argptrend;
	//ans rr;
	//long cond,ii;
	//for(ii=0;ii<8;ii++) printf("%d ",*(argptr+ii));
	//ngetchx();
	//argptr++;
	argptrend=argyblock[*(argptr+2)]-4;
	//printf("%ld",argptrend); ngetchx();
	argptr+=3;	//pointe maintenant sur la condition
	//cond=getsl;
	//printf("cond %ld",cond); ngetchx();
	/*if(getsl) {while(argptr<=argptrend) (*(fonc[*(argptr)]))();}
	else argptr=argptrend+4;*/
	if(!getsl) argptr=argptrend+4;
}
ans forr(void)	//fonction à 3 arguments
{
	unsigned long vdest;
	long lim,step;
	unsigned char varn;
	argptr+=5;
	//varn=*(argptr-3);
//	printf("Identifiant boucle : %d",varn); ngetchx();
	//vdest=*(argptr-1);
//	printf("Identifiant variable : %d",vdest); ngetchx();
	//argptr+=2;
	(varlist[*(argptr-1)].sl)=getsl;	//valeur de départ
//	printf("Valeur de départ : %ld",varlist[vdest].sl); ngetchx();
	//printf("argptr à lim = %lp",argptr); ngetchx();
	/*lim=*/getsl;
	/*step=*/getsl;
//	printf("Valeur limite : %ld",lim); ngetchx();
//	printf("\nStep : %ld",step); ngetchx();
	//if((varlist[vdest].sl)==(lim+step)) {argptr=argendfor[varn]; /*printf("condition de fin"); ngetchx();*/}		//condition qui peut éviter des plantages à mon avis
	//else getsl;	//passe le step
}
ans eforr(void)
{
	long _step,_lim;
	unsigned char _vdest,_nefor;
	ESI tmpesi;
	argptr+=3;
	_nefor=*(argptr-1);//identifiant de la boucle for endfor
//		printf("Dans Endfor : Identifiant boucle : %d",_nefor); ngetchx();
	_vdest=varnfor[_nefor];	//La variable à faire évoluer
	tmpesi=argptr;	//sauvegarde du PC
//	printf("\nDans endfor0 : *argptr=%d et argptr=%lp",*(char*)argptr,argptr); ngetchx();
	argptr=argfor[_nefor];	//saute au for pour lire la limite et le pas
	//printf("\nDans endfor1 : *argptr=%d et argptr=%lp",*(char*)argptr,argptr); ngetchx();
	_lim=getsl;
		//printf("\nValeur limite : %ld",_lim); ngetchx();
//		printf("\nDans endfor2 : *argptr=%ld et argptr=%lp",*argptr,argptr); ngetchx();
	_step=getsl;
	//printf("\nStep : %ld",_step); ngetchx();
//		printf("\nDans endfor2-2 : *argptr=%ld et argptr=%lp",*argptr,argptr); ngetchx();
	if((varlist[_vdest].sl/*+_step*/)!=_lim) 
	{
//		printf("condition de fin non atteinte"); ngetchx();
		varlist[_vdest].sl+=_step;
	}
	else argptr=tmpesi;	//retourne à l'endroit du endfor et sort de la boucle, la condition de fin étant atteinte
//	printf("\nDans endfor3 : *argptr=%ld et argptr=%lp",*argptr,argptr); ngetchx();
}
ans catalog(void)
{
	EVENT ev;
  static char varlink_return[20];
  long rr;
  ptr = NULL;
  handle = H_NULL;

	argptr++;

  EV_captureEvents (Handler);
  CAT_dialog ();
  TRY
    EV_eventLoop ();
  ONERR
    EV_captureEvents (NULL);
  ENDTRY
  if (handle != H_NULL)
    ptr = HLock (handle);
  if (ptr != NULL)
  {
    strcpy(varlink_return,ptr);
    //sprintf (varlink_return, "You selected \"%s\".", ptr);
    //ST_helpMsg (varlink_return);
    rr=varlink_return;
  }
  else /*ST_helpMsg ("You pressed ESC.");*/ rr=0;
  if (handle != H_NULL)
    HeapFree (handle);
  //ev.Type = CM_UNFOCUS;               // This is more due to some
  //EV_sendEvent (AP_CURRENT, &ev);     // aesthetical reasons
	rsl(rr);
}
ans open(void)		//retourne la string du fichier sélectionné, étant un nom complet rep\var_name
{
	static unsigned char open_return[18];
	unsigned char ii,narg,esqtemp,*esq2,ESQ_list[11],*oth_str[6],nb_oth;
	argptr++;
	nb_oth=0;
	for(ii=0;ii<11;ii++) ESQ_list[ii]=0;
	if(*argptr==216)	//si l'argument est une nilist
	{
		argptr++;	//passe le tag de nilist
		getsl;	//passe la taille des éléments ; cet argument ne doit pas être utile je pense l'usage qu'on fait d'une nilist	
	  narg=getsl;	//le nombre d'éléments de la nilist	
 	 if(narg>10) exit2("In open() : Too much element in nilist");
	  for(ii=0;ii<narg-nb_oth;ii++)
	  {
	  	esqtemp=getsl;
	  	//printf("%d",esqtemp); ngetchx();
	  	ESQ_list[ii]=esqtemp;
	  	if(esqtemp==OTH_TAG)
	  	{
	  		//++ii;
	  		if(*argptr!=STR_TAG) exit2("Open():String expected after othtag");
	  		nb_oth++;
	  		oth_str[ii]=getpuc;
	  		//exit2("In open() : othtag forbiden");	
	  	}
	  	
	  }
	  //ESQ_list[ii+1]=0;
	  esq2=ESQ_list;
	}
	else esq2=getpuc;
  for(ii=0;ii<18;ii++)	open_return[ii]=0;
  if(!HSYMtoName (VarOpen (esq2,oth_str), open_return)) rsl(0);
  rpuc(open_return);
}
ans mod(void)
{
	long a1;
	argptr++;
	a1=getsl;
	rsl(a1%getsl);
}
ans strcat2(void)
{
	static unsigned char strcat2_return[50];
	unsigned char *src1,*src2,temp_str[50]/*,temp_str2[50]*/;
	argptr++;
	
	//Programme ci dessous dédié à la compatibilité de la fonction lorsque deux string() sont en argument
	/*
	if(*argptr==212)		//si c'est la fonction string
	{
		src1=getpuc;	//string a jouter à dest
		if(*argptr==212)
		{
			//temp_str2=malloc(50);		//se prépare à mémoriser le premier argument
			//if(temp_str2==NULL) exit2("Memory error");
			strcpy(temp_str,src1);	//copy la première évaluation de string() car elle sera effacée par le prochain appel pour la lecture du second argument
			src1=temp_str;
		}
		goto is_not_string_string;
	} 
	*/
	src1=getpuc;	//string a ajouter à dest
//is_not_string_string:
	src2=getpuc;	//string dest
	
	if(src2==strcat2_return) rpuc(strcat(strcat2_return,src1));
	if(src1==strcat2_return)
	{
		//temp_str=malloc(50);
		//if(temp_str==NULL) exit2("Memory error");
		strcpy(temp_str,strcat2_return);
		strcat2_return[0]=0;
		strcat(strcat2_return,src2);
		strcat(strcat2_return,temp_str);
		//free(temp_str);
		rpuc(strcat2_return);
	}
	else
	{
		strcat2_return[0]=0;
		strcat(strcat2_return,src2);
		//if(is_double_string_temporary_func) free(src1);
		rpuc(strcat(strcat2_return,src1));
	}
}
ans exprr(void)		//pour de la rapidité, utiliser atol
{
	long s,n;
	ESI argptr_end;
	ans rr;
	argptr++;
	switch(*argptr)
	{
		case 45:	//c'est une string enregistrée dans le fichier
		case 2:
		rsl(atol(getpuc));
		break;
		case 1:
		case 37:
		case 38:
		rsl(getsl);
		break;
		case 216:	//exécute la nilist
		argptr++;
		s=getsl;
		n=getsl;
		argptr_end=argptr+s;
		while(argptr<argptr_end) rr=((*(fonc[*(argptr)]))());		
		rsl(rr.sl);	
		break;
		case 206:		//x:y block
		rsl(getsl);
		break;
	}
	rsl(getsl);
}
ans stringg(void)		//ne garde en mémoire que temporairement le résultat en string (jusqu'au prochain appel de la fonction)
{
	static unsigned char stringg_return[12*4+1];	//les unsigned long ont jusqu'à 10 chiffres ; penser au signe moins si négatif
	argptr++;
	if(!(stringg_return[0]>2)) stringg_return[0]++;
	else stringg_return[0]=0;
	sprintf(stringg_return+stringg_return[0]*12+1,"%ld",getpuc);
	rpuc(stringg_return+stringg_return[0]*12+1);	
	
}
ans lscroll4(void)
{
	unsigned char nbline,i,temp1;
	unsigned char *lcdad_temp;
	register unsigned char decal;
	unsigned long templ,andvl;
	unsigned int andvi;
	argptr++;
	nbline=getsl;
	decal=getsl;
	andvl=0b11111111111111111111111111111111;
	andvi=0b1111111111111111;
	andvl=~(andvl>>decal);		//mask
	andvi=~(andvi>>decal);		//mask
	temp1=32-decal;

		for(i=0;i<=nbline;i++)
		{
			lcdad_temp=lcdad+30*i;
			*(unsigned long*)(lcdad_temp)=(((*(unsigned long*)(lcdad_temp))<<decal) | ((*(unsigned long*)(lcdad_temp+4))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+4)=(((*(unsigned long*)(lcdad_temp+4))<<decal) | ((*(unsigned long*)(lcdad_temp+8))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+8)=(((*(unsigned long*)(lcdad_temp+8))<<decal) | ((*(unsigned long*)(lcdad_temp+12))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+12)=(((*(unsigned long*)(lcdad_temp+12))<<decal) | ((*(unsigned long*)(lcdad_temp+16))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+16)=(((*(unsigned long*)(lcdad_temp+16))<<decal) | ((*(unsigned long*)(lcdad_temp+20))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+20)=(((*(unsigned long*)(lcdad_temp+20))<<decal) | ((*(unsigned long*)(lcdad_temp+24))&andvl)>>(temp1));
			*(unsigned long*)(lcdad_temp+24)=(((*(unsigned long*)(lcdad_temp+24))<<decal) | ((*(unsigned int*)(lcdad_temp+28))&andvi)>>(temp1));
			*(unsigned int*)(lcdad_temp+28)<<=decal;
		}

}
ans b(void)		//skip the b block
{
	unsigned char var;
	ESI argptr_return;
	unsigned int nbelemm;
	argptr+=3;
	var=*(argptr-1);
	nbelemm=getsl;
//	printf("*argptr=%d",*argptr); ngetchx();
	//if(*argptr==0xE5) argptr++; //in the case of an not even adress
	if(((unsigned long)argptr%2)==1) argptr++;	
	varlist[var].sl=argptr;
	argptr_return=argptr;
	argptr+=nbelemm;	//skip the data and the y
	rpuc(argptr_return);
}
ans w(void)
{
	unsigned char var;
	ESI argptr_return;
	unsigned int nbelemm;
	argptr+=3;
	var=*(argptr-1);
	nbelemm=getsl;
	if(((unsigned long)argptr%2)==1) argptr++;	//in the case of an not even adress
	varlist[var].sl=argptr;
	argptr_return=argptr;
	argptr+=nbelemm*2;	//skip the y
	rpuc(argptr_return);
}
ans l(void)
{
	unsigned char var;
	ESI argptr_return;
	unsigned int nbelemm;
	argptr+=3;
	var=*(argptr-1);
	nbelemm=getsl;
	if(((unsigned long)argptr%2)==1) argptr++;	//in the case of an not even adress
	varlist[var].sl=argptr;
	argptr_return=argptr;
	argptr+=nbelemm*4;	//skip the y
	//printf("%ld",argptr_return);ngetchx();
	rpuc(argptr_return);
	//printf("*(argptr-1) %d",*(argptr-1)); ngetchx();
}

ans prettyxy(void)	//Syntax prettyxy,
{
	unsigned char xxx,yyy,*expr_str;
	argptr++;
	xxx=getsl;
	yyy=getsl;
	expr_str=getpuc;
	TRY
    //reset_control_flags();
    push_parse_text (expr_str);
    NG_rationalESI (top_estack);
    //WinClr (&wind);
    Print2DExpr (Parse2DExpr (top_estack, FALSE), &wind, xxx, yyy);
    //reset_control_flags();
    rsl(1);
  ONERR
    rsl(0);
  ENDTRY

}
ans getwbt(void)
{
	unsigned char ww,bb,tt,*expr_str;
	short wp,bp,tp;
	argptr++;
	expr_str=getpuc;
	if(*(argptr)!=2 || *(argptr+2)!=2 || *(argptr+4)!=2) exit2("Syntax : getwbt(wide_var,\nbottom_var,top_var,expr_ptr)");

	ww=*(argptr+1);
	bb=*(argptr+3);
	tt=*(argptr+5);

	argptr+=6;
	//expr_str=getpuc;
	TRY
    //reset_control_flags();
    push_parse_text (expr_str);
    //NG_rationalESI (top_estack);
    //WinClr (&wind);
    Parse2DExpr (top_estack, FALSE);
    Parms2D (top_estack, &wp, &bp, &tp);
    varlist[ww].sl=wp;
    varlist[bb].sl=bp;
    varlist[tt].sl=tp;
    //Print2DExpr (Parse2DExpr (top_estack, FALSE), &wind, xxx, yyy);
    rsl(1);
  ONERR
    rsl(0);
  ENDTRY
	
	 
	
}
ans cwidth(void)
{
	argptr++;
	rsl(FontCharWidth (getsl));
}
ans settype(void)
{
	unsigned char old_ttyyppee,var;
	unsigned int ttyyppee;
	argptr+=3;
	var=*(argptr-1);
	//ttyyppee=getsl;
	old_ttyyppee=byte_width_ilist[var];
	ttyyppee=getsl;
	//printf("La var num %d, data_size (tpe)=%d   1",var,ttyyppee); ngetchx();
	if(ttyyppee==0)
	{
			//nop	
	}
	else
	{
		//printf("La var num %d, data_size (tpe)=%d   2",var,ttyyppee); ngetchx();
		byte_width_ilist[var]=ttyyppee;
	}
	rsl(old_ttyyppee);	
}
ans movto(void)
{
	unsigned int xx;
	argptr++;
	xx=getsl;
	MoveTo(xx,getsl);
}
ans pause(void)
{
	argptr++;
	printf("\n%s\n",getpuc); 
	if(save_int_1)		//for avoiding crash with keyclear()=>Restore auto int1
	{
		SetIntVec (AUTO_INT_1, save_int_1);
		save_int_1=NULL;		//is useful later	
	}
	rsl(ngetchx());
}

ans seqs(void)
{
	unsigned char var,*tivar,*p_expr,*p_eval;
	long strt,endd,stepp;
	unsigned int ii,nbelem,data_dim;
	HANDLE handle;
	//ESI sp1;
	argptr++;
	data_dim=4;	//comprend les tag et les octets de la taille en mémoire
	if(*argptr!=2) exit2("Syntax : seqs(var,start,\nend,step,var_dest_str,string_ptr");
	var=*(argptr+1);
	argptr+=2;
	strt=getsl;
	endd=getsl;
	stepp=getsl;
	tivar=getpuc;
	p_expr=argptr;
	nbelem=0;
	for(varlist[var].sl=strt; varlist[var].sl<=endd; varlist[var].sl+=stepp)
	{
		p_eval=getpuc;	//string à copier dans le fichier
		data_dim+=(strlen(p_eval)+3);
		argptr=p_expr;
		push_zstr (p_eval);
		nbelem++; 
	}

	handle = CreateFile_with_specified_size (tivar,data_dim+10);		//+10 étant une marge d'erreur éventuelle
	if(!handle)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seqs():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	
	AppendCharToFile(handle,END_TAG);

	//for inverting list
	for(ii=0;ii<nbelem;ii++)
	{
		p_eval=GetStrnArg (top_estack); 
		AppendCharToFile(handle,0);
		AppendBlockToFile (handle, p_eval, strlen(p_eval)+1);
		AppendCharToFile(handle,STR_TAG);

	}
	
	CloseFile_type (handle,LIST_TAG);
	rsl(nbelem);
	
}
ans seqe(void)
{
	unsigned char var,*tivar,*p_expr,type;
	long strt,endd,stepp,value;
	unsigned int ii,nbelem;
	HANDLE handle;
	ESI sp1,sp2,sp3;
	argptr++;
	if(*argptr!=2) exit2("Syntax : seqe(var,start,\nend,step,var_dest_str,value");
	var=*(argptr+1);
	argptr+=2;
	strt=getsl;
	endd=getsl;
	stepp=getsl;
	tivar=getpuc;
	p_expr=argptr;
	nbelem=0;
	for(varlist[var].sl=strt; varlist[var].sl<=endd; varlist[var].sl+=stepp)
	{
		value=getsl;	//string à copier dans le fichier
		argptr=p_expr;
		push_longint (value);
		nbelem++; 
	}
	handle = CreateFile_with_specified_size (tivar,4+nbelem*6);
	if(!handle)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seqe():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	
	AppendCharToFile(handle,END_TAG);
	for(ii=0;ii<nbelem;ii++)
	{
		sp2=next_expression_index(top_estack)+1;
		sp3=sp2-1;	//pointe sur la prochaine valeur
		while(sp2!=(top_estack+1))
		{
			AppendCharToFile(handle,*sp2);
			sp2++;
		}
		top_estack=sp3;	//pointe sur la prochaine valeur
	}
	
	CloseFile_type (handle,LIST_TAG);
	rsl(nbelem);	
}
unsigned char *save_main_npp_state(unsigned char sub_nb_var, unsigned char sub_nb_def_fonc)
{
	unsigned int srcsize,nintr,sintr,iintr,byte_width_ilist[256];		//changer le 256 avec nbvar de la fonction lue3
	unsigned char *srcptr,inc,sv_scr_on,*screen_buffer,nbvar_main;
	long condswitch[5],rtnf[30],argin[30]; //retour des fonctions inlines : imbrication max de 30 appels . Entrée fonction inline
	unsigned char i_rtnf,i_intr,varnfor[50];
	//HANDLE handle;
	ESI argptr,argdep,tmpesi,argintr[21],speedintr[21],intrdeb,argfunc[30],argendfunc[30],arglbl[256],argwhile[NB_WHILE],argendwhile[NB_WHILE],argfor[NB_FOR],argendfor[NB_FOR],argelse[257],argendif[257],argyblock[50];
	void *kbq;		//For the function gkey()

	malloc(sizeof(srcsize)+sizeof(nintr)+sizeof(sintr)+sizeof(iintr)	//unsigned int : two bytes long
				+sizeof(byte_width_ilist)+sizeof(srcptr)+sizeof(screen_buffer)+sizeof(rtnf)+sizeof(argin)+sizeof(varnfor)		//4 bytes long
				+sizeof(argptr)+sizeof(argdep)+sizeof(tmpesi)+sizeof(argintr)+sizeof(speedintr)+sizeof(intrdeb)+sizeof(argfunc)+sizeof(argendfunc)+sizeof(arglbl)+sizeof(argwhile)		//4 bytes long
				+sizeof(argendwhile)+sizeof(argfor)+sizeof(argendfor)+sizeof(argelse)+sizeof(argendif)+sizeof(argyblock)+sizeof(kbq)		//4 bytes long
				+sizeof(inc)+sizeof(sv_scr_on)+sizeof(nbvar_main));	//one byte long

//A sauvegardée en variable simple :
//2 bytes long - no array
//unsigned int srcsize : taille du fichier main exécuté
//unsigned int nintr : nombre de commandes présentes dans la nilist d'interruption
//unsigned int sintr : donnée qui n'est pas utilisée mais sauvegardée tout de même
//unsigned int iintr : index de l'élément exécuté dans la nilist d'interruption

//4 bytes long - no array
//unsigned char* srcptr : pointeur du programme main NPP
//unsigned char* screen_buffer	:	pointeur sur copie simple de l'écran
//ESI argptr : position du PC du programme principal
//ESI argdep : pointeur de base du programme NPP principal : indispensable pour la libération de la mémoire à la fin du programme
//ESI tmpesi : variable utilisées pour lire le pas et la valeur de fin dans endfor ; à sauvegarder obligatoirement
//ESI intrdeb : sauvegarde du Pc avant l'exécution des nilist d'interruptions

//1 bytes long - no array
//unsigned char inc : valeur incrémenter tous les 1/20 sec. Elle sert à effectuer un modulo. Ne pas sauvegarder.
//sv_scr_on : Sauvegarde ou non de l'écran principal. Ne pas sauvegarder car ce serait trop couteux en mémoire de sauvegarder n écrans.
//nbvar_main : nombre de variables du programme appelant.

//4 bytes long - Array []	A FAIRE
//ESI* argintr : tableau de pointeur sur nilist d'interruptions

//speed intr


//i_rtnf : fonction définie (avec def()) actuellement exécutée : 1 pour une fonction en cours d'exécution ; 0 pas de fonction exécutée


//Attention : Dans exec non stop secured : 	arg_enddd=argdep+srcsize;

}

void restore_main_npp_state(unsigned char *state_ptr)
{
	
}
ans execnpp(void)
{
	unsigned char sub_nb_var,sub_nb_def_fonc,*sub_npp_str,*saved_main_argptr/*,*state_copy*/;
	char *fptr, *cptr;
	unsigned short sub_plen,sub_srcsize;
	long *sub_varlist_ptr;
	ans *main_varlist_ptr;
	File *fileptr;
	SYM_ENTRY *SymPtr;
  HANDLE h;
  
	argptr++;
	sub_npp_str=getpuc;
	saved_main_argptr=argptr;
	
	
  //printf("\n Compiled with version : %d",*((unsigned char*)(f->base)+srcsize+1-6)); ngetchx();
  SymPtr = DerefSym (SymFind (SYMSTR (sub_npp_str)));
  if (!SymPtr) exit2("NPP file not found");
  h = SymPtr->handle;
  if (HeapGetLock (h))
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }
  sub_plen = *(short*)(cptr) + 3;
  if (SymPtr->flags.bits.archived)
    {
      if (!(cptr = malloc (sub_plen)))
        {
          if (h) HeapUnlock (h);
          exit2("Out of memory to load NPP");
        }
      memcpy (cptr, fptr, sub_plen);
    }
  
  sub_srcsize=*(unsigned int*)(cptr);	//srcsize=size of data without first two bytes
  sub_nb_def_fonc=*(cptr+sub_srcsize+1-8);
  sub_nb_var=*(cptr+sub_srcsize+1-7);
	//clrscr();
  printf("sub NPP nb var %d",sub_nb_var); ngetchx();
  
  argptr=cptr+2;	//jumps to the subfunction
  main_varlist_ptr=varlist;
  //sub_varlist_ptr=&(varlist[nbvar_main]);
  
  varlist=&(varlist[nbvar_main]);
  
  while(argptr<(cptr+sub_srcsize))
  {
  	//(*(fonc[*(argptr)]))();
  	printf("\n*argptr=%x &=%x %s",*argptr,(int)(argptr-argdep+2),foncs[*argptr]); ngetchx();
		(*(fonc[*(argptr)]))();
  }
  
  argptr=saved_main_argptr;		//restore main PC
  varlist=main_varlist_ptr;
  //state_copy=save_main_npp_state(sub_nb_var,sub_nb_def_fonc);
  
  
  
	//Close the file
  if (h) HeapUnlock (h);
  if (cptr != fptr) free (cptr);  
}

ans sprt82(void)	//print a sprite and return if there is a collision detected : no display if collision
{
	unsigned char gsprite_buf[128],*sprite,rr;
	short x,y,ii;
	unsigned int height;
	argptr++;
	x=getsl;
	y=getsl;
	height=getsl;
	sprite=getpuc;
	ClipSprite8Get_R(x,y,height,gsprite_buf,lcdad);
	//if(!memcmp (sprite, gsprite_buf, height)) rsl(1);
	//else rr=0;
	for(ii=0;ii<height;ii++)		//compare sprites
	{
		if(gsprite_buf[ii]&sprite[ii])
		{
			//printf_xy(0,0,"Collision  ",0);
			//rsl(0|(height<<24)|gsprite_buf[ii]);
			//rsl(1);
			sprt2_return[0]=ii;
			sprt2_return[1]=(signed long)((signed char)(gsprite_buf[ii]));
			rpuc(sprt2_return);
		}

	}
	//rr=TestCollide8(0,0,0,0,height,gsprite_buf,sprite);
	//printf("gsprite_buf[0]= %d, rr=%d",gsprite_buf[0],rr); ngetchx();
	switch(gmode)
	{
		case 2:	//xor
		ClipSprite8_XOR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 3:		//AND
		ClipSprite8_AND_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 0:	//or
		ClipSprite8_OR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 1:	//blank
		ClipSprite8_RPLC_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
	}	
	rsl(0);
}
ans sprt162(void)		//print a sprite and return if there is a collision detected : no display if collision
{
	unsigned int gsprite_buf[128];
	short x,y,ii;
	unsigned int height,*sprite;
//	long rr;
	argptr++;
	x=getsl;
	y=getsl;
	height=getsl;
	sprite=getpuc;
	ClipSprite16Get_R(x,y,height,gsprite_buf,lcdad);
	//printf_xy(0,0,"No Collision  ",0);

	//ClipSprite16_RPLC_R(70,10,height,sprite,lcdad);
	//ClipSprite16_RPLC_R(45,10,height,gsprite_buf,lcdad);

	for(ii=0;ii<height;ii++)		//compare sprites
	{
		if(gsprite_buf[ii]&sprite[ii])
		{
			//printf_xy(0,0,"Collision  ",0);
			//rsl(1);
			//rsl(0|(height<<24)|gsprite_buf[ii]);
			sprt2_return[0]=ii;
			sprt2_return[1]=gsprite_buf[ii];
			rpuc(sprt2_return);
		}

	}
	//if(!memcmp (sprite, gsprite_buf, height*2)) rsl(1);
	//else rr=0;
	//if(rr=TestCollide16(0,0,0,0,height,gsprite_buf,sprite)) rsl(1);
	//printf("gsprite_buf[0]= %d, rr=%d",gsprite_buf[0],rr); ngetchx();
	switch(gmode)
	{
		case 2:	//xor
		ClipSprite16_XOR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 3:		//AND
		ClipSprite16_AND_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 0:	//or
		ClipSprite16_OR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 1:	//blank
		ClipSprite16_RPLC_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
	}	
	rsl(0);
}
ans sprt322(void)
{
	short x,y,height,ii;
	unsigned long *sprite,rr,gsprite_buf[128];
	//void *video_mem;
	argptr++;
	x=getsl;
	y=getsl;
	height=getsl;
	sprite=getpuc;
	
	ClipSprite32Get_R(x,y,height,gsprite_buf,lcdad);
	//if(!memcmp (sprite, gsprite_buf, h*4)) rsl(1);
	//else rr=0;
	
	for(ii=0;ii<height;ii++)		//compare sprites
	{
		if(gsprite_buf[ii]&sprite[ii])
		{
			//printf_xy(0,0,"Collision  ",0);
			//rsl(0|(height<<24)|gsprite_buf[ii]);
			sprt2_return[0]=ii;
			sprt2_return[1]=(((0b11111111000000000000000000000000&gsprite_buf[ii])>>16)|(0b11111111&gsprite_buf[ii]));		//prend que les coins
			rpuc(sprt2_return);
		}

	}
	//video_mem=getsl;

	switch(gmode)
	{
		case 2:	//xor
		ClipSprite32_XOR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 3:		//AND
		ClipSprite32_AND_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 0:	//or
		ClipSprite32_OR_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		case 1:	//blank
		ClipSprite32_RPLC_R(x,y,height,sprite,lcdad);	rsl(0);
		break;
		
	}
	rsl(0);
}
ans next(void)
{
	long _lim,_step;
	unsigned char _nefor,_vdest;
	//argptr+=3;	//pointe sur l'identifiant de la boucle for ou while
	ESI tmp_esi;
	argptr+=5;		
	if(*(argptr-3)==1)		//for loop
	{
		//printf("c'est un for"); ngetchx();
		//argptr+=3;
		_nefor=*(argptr-1);//identifiant de la boucle for endfor
		//		printf("Dans Endfor : Identifiant boucle : %d",_nefor); ngetchx();
		_vdest=varnfor[_nefor];	//La variable à faire évoluer
						//tmpesi=argptr;	//sauvegarde du PC
		//	printf("\nDans endfor0 : *argptr=%d et argptr=%lp",*(char*)argptr,argptr); ngetchx();
		argptr=argfor[_nefor];	//saute au for pour lire la limite et le pas
		//printf("\nDans endfor1 : *argptr=%d et argptr=%lp",*(char*)argptr,argptr); ngetchx();
		_lim=getsl;
		//		printf("Valeur limite : %ld",_lim); ngetchx();
		//		printf("\nDans endfor2 : *argptr=%ld et argptr=%lp",*argptr,argptr); ngetchx();
		_step=getsl;
		//		printf("\nDans endfor2-2 : *argptr=%ld et argptr=%lp",*argptr,argptr); ngetchx();
		if((varlist[_vdest].sl/*+_step*/)!=_lim) 
		{
		//		printf("condition de fin non atteinte"); ngetchx();
			varlist[_vdest].sl+=_step;
		}
		else argptr=argendfor[_nefor];	//retourne à l'endroit du endfor et sort de la boucle, la condition de fin étant atteinte
	}
	else	//while loop
	{
		//printf("c'est un while"); ngetchx();
		//var=*(argptr+1);
		argptr=argwhile[*(argptr-1)];	
	}
}
ans breakk(void)
{
	argptr+=5;		
	if(*(argptr-3)==1)		//for loop
	{
		argptr=argendfor[*(argptr-1)];	//retourne à l'endroit du endfor et sort de la boucle, la condition de fin étant atteinte
	}
	else	//while loop
	{
		argptr=argendwhile[*(argptr-1)];	
	}
}
ans offf(void)
{
	argptr++;
	off();
}
ans drawpic(void)
{
	short x,y;
	char *pic_name,gmode2;

	char *fptr, *cptr;

	SYM_ENTRY *SymPtr;
	HANDLE h;

	argptr++;
	x=getsl;
	y=getsl;
	pic_name=getpuc;

	SCR_RECT full_screen = {{0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1}};
	
	SymPtr = DerefSym (SymFind (SYMSTR (pic_name)));
	if (!SymPtr) { rsl(0);}
	h = SymPtr->handle;

  if (HeapGetLock (h))		//si archivé
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }

	switch(gmode)
	{
		case 2:	//xor
		gmode2=A_XOR;
		break;
		case 3:		//AND
		gmode2=A_AND;
		break;
		case 0:	//or
		gmode2=A_OR;
		break;
		case 1:	//blank
		gmode2=A_REPLACE;
		break;
	}
	BitmapPut (x, y, cptr+2, &full_screen, gmode2); 

	if (h) HeapUnlock (h);
	rsl(1);
}
ans getpic(void)
{
	SCR_RECT rect;
	unsigned char bmp[LCD_SIZE+4],*tivar_str;
	short bmp_size;
	HANDLE handle;
	argptr++;
	rect.xy.x0=getsl;
	rect.xy.y0=getsl;
	rect.xy.x1=getsl;
	rect.xy.x1=getsl;
	if(*argptr!=45) exit2("Syntax:getpic(x1,y1,x2,y2,dest_str");
	tivar_str=getpuc;
	bmp_size=BitmapSize (&rect);
	BitmapGet (&rect, bmp); 
	handle = CreateFile_with_specified_size (tivar_str,bmp_size+5);	//2 de marge
	if(!handle)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Seqs():Exit by pressing ENTER");
			}
		}
		rsl(0);
	}
	AppendBlockToFile2 (handle, bmp, bmp_size);
	CloseFile_type (handle,0xDF);
	rsl(bmp_size+3);
}

ans osvar(void)		//cette fonction marche, mais pourterai un intérêt si seulement elle serait très évoluée. Je n'ai pas envie de remettre en cause profondémenet le code source pour le momment
{
	char *var_name;

	unsigned char *fptr, *cptr,*lptr;
	long rval;

	SYM_ENTRY *SymPtr;
	HANDLE h;
	argptr++;
	rval=0;
	var_name=getpuc;
	SymPtr = DerefSym (SymFind (SYMSTR (var_name)));
	if (!SymPtr) { rsl(0);}
	h = SymPtr->handle;

	lptr=HToESI (h); 
	switch(*lptr)
	{
		case POSINT_TAG:
		rval=GetIntArg (lptr);
		rsl(rval);
		break;
		case NEGINT_TAG:
		rval=-GetIntArg (lptr);
		rsl(rval);
		break;
		case STR_TAG:
		rval=GetStrnArg (lptr);
		rsl(rval);
		break;
		case FLOAT_TAG:
		rsl((signed long)GetFloatArg (lptr));
		break;
	}
	exit2("In osvar(var_str)\nUnknown type");
}
ans isarchi(void)
{
	unsigned char *var_name;
	SYM_ENTRY *SymPtr;
	argptr++;
	var_name=getpuc;
	SymPtr = DerefSym (SymFind (SYMSTR (var_name)));
	if (!SymPtr) { rsl(-1);}
	rsl(SymPtr->flags.bits.archived);
}
ans archiv(void)
{
	unsigned int nbvar,ii;
	unsigned char CESI_list[30],*var_name;
	argptr++;
	nbvar=getsl;
	//printf("nbvar %d",nbvar); ngetchx();
	CESI_list[0]=END_TAG;
	CESI_list[1]=0;
	TRY
	for(ii=0;ii<nbvar;ii++)
	{
		var_name=getpuc;
		//printf("varname %s",var_name); ngetchx();
		strcpy(CESI_list+2,var_name);
		cmd_archive (CESI_list+2+strlen(var_name));
	}
	ONERR
	if(disp_err)
	{
		if(ERD_dialog (ER_MEMORY, TRUE))
		{
			if(handle) HeapFree (handle); exit2("Archi():Exit by pressing ENTER");
		}
	}
	rsl(0);
	ENDTRY
	rsl(1);
}
ans unarchiv(void)
{
	unsigned int nbvar,ii;
	unsigned char CESI_list[30],*var_name;
	argptr++;
	nbvar=getsl;
	//printf("nbvar %d",nbvar); ngetchx();
	CESI_list[0]=END_TAG;
	CESI_list[1]=0;
	TRY
	for(ii=0;ii<nbvar;ii++)
	{
		var_name=getpuc;
		//printf("varname %s",var_name); ngetchx();
		strcpy(CESI_list+2,var_name);
		cmd_unarchiv (CESI_list+2+strlen(var_name));
	}
	ONERR
	if(disp_err)
	{
		if(ERD_dialog (ER_MEMORY, TRUE))
		{
			if(handle) HeapFree (handle); exit2("Unarchi():Exit by pressing ENTER");
		}
	}
	rsl(0);
	ENDTRY
	rsl(1);
}
ans gsprt8x(void)
{
	unsigned char x,y,h,w,*dest;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	w=getsl;
	dest=getpuc;
	SpriteX8Get_R(x,y,h,lcdad,dest,w);
	rsl(dest);
}
ans sprt8x(void)
{
	unsigned char x,y,h,w,*sprite;
	argptr++;
	x=getsl;
	y=getsl;
	h=getsl;
	w=getsl;
	sprite=getpuc;
	
	switch(gmode)
	{
		case 2:	//xor
		SpriteX8_XOR(x,y,h,sprite,w,lcdad);
		break;
		case 3:		//AND
		SpriteX8_AND(x,y,h,sprite,w,lcdad);
		break;
		case 0:	//or
		SpriteX8_OR(x,y,h,sprite,w,lcdad);
		break;
		case 1:	//rplc
		SpriteX8_RPLC_R(x,y,h,sprite,w,lcdad);
		break;
	}
	rpuc(sprite);
}
ans dcircle(void)
{
	short xcenter,ycenter,radius;
	argptr++;
	xcenter=getsl;
	ycenter=getsl;
	radius=getsl;
	//FastOutlinedCircle_DRAW_R(lcdad,xcenter,ycenter,radius);
	switch(gmode)
	{
		case 2:	//xor
		ClipFastOutlinedCircle_INVERT_R(lcdad,xcenter,ycenter,radius);	return ;
		break;
		case 3:		//AND
		case 0:	//or
		FastOutlinedCircle_DRAW_R(lcdad,xcenter,ycenter,radius); return ;
		break;
		case 1:	//rplc - erase
		FastOutlinedCircle_ERASE_R(lcdad,xcenter,ycenter,radius); return ;
		break;
	}
}
ans fillcirc(void)
{
	short x,y,radius;
	argptr++;
	x=getsl;
	y=getsl;
	radius=getsl;
	//ClipFastFilledCircle_R(x,y,radius,DrawSpan_XOR_R);
	switch(gmode)
	{
		case 2:	//xor
		ClipFastFilledCircle_R(lcdad,x,y,radius,DrawSpan_XOR_R);
		break;
		case 3:		//AND
		case 0:	//or
		ClipFastFilledCircle_R(lcdad,x,y,radius,DrawSpan_OR_R);
		break;
		case 1:	//rplc - erase
		ClipFastFilledCircle_R(lcdad,x,y,radius,DrawSpan_REVERSE_R);
		break;
	}
	
}
ans reallo(void)
{
	unsigned char *ptr;
	unsigned int len;
	argptr++;
	ptr=getpuc;
	len=getsl;
	realloc (ptr, len);
	if(!ptr)
	{
		if(disp_err)
		{
			if(ERD_dialog (ER_MEMORY, TRUE))
			{
				exit2("Realloc():Exit by pressing ENTER");
			}
		}
		rpuc(0);
	}
	rpuc(ptr);
}
ans unsigb(void)
{
//	long val;
	argptr++;
//	val=getsl;
//	if(val>0 && val<=255) rsl(val);	//nombre positif inférieur à 255 (ou plutot à environ 127)
//	if(val>0 && val>255) rsl(255);	//nombre positif mais supérieur à 255
	rsl(getsl&0b011111111);	
}
ans unsigw(void)
{
	argptr++;
	rsl(getsl&0b01111111111111111);
}
ans memch(void)
{
	unsigned char *str;
	short c;
	unsigned long len;
	argptr++;
	str=getpuc;
	c=getsl;
	len=getsl;
	rpuc(memchr (str,c,len)); 
}
ans textt(void)
{
	
	unsigned char *str,len,CESI_list[50];
	argptr++;
	CESI_list[0]=0;
	str=getpuc;
	strcpy(CESI_list+1,str);
	len=strlen(str);
	CESI_list[len+2]=STR_TAG;
	if(save_int_1)		//for avoiding crash with keyclear()=>Restore auto int1
	{
		SetIntVec (AUTO_INT_1, save_int_1);
		save_int_1=NULL;		//is useful later	
	}
	TRY
	cmd_text (CESI_list+len+2);
	ONERR
	rsl(0);
	ENDTRY
	rsl(1);
}
/*ans ifsh(void)	//Cette fonction marche
{
	unsigned char *ptr;
	//unsigned int dim;
	argptr+=2;
	ptr=argptr-1;	//pointe sur la dimension de la condition et de l'instruction
	//printf("\n*argptr=%d",*argptr); ngetchx();
	//dim=getsl;
	//printf("\ncond=%ld",cond); ngetchx();
	if(!getsl)
	{
		argptr=ptr+(*ptr);	//skip the instruction
	}
	else rsl(getsl);
}*/
ans ifshort(void)	//Cette fonction marche
{
	unsigned char *ptr;
	//unsigned int dim;
	argptr+=2;
	ptr=argptr-1;	//pointe sur la dimension de la condition et de l'instruction
	//printf("\n*argptr=%d",*argptr); ngetchx();
	//dim=getsl;
	//printf("\ncond=%ld",cond); ngetchx();
	if(!getsl)
	{
		argptr=ptr+(*ptr);	//skip the instruction
	}
	else rsl(getsl);		//si cond vraie, alors exécute l'instruction
}
ans disperr(void)
{
	unsigned char last_disp_err;
	argptr++;
	last_disp_err=disp_err;
	disp_err=getsl;
	rsl(last_disp_err);
}
										//0				1				2				3				4				5				6				7				8				9
ans
 (*fonc[])(void)={		a		,	guchar,	gslvar,  	a		,		LBL	,	GOTO	,	kwait	,		isz	,		dsz	,		a		, //0
										freeh ,tohandl,	exech	,	GOTOL	,	indir	,printf1,printf2,newline,prints,		a		, //1
									svscroff,EDWHILE,	finish,		when,strlenn,	printc,sprntf	,	chars	,	strct,	atoll	, //2
									execnpp	,	guint	,		gint,gsprt8,gsprt16,printd,printxy,	glong	,	gulong,	inter	, //3
										dline	,	dmline,setgmod,	sprt8	,	sprt16,	gstr	,		ordd,sprt82 ,sprt162,sprt322, //4
										setlcd,	dpix	,	gpix	,	sprt32,fillrec,	clrdrw,	rwky,keyclear,keydisp	,	ifthen, //5
										getlcd,	WHILE	,		offf,gsprt32,reallo	,		a		,strcat2,	next,breakk	,	elsee	, //6
										gryon	,	gryoff,	ligh	,	dar		,		a		,drwstr,setfontt,freet ,	sett	,	endif	, //7
									gotopos	,	pos		,	jsr 	,		rts	,	pause	,unsigb,unsigw	,		texp,		tval,	ifshort, //8
									scrleft	,scrrigh,scrup	,scrbot	,	lrol	,	rrol	,	osvar,	 idlee,memcpyy,		a		, //9
									clscr		,	randd	,	gsprt,scrleft2,scrrigh2,scrup2,scrbot2,		a		,memmov,		a		, //10
									fopenn	,disperr,fcreatee,	a		,files	,		reps,		a		,	gts		,		a		,		a		, //11
											nott,	orb		,		neg	,	notb	,dcircle,fillcirc,		a		,		a		,		sto	,		a		, //12
											xorr,		orl	,		andl,		inf	,	infeq	,		eq	,	supeq	,		sup	,	noteq	,	addd	, //13
										textt	,	sub		,		andb,	mul		,		a		,	divv	,	eqs		,		escc,		up	,	second, //14
											def	,	enddef,		a		,		fc	,sprt8x	,		rtn	,	group	,		a		,	down	,	majj	, //15
										repeat,		a		,savescr,loadscr,		mod	,		belm,	welm	,	lelm	,	left	,diamond, //16
										movto	,	tios	,	toos	,	newstr,gsprt8x,		wb	,		ww	,		wl	,	right	,alpha	, //17
									strcmpp	,strcpyy,		gkey,keydlay,keysped,	forr	,	eforr	,		a		,		a		,		a		, //18
											pokb,	pokw	,	pokl ,lscroll4,	archiv,unarchiv,	i		,		b		,		w		,		l		, //19
										pekb	,	pekw	,	pekl	,isarchi,loadasm,		a		,	xb		,		yb	,		a		,		a		, //20
										newstr,	exprr	,stringg,llelem	,execasm,		a		,	nilist,	mklist,lusfunc,		a		, //21
											map	,	multi	,	two		,	memch	,closeasm,		a	,catalog,	open	,		a		,	endtag, //22
											a		,		finl,settype,	finish,	seqb	,	lcdup	,lcddown,drawpic,	getpic,		a		, //23
									debugon	,DEBUGOF,	seqs	,	seqe	,	seqw	,prettyxy,getwbt,	cwidth,execbas,		a		, //24
											nop	,	mallo	,		fre	,	mmset	,		seql,asm_cal,		a		,		a		,		a		,		a		}; //25




void exit2(unsigned char *str_error)
{
	int ii;
	clrscr();
	printf("\n%s",str_error);
	SetIntVec (AUTO_INT_5, OldInt5);
	ngetchx();
	free(argdep);
	if(sv_scr_on==1) {memcpy (LCD_MEM, screen_buffer, LCD_SIZE); free(screen_buffer);}
	if(GLOBAL_data) free(GLOBAL_data);
	OSInitKeyInitDelay(336);
	OSInitBetweenKeyDelay (48);
	for(ii=0;ii<4;ii++)			//free the saved screens
	{
		if(scr_copy[ii]!=NULL) free(scr_copy[ii]);
	}
	WinClose (&wind);	//for prettyxy function
	if(handle_execbas) HeapFree (handle_execbas);
	exit(4);
}
void exit3(unsigned char *str_error)
{
	int ii;
	clrscr();
	printf("\n%s",str_error);
	SetIntVec (AUTO_INT_5, OldInt5);
	ngetchx();
	if(sv_scr_on==1) {memcpy (LCD_MEM, screen_buffer, LCD_SIZE); free(screen_buffer);}
	if(GLOBAL_data) free(GLOBAL_data);
	OSInitKeyInitDelay(336);
	OSInitBetweenKeyDelay (48);
	for(ii=0;ii<4;ii++)			//free the saved screens
	{
		if(scr_copy[ii]!=NULL) free(scr_copy[ii]);
	}
	WinClose (&wind);	//for prettyxy function
	if(handle_execbas) HeapFree (handle_execbas);
	exit(4);
}
void disp_stack(void)
{
	ESI a;
	a=top_estack;
	printf("\nstack:\n");
	while(a!=bottom_estack) {printf("%c",*a); a--;}
	printf("\n");
	a=top_estack;
	while(a!=bottom_estack) {printf("%x ",*a); a--;}
}
// Main Function
void _main(void)
{
	ESI arg = top_estack;
	//SYM_ENTRY *src_entry;
	FILE *f;
	unsigned char *temp_str,srcname[20];
	unsigned int i;
	scr_rect.xy.x0=0;
	scr_rect.xy.y0=0;
	scr_rect.xy.x1=239;
	scr_rect.xy.y1=127;
	scr_copy[0]=NULL;	scr_copy[1]=NULL;	scr_copy[2]=NULL; scr_copy[3]=NULL;
	save_int_1=NULL; save_int_5=NULL;
	i_var_user_func_backup=0;



	//ESI argptr,argdep,tmpesi,argintr[21],intrdeb,argwhile[NB_WHILE],argendwhile[NB_WHILE],argyblock[50];

	GLOBAL_data=malloc(260*4*(5)+NB_FOR*4*(2));
	if(!GLOBAL_data) exit2("Not enough memory");	

	argendif=GLOBAL_data+0;		//260
	argelse=GLOBAL_data+260*4*1;		//260
	arglbl=GLOBAL_data+260*4*2;		//260
	argfunc=GLOBAL_data+260*4*3;		//260
	argendfunc=GLOBAL_data+260*4*4;		//260
	
	argendfor=GLOBAL_data+260*4*5;	//NB_FOR
	argfor=GLOBAL_data+260*4*5+4*NB_FOR*1;	//NB_FOR
	

	
	//Save screen automatically by default
	sv_scr_on=1;
	screen_buffer=malloc(LCD_SIZE);
	if(screen_buffer==NULL) exit2("Memory error in svscron()");
	memcpy (screen_buffer, LCD_MEM, LCD_SIZE);


	WIN_RECT winr = {0, 0, 239, 127};	//for prettyxy function
  WinOpen (&wind, &winr, WF_TTY | WF_NOBORDER); //an empty window with no border ready to write in. It will be necessary to close the window before exiting program
  WinActivate (&wind);	//
  memcpy (LCD_MEM, screen_buffer, LCD_SIZE);	//restore screen because prettyxy l'efface


	//For the function gkey()
	kbq = kbd_queue ();

	Counter=0;
	//int5_allowed=1;
	OldInt5 = GetIntVec (AUTO_INT_5);
  SetIntVec (AUTO_INT_5, MyInt5);
  arg=top_estack;
  
  varlist=varlist_array;
  
  /*i_rtnf=0;*/ inc=0;
  for(i=0;i<256;i++)	{byte_width_ilist[i]=4; varlist[i].sl=0;} //for llelem function, initialized to 4 by default for compatibility with the group() function
	i=0;
	for(i=1;i<=21;i++) argintr[i]=0;
	i=0;
  for(i_intr=0;i_intr<20;i_intr++) //met a 0 toutes les interuptions
  {
  	argintr[i_intr]=0;
  	speedintr[i_intr]=0;
  }
  i_intr=0;
  nsubfonc=0; nswitch=0; handle_execbas=H_NULL;
  disp_err=1; disp_err_old=1;	//par défaut, affiche un message d'erreur Tibasic
  
  if(GetArgType (arg) != STR_TAG) exit3("String arg expected\nSource file expected.");
  temp_str = GetStrnArg(arg);
  reset_control_flags();	//This is useful for prettyxy and getwbt functions.
  strcpy (srcname , temp_str);				//le nom du fichier header est affecte definitivement ici
  f=fopen(srcname,"r");
  srcsize=*(unsigned int*)(f->base);	//srcsize=size of data without first two bytes
  //printf("\n Compiled with version : %d",*((unsigned char*)(f->base)+srcsize+1-6)); ngetchx();
  nbvar_main=*((unsigned char*)(f->base)+srcsize+1-7);
  if(*((unsigned char*)(f->base)+srcsize+1)!=OTH_TAG && strcmp("NPP",(unsigned char*)(f->base)+srcsize+1-4)!=0) { SetIntVec (AUTO_INT_5, OldInt5); fclose(f);clrscr(); printf("NPP file expected"); ngetchx(); WinClose (&wind); if(sv_scr_on==1) {memcpy (LCD_MEM, screen_buffer, LCD_SIZE); free(screen_buffer);}  exit(4);}

	

  argptr=malloc(srcsize);
  memcpy (argptr, (unsigned char*)(f->base)+2, srcsize);
  fclose(f);
  //src_entry = DerefSym(SymFind(SYMSTR(srcname)));
  //if(src_entry && src_entry->name);
	//else exit2("fichier inexistant");
	//argptr=HToESI(src_entry->handle);
	//if(*argptr!=OTH_TAG) { exit2("OTHer prgm file expected");}
	//argptr=argptr-srcsize+1;
	argdep=argptr;
	gmode=0; nsubfonc=0; lcdad=LCD_MEM;
	randomize();	//for having real random number with rand()
	init_bkm();
	//OSDisableBreak(); //disable ON KEY breaking
	//OSSetSR (0x0700); //a enlever	
		
	exec_none_stop_secured();
	exit2("Execution stopped");
}
