Lame i8080 emulator

Lame patterned emulator

by Ruslan Alikberov

HTML

<body onload='main()'>
<table>
<tr valign=top><td>
<p>
<input type=radio name=Viewer id=toKnot><label for=toKnot accessKey=K>&#9776;</label>
<input type=radio name=Viewer id=toListing><label id=laListing for=toListing accessKey=L>&#9776;Listing</label>
<input type=radio name=Viewer id=toModel><label id=laModel for=toModel accessKey=M>&#9939;Matrix</label>
<button id=Reset accessKey=R onclick='cpu.ram(mon32, 0xF800); cpu.reset()' title='[ALT+R] Reload "Monitor"'>Reset</button>
<button id=Start accessKey=S onclick='cpu.core.is_active = true; cpu.debug.is_step = false;'>Start</button>
<button id=Trace accessKey=T onclick='cpu.debug.is_step = true;'>Trace</button>
<textarea id=Listing rows=32 cols=128 style=position:absolute>
	ORG	0xF800
BEGIN:	LXI	SP,0x75FF
	LXI	H,0x76D0
	LXI	D,0x7FF3
.loop:	MOV	A,M
	XRI	0x7F
	MOV	M,A
	INX	H
	MOV	A,L
	CMP	E
	JNZ	.loop
	RLC
	MOV	A,H
	CMP	D
	JC	.loop
	MVI	A,0x3D
	NOP
	JMP	.loop</textarea>
<textarea id=Pattern rows=32 cols=128 style=position:absolute>
-------		regex-field	-------
pc:0xF800	IP	`r.pc.x.toHex(4)` `m.slice(r.pc.x, r.pc.x+16).toHex()`|PC(Program Counter)
sp:0x0000	SP	`r.sp.x.toHex(4)` `m.slice(r.sp.x-8,r.sp.x+8).toHex(8,"|")`|SP(Stack Pointer)
bc:0x4358	BC	`r.bc.x.toHex(4)` `m.slice(r.bc.x, r.bc.x+16).toHex()`|BC(All Purposes Counters)
de:0x4458	DE	`r.de.x.toHex(4)` `m.slice(r.de.x, r.de.x+16).toHex()`|DE(All Purposes Enhancer)
hl:0x4258	HL	`r.hl.x.toHex(4)` `m.slice(r.hl.x-8,r.hl.x+8).toHex(8,"|")`|HL(All Purposes Pointer)
psw:0x4100	AF	`r.psw.x.toHex(4)` AF:`$0=r.psw.l,"sf zf ?0 af ?0 pf ?0 cf".replace(/(\S+)/g, function(s, b) { return 256&($0*=2)?b.toUpperCase().replace("0","1"):b })`
assm:50		ASSM	@@@@ ## ## ##|$$$$ %%%%%%%%%|........................................
-------		operex-field	-------
ZERO		CALCULATE	?r.psw.l|=64:r.psw.l&=-64						ZF
PARITY		CALCULATE	
-------		operex-field	-------
_1			_1	r.pc.n									DB
_2			___2	r.pc.w									ADDR

S0/P0			B/B	r.bc.x									B and C
S1/P1			D/D	r.de.x									D and...

CSS

body	{
	background-color: black;
	color		:lightgreen;
}
pre#Commands, #Coding	{
	color		: lightgreen;
	cursor		: default;
}
span.active {
	text-decoration	: overline underline;
}
span.halted {
	cursor		: cell;
	text-decoration	: line-through;
}
span.CPU_Group__{
	background-color: #012;
	cursor		: pointer;
}
span.CPU_Group_A{
	background-color: #772;	/*ALU*/
}
span.CPU_Group_B{
	background-color: #764;	/*JMP*/
}
span.CPU_Group_C{
	background-color: #888;	/*HLT*/
}
span.CPU_Group_D{
	background-color: #652;	/*INX-*/
}
span.CPU_Group_E{
	background-color: #363;	/*POP*/
}
span.CPU_Group_F{
	background-color: #367;	/*MOV*/
}
span.CPU_Group_X{
	background-color: #437;	/*???*/
}
span.CPU_Group_A_{
	background-color: #EE4;	/*ALU*/
	color		: darkgreen;
}
span.CPU_Group_B_{
	background-color: #EC8;	/*JMP*/
	color		: darkgreen;
}
span.CPU_Group_C_{
	background-color: #FFF;	/*HLT*/
	color		: darkgreen;
}
span.CPU_Group_D_{
	background-color: #CA4;	/*INX-*/
	color		: darkgreen;
}
span.CPU_Group_E_{
	background-color: #6C6;	/*POP*/
	color		: darkgreen;
}
span.CPU_Group_F_{
	background-color: #6CE;	/*MOV*/
	color		: darkgreen;
}
span.CPU_Group_X_{
	background-color: #86E;	/*???*/
	color		: darkgreen;
}
textarea#Pattern	{
	opacity		: 0.95;
}
input[type=radio],
input[type=radio] + label ~ textarea,
input#toK + label ~ textarea#k,
input#toListing + label ~ textarea#Listing,
input#toModel + label ~ textarea#Pattern {
	display	:none;
}
input#toListing:checked + label ~ textarea#Listing,
input#toModel:checked + label ~ textarea#Pattern {
	display	:block;
}
input + label {
	border			: medium buttonface outset;
	background-color	: buttonface;
	color			: buttontext;
}
input:checked + label {
	border-top-style	: inset;
	border-left-style	: inset;
	border-right-style	: inset;
	border-bottom-color	: transparent;
	background-color	: transparent;
	color			: lightgreen;
}

JavaScript

Object.defineProperty(Array.prototype, 'toHex', {
	enumerable	: false,
	value		: function(ofs, sep) {
				var	s = [];
				this.forEach(function(code) {
					s.push(Number(code).toHex(2));
				});
				s = s.join("\xA0");
				return	!ofs || !sep ? s : s.replace(new RegExp("(([0-9A-F]{2}\\s?){" + ofs + "})\\s", "g"), "$1" + sep);
			}
});
Object.defineProperty(Array.prototype, 'toText', {
	enumerable	: false,
	value		: function() {
				var	s = "";
				this.forEach(function(code) {
					s += "&#" + /*String.fromCharCode*/(c >= 32 && c < 127 ? c : 0xB7) + ";";
				});
				return s;
			}
});

String.prototype.x = function(n, j) {var s = this, buf = ""; while(n > 0) { if(n&1) buf+=s; s+=(j?j:"")+s; n >>= 1; } return buf; }

Number.prototype.toHex = function(n) {
	return	(n < 0 ? "0x" : "") + ((((this >> 16) & 0x0000FFFF) | 0x00010000).toString(16) + ((this & 0x0000FFFF) | 0x00010000).toString(16).substr(1)).substr(-Math.abs(n)).toUpperCase();
}
Number.prototype.hi = function(n) {
	if(isFinite(n))
		return	(this & 255) | ((n & 255) << 8);
	return	(this >> 8) & 255;
}
Number.prototype.lo = function(n) {
	if(isFinite(n))
		return	(this & 0xFF00) | (n & 255);
	return	this & 255;
}
var	CPU	=
function(pattern) {
	this.xz = {
		set	cmmd(x) {
		alert(x);
		}
	};
	var	Register	=
	function(x) {
		return	{
			id	: "",
			fx	: 0,
			hi	: (x >> 8) & 255,
			lo	: x & 255,
			start	: x & 65535,
			get reset()	{
				this.lo = this.start & 255,
				this.hi = this.start >> 8;
				return	this.lo | (this.hi << 8);
			},
			get h()		{
				return	this.hi;
			},
			set h(x)	{
				this.fx = (x >> 8) & 1;
				this.hi = (x &= 255);
				this.fx |= (x & 128) | (!x ? 64 : 0);
				x ^= x >> 4;
				x ^= x << 2;
				x ^= x >> 1;
				this.fx |= x & 4;
				//console.log(this.id + ":" + (this.lo | (this.hi << 8)).toHex(-4));
			},
			get l()		{
				return	this.lo;
			},
			set l(x)	{
				this.fx = (x >> 8) & 1;
				this.lo = (x &= 255);
				this.fx |= (x & 128) | (!x ? 64 : 0);
				x ^= x >> 4;
				x ^=...