//
/*
--------------------------------------------------------------------------------------------------------
	v8.java	仮想コンピュータ (petit8)							ver. 1.01 (JDK 1.02) update: 2004.05.09
																ueyama@infonet.co.jp 2004.02.20
--------------------------------------------------------------------------------------------------------
*/

import java.applet.*;
import java.awt.*;
import java.util.*;

public class v8 extends Applet implements Runnable
{
				//Reg: m0  m1  m2  m3  m4  m5  m6  m7  m8  m9  mA  mB  mC  mD  mE  mF  Acc Ir Out In  Pc  Ix  Frg
	int			Rx[] ={180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 8,180,180, 20, 20, 37};
	int			Ry[] ={ 99,117,135,153,171,189,207,225,243,261,279,297,315,333,351,369, 45,45,414,  0,189,270,342};
	int			Fx=37, Fy=342;										// Flag register X,Y
	
	int			Reg[]=new int[22];									// Register/Memory value
	String		Lbl[]=new String[16];								// Label Name
	String		Asm[]={"NOP","CLR","IN","OUT","INC","DEC","INC_X","DEC_X",	// OP code
					   "SFT_L","SFT_R","NOT","-","-","-","-","-","-",		//
					   "READ","WRITE","ADD","SUB","CMP","AND","OR","INC_M",	//
					   "DEC_M","SET_X","JMP","JEZ","JNZ","JCS","JCC",		// 31
					   "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F",	// operand
					   "$0","$1","$2","$3","$4","$5","$6","$7","$8","$9","$A","$B","$C","$D","$E","$F",
					   "IX","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15",
					   "%0","%1","%2","%3","%4","%5","%6","%7","%8","%9","%10","%11","%12","%13","%14","%15",
					   "0000","0001","0010","0011","0100","0101","0110","0111",
					   "1000","1001","1010","1011","1100","1101","1110","1111",			// 111
					   "#0000","#0001","#0010","#0011","#0100","#0101","#0110","#0111",
					   "#1000","#1001","#1010","#1011","#1100","#1101","#1110","#1111",	// 127
					   "STORE","END"};									// Assembler
	int			Frm[]={-1,-1,19,16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,16,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1};
	int			To[] ={-1,16,16,18,16,16,16,16,16,22,22,21,21,-1,-1,-1,-1,16,0,16,16,16,16,16,0,0,21,20,20,20,20,20};
	int			Frf, Trf, Fre, Tre, Ysf, Yef, Yse, Yee, Opb=-1, Pofs=0;
	int			Acc;												// Accumulator 
	int			PC;													// Program Counter
	int			Op, Ad;												// Operand & Address
	int			C=0, Z=0, O=0;										// C,Z,O Flag
	int			Clk=0;												// Clock
	int			Cf=6;												// Clock Frequency
	boolean		Dsp=true;											// Display
	int			End=-1;												// End point
	TextArea	Tasm = new TextArea(10,16);							// Text area
	String		Prg[]=new String[32];								// program
	boolean		Run= false;											// true:   false: 
	int			Clock=1024;											// wait time (Clock)
	int			Bgc;												// 背景色
	String		Chk="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:;,$%# \r\n\t";	// for Err check
	String		Mes="";
	boolean		Err=false;
	Image		Img;
	Graphics	gr;
	Thread		th=null;
	
	public void start()
	{
		if(th==null)
		{
			th=new Thread(this);
			th.start();
		}
	}
	
	public void init()												// 初期設定
	{
		int i;
		gr=getGraphics();
		String bg=getParameter("BgColor");
		Bgc=Integer.valueOf(bg,16).intValue();
		setBackground(new Color(Bgc)); 
		MediaTracker mt=new MediaTracker(this);
		Img=getImage(getCodeBase(), getParameter("figure"));
		mt.addImage(Img, 0);
		try { mt.waitForID(0); }
		catch(InterruptedException e){};
		setLayout(null);
		add(Tasm);
		Tasm.reshape(420,63,240,325);
		for(i=0; i<22; i++) Reg[i]=0;								// レジスタ類初期値設定
		for(i=0; i<32; i++) Prg[i]="";
	}

	public boolean inside(int x, int a, int b)						// マウスの位置座標チェック
	{
		return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
	}

	public void dsp_reg(int n, int c)								// レジスタ 値の表示
	{
		int i, j=(n>19)? 3:7;
		String	bin=Integer.toString(Reg[n], 2)+" ";				// 2進数 文字列
		for(i=bin.length(); i<((n>19)? 5:9); i++) bin="0"+bin;
		for(i=j; i>=0; i--)											// 2進数の表示
		{
			dsp_g(Rx[n]+i*17+5, Ry[n]+3, c, Integer.parseInt(bin.substring(i,i+1)), 0);
		}
		dsp_g(Fx+ 5,Fy+3,0,C,0);									// C フラグの表示
		dsp_g(Fx+22,Fy+3,0,Z,0);									// Z フラグの表示
	}

	public void dsp_g(int x, int y, int c, int m, int n)			// 画像の表示
	{
		int			w=0, h=0, ox=0, oy=0;
		Graphics	gx=gr.create();
		switch(c)
		{
			case  0: w=  8; h= 12; ox=684; oy= 38; break;			// 2進数
			case  1: w=296; h= 35; ox=410; oy= 76; break;			// IR へのバス(赤)
			case  2: w=296; h= 35; ox= 15; oy= 64; break;			// 同上       (通常)
			case  3: w=137; h= 19; ox=410; oy=  0; break;			// レジスタ枠 (太 8 bit)
			case  4: w= 69; h= 19; ox=410; oy= 57; break;			// レジスタ枠 (4 bit)
			case  5: w=137; h= 19; ox=410; oy= 19; break;			// レジスタ枠 (8 bit)
			case  6: w= 69; h= 19; ox=548; oy= 57; break;			// レジスタ枠 (2 bit)
			case  8: w=124; h=  6; ox=410; oy=111; break;			// ▲
			case  9: w=124; h=  6; ox=410; oy=117; break;			// ▼
			case 10: w= 44; h= 23; ox=410; oy=123; break;			// ボタン
			case 11: w=127; h= 15; ox=410; oy=331; break;			// "Assemblar Program"
			case 16: w= 30; h=  9; ox=410; oy=307; break;			// "clock"
			case 17: w= 42; h= 11; ox=410; oy=316; break;			// "Display"
			case 18: w= 13; h= 13; ox=684; oy=  0; break;			// Check Box
			case 19: w= 43; h= 13; ox=542; oy=123; break;			// Niemonic
			case 21: w= 42; h= 11; ox=710; oy=  0; break;			// Clock Frequency
			case 22: w=406; h=433; ox=  0; oy=  0; break;
		}
		gx.clipRect(x, y, w, h);
		gx.drawImage(Img,x-(ox+m*w),y-(oy+n*h),this);
		gx.dispose();
	}
	
	public int sel_no(int n)										// レジスタ表示枠 No.
	{
		if(n==17)	  return 4;										// Instruction Register
		if(n<20)	  return 5;										// Memory, Acc, Port
		else if(n<22) return 4;										// PC, IR
		else		  return 6;										// Flag Register
	}

	public void dsp_button()										// ボタンの表示
	{
		dsp_g(110, 449, 10, 0, 0);									// CLR
		dsp_g(172, 449, 10, (Clock==16384)?2:0, 1);					// SLOW
		dsp_g(277, 449, 10, (Clock==16)?2:0, 2);					// FAST
		dsp_g(461, 449, 10, 0, (Run)?4:3);							// RUN
		dsp_g(509, 449, 10, 0, 5);									// STEP
		dsp_g(616, 414, 10, 0, 6);									// LOAD
		dsp_g(616, 449, 10, 2, 0);									// CREAN
		dsp_g(413, 449, 10, 0, 7);									// RESET
		dsp_g(229, 447, 16, 0, 0);									// "clock"
		dsp_g(358, 457, 17, 0, 0);									// "Display"
		dsp_g(342, 455, 18, (Dsp)?1:0, 0);							// Check Box
		dsp_g(227, 460, 21, 0, Cf);									// Clock Frequency
	}

	public void dsp_nmc()											// ニーモニックの表示
	{
		int m=Reg[17]/16, n=Reg[17]%16;
		int h, v;
		v=(m==0)?n:m;
		h=(m==0)?0:1;
		if(n==0 && Op<27) n=Reg[21];								// Index addressing
		dsp_g(80, 4, 19, 1, 0);										// オペランドの消去
		if(PC==End) dsp_g(15, 4, 19, 3, 0);							// "END"
		else
		{
			dsp_g(15, 4, 19, h, v);									// 命令
			if(m>0) dsp_g(80, 4, 19, 2, n);							// オペランド
		}
	}

	public void paint(Graphics g)									// 画面の表示
	{
		int i,j;
		g.clearRect(0, 0, size().width, size().height);
		dsp_g(0, 0, 22, 0, 0);
		for(i=0; i<22; i++) dsp_reg(i, 0);
		dsp_button();
		dsp_g(475, 44, 11, 0, 0);
	}

	public void cpu_run()											// 命令の実行
	{
		Clk++;
		if(Clk%2==0)												// excute cycle
		{
			excute();
			if(Reg[20]21 || i==n) Reg[i]=0;				// Reg[19] は Input Port のためクリアしない
		for(i=20; i<22; i++) if(n>21 || i==n) Reg[i]=0;
		for(i=0; i<32; i++) if(n>21) Prg[i]="";
		if(n>21) C=Z=O=PC=Clk=0;
		Run=false;
	}
	
	public int flag(int m, int n)									// フラグ  m=0: Z flag only
	{
		if(m>0) C=(n>255 || n<0)?1:0;
		Z=(n%256==0)?1:0;
		return n&255;
	}
	
	public int reg_no(int n)										// レジスタ(メモリ)No. の算出
	{
		int r=(n==0)?Frm[Op]:To[Op];
		if(r==0)
		{
			r=Reg[17]%16;
			if(r==0) r=Reg[21];										// Index Register
		}
		return r;
	}

	public void fetch()												// 命令のフェッチ
	{
		int i;
		Reg[17]=Reg[Reg[20]];										// 命令レジスタにメモリデータをコピー

		Op=Reg[17];													// 命令(Reg[17]:命令レジスタ)
		PC=Reg[20];
		if(Op>15)
		{
			Ad=Op%16;												// operand
			if(Ad==0) Ad=Reg[21];									// index addressing
			Op=Op/16+16;											// ope code
		}
		else if(Op==2) Ad=19;										// INPUT
		else if(Op==3) Ad=18;										// OUTPUT

		if((Frf=Frm[Op])>=0)										// レジスタ表示色変更
		{
			Frf=reg_no(0);
			dsp_g(Rx[Frf], Ry[Frf], sel_no(Frf), 1, 0);
		}
		if((Trf=To[Op])>=0)											// レジスタ表示色変更
		{
			Trf=reg_no(1);
			dsp_g(Rx[Trf], Ry[Trf], sel_no(Trf), 1, 0);
		}
		Ysf=Ry[0]; Yef=Ry[PC];

		dsp_reg(17, 0);												// 命令レジスタの表示
		dsp_nmc();
		if(Dsp && Trf>=0)
		{
			if(PC>0) dsp_exec(1);
			if(PC>0) dsp_bus(Yse, Yee);
			if(Opb>0) dsp_reg(Opb, 0);
			dsp_fetch(0);
			dsp_bus(Ysf, Yef);
		}
	}
	
	public void dsp_fetch(int n)									// フェッチ動作表示
	{
		int i;
		dsp_g(15, 64, 1+n, 0, 0);									// IR へのデータバス
		dsp_g(Rx[0], Ry[PC], 3, n, 0);								// メモリ (命令)
		dsp_g(Rx[20], Ry[20], 4, n, 0);								// プログラムカウンタ
	}

	public void dsp_bus(int s, int e)								// データバス表示
	{
		gr.setXORMode(new Color(51,255,255));
		for(int i=0; i<8; i++) gr.drawLine(Rx[0]+i*17+9, s, Rx[0]+i*17+9, e);
		gr.setPaintMode();
	}
	
	public void excute()												// 命令の実行
	{
		int i;
		Acc=Reg[16];													// Accumulator 
		switch(Op)
		{
			case  0: break;												// NOP
			case  1: Acc=flag(0, 0); break;								// CLEAR
			case  2: Ad=19; Acc=flag(0, Reg[Ad]); break;				// INPUT
			case  3: Ad=18; Reg[Ad]=flag(0, Acc); break;				// OUTPUT
			case  4: Acc=flag(0, Acc+1); break;							// INC_ACC
			case  5: Acc=flag(0, Acc-1); break;							// DEC_ACC
			case  6: Reg[21]++; Reg[21]&=15; Z=(Reg[21]==0)?1:0; break;	// INC_IX
			case  7: Reg[21]--; Reg[21]&=15; Z=(Reg[21]==0)?1:0; break;	// DEC_IX
			case  8: Acc*=2; C=Acc/256; Acc%=256; Z=(Acc==0)?1:0; break;// SHIFT_L
			case  9: C=Acc%2; Acc/=2; Z=(Acc==0)?1:0; break;			// SHIFT_R
			case 10: Acc=flag(0, 255-Acc); break;						// NOT
			case 11: C=0; break;										// CLR_C
			case 12: C=1; break;										// SET_C
			case 17: Acc=flag(0, Reg[Ad]); break;						// READ
			case 18: Reg[Ad]=flag(0, Acc); break;						// WRITE
			case 19: Acc=flag(1, Acc+Reg[Ad]); break; 					// ADD
			case 20: Acc=flag(1, Acc-Reg[Ad]); break; 					// SUB
			case 21: flag(1, Acc - Reg[Ad]); Acc=Reg[16]; break;		// CMP
			case 22: Acc=flag(0, Acc & Reg[Ad]); break;					// AND
			case 23: Acc=flag(0, Acc | Reg[Ad]); break;					// OR
			case 24: Reg[Ad]=flag(0, Reg[Ad]+1); break;					// INC
			case 25: Reg[Ad]=flag(0, Reg[Ad]-1); break;					// DEC
			case 26: Reg[21]=Ad; break;									// SET_IX
			case 27: Reg[20]=Ad-1; break;								// JUMP
			case 28: if(Z==1) Reg[20]=Ad-1; break;						// JUMP_Z
			case 29: if(Z==0) Reg[20]=Ad-1; break;						// JUMP_NZ
			case 30: if(C==1) Reg[20]=Ad-1; break;						// JUMP_C
			case 31: if(C==0) Reg[20]=Ad-1; break;						// JUMP_NC
		}
		Reg[16]=Acc;
		dsp_reg(16, 0);
		dsp_reg(21, 0);
		dsp_reg(Ad, 0);

		if((Fre=Frm[Op])>=0)										// レジスタ表示色変更
		{
			Fre=reg_no(0);
			dsp_g(Rx[Fre], Ry[Fre], sel_no(Fre), 1, 0);
		}
		if((Tre=To[Op])>=0)											// レジスタ表示色変更
		{
			Tre=reg_no(1);
			dsp_g(Rx[Tre], Ry[Tre], sel_no(Tre), 1, 0);
		}
		if(Tre*Fre>=0 && Tre>=0)
		{
			if(Ry[Tre]16) dsp_g(Rx[17]+68, Ry[17], 4, n, 0);				// 命令レジスタ オペランド部 赤枠
		if(Fre>=0)													// データバス (Op: Ope-code)
		{
			d=(Tre==16 && Fre<19)?8:9;
			if(Op!=21) dsp_g(Rx[Tre]+7, Ry[Tre]+((d==8)?19:-6), d, n, 0);	// ▲ or ▼
			dsp_g(Rx[Fre], Ry[Fre], 3, n, 0);						// レジスタ赤太枠
			dsp_g(Rx[Tre], Ry[Tre], sel_no(Tre), n, 0);				// レジスタ枠
		}
	}
	
	public boolean is_legal(String c, String s)
	{
		int i;
		for(i=0; i=0)
		{
			if(d.equals("$") && is_legal("0123456789ABCDEF", n)) m=Integer.parseInt(n,16);
			else if(d.equals("#") && is_legal("01", n)) m=Integer.parseInt(n,2);
			else if(d.equals("%") && is_legal("0123456789", n)) m=Integer.parseInt(n,10);
		}
		else if(is_legal("0123456789", s)) m=Integer.parseInt(s);
		return m;
	}
	
	public void err_mes(int i, String s)							// error message
	{
		Mes="Program Error: line "+i+",  "+s;
		Err=true;
	}

	public boolean mouseDown(Event e, int x, int y)					// マウスがクリックされたときの処理
	{
		int	i=0,j=0,k=0,l=0,m=0,n=0,r=-1,s=0,v=0;
		String	c,d,p,q;
		boolean lf=false;
		Err=false;
		Mes="";
		gr.clearRect(420,390,240,20);
		if(inside(x, 616, 660) && inside(y, 414, 437))				// *** LOAD ***
		{
			dsp_g(616, 414, 10, 1, 6);
			End=-1;
			Pofs=0;
			for(i=0; i<16; i++) Lbl[i]="";
			for(i=0; i<32; i++) Prg[i]="";
			p=Tasm.getText();
			StringTokenizer st=new StringTokenizer(p,"\n\r");
			n=st.countTokens();
			if(n==0) {Mes="Program Error: program not found."; Err=true;}
			for(i=0; st.hasMoreTokens(); i++)
			{
				q=st.nextToken();
				if((m=q.indexOf(";"))>0) q=q.substring(0,m);		// Comment
				Prg[i]=q.toUpperCase();
				if(!is_legal(Chk, Prg[i])) err_mes(i+1, q);			// Error Check
				StringTokenizer ec=new StringTokenizer(Prg[i],"\t ");
				for(j=0; ec.hasMoreTokens(); j++)					// missing operand
				{
					q=ec.nextToken();
					for(k=17; k<32; k++)							// 要オペランド命令
					{
						if(Asm[k].equals(q))
						{
							if(!ec.hasMoreTokens())
							{
								err_mes(i+1, Prg[i]);
								break;
							}
						}
					}
				}
				if(Err) break;
			}
			if(!Err)
			{
				for(i=0; i0)					// Label
						{
							Lbl[s]=q.substring(0,m);
							q=st.nextToken();
							lf=true;
						}
						for(k=0; k<130; k++)
						{
							if(Asm[k].equals(q))
							{
								if(k<16) Reg[s]=k;
								else if(k<32)  Reg[s]=k%16*16;
								else if(k<128) Reg[s]+=k%16;
								else if(k==128)						// STORE
								{
									m=-1;
									l=0;							// *1
									if(st.hasMoreTokens())
									{
										m=cal_adr(st.nextToken("\t, "));
										if(m>15) err_mes(i+1, Prg[i]);	// *1
										if(m>=0 && st.hasMoreTokens())
										{
											if((v=cal_adr(st.nextToken()))>=0) Reg[m]=v;
											else m=-1;
											Pofs++;
											l++;
										}
									}
									if(l<1) err_mes(i+1, Prg[i]);	// *1
								}
								else if(k==129) End=s;				// END
								break;
							}
						}
						if(j==0 && (k>129 || inside(k,32,127))) err_mes(i+1, Prg[i]);
						if(Err) break;
						j++;
					}
					if(Reg[s]>0) s++;
					if(End>=0 || Err) break;
				}
				if(!Err)
				{
					if(lf)											// ラベルの処理
					{
//						for(i=0; i<16; i++) System.out.println("i="+i+",  Prg="+Prg[i]+",  l="+Lbl[i]);
						for(i=0; i<16; i++)
						{
							s=0; j=0;
							while(!Prg[j].equals(""))
							{
								if(Prg[j].indexOf(Lbl[i])>0) Reg[s]+=i;
								if(Prg[j].indexOf("STORE")==-1) s++;
								j++;
							}
						}
						for(i=0; !Prg[i].equals(""); i++)			// Illegal label
						{
							StringTokenizer ec=new StringTokenizer(Prg[i],",:\t ");
							while(ec.hasMoreTokens())
							{
								q=ec.nextToken();
								if(q.indexOf("STORE")>=0) break;
								for(k=0; k<130; k++) if(Asm[k].equals(q)) break;
								if(k==130) for(k=0; k<16; k++) if(Lbl[k].equals(q)) break;
								if(k==16)
								{
									err_mes(i+1, Prg[i]);
									break;
								}
							}
						}
					}
				}
				if(!Err)
				{
					if(End<0) err_mes(i+1, "\"END\" expected.");
					else
					{
						for(i=0; i<16; i++) dsp_reg(i, 0);
						Mes="Assemble completed.";
					}
				}
			}
		}
		if(y>449)
		{
			if(inside(x, 110, 154))									// *** CLR ***
			{
				repaint();
				clr_reg(32);										// 全レジスタ・メモリのクリア
				dsp_g(461, 449, 10, 0, (Run)?4:3);					// RUN or STOP
				dsp_g(509, 449, 10, 0, 5);							// STEP
				for(i=0; i<22; i++) dsp_reg(i, 0);
			}
			if(inside(x, 172, 321))									// *** SLOW & FAST ***
			{
				if(x<216 && Clock<16384) {Clock*=2; dsp_g(172, 449, 10, 1, 1);}
				if(x>277 && Clock>16) {Clock/=2; dsp_g(277, 449, 10, 1, 2);}
				Cf=(int)(Math.log((double)(Clock/16))/Math.log(2));
				dsp_g(227, 460, 21, 0, Cf);							// Clock Frequency
			}
			if(inside(x, 413, 457))									// *** RESET ***
			{
				PC=Reg[20]=Clk=0;
				dsp_g(413, 449, 10, 1, 7);							// RESET
				dsp_g(509, 449, 10, (PC==End)?2:0, 5);				// STEP
				dsp_reg(20, 0);
				
			}
			if(inside(x, 461, 504))									// ***  RUN ***
			{
				dsp_g(461, 449, 10, 1, (Run)?4:3);
				Run=!Run;
				if(Run && End<0)
				{
					Mes="Error: Program empty !";
					Run=false;
					dsp_g(461, 449, 10, 1, 3);
				}
			}
			if(inside(x, 509, 553))									// *** STEP ***
			{
				if(PC616) repaint();									// *** CLEAN ***
			if(inside(x,342,355) && inside(y,453,466))
			{
				Dsp=!Dsp;
				dsp_g(342, 455, 18, (Dsp)?1:0, 0);					// Check Box
			}
		}
		else if(x<316)												// レジスタ値の編集
		{
			if(inside(x,Rx[0],Rx[0]+136))
			{
				if(inside(y,Ry[0], Ry[15]+18)) r=(y-Ry[0])/18;		// Memory
				if(inside(y,Ry[19],Ry[19]+18)) r=19;				// Input Port
				if(inside(y,Ry[16],Ry[16]+18)) r=16;				// Accumulator
				if(inside(y,Ry[18],Ry[18]+18)) r=18;				// Output Port
			}
			if(inside(x,Rx[17],Rx[17]+136) && inside(y,Ry[17],Ry[17]+18)) r=17;	// Instruction Regidter
			if(inside(x,Rx[20],Rx[20]+ 68) && inside(y,Ry[20],Ry[20]+18)) r=20;	// Program Counter
			if(inside(x,Rx[21],Rx[21]+ 68) && inside(y,Ry[21],Ry[21]+18)) r=21;	// Program Counter
			if(r>=0)
			{
				m=7-(x-Rx[r]+((r>19)?68:0))/17; n=1;
				for(i=0; i< m; i++) n*=2;
				Reg[r]+=((Reg[r] & n) ==0)? n:-n;
				dsp_reg(r, 0);
			}
			if(inside(x,Fx,Fx+17) && inside(y,Fy,Fy+18)) {C=(C==0)?1:0; dsp_g(Fx+ 5,Fy+3,0,C,0);}		// C Flag
			if(inside(x,Fx+18,Fx+34) && inside(y,Fy,Fy+18)) {Z=(Z==0)?1:0; dsp_g(Fx+22,Fy+3,0,Z,0);}	// Z Flag
		}
		if(Mes.indexOf("Error")>=0) gr.setColor(new Color(204,0,0));
		else  gr.setColor(new Color(102,102,102));
		Font f=new Font("Helvetica", Font.PLAIN, 10);
		gr.drawString(Mes, 423, 406);
		return true;
	}

	public boolean mouseUp(Event e, int x, int y)					// マウスボタンが離されたときの処理
	{
		if(inside(x, 616, 660) && inside(y, 414, 437)) dsp_g(616, 414, 10, 0, 6);	// *** STORE ***
		if(y>449)
		{
			if(inside(x, 172, 216)) dsp_g(172, 449, 10, (Clock==16384)?2:0, 1);		// *** SLOW ***
			if(Clock>16) dsp_g(277, 449, 10, 0, 2);
			if(inside(x, 277, 321)) dsp_g(277, 449, 10, (Clock==16)?2:0, 2);		// *** FAST ***
			if(Clock<16384) dsp_g(172, 449, 10, 0, 1);
			if(inside(x, 413, 457))													// *** RESET ***
			{
				dsp_g(413, 449, 10, 0, 7);							// RESET
				dsp_g(461, 449, 10, 0, (Run)?4:3);					// RUN
			}
			if(inside(x, 461, 504)) dsp_g(461, 449, 10, 0, (Run)?4:3);				// ***  RUN ***
			if(inside(x, 509, 553)) dsp_g(509, 449, 10, (PC==End)?2:0, 5);			// *** STEP ***
		}
		return true;
	}

	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
}
// *1  2004.05.09
//
戻る