【しばらく編集不可モードで運営します】 編集(管理者用) | 差分 | 新規作成 | 一覧 | RSS | FrontPage | 検索 | 更新履歴

CategoryLanguage - --(

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define NON 0

#define PROG 1

#define DATW 2

#define DATL 4

#define ANLZ 8

#define swapw(a) ((((a)<<8) &0xff00)+(((a)>>8) &0x00ff))

#define swapl(a) ((((a)<<24) &0xff000000)+(((a)<<8) &0x00ff0000)+(((a)>>8) &0x0000ff00)+(((a)>>24) &0x000000ff))

int offset,size,start,maxlabel;
unsigned short *buf;
char inst[256];
unsigned char flag[65536];

typedef struct LABELLIST {
	int adr;
	short type;
	short next;
} Labellist;

Labellist labellist[32768+1024];

void initlabellist()
{
	int i;
	for(i=0;i<32768+1024;i++)
		labellist[i].next=-1;
	maxlabel=0;
}

void addlabel(int q,int t)
{
	int i,j;
	i=((q+q/17)&1023)+32768;
	while((j=labellist[i].next)>=0)
		if(labellist[j].adr==q){
			labellist[j].type|=t;
			return;
		} else
			i=j;
	labellist[i].next=maxlabel;
	labellist[maxlabel].adr=q;
	labellist[maxlabel].next=-1;
	labellist[maxlabel++].type=t;
	if(maxlabel==32768){
		printf("ラベルが多すぎます\n");
		exit(1);
	}
}

void sublabel(int q,int t)
{
	int i,j;
	i=((q+q/17)&1023)+32768;
	while((j=labellist[i].next)>=0)
		if(labellist[j].adr==q){
			labellist[j].type&=~t;
			return;
		} else
			i=j;
	labellist[i].next=maxlabel;
	labellist[maxlabel].adr=q;
	labellist[maxlabel].next=-1;
	labellist[maxlabel++].type=0;
	if(maxlabel==32768){
		printf("ラベルが多すぎます\n");
		exit(1);
	}
}

int getlabel(int q)
{
	int i,j;
	i=((q+q/17)&1023)+32768;
	while((j=labellist[i].next)>=0)
		if(labellist[j].adr==q){
			return labellist[j].type;
		} else
			i=j;
	return -1;
}

void dis(unsigned short a,int q)
{
	unsigned long b,c,d;
	inst[0]=0;
	switch(a>>12){
	case 0:
		b=(a>>4)&15;
		c=(a>>8)&15;
		switch(a&15){
		case 2:
			switch(b){
			case 0:
				sprintf(inst,"stc\tSR,r%d",c);
				break;
			case 1:
				sprintf(inst,"stc\tGBR,r%d",c);
				break;
			case 2:
				sprintf(inst,"stc\tVBR,r%d",c);
				break;
			}
			break;
		case 3:
			switch(b){
			case 0:
				sprintf(inst,"bsrf\tr%d",c);
				break;
			case 2:
				sprintf(inst,"braf\tr%d",c);
				break;
			}
			break;
		case 4:
			sprintf(inst,"mov.b\tr%d,(r0,r%d)",b,c);
			break;
		case 5:
			sprintf(inst,"mov.w\tr%d,(r0,r%d)",b,c);
			break;
		case 6:
			sprintf(inst,"mov.l\tr%d,(r0,r%d)",b,c);
			break;
		case 7:
			sprintf(inst,"mul?\tr%d,r%d",b,c);
			break;
		case 8:
			switch(b){
			case 0:
				strcpy(inst,"clrt");
				break;
			case 1:
				strcpy(inst,"sett");
				break;
			case 2:
				strcpy(inst,"clrmac");
				break;
			}
			break;
		case 9:
			switch(b){
			case 0:
				strcpy(inst,"nop");
				break;
			case 1:
				strcpy(inst,"div0u");
				break;
			case 2:
				sprintf(inst,"movt\tr%d",c);
				break;
			}
			break;
		case 10:
			switch(b){
			case 0:
				sprintf(inst,"sts\tMACH,r%d",c);
				break;
			case 1:
				sprintf(inst,"sts\tMACL,r%d",c);
				break;
			case 2:
				sprintf(inst,"sts\tPR,r%d",c);
				break;
			}
			break;
		case 11:
			switch(b){
			case 0:
				strcpy(inst,"rts");
				break;
			case 1:
				strcpy(inst,"sleep");
				break;
			case 2:
				strcpy(inst,"rte");
				break;
			}
			break;
		case 12:
			sprintf(inst,"mov.b\t(r0,r%d),r%d",b,c);
			break;
		case 13:
			sprintf(inst,"mov.w\t(r0,r%d),r%d",b,c);
			break;
		case 14:
			sprintf(inst,"mov.l\t(r0,r%d),r%d",b,c);
			break;
		case 15:
			sprintf(inst,"mac.l\t@r%d+,@r%d+",b,c);
			break;
		}
		break;
	case 1:
		b=(a>>4)&15;
		c=(a&15)*4;
		d=(a>>8)&15;
		sprintf(inst,"mov.l\tr%d,@(H'%02x,r%d)",b,c,d);
		break;
	case 2:
		b=(a>>4)&15;
		c=(a>>8)&15;
		switch(a&15){
		case 0:
			sprintf(inst,"mov.b\tr%d,@r%d",b,c);
			break;
		case 1:
			sprintf(inst,"mov.w\tr%d,@r%d",b,c);
			break;
		case 2:
			sprintf(inst,"mov.l\tr%d,@r%d",b,c);
			break;
		case 4:
			sprintf(inst,"mov.b\tr%d,@-r%d",b,c);
			break;
		case 5:
			sprintf(inst,"mov.w\tr%d,@-r%d",b,c);
			break;
		case 6:
			sprintf(inst,"mov.l\tr%d,@-r%d",b,c);
			break;
		case 7:
			sprintf(inst,"div0s\tr%d,r%d",b,c);
			break;
		case 8:
			sprintf(inst,"tst\tr%d,r%d",b,c);
			break;
		case 9:
			sprintf(inst,"and\tr%d,r%d",b,c);
			break;
		case 10:
			sprintf(inst,"xor\tr%d,r%d",b,c);
			break;
		case 11:
			sprintf(inst,"or\tr%d,r%d",b,c);
			break;
		case 12:
			sprintf(inst,"cmp/str\tr%d,r%d",b,c);
			break;
		case 13:
			sprintf(inst,"xtrct\tr%d,r%d",b,c);
			break;
		case 14:
			sprintf(inst,"mulu\tr%d,r%d",b,c);
			break;
		case 15:
			sprintf(inst,"muls\tr%d,r%d",b,c);
			break;
		}
		break;
	case 3:
		b=(a>>4)&15;
		c=(a>>8)&15;
		switch(a&15){
		case 0:
			sprintf(inst,"cmp/eq\tr%d,r%d",b,c);
			break;
		case 2:
			sprintf(inst,"cmp/hs\tr%d,r%d",b,c);
			break;
		case 3:
			sprintf(inst,"cmp/ge\tr%d,r%d",b,c);
			break;
		case 4:
			sprintf(inst,"div1\tr%d,r%d",b,c);
			break;
		case 5:
			sprintf(inst,"dmulu.l\tr%d,r%d",b,c);
			break;
		case 6:
			sprintf(inst,"cmp/hi\tr%d,r%d",b,c);
			break;
		case 7:
			sprintf(inst,"cmp/gt\tr%d,r%d",b,c);
			break;
		case 8:
			sprintf(inst,"sub\tr%d,r%d",b,c);
			break;
		case 10:
			sprintf(inst,"subc\tr%d,r%d",b,c);
			break;
		case 11:
			sprintf(inst,"subv\tr%d,r%d",b,c);
			break;
		case 12:
			sprintf(inst,"add\tr%d,r%d",b,c);
			break;
		case 13:
			sprintf(inst,"dmuls.l\tr%d,r%d",b,c);
			break;
		case 14:
			sprintf(inst,"addc\tr%d,r%d",b,c);
			break;
		case 15:
			sprintf(inst,"addv\tr%d,r%d",b,c);
			break;
		}
		break;
	case 4:
		b=(a>>4)&15;
		c=(a>>8)&15;
		switch(a&15){
		case 0:
			switch(b){
			case 0:
				sprintf(inst,"shll\tr%d",c);
				break;
			case 1:
				sprintf(inst,"dt\tr%d",c);
				break;
			case 2:
				sprintf(inst,"shal\tr%d",c);
				break;
			}
			break;
		case 1:
			switch(b){
			case 0:
				sprintf(inst,"shlr\tr%d",c);
				break;
			case 1:
				sprintf(inst,"cmp/pz\tr%d",c);
				break;
			case 2:
				sprintf(inst,"shar\tr%d",c);
				break;
			}
			break;
		case 2:
			switch(b){
			case 0:
				sprintf(inst,"sts.l\tMACH,@-r%d",c);
				break;
			case 1:
				sprintf(inst,"sts.l\tMACL,@-r%d",c);
				break;
			case 2:
				sprintf(inst,"sts.l\tPR,@-r%d",c);
				break;
			}
			break;
		case 3:
			switch(b){
			case 0:
				sprintf(inst,"stc.l\tSR,@-r%d",c);
				break;
			case 1:
				sprintf(inst,"stc.l\tGBR,@-r%d",c);
				break;
			case 2:
				sprintf(inst,"stc.l\tVBR,@-r%d",c);
				break;
			}
			break;
		case 4:
			switch(b){
			case 0:
				sprintf(inst,"rotl\tr%d",c);
				break;
			case 2:
				sprintf(inst,"rotcl\tr%d",c);
				break;
			}
			break;
		case 5:
			switch(b){
			case 0:
				sprintf(inst,"rotr\tr%d",c);
				break;
			case 1:
				sprintf(inst,"cmp/pl\tr%d",c);
				break;
			case 2:
				sprintf(inst,"rotcr\tr%d",c);
				break;
			}
			break;
		case 6:
			switch(b){
			case 0:
				sprintf(inst,"lds.l\t@r%d+,MACH",c);
				break;
			case 1:
				sprintf(inst,"lds.l\t@r%d+,MACL",c);
				break;
			case 2:
				sprintf(inst,"lds.l\t@r%d+,PR",c);
				break;
			}
			break;
		case 7:
			switch(b){
			case 0:
				sprintf(inst,"ldc.l\t@r%d+,SR",c);
				break;
			case 1:
				sprintf(inst,"ldc.l\t@r%d+,GBR",c);
				break;
			case 2:
				sprintf(inst,"ldc.l\t@r%d+,VBR",c);
				break;
			}
			break;
		case 8:
			switch(b){
			case 0:
				sprintf(inst,"shll2\tr%d",c);
				break;
			case 1:
				sprintf(inst,"shll8\tr%d",c);
				break;
			case 2:
				sprintf(inst,"shll16\tr%d",c);
				break;
			}
			break;
		case 9:
			switch(b){
			case 0:
				sprintf(inst,"shlr2\tr%d",c);
				break;
			case 1:
				sprintf(inst,"shlr8\tr%d",c);
				break;
			case 2:
				sprintf(inst,"shlr16\tr%d",c);
				break;
			}
			break;
		case 10:
			switch(b){
			case 0:
				sprintf(inst,"lds\t@r%d,MACH",c);
				break;
			case 1:
				sprintf(inst,"lds\t@r%d,MACL",c);
				break;
			case 2:
				sprintf(inst,"lds\t@r%d,PR",c);
				break;
			}
			break;
		case 11:
			switch(b){
			case 0:
				sprintf(inst,"jsr\t@r%d",c);
				break;
			case 1:
				sprintf(inst,"tas.b\t@r%d",c);
				break;
			case 2:
				sprintf(inst,"jmp\t@r%d",c);
				break;
			}
			break;
		case 14:
			switch(b){
			case 0:
				sprintf(inst,"ldc.l\tr%d,SR",c);
				break;
			case 1:
				sprintf(inst,"ldc.l\tr%d,GBR",c);
				break;
			case 2:
				sprintf(inst,"ldc.l\tr%d,VBR",c);
				break;
			}
			break;
		case 15:
			sprintf(inst,"mac.l\t@r%d+,r%d",b,c);
			break;
		}
		break;
	case 5:
		b=(a&15)*4;
		c=(a>>4)&15;
		d=(a>>8)&15;
		sprintf(inst,"mov.l\t@(H'%02x,r%d),r%d",b,c,d);
		break;
	case 6:
		b=(a>>4)&15;
		c=(a>>8)&15;
		switch(a&15){
		case 0:
			sprintf(inst,"mov.b\t@r%d,r%d",b,c);
			break;
		case 1:
			sprintf(inst,"mov.w\t@r%d,r%d",b,c);
			break;
		case 2:
			sprintf(inst,"mov.l\t@r%d,r%d",b,c);
			break;
		case 3:
			sprintf(inst,"mov\tr%d,r%d",b,c);
			break;
		case 4:
			sprintf(inst,"mov.b\t@r%d+,r%d",b,c);
			break;
		case 5:
			sprintf(inst,"mov.w\t@r%d+,r%d",b,c);
			break;
		case 6:
			sprintf(inst,"mov.l\t@r%d+,r%d",b,c);
			break;
		case 7:
			sprintf(inst,"not\tr%d,r%d",b,c);
			break;
		case 8:
			sprintf(inst,"swap.b\tr%d,r%d",b,c);
			break;
		case 9:
			sprintf(inst,"swap.w\tr%d,r%d",b,c);
			break;
		case 10:
			sprintf(inst,"negc\tr%d,r%d",b,c);
			break;
		case 11:
			sprintf(inst,"neg\tr%d,r%d",b,c);
			break;
		case 12:
			sprintf(inst,"extu.b\tr%d,r%d",b,c);
			break;
		case 13:
			sprintf(inst,"extu.w\tr%d,r%d",b,c);
			break;
		case 14:
			sprintf(inst,"exts.b\tr%d,r%d",b,c);
			break;
		case 15:
			sprintf(inst,"exts.w\tr%d,r%d",b,c);
			break;
		}
		break;
	case 7:
		b=a&0xff;
		if(b>=0x80)
			b|=0xffffff00;
		c=(a>>8)&15;
		sprintf(inst,"add\t#H'%08x,r%d",b,c);
		break;
	case 8:
		b=a&15;
		c=(a>>4)&15;
		d=a&0xff;
		if(d>=0x80)
			d|=0xffffff00;
		switch((a>>8)&15){
		case 0:
			sprintf(inst,"mov.b\tr0,@(H'%02x,r%d)",b,c);
			break;
		case 1:
			sprintf(inst,"mov.w\tr0,@(H'%02x,r%d)",b*2,c);
			break;
		case 4:
			sprintf(inst,"mov.b\t@(H'%02x,r%d),r0",b,c);
			break;
		case 5:
			sprintf(inst,"mov.w\t@(H'%02x,r%d),r0",b*2,c);
			break;
		case 8:
			sprintf(inst,"cmp/eq\t#H'%08x,r0",d);
			break;
		case 9:
			sprintf(inst,"bt\tL%08x",q+d*2+4);
			break;
		case 11:
			sprintf(inst,"bf\tL%08x",q+d*2+4);
			break;
		case 13:
			sprintf(inst,"bt/s\tL%08x",q+d*2+4);
			break;
		case 15:
			sprintf(inst,"bf/s\tL%08x",q+d*2+4);
			break;
		}
		break;
	case 9:
		b=q+(a&0xff)*2+4;
		c=(a>>8)&15;
		sprintf(inst,"mov.w\t#H'%04x,r%d",swapw(*(buf+(b-offset)/2)),c);
		break;
	case 10:
		b=a&0xfff;
		if(b>=0x800)
			b|=0xfffff000;
		b=q+b*2+4;
		sprintf(inst,"bra\tL%08x",b);
		break;
	case 11:
		b=a&0xfff;
		if(b>=0x800)
			b|=0xfffff000;
		b=q+b*2+4;
		sprintf(inst,"bsr\tL%08x",b);
		break;
	case 12:
		b=a&0xff;
		switch((a>>8)&15){
		case 0:
			sprintf(inst,"mov.b\tr0,@(H'%04x,GBR)",b);
			break;
		case 1:
			sprintf(inst,"mov.w\tr0,@(H'%04x,GBR)",b*2);
			break;
		case 2:
			sprintf(inst,"mov.l\tr0,@(H'%04x,GBR)",b*4);
			break;
		case 3:
			sprintf(inst,"trapa\t#H'%04x",b*4);
			break;
		case 4:
			sprintf(inst,"mov.b\t@(H'%04x,GBR),r0",b);
			break;
		case 5:
			sprintf(inst,"mov.w\t@(H'%04x,GBR),r0",b*2);
			break;
		case 6:
			sprintf(inst,"mov.l\t@(H'%04x,GBR),r0",b*4);
			break;
		case 7:
			sprintf(inst,"mova\tH'%08x,r0",(q&-4)+b*4+4);
			break;
		case 8:
			sprintf(inst,"tst\t#H'%02x,r0",b);
			break;
		case 9:
			sprintf(inst,"and\t#H'%02x,r0",b);
			break;
		case 10:
			sprintf(inst,"xor\t#H'%02x,r0",b);
			break;
		case 11:
			sprintf(inst,"or\t#H'%02x,r0",b);
			break;
		case 12:
			sprintf(inst,"tst.b\t#H'%02x,@(r0,GBR)",b);
			break;
		case 13:
			sprintf(inst,"and.b\t#H'%02x,@(r0,GBR)",b);
			break;
		case 14:
			sprintf(inst,"xor.b\t#H'%02x,@(r0,GBR)",b);
			break;
		case 15:
			sprintf(inst,"or.b\t#H'%02x,@(r0,GBR)",b);
			break;
		}
		break;
	case 13:
		b=(q&-4)+(a&0xff)*4+4;
		c=(a>>8)&15;
		sprintf(inst,"mov.l\t#H'%08x,r%d",swapl(*(long*)(buf+(b-offset)/2)),c);
		break;
	case 14:
		b=a&0xff;
		if(b>=0x80)
			b|=0xffffff00;
		c=(a>>8)&15;
		sprintf(inst,"mov.l\t#H'%08x,r%d",b,c);
		break;
	}
}

int analyze(int q)
{
	unsigned short a;
	unsigned long b,c,d;
	int p;
	p=q;
	putchar('>');
	fflush(stdout);
	if((getlabel(p)&(PROG|ANLZ))==(PROG|ANLZ) ||
	   ((getlabel(p)&PROG) && (q<offset || q>=offset+size))){
	  addlabel(p,PROG|ANLZ);
	  putchar('<');
	  return 0;
	}
	addlabel(p,PROG|ANLZ);
	if(q&1 || q<offset || q>=offset+size){
		putchar('?');
		sublabel(p,PROG);
		return -1;
	}
	while(1){
		a=swapw(*(buf+(q-offset)/2));
		if(flag[a]==0){
			dis(a,q);
			flag[a]=(inst[0]==0)+1;
		}
		if(flag[a]==2){
			printf("?(%08x:%04x)",q,a);
			sublabel(p,PROG);
			return -1;
		}
		switch(a>>12){
		case 0:
			b=(a>>4)&15;
			c=(a>>8)&15;
			switch(a&15){
			case 3:
				switch(b){
				case 2:	/*"braf\tr%d",c*/
					goto b1;
				}
				break;
			case 11:
				switch(b){
				case 0:	/*"rts"*/
				case 1:	/*"sleep"*/
				case 2:	/*"rte"*/
					goto b1;
					break;
				}
				break;
			}
			break;
		case 4:
			b=(a>>4)&15;
			c=(a>>8)&15;
			switch(a&15){
			case 11:
				switch(b){
				case 2:	/*"jmp\t@r%d",c*/
					goto b1;
				}
				break;
			}
			break;
		case 8:
			d=a&0xff;
			if(d>=0x80)
				d|=0xffffff00;
			switch((a>>8)&15){
			case 9:
			case 11:
			case 13:
			case 15:
				addlabel(q+d*2+4,PROG);
				if(analyze(q+d*2+4)<0){
					putchar('?');
					sublabel(p,PROG);
					return -1;
				}
				break;
			}
			break;
		case 9:
			addlabel(q+(a&0xff)*2+4,DATW);
			addlabel(q+(a&0xff)*2+6,NON);
			break;
		case 10:
			b=a&0xfff;
			if(b>=0x800)
				b|=0xfffff000;
			addlabel(q+b*2+4,PROG);
			analyze(q+b*2+4);
			if(analyze(q+b*2+4)<0){
				putchar('?');
				sublabel(p,PROG);
				return -1;
			}
			goto b1;
		case 11:
			b=a&0xfff;
			if(b>=0x800)
				b|=0xfffff000;
			addlabel(q+b*2+4,PROG);
			if(analyze(q+b*2+4)<0){
				putchar('?');
				sublabel(p,PROG);
				return -1;
			}
			break;
		case 12:
			b=a&0xff;
			switch((a>>8)&15){
			case 7:		/*"mova"*/
				addlabel((q&-4)+b*4+4,DATW);
				a=swapw(*(buf+(q+4-offset)/2));
				if((a&0xf0ff)==0x0023){ /*"braf"*/
					b=(q&-4)+b*4+4;
					do {	/*普段見掛けるテーブルジェンプ*/
						c=swapw(*(buf+(b-offset)/2));
						addlabel(q+8+c,PROG);
						b+=2;
					} while(getlabel(b)<0);
				} else
				if((swapw(*(buf+(q+6-offset)/2))&0xf0ff)==0x402b){
					a=swapw(*(buf+(q+2-offset)/2));
					b=d=(q&-4)+b*4+4;
					if((a&0xf00f)==0x000d){
						do {	/*だいななテーブルジェンプ*/
							c=swapw(*(buf+(b-offset)/2));
							addlabel(d+c,PROG);
							b+=2;
						} while(getlabel(b)<0);
					} else
					if((a&0xf00f)==0x000c){
						do {
							c=*(((signed char *)buf)+(b-offset));
							addlabel(d+c,PROG);
							b++;
						} while(getlabel(b)<0);
					}
				}
				break;
			}
			break;
		case 13:
			addlabel(c=(q&-4)+(a&0xff)*4+4,DATL);
			addlabel((q&-4)+(a&0xff)*4+8,NON);
			b=a&0x0f00;
			a=swapw(*(buf+(q+2-offset)/2));
			d=swapl(*(long*)(buf+(c-offset)/2));
			if(a==(0x402b+b) || a==(0x400b+b)){
				addlabel(d,PROG);
				analyze(d);
				if(analyze(d)<0){
					putchar('?');
					sublabel(p,PROG);
					return -1;
				}
			} else
			if(d>=offset && d<offset+size){
				addlabel(d,NON);
			}
			break;
		}
		q+=2;
	}
b1:	putchar('<');
	addlabel(q+4,NON);
	return 0;
}

const int cmplabel(Labellist *p,Labellist *q)
{
	return p->adr-q->adr;
}

void load_symbol_file(FILE *fp)
{
	static char str[256];
	char *s;
	int adr;

	printf("ラベルファイル読み込み中\n");
	while(fgets(str,256,fp)!=NULL){
		if((s=strtok(str,"\r\n\t "))==NULL)
			continue;
		adr=strtol(s,NULL,16);
		if((s=strtok(NULL,"\r\n\t "))==NULL)
			continue;
		switch(s[0]){
		case 'W':
			addlabel(adr,DATW|ANLZ);
			break;
		case 'L':
			addlabel(adr,DATL|ANLZ);
			break;
		case 'P':
			addlabel(adr,PROG|ANLZ);
			break;
		case 'p':
			addlabel(adr,PROG);
			break;
		}
	}
}

void save_symbol_file(FILE *fp)
{
	int i;
	printf("ラベルファイル出力中\n");
	for(i=0;i<maxlabel;i++){
		char *t;
		if(labellist[i].type&PROG){
			t="P";
		} else
		if(labellist[i].type&DATL){
			t="L";
		} else {
			t="W";
		}
		fprintf(fp,"%08x %s\n",labellist[i].adr,t);
	}
}

void main(int argc,char *argv[])
{
	FILE *fp,*outfile;
	int adr,i,j,k,l,f;
	if(argc<3){
		sprintf(inst,"SH2 Disassember for X68k\n");
		sprintf(inst,"dish2 <inputfile> <outputfile> [startaddress]\n");
		return;
	}
	if((fp=fopen(argv[1],"rb"))==NULL){
		sprintf(inst,"ファイルがありません\n");
		return;
	}
	if((outfile=fopen(argv[2],"wt"))==NULL){
		sprintf(inst,"ファイルを作れません\n");
		return;
	}
	if(argc>3)
		offset=strtol(argv[3],NULL,16);
	else
		offset=0x06080000;
	fseek(fp,0,2);
	size=ftell(fp);
	fseek(fp,0,0);
	if((buf=malloc(size))==NULL){
		sprintf(inst,"メモリが足りません\n");
		return;
	}
	fread(buf,1,size,fp);
	if(argc>4)
		start=strtol(argv[4],NULL,16);
	else
		start=offset;
	initlabellist();
	if(start!=offset){
		addlabel(offset,NON);
		addlabel(start,PROG);
	} else
		addlabel(start,PROG);
	addlabel(offset+size,DATL);
	if(argc>5){
		fp=fopen(argv[5],"rt");
		if(fp){
			load_symbol_file(fp);
			fclose(fp);
		}
	}
	for(i=0;i<65536;i++)
		flag[i]=0;
	do{
		f=0;
		for(i=0;i<maxlabel;i++)
			if((labellist[i].type&(PROG|ANLZ))==PROG || labellist[i].type==NON){
				analyze(labellist[i].adr);
				f++;
			}
		printf("\n");
	} while(f);
	printf("\nラベルソート中\n");
	qsort(labellist,maxlabel,sizeof(Labellist),cmplabel);
	size/=2;
	if(argc>5){
		fp=fopen(argv[5],"wt");
		if(fp){
			save_symbol_file(fp);
			fclose(fp);
		}
	}
	printf("出力ファイル作成中:");
	for(i=0;labellist[i].adr<=offset;i++);
	i--;
	for(adr=0;adr<size;adr++){
		if(labellist[i].adr<=adr*2+offset){
			j=labellist[i].type;
			if((labellist[i+1].type&(DATL|DATW|PROG)) && (
			(labellist[i+1].adr-labellist[i].adr==4 && (j&DATL)) ||
			(labellist[i+1].adr-labellist[i].adr==2 && (j&DATW)) ) ){
				adr+=(labellist[i+1].adr-labellist[i].adr)/2-1;
				i++;
				continue;
			}
			fprintf(outfile,"L%08x:\n",labellist[i].adr);
			i++;
			putchar(*("?.#.#.#."+(j&7)));
			fflush(stdout);
		}
		if(j&PROG){
			dis(swapw(*(buf+adr)),adr*2+offset);
			if(inst[0]==0){
				sprintf(inst,"dc.w\t$%04x",swapw(*(buf+adr)));
				printf("%08x(%x)",adr*2+offset,j);
			}
			fprintf(outfile,"\t%s\n",inst);
		} else
		if(j&DATL){
			fprintf(outfile,"\tdc.l\t$%08x\n",swapl(*(long*)(buf+adr)));
			adr++;
		} else {
			for(l=adr,k=0;l*2+offset<labellist[i].adr;l++){
				if(k==0){
					fprintf(outfile,"\tdc.w\t$%04x",swapw(*(buf+l)));
					k++;
				} else {
					fprintf(outfile,",$%04x",swapw(*(buf+l)));
					k++;
					if(k==8){
						putc('\n',outfile);
						k=0;
					}
				}
			}
			if(k)
				putc('\n',outfile);
			adr=l-1;
		}
	}
}