_8085 = function(PC)
{
	this.start = PC;
	this.PC = PC;
	this.A = "00";
	this.B = "00";
	this.C = "00";
	this.D = "00";
	this.E = "00";
	this.F = "00";
	this.H = "00";
	this.L = "00";
	
	this.Z = 0;
	this.CY = 0;
	this.P = 0;
	this.S = 0;
	this.AC = 0;
	
	this.err = 0;
	this.stop = 0;
	this.exec = 0;
	
	this.SP = ("FFFF");
	this.memmap = {};
	this.getmem = function(addr)
	{
		if(this.memmap["D"+addr])
		{
			return this.memmap["D"+addr];
		}
		else
		{
			this.err = 1;
			alert("Accessed Memory ["+addr+"] not found");
			return "00";
		}
	}
	this.setmem = function(addr,data)
	{
		this.memmap["D"+addr]=data;
		if(e=document.getElementById("M"+addr))
		{
			e.innerHTML = addr + ": " + data;
		}
		else
		{
			var self = document.createElement("span");
			self.id="M"+addr;
			self.className = 'memblock';
			self.innerHTML = addr + ": " + data;
			document.getElementById("memcode").appendChild(self);
      sortbyid("memcode");
		}
	}
	this.push = function(data)
	{
		var a=this.SP;
		this.SP = inrPC(this.SP,-1);
		this.memmap["D"+this.SP] = data;
		
		var self = document.createElement("span");
		self.id="S"+this.SP;
		self.className = 'memblock';
		self.innerHTML = this.SP + ": " + data;
		document.getElementById("stkcode").appendChild(self);
	}
	this.pop = function()
	{
		var a=this.memmap["D"+this.SP];
		if(!a){alert("Stack Error");this.err=1;this.stop=1;return 0;}
		var self=document.getElementById("S"+this.SP);
		if(self)document.getElementById("stkcode").removeChild(self);
		this.SP = inrPC(this.SP,1);
		return a;
	}
	this.next = function()
	{
    HlitPC(this.PC,0);
		if(this.PC == "0000")
		{
			var i=0;
			do{
			i = prompt("A=");
			}
			while(isNaN(parseInt(i,16)));	
			this.A = i;
			
			this.memmap["D0000"] = "C9";
		}
		else if(!this.memmap["D"+this.PC])
		{
			alert("Runtime Error: No Code at "+this.PC);
			this.err=1;
			return;
		}
		
		this.handle(this.memmap["D"+this.PC]);
		this.disp();
		
		HlitPC(this.PC,1);
	}
	
	this.handle = function(hex)
	{
		var inr=1;

		var dcd=parseInt(hex,16);

		if((dcd & 0xC0) == 0x40 && dcd != 0x76) //MOV
		{
			var b=getReg(hex,0,0);
			var c=getReg(hex,3,0);
			if(b != "M" && c != "M")
				eval("this."+c+" = this."+b);
			else if(b == "M")
				eval("this."+c+" = this.getmem('"+this.H+this.L+"')");
			else if(c == "M")
			{
				this.setmem(this.H+this.L,eval("this."+b));
			}
		}
		else if((dcd & 0xC7) == 0x06)		//MVI
		{
			inr = 2;
			var a=this.memmap["D"+inrPC(this.PC,1)];
			var b=getReg(hex,3,0);
			if(b=="M")
				this.setmem(this.H+this.L,a);
			else
				eval("this."+b+" = a");
		}
		else if((dcd & 0xC6) == 0x04)			//DCR & INR
		{
			var b=getReg(hex,3,0);
			var c=(dcd & 1)?-1:1;
			if(b == "M")
			{
				var a = No2Hex((parseInt(this.getmem(this.H+this.L),16)+c)%256,2);
				this.setmem(this.H+this.L,a);
			}
			else
			{
				var a = No2Hex((parseInt(eval("this."+b),16)+c)%256,2);
				eval("this."+b+" = a");
			}
			
			this.Z = (a == "00")?1:0;
			this.P = calcParity(a);
			this.S = (parseInt(a,16) & 128)?1:0;
			this.AC = (a.substr(1) == "F")?1:0;
		}
		else if((dcd & 0xC7) == 0x03) //INX & DCX
		{
			var b=getReg(hex,4,1);
			var c=(dcd & 0x08)?-1:1;
			if(b == "SP")
				this.SP = No2Hex(parseInt(this.SP,16)+c,4);
			else
			{
				var d=getPair(b);
				//alert(eval("this."+b)+""+eval("this."+d));
				var a = No2Hex(parseInt(eval("this."+b)+""+eval("this."+d),16)+c,4);
				eval("this."+b+" = a.substr(0,2)");
				eval("this."+d+" = a.substr(2)");
			}
		}
		else if((dcd & 0xC7) == 0xC2) //Conditional Jumps 
		{
			var b=(getReg(hex,3,2));
			if(eval("this."+b+"=1"))
			{
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				if(!this.memmap["D"+a]){this.err=1;alert("Jump Location ["+a+"] not found");}
				inr = 0;
				this.PC = a;
			}
			else
				inr = 3;
		}
		else if((dcd & 0xC7) == 0xC4) //Conditional Calls
		{
			var b=(getReg(hex,3,2));
			if(eval("this."+b+"=1"))
			{				
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				var b=inrPC(this.PC,3);
				this.push(b.substr(0,2));
				this.push(b.substr(2));
				if(!this.memmap["D"+a]){this.err=1;alert("Call Location ["+a+"] not found");}
				this.PC = a;
				inr = 0;
			}
			else
				inr = 3;
		}
		else if((dcd & 0xC7) == 0xC0) //Conditional Returns
		{
			var b=(getReg(hex,3,2));
			if(eval("this."+b+"=1"))
			{				
				inr=0;
				var a=this.pop();
				var b=this.pop();
				this.PC = b + a;
			}
		}
		else if((dcd & 0xC0) == 0x80 || (dcd & 0xC7) == 0xC6) //Arithmetic Operations ALU
		{
			var b=0,c=0,d=0;
			if((dcd & 0xC7) == 0xC6)
			{
				c=parseInt(this.A,16);
				d=parseInt(this.memmap["D"+inrPC(this.PC,1)],16);
				inr=2;
			}
			else
			{
				b=getReg(hex,0,0);
				c=parseInt(this.A,16);
				
				if(b=="M")
				d=parseInt(this.getmem(this.H+this.L),16);
				else
				d=parseInt(eval("this."+b),16);
			}
			var res = 0;

			switch(getReg(hex,3,3))
			{
				case 0:
					res=c+d;
					this.CY = (res > 0xff)?1:0;
					this.AC = (((d&0xf)+(c&0xf))>0xf)?1:0;
					res %= 256;
					this.A = No2Hex(res,2);
					break;
				case 1:
					d=d+this.CY;
					res=c+d;
					this.CY = (res > 0xff)?1:0;
					this.AC = (((d&0xf)+(c&0xf))>0xf)?1:0;
					res %= 256;
					this.A = No2Hex(res,2);
					break;
				case 2:
					d=(0xff^d)+1;
					res=c+d;
					//alert(c+" "+d);
					this.CY = (res <= 0xff)?1:0;
					this.AC = (((d&0xf)+(c&0xf))>0xf)?1:0;
					res %= 256;
					this.A = No2Hex(res,2);
					break;
				case 3:
					d=(0xff^(d+this.CY))+1;
					res=c+d;
					this.CY = (res <= 0xff)?1:0;
					this.AC = (((d&0xf)+(c&0xf))>0xf)?1:0;
					res %= 256;
					this.A = No2Hex(res,2);
					break;
				case 4:
					res=c&d;
					this.CY=0;
					this.AC=1;
					this.A = No2Hex(res,2);
					break;
				case 5:
					res=c^d;
					this.CY=0;
					this.AC=0;
					this.A = No2Hex(res,2);
					break;
				case 6:
					res=c|d;
					this.CY=0;
					this.AC=0;
					this.A = No2Hex(res,2);
					break;
				case 7:
					d=(0xff^d)+1;
					res=c+d;
					this.CY = (res <= 0xff)?1:0;
					this.AC = (((d&0xf)+(c&0xf))>0xf)?1:0;
					res%=256;
					break;
			}
			
			this.Z = (res == 0)?1:0;
			this.P = calcParity(res);
			this.S = (res & 128)?1:0;
		}
		else if((dcd & 0xCF) == 0x01) //LXI
		{
			inr = 3;
			var a=this.memmap["D"+inrPC(this.PC,2)];
			var b=this.memmap["D"+inrPC(this.PC,1)];
			var c=getReg(hex,4,1);
			var d=getPair(c);
			if(d.length)
			{
				eval("this."+c+" = a");
				eval("this."+d+" = b");
			}
			else
			{this.SP = a+b;}
		}
		else if((dcd & 0xCF) == 0x09) //DAD
		{
			var b=getReg(hex,4,1);
			var c=parseInt(this.H+""+this.L,16);
			var a=0;
			
			if(b == "SP")
				a = parseInt(this.SP,16);
			else
			{
				var d=getPair(b);
				a=parseInt(eval("this."+b)+""+eval("this."+d),16);
			}
			
			this.CY = (a+c)>0xffff?1:0;
			a = No2Hex((a+c)%0x10000,4);
			this.H = a.substr(0,2);
			this.L = a.substr(2);
		}
		else if((dcd & 0xCF) == 0xC5) //PUSH
		{
			inr=1;
			var c=getReg(hex,4,1);
			var d=getPair(c);
			if(d.length)
			{
				this.push(eval("this."+c));
				this.push(eval("this."+d));
			}
			else
			{
				this.push(this.A);
				this.push(No2Hex((this.S<<7)+(this.Z<<6)+(this.AC<<4)+(this.P<<2)+(this.CY),2));
			}
		}
		else if((dcd & 0xCF) == 0xC1) //POP
		{
			inr=1;
			var c=getReg(hex,4,1);
			var d=getPair(c);
			if(d.length)
			{
				eval("this."+d+"=this.pop()");
				eval("this."+c+"=this.pop()");
			}
			else
			{
				this.A=parseInt(this.pop(),16);
				this.S = (this.A & 128)?1:0;
				this.Z = (this.A & 64)?1:0;
				this.AC= (this.A & 16)?1:0;
				this.P = (this.A & 4)?1:0;
				this.CY= (this.A & 1)?1:0;
				this.A=this.pop();
			}
		}
		else
		switch(hex)
		{
			case "00": //NOP
				break;
			case "2F":this.A = No2Hex(parseInt(this.A,16)^0xff,2);break; //CMA
			case "3F":this.CY = this.CY?0:1;break; //CMC
			case "37":this.CY = 1;break; //STC
			
			case "D3"://IN
			case "DB"://OUT
			case "FB"://EI
			case "F3":break;//DI
			
			case "3A": //LDA
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				this.A = this.getmem(a);
				inr = 3;
				break;
			case "32": //STA
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				this.setmem(a,this.A);
				inr = 3;
				break;
			case "0A":this.A = this.getmem(this.B+this.C);break; //LDAX B
			case "1A":this.A = this.getmem(this.D+this.E);break;//LDAX D
			case "02":this.setmem(this.B+this.C,this.A);break;//STAX B
			case "12":this.setmem(this.D+this.E,this.A);break;//STAX D
			case "17"://RAL
				var a=this.CY;
				this.A = parseInt(this.A,16);
				this.CY = (this.A & 128)?1:0;
				this.A <<=1;
				this.A+=a;
				this.A %= 256;
				this.A = No2Hex(this.A,2);
				break;
			case "1F": //RAR
				var a=this.CY;
				this.A = parseInt(this.A,16);
				this.CY = (this.A & 1)?1:0;
				this.A >>=1;
				this.A+=(a<<7);
				this.A %= 256;
				this.A = No2Hex(this.A,2);
				break;
			case "07": //RLC
				this.A = parseInt(this.A,16);
				var a=this.CY;
				this.CY = (this.A & 128)?1:0;
				this.A <<=1;
				this.A+=a;
				this.A %= 256;
				this.A = No2Hex(this.A,2);
				break;
			case "0F": //RRC
				this.A = parseInt(this.A,16);
				var a=this.CY;
				this.CY = (this.A & 1)?1:0;
				this.A >>=1;
				this.A+=(a<<7);
				this.A %= 256;
				this.A = No2Hex(this.A,2);
				break;
			case "CD": //CALL
				inr = 0;
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				var b=inrPC(this.PC,3);
				this.push(b.substr(0,2));
				this.push(b.substr(2));
				if(!this.memmap["D"+a] && (parseInt(a,16) > 0xff)){this.err=1;alert("Call Location ["+a+"] not found");}
				this.PC = a;
				break;
			case "C9"://RET
				inr=0;
				var a=this.pop();
				var b=this.pop();
				this.PC = b + a;
				break;
			case "C3"://JMP
				inr = 0;
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				var b=inrPC(this.PC,3);
				if(!this.memmap["D"+a]){this.err=1;alert("Jump Location ["+a+"] not found");}
				this.PC = a;
				break;
			case "E9":inr=0;this.PC = this.H+this.L;break;//PCHL
			case "F9":this.SP =this.H+this.L;break;//SPHL
			case "22"://SHLD
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				this.setmem(a,this.L);
				this.setmem(inrPC(a,1),this.H);
				inr=3;
				break;
			case "2A": //LHLD
				var a=this.memmap["D"+inrPC(this.PC,2)]+""+this.memmap["D"+inrPC(this.PC,1)];
				this.L = this.getmem(a);
				this.H = this.getmem(inrPC(a,1));
				inr=3;
				break;
			case "EB":  //XCHG
				var a=this.H;
				this.H = this.D;
				this.D = a;
				a=this.L;
				this.L = this.E;
				this.E = a;
				break;
			case "76": //HLT
				inr=0;
				this.stop=1;
				//alert("Program has ended!");
				break;
			case "E3": //XTHL
				var a=this.pop();
				var b=this.pop();
				this.push(this.H);
				this.push(this.L);
				this.H=b;
				this.L=a;
				break;
			case "27": //DAA
				var a=parseInt(this.A,16);

				if(((a&0x00f) > 0x09) || this.AC) {a+=0x06;this.AC=1;}
				if(((a&0xff0) > 0x90) || this.CY) {a+=0x60;this.CY=1;}
				//alert(a);
				this.CY = (a > 255)?1:0;
				a %= 256;
				this.Z = (a == 0)?1:0;
				this.P = calcParity(a);
				this.S = (a & 128)?1:0;
				this.A = No2Hex(a,2);
				break;
			default:
				inr=0;
				this.err=1;
				alert("unknown code ["+hex+"] at ["+this.PC+"]");
		}
		if(inr)	this.PC = No2Hex(parseInt(this.PC,16)+inr,4);
	}
	this.disp = function()
	{
		document.getElementById("rA").value = this.A;
		document.getElementById("rB").value = this.B;
		document.getElementById("rC").value = this.C;
		document.getElementById("rD").value = this.D;
		document.getElementById("rE").value = this.E;
		document.getElementById("rH").value = this.H;
		document.getElementById("rL").value = this.L;
		//document.getElementById("rF").value = this.F;
		document.getElementById("rSP").value = this.SP;
		document.getElementById("rPC").value = this.PC;
		//
		document.getElementById("rS").value = this.S;
		document.getElementById("rZ").value = this.Z;
		document.getElementById("rAC").value = this.AC;
		document.getElementById("rP").value = this.P;
		document.getElementById("rCY").value = this.CY;
		
	}
	
	this.reset = function()
	{
		HlitPC(this.PC,0);
		this.stop=0;
		this.err =0;
		this.PC = this.start;
		document.getElementById("memcode").innerHTML = "";
		document.getElementById("stkcode").innerHTML = "";
		this.SP = "FFFF";
	}
}
function inrPC(no,cnt)
{
	no = parseInt(no,16);
	no+=cnt;
	var str="";
	h = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
	do{
		str = h[parseInt(no%16)] + str;
		no /= 16;
		no = parseInt(no);
	}while(no);
	if(str.length < 4)
	{
		do
		{
			str = "0"+str;
		}while(str.length != 4);
	}
	return str;
}
function No2Hex(no,len)
{
	var lim=(len==2)?256:65536;
	if(no < 0) no += lim;
	if(no >= lim) no -= lim;
	var str="";
	h = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
	do{
		str = h[parseInt(no%16)] + str;
		no /= 16;
		no = parseInt(no);
	}while(no);
	if(str.length < len)
	{
		do
		{
			str = "0"+str;
		}while(str.length != len);
	}
	return str;
}

function HlitPC(pc,un)
{
	if(e=document.getElementById("lD"+pc)) { e.style.background = un?'#cdf':'#fff'; if(un)e.scrollIntoView(true);}
}

function getReg(hex,push,sw)
{
	//mask = parseInt(mask,16);
	mask = 0;
	switch(sw)
	{
		case 0:mask=7;break;
		case 1:mask=3;break;
		case 2:mask=7;break;
		case 3:mask=7;break;
	}
	mask <<=push;
	hex  = parseInt(hex,16);
	hex&=mask;
	
	hex >>=push;
	switch(sw)
	{
		case 0:	reg = new Array("B","C","D","E","H","L","M","A");return reg[hex];
		case 1: reg = new Array("B","D","H","SP");return reg[hex];
		case 2: reg = new Array("Z!","Z=","CY!","CY=","P!","P=","S!","S=");return reg[hex];
		case 3: return hex;
	}
}
function getPair(c)
{
	if(c=="D") return "E";
	else if(c=="B")return "C";
	else if(c=="H")return "L";
	return "";
}
function calcParity(a)
{
	b=1;
	p=0;
	a = parseInt(a,16);
	
	for(i=0;i<8;i++)
	{
		if(a & b)		p++;
		b<<=1;
	}
	return (p+1)%2;
}
function sortbyid(id)
{
  var e = document.getElementById(id);
  if(e)
  {
    var f = document.getElementsByTagName("span");
    var ida = new Array();
    for(i=0;i<f.length;i++)
      if(f[i].id.substr(0,1) == "M")
      {
        ida.push(f[i].id);
      }
    ida.sort();
    
    var temp = "";
    for(i=0;i<ida.length;i++)
    {
      temp += ('<span class="memblock" id="'+ida[i]+'">'+ document.getElementById(ida[i]).innerHTML + '</span>');
    }
    e.innerHTML = temp;
  }
}