mirror of
https://github.com/trebonian/visual6502.git
synced 2025-07-08 13:24:09 +00:00
Compare commits
64 Commits
Author | SHA1 | Date | |
---|---|---|---|
84b005673b | |||
09c578e361 | |||
167f93f836 | |||
c88e0749cf | |||
6db8836c5c | |||
27fb1d539e | |||
21c7a8ca90 | |||
cfb726d0e7 | |||
d352501c7c | |||
4eb1e4c848 | |||
c3f0d10199 | |||
4398fdaddf | |||
4f7930eef3 | |||
c04f37a3df | |||
fc664c7243 | |||
8bdb9a0682 | |||
ae30a57822 | |||
8a89310e96 | |||
1c66a8af28 | |||
78deb4aaa4 | |||
85c8447064 | |||
6cdbfc0c15 | |||
8ef98d131f | |||
e660736204 | |||
fc46e50289 | |||
4967b58e7f | |||
6f7dab7990 | |||
04196aa36a | |||
94a2b38d27 | |||
e052255c55 | |||
15453f4435 | |||
7572b25453 | |||
93252a0eb1 | |||
172394845a | |||
ec7da19d77 | |||
13e1f51b47 | |||
e6d3c62057 | |||
fbf0830d15 | |||
019bca0a26 | |||
e866a3b58e | |||
611490ad76 | |||
b3e58dcbab | |||
c7ac03edd8 | |||
b51b5c4398 | |||
398060f56b | |||
cdd837dd0c | |||
3df7065b83 | |||
f860067206 | |||
33f00022ca | |||
8a6fe3634f | |||
296599890a | |||
580f4585a6 | |||
d045485ec4 | |||
71a85b3135 | |||
b3a6a12ddc | |||
5f472cbe10 | |||
6ced887613 | |||
6be4dd1673 | |||
7e6eb926ee | |||
6c899eda1a | |||
6c2217b8fa | |||
f6a86088f0 | |||
5c9b4e7581 | |||
2a0e251088 |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Visual 6502 in JavaScript</title>
|
<title>Visual 6502 in JavaScript</title>
|
||||||
<style type="text/css">@import "wires.css";</style>
|
<style type="text/css">@import "kiosk.css";</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
36
expert.css
36
expert.css
@ -138,6 +138,14 @@ a#linkHere{
|
|||||||
padding:2px;
|
padding:2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea#consolebox{
|
||||||
|
font-family:courier,monospace;
|
||||||
|
border: 1px solid gray;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 2px;
|
||||||
|
width: 80em;
|
||||||
|
}
|
||||||
|
|
||||||
div#logstreamscroller{
|
div#logstreamscroller{
|
||||||
overflow:auto;
|
overflow:auto;
|
||||||
}
|
}
|
||||||
@ -145,10 +153,31 @@ div#logstreamscroller{
|
|||||||
table.logstream {
|
table.logstream {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border-spacing: 2px;
|
border-collapse: collapse;
|
||||||
text-align:center;
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding-left: 3px;
|
||||||
|
padding-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.header {
|
||||||
|
background-color: rgb(187, 204, 255); /* medium-dark blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
td.oddcol {
|
||||||
|
background-color: rgb(227, 233, 255); /* light blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
td.oddrow {
|
||||||
|
background-color: rgb(207, 218, 255); /* medium blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
td.oddrowcol {
|
||||||
|
background-color: rgb(227, 233, 255); /* light blue */
|
||||||
|
}
|
||||||
|
|
||||||
/* Splitter */
|
/* Splitter */
|
||||||
#frame {
|
#frame {
|
||||||
height: 750px;
|
height: 750px;
|
||||||
@ -192,3 +221,8 @@ div.rightcolumn {
|
|||||||
.hsplitbar.active, .hsplitbar:hover {
|
.hsplitbar.active, .hsplitbar:hover {
|
||||||
background: #c66 url(3rdparty/img/hgrabber.gif) no-repeat center;
|
background: #c66 url(3rdparty/img/hgrabber.gif) no-repeat center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span#plain {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
15
expert.html
15
expert.html
@ -76,7 +76,7 @@ $().ready(function(){
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="layoutControlPanel">
|
<div id="layoutControlPanel">
|
||||||
Use '>' to zoom in, '<' to zoom out, click to probe signals and drag to pan.
|
Use 'z' or '>' to zoom in, 'x' or '<' to zoom out, click to probe signals and drag to pan.
|
||||||
<form id="updateShow"> Show:
|
<form id="updateShow"> Show:
|
||||||
<input type="checkbox" name="1" id="updateShow1" onchange="updateShow(this.name,this.checked)" />(diffusion)
|
<input type="checkbox" name="1" id="updateShow1" onchange="updateShow(this.name,this.checked)" />(diffusion)
|
||||||
<input type="checkbox" name="3" id="updateShow3" onchange="updateShow(this.name,this.checked)" />(grounded diffusion)
|
<input type="checkbox" name="3" id="updateShow3" onchange="updateShow(this.name,this.checked)" />(grounded diffusion)
|
||||||
@ -85,8 +85,8 @@ $().ready(function(){
|
|||||||
<input type="checkbox" name="0" id="updateShow0" onchange="updateShow(this.name,this.checked)" />(metal)
|
<input type="checkbox" name="0" id="updateShow0" onchange="updateShow(this.name,this.checked)" />(metal)
|
||||||
<input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(protection)
|
<input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(protection)
|
||||||
</form>
|
</form>
|
||||||
<form action="javascript:hiliteNodeList();" />
|
<form action="javascript:hiliteNodeList();">
|
||||||
<input type="button" value="Highlight:" onclick="hiliteNodeList();" />
|
<input type="button" value="Find:" onclick="hiliteNodeList();" />
|
||||||
<input type="text" id="HighlightThese" name="HighlightThese" value="" />
|
<input type="text" id="HighlightThese" name="HighlightThese" value="" />
|
||||||
<input type="button" value="Clear Highlighting" onclick="clearHighlight();" />
|
<input type="button" value="Clear Highlighting" onclick="clearHighlight();" />
|
||||||
<span class="animatebox">
|
<span class="animatebox">
|
||||||
@ -114,6 +114,10 @@ $().ready(function(){
|
|||||||
<a href ="javascript:goUntilSyncOrWrite()"><img class="navbutton" src="images/singlestep.png" title="step"></a>
|
<a href ="javascript:goUntilSyncOrWrite()"><img class="navbutton" src="images/singlestep.png" title="step"></a>
|
||||||
<a href ="javascript:goFor()"><img class="navbutton" src="images/fastforward.png" title="fastforward"></a>
|
<a href ="javascript:goFor()"><img class="navbutton" src="images/fastforward.png" title="fastforward"></a>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="float:right;">
|
||||||
|
<a href="http://visual6502.org/wiki/index.php?title=JssimUserHelp" target="_blank">User Guide</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div> <!-- buttons -->
|
</div> <!-- buttons -->
|
||||||
<div class="status" id="status"><p>x: 0<br>y: 0</p>
|
<div class="status" id="status"><p>x: 0<br>y: 0</p>
|
||||||
</div> <!-- status -->
|
</div> <!-- status -->
|
||||||
@ -124,7 +128,10 @@ $().ready(function(){
|
|||||||
</div> <!-- righttopdiv -->
|
</div> <!-- righttopdiv -->
|
||||||
|
|
||||||
<div id="tracingdiv">
|
<div id="tracingdiv">
|
||||||
<div id="expertControlPanel">
|
<textarea id="consolebox">
|
||||||
|
click here and type if your program handles input
|
||||||
|
</textarea>
|
||||||
|
<div id="expertControlPanel" tabindex="3">
|
||||||
<form action="javascript:updateLogList()">
|
<form action="javascript:updateLogList()">
|
||||||
<input type="button" value="Trace more" onclick="updateLoglevel(++loglevel)" />
|
<input type="button" value="Trace more" onclick="updateLoglevel(++loglevel)" />
|
||||||
<input type="button" value="Trace less" onclick="updateLoglevel(--loglevel)" />
|
<input type="button" value="Trace less" onclick="updateLoglevel(--loglevel)" />
|
||||||
|
201
expertWires.js
201
expertWires.js
@ -24,6 +24,8 @@ var centerx=300, centery=300;
|
|||||||
var zoom=1;
|
var zoom=1;
|
||||||
var dragMouseX, dragMouseY, moved;
|
var dragMouseX, dragMouseY, moved;
|
||||||
var statbox;
|
var statbox;
|
||||||
|
var findThese;
|
||||||
|
var labelThese=[];
|
||||||
|
|
||||||
// Some constants for the graphics presentation
|
// Some constants for the graphics presentation
|
||||||
// the canvas is embedded in an 800x600 clipping div
|
// the canvas is embedded in an 800x600 clipping div
|
||||||
@ -103,6 +105,7 @@ function setup_part4(){
|
|||||||
setupNodeNameList();
|
setupNodeNameList();
|
||||||
logThese=signalSet(loglevel);
|
logThese=signalSet(loglevel);
|
||||||
loadProgram();
|
loadProgram();
|
||||||
|
setupConsole();
|
||||||
if(noSimulation){
|
if(noSimulation){
|
||||||
stopChip();
|
stopChip();
|
||||||
running=undefined;
|
running=undefined;
|
||||||
@ -172,6 +175,14 @@ function setupParams(){
|
|||||||
} else if(name=="zoom" && parseInt(value)!=NaN){
|
} else if(name=="zoom" && parseInt(value)!=NaN){
|
||||||
zoom=parseInt(value);
|
zoom=parseInt(value);
|
||||||
} else
|
} else
|
||||||
|
// perform a search, highlight and zoom to object(s)
|
||||||
|
if(name=="find" && value.length>0){
|
||||||
|
findThese=value;
|
||||||
|
} else
|
||||||
|
// affix label with optional box to highlight an area of interest
|
||||||
|
if(name=="label" && value.length>0){
|
||||||
|
labelThese.push(value.split(","));
|
||||||
|
} else
|
||||||
// load a test program: Address, Data and Reset
|
// load a test program: Address, Data and Reset
|
||||||
if(name=="a" && parseInt(value,16)!=NaN){
|
if(name=="a" && parseInt(value,16)!=NaN){
|
||||||
userAddress=parseInt(value,16);
|
userAddress=parseInt(value,16);
|
||||||
@ -187,6 +198,14 @@ function setupParams(){
|
|||||||
clockTriggers[value]="setLow('res');";
|
clockTriggers[value]="setLow('res');";
|
||||||
} else if(name=="reset1" && parseInt(value)!=NaN){
|
} else if(name=="reset1" && parseInt(value)!=NaN){
|
||||||
clockTriggers[value]="setHigh('res');";
|
clockTriggers[value]="setHigh('res');";
|
||||||
|
} else if(name=="irq0" && parseInt(value)!=NaN){
|
||||||
|
clockTriggers[value]="setLow('irq');";
|
||||||
|
} else if(name=="irq1" && parseInt(value)!=NaN){
|
||||||
|
clockTriggers[value]="setHigh('irq');";
|
||||||
|
} else if(name=="nmi0" && parseInt(value)!=NaN){
|
||||||
|
clockTriggers[value]="setLow('nmi');";
|
||||||
|
} else if(name=="nmi1" && parseInt(value)!=NaN){
|
||||||
|
clockTriggers[value]="setHigh('nmi');";
|
||||||
} else
|
} else
|
||||||
// run a test program, and optionally check against a golden checksum
|
// run a test program, and optionally check against a golden checksum
|
||||||
if(name=="steps" && parseInt(value)!=NaN){
|
if(name=="steps" && parseInt(value)!=NaN){
|
||||||
@ -219,7 +238,7 @@ function updateChipLayoutAnimation(isOn){
|
|||||||
|
|
||||||
// these keyboard actions are primarily for the chip display
|
// these keyboard actions are primarily for the chip display
|
||||||
function handleKey(e){
|
function handleKey(e){
|
||||||
var c = e.charCode;
|
var c = e.charCode || e.keyCode;
|
||||||
c = String.fromCharCode(c);
|
c = String.fromCharCode(c);
|
||||||
if('<>?npZzx'.indexOf(c)==-1) return;
|
if('<>?npZzx'.indexOf(c)==-1) return;
|
||||||
if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2);
|
if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2);
|
||||||
@ -284,35 +303,141 @@ function recenter(){
|
|||||||
top: top+'px',
|
top: top+'px',
|
||||||
left: left+'px',
|
left: left+'px',
|
||||||
});
|
});
|
||||||
document.getElementById('linkHere').href=location.pathname+"?"+whereAmIAsQuery();
|
updateLinkHere();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinkHere(){
|
||||||
|
var target = location.pathname + "?nosim=t&";
|
||||||
|
var findlist = document.getElementById('HighlightThese').value.split(/[\s,]+/).join(",");
|
||||||
|
if (findlist != "")
|
||||||
|
target = target + "find=" + findlist + "&";
|
||||||
|
target = target + whereAmIAsQuery();
|
||||||
|
document.getElementById('linkHere').href=target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// place a text label on the highlight layer
|
||||||
|
// with an optional box around an area of interest
|
||||||
|
// coordinates used are those reported by a click
|
||||||
|
// for example:
|
||||||
|
// boxLabel(['PD', 50, 8424, 3536, 9256, 2464])
|
||||||
|
// boxLabel(['IR', 50, 8432, 2332, 9124, 984])
|
||||||
|
// boxLabel(['PLA', 100, 1169, 2328, 8393, 934])
|
||||||
|
// boxLabel(['Y', 50, 2143, 8820, 2317, 5689])
|
||||||
|
// boxLabel(['X', 50, 2317, 8820, 2490, 5689])
|
||||||
|
// boxLabel(['S', 50, 2490, 8820, 2814, 5689])
|
||||||
|
// boxLabel(['ALU', 50, 2814, 8820, 4525, 5689])
|
||||||
|
// boxLabel(['DAdj', 40, 4525, 8820, 5040, 5689])
|
||||||
|
// boxLabel(['A', 50, 5040, 8820, 5328, 5689])
|
||||||
|
// boxLabel(['PC', 50, 5559, 8820, 6819, 5689])
|
||||||
|
// boxLabel(['ID', 50, 7365, 8820, 7676, 5689])
|
||||||
|
// boxLabel(['TimC', 40, 600, 1926, 1174, 604])
|
||||||
|
|
||||||
|
function flashBoxLabel(args) {
|
||||||
|
clearHighlight();
|
||||||
|
var callBack = function(){boxLabel(args);};
|
||||||
|
setTimeout(callBack, 400);
|
||||||
|
setTimeout(clearHighlight, 800);
|
||||||
|
setTimeout(callBack, 1200);
|
||||||
|
}
|
||||||
|
|
||||||
|
function boxLabel(args) {
|
||||||
|
var text = args[0];
|
||||||
|
var textsize = args[1];
|
||||||
|
var thickness = 1+ textsize / 20;
|
||||||
|
var boxXmin = args[2] * grCanvasSize / grChipSize;
|
||||||
|
var boxYmin = args[3] * grCanvasSize / grChipSize;
|
||||||
|
var boxXmax = args[4] * grCanvasSize / grChipSize;
|
||||||
|
var boxYmax = args[5] * grCanvasSize / grChipSize;
|
||||||
|
ctx.lineWidth = thickness;
|
||||||
|
ctx.font = textsize + 'px sans-serif';
|
||||||
|
ctx.fillStyle = '#ff0'; // yellow
|
||||||
|
ctx.fillStyle = '#f8f'; // magenta
|
||||||
|
ctx.fillStyle = '#fff'; // white
|
||||||
|
ctx.strokeStyle = '#fff'; // white
|
||||||
|
if(args.length>4){
|
||||||
|
ctxDrawBox(ctx, boxXmin, boxYmin, boxXmax, boxYmax);
|
||||||
|
// offset the text label to the interior of the box
|
||||||
|
boxYmin -= thickness * 2;
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = '#fff'; // white
|
||||||
|
ctx.strokeStyle = '#000'; // black
|
||||||
|
ctx.lineWidth = thickness*2;
|
||||||
|
ctx.strokeText(text, boxXmin, boxYmin);
|
||||||
|
ctx.fillText(text, boxXmin, boxYmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
var highlightThese;
|
var highlightThese;
|
||||||
|
|
||||||
// flash some set of nodes according to user input
|
// flash some set of nodes according to user input
|
||||||
|
// also zoom to fit those nodes (not presently optional)
|
||||||
function hiliteNodeList(){
|
function hiliteNodeList(){
|
||||||
var tmplist = document.getElementById('HighlightThese').value.split(/[\s,]+/);
|
var tmplist = document.getElementById('HighlightThese').value.split(/[\s,]+/);
|
||||||
if(tmplist.length==0){
|
if(tmplist.join("").length==0){
|
||||||
// request to highlight nothing, so switch off any signal highlighting
|
// request to highlight nothing, so switch off any signal highlighting
|
||||||
hiliteNode(-1);
|
hiliteNode(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
highlightThese = [];
|
highlightThese = [];
|
||||||
|
var seglist=[];
|
||||||
|
var report="";
|
||||||
for(var i=0;i<tmplist.length;i++){
|
for(var i=0;i<tmplist.length;i++){
|
||||||
// get a node number from a signal name or a node number
|
// get a node number from a signal name or a node number
|
||||||
var name = tmplist[i];
|
var name = tmplist[i];
|
||||||
var value = parseInt(tmplist[i]);
|
var value = parseInt(tmplist[i]);
|
||||||
if((value!=NaN) && (typeof nodes[name] != "undefined")) {
|
if((value!=NaN) && (typeof nodes[value] != "undefined")) {
|
||||||
highlightThese.push(value);
|
highlightThese.push(value);
|
||||||
|
report="node: " + value + ' ' + nodeName(value);
|
||||||
|
for(var s in nodes[value].segs)
|
||||||
|
seglist.push(nodes[value].segs[s]);
|
||||||
} else if(typeof nodenames[name] != "undefined") {
|
} else if(typeof nodenames[name] != "undefined") {
|
||||||
highlightThese.push(nodenames[name]);
|
highlightThese.push(nodenames[name]);
|
||||||
|
report="node: " + nodenames[name] + ' ' + name;
|
||||||
|
for(var s in nodes[nodenames[name]].segs)
|
||||||
|
seglist.push(nodes[nodenames[name]].segs[s]);
|
||||||
|
} else if(typeof transistors[name] != "undefined") {
|
||||||
|
// normally we push numbers: a non-number is a transistor name
|
||||||
|
highlightThese.push(name);
|
||||||
|
report="transistor: " + name;
|
||||||
|
seglist.push([
|
||||||
|
transistors[name].bb[0],transistors[name].bb[2],
|
||||||
|
transistors[name].bb[1],transistors[name].bb[3]
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// allow match of underscore-delimited components, so
|
||||||
|
// SUMS and dpc17 both match the node dpc17_SUMS
|
||||||
|
for(var i in nodenames){
|
||||||
|
re=new RegExp("(^" + name + "_|_" + name + "$)");
|
||||||
|
if (re.test(i)){
|
||||||
|
value = nodenames[i];
|
||||||
|
highlightThese.push(value);
|
||||||
|
report="node: " + value + ' ' + nodeName(value);
|
||||||
|
for(var s in nodes[value].segs)
|
||||||
|
seglist.push(nodes[value].segs[s]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// invalid input: how to tell the user?
|
|
||||||
}
|
}
|
||||||
if(highlightThese.length==0){
|
if(highlightThese.length==0){
|
||||||
// all input rejected: how to tell the user?
|
setStatus('Find: nothing found!','(Enter a list of nodenumbers, names or transistor names)');
|
||||||
return;
|
return;
|
||||||
|
} else if (highlightThese.length==1){
|
||||||
|
setStatus('Find results:',report);
|
||||||
|
} else {
|
||||||
|
setStatus('Find: multiple objects found','(' + highlightThese.length + ' objects)');
|
||||||
}
|
}
|
||||||
|
var xmin=seglist[0][0], xmax=seglist[0][0];
|
||||||
|
var ymin=seglist[0][1], ymax=seglist[0][1];
|
||||||
|
for(var s in seglist){
|
||||||
|
for(var i=0;i<seglist[s].length;i+=2){
|
||||||
|
if(seglist[s][i]<xmin) xmin=seglist[s][i];
|
||||||
|
if(seglist[s][i]>xmax) xmax=seglist[s][i];
|
||||||
|
if(seglist[s][i+1]<ymin) ymin=seglist[s][i+1];
|
||||||
|
if(seglist[s][i+1]>ymax) ymax=seglist[s][i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zoomToBox(xmin,xmax,ymin,ymax);
|
||||||
|
updateLinkHere();
|
||||||
clearHighlight(); // nullify the simulation overlay (orange/purple)
|
clearHighlight(); // nullify the simulation overlay (orange/purple)
|
||||||
hiliteNode(-1); // unhighlight all nodes
|
hiliteNode(-1); // unhighlight all nodes
|
||||||
setTimeout("hiliteNode(highlightThese);", 400);
|
setTimeout("hiliteNode(highlightThese);", 400);
|
||||||
@ -320,22 +445,53 @@ function hiliteNodeList(){
|
|||||||
setTimeout("hiliteNode(highlightThese);", 1200);
|
setTimeout("hiliteNode(highlightThese);", 1200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// some notes on coordinates:
|
||||||
|
// the localx and localy functions return canvas coordinate offsets from the canvas window top left corner
|
||||||
|
// we divide the results by 'zoom' to get drawn coordinates useful in findNodeNumber
|
||||||
|
// to convert to reported user chip coordinates we multiply by grChipSize/600
|
||||||
|
// to compare to segdefs and transdefs coordinates we subtract 400 from x and subtract y from grChipSize
|
||||||
|
|
||||||
function handleClick(e){
|
function handleClick(e){
|
||||||
var x = localx(hilite, e.clientX)/zoom;
|
var x = localx(hilite, e.clientX)/zoom;
|
||||||
var y = localy(hilite, e.clientY)/zoom;
|
var y = localy(hilite, e.clientY)/zoom;
|
||||||
var w = findNodeNumber(x,y);
|
var w = findNodeNumber(x,y);
|
||||||
if(e.shiftKey) hiliteNode(getNodeGroup(w));
|
// convert to chip coordinates
|
||||||
else {var a=new Array(); a.push(w); hiliteNode(a);}
|
|
||||||
var cx = Math.round(x*grChipSize/600);
|
var cx = Math.round(x*grChipSize/600);
|
||||||
var cy = Math.round(y*grChipSize/600);
|
var cy = Math.round(y*grChipSize/600);
|
||||||
if(w==-1) {
|
// prepare two lines of status report
|
||||||
setStatus('x: '+cx, 'y: '+cy);
|
|
||||||
} else {
|
|
||||||
var s1='x: ' + cx + ' y: ' + cy;
|
var s1='x: ' + cx + ' y: ' + cy;
|
||||||
var s2='node: ' + w + ' ' + nodeName(w);
|
var s2='node: ' + w + ' ' + nodeName(w);
|
||||||
|
if(w==-1) {
|
||||||
|
setStatus(s1); // no node found, so report only coordinates
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// we have a node, but maybe we clicked over a transistor
|
||||||
|
var nodelist=[w];
|
||||||
|
// match the coordinate against transistor gate bounding boxes
|
||||||
|
x=cx-400;
|
||||||
|
y=grChipSize-cy;
|
||||||
|
for(var i=0;i<nodes[w].gates.length;i++){
|
||||||
|
var xmin=nodes[w].gates[i].bb[0], xmax=nodes[w].gates[i].bb[1];
|
||||||
|
var ymin=nodes[w].gates[i].bb[2], ymax=nodes[w].gates[i].bb[3];
|
||||||
|
if((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)){
|
||||||
|
// only one match at most, so we replace rather than push
|
||||||
|
nodelist=[nodes[w].gates[i].name];
|
||||||
|
s2='transistor: ' + nodes[w].gates[i].name + ' on ' + s2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if this is a shift-click, just find and highlight the pass-connected group
|
||||||
|
// and list the nodes (or nodenames, preferably)
|
||||||
|
if(e.shiftKey) {
|
||||||
|
getNodeGroup(w);
|
||||||
|
nodelist = group;
|
||||||
|
s2 = "nodegroup from " + s2 +
|
||||||
|
" (nodes: " +
|
||||||
|
group.map(function(x){return nodeName(x)?nodeName(x):x;}).join(",") +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
hiliteNode(nodelist);
|
||||||
setStatus(s1, s2);
|
setStatus(s1, s2);
|
||||||
if(ctrace) console.log(s1, s2);
|
if(ctrace) console.log(s1, s2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLoglevel(value){
|
function updateLoglevel(value){
|
||||||
@ -352,6 +508,14 @@ function setupExpertMode(isOn){
|
|||||||
document.getElementById('layoutControlPanel').style.display = 'block';
|
document.getElementById('layoutControlPanel').style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var consolegetc; // global variable to hold last keypress in the console area
|
||||||
|
var consolebox;
|
||||||
|
|
||||||
|
function setupConsole(){
|
||||||
|
consolebox=document.getElementById('consolebox');
|
||||||
|
consolebox.onkeypress=function(e){consolegetc=e.charCode || e.keyCode;};
|
||||||
|
}
|
||||||
|
|
||||||
var chipsurround;
|
var chipsurround;
|
||||||
|
|
||||||
function updateChipLayoutVisibility(isOn){
|
function updateChipLayoutVisibility(isOn){
|
||||||
@ -392,8 +556,19 @@ function setupChipLayoutGraphics(){
|
|||||||
refresh();
|
refresh();
|
||||||
document.getElementById('waiting').style.display = 'none';
|
document.getElementById('waiting').style.display = 'none';
|
||||||
setStatus('Ready!'); // would prefer chipStatus but it's not idempotent
|
setStatus('Ready!'); // would prefer chipStatus but it's not idempotent
|
||||||
|
// pre-fill the Find box if parameters supplied
|
||||||
|
if(typeof findThese != "undefined") {
|
||||||
|
document.getElementById('HighlightThese').value = findThese;
|
||||||
|
hiliteNodeList(); // will pan and zoom to fit
|
||||||
|
}
|
||||||
|
// pre-pan and zoom if requested (will override any zoom-to-fit by hiliteNodeList)
|
||||||
if(moveHereFirst!=null)
|
if(moveHereFirst!=null)
|
||||||
moveHere(moveHereFirst);
|
moveHere(moveHereFirst);
|
||||||
|
// draw any URL-requested labels and boxes
|
||||||
|
if(labelThese.length>0) {
|
||||||
|
for(var i=0;i<labelThese.length;i+=1)
|
||||||
|
flashBoxLabel(labelThese[i]);
|
||||||
|
}
|
||||||
// grant focus to the chip display to enable zoom keys
|
// grant focus to the chip display to enable zoom keys
|
||||||
chipsurround.focus();
|
chipsurround.focus();
|
||||||
chipsurround.onmousedown = function(e){mouseDown(e);};
|
chipsurround.onmousedown = function(e){mouseDown(e);};
|
||||||
|
11
index.html
11
index.html
@ -12,8 +12,8 @@
|
|||||||
<script src="wires.js"></script>
|
<script src="wires.js"></script>
|
||||||
<script src="chipsim.js"></script>
|
<script src="chipsim.js"></script>
|
||||||
<script src="memtable.js"></script>
|
<script src="memtable.js"></script>
|
||||||
<script src="testprogram.js"></script>
|
|
||||||
<script src="macros.js"></script>
|
<script src="macros.js"></script>
|
||||||
|
<script src="testprogram.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function handleOnload() {
|
function handleOnload() {
|
||||||
@ -62,11 +62,11 @@ lots of RAM. If you have trouble, please <a href="browsertrouble.html">check com
|
|||||||
<br />
|
<br />
|
||||||
<span id="browsertrouble"></span>
|
<span id="browsertrouble"></span>
|
||||||
<br />
|
<br />
|
||||||
Hit '>' to zoom in, '<' to zoom out
|
Keyboard controls: 'z' to zoom in, 'x' to zoom out, 'n' to step the simulation.
|
||||||
<br />
|
<br />
|
||||||
Left-click and drag to scroll around
|
Mouse controls: Left-click and drag to scroll around (when you're zoomed in.)
|
||||||
<br />
|
<br />
|
||||||
Enter your own program into the array of RAM
|
More information in the <a href="http://visual6502.org/wiki/index.php?title=JssimUserHelp">User Guide<a>.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</span>
|
</span>
|
||||||
@ -87,6 +87,7 @@ Enter your own program into the array of RAM
|
|||||||
<a href ="javascript:stepBack()"><img class="navbutton" src="images/prev.png"></a>
|
<a href ="javascript:stepBack()"><img class="navbutton" src="images/prev.png"></a>
|
||||||
<a href ="javascript:stepForward()"><img class="navbutton" src="images/next.png"></a>
|
<a href ="javascript:stepForward()"><img class="navbutton" src="images/next.png"></a>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="float:right; margin-left:20px;">... or try <a href="expert.html">Advanced</a></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="status" id="status">x: 0<br>y: 0</p>
|
<p class="status" id="status">x: 0<br>y: 0</p>
|
||||||
<table class="memtable" id="memtable"></table>
|
<table class="memtable" id="memtable"></table>
|
||||||
@ -99,7 +100,7 @@ Source code is available on <a href="http://github.com/trebonian/visual6502">git
|
|||||||
Use the online <a href="http://www.6502asm.com/">emulator and assembler</a> from 6502asm.com
|
Use the online <a href="http://www.6502asm.com/">emulator and assembler</a> from 6502asm.com
|
||||||
and <a href="http://www.e-tradition.net/bytes/6502/disassembler.html">disassembler</a> from e-tradition.net
|
and <a href="http://www.e-tradition.net/bytes/6502/disassembler.html">disassembler</a> from e-tradition.net
|
||||||
<br />
|
<br />
|
||||||
For in-depth 6502 investigation and some more advanced features, try our <a href="/JSSim/expert.html">Experimenter's (Beta) version</a>.
|
For in-depth 6502 investigation and some more advanced features, try our <a href="expert.html">Advanced</a> page.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ function setup_part2(){
|
|||||||
|
|
||||||
function setup_part3(){
|
function setup_part3(){
|
||||||
loadProgram();
|
loadProgram();
|
||||||
|
writeTriggers={}; // kiosk mode does not handle I/O
|
||||||
initChip();
|
initChip();
|
||||||
document.getElementById('stop').style.visibility = 'hidden';
|
document.getElementById('stop').style.visibility = 'hidden';
|
||||||
go();
|
go();
|
||||||
@ -101,11 +102,11 @@ function setup_part3(){
|
|||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
function handleKey(e){
|
function handleKey(e){
|
||||||
var c = e.charCode;
|
var c = e.charCode || e.keyCode;
|
||||||
c = String.fromCharCode(c);
|
c = String.fromCharCode(c);
|
||||||
if('<>?np'.indexOf(c)==-1) return;
|
if('zx<>?np'.indexOf(c)==-1) return;
|
||||||
if(c=='<' && zoom>1) setZoom(zoom/1.2);
|
if((c=='x' || c=='<') && zoom>1) setZoom(zoom/1.2);
|
||||||
else if(c=='>' && zoom<grMaxZoom) setZoom(zoom*1.2);
|
else if((c=='z' || c=='>') && zoom<grMaxZoom) setZoom(zoom*1.2);
|
||||||
else if(c=='?') setZoom(1);
|
else if(c=='?') setZoom(1);
|
||||||
else if(c=='n') stepForward();
|
else if(c=='n') stepForward();
|
||||||
else if(c=='p') stepBack();
|
else if(c=='p') stepBack();
|
||||||
@ -168,7 +169,10 @@ function handleClick(e){
|
|||||||
var x = localx(hilite, e.clientX)/zoom;
|
var x = localx(hilite, e.clientX)/zoom;
|
||||||
var y = localy(hilite, e.clientY)/zoom;
|
var y = localy(hilite, e.clientY)/zoom;
|
||||||
var w = findNodeNumber(x,y);
|
var w = findNodeNumber(x,y);
|
||||||
if(e.shiftKey) hiliteNode(getNodeGroup(w));
|
if(e.shiftKey) {
|
||||||
|
getNodeGroup(w);
|
||||||
|
hiliteNode(group);
|
||||||
|
}
|
||||||
else {var a=new Array(); a.push(w); hiliteNode(a);}
|
else {var a=new Array(); a.push(w); hiliteNode(a);}
|
||||||
var cx = Math.round(x*grChipSize/600);
|
var cx = Math.round(x*grChipSize/600);
|
||||||
var cy = Math.round(y*grChipSize/600);
|
var cy = Math.round(y*grChipSize/600);
|
||||||
|
338
macros.js
338
macros.js
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles
|
Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles, Achim Breidenbach
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -28,11 +28,12 @@ var running = false;
|
|||||||
var logThese=[];
|
var logThese=[];
|
||||||
var presetLogLists=[
|
var presetLogLists=[
|
||||||
['cycle'],
|
['cycle'],
|
||||||
['ab','db','rw','sync','pc','a','x','y','s','p'],
|
['ab','db','rw','Fetch','pc','a','x','y','s','p'],
|
||||||
['ir','tcstate','pd'],
|
['Execute','State'],
|
||||||
|
['ir','tcstate','-pd'],
|
||||||
['adl','adh','sb','alu'],
|
['adl','adh','sb','alu'],
|
||||||
['alucin','alua','alub','alucout','aluvout','dasb'],
|
['alucin','alua','alub','alucout','aluvout','dasb'],
|
||||||
['plaOutputs'],
|
['plaOutputs','DPControl'],
|
||||||
['idb','dor'],
|
['idb','dor'],
|
||||||
['irq','nmi','res'],
|
['irq','nmi','res'],
|
||||||
];
|
];
|
||||||
@ -209,24 +210,42 @@ function step(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// triggers for breakpoints, watchpoints, input pin events
|
// triggers for breakpoints, watchpoints, input pin events
|
||||||
|
// almost always are undefined when tested, so minimal impact on performance
|
||||||
clockTriggers={};
|
clockTriggers={};
|
||||||
|
writeTriggers={};
|
||||||
|
readTriggers={};
|
||||||
|
fetchTriggers={};
|
||||||
|
|
||||||
|
// example instruction tracing triggers
|
||||||
|
// fetchTriggers[0x20]="console.log('0x'+readAddressBus().toString(16)+': JSR');";
|
||||||
|
// fetchTriggers[0x60]="console.log('0x'+readAddressBus().toString(16)+': RTS');";
|
||||||
|
// fetchTriggers[0x4c]="console.log('0x'+readAddressBus().toString(16)+': JMP');";
|
||||||
|
|
||||||
// simulate a single clock phase with no update to graphics or trace
|
// simulate a single clock phase with no update to graphics or trace
|
||||||
function halfStep(){
|
function halfStep(){
|
||||||
var clk = isNodeHigh(nodenames['clk0']);
|
var clk = isNodeHigh(nodenames['clk0']);
|
||||||
eval(clockTriggers[cycle]); // usually undefined, no measurable performance loss
|
eval(clockTriggers[cycle]);
|
||||||
if (clk) {setLow('clk0'); handleBusRead(); }
|
if (clk) {setLow('clk0'); handleBusRead(); }
|
||||||
else {setHigh('clk0'); handleBusWrite();}
|
else {setHigh('clk0'); handleBusWrite();}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBusRead(){
|
function handleBusRead(){
|
||||||
if(isNodeHigh(nodenames['rw'])) writeDataBus(mRead(readAddressBus()));
|
if(isNodeHigh(nodenames['rw'])){
|
||||||
|
var a = readAddressBus();
|
||||||
|
var d = eval(readTriggers[a]);
|
||||||
|
if(d == undefined)
|
||||||
|
d = mRead(readAddressBus());
|
||||||
|
if(isNodeHigh(nodenames['sync']))
|
||||||
|
eval(fetchTriggers[d]);
|
||||||
|
writeDataBus(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBusWrite(){
|
function handleBusWrite(){
|
||||||
if(!isNodeHigh(nodenames['rw'])){
|
if(!isNodeHigh(nodenames['rw'])){
|
||||||
var a = readAddressBus();
|
var a = readAddressBus();
|
||||||
var d = readDataBus();
|
var d = readDataBus();
|
||||||
|
eval(writeTriggers[a]);
|
||||||
mWrite(a,d);
|
mWrite(a,d);
|
||||||
if(a<0x200) setCellValue(a,d);
|
if(a<0x200) setCellValue(a,d);
|
||||||
}
|
}
|
||||||
@ -243,7 +262,7 @@ function readPstring(){
|
|||||||
result = (isNodeHigh(nodenames['p7'])?'N':'n') +
|
result = (isNodeHigh(nodenames['p7'])?'N':'n') +
|
||||||
(isNodeHigh(nodenames['p6'])?'V':'v') +
|
(isNodeHigh(nodenames['p6'])?'V':'v') +
|
||||||
'‑' + // non-breaking hyphen
|
'‑' + // non-breaking hyphen
|
||||||
(isNodeHigh(nodenames['p3'])?'B':'b') +
|
(isNodeHigh(nodenames['p4'])?'B':'b') +
|
||||||
(isNodeHigh(nodenames['p3'])?'D':'d') +
|
(isNodeHigh(nodenames['p3'])?'D':'d') +
|
||||||
(isNodeHigh(nodenames['p2'])?'I':'i') +
|
(isNodeHigh(nodenames['p2'])?'I':'i') +
|
||||||
(isNodeHigh(nodenames['p1'])?'Z':'z') +
|
(isNodeHigh(nodenames['p1'])?'Z':'z') +
|
||||||
@ -255,18 +274,31 @@ function readPC(){return (readBits('pch', 8)<<8) + readBits('pcl', 8);}
|
|||||||
function readPCL(){return readBits('pcl', 8);}
|
function readPCL(){return readBits('pcl', 8);}
|
||||||
function readPCH(){return readBits('pch', 8);}
|
function readPCH(){return readBits('pch', 8);}
|
||||||
|
|
||||||
function listActivePlaOutputs(){
|
// for one-hot or few-hot signal collections we want to list the active ones
|
||||||
// PLA outputs are mostly ^op- but some have a prefix too
|
// and for brevity we remove the common prefix
|
||||||
// - we'll allow the x and xx prefix but ignore the #
|
function listActiveSignals(pattern){
|
||||||
var r=new RegExp('^([x]?x-)?op-');
|
var r=new RegExp(pattern);
|
||||||
var pla=[];
|
var list=[];
|
||||||
for(var i in nodenamelist){
|
for(var i in nodenamelist){
|
||||||
if(r.test(nodenamelist[i])) {
|
if(r.test(nodenamelist[i])) {
|
||||||
if(isNodeHigh(nodenames[nodenamelist[i]]))
|
if(isNodeHigh(nodenames[nodenamelist[i]]))
|
||||||
pla.push(nodenamelist[i]);
|
// also map hyphen to a non-breaking version
|
||||||
|
list.push(nodenamelist[i].replace(r,'').replace(/-/g,'‑'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pla;
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The 6502 TCState is almost but not quite an inverted one-hot shift register
|
||||||
|
function listActiveTCStates() {
|
||||||
|
var s=[];
|
||||||
|
if(!isNodeHigh(nodenames['clock1'])) s.push("T0");
|
||||||
|
if(!isNodeHigh(nodenames['clock2'])) s.push("T1");
|
||||||
|
if(!isNodeHigh(nodenames['t2'])) s.push("T2");
|
||||||
|
if(!isNodeHigh(nodenames['t3'])) s.push("T3");
|
||||||
|
if(!isNodeHigh(nodenames['t4'])) s.push("T4");
|
||||||
|
if(!isNodeHigh(nodenames['t5'])) s.push("T5");
|
||||||
|
return s.join("+");
|
||||||
}
|
}
|
||||||
|
|
||||||
function readBit(name){
|
function readBit(name){
|
||||||
@ -284,6 +316,7 @@ function readBits(name, n){
|
|||||||
function busToString(busname){
|
function busToString(busname){
|
||||||
// takes a signal name or prefix
|
// takes a signal name or prefix
|
||||||
// returns an appropriate string representation
|
// returns an appropriate string representation
|
||||||
|
// some 'signal names' are CPU-specific aliases to user-friendly string output
|
||||||
if(busname=='cycle')
|
if(busname=='cycle')
|
||||||
return cycle>>1;
|
return cycle>>1;
|
||||||
if(busname=='pc')
|
if(busname=='pc')
|
||||||
@ -292,15 +325,34 @@ function busToString(busname){
|
|||||||
return readPstring();
|
return readPstring();
|
||||||
if(busname=='tcstate')
|
if(busname=='tcstate')
|
||||||
return ['clock1','clock2','t2','t3','t4','t5'].map(busToHex).join("");
|
return ['clock1','clock2','t2','t3','t4','t5'].map(busToHex).join("");
|
||||||
|
if(busname=='State')
|
||||||
|
return listActiveTCStates();
|
||||||
|
if(busname=='Execute')
|
||||||
|
return dis6502toHTML(readBits('ir',8));
|
||||||
|
if(busname=='Fetch')
|
||||||
|
return isNodeHigh(nodenames['sync'])?dis6502toHTML(readDataBus()):"";
|
||||||
if(busname=='plaOutputs')
|
if(busname=='plaOutputs')
|
||||||
return listActivePlaOutputs();
|
// PLA outputs are mostly ^op- but some have a prefix too
|
||||||
|
// - we'll allow the x and xx prefix but ignore the #
|
||||||
|
return listActiveSignals('^([x]?x-)?op-');
|
||||||
|
if(busname=='DPControl')
|
||||||
|
return listActiveSignals('^dpc[0-9]+_');
|
||||||
|
if(busname[0]=="-"){
|
||||||
|
// invert the value of the bus for display
|
||||||
|
var value=busToHex(busname.slice(1))
|
||||||
|
if(typeof value != "undefined")
|
||||||
|
return value.replace(/./g,function(x){return (15-parseInt(x,16)).toString(16)});
|
||||||
|
else
|
||||||
|
return undefined;;
|
||||||
|
} else {
|
||||||
return busToHex(busname);
|
return busToHex(busname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function busToHex(busname){
|
function busToHex(busname){
|
||||||
// may be passed a bus or a signal, so allow multiple signals
|
// may be passed a bus or a signal, so allow multiple signals
|
||||||
var width=0;
|
var width=0;
|
||||||
var r=new RegExp('^' + busname + '[0-9]');
|
var r=new RegExp('^' + busname + '[0-9]+$');
|
||||||
for(var i in nodenamelist){
|
for(var i in nodenamelist){
|
||||||
if(r.test(nodenamelist[i])) {
|
if(r.test(nodenamelist[i])) {
|
||||||
width++;
|
width++;
|
||||||
@ -407,25 +459,56 @@ function chipStatus(){
|
|||||||
' Y:' + hexByte(readY()) +
|
' Y:' + hexByte(readY()) +
|
||||||
' SP:' + hexByte(readSP()) +
|
' SP:' + hexByte(readSP()) +
|
||||||
' ' + readPstring();
|
' ' + readPstring();
|
||||||
var chk='';
|
var machine3 =
|
||||||
|
'Hz: ' + estimatedHz().toFixed(1);
|
||||||
|
if(typeof expertMode != "undefined") {
|
||||||
|
machine3 += ' Exec: ' + busToString('Execute') + '(' + busToString('State') + ')';
|
||||||
|
if(isNodeHigh(nodenames['sync']))
|
||||||
|
machine3 += ' (Fetch: ' + busToString('Fetch') + ')';
|
||||||
if(goldenChecksum != undefined)
|
if(goldenChecksum != undefined)
|
||||||
chk=" Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
|
machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
|
||||||
setStatus(machine1, machine2, "Hz: " + estimatedHz().toFixed(1) + chk);
|
}
|
||||||
|
setStatus(machine1, machine2, machine3);
|
||||||
if (loglevel>0) {
|
if (loglevel>0) {
|
||||||
updateLogbox(logThese);
|
updateLogbox(logThese);
|
||||||
}
|
}
|
||||||
selectCell(ab);
|
selectCell(ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run for an extended number of cycles, with low overhead, for interactive programs or for benchmarking
|
||||||
|
// note: to run an interactive program, use an URL like
|
||||||
|
// http://visual6502.org/JSSim/expert.html?graphics=f&loglevel=-1&headlesssteps=-500
|
||||||
function goFor(){
|
function goFor(){
|
||||||
var n = headlessSteps;
|
var n = headlessSteps; // a negative value is a request to free-run
|
||||||
estimatedHz1();
|
if(headlessSteps<0)
|
||||||
|
n=-n;
|
||||||
|
var start = document.getElementById('start');
|
||||||
|
var stop = document.getElementById('stop');
|
||||||
|
start.style.visibility = 'hidden';
|
||||||
|
stop.style.visibility = 'visible';
|
||||||
|
if(typeof running == "undefined") {
|
||||||
|
initChip();
|
||||||
|
}
|
||||||
|
running = true;
|
||||||
|
setTimeout("instantaneousHz(); goForN("+n+")",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function: allows us to poll 'running' without resetting it when we're re-scheduled
|
||||||
|
function goForN(n){
|
||||||
|
var n2=n; // save our parameter so we can re-submit ourselves
|
||||||
while(n--){
|
while(n--){
|
||||||
halfStep();
|
halfStep();
|
||||||
cycle++;
|
cycle++;
|
||||||
}
|
}
|
||||||
estimatedHz1();
|
instantaneousHz();
|
||||||
chipStatus();
|
chipStatus();
|
||||||
|
if((headlessSteps<0) && running){
|
||||||
|
setTimeout("goForN("+n2+")",0); // re-submit ourselves if we are meant to free-run
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
start.style.visibility = 'visible';
|
||||||
|
stop.style.visibility = 'hidden';
|
||||||
}
|
}
|
||||||
|
|
||||||
var prevHzTimeStamp=0;
|
var prevHzTimeStamp=0;
|
||||||
@ -434,13 +517,10 @@ var prevHzEstimate1=1;
|
|||||||
var prevHzEstimate2=1;
|
var prevHzEstimate2=1;
|
||||||
var HzSamplingRate=10;
|
var HzSamplingRate=10;
|
||||||
|
|
||||||
|
// return an averaged speed: called periodically during normal running
|
||||||
function estimatedHz(){
|
function estimatedHz(){
|
||||||
if(cycle%HzSamplingRate!=3)
|
if(cycle%HzSamplingRate!=3)
|
||||||
return prevHzEstimate1;
|
return prevHzEstimate1;
|
||||||
return estimatedHz1();
|
|
||||||
}
|
|
||||||
|
|
||||||
function estimatedHz1(){
|
|
||||||
var HzTimeStamp = now();
|
var HzTimeStamp = now();
|
||||||
var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01);
|
var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01);
|
||||||
HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz
|
HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz
|
||||||
@ -455,12 +535,26 @@ function estimatedHz1(){
|
|||||||
return prevHzEstimate1
|
return prevHzEstimate1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return instantaneous speed: called twice, before and after a timed run using goFor()
|
||||||
|
function instantaneousHz(){
|
||||||
|
var HzTimeStamp = now();
|
||||||
|
var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01);
|
||||||
|
HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz
|
||||||
|
prevHzEstimate1=HzEstimate;
|
||||||
|
prevHzEstimate2=prevHzEstimate1;
|
||||||
|
prevHzTimeStamp=HzTimeStamp;
|
||||||
|
prevHzCycleCount=cycle;
|
||||||
|
return prevHzEstimate1
|
||||||
|
}
|
||||||
|
|
||||||
|
var logbox;
|
||||||
function initLogbox(names){
|
function initLogbox(names){
|
||||||
var logbox=document.getElementById('logstream');
|
logbox=document.getElementById('logstream');
|
||||||
if(logbox==null)return;
|
if(logbox==null)return;
|
||||||
|
|
||||||
|
names=names.map(function(x){return x.replace(/^-/,'')});
|
||||||
logStream = [];
|
logStream = [];
|
||||||
logStream.push("<td>" + names.join("</td><td>") + "</td>");
|
logStream.push("<td class=header>" + names.join("</td><td class=header>") + "</td>");
|
||||||
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,9 +563,8 @@ var logboxAppend=true;
|
|||||||
// can append or prepend new states to the log table
|
// can append or prepend new states to the log table
|
||||||
// when we reverse direction we need to reorder the log stream
|
// when we reverse direction we need to reorder the log stream
|
||||||
function updateLogDirection(){
|
function updateLogDirection(){
|
||||||
logboxAppend=!logboxAppend;
|
|
||||||
var logbox=document.getElementById('logstream');
|
|
||||||
var loglines=[];
|
var loglines=[];
|
||||||
|
logboxAppend=!logboxAppend;
|
||||||
// the first element is the header so we can't reverse()
|
// the first element is the header so we can't reverse()
|
||||||
for (var i=1;i<logStream.length;i++) {
|
for (var i=1;i<logStream.length;i++) {
|
||||||
loglines.unshift(logStream[i]);
|
loglines.unshift(logStream[i]);
|
||||||
@ -483,18 +576,27 @@ function updateLogDirection(){
|
|||||||
|
|
||||||
// update the table of signal values, by prepending or appending
|
// update the table of signal values, by prepending or appending
|
||||||
function updateLogbox(names){
|
function updateLogbox(names){
|
||||||
var logbox=document.getElementById('logstream');
|
|
||||||
var signals=[];
|
var signals=[];
|
||||||
|
var odd=true;
|
||||||
|
var bg;
|
||||||
|
var row;
|
||||||
|
|
||||||
for(i in names){
|
for(var i in names){
|
||||||
signals.push(busToString(names[i]));
|
if(cycle % 4 < 2){
|
||||||
|
bg = odd ? " class=oddcol":"";
|
||||||
|
} else {
|
||||||
|
bg = odd ? " class=oddrow":" class=oddrowcol";
|
||||||
}
|
}
|
||||||
|
signals.push("<td" + bg + ">" + busToString(names[i]) + "</td>");
|
||||||
|
odd =! odd;
|
||||||
|
}
|
||||||
|
row = "<tr>" + signals.join("") + "</tr>";
|
||||||
if(logboxAppend)
|
if(logboxAppend)
|
||||||
logStream.push("<td>" + signals.join("</td><td>") + "</td>");
|
logStream.push(row);
|
||||||
else
|
else
|
||||||
logStream.splice(1,0,"<td>" + signals.join("</td><td>") + "</td>");
|
logStream.splice(1,0,row);
|
||||||
|
|
||||||
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
logbox.innerHTML = logStream.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMem(){
|
function getMem(){
|
||||||
@ -519,3 +621,167 @@ function adler32(x){
|
|||||||
}
|
}
|
||||||
return (0x100000000+(b<<16)+a).toString(16).slice(-8);
|
return (0x100000000+(b<<16)+a).toString(16).slice(-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanitised opcode for HTML output
|
||||||
|
function dis6502toHTML(byte){
|
||||||
|
var opcode=dis6502[byte];
|
||||||
|
if(typeof opcode == "undefined")
|
||||||
|
return "unknown"
|
||||||
|
return opcode.replace(/ /,' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// opcode lookup for 6502 - not quite a disassembly
|
||||||
|
// javascript derived from Debugger.java by Achim Breidenbach
|
||||||
|
var dis6502={
|
||||||
|
0x00:"BRK",
|
||||||
|
0x01:"ORA (zp,X)",
|
||||||
|
0x05:"ORA zp",
|
||||||
|
0x06:"ASL zp",
|
||||||
|
0x08:"PHP",
|
||||||
|
0x09:"ORA #",
|
||||||
|
0x0A:"ASL ",
|
||||||
|
0x0D:"ORA Abs",
|
||||||
|
0x0E:"ASL Abs",
|
||||||
|
0x10:"BPL ",
|
||||||
|
0x11:"ORA (zp),Y",
|
||||||
|
0x15:"ORA zp,X",
|
||||||
|
0x16:"ASL zp,X",
|
||||||
|
0x18:"CLC",
|
||||||
|
0x19:"ORA Abs,Y",
|
||||||
|
0x1D:"ORA Abs,X",
|
||||||
|
0x1E:"ASL Abs,X",
|
||||||
|
0x20:"JSR Abs",
|
||||||
|
0x21:"AND (zp,X)",
|
||||||
|
0x24:"BIT zp",
|
||||||
|
0x25:"AND zp",
|
||||||
|
0x26:"ROL zp",
|
||||||
|
0x28:"PLP",
|
||||||
|
0x29:"AND #",
|
||||||
|
0x2A:"ROL ",
|
||||||
|
0x2C:"BIT Abs",
|
||||||
|
0x2D:"AND Abs",
|
||||||
|
0x2E:"ROL Abs",
|
||||||
|
0x30:"BMI ",
|
||||||
|
0x31:"AND (zp),Y",
|
||||||
|
0x35:"AND zp,X",
|
||||||
|
0x36:"ROL zp,X",
|
||||||
|
0x38:"SEC",
|
||||||
|
0x39:"AND Abs,Y",
|
||||||
|
0x3D:"AND Abs,X",
|
||||||
|
0x3E:"ROL Abs,X",
|
||||||
|
0x40:"RTI",
|
||||||
|
0x41:"EOR (zp,X)",
|
||||||
|
0x45:"EOR zp",
|
||||||
|
0x46:"LSR zp",
|
||||||
|
0x48:"PHA",
|
||||||
|
0x49:"EOR #",
|
||||||
|
0x4A:"LSR ",
|
||||||
|
0x4C:"JMP Abs",
|
||||||
|
0x4D:"EOR Abs",
|
||||||
|
0x4E:"LSR Abs",
|
||||||
|
0x50:"BVC ",
|
||||||
|
0x51:"EOR (zp),Y",
|
||||||
|
0x55:"EOR zp,X",
|
||||||
|
0x56:"LSR zp,X",
|
||||||
|
0x58:"CLI",
|
||||||
|
0x59:"EOR Abs,Y",
|
||||||
|
0x5D:"EOR Abs,X",
|
||||||
|
0x5E:"LSR Abs,X",
|
||||||
|
0x60:"RTS",
|
||||||
|
0x61:"ADC (zp,X)",
|
||||||
|
0x65:"ADC zp",
|
||||||
|
0x66:"ROR zp",
|
||||||
|
0x68:"PLA",
|
||||||
|
0x69:"ADC #",
|
||||||
|
0x6A:"ROR ",
|
||||||
|
0x6C:"JMP zp",
|
||||||
|
0x6D:"ADC Abs",
|
||||||
|
0x6E:"ROR Abs",
|
||||||
|
0x70:"BVS ",
|
||||||
|
0x71:"ADC (zp),Y",
|
||||||
|
0x75:"ADC zp,X",
|
||||||
|
0x76:"ROR zp,X",
|
||||||
|
0x78:"SEI",
|
||||||
|
0x79:"ADC Abs,Y",
|
||||||
|
0x7D:"ADC Abs,X",
|
||||||
|
0x7E:"ROR Abs,X",
|
||||||
|
0x81:"STA (zp,X)",
|
||||||
|
0x84:"STY zp",
|
||||||
|
0x85:"STA zp",
|
||||||
|
0x86:"STX zp",
|
||||||
|
0x88:"DEY",
|
||||||
|
0x8A:"TXA",
|
||||||
|
0x8C:"STY Abs",
|
||||||
|
0x8D:"STA Abs",
|
||||||
|
0x8E:"STX Abs",
|
||||||
|
0x90:"BCC ",
|
||||||
|
0x91:"STA (zp),Y",
|
||||||
|
0x94:"STY zp,X",
|
||||||
|
0x95:"STA zp,X",
|
||||||
|
0x96:"STX zp,Y",
|
||||||
|
0x98:"TYA",
|
||||||
|
0x99:"STA Abs,Y",
|
||||||
|
0x9A:"TXS",
|
||||||
|
0x9D:"STA Abs,X",
|
||||||
|
0xA0:"LDY #",
|
||||||
|
0xA1:"LDA (zp,X)",
|
||||||
|
0xA2:"LDX #",
|
||||||
|
0xA4:"LDY zp",
|
||||||
|
0xA5:"LDA zp",
|
||||||
|
0xA6:"LDX zp",
|
||||||
|
0xA8:"TAY",
|
||||||
|
0xA9:"LDA #",
|
||||||
|
0xAA:"TAX",
|
||||||
|
0xAC:"LDY Abs",
|
||||||
|
0xAD:"LDA Abs",
|
||||||
|
0xAE:"LDX Abs",
|
||||||
|
0xB0:"BCS ",
|
||||||
|
0xB1:"LDA (zp),Y",
|
||||||
|
0xB4:"LDY zp,X",
|
||||||
|
0xB5:"LDA zp,X",
|
||||||
|
0xB6:"LDX zp,Y",
|
||||||
|
0xB8:"CLV",
|
||||||
|
0xB9:"LDA Abs,Y",
|
||||||
|
0xBA:"TSX",
|
||||||
|
0xBC:"LDY Abs,X",
|
||||||
|
0xBD:"LDA Abs,X",
|
||||||
|
0xBE:"LDX Abs,Y",
|
||||||
|
0xC0:"CPY #",
|
||||||
|
0xC1:"CMP (zp,X)",
|
||||||
|
0xC4:"CPY zp",
|
||||||
|
0xC5:"CMP zp",
|
||||||
|
0xC6:"DEC zp",
|
||||||
|
0xC8:"INY",
|
||||||
|
0xC9:"CMP #",
|
||||||
|
0xCA:"DEX",
|
||||||
|
0xCC:"CPY Abs",
|
||||||
|
0xCD:"CMP Abs",
|
||||||
|
0xCE:"DEC Abs",
|
||||||
|
0xD0:"BNE ",
|
||||||
|
0xD1:"CMP (zp),Y",
|
||||||
|
0xD5:"CMP zp,X",
|
||||||
|
0xD6:"DEC zp,X",
|
||||||
|
0xD8:"CLD",
|
||||||
|
0xD9:"CMP Abs,Y",
|
||||||
|
0xDD:"CMP Abs,X",
|
||||||
|
0xDE:"DEC Abs,X",
|
||||||
|
0xE0:"CPX #",
|
||||||
|
0xE1:"SBC (zp,X)",
|
||||||
|
0xE4:"CPX zp",
|
||||||
|
0xE5:"SBC zp",
|
||||||
|
0xE6:"INC zp",
|
||||||
|
0xE8:"INX",
|
||||||
|
0xE9:"SBC #",
|
||||||
|
0xEA:"NOP",
|
||||||
|
0xEC:"CPX Abs",
|
||||||
|
0xED:"SBC Abs",
|
||||||
|
0xEE:"INC Abs",
|
||||||
|
0xF0:"BEQ ",
|
||||||
|
0xF1:"SBC (zp),Y",
|
||||||
|
0xF5:"SBC zp,X",
|
||||||
|
0xF6:"INC zp,X",
|
||||||
|
0xF8:"SED",
|
||||||
|
0xF9:"SBC Abs,Y",
|
||||||
|
0xFD:"SBC Abs,X",
|
||||||
|
0xFE:"INC Abs,X",
|
||||||
|
};
|
||||||
|
327
nodenames.js
327
nodenames.js
@ -90,13 +90,13 @@ pcl4: 900,
|
|||||||
pcl5: 622,
|
pcl5: 622,
|
||||||
pcl6: 377,
|
pcl6: 377,
|
||||||
pcl7: 1611,
|
pcl7: 1611,
|
||||||
pclp0: 526, // machine state: program counter low (pre-incremented?, second storage node)
|
pclp0: 1227, // machine state: program counter low (pre-incremented?, second storage node)
|
||||||
pclp1: 1102,
|
pclp1: 1102,
|
||||||
pclp2: 1411,
|
pclp2: 1079,
|
||||||
pclp3: 868,
|
pclp3: 868,
|
||||||
pclp4: 15,
|
pclp4: 39,
|
||||||
pclp5: 1326,
|
pclp5: 1326,
|
||||||
pclp6: 993,
|
pclp6: 731,
|
||||||
pclp7: 536,
|
pclp7: 536,
|
||||||
pch0: 1670, // machine state: program counter high (first storage node)
|
pch0: 1670, // machine state: program counter high (first storage node)
|
||||||
pch1: 292,
|
pch1: 292,
|
||||||
@ -107,21 +107,33 @@ pch5: 49,
|
|||||||
pch6: 1551,
|
pch6: 1551,
|
||||||
pch7: 205,
|
pch7: 205,
|
||||||
pchp0: 780, // machine state: program counter high (pre-incremented?, second storage node)
|
pchp0: 780, // machine state: program counter high (pre-incremented?, second storage node)
|
||||||
pchp1: 126,
|
pchp1: 113,
|
||||||
pchp2: 114,
|
pchp2: 114,
|
||||||
pchp3: 1061,
|
pchp3: 124,
|
||||||
pchp4: 820,
|
pchp4: 820,
|
||||||
pchp5: 469,
|
pchp5: 33,
|
||||||
pchp6: 751,
|
pchp6: 751,
|
||||||
pchp7: 663,
|
pchp7: 535,
|
||||||
p0: 687, // machine state: status register
|
// machine state: status register (not the storage nodes)
|
||||||
p1: 1444,
|
p0: 32, // C bit of status register (storage node)
|
||||||
p2: 1421,
|
p1: 627, // Z bit of status register (storage node)
|
||||||
p3: 439,
|
p2: 1553, // I bit of status register (storage node)
|
||||||
p4: 1119, // there is no bit4 in the status register!
|
p3: 348, // D bit of status register (storage node)
|
||||||
p5: -1, // there is no bit5 in the status register!
|
p4: 1119, // there is no bit4 in the status register! (not a storage node)
|
||||||
p6: 77,
|
p5: -1, // there is no bit5 in the status register! (not a storage node)
|
||||||
p7: 1370,
|
p6: 77, // V bit of status register (storage node)
|
||||||
|
p7: 1370, // N bit of status register (storage node)
|
||||||
|
|
||||||
|
// internal bus: status register outputs for push P
|
||||||
|
Pout0: 687,
|
||||||
|
Pout1: 1444,
|
||||||
|
Pout2: 1421,
|
||||||
|
Pout3: 439,
|
||||||
|
Pout4: 1119, // there is no bit4 in the status register!
|
||||||
|
Pout5: -1, // there is no bit5 in the status register!
|
||||||
|
Pout6: 77,
|
||||||
|
Pout7: 1370,
|
||||||
|
|
||||||
s0: 1403, // machine state: stack pointer
|
s0: 1403, // machine state: stack pointer
|
||||||
s1: 183,
|
s1: 183,
|
||||||
s2: 81,
|
s2: 81,
|
||||||
@ -147,12 +159,28 @@ notir5: 1394,
|
|||||||
notir6: 895,
|
notir6: 895,
|
||||||
notir7: 1320,
|
notir7: 1320,
|
||||||
irline3: 996, // internal signal: PLA input - ir0 AND ir1
|
irline3: 996, // internal signal: PLA input - ir0 AND ir1
|
||||||
clock1: 1536, // internal state: timing control
|
clock1: 1536, // internal state: timing control aka #T0
|
||||||
clock2: 156, // internal state: timing control
|
clock2: 156, // internal state: timing control aka #T+
|
||||||
t2: 971, // internal state: timing control
|
t2: 971, // internal state: timing control
|
||||||
t3: 1567,
|
t3: 1567,
|
||||||
t4: 690,
|
t4: 690,
|
||||||
t5: 909,
|
t5: 909,
|
||||||
|
noty0: 1025, // datapath state: not Y register
|
||||||
|
noty1: 1138,
|
||||||
|
noty2: 1484,
|
||||||
|
noty3: 184,
|
||||||
|
noty4: 565,
|
||||||
|
noty5: 981,
|
||||||
|
noty6: 1439,
|
||||||
|
noty7: 1640,
|
||||||
|
notx0: 987, // datapath state: not X register
|
||||||
|
notx1: 1434,
|
||||||
|
notx2: 890,
|
||||||
|
notx3: 1521,
|
||||||
|
notx4: 485,
|
||||||
|
notx5: 1017,
|
||||||
|
notx6: 730,
|
||||||
|
notx7: 1561,
|
||||||
nots0: 418, // datapath state: not stack pointer
|
nots0: 418, // datapath state: not stack pointer
|
||||||
nots1: 1064,
|
nots1: 1064,
|
||||||
nots2: 752,
|
nots2: 752,
|
||||||
@ -185,7 +213,7 @@ sb4: 1405,
|
|||||||
sb5: 166,
|
sb5: 166,
|
||||||
sb6: 1336,
|
sb6: 1336,
|
||||||
sb7: 1001,
|
sb7: 1001,
|
||||||
notalu0: 394, // datapath state: alu output storage node (inverse)
|
notalu0: 394, // datapath state: alu output storage node (inverse) aka #ADD0
|
||||||
notalu1: 697,
|
notalu1: 697,
|
||||||
notalu2: 276,
|
notalu2: 276,
|
||||||
notalu3: 495,
|
notalu3: 495,
|
||||||
@ -193,7 +221,7 @@ notalu4: 1490,
|
|||||||
notalu5: 893,
|
notalu5: 893,
|
||||||
notalu6: 68,
|
notalu6: 68,
|
||||||
notalu7: 1123,
|
notalu7: 1123,
|
||||||
alu0: 401, // datapath signal: ALU output
|
alu0: 401, // datapath signal: ALU output aka ADD0out
|
||||||
alu1: 872,
|
alu1: 872,
|
||||||
alu2: 1637,
|
alu2: 1637,
|
||||||
alu3: 1414,
|
alu3: 1414,
|
||||||
@ -210,7 +238,7 @@ dasb4: 1405, // same node as sb4
|
|||||||
dasb5: 263,
|
dasb5: 263,
|
||||||
dasb6: 679,
|
dasb6: 679,
|
||||||
dasb7: 1494,
|
dasb7: 1494,
|
||||||
adl0: 413, // internal state: address latch low
|
adl0: 413, // internal bus: address low
|
||||||
adl1: 1282,
|
adl1: 1282,
|
||||||
adl2: 1242,
|
adl2: 1242,
|
||||||
adl3: 684,
|
adl3: 684,
|
||||||
@ -218,7 +246,7 @@ adl4: 1437,
|
|||||||
adl5: 1630,
|
adl5: 1630,
|
||||||
adl6: 121,
|
adl6: 121,
|
||||||
adl7: 1299,
|
adl7: 1299,
|
||||||
adh0: 407, // internal state: address latch high
|
adh0: 407, // internal bus: address high
|
||||||
adh1: 52,
|
adh1: 52,
|
||||||
adh2: 1651,
|
adh2: 1651,
|
||||||
adh3: 315,
|
adh3: 315,
|
||||||
@ -226,7 +254,7 @@ adh4: 1160,
|
|||||||
adh5: 483,
|
adh5: 483,
|
||||||
adh6: 13,
|
adh6: 13,
|
||||||
adh7: 1539,
|
adh7: 1539,
|
||||||
idb0: 1108, // internal state: data buffer
|
idb0: 1108, // internal bus: data bus
|
||||||
idb1: 991,
|
idb1: 991,
|
||||||
idb2: 1473,
|
idb2: 1473,
|
||||||
idb3: 1302,
|
idb3: 1302,
|
||||||
@ -250,33 +278,79 @@ dor4: 1088,
|
|||||||
dor5: 1453,
|
dor5: 1453,
|
||||||
dor6: 1415,
|
dor6: 1415,
|
||||||
dor7: 63,
|
dor7: 63,
|
||||||
pd0: 1622, // internal state: predecode register output (anded with not ClearIR)
|
"pd0.clearIR": 1622, // internal state: predecode register output (anded with not ClearIR)
|
||||||
pd1: 809,
|
"pd1.clearIR": 809,
|
||||||
pd2: 1671,
|
"pd2.clearIR": 1671,
|
||||||
pd3: 1587,
|
"pd3.clearIR": 1587,
|
||||||
pd4: 540,
|
"pd4.clearIR": 540,
|
||||||
pd5: 667,
|
"pd5.clearIR": 667,
|
||||||
pd6: 1460,
|
"pd6.clearIR": 1460,
|
||||||
pd7: 1410,
|
"pd7.clearIR": 1410,
|
||||||
notpd0: 758, // internal state: predecode register (storage node)
|
pd0: 758, // internal state: predecode register (storage node)
|
||||||
notpd1: 361,
|
pd1: 361,
|
||||||
notpd2: 955,
|
pd2: 955,
|
||||||
notpd3: 894,
|
pd3: 894,
|
||||||
notpd4: 369,
|
pd4: 369,
|
||||||
notpd5: 829,
|
pd5: 829,
|
||||||
notpd6: 1669,
|
pd6: 1669,
|
||||||
notpd7: 1690,
|
pd7: 1690,
|
||||||
|
// internal signals: predecode latch partial decodes
|
||||||
|
"PD-xxxx10x0": 1019,
|
||||||
|
"PD-1xx000x0": 1294,
|
||||||
|
"PD-0xx0xx0x": 365,
|
||||||
|
"PD-xxx010x1": 302,
|
||||||
|
"PD-n-0xx0xx0x": 125,
|
||||||
|
"#TWOCYCLE": 851,
|
||||||
|
"#TWOCYCLE.phi1": 792,
|
||||||
|
"ONEBYTE": 778,
|
||||||
|
|
||||||
|
abl0: 1096, // internal bus: address bus low latched data out (inverse of inverted storage node)
|
||||||
|
abl1: 376,
|
||||||
|
abl2: 1502,
|
||||||
|
abl3: 1250,
|
||||||
|
abl4: 1232,
|
||||||
|
abl5: 234,
|
||||||
|
abl6: 178,
|
||||||
|
abl7: 178,
|
||||||
|
"#ABL0": 153, // internal state: address bus low latched data out (storage node, inverted)
|
||||||
|
"#ABL1": 107,
|
||||||
|
"#ABL2": 707,
|
||||||
|
"#ABL3": 825,
|
||||||
|
"#ABL4": 364,
|
||||||
|
"#ABL5": 1513,
|
||||||
|
"#ABL6": 1307,
|
||||||
|
"#ABL7": 28,
|
||||||
|
abh0: 1429, // internal bus: address bus high latched data out (inverse of inverted storage node)
|
||||||
|
abh1: 713,
|
||||||
|
abh2: 287,
|
||||||
|
abh3: 422,
|
||||||
|
abh4: 1143,
|
||||||
|
abh5: 775,
|
||||||
|
abh6: 997,
|
||||||
|
abh7: 489,
|
||||||
|
"#ABH0": 1062, // internal state: address bus high latched data out (storage node, inverted)
|
||||||
|
"#ABH1": 907,
|
||||||
|
"#ABH2": 768,
|
||||||
|
"#ABH3": 92,
|
||||||
|
"#ABH4": 668,
|
||||||
|
"#ABH5": 1128,
|
||||||
|
"#ABH6": 289,
|
||||||
|
"#ABH7": 429,
|
||||||
|
|
||||||
notRdy0: 248, // internal signal: global pipeline control
|
notRdy0: 248, // internal signal: global pipeline control
|
||||||
Reset0: 67, // internal signal: retimed reset from pin
|
Reset0: 67, // internal signal: retimed reset from pin
|
||||||
C1x5Reset: 926, // retimed and pipelined reset in progress
|
C1x5Reset: 926, // retimed and pipelined reset in progress
|
||||||
notRnWprepad: 187, // internal signal: to pad, yet to be inverted and retimed
|
notRnWprepad: 187, // internal signal: to pad, yet to be inverted and retimed
|
||||||
RnWstretched: 353, // internal signal: control datapad output drivers
|
RnWstretched: 353, // internal signal: control datapad output drivers, aka TRISTATE
|
||||||
|
"#DBE": 1035, // internal signal: formerly from DBE pad (6501)
|
||||||
cp1: 710, // internal signal: clock phase 1
|
cp1: 710, // internal signal: clock phase 1
|
||||||
cclk: 943, // unbonded pad: internal non-overlappying phi2
|
cclk: 943, // unbonded pad: internal non-overlappying phi2
|
||||||
fetch: 879, // internal signal
|
fetch: 879, // internal signal
|
||||||
clearIR: 1077, // internal signal
|
clearIR: 1077, // internal signal
|
||||||
D1x1: 827, // internal signal: interrupt handler related
|
D1x1: 827, // internal signal: interrupt handler related
|
||||||
H1x1: 1042, // internal signal: drive status byte onto databus
|
H1x1: 1042, // internal signal: drive status byte onto databus
|
||||||
|
"brk-done": 1382, // internal signal: interrupt handler related
|
||||||
|
INTG: 1350, // internal signal: interrupt handler related
|
||||||
|
|
||||||
// internal signal: pla outputs block 1 (west/left edge of die)
|
// internal signal: pla outputs block 1 (west/left edge of die)
|
||||||
// often 130 pla outputs are mentioned - we have 131 here
|
// often 130 pla outputs are mentioned - we have 131 here
|
||||||
@ -434,11 +508,36 @@ H1x1: 1042, // internal signal: drive status byte onto databus
|
|||||||
"op-clv":1164, // pla129
|
"op-clv":1164, // pla129
|
||||||
"op-implied":1006, // pla130 // has extra pulldowns: pla121 and ir0
|
"op-implied":1006, // pla130 // has extra pulldowns: pla121 and ir0
|
||||||
|
|
||||||
|
// internal signals: derived from pla outputs
|
||||||
|
"#op-branch-done": 1048,
|
||||||
|
"op-ANDS": 1228,
|
||||||
|
"op-EORS": 1689,
|
||||||
|
"op-ORS": 522,
|
||||||
|
"op-SUMS": 1196,
|
||||||
|
"op-SRS": 934,
|
||||||
|
"#op-store": 925,
|
||||||
|
"#WR": 1352,
|
||||||
|
"op-rmw": 434,
|
||||||
|
"short-circuit-idx-add": 1185,
|
||||||
|
"#op-set-C": 252,
|
||||||
|
|
||||||
// internal signals: control signals
|
// internal signals: control signals
|
||||||
nnT2BR: 967, // doubly inverted
|
nnT2BR: 967, // doubly inverted
|
||||||
BRtaken: 1544,
|
BRtaken: 1544, // aka #TAKEN
|
||||||
|
|
||||||
|
// interrupt and vector related
|
||||||
|
NMIP: 1032,
|
||||||
|
VEC0: 1465,
|
||||||
|
VEC1: 1481,
|
||||||
|
"#VEC": 1134,
|
||||||
|
|
||||||
// internal state: misc pipeline state clocked by cclk (phi2)
|
// internal state: misc pipeline state clocked by cclk (phi2)
|
||||||
|
"pipe#VEC": 1431, // latched #VEC
|
||||||
|
"pipeT-SYNC": 537,
|
||||||
|
pipeT2out: 40,
|
||||||
|
pipeT3out: 706,
|
||||||
|
pipeT4out: 1373,
|
||||||
|
pipeT5out: 940,
|
||||||
pipeBRtaken: 832,
|
pipeBRtaken: 832,
|
||||||
pipeUNK01: 1530,
|
pipeUNK01: 1530,
|
||||||
pipeUNK02: 974,
|
pipeUNK02: 974,
|
||||||
@ -477,20 +576,23 @@ pipeUNK34: 56,
|
|||||||
pipeUNK35: 1713,
|
pipeUNK35: 1713,
|
||||||
pipeUNK36: 729,
|
pipeUNK36: 729,
|
||||||
pipeUNK37: 197,
|
pipeUNK37: 197,
|
||||||
pipeUNK38: 1131,
|
"pipe#WR.phi2": 1131,
|
||||||
pipeUNK39: 151,
|
pipeUNK39: 151,
|
||||||
pipeUNK40: 456,
|
pipeUNK40: 456,
|
||||||
pipeUNK41: 1438,
|
pipeUNK41: 1438,
|
||||||
pipeUNK42: 1104,
|
pipeUNK42: 1104,
|
||||||
pipeUNK43: 554,
|
"pipe#T0": 554, // aka #T0.phi2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// internal state: vector address pulldown control
|
// internal state: vector address pulldown control
|
||||||
pipeVectorA0: 357,
|
pipeVectorA0: 357,
|
||||||
pipeVectorA1: 170,
|
pipeVectorA1: 170,
|
||||||
pipeVectorA2: 45,
|
pipeVectorA2: 45,
|
||||||
|
|
||||||
|
// internal signals: vector address pulldown control
|
||||||
|
"0/ADL0": 217,
|
||||||
|
"0/ADL1": 686,
|
||||||
|
"0/ADL2": 1193,
|
||||||
|
|
||||||
// internal state: datapath control drivers
|
// internal state: datapath control drivers
|
||||||
pipedpc28: 683,
|
pipedpc28: 683,
|
||||||
|
|
||||||
@ -512,17 +614,105 @@ alub5: 1678,
|
|||||||
alub6: 235,
|
alub6: 235,
|
||||||
alub7: 1535,
|
alub7: 1535,
|
||||||
|
|
||||||
aluanorb0: 143,
|
// alu carry chain and decimal mode
|
||||||
aluanandb0: 1628,
|
C01: 1285,
|
||||||
aluaorb0: 693,
|
C12: 505,
|
||||||
notaluoutmux0: 957, // alu result latch input
|
C23: 1023,
|
||||||
|
C34: 78,
|
||||||
|
C45: 142,
|
||||||
|
C56: 500,
|
||||||
|
C67: 1314,
|
||||||
|
C78: 808,
|
||||||
|
"C78.phi2": 560,
|
||||||
|
DC34: 1372, // lower nibble decimal carry
|
||||||
|
DC78: 333, // carry for decimal mode
|
||||||
|
"DC78.phi2": 164,
|
||||||
|
"#C01": 1506,
|
||||||
|
"#C12": 1122,
|
||||||
|
"#C23": 1003,
|
||||||
|
"#C34": 1425,
|
||||||
|
"#C45": 1571,
|
||||||
|
"#C56": 427,
|
||||||
|
"#C67": 592,
|
||||||
|
"#C78": 1327,
|
||||||
|
"DA-C01": 623,
|
||||||
|
"DA-AB2": 216,
|
||||||
|
"DA-AxB2": 516,
|
||||||
|
"DA-C45": 1144,
|
||||||
|
"#DA-ADD1": 901,
|
||||||
|
"#DA-ADD2": 699,
|
||||||
|
|
||||||
aluanorb1: 155,
|
// misc alu internals
|
||||||
aluanandb1: 841,
|
"#(AxBxC)0": 371,
|
||||||
aluaorb1: 1021,
|
"#(AxBxC)1": 965,
|
||||||
notaluoutmux1: 250, // alu result latch input
|
"#(AxBxC)2": 22,
|
||||||
|
"#(AxBxC)3": 274,
|
||||||
|
"#(AxBxC)4": 651,
|
||||||
|
"#(AxBxC)5": 486,
|
||||||
|
"#(AxBxC)6": 1197,
|
||||||
|
"#(AxBxC)7": 532,
|
||||||
|
AxB1: 425,
|
||||||
|
AxB3: 640,
|
||||||
|
AxB5: 1220,
|
||||||
|
AxB7: 1241,
|
||||||
|
"#(AxB)0": 1525,
|
||||||
|
"#(AxB)2": 701,
|
||||||
|
"#(AxB)4": 308,
|
||||||
|
"#(AxB)6": 1459,
|
||||||
|
"(AxB)0.#C0in": 555,
|
||||||
|
"(AxB)2.#C12": 193,
|
||||||
|
"(AxB)4.#C34": 65,
|
||||||
|
"(AxB)6.#C56": 174,
|
||||||
|
"#(AxB1).C01": 295,
|
||||||
|
"#(AxB3).C23": 860,
|
||||||
|
"#(AxB5).C45": 817,
|
||||||
|
"#(AxB7).C67": 1217,
|
||||||
|
"#A.B0": 1628,
|
||||||
|
"#A.B1": 841,
|
||||||
|
"#A.B2": 681,
|
||||||
|
"#A.B3": 350,
|
||||||
|
"#A.B4": 1063,
|
||||||
|
"#A.B5": 477,
|
||||||
|
"#A.B6": 336,
|
||||||
|
"#A.B7": 1318,
|
||||||
|
"A+B0": 693,
|
||||||
|
"A+B1": 1021,
|
||||||
|
"A+B2": 110,
|
||||||
|
"A+B3": 1313,
|
||||||
|
"A+B4": 918,
|
||||||
|
"A+B5": 1236,
|
||||||
|
"A+B6": 803,
|
||||||
|
"A+B7": 117,
|
||||||
|
"#(A+B)0": 143,
|
||||||
|
"#(A+B)1": 155,
|
||||||
|
"#(A+B)2": 1691,
|
||||||
|
"#(A+B)3": 649,
|
||||||
|
"#(A+B)4": 404,
|
||||||
|
"#(A+B)5": 1632,
|
||||||
|
"#(A+B)6": 1084,
|
||||||
|
"#(A+B)7": 1398,
|
||||||
|
"#(AxB)0": 1525,
|
||||||
|
"#(AxB)2": 701,
|
||||||
|
"#(AxB)4": 308,
|
||||||
|
"#(AxB)6": 1459,
|
||||||
|
"#(AxB)1": 953,
|
||||||
|
"#(AxB)3": 884,
|
||||||
|
"#(AxB)5": 1469,
|
||||||
|
"#(AxB)7": 177,
|
||||||
|
"#aluresult0": 957, // alu result latch input
|
||||||
|
"#aluresult1": 250,
|
||||||
|
"#aluresult2": 740,
|
||||||
|
"#aluresult3": 1071,
|
||||||
|
"#aluresult4": 296,
|
||||||
|
"#aluresult5": 277,
|
||||||
|
"#aluresult6": 722,
|
||||||
|
"#aluresult7": 304,
|
||||||
|
|
||||||
// internal signals: datapath control signals
|
// internal signals: datapath control signals
|
||||||
|
|
||||||
|
"ADL/ABL": 639, // load ABL latches from ADL bus
|
||||||
|
"ADH/ABH": 821, // load ABH latches from ADH bus
|
||||||
|
|
||||||
dpc0_YSB: 801, // drive sb from y
|
dpc0_YSB: 801, // drive sb from y
|
||||||
dpc1_SBY: 325, // load y from sb
|
dpc1_SBY: 325, // load y from sb
|
||||||
dpc2_XSB: 1263, // drive sb from x
|
dpc2_XSB: 1263, // drive sb from x
|
||||||
@ -544,21 +734,27 @@ dpc16_EORS: 1666, // alu op: a xor b (?)
|
|||||||
dpc17_SUMS: 921, // alu op: a plus b (?)
|
dpc17_SUMS: 921, // alu op: a plus b (?)
|
||||||
alucin: 910, // alu carry in
|
alucin: 910, // alu carry in
|
||||||
notalucin: 1165,
|
notalucin: 1165,
|
||||||
dpc18_DAA: 1201, // decimal related
|
"dpc18_#DAA": 1201, // decimal related (inverted)
|
||||||
dpc19_ADDSB7: 214, // alu to sb bit 7 only
|
dpc19_ADDSB7: 214, // alu to sb bit 7 only
|
||||||
|
|
||||||
dpc20_ADDSB06: 129, // alu to sb bits 6-0 only
|
dpc20_ADDSB06: 129, // alu to sb bits 6-0 only
|
||||||
dpc21_ADDADL: 1015, // alu to adl
|
dpc21_ADDADL: 1015, // alu to adl
|
||||||
alurawcout: 808, // alu raw carry out (no decimal adjust)
|
alurawcout: 808, // alu raw carry out (no decimal adjust)
|
||||||
|
notalucout: 412, // alu carry out (inverted)
|
||||||
alucout: 1146, // alu carry out (latched by phi2)
|
alucout: 1146, // alu carry out (latched by phi2)
|
||||||
notaluvout: 1308, // alu overflow out
|
notaluvout: 1308, // alu overflow out
|
||||||
aluvout: 938, // alu overflow out (latched by phi2)
|
aluvout: 938, // alu overflow out (latched by phi2)
|
||||||
dpc22_DSA: 725, // decimal related/SBC only
|
|
||||||
|
"#DBZ": 1268, // internal signal: not (databus is zero)
|
||||||
|
DBZ: 744, // internal signal: databus is zero
|
||||||
|
DBNeg: 1200, // internal signal: databus is negative (top bit of db) aka P-#DB7in
|
||||||
|
|
||||||
|
"dpc22_#DSA": 725, // decimal related/SBC only (inverted)
|
||||||
dpc23_SBAC: 534, // (optionalls decimal-adjusted) sb to acc
|
dpc23_SBAC: 534, // (optionalls decimal-adjusted) sb to acc
|
||||||
dpc24_ACSB: 1698, // acc to sb
|
dpc24_ACSB: 1698, // acc to sb
|
||||||
dpc25_SBDB: 1060, // sb pass-connects to idb
|
dpc25_SBDB: 1060, // sb pass-connects to idb (bi-directionally)
|
||||||
dpc26_ACDB: 1331, // acc to idb
|
dpc26_ACDB: 1331, // acc to idb
|
||||||
dpc27_SBADH: 140, // sb pass-connects to adh
|
dpc27_SBADH: 140, // sb pass-connects to adh (bi-directionally)
|
||||||
dpc28_0ADH0: 229, // zero to adh0 bit0 only
|
dpc28_0ADH0: 229, // zero to adh0 bit0 only
|
||||||
dpc29_0ADH17: 203, // zero to adh bits 7-1 only
|
dpc29_0ADH17: 203, // zero to adh bits 7-1 only
|
||||||
|
|
||||||
@ -567,14 +763,23 @@ dpc31_PCHPCH: 741, // load pch from pch incremented
|
|||||||
dpc32_PCHADH: 1235, // drive adh from pch incremented
|
dpc32_PCHADH: 1235, // drive adh from pch incremented
|
||||||
dpc33_PCHDB: 247, // drive idb from pch incremented
|
dpc33_PCHDB: 247, // drive idb from pch incremented
|
||||||
dpc34_PCLC: 1704, // pch carry in and pcl FF detect?
|
dpc34_PCLC: 1704, // pch carry in and pcl FF detect?
|
||||||
dpc35: 1334, // pcl 0x?F detect - half-carry
|
dpc35_PCHC: 1334, // pcl 0x?F detect - half-carry
|
||||||
dpc36_IPC: 379, // pcl carry in
|
dpc36_IPC: 379, // pcl carry in
|
||||||
dpc37_PCLDB: 283, // drive idb from pcl incremented
|
dpc37_PCLDB: 283, // drive idb from pcl incremented
|
||||||
dpc38_PCLADL: 438, // drive adl from pcl incremented
|
dpc38_PCLADL: 438, // drive adl from pcl incremented
|
||||||
dpc39_PCLPCL: 898, // load pcl from pcl incremented
|
dpc39_PCLPCL: 898, // load pcl from pcl incremented
|
||||||
|
|
||||||
dpc40_ADLPCL: 414, // load pcl from adl
|
dpc40_ADLPCL: 414, // load pcl from adl
|
||||||
dpc41: 1564, // pass-connect adl to mux node driven by idl
|
"dpc41_DL/ADL": 1564,// pass-connect adl to mux node driven by idl
|
||||||
dpc42: 41, // pass-connect adh to mux node driven by idl
|
"dpc42_DL/ADH": 41, // pass-connect adh to mux node driven by idl
|
||||||
dpc43: 863, // pass-connect idb to mux node driven by idl
|
"dpc43_DL/DB": 863, // pass-connect idb to mux node driven by idl
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* many bus names taken from Donald F. Hanson's block diagram, found
|
||||||
|
* http://www.weihenstephan.org/~michaste/pagetable/6502/6502.jpg
|
||||||
|
* from his paper "A VHDL conversion tool for logic equations with embedded D latches"
|
||||||
|
* http://portal.acm.org/citation.cfm?id=1275143.1275151
|
||||||
|
* also available at
|
||||||
|
* http://www.ncsu.edu/wcae/WCAE1/hanson.pdf
|
||||||
|
*/
|
||||||
|
@ -8,8 +8,29 @@
|
|||||||
//
|
//
|
||||||
testprogramAddress=0x0000;
|
testprogramAddress=0x0000;
|
||||||
|
|
||||||
|
// we want to auto-clear the console if any output is sent by the program
|
||||||
|
var consoleboxStream="";
|
||||||
|
|
||||||
|
// demonstrate write hook
|
||||||
|
writeTriggers[0x000F]="consoleboxStream += String.fromCharCode(d);"+
|
||||||
|
"consolebox.innerHTML = consoleboxStream;";
|
||||||
|
|
||||||
|
// demonstrate read hook (not used by this test program)
|
||||||
|
readTriggers[0xD011]="((consolegetc==undefined)?0:0xff)"; // return zero until we have a char
|
||||||
|
readTriggers[0xD010]="var c=consolegetc; consolegetc=undefined; (c)";
|
||||||
|
|
||||||
testprogram = [
|
testprogram = [
|
||||||
0xa9, 0x00, 0x20, 0x10, 0x00, 0x4c, 0x02, 0x00,
|
0xa9, 0x00, // LDA #$00
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x20, 0x10, 0x00, // JSR $0010
|
||||||
0xe8, 0x88, 0xe6, 0x40, 0x38, 0x69, 0x02, 0x60
|
0x4c, 0x02, 0x00, // JMP $0002
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x40,
|
||||||
|
|
||||||
|
0xe8, // INX
|
||||||
|
0x88, // DEY
|
||||||
|
0xe6, 0x0F, // INC $0F
|
||||||
|
0x38, // SEC
|
||||||
|
0x69, 0x02, // ADC #$02
|
||||||
|
0x60 // RTS
|
||||||
];
|
];
|
||||||
|
7031
transdefs.js
7031
transdefs.js
File diff suppressed because it is too large
Load Diff
52
wires.js
52
wires.js
@ -50,9 +50,10 @@ function setupTransistors(){
|
|||||||
var gate = tdef[1];
|
var gate = tdef[1];
|
||||||
var c1 = tdef[2];
|
var c1 = tdef[2];
|
||||||
var c2 = tdef[3];
|
var c2 = tdef[3];
|
||||||
|
var bb = tdef[4];
|
||||||
if(c1==ngnd) {c1=c2;c2=ngnd;}
|
if(c1==ngnd) {c1=c2;c2=ngnd;}
|
||||||
if(c1==npwr) {c1=c2;c2=npwr;}
|
if(c1==npwr) {c1=c2;c2=npwr;}
|
||||||
var trans = {name: name, on: false, gate: gate, c1: c1, c2: c2};
|
var trans = {name: name, on: false, gate: gate, c1: c1, c2: c2, bb: bb};
|
||||||
nodes[gate].gates.push(trans);
|
nodes[gate].gates.push(trans);
|
||||||
nodes[c1].c1c2s.push(trans);
|
nodes[c1].c1c2s.push(trans);
|
||||||
nodes[c2].c1c2s.push(trans);
|
nodes[c2].c1c2s.push(trans);
|
||||||
@ -149,20 +150,63 @@ function overlayNode(w){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// originally to highlight using a list of node numbers
|
||||||
|
// but can now include transistor names
|
||||||
function hiliteNode(n){
|
function hiliteNode(n){
|
||||||
var ctx = hilite.getContext('2d');
|
var ctx = hilite.getContext('2d');
|
||||||
ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
|
ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
|
||||||
ctx.fillStyle = 'rgba(255,255,255,0.7)';
|
|
||||||
if(n==-1) return;
|
if(n==-1) return;
|
||||||
if(isNodeHigh(n[0]))
|
|
||||||
ctx.fillStyle = 'rgba(255,0,0,0.7)';
|
|
||||||
|
|
||||||
for(var i in n){
|
for(var i in n){
|
||||||
|
if(typeof n[i] != "number") {
|
||||||
|
hiliteTrans([n[i]]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(isNodeHigh(n[i])) {
|
||||||
|
ctx.fillStyle = 'rgba(255,0,0,0.7)';
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = 'rgba(255,255,255,0.7)';
|
||||||
|
}
|
||||||
var segs = nodes[n[i]].segs;
|
var segs = nodes[n[i]].segs;
|
||||||
for(var s in segs){drawSeg(ctx, segs[s]); ctx.fill();}
|
for(var s in segs){drawSeg(ctx, segs[s]); ctx.fill();}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// highlight a single transistor (additively - does not clear highlighting)
|
||||||
|
function hiliteTrans(n){
|
||||||
|
var ctx = hilite.getContext('2d');
|
||||||
|
ctx.strokeStyle = 'rgba(255,255,255,0.7)';
|
||||||
|
ctx.lineWidth = 4
|
||||||
|
for(var t in n){
|
||||||
|
var bb = transistors[n[t]].bb
|
||||||
|
var segs = [[bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3]]]
|
||||||
|
for(var s in segs){drawSeg(ctx, segs[s]); ctx.stroke();}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ctxDrawBox(ctx, xMin, yMin, xMax, yMax){
|
||||||
|
var cap=ctx.lineCap;
|
||||||
|
ctx.lineCap="square";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(xMin, yMin);
|
||||||
|
ctx.lineTo(xMin, yMax);
|
||||||
|
ctx.lineTo(xMax, yMax);
|
||||||
|
ctx.lineTo(xMax, yMin);
|
||||||
|
ctx.lineTo(xMin, yMin);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineCap=cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// takes a bounding box in chip coords and centres the display over it
|
||||||
|
function zoomToBox(xmin,xmax,ymin,ymax){
|
||||||
|
var xmid=(xmin+xmax)/2;
|
||||||
|
var ymid=(ymin+ymax)/2;
|
||||||
|
var x=(xmid+400)/grChipSize*600;
|
||||||
|
var y=600-ymid/grChipSize*600;
|
||||||
|
var zoom=5; // pending a more careful calculation
|
||||||
|
moveHere([x,y,zoom]);
|
||||||
|
}
|
||||||
|
|
||||||
function drawSeg(ctx, seg){
|
function drawSeg(ctx, seg){
|
||||||
var dx = 400;
|
var dx = 400;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
Reference in New Issue
Block a user