19 Commits
V0.0 ... V0.1

Author SHA1 Message Date
Barry Silverman
18fbd2eb36 Merge branch 'ed' 2010-09-18 14:14:05 -04:00
BigEd
bc901566e3 all layers start off visible 2010-09-18 18:06:42 +00:00
Barry Silverman
6276d019d7 Fixed localx/localy calculation 2010-09-18 14:04:52 -04:00
BigEd
69ab63e406 fixup space above memtable 2010-09-18 17:56:34 +00:00
BigEd
d032580201 improve load sequencing, add layer choosing, link to python sim, add keyboard tips, add example nmi test, tweak navbuttons, enhance chipstatus output 2010-09-18 17:46:24 +00:00
BigEd
0ecb753ec6 fixup nav button positioning 2010-09-18 17:29:45 +00:00
BigEd
e2e88cfae1 more internal busses and latches named 2010-09-18 17:25:33 +00:00
BigEd
1fd86334f7 fixup line ends on one remaining file (by touching every line...) 2010-09-18 17:12:28 +00:00
BigEd
bf2108b9d6 ignore patch detritus 2010-09-18 17:07:48 +00:00
BigEd
2d2d0ef9b6 Merge branch 'master' of git://github.com/trebonian/visual6502
Conflicts:

	segdefs.js
2010-09-18 17:06:09 +00:00
BigEd
3398a6f181 add copyright 2010-09-18 17:01:20 +00:00
Barry Silverman
b6d4ffda6a More copyrights 2010-09-18 13:00:23 -04:00
Barry Silverman
6dd7e9c24e Fixed line endings and Copyright notices 2010-09-18 12:56:48 -04:00
BigEd
51b4d8d7a0 Introduce end-of-line normalization 2010-09-18 16:38:22 +00:00
BigEd
e01093def5 ignore emacs backup files 2010-09-18 16:20:56 +00:00
BigEd
27f085b743 Merge branch 'master' of git://github.com/trebonian/visual6502 2010-09-18 16:17:54 +00:00
Barry Silverman
d3223a9478 Fixed README from Ed 2010-09-18 12:13:48 -04:00
BigEd
f8931fce49 initial README content 2010-09-18 15:59:17 +00:00
Barry Silverman
b9cbe765b2 Fix slow reset loop 2010-09-18 11:42:30 -04:00
13 changed files with 13121 additions and 12822 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
* text=auto
*.js text
*.css text
*.html text

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# emacs-style backup files
*~
# patch detritus
*.orig
*.rej

8
README
View File

@@ -0,0 +1,8 @@
This is the javascript simulator from the visual5602.org project.
It includes a general purpose switch-level simulator, layout browser,
and data from a 6502D chip.
Please note the various licenses of the different files.
Enjoy!

View File

@@ -21,6 +21,8 @@
*/
var ctrace = false;
var noGraphics = false;
var loglevel = 3;
var ridx = 0;
function recalcNodeList(list){

View File

@@ -12,8 +12,21 @@
<script src="macros.js"></script>
</head>
<body onload="setup();">
<p class="title">The 6502</p>
<body onload="setTimeout(setup,200)">
<br />
<span id="title"><a href="/">The Visual 6502</a></span><br /><br />
<span id="plain">
If the chip does not load, try another browser: Chrome, Safari, or Firefox
<br />
<br />
Hit '>' to zoom in, '<' to zoom out
<br />
Right-click to scroll around
<br />
Enter your own program into the array of RAM
<br />
<br />
</span>
<div class="frame" id="frame">
<div class="chip">
<canvas class="chip" id="chipbg"></canvas>
@@ -22,15 +35,30 @@
<canvas class="chip" id="hitbuffer"></canvas>
</div>
<div class = "buttons">
<a href ="javascript:stopChip()"id="stop"><img class="navstop" src="images/stop.png"></a>
<a href ="javascript:runChip()" id="start"><img class="navplay" src="images/play.png"></a>
<a href ="javascript:resetChip()"><img class="navbutton" src="images/up.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>
<div style="position:relative; float:left;">
<a href ="javascript:stopChip()"id="stop"><img class="navstop" src="images/stop.png"></a>
<a href ="javascript:runChip()" id="start"><img class="navplay" src="images/play.png"></a>
</div>
<div style="float:left;">
<a href ="javascript:resetChip()"><img class="navbutton" src="images/up.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>
</div>
</div>
<p class="status" id="status">x: 0<br>y: 0</p>
<table class="memtable" id="memtable"></table>
</div>
<div id="updateShow"> Show:
<input type="checkbox" name="0" id="updateShow0" onchange="updateShow(this.name,this.checked)" />(metal)
<input type="checkbox" name="1" id="updateShow1" onchange="updateShow(this.name,this.checked)" />(diff)
<input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(diode)
<input type="checkbox" name="3" id="updateShow3" onchange="updateShow(this.name,this.checked)" />(diff0)
<input type="checkbox" name="4" id="updateShow4" onchange="updateShow(this.name,this.checked)" />(diff1)
<input type="checkbox" name="5" id="updateShow5" onchange="updateShow(this.name,this.checked)" />(poly)
</div>
<br />
<br />
In addition to this JavaScript project, see our <a href="../python6502.html">Python-based simulator</a> which may be easier to customize, verify, and apply to the study of long programs.<br />
<br />
</body>
</html>

124
macros.js
View File

@@ -39,11 +39,55 @@ function go(n){
}
function steps(){
if(running) step();
setTimeout(steps, 200);
if(running) {
step();
setTimeout(steps, 0); // schedule the next poll
}
}
function testNMI(n){
initChip();
mWrite(0x0000, 0x38); // set carry
mWrite(0x0001, 0x4c); // jump to test code
mWrite(0x0002, 0x06);
mWrite(0x0003, 0x23);
mWrite(0x22ff, 0x38); // set carry
mWrite(0x2300, 0xea);
mWrite(0x2301, 0xea);
mWrite(0x2302, 0xea);
mWrite(0x2303, 0xea);
mWrite(0x2304, 0xb0); // branch carry set to self
mWrite(0x2305, 0xfe);
mWrite(0x2306, 0xb0); // branch carry set to self
mWrite(0x2307, 0x01);
mWrite(0x2308, 0x00); // brk should be skipped
mWrite(0x2309, 0xa9); // anything
mWrite(0x230a, 0xde); // anything
mWrite(0x230b, 0xb0); // branch back with page crossing
mWrite(0x230c, 0xf2);
mWrite(0xc018, 0x40); // nmi handler
mWrite(0xfffa, 0x18); // nmi vector
mWrite(0xfffb, 0xc0);
mWrite(0xfffc, 0x00); // reset vector
mWrite(0xfffd, 0x00);
for(var i=0;i<n;i++){step();}
setLow('nmi');
chipStatus();
for(var i=0;i<8;i++){step();}
setHigh('nmi');
chipStatus();
for(var i=0;i<16;i++){step();}
}
function initChip(){
var start = now();
for(var nn in nodes) nodes[nn].state = 'fl';
nodes[ngnd].state = 'gnd';
nodes[npwr].state = 'vcc';
@@ -55,11 +99,12 @@ function initChip(){
recalcNodeList(allNodes());
for(var i=0;i<8;i++){setHigh('clk0'), setLow('clk0');}
setHigh('res');
for(var i=0;i<14;i++){step();}
for(var i=0;i<18;i++){resetStep();}
refresh();
cycle = 0;
trace = Array();
chipStatus();
console.log('initChip done after', now()-start);
}
function step(){
@@ -76,6 +121,12 @@ function halfStep(){
refresh();
}
function resetStep(){
var clk = isNodeHigh(nodenames['clk0']);
if (clk) {setLow('clk0'); handleBusRead(); }
else {setHigh('clk0'); handleBusWrite();}
}
function handleBusRead(){
if(isNodeHigh(nodenames['rw'])) writeDataBus(mRead(readAddressBus()));
}
@@ -95,8 +146,26 @@ function readA(){return readBits('a', 8);}
function readY(){return readBits('y', 8);}
function readX(){return readBits('x', 8);}
function readP(){return readBits('p', 8);}
function readPstring(){
var result;
result = (isNodeHigh(nodenames['p7'])?'N':'n') +
(isNodeHigh(nodenames['p6'])?'V':'v') +
'-' +
(isNodeHigh(nodenames['p3'])?'B':'b') +
(isNodeHigh(nodenames['p3'])?'D':'d') +
(isNodeHigh(nodenames['p2'])?'I':'i') +
(isNodeHigh(nodenames['p1'])?'Z':'z') +
(isNodeHigh(nodenames['p0'])?'C':'c');
return result;
}
function readSP(){return readBits('s', 8);}
function readPC(){return (readBits('pch', 8)<<8) + readBits('pcl', 8);}
function readPCL(){return readBits('pcl', 8);}
function readPCH(){return readBits('pch', 8);}
function readBit(name){
return isNodeHigh(nodenames[name])?1:0;
}
function readBits(name, n){
var res = 0;
for(var i=0;i<n;i++){
@@ -144,6 +213,7 @@ function runChip(){
start.style.visibility = 'hidden';
stop.style.visibility = 'visible';
running = true;
steps();
}
function stopChip(){
@@ -156,7 +226,8 @@ function stopChip(){
function resetChip(){
stopChip();
initChip();
setStatus('resetting 6502...');
setTimeout(initChip,0);
}
function stepForward(){
@@ -174,17 +245,40 @@ function stepBack(){
}
function chipStatus(){
var pc = readAddressBus();
setStatus('PC:', hexWord(pc),
'D:', hexByte(readDataBus()),
'SP:',hexByte(readSP()),
'cycle:', cycle, '<br>',
'A:', hexByte(readA()),
'X:', hexByte(readX()),
'Y:', hexByte(readY()),
'P:', hexByte(readP())
);
selectCell(pc);
var ab = readAddressBus();
var machine1 =
' halfcyc:' + cycle +
' phi0:' + readBit('clk0') +
' AB:' + hexWord(ab) +
' D:' + hexByte(readDataBus()) +
' RnW:' + readBit('rw');
var machine2 =
' PC:' + hexWord(readPC()) +
' A:' + hexByte(readA()) +
' X:' + hexByte(readX()) +
' Y:' + hexByte(readY()) +
' SP:' + hexByte(readSP()) +
' ' + readPstring();
var machine3 =
' Sync:' + readBit('sync')
' IRQ:' + readBit('irq') +
' NMI:' + readBit('nmi');
var machine4 =
' IR:' + hexByte(255 - readBits('notir', 8)) +
' idl:' + hexByte(255 - readBits('idl', 8)) +
' alu:' + hexByte(255 - readBits('alu', 8)) +
' TCstate:' + readBit('clock1') + readBit('clock2') +
readBit('t2') + readBit('t3') + readBit('t4') + readBit('t5');
var machine5 =
' notRdy0:' + readBit('notRdy0') +
' fetch:' + readBit('fetch') +
' clearIR:' + readBit('clearIR') +
' D1x1:' + readBit('D1x1');
setStatus(machine1 + "<br>" + machine2);
if (loglevel>2) {
console.log(machine1 + " " + machine2 + " " + machine3 + " " + machine4 + " " + machine5);
}
selectCell(ab);
}
function getMem(){

View File

@@ -29,6 +29,14 @@ db5: 175,
db4: 1393,
db7: 1349,
db6: 1591,
idl0: 116,
idl1: 576,
idl2: 1485,
idl3: 1284,
idl4: 1516,
idl5: 498,
idl6: 1537,
idl7: 529,
a1: 1234,
ab1: 451,
ab2: 1340,
@@ -67,6 +75,14 @@ s7: 1435,
s6: 1212,
s5: 1098,
s4: 1702,
nots0: 418,
nots1: 1064,
nots2: 752,
nots3: 828,
nots4: 1603,
nots5: 601,
nots6: 1029,
nots7: 181,
rw: 1156,
x2: 1,
x3: 1648,
@@ -113,5 +129,81 @@ y5: 615,
y4: 989,
y7: 843,
y6: 115,
cclk: 943
cclk: 943, // aka cp2
clock1: 156,
clock2: 1536,
notir7: 1320,
notir6: 895, // OK
notir5: 1394, // OK
notir4: 26,
notir3: 1125,
notir2: 1182,
notir1: 702,
notir0: 194,
t2: 971,
t3: 1567,
t4: 690,
t5: 909,
cp1: 710,
fetch: 879,
clearIR: 1077,
D1x1: 827,
notRdy0: 248,
alu0: 394,
alu1: 697,
alu2: 276,
alu3: 495,
alu4: 1490,
alu5: 893,
alu6: 68,
alu7: 1123,
adl0: 413,
adl1: 1282,
adl2: 1242,
adl3: 684,
adl4: 1437,
adl5: 1630,
adl6: 121,
adl7: 1299,
adh0: 407,
adh1: 52,
adh2: 1651,
adh3: 315,
adh4: 1160,
adh5: 483,
adh6: 13,
adh7: 1539,
sb0: 54,
sb1: 1150,
sb2: 1287,
sb3: 1188,
sb4: 1405,
sb5: 166,
sb6: 1336,
sb7: 1001,
idb0: 1108,
idb1: 991,
idb2: 1473,
idb3: 1302,
idb4: 892,
idb5: 1503,
idb6: 833,
idb7: 493,
dor0: 222,
dor1: 527,
dor2: 1288,
dor3: 823,
dor4: 873,
dor5: 1266,
dor6: 1418,
dor7: 158,
pd0: 758,
pd1: 361,
pd2: 955,
pd3: 894,
pd4: 369,
pd5: 829,
pd6: 1669,
pd7: 1690,
h1x1: 1042, // drive status byte onto databus
}

View File

@@ -1,3 +1,14 @@
/*
Copyright (c) 2010 Greg James, Brian Silverman, Barry Silverman
The following is provided under terms of the Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 Unported license:
http://creativecommons.org/licenses/by-nc-sa/3.0/
Specify the original author as Greg James and the following URL
for original source material: www.visual6502.org
*/
var segdefs = [
[ 0,'+',1,5391,8260,5391,8216,5357,8216,5357,8260],
[ 0,'+',1,5391,7919,5391,7873,5356,7873,5356,7919],

View File

@@ -1,3 +1,14 @@
/*
Copyright (c) 2010 Greg James, Brian Silverman, Barry Silverman
The following is provided under terms of the Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 Unported license:
http://creativecommons.org/licenses/by-nc-sa/3.0/
Specify the original author as Greg James and the following URL
for original source material: www.visual6502.org
*/
var transdefs = [
['t0', 357, 558, 217],
['t1', 1608, 657, 349],

View File

@@ -1,8 +1,30 @@
/*
Copyright (c) 2010 Brian Silverman, Barry Silverman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
body {
background: white;
color: black;
font-family: cursive;
font-size: 30px;
font-size: 12px;
}
div.frame {
@@ -42,25 +64,23 @@ p.status {
}
img.navbutton{
margin-left: -5px;
border: 0px;
}
img.navplay{
margin-left: -5px;
position: relative;
margin-right: 5px;
border: 0px;
}
img.navstop{
position: absolute;
left: -5px;
top: 9px;
border: 0px;
}
table.memtable {
position: absolute;
top: 63px;
top: 78px;
left: 820px;
font-family: monospace;
font-size: 12px;

View File

@@ -26,8 +26,10 @@ var zoom=1;
var dragMouseX, dragMouseY, moved;
var statbox;
var colors = ['rgba(128,128,128,0.4)','#FFFF00','#FF00FF','#4DFF4D',
var layernames = ['metal', 'diff', 'inputdiode', 'diff0', 'diff1', 'poly'];
var colors = ['rgba(128,128,192,0.4)','#FFFF00','#FF00FF','#4DFF4D',
'#FF4D4D','#801AC0','rgba(128,0,255,0.75)'];
var drawlayers = [true, true, true, true, true, true];
var nodes = new Array();
var transistors = {};
@@ -42,11 +44,19 @@ var npwr = nodenames['vcc'];
//
/////////////////////////
// try to present a meaningful page before starting expensive work
function setup(){
statbox = document.getElementById('status');
setStatus('loading 6502...');
setTimeout(setup_part2, 0);
}
function setup_part2(){
frame = document.getElementById('frame');
statbox = document.getElementById('status');
setupNodes();
setupTransistors();
setupLayerVisibility();
setupBackground();
setupOverlay();
setupHilite();
@@ -56,6 +66,11 @@ function setup(){
setupTable();
window.onkeypress = function(e){handleKey(e);}
hilite.onmousedown = function(e){mouseDown(e);}
setStatus('resetting 6502...');
setTimeout(setup_part3, 0);
}
function setup_part3(){
initChip();
document.getElementById('stop').style.visibility = 'hidden';
go();
@@ -89,8 +104,17 @@ function setupTransistors(){
}
}
function setupLayerVisibility(){
var x=document.getElementById('updateShow');
for (var i=0;i<x.childNodes.length;i++) {
if(x.childNodes[i].type='checkbox'){
x.childNodes[i].checked=drawlayers[x.childNodes[i].name];
}
}
}
function setupBackground(){
console.log('starting setupBackground');
chipbg = document.getElementById('chipbg');
chipbg.width = 4000;
chipbg.height = 4000;
@@ -100,16 +124,16 @@ function setupBackground(){
ctx.strokeStyle = 'rgba(255,255,255,0.5)';
ctx.lineWidth = 4;
ctx.fillRect(0,0,10000,10000);
var start = now();
for(var i in segdefs){
var seg = segdefs[i];
var c = seg[2];
ctx.fillStyle = colors[c];
drawSeg(ctx, segdefs[i].slice(3));
ctx.fill();
if((c==0)||(c==6)) ctx.stroke();
if (drawlayers[c]) {
ctx.fillStyle = colors[c];
drawSeg(ctx, segdefs[i].slice(3));
ctx.fill();
if((c==0)||(c==6)) ctx.stroke();
}
}
// console.log('time to draw: ', now() - start, ' ms');
}
function setupOverlay(){
@@ -189,6 +213,7 @@ function hiliteNode(n){
function drawSeg(ctx, seg){
if(noGraphics) return;
var dx = 400;
ctx.beginPath();
ctx.moveTo(seg[0]+dx, 10000-seg[1])
@@ -288,6 +313,11 @@ function findNodeNumber(x,y){
return (high<<8)+(mid<<4)+low;
}
function updateShow(layer, on){
drawlayers[layer]=on;
setupBackground();
}
/////////////////////////
//
// Etc.
@@ -306,19 +336,13 @@ function setChipStyle(props){
function localx(el, gx){
var lx = gx+window.pageXOffset;
while(el.offsetLeft!=undefined){
lx-=el.offsetLeft+el.clientLeft;
el = el.parentNode;
}
lx-=el.getBoundingClientRect().left
return lx;
}
function localy(el, gy){
var ly = gy+window.pageYOffset;
while(el.offsetTop!=undefined){
ly-=el.offsetTop+el.clientTop;
el = el.parentNode;
}
ly-=el.getBoundingClientRect().top
return ly;
}