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>☰</label>
<input type=radio name=Viewer id=toListing><label id=laListing for=toListing accessKey=L>☰Listing</label>
<input type=radio name=Viewer id=toModel><label id=laModel for=toModel accessKey=M>⛓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 ^=...