#include <stdio.h>
#include <string.h>
#include "stdlib.h"
#include "printlog.h"
#include "expression.h"

FILE *FO;

char basedir[200];
char filename[100][200];
int filen;
int totalerr=0;
int totalwarn=0;
int commentdepth=0;
int	PC,totalbytes;
int ifdepth=0;
bool ifvalue[1000];
bool ifskip[1000];

#define iftrue ((ifdepth==0)||((ifdepth>0)&&(ifvalue[ifdepth-1]!=0)))


struct	definet	{
	char *src;
	int srcn;
	char *dst;
	int dstn;
	bool removed;
	struct definet *next;
} *def0, *defp, *labren0, *labrenp;


struct	labelt	{
	char *src;
	int srcn;
	int PC;
	struct labelt *next;
} *lab0, *labp, *labmp;

struct argt {
	int len;
	char *s;
};
struct arglink {
	char *s;
	int n;
	struct arglink *next;
};

struct macrot {
	struct textt *p;
	int tlen;
	int argn;
	int linen;
	struct argt *arg;
	struct labelt *lab0;
	struct macrot *next;
}	*mac0, *macp;

struct macrostackt {
	struct definet *def;
	struct definet *labren;
} macrostack[100];

struct	textt	{
	char *s;
	char *s0;
	char filen;
	int linen;
	char macrodepth;
	char maclinen;
	struct macrot *mac;	
	bool dopass2;
	int pass2st;
	bool ispreprocess;
	int preprecessv;
	int PC;
	struct textt *next;
}	*text0, *textp;


//#define blksize 65536      //64KB
//#define blksize 131072       //128KB
//#define blksize 262144       //256KB
//#define blksize 524288       //512KB
//#define blksize 1048576        //1MB
//#define blksize 4194304        //4MB
#define blksize 8388608        //8MB
//#define blksize 16777216         //16MB  (100 0000)

#define blkmask (blksize-1)
struct resultt {
	unsigned char b[blksize];
	struct resultt *next;
} result, *resultp;

void dispmsg(const char *types,const char *errs)
{
	int i;
	if (textp==NULL) {
		print2("%s:%s\n",types,errs);
		return;
	}

	print2("%s:%s(%d)",types,filename[textp->filen],textp->linen);
	if (textp->macrodepth!=0) {
		print2("[macro ");
		for(i=0;i<textp->mac->tlen;i++) print2("%c",textp->mac->p->s[i]);
		print2("(%d)]",textp->maclinen);
	}
	print2(":%s\n::",errs);
	i=0;
	while(textp->s[i]!=0) {
		if (textp->s[i]<=' ') print2(" "); else print2("%c",textp->s[i]);
		i++;
	}
	print2("\n");
}

void disperr(const char *errs)
{
	dispmsg("Error",errs);
	totalerr++;
}
void dispwarn(const char *warns)
{
	dispmsg("Warning",warns);
	totalwarn++;
}
void dispptr(int n)
{
	int i;
	print2("@@");
	for(i=0;i<n;i++) print2(" ");
	print2("^\n");
}

int strblankn(char *s)
{
	int i;
	i=0;
	while(((s[i]>0)&&(s[i]<=' '))||(s[i]==0x7F)) i++;

	return(i);
}

int strnonblankn(char *s)
{
	int i;
	i=0;
	while(s[i]>' ') i++;
	return(i);
}

bool isends(char *s)
{
	if ((*s==0)||(*s==';')||((*s=='/')&&(*(s+1)=='/'))) return(true);
	else return(false);
}
int strendn(char *s)
{
	int i;
	i=0;
	while(!isends(s+i)) i++;
	while((i>0)&&(s[i-1]<=' ')) i--;
	return(i);
}

bool memcmpn(const char *s, const char *p)
{
	int n;
	n=strlen(p);
	if ((!memcmp(s,p,n))&&(s[n]>=0)&&(s[n]<=' '))
		return(true);
	else
		return(false);
}

bool memicmpn(const char *s, const char *p)
{
	int n;
	n=strlen(p);
	if ((!memicmp(s,p,n))&&(((s[n]>=0)&&(s[n]<=' '))||(s[n]==0x7F)))
		return(true);
	else
		return(false);
}

bool memicmpd(const char *s, const char *p)
{
	int n;
	n=strlen(p);
	if ((!memicmp(s,p,n))&&(((s[n]>=0)&&(s[n]<=' '))||(s[n]=='.')||(s[n]==',')))
		return(true);
	else
		return(false);
}

char fgets0(char *s,int n,FILE *F)
{
	s[0]=0;
	fgets(s,n,F);
	return(s[0]);
}

struct textt * loadfile(int fn,struct textt *next)
{
	char ss[300];
	FILE *FR;
	struct textt *t0,*tp,*tt;
	int i,ln;
	strcpy(ss,basedir);
	strcat(ss,filename[fn]);
	FR=fopen(ss,"r");
	if (FR==NULL) return(NULL);
	t0=NULL; tp=NULL;
	ln=0;
	while(fgets0(ss,300,FR)) {
		tt=new struct textt;
		if (t0==NULL) {t0=tt; tp=t0;} else {tp->next=tt; tp=tp->next;}
		i=0;
		while(!(ss[i]==0)) {
			if (ss[i]<' ') ss[i]=' ';
			i++;
		}
		while((i>0)&&(ss[i-1]>0)&&(ss[i-1]<=' ')) i--;
		tp->s=new char[i+1];
		memcpy(tp->s,ss,i);
		tp->s[i]=0;
		tp->filen=fn;
		tp->linen=ln+1;
		tp->macrodepth=0;
		tp->mac=NULL;
		tp->maclinen=0;
		tp->dopass2=0;
		tp->ispreprocess=0;
		tp->PC=0;
		tp->next=next;
		ln++;
	}
	fclose(FR);
	return(t0);
}

void expand_include(int i)
{
	int j;
	struct textt *textl;
	i+=strblankn(textp->s+i);
	while((textp->s[i]>0)&&(textp->s[i]<=' ')) i++;
	if (textp->s[i]!='\"') {
		disperr("\" miss");
		dispptr(i);
	} else {
		i++; j=i;
		while((textp->s[i]!=0)&&(textp->s[i]!='\"')) i++;
		if (textp->s[i]!='\"') {
			disperr("\" mismatch");
			dispptr(i);
			totalerr++;
		} else {
			memcpy(filename[filen],textp->s+j,i-j);
			filename[filen][i-j]=0;
			textl=loadfile(filen,textp->next);
			if (textl==NULL) {
				disperr("file not found");
			} else {
				textp->next=textl;
				filen++;
			}
		}
	}
}

struct definet *find_def(char *src, int sn)
{
	struct definet *deft;
	deft=def0;
	while(deft!=NULL) {
		if ((deft->srcn==sn)&&!(memcmp(src,deft->src,sn))) {
			return(deft);
		}
		deft=deft->next;
	}
	return(deft);
}

void add_define(char *src,char *dst,int sn,int dn)
{
	struct definet *deft;
	if ((sn==dn)&&!memcmp(src,dst,sn)) return;
	deft=find_def(src,sn);
	if (deft!=NULL) {
		dispwarn("symbol redefine");
		return;
	}

	deft=new struct definet;
	deft->src=src;
	deft->srcn=sn;
	deft->dst=dst;
	deft->dstn=dn;
	deft->next=def0;
	def0=deft;
}

void add_label(char *lab,int k,int pos,int inmacro)
{
	struct labelt *labt;

	if (!inmacro) labt=lab0;
	else labt=macp->lab0;
	while(labt!=NULL) {
		if ((labt->srcn==k)&&(!memcmp(textp->s,labt->src,k))) {
			disperr("label redefined");
		}
		labt=labt->next;
	}	
	labt=new struct labelt;
	labt->src=lab;
	labt->srcn=k;
	labt->PC=PC;
	labt->next=NULL;
	if (inmacro) {
		if (macp->lab0==NULL) {macp->lab0=labt; labmp=labt;} else {labmp->next=labt; labmp=labp->next;}
	} else {
		if (lab0==NULL) {lab0=labt; labp=labt;} else {labp->next=labt; labp=labp->next;}
	}
}

struct arglink *getarg(int *num,int j,bool isasc)
{
	int k,n;
	bool err;
	struct arglink *arg0, *argp, *argt;
	arg0=NULL;
	err=0; n=0;
	if (textp->s[j]==0) {*num=0; return(NULL);}
	while (textp->s[j]!=0) {
		k=j;
		if (isasc) {
			j+=strvarn(textp->s+j);
		} else {
			while((textp->s[j]!=0)&&(textp->s[j]!=',')) j++;
		}
		if (k==j) {
			disperr("argument error");
			dispptr(j);
			err=1;
			break;
		}
		if (isasc) {
			argt=arg0;
			while(argt!=NULL) {
				if ((argt->n==(j-k))&&(!memcmp(argt->s,textp->s+k,j-k))) {
					disperr("argument duplicate");
					dispptr(j);
					err=1;
					break;
				}
				argt=argt->next;
			}
			if (err) break;
		}

		argt=new struct arglink;
		if (arg0==NULL) {arg0=argt; argp=arg0;} else {argp->next=argt; argp=argp->next;}
		argp->s=textp->s+k;
		argp->n=j-k;
		argp->next=NULL;
		j+=strblankn(textp->s+j);
		if ((textp->s[j]!=',')&&(textp->s[j]!=0)) {
			disperr("argument error");
			dispptr(j);
			err=1;
			break;
		}
		if (textp->s[j]==',') {
			j++;
			j+=strblankn(textp->s+j);
			if (textp->s[j]==0) {
				disperr("argument error");
				dispptr(j);
				err=1;
				break;
			}
			n++;
		}
	}
	if (err) {
		while(arg0!=NULL) {
			argp=arg0->next;
			delete arg0;
			arg0=argp;
		}
		return NULL;
	}
	*num=n+1;
	return(arg0);
}
void add_macro(int k,int j)
{
	struct macrot *mact;
	int i,n;
	bool err;
	struct arglink *arg0, *argp;
	mact=mac0;
	while(mact!=NULL) {
		if ((mact->tlen==k)&&(!memcmp(textp->s,mact->p->s,k))) {
			disperr("macro redefined");
			return;
		}
		else mact=mact->next;
	}
	j+=strblankn(textp->s+j);
	err=0;
	arg0=getarg(&n,j,true);

	mact=new struct macrot;
	if (mac0==NULL) {mac0=mact; macp=mac0;} else {macp->next=mact; macp=macp->next;}
	macp->p=textp;
	macp->tlen=k;
	macp->next=NULL;
	macp->argn=n;
	macp->lab0=NULL;
	mact->linen=0;
	if (n==0) macp->arg=NULL;
	else {
		macp->arg=new struct argt[n];
		for(i=0;i<n;i++) {
			macp->arg[i].s=arg0->s;
			macp->arg[i].len=arg0->n;
			argp=arg0->next;
			delete arg0;
			arg0=argp;
		}
	}

}

void push_macro(int i,struct macrot *mact,unsigned long pos)
{
	struct textt *mp,*tt,*next,*tp;
	struct arglink *arg0, *argp;
	struct definet *deft;
	struct labelt *labt;
	int n,j,depth;
	char *ss0;
	char ss[200];

	next=textp->next;

	depth=textp->macrodepth+1;
	macrostack[depth-1].def=def0;
	macrostack[depth-1].labren=labren0;
	labt=mact->lab0;
	if (labt!=NULL) {
		def0=NULL;
		while(labt!=NULL) {
			j=labt->srcn;
			memcpy(ss,labt->src,labt->srcn);
			ss[j]='_'; j++;
			itoa(depth,ss+j,10);
			j+=strlen(ss+j);
			ss[j]='_'; j++;
			itoa(pos,ss+j,16);
			j+=strlen(ss+j);
			ss[j]=0;
			ss0=new char[j+1];
			strcpy(ss0,ss);
			add_define(labt->src,ss0,labt->srcn,j);
			labt=labt->next;
		}
		deft=def0;
		while(def0->next!=NULL) def0=def0->next;
		def0->next=labren0;
		labren0=deft;
		def0=macrostack[depth-1].def;
	}

	i+=strnonblankn(textp->s+i);
	i+=strblankn(textp->s+i);
	arg0=getarg(&n,i,false);
	if (n!=mact->argn) {
		disperr("macro argument number mismatch");
	} else {
		argp=arg0;
		if (n!=0) {
			def0=NULL;
			for(i=0;i<n;i++) {
				add_define(mact->arg[i].s,argp->s,mact->arg[i].len,argp->n);
				argp=argp->next;
			}
			if (def0!=NULL) {
				deft=def0;
				while(def0->next!=NULL) def0=def0->next;
				def0->next=macrostack[depth-1].def;
				def0=deft;
			} else def0=macrostack[depth-1].def;
		}
	}
	while(arg0!=NULL) {
		argp=arg0->next;
		delete arg0;
		arg0=argp;
	}

	mp=mact->p->next;
	tp=textp;
	for(i=0;i<mact->linen;i++) {
		tt=new struct textt;
		tt->s=mp->s;
		tt->s0=mp->s0;
		tt->linen=textp->linen;
		tt->filen=textp->filen;
		tt->macrodepth=depth;
		tt->mac=mact;
		tt->maclinen=i+1;
		tt->dopass2=0;
		tt->PC=0;
		tt->next=next;
		tp->next=tt;
		tp=tp->next;
		mp=mp->next;
	}
}

void pop_macro()
{
	int i;
	i=textp->macrodepth-1;
	struct definet *deft;
	while(def0!=macrostack[i].def) {
		deft=def0;
		def0=def0->next;
		delete deft;
	}
	while(labren0!=macrostack[i].labren) {
		deft=labren0;
		labren0=labren0->next;
		delete deft;
	}
}

struct macrot *ismacro(char *s)
{
	int n;
	struct macrot *mact;
	n=strvarn(s);
	mact=mac0;
	while(mact!=NULL) {
		if ((mact->tlen==n)&&(!memcmp(mact->p->s,s,n))) {
			return(mact);
		}
		mact=mact->next;
	}
	return(NULL);
}

char * convert_define(char *src,char depth)
{
	int i,j,k;
	bool dirty,dirtya;
	char dst0[2000];
	char dst1[2000];
	char *dst;
	char *dstr;
	struct definet *deft;
	int commentdepth0=commentdepth;
	dst=dst0; dirtya=0;
	do {
		i=0; j=0; dirty=0; commentdepth=commentdepth0;
		while(!isends(src+j)) {
			if (commentdepth!=0) {
				if ((src[j]=='*')&&(src[j+1]=='/')) {
					dst[i++]=src[j++]; dst[i++]=src[j++];
					commentdepth--;
				} else {
					dst[i++]=src[j++];
				}
			} else if ((src[j]=='/')&&(src[j+1]=='*')) {
				dst[i++]=src[j++]; dst[i++]=src[j++];
				commentdepth++;
			} else if (((src[j]>='a')&&(src[j]<='z'))||((src[j]>='A')&&(src[j]<='Z'))) {
				k=j;
				j+=strvarn(src+j);
				deft=NULL;
				if ((depth>0)&&!dirty) { //rename label in macro
					deft=labren0;
					while(deft!=NULL) {
						if ((deft->srcn==(j-k))&&(!memcmp(src+k,deft->src,j-k))) {
							break;
						}
						deft=deft->next;
					}
				}
				if ((k!=0)&&(deft==NULL)) {//k!=0:do not convert label
					deft=def0;
					while(deft!=NULL) {
						if ((deft->srcn==(j-k))&&(!memcmp(src+k,deft->src,j-k))) {
							break;
						}
						deft=deft->next;
					}
				}
				if (deft==NULL) {
					memcpy(dst+i,src+k,j-k);
					i+=j-k;
				} else {
					memcpy(dst+i,deft->dst,deft->dstn);
					i+=deft->dstn;
					dst[i]='/'; dst[i+1]='*'; i+=2;
					memcpy(dst+i,src+k,j-k);
					i+=j-k;
					dst[i]='*'; dst[i+1]='/'; i+=2;
					dirty=1;
				}
			} else {
				dst[i++]=src[j++];
			}
		}
		dst[i]=0;
		if (src[j]!=0) {
			strcpy(dst+i,src+j);
			i+=strlen(src+j);
		}
		if (dirty) {
			if (dst==dst0) {
				dst=dst1; src=dst0;
			} else {
				dst=dst0; src=dst1;
			}
			j=0;
		}
		dirtya|=dirty;
	} while(dirty);
	if (!dirtya) return(src);
	else {
		dstr=new char[i+1];
		memcpy(dstr,dst,i+1);
		return(dstr);
	}
}

int convert_label(char *src,int *n,bool *err)
{
	int j;
	struct labelt *labt;
	j=strlabn(src);
	if (n!=NULL) *n=j;
	labt=lab0;
	while(labt!=NULL) {
		if ((labt->srcn==j)&&(!memcmp(src,labt->src,j))) break;
		labt=labt->next;
	}
	if (labt==NULL) {
		if (err!=NULL) *err=1;
		return(0);
	} else {
		if (err!=NULL) *err=0;
		return(labt->PC);
	}
}

#define argtoofew 1
#define argtoomuch 2
#define argregname 3
#define argregn 4
#define argoverflow 5
#define argconstwrong 6
int parse_instruct()
{
	int i,j,k,m,cmdn,argn;
	char cmds[5];
	char cmdlen[5];
	char args[5];
	char arglen[5];
	int argvalue[5];
	char works[2000];
	int err;
	int cmderrn=-1;
	int argerrn=-1;
	int errm=0;
	struct resultt *rest;
	int oldpc;
	char opc;
	
	char fmt,argm;
	static const char *cmps[10]={"eq","ne","lt","le","gt","ge","ltu","leu","gtu","geu"};
	union {
		unsigned char b[4];
		unsigned short w[2];
		unsigned long d;
	}	op;
	op.d=0;

	while(PC<textp->PC) {
		resultp->b[PC&blkmask]=0;
		PC++;
		if ((PC&blkmask)==0) {
			resultp->next=new struct resultt;
			resultp=resultp->next;
		}
	}
	oldpc=PC;
	rest=resultp;

	strcpy(works,textp->s);
	j=textp->pass2st;
	i=0;
	while(!isends(works+j)) { //convert comment to blank
		if (i) {
			if ((works[j]=='*')&&(works[j+1]=='/')) {
				works[j]=0x7F; works[j+1]=0x7F; j+=2;
				i=0;
			} else {
				works[j]=0x7F; j++;
			}
		} else {
			if ((works[j]=='/')&&(works[j+1]=='*')) {
				works[j]=0x7F; works[j+1]=0x7F; j+=2;
				i=1;
			} else {
				j++;
			}
		}
	}
	works[j]=0;

	j=textp->pass2st; //first command pos
	err=0;
	/////////////////get pred
	if ((works[j]=='P')||(works[j]=='p')) {
		if ((works[j+1]>='0')&&(works[j+1]<='7')&&(((works[j+2]>0)&&(works[j+2]<=' '))||(works[j+2]==0x7F))) {
			op.b[3]=((works[j+1]-'0')<<5);
			j+=2;
		}
	}
	j+=strblankn(works+j);

	/////////////////DB
	if (memicmpn(works+j,"DB")||memicmpn(works+j,"DW")||memicmpn(works+j,"DD")) {
		if ((works[j+1]|0x20)=='b') m=1;
		else if ((works[j+1]|0x20)=='w') m=2;
		else if ((works[j+1]|0x20)=='d') m=4;
		j+=2;
		j+=strblankn(works+j);
		while(!isends(works+j)) {
			i=expression(works+j,&err);
			if (err>=0) {argerrn=j+err; break;}
			while((works[j]!=',')&&!isends(works+j)) j++;
			if (works[j]==',') j++;
			if (m==4) {
				//resultp->b[PC&blkmask]=i>>24; PC++;  //64KB
				//resultp->b[PC&blkmask]=i>>48; PC++;   //128KB
				//resultp->b[PC&blkmask]=i>>96; PC++;   //256KB
				//resultp->b[PC&blkmask]=i>>384; PC++;   //1MB
				//resultp->b[PC&blkmask]=i>>1536; PC++;   //4MB
				resultp->b[PC&blkmask]=i>>3072; PC++;   //8MB
				//resultp->b[PC&blkmask]=i>>6144; PC++;   //16MB
				
				//resultp->b[PC&blkmask]=i>>16; PC++;  //64KB
				//resultp->b[PC&blkmask]=i>>32; PC++;    //128KB
				//resultp->b[PC&blkmask]=i>>64; PC++;    //256KB
				//resultp->b[PC&blkmask]=i>>256; PC++;    //1MB
				//resultp->b[PC&blkmask]=i>>1024; PC++;    //4MB
				resultp->b[PC&blkmask]=i>>2048; PC++;    //8MB
				//resultp->b[PC&blkmask]=i>>4096; PC++;    //16MB
			}
			//if (m!=1) {resultp->b[PC&blkmask]=i>>8; PC++;}
			//if (m!=1) {resultp->b[PC&blkmask]=i>>16; PC++;}  //128KB
			//if (m!=1) {resultp->b[PC&blkmask]=i>>32; PC++;}  //256KB
			//if (m!=1) {resultp->b[PC&blkmask]=i>>128; PC++;}  //1MB
			//if (m!=1) {resultp->b[PC&blkmask]=i>>512; PC++;}  //4MB
			if (m!=1) {resultp->b[PC&blkmask]=i>>1024; PC++;}  //8MB
			//if (m!=1) {resultp->b[PC&blkmask]=i>>2048; PC++;}   //16MB
			resultp->b[PC&blkmask]=i; PC++;
			if ((PC&blkmask)==0) {
				resultp->next=new struct resultt;
				resultp=resultp->next;
			}
		}
		goto lab_encend;
	}


	/////////////////get cmd words
	j+=strblankn(works+j);
	cmdn=0;
	while(works[j]>' ') {
		cmds[cmdn]=j;
		if (works[j]=='.') {
			cmderrn=j;
			break;
		}
		while((works[j]>' ')&&(works[j]!='.')) j++;
		cmdlen[cmdn]=j-cmds[cmdn];
		if (works[j]=='.') {
			j++;
		}
		cmdn++;
		if (cmdn>4) {
			cmderrn=j;
			break;
		}
	}

	if (cmdn==0) {
		cmderrn=j;
	}
	cmds[cmdn]=cmds[cmdn-1]+cmdlen[cmdn-1];
	i=0;
	while(works[i]!=0) {if (works[i]==0x7F) works[i]=' '; i++;}
	/////////////////get arg words
	j+=strblankn(works+j);
	argn=0;
	args[0]=cmds[cmdn-1]+cmdlen[cmdn-1]; arglen[0]=0;
	while(works[j]!=0) {
		args[argn]=j;
		if (works[j]==',') {
			argerrn=j;
			break;
		}
		while((works[j]!=0)&&(works[j]!=',')) j++;
		arglen[argn]=j-args[argn];
		if (works[j]==',') {
			j++;
			j+=strblankn(works+j);
		}
		argn++;
		if (argn>4) {
			argerrn=j;
			break;
		}
	}
	args[argn]=j;
	for(i=0;i<argn;i++) {
		j=arglen[i];
		while((j>0)&&(works[args[i]+j-1]==' ')) j--;
		arglen[i]=j;
	}
	if ((cmderrn>=0)||(argerrn>=0)) goto lab_encend;
	//////////////////encode command
	////////////////////////////one word command
	if (memicmpd(works+cmds[0],"jmp")) {
		if (cmdn==1) {//00
			op.w[1]|=(0x00<<7);
		} else if (memicmpn(works+cmds[1],"link")) {//01
			op.w[1]|=(0x01<<7);
		} else if (memicmpd(works+cmds[1],"reg")) {//02
			if (cmdn==2) {
				op.w[1]|=(0x02<<7);
			} else if (memicmpn(works+cmds[2],"link")) {//03
				op.w[1]|=(0x03<<7);
			} else cmderrn=cmds[2];
		} else cmderrn=cmds[1];
	} else if (memicmpn(works+cmds[0],"call")) { //01
		op.w[1]|=(0x01<<7);
	} else if (memicmpd(works+cmds[0],"ret")) {//02
		op.w[1]|=(0x02<<7);
	} else if (memicmpd(works+cmds[0],"loadi")) {//04
		op.w[1]|=(0x04<<7);
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		if (memicmpd(works+cmds[1],"z")) op.w[1]|=(0x00<<7); //04
		else if (memicmpd(works+cmds[1],"k")) op.w[1]|=(0x01<<7); //05
		else cmderrn=cmds[1];
		if (memicmpn(works+cmds[2],"0")) op.w[1]|=(0x00); 
		else if (memicmpn(works+cmds[2],"1")) op.w[1]|=(0x01);
		else if (memicmpn(works+cmds[2],"2")) op.w[1]|=(0x02);
		else if (memicmpn(works+cmds[2],"3")) op.w[1]|=(0x03);
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"reti")) { //06
		if (cmdn==1) op.w[1]|=(0x06<<7);
		else cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"trap")) {//07
		if (cmdn==1) op.w[1]|=(0x07<<7);
		else cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"cmp")) {//08
		op.w[1]|=(0x08<<7);
		if (memicmpd(works+cmds[1],"4")) {
			op.b[1]|=0x08;
			j=2; 
		} else j=1;

		for(i=0;i<10;i++) {
			if (memicmpd(works+cmds[j],cmps[i])) break;
		}
		if (i==10) 	cmderrn=cmds[j];
		op.b[0]|=i;
		if (cmderrn==-1) {
			if ((j==1)&&(cmdn>=3)) {
				if (memicmpn(works+cmds[2],"pw0")) op.b[1]|=0x10;
				else if (memicmpn(works+cmds[2],"pw1")) op.b[1]|=0x14;
				else cmderrn=cmds[2];
			} else if ((j==2)&&(cmdn>3)) {
				cmderrn=cmds[3];
			}
		}
	} else if (memicmpd(works+cmds[0],"cmpi")) {//09
		op.w[1]|=(0x09<<7);
		if (cmdn!=2) cmderrn=cmds[(cmdn>3)?3:cmdn];
		for(i=0;i<10;i++) {
			if (memicmpn(works+cmds[1],cmps[i])) break;
		}
		if (i==10) cmderrn=cmds[1];
		op.b[0]|=i;
	} else if (memicmpn(works+cmds[0],"testbit")) {//0A
		op.w[1]|=(0x0A<<7);
	} else if (memicmpn(works+cmds[0],"changepr")) {//0B
		op.w[1]|=(0x0B<<7);
	} else if (memicmpn(works+cmds[0],"changepr.ld")) {//0C
		op.w[1]|=(0x0C<<7);
	} else if (memicmpd(works+cmds[0],"loadx")) {//10
		op.w[1]|=(0x10<<7);
		if (cmdn>3) {cmderrn=cmds[3];}
		else if (memicmpd(works+cmds[1],"4")) ;
		else if (memicmpd(works+cmds[1],"8")) op.w[1]|=(0x01<<7);
		else {cmderrn=cmds[1];}
		if ((cmderrn==-1)&&(cmdn>2)) {
			if ((memicmpn(works+cmds[2],"update"))) op.w[1]|=(0x04<<7);
			else {cmderrn=cmds[2];}
		}
	} else if (memicmpd(works+cmds[0],"load")) {//12
		op.w[1]|=(0x12<<7);
		if (cmdn>3) {cmderrn=cmds[3];}
		else if (memicmpd(works+cmds[1],"4")) ;
		else if (memicmpd(works+cmds[1],"8")) op.w[1]|=(0x01<<7);
		else {cmderrn=cmds[1];}
		if ((cmderrn==-1)&&(cmdn>2)) {
			if ((memicmpn(works+cmds[2],"update"))) op.w[1]|=(0x04<<7);
			else {cmderrn=cmds[2];}
		}
	} else if (memicmpd(works+cmds[0],"store")) {//18
		op.w[1]|=(0x18<<7);
		if (cmdn>3) {cmderrn=cmds[3];}
		else if (memicmpd(works+cmds[1],"1")) ;
		else if (memicmpd(works+cmds[1],"2")) op.w[1]|=(0x01<<7);
		else if (memicmpd(works+cmds[1],"4")) op.w[1]|=(0x02<<7);
		else if (memicmpd(works+cmds[1],"8")) op.w[1]|=(0x03<<7);
		else {cmderrn=cmds[1];}
		if ((cmderrn==-1)&&(cmdn>2)) {
			if ((memicmpn(works+cmds[2],"update"))) op.w[1]|=(0x04<<7);
			else {cmderrn=cmds[2];}
		}
	} else if (memicmpd(works+cmds[0],"addi")) {//20
		op.w[1]|=(0x20<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"subi")) {//21
		op.w[1]|=(0x21<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"andi")) {//22
		op.w[1]|=(0x22<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"ori")) {//23
		op.w[1]|=(0x23<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"xori")) {//24
		op.w[1]|=(0x24<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"slli")) {//25
		op.w[1]|=(0x25<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"srai")) {//26
		op.w[1]|=(0x26<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"srli")) {//27
		op.w[1]|=(0x27<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"deposit")) {//28
		op.w[1]|=(0x28<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"extract")) {//29
		op.w[1]|=(0x29<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"shrp")) {//2A
		op.w[1]|=(0x2A<<7);
		if (cmdn>1) {cmderrn=cmds[0];}
	} else if (memicmpd(works+cmds[0],"padd")) {//30,00
		op.w[1]|=(0x30<<7);
		if (cmdn==2) op.b[0]|=0x00<<2;
		else if (memicmpn(works+cmds[2],"u")) op.b[0]|=0x01<<2;
		else if (memicmpn(works+cmds[2],"s")) op.b[0]|=0x02<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"paddincr")) {//30,03
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x03<<2;
		if (cmdn>2) cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"psub")) {//30,04
		op.w[1]|=(0x30<<7);
		if (cmdn==2) op.b[0]|=0x04<<2;
		else if (memicmpn(works+cmds[2],"u")) op.b[0]|=0x05<<2;
		else if (memicmpn(works+cmds[2],"s")) op.b[0]|=0x06<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"psubdecr")) {//30,07
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x07<<2;
		if (cmdn!=2) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"pavg")) {//30,08
		op.w[1]|=(0x30<<7);
		if (cmdn==2) op.b[0]|=0x08<<2;
		else if (memicmpn(works+cmds[2],"raz")) op.b[0]|=0x09<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"psubavg")) {//30,0A
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x0A<<2;
		if (cmdn!=2) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"pshiftadd")) {//30,11
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x10<<2;
		if (cmdn==4) {
			if (memicmpd(works+cmds[1],"1")) op.b[0]|=0x00;
			else if (memicmpd(works+cmds[1],"2")) op.b[0]|=0x01;
			else if (memicmpd(works+cmds[1],"4")) op.b[0]|=0x02;
			else if (memicmpd(works+cmds[1],"8")) op.b[0]|=0x03;
			else cmderrn=cmds[1];
			i=2;
		} else if (cmdn==3) {op.b[0]|=0x01;i=1;} //subword=2
		else cmderrn=cmds[(cmdn>3)?3:cmdn];
		if (cmderrn==-1) {
			if (memicmpn(works+cmds[i+1],"l")) op.b[0]|=0x00<<2;
			else if (memicmpn(works+cmds[i+1],"r")) op.b[0]|=0x04<<2;
			else cmderrn=cmds[i+1];
			if (memicmpd(works+cmds[i],"1")) op.b[0]|=0x01<<2;
			else if (memicmpd(works+cmds[i],"2")) op.b[0]|=0x02<<2;
			else if (memicmpd(works+cmds[i],"3")) op.b[0]|=0x03<<2;
			else cmderrn=cmds[i];
		}
	} else if (memicmpd(works+cmds[0],"pcmp")) {//30,20
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x20<<2;
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		for(i=0;i<8;i++) {
			if (memicmpd(works+cmds[2],cmps[i])) break;
		}
		if (i==8) cmderrn=cmds[2];
		else op.b[0]|=(i<<2);
	} else if (memicmpd(works+cmds[0],"pmax")) {//30,28
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x28<<2;
		if (cmdn!=2) cmderrn=cmds[(cmdn>2)?2:cmdn];
	} else if (memicmpd(works+cmds[0],"pmin")) {//30,2A
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x2A<<2;
		if (cmdn!=2) cmderrn=cmds[(cmdn>2)?2:cmdn];
	} else if (memicmpd(works+cmds[0],"and")) {//30,30
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x30<<2;
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"andcm")) {//30,31
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x31<<2;
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"or")) {//30,32
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x32<<2;
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"xor")) {//30,33
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x33<<2;
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"not")) {//30,34
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x34<<2;
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"psum")) {//30,38
		op.w[1]|=(0x30<<7);
		op.b[0]|=0x38<<2;
		if (cmdn!=2) cmderrn=(cmdn>2)?cmds[2]:cmds[1];
	} else if (memicmpd(works+cmds[0],"pmul")) {//31
		op.w[1]|=(0x31<<7);
		if (memicmpn(works+cmds[cmdn-1],"u")) {op.b[0]|=0x01<<2; i=cmdn-2;}
		else i=cmdn-1;
		if (i<0) cmderrn=cmds[0];
		else if (memicmpd(works+cmds[i],"odd")) op.b[0]|=0x00<<2;
		else if (memicmpd(works+cmds[i],"even")) op.b[0]|=0x02<<2;
		else cmderrn=cmds[i];
		if (i==2) {
			if (memicmpd(works+cmds[1],"1")) {op.b[0]|=0x00; i=2;}
			else if (memicmpd(works+cmds[1],"2")) {op.b[0]|=0x01; i=2;}
			else if (memicmpd(works+cmds[1],"4")) {op.b[0]|=0x02; i=2;}
			else cmderrn=cmds[1];
		} else op.b[0]|=0x01;
	} else if (memicmpd(works+cmds[0],"pmulshr")) {//31
		op.w[1]|=(0x31<<7);
		if (memicmpn(works+cmds[cmdn-1],"a")) {op.b[0]|=0x04<<2; i=cmdn-2;}
		else {op.b[0]|=0x08<<2; i=cmdn-1;}
		if (i<0) cmderrn=cmds[0];
		else if (memicmpd(works+cmds[i],"0")) op.b[0]|=0x00<<2;
		else if (memicmpd(works+cmds[i],"8")) op.b[0]|=0x01<<2;
		else if (memicmpd(works+cmds[i],"15")) op.b[0]|=0x02<<2;
		else if (memicmpd(works+cmds[i],"16")) op.b[0]|=0x03<<2;
		else if (memicmpd(works+cmds[i],"32")) op.b[0]|=0x10<<2;
		else cmderrn=cmds[i];
		if (i==2) {
			if (memicmpd(works+cmds[1],"1")) {op.b[0]|=0x00; }
			else if (memicmpd(works+cmds[1],"2")) {op.b[0]|=0x01; }
			else if (memicmpd(works+cmds[1],"4")) {op.b[0]|=0x02; }
			else cmderrn=cmds[1];
		} else op.b[0]|=0x01;
	} else if (memicmpd(works+cmds[0],"pshift")) {//32,00
		op.w[1]|=(0x32<<7);
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		
		if (memicmpn(works+cmds[2],"l")) op.b[0]|=0x00<<2;
		else if (memicmpn(works+cmds[2],"ra")) op.b[0]|=0x01<<2;
		else if (memicmpn(works+cmds[2],"r")) op.b[0]|=0x02<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"mix")) {//32,10
		op.w[1]|=(0x32<<7);
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		
		if (memicmpn(works+cmds[2],"l")) op.b[0]|=0x10<<2;
		else if (memicmpn(works+cmds[2],"r")) op.b[0]|=0x11<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"check")) {//32,10
		op.w[1]|=(0x32<<7);
		if (cmdn!=2) cmderrn=cmds[(cmdn>2)?2:cmdn];		
		op.b[0]|=0x04<<2;
	} else if (memicmpd(works+cmds[0],"excheck")) {//32,10
		op.w[1]|=(0x32<<7);
		if (cmdn!=2) cmderrn=cmds[(cmdn>2)?2:cmdn];		
		op.b[0]|=0x05<<2;
	} else if (memicmpd(works+cmds[0],"pshifti")) {//33,00
		op.w[1]|=(0x33<<7);
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		
		if (memicmpn(works+cmds[2],"l")) op.b[0]|=0x00<<2;
		else if (memicmpn(works+cmds[2],"ra")) op.b[0]|=0x01<<2;
		else if (memicmpn(works+cmds[2],"r")) op.b[0]|=0x02<<2;
		else cmderrn=cmds[2];
	} else if (memicmpd(works+cmds[0],"mux")) {//33,08
		op.w[1]|=(0x33<<7);
		if (cmdn!=3) cmderrn=cmds[(cmdn>3)?3:cmdn];
		
		if (memicmpn(works+cmds[2],"rev")) op.b[0]|=0x08<<2;
		else if (memicmpn(works+cmds[2],"mix")) op.b[0]|=0x09<<2;
		else if (memicmpn(works+cmds[2],"shuf")) op.b[0]|=0x0A<<2;
		else if (memicmpn(works+cmds[2],"alt")) op.b[0]|=0x0B<<2;
		else if (memicmpn(works+cmds[2],"brcst")) op.b[0]|=0x0C<<2;
		else cmderrn=cmds[2];
	} else if (memicmpn(works+cmds[0],"readsfr")) {//3A
		op.w[1]|=(0x3A<<7);
		if (cmdn!=1) cmderrn=cmds[1];
	} else if (memicmpd(works+cmds[0],"writesfr")) {//#3C,3D
		op.w[1]|=(0x3C<<7);
		if (cmdn==1) ;
		else if (cmdn==2) {
		    op.w[1]|=(0x01<<7);
		    if (memicmpd(works+cmds[1],"set")) op.w[1]|=0x00;
		    else if (memicmpd(works+cmds[1],"and")) op.w[1]|=0x01;
		    else if (memicmpd(works+cmds[1],"or")) op.w[1]|=0x02;
		    else if (memicmpd(works+cmds[1],"xor")) op.w[1]|=0x03;
		    else cmderrn=cmds[1];
		} else cmderrn=cmds[cmdn];
	} else if (memicmpn(works+cmds[0],"halt")) {//3E
		op.w[1]|=(0x3E<<7);
	} else if (memicmpn(works+cmds[0],"nop")) {//3F
		op.w[1]|=(0x3F<<7);
	} else cmderrn=cmds[0];
	/////////////////////////////////////////////////////
	opc=(op.w[1]>>7)&0x3F;
	k=op.b[0]>>2;
	if (((opc==0x30)&&((k&0x38)!=0x10)&&((k&0x38)!=0x30))||(opc==0x32)||(opc==0x33)) {
		if (cmdn<2) {cmderrn=cmds[0];}
		else {
			if (memicmpd(works+cmds[1],"1")) ;
			else if (memicmpd(works+cmds[1],"2")) op.b[0]|=0x01;
			else if (memicmpd(works+cmds[1],"4")) op.b[0]|=0x02;
			else if (memicmpd(works+cmds[1],"8")) op.b[0]|=0x03;
			else cmderrn=cmds[1];
		}
	}
	/////////////////////////////////////////////////////
	switch(opc) {
	case 0x00:fmt=0x01; argm=1; break;//printf("jmp %08lXh========",jmpa); break;
        case 0x01:fmt=0x01; argm=1; break;//printf("jmp.link %08lXh========",jmpa); break;
        case 0x02:fmt=0x03; argm=1; break;//printf("jmp.reg R%d========",Rd); break;
        case 0x03:fmt=0x03; argm=1; break;//printf("jmp.reg.link R%d========",Rd); break;
        case 0x04:fmt=0x10; argm=2; break;//printf("loadi.z.%d R%d,%04Xh========",loadpos,Rd,loadimm); break;
        case 0x05:fmt=0x10; argm=2; break;//printf("loadi.k.%d R%d,%04Xh========",loadpos,Rd,loadimm); break;
        case 0x06:fmt=0x03; argm=0; break;//printf("reti========"); break;
        case 0x07:fmt=0x02; argm=1; break;//printf("trap %04X========",immu); break;
        case 0x08:fmt=0x5A; argm=4; break;//printf("cmp.%s R%d,R%d,P%d,P%d========",cmps[cmprel],Rd,Rs1,Pd1,Pd2); break;
        case 0x09:fmt=0x5B; argm=4; break;//printf("cmpi.%s R%d,%d,P%d,P%d========",cmps[cmprel],Rd,cmpimm,Pd1,Pd2); break;
        case 0x0A:fmt=0x5E; argm=3; break;//printf("testbit R%d.%d,P%d,P%d========",Rd,testb,Pd1,Pd2); break;
        case 0x0B:fmt=0x5C; argm=1; break;//printf("changepr %d========",prset); break;
        case 0x0C:fmt=0x5D; argm=2; break;//printf("changepr.ld %d,%02Xh========",prset,pnewvalue); break;
        case 0x0D:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x0E:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x0F:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x10:fmt=0x40; argm=3; break;//printf("loadx.4 R%d,R%d,R%d========",Rd,Rs1,Rs2); break;
        case 0x11:fmt=0x40; argm=3; break;//printf("loadx.8 R%d,R%d,R%d========",Rd,Rs1,Rs2); break;
        case 0x12:fmt=0x24; argm=3; break;//printf("load.4 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x13:fmt=0x24; argm=3; break;//printf("load.8 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x14:fmt=0x40; argm=3; break;//printf("loadx.4.update R%d,R%d,R%d========",Rd,Rs1,Rs2); break;
        case 0x15:fmt=0x40; argm=3; break;//printf("loadx.8.update R%d,R%d,R%d========",Rd,Rs1,Rs2); break;
        case 0x16:fmt=0x24; argm=3; break;//printf("load.4.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x17:fmt=0x24; argm=3; break;//printf("load.8.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x18:fmt=0x24; argm=3; break;//printf("store.1 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x19:fmt=0x24; argm=3; break;//printf("store.2 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1A:fmt=0x24; argm=3; break;//printf("store.4 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1B:fmt=0x24; argm=3; break;//printf("store.8 R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1C:fmt=0x24; argm=3; break;//printf("store.1.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1D:fmt=0x24; argm=3; break;//printf("store.2.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1E:fmt=0x24; argm=3; break;//printf("store.4.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x1F:fmt=0x24; argm=3; break;//printf("store.8.update R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x20:fmt=0x24; argm=3; break;//printf("addi R%d,R%d,%d========",Rd,Rs1,imms); break;
        case 0x21:fmt=0x24; argm=3; break;//printf("subi R%d,R%d,%d========",Rd,Rs1,imms); break;
        case 0x22:fmt=0x20; argm=3; break;//printf("andi R%d,R%d,%03Xh========",Rd,Rs1,immu); break;
        case 0x23:fmt=0x20; argm=3; break;//printf("ori R%d,R%d,%03Xh========",Rd,Rs1,immu); break;
        case 0x24:fmt=0x20; argm=3; break;//printf("xori R%d,R%d,%03Xh========",Rd,Rs1,immu); break;
        case 0x25:fmt=0x20; argm=3; break;//printf("slli R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x26:fmt=0x20; argm=3; break;//printf("srai R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x27:fmt=0x20; argm=3; break;//printf("srli R%d,R%d,%d========",Rd,Rs1,immu); break;
        case 0x28:fmt=0x30; argm=4; break;//printf("deposit R%d,R%d,%d,%d========",Rd,Rs1,depos_p,depos_l); break;
        case 0x29:fmt=0x30; argm=4; break;//printf("extract R%d,R%d,%d,%d========",Rd,Rs1,depos_p,depos_l); break;
        case 0x2A:fmt=0x4C; argm=4; break;//printf("shrp R%d,R%d,R%d,%d========",Rd,Rs1,Rs2,shrn); break;
        case 0x2B:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x2C:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x2D:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x2E:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x2F:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x30:if (((op.b[0]>>2)==0x34)||((op.b[0]>>2)==0x38)) {fmt=0x4D; argm=2;} //printf("not R%d,R%d========",sw,Rd,Rs1); break;
				  else {fmt=0x4A; argm=3; }//printf("palu.%d R%d,R%d,R%d========",sw,Rd,Rs1,Rs2); break;
				  break;
        case 0x31:fmt=0x4A; argm=3; break;//printf("pmul R%d,R%d,R%d========",Rd,Rs1,Rs2); break;
        case 0x32:fmt=0x4A; argm=3; break;//printf("pshift.%d.l R%d,R%d,R%d========",sw,Rd,Rs1,Rs2); break;
        case 0x33:if(!(op.b[0]&(0x08<<2))) {fmt=0x4B; argm=3; }//printf("pshifti.%d.l R%d,R%d,%d========",sw,Rd,Rs1,pshiftn); break;
				  else {fmt=0x4D; argm=2; break;}//printf("mux.%d.rev R%d,R%d========",sw,Rd,Rs1); break;
				  break;
        case 0x34:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x35:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x36:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x37:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x38:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x39:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x3A:fmt=0x71; argm=2; break;//print2("ReadSFR R%d,S%d========",Rd,Rs1); break;
        case 0x3B:fmt=0x00; argm=0; break;//printf("INVALID========"); break;
        case 0x3C:fmt=0x72; argm=2; break;//print2("WriteSFR S%d,R%d========",Rd,Rs1); break;
        case 0x3D:fmt=0x73; argm=2; break;//print2("WriteSFR.const S%d,%04Xh========",Rd,loadimm); break;
        case 0x3E:fmt=0x03; argm=0; break;//printf("halt========"); break;
        case 0x3F:fmt=0x00; argm=0; break;//printf("NOP========"); break;
		}
		//check argument number
		if ((argn==0)&&(argm!=0)) {argerrn=cmds[cmdn]; errm=argtoofew;}
		else if (argn<argm) {argerrn=args[argn]; errm=argtoofew;}
		else if (argn>argm) {argerrn=args[argm]; errm=argtoomuch;}
		//convert testbit rr.nn to rr,nn
		if ((fmt==0x5E)&&(argn==3)&&(argerrn==-1)) {
			args[3]=args[2]; args[2]=args[1];
			arglen[3]=arglen[2]; arglen[2]=arglen[1];
			argn=4; fmt=0x5B;
			i=args[0];
			while((works[i]!=',')&&(works[i]!='.')) i++;
			if (works[i]=='.') {
				arglen[1]=args[0]+arglen[0]-i-1;
				args[1]=i+1;
				i=i-args[0];
				while((i>0)&&(works[args[0]+i-1]==' ')) i--;
				arglen[0]=i;
			} else argerrn=i;
		}

		char c1,c2,cn;
		if (argerrn==-1) {
			//argument value and R,P,S check
			for(i=0;i<4;i++) {
				argvalue[i]=0;
				if ((i<argn)&&(argerrn==-1)) {
					c1='R'; c2='r'; cn=32;
					if ((i==3)||((i==2)&&(fmt>0x50))) {c1='P'; c2='p'; cn=8;}
					if (fmt==0x71) {if (i==0) {c1='R'; c2='r'; cn=32;} else {c1='S'; c2='s'; cn=32;}}
					if (fmt==0x72) {if (i==0) {c1='S'; c2='s'; cn=32;} else {c1='R'; c2='r'; cn=32;}}
					if (fmt==0x73) {if (i==0) {c1='S'; c2='s'; cn=32;} }
					if (    ((i==0)&&((fmt>=0x03)&&(fmt<=0x5B)))||
						((i==1)&&((fmt>=0x20)&&(fmt<=0x5A)))||
						((i==2)&&((fmt>=0x40)&&(fmt<=0x5B)&&(fmt!=0x4B)))||
						((i==3)&&((fmt>=0x5A)&&(fmt<=0x5B))) ||
						((i==0)&&((fmt>=0x71)&&(fmt<=0x73))) ||
						((i==1)&&((fmt>=0x71)&&(fmt<=0x72))) 
						) {
						if ((arglen[i]<2)||(arglen[i]>3)) argerrn=args[i];
						else if ((works[args[i]]!=c1)&&(works[args[i]]!=c2)) {argerrn=args[i]; errm=argregname;}
						else if ((works[args[i]+1]<'0')||(works[args[i]+1]>'9')) {argerrn=args[i]+1; errm=argregname;}
						else if ((arglen[i]==3)&&((works[args[i]+1]<'0')||(works[args[i]+1]>'9'))) {argerrn=args[i]+1; errm=argregname;}
						else {argvalue[i]=atoi(works+args[i]+1); if (argvalue[i]>=cn) {argerrn=args[i]; errm=argregn;}}
					} else {
						argvalue[i]=expression(works+args[i],&j);
						if (j>=0) {argerrn=args[i]+j; errm=argconstwrong;}
					}
				}
			}
		}
		//set op of Rd,Rs1,Rs2
		if (argerrn==-1) {
			for(i=0;i<3;i++) {
				if ((i==0)&&((fmt>=0x03)&&(fmt<=0x5B))) {
					op.d|=(argvalue[0]<<18);
				} else if ((i==1)&&((fmt>=0x20)&&(fmt<=0x5A))) {
					op.d|=(argvalue[1]<<13);
				} else if ((i==2)&&((fmt>=0x40)&&(fmt<=0x4C))) {
					op.d|=(argvalue[2]<<8);
				}
				if ((i==0)&&((fmt>=0x71)&&(fmt<=0x73))) {
					op.d|=(argvalue[0]<<18);
				} else if ((i==1)&&((fmt>=0x71)&&(fmt<=0x72))) {
					op.d|=(argvalue[1]<<13);
				}
			}
		//set op of imm
		switch(fmt) {
		case 0x00: break;
		case 0x01: //,jmpa
			i=argvalue[0]-(PC+4);
			if ((i>0x007FFFFC)||(i<=-0x00800000)) {argerrn=args[0]; errm=argoverflow;}
			else op.d|=i&0x007FFFFF;
			break;
		case 0x02: //,immu
			if ((argvalue[0]>0xFFFF)||(argvalue[0]<0)) {argerrn=args[0]; errm=argoverflow;}
			op.w[0]|=argvalue[0];
			break;
		case 0x03: //,Rd
			break;
		case 0x10: //,Rd,loadimm
			//if ((argvalue[1]>0xFFFF)||(argvalue[1]<0)) {argerrn=args[1]; errm=argoverflow;}
			i=(argvalue[1]>>16)&0xFFFF;
			if ((i!=0)&&(i!=0xFFFF)) {argerrn=args[1]; errm=argoverflow;}
			op.w[0]|=argvalue[1]&0xFFFF;
			break;
		case 0x20: //,Rd,Rs1,immu
			//if ((argvalue[2]>0x1FFF)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			i=(argvalue[1]>>13)&0xFFFF;
			if ((i!=0)&&(i!=0x7FFFF)) {argerrn=args[1]; errm=argoverflow;}
			op.w[0]|=argvalue[2]&0x1FFF;
			break;
		case 0x24: //,Rd,Rs1,imms
			if ((argvalue[2]>0x0FFF)||(argvalue[2]<-0x1000)) {argerrn=args[2]; errm=argoverflow;}
			op.w[0]|=argvalue[2]&0x1FFF;
			break;
		case 0x30: //,Rd,Rs1,depos_p,depos_l
			if ((argvalue[2]>0x7F)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			if ((argvalue[3]>0x3F)||(argvalue[3]<0)) {argerrn=args[3]; errm=argoverflow;}
			op.w[0]|=(argvalue[2]&0x7F)<<6;
			op.w[0]|=(argvalue[3]&0x3F);
			break;
		case 0x40: //,Rd,Rs1,Rs2  
		case 0x4A: //,Rd,Rs1,Rs2
			break;
		case 0x4B: //,Rd,Rs1,pshiftn
			if ((argvalue[2]>0x1F)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			break;
		case 0x4C: //,Rd,Rs1,Rs2,shrn
			if ((argvalue[2]>0xFF)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			op.b[0]|=argvalue[3];
			break;
		case 0x4D: //,Rd,Rs1
			break;
		case 0x5A: //,Rd,Rs1,Pd1,Pd2
			if ((argvalue[2]>0x7)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			if ((argvalue[3]>0x7)||(argvalue[3]<0)) {argerrn=args[3]; errm=argoverflow;}
			op.w[0]|=argvalue[2]<<7;
			op.w[0]|=argvalue[3]<<4;
			break;
		case 0x5B: //,Rd,cmpimm,Pd1,Pd2
			if ((argvalue[1]>0x7F)||(argvalue[1]<-0x80)) {argerrn=args[1]; errm=argoverflow;}
			if ((argvalue[2]>0x7)||(argvalue[2]<0)) {argerrn=args[2]; errm=argoverflow;}
			if ((argvalue[3]>0x7)||(argvalue[3]<0)) {argerrn=args[3]; errm=argoverflow;}
			op.d|=(argvalue[1]&0xFF)<<10;
			op.w[0]|=argvalue[2]<<7;
			op.w[0]|=argvalue[3]<<4;
			break;
		case 0x5C: //,prset
			if ((argvalue[0]>0xF)||(argvalue[0]<0)) {argerrn=args[0]; errm=argoverflow;}
			op.w[0]|=argvalue[0];
			break;
		case 0x5D: //,prset,pnewvalue
			if ((argvalue[0]>0xF)||(argvalue[0]<0)) {argerrn=args[0]; errm=argoverflow;}
			if ((argvalue[1]>0x7)||(argvalue[1]<0)) {argerrn=args[1]; errm=argoverflow;}
			op.w[0]|=argvalue[0];
			op.d|=argvalue[1]<<10;
			break;
		case 0x73: //Sd,immu
			//if ((argvalue[1]>0xFFFF)||(argvalue[1]<0)) {argerrn=args[0]; errm=argoverflow;}
			i=(argvalue[1]>>16)&0xFFFF;
			if ((i!=0)&&(i!=0xFFFF)) {argerrn=args[1]; errm=argoverflow;}
			op.w[0]|=argvalue[1]&0xFFFF;
			break;
		}
		}
		for(i=0;i<4;i++) resultp->b[(PC&blkmask)+i]=op.b[3-i];
		PC+=4;
		if ((PC&blkmask)==0) {
			resultp->next=new struct resultt;
			resultp=resultp->next;
		}
lab_encend:;
	if (cmderrn>=0) {
		disperr("unknown instruction");
		dispptr(cmderrn);
	} else if (argerrn>=0) {
		if (errm==argtoofew) disperr("Argument too few");
		else if (errm==argtoomuch) disperr("Argument too much");
		else if (errm==argregname) disperr("Register name error");
		else if (errm==argregn) disperr("Register number error");
		else if (errm==argoverflow) disperr("Immediate value overflow");
		else if (errm==argconstwrong) disperr("Immediate value error");
		else disperr("unknown identifier");
		dispptr(argerrn);
	} else {
		print1("%08X ",oldpc);
		if (PC-oldpc<4) j=PC-oldpc;
		else j=4;
		for(i=0;i<j;i++) print1("%02X",rest->b[(oldpc+i)&blkmask]);
		for(;i<4;i++) print1("  ");
		print1(" ");
		for(i=0;i<textp->macrodepth;i++) print1(">");
		print1("%s\n",textp->s);
		oldpc+=j;
		if ((oldpc&blkmask)==0) rest=rest->next;
		while(PC!=oldpc) {
			print1("         ");
			if (PC-oldpc<4) j=PC-oldpc;
			else j=4;
			for(i=0;i<j;i++) print1("%02X",rest->b[(oldpc+i)&blkmask]);
			for(;i<4;i++) print1("  ");
			print1("\n");
			oldpc+=j;
		}		
	}
	return(4);

}

void parse2()
{
	textp=text0;
	resultp=&result;
	PC=0;
	while(textp!=NULL) {

		if (textp->dopass2) {
			parse_instruct();
		} else {
			print1("%08X ",textp->PC);
			if (textp->ispreprocess) print1("%08X ",textp->preprecessv);
			else print1("         ");
			for(int i=0;i<textp->macrodepth;i++) print1(">");
			print1("%s\n",textp->s);
		}
		textp=textp->next;
	}
}

void parse1(void)
{
	int i,j,k,m,n;
	int commentdepth0;
	bool inmacro;
	bool cont;
	char *temps;
	//def0=NULL;
	defp=def0;
	labren0=NULL;
	labrenp=NULL;
	lab0=NULL;
	labp=NULL;
	mac0=NULL;
	macp=NULL;
	textp=text0;
	inmacro=0;
	PC=0;
	ifdepth=0; 
	while(textp!=NULL) {
		textp->PC=PC;
		textp->dopass2=0;
		textp->s0=textp->s; //reserve for macro arg
		j=0;
		if (inmacro) {
			macp->linen++;
		} else {
			commentdepth0=commentdepth;
			j=strblankn(textp->s);
			if (!memicmpn(textp->s+j,"#ifdef")&&!memicmpn(textp->s+j,"#ifndef")&&!memicmpn(textp->s+j,"#define")) 
				textp->s=convert_define(textp->s,textp->macrodepth);
			if (commentdepth0!=0) {
				j=0;
				while ((commentdepth0!=0)&&(textp->s[j]!=0)) {
					if ((textp->s[j]=='*')&&(textp->s[j+1]=='/')) {
						j+=2;
						commentdepth0--;
					} else j++;
				}
				if (commentdepth0!=0) {
					textp=textp->next;
					continue;
				}
			}
		}
		cont=true;
		if (textp->s[0]=='.') {
			if (memicmpn(textp->s+1,"byte")) {
				textp->s[0]=' ';
				textp->s[1]='D';
				textp->s[2]='B';
				textp->s[3]=' ';
				textp->s[4]=' ';
			} else if (memicmpn(textp->s+1,"align")) {
				j=0;
				while(textp->s[j]>' ') j++;
				while((textp->s[j]>0)&&(textp->s[j]<=' ')) j++;
				k=atoi(textp->s+j);
				if (k>0) {
					if ((PC%k)!=0) PC+=(k-(PC%k));
				}
				cont=false;
			} else {
				cont=false;
			}
		}
		if ((j==0)&&(textp->s[0]>' ')&&((j=strlabn(textp->s))>0)&&iftrue) { //define and label
			if (textp->s[j]==':') {
				add_label(textp->s,j,PC,inmacro);
				j++;
				j+=strblankn(textp->s+j);
				if (inmacro) cont=false;
			} else if (textp->s[j]==' ') {
				if ((j==2)&&((textp->s[0]=='p')||(textp->s[0]=='P'))&&((textp->s[1]>='0')&&(textp->s[1]<='7'))) {
					j=0;
					cont=true;
				} else {
					k=j;
					j++;
					j+=strblankn(textp->s+j);
						if (memicmpn(textp->s+j,"equ")) {
						if (!inmacro) {
							j+=3;
							j+=strblankn(textp->s+j);
							n=strendn(textp->s+j);
							add_define(textp->s,textp->s+j,k,n);
							textp->ispreprocess=1;
							temps=convert_define(textp->s+j-1,textp->macrodepth);
							textp->preprecessv=expression(temps,NULL);
							if (temps!=textp->s+j-1) delete [] temps;
						}
						cont=0;
					} else if (memicmpn(textp->s+j,"macro")) {//macro
						if (inmacro) {
							disperr("macro cannot nested");
						} else {
							j+=5;
							add_macro(k,j);
							inmacro=1;
							cont=false;
						}
					} else if (memicmpn(textp->s+j,"endp")) {//endp
						cont=false;
					} else {
						add_label(textp->s,k,PC,inmacro);
						if (inmacro) cont=false;
					}
				}
			} else {
				disperr("variable error");
				dispptr(j);
			}
		}
		if (cont) {
			j+=strblankn(textp->s+j);
			if (iftrue&&memicmpn(textp->s+j,"endm")) {
				if (inmacro) {
					inmacro=0;
				} else if (textp->macrodepth==0) {
					disperr("macro-endm not match");
				} else {
					pop_macro();
				}
			} else if (!inmacro) {
				if ((textp->s[j]=='/')&&(textp->s[j+1]=='*')) ;
				else if (textp->s[j]=='#') {
					j++;
					if (memcmpn(textp->s+j,"ifdef")) {
							j+=5; 
							j+=strblankn(textp->s+j);
							k=strvarn(textp->s+j);
							if (find_def(textp->s+j,k)!=NULL) ifvalue[ifdepth]=1;
							else ifvalue[ifdepth]=0;
							ifskip[ifdepth]=0;
							ifdepth++;
					} else if (memcmpn(textp->s+j,"ifndef")) {
							j+=6; 
							j+=strblankn(textp->s+j);
							k=strvarn(textp->s+j);
							if (find_def(textp->s+j,k)!=NULL) ifvalue[ifdepth]=0;
							else ifvalue[ifdepth]=1;
							ifskip[ifdepth]=0;
							ifdepth++;
					} else if (memcmpn(textp->s+j,"if")) {
							j+=2; 
							j+=strblankn(textp->s+j);
							k=expression(textp->s+j,&m);
							if (m>=0) {
								disperr("expression error");
							}
							if (k!=0) ifvalue[ifdepth]=1;
							else ifvalue[ifdepth]=0;
							ifskip[ifdepth]=0;
							ifdepth++;
					} else if (memcmpn(textp->s+j,"elif")) {
						if (ifdepth==0) {
							disperr("error if block");
						} else if (ifskip[ifdepth-1]==1) {
							//nop
						} else if (ifvalue[ifdepth-1]==0) {
							j+=4;
							j+=strblankn(textp->s+j);
							k=expression(textp->s+j,&m);
							if (m>=0) {
								disperr("expression error");
							}
							if (k!=0) ifvalue[ifdepth-1]=1;
							else ifvalue[ifdepth-1]=0;
						} else { //ifvalue[ifdepth-1]==1)
							ifvalue[ifdepth-1]=0;
							ifskip[ifdepth-1]=1;
						}
						//ifdepth no change
					} else if (memcmpn(textp->s+j,"else")) {
						if (ifdepth==0) {
							disperr("error if block");
						} else if (ifskip[ifdepth-1]==1) {
							//nop
						} else ifvalue[ifdepth-1]=!ifvalue[ifdepth-1];
					} else if (memcmpn(textp->s+j,"endif")) {
						if (ifdepth==0) {
							disperr("error if block");
						} else {
							ifdepth--;
						}
					} else if (iftrue) {
						if (memcmpn(textp->s+j,"include")) {//#include
							expand_include(j+7);
						}
						else if (iftrue&&memcmpn(textp->s+j,"define")) {//#define
							j+=6;
							j+=strblankn(textp->s+j);
							i=j;
							k=strvarn(textp->s+j);
							j+=k;
							if (textp->s[j]>' ') {
								disperr("variable error");
								dispptr(j);
							} else {
								j+=strblankn(textp->s+j);
								m=j;
								n=strendn(textp->s+m);
								add_define(textp->s+i,textp->s+m,k,n);
								textp->ispreprocess=1;
								temps=convert_define(textp->s+i+k,textp->macrodepth);
								textp->preprecessv=expression(temps,NULL);
								if (temps!=textp->s+i+k) delete [] temps;
							}
						} else if (iftrue) {
							//dispwarn("Unknown preprocessor");
							//dispptr(j);
						}
					}
				} else if (memicmpn(textp->s+j,"end")) {
					struct textt *tt,*ttn;
					tt=textp->next;
					while(tt!=NULL) {
						ttn=tt->next;
						delete [] tt->s;
						delete tt;
						tt=ttn;
					}
					textp->next=NULL;
					break;
				} else if (iftrue) {
					if (memicmpn(textp->s+j,"proc")) {
					} else if (memicmpn(textp->s+j,"endp")) {
					} else if (memicmpn(textp->s+j,"org")) {
						j+=3;
						j+=strblankn(textp->s+j);
						i=expression(textp->s+j,&m);
						if (m>=0) {
							disperr("number error");
						} else if (i<PC) {
							disperr("PC rewind");
						} else {
							PC=i;
						}
					} else if ((memicmpn(textp->s+j,"db"))||(memicmpn(textp->s+j,"dw"))||(memicmpn(textp->s+j,"dd"))) {
						textp->pass2st=j;
						textp->dopass2=1;
						if (memicmpn(textp->s+j,"db")) m=1;
						else if (memicmpn(textp->s+j,"dw")) m=2;
						else if (memicmpn(textp->s+j,"dd")) m=4;
						j+=2;
						j+=strblankn(textp->s+j);
						i=0;
						while(!isends(textp->s+j)) {
							if (textp->s[j]==',') i++;
							j++;
						}
						PC+=((i+1)*m);
					} else {
						struct macrot *mact;
						mact=ismacro(textp->s+j);
						if (mact!=NULL) {
							push_macro(j,mact,PC);
						} else if (isends(textp->s+j)) {//normal
						} else {
							PC+=4;
							textp->dopass2=1;
							textp->pass2st=j;
						}
					}
				}
			}
		}
		textp=textp->next;
	}
	if (commentdepth!=0) {
		disperr("/*Comment not finish");
	}
}

void outputf(char *fname,char ftype)
{
	FILE *FO;
	int i,j,k,m,n,b,l;
    //int how;

	if (ftype=='b') 
		FO=fopen(fname,"wb");
	else
		FO=fopen(fname,"w");
	n=totalbytes/blksize;	
	//
	//fprintf(FO,":%d\n",totalbytes); //intel extended format
	//fprintf(FO,":%d\n",blksize); //intel extended format
	//fprintf(FO,":%d\n",n); //intel extended format
	//
	resultp=&result;
	for(b=0;b<=n;b++) {
		if ((ftype=='h')&&(n!=0)) {
			i=b<<16;
			if (n>=16) {
				j=(i&0xFF)+0x02+0x02;
				fprintf(FO,":02000002%02X00%02x\n",i,(0x100-j)&0xFF); //intel extended format
			} else {
				j=(i&0xFF)+(i>>8)+0x03+0x02;
				fprintf(FO,":03000002%04X00%02x\n",i,(0x100-j)&0xFF); //intel extended format
			}
		}
		m=(b==n)?(totalbytes&blkmask):blkmask;
		if (ftype=='b') {
			fwrite(resultp->b,m,1,FO);
            //fprintf(FO,":%d\n",how); //intel extended format

		} else if (ftype=='h') {
			for(l=0;l<m;l+=16) {
				if ((b*blksize+l+16)>totalbytes) k=totalbytes&0x0F; else k=16;
				j=((b*blksize)+l)&0xFFFF;
				fprintf(FO,":%02X%04X00",k,j);
				for(i=0;i<k;i++) fprintf(FO,"%02X",resultp->b[l+i]);
				j=(j&0xFF)+(j>>8)+k;
				for(i=0;i<k;i++) j+=resultp->b[l+i];
				j=0x7F00-j;
				fprintf(FO,"%02X\n",(j&0xFF));
			}
		}
	}
	if (ftype=='h') {
		if (n>16) fprintf(FO,":0400000300000000F9\n");
		fprintf(FO,":00000001FF\n");
	}
	fclose(FO);

}

bool cmddefine(char *s)
{
	int k,n;
	k=strvarn(s);
	if (s[k]!='=') {
		printf("define error %s\n",s);
		return(false);
	} else {
		n=strendn(s+k+1);
		add_define(s,s+k+1,k,n);
	}
	return(true);
}
int main(int argc,char *argv[])
{
	int i,j,err=0;
	char ss[1000];
	char *iname=NULL;
	char *oname=NULL;
	if (argc<2) err=1;
	else {
		for(i=1;i<argc;i++) {
			if ((argv[i][0]=='-')||(argv[i][0]=='/')) {
				if (argv[i][1]=='o') {
					if (oname!=NULL) printf("Error:%s outputname already declared as %s\n",argv[i],oname);
					oname=argv[i]+2;
				} else if (argv[i][1]=='D') {
					if (!cmddefine(argv[i]+2)) err=1;
				}
			} else {
				if (iname!=NULL) printf("Error:%s inputname already exist as %s\n",argv[i],iname);
				iname=argv[i];
			}
		}
	}
	if (err) {
		printf("PLXASM file.asm [-ooutname] [/Ddefine=value]\n");
		return(1);
	}
	strcpy(basedir,iname);
	i=strlen(basedir);
	while((i>0)&&(basedir[i-1]!='\\')&&(basedir[i-1]!='/')) i--;
	basedir[i]=0;
	strcpy(filename[0],iname+i);

	if (oname!=NULL) {
		strcpy(ss,oname);
		j=strlen(ss);
	} else {
		strcpy(ss,iname);
		j=strlen(ss);
		while((j>i)&&(ss[j-1]!='.')) j--;
		if (j==i) j=i+strlen(ss+i); else j--;
	}
	strcpy(ss+j,".lst");
	openlog(ss);
	ss[j]=0;

	text0=loadfile(0,NULL);
	if (text0==NULL) {
		printf("Error: %s file not found\n",argv[1]);
		return(1);
	}
	filen=1;


	parse1();
	if (totalerr!=0) return 2;

	while(def0!=NULL) {
		defp=def0->next;
		delete def0;
		def0=defp;
	}

	totalbytes=PC;
	parse2();

	while(lab0!=NULL) {
		labp=lab0->next;
		delete lab0;
		lab0=labp;
	}

	while(mac0!=NULL) {
		macp=mac0->next;
		delete mac0;
		mac0=macp;
	}

	j=strlen(ss);
	strcpy(ss+j,".bin");
	outputf(ss,'b');
	strcpy(ss+j,".hex");
	outputf(ss,'h');
	print2("%d warnings, %d errors\n",totalwarn, totalerr);

	closelog();

	return(totalerr+totalwarn);
}
