30 Commits
V0.4.1 ... V0.5

Author SHA1 Message Date
93252a0eb1 [bug]fixup obsolete css file reference in browsertrouble.html 2010-11-27 15:58:46 +00:00
172394845a [bug]typo: fixed B bit of status register 2010-11-27 14:30:19 +00:00
ec7da19d77 add z and x to expert mode help text 2010-11-27 14:19:57 +00:00
13e1f51b47 kiosk mode: add link to user guide, tweak help text and add alphabetic zoom controls 2010-11-27 13:54:31 +00:00
e6d3c62057 [bug]deal with disassembly of unknown opcodes 2010-11-27 12:37:14 +00:00
fbf0830d15 Expert page: add link to user guide (wiki page) 2010-11-27 11:37:08 +00:00
019bca0a26 remove white gaps in new logstream table colour scheme 2010-11-26 22:14:09 +00:00
e866a3b58e put non-breaking spaces into disassembly fragments 2010-11-26 14:27:03 +00:00
611490ad76 various blue backgrounds to logstream table 2010-11-26 14:22:45 +00:00
b3e58dcbab immunize kiosk mode against I/O triggers in test program 2010-11-22 15:20:24 +00:00
c7ac03edd8 move the I/O port (incremented value) to the top right for better visibility 2010-11-22 15:19:38 +00:00
b51b5c4398 re-simplify kiosk mode status panel 2010-11-22 15:18:55 +00:00
398060f56b add opcode and machine state info to status panel, add Fetch Execute and State pseudo signals to log tabulation 2010-11-22 13:27:26 +00:00
cdd837dd0c display machine state in status panel 2010-11-22 12:23:20 +00:00
3df7065b83 fold 6502 opcode lookup into macro.js and delete Java original 2010-11-22 12:22:36 +00:00
f860067206 convert java debugger to javascript almost-disassembler 2010-11-22 11:40:14 +00:00
33f00022ca add Achim's original Debugger.java 2010-11-22 11:33:56 +00:00
8a6fe3634f add tracing of datapath control signals 2010-11-19 22:42:26 +00:00
296599890a correct the PC master/slave labelling and revert the predecode to the (inverted) latch nodes 2010-11-19 21:50:20 +00:00
580f4585a6 allow inverted display of negative sense busses 2010-11-19 21:49:16 +00:00
d045485ec4 [enh]allow free-running low-overhead mode, for interactive programs 2010-11-15 17:29:50 +00:00
71a85b3135 small improvement to trigger examples in testprogram 2010-11-15 17:28:45 +00:00
b3a6a12ddc adding URL control of IRQ and NMI pins 2010-11-14 20:15:49 +00:00
5f472cbe10 Merge branch 'master' of git://github.com/trebonian/visual6502 2010-11-10 22:20:36 +00:00
6be4dd1673 add link to Advanced page and re-word other link 2010-11-09 21:25:56 +00:00
7e6eb926ee Merge branch 'master' of git://github.com/trebonian/visual6502 2010-11-09 20:31:19 +00:00
6c2217b8fa [bug]kiosk mode must also load macros before testprogram 2010-11-08 22:29:08 +00:00
f6a86088f0 [enh]add a putc action to the test program 2010-11-08 22:18:07 +00:00
5c9b4e7581 [dev]adding console box and read/write hook mechanism for test program I/O 2010-11-08 22:03:47 +00:00
2a0e251088 [bug]fix improper closing tag (expert.html) 2010-11-08 16:36:45 +00:00
9 changed files with 418 additions and 79 deletions

View File

@ -2,7 +2,7 @@
<head>
<title>Visual 6502 in JavaScript</title>
<style type="text/css">@import "wires.css";</style>
<style type="text/css">@import "kiosk.css";</style>
</head>
<body>

View File

@ -138,6 +138,14 @@ a#linkHere{
padding:2px;
}
textarea#consolebox{
font-family:courier,monospace;
border: 1px solid gray;
margin: 2px;
padding: 2px;
width: 80em;
}
div#logstreamscroller{
overflow:auto;
}
@ -145,10 +153,31 @@ div#logstreamscroller{
table.logstream {
font-family: monospace;
font-size: 12px;
border-spacing: 2px;
border-collapse: collapse;
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 */
#frame {
height: 750px;
@ -197,5 +226,3 @@ span#plain {
display: block;
margin-bottom: 4px;
}

View File

@ -76,7 +76,7 @@ $().ready(function(){
</form>
</div>
<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:
<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)
@ -85,7 +85,7 @@ $().ready(function(){
<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)
</form>
<form action="javascript:hiliteNodeList();" />
<form action="javascript:hiliteNodeList();">
<input type="button" value="Highlight:" onclick="hiliteNodeList();" />
<input type="text" id="HighlightThese" name="HighlightThese" value="" />
<input type="button" value="Clear Highlighting" onclick="clearHighlight();" />
@ -114,6 +114,10 @@ $().ready(function(){
<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>
</div>
<div style="float:right;">
<a href="http://visual6502.org/wiki/index.php?title=JssimUserHelp" target="_blank">User Guide</a>
&nbsp;
</div>
</div> <!-- buttons -->
<div class="status" id="status"><p>x: 0<br>y: 0</p>
</div> <!-- status -->
@ -124,7 +128,10 @@ $().ready(function(){
</div> <!-- righttopdiv -->
<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()">
<input type="button" value="Trace more" onclick="updateLoglevel(++loglevel)" />
<input type="button" value="Trace less" onclick="updateLoglevel(--loglevel)" />

View File

@ -103,6 +103,7 @@ function setup_part4(){
setupNodeNameList();
logThese=signalSet(loglevel);
loadProgram();
setupConsole();
if(noSimulation){
stopChip();
running=undefined;
@ -187,6 +188,14 @@ function setupParams(){
clockTriggers[value]="setLow('res');";
} else if(name=="reset1" && parseInt(value)!=NaN){
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
// run a test program, and optionally check against a golden checksum
if(name=="steps" && parseInt(value)!=NaN){
@ -352,6 +361,14 @@ function setupExpertMode(isOn){
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;};
}
var chipsurround;
function updateChipLayoutVisibility(isOn){

View File

@ -12,8 +12,8 @@
<script src="wires.js"></script>
<script src="chipsim.js"></script>
<script src="memtable.js"></script>
<script src="testprogram.js"></script>
<script src="macros.js"></script>
<script src="testprogram.js"></script>
<script type="text/javascript">
function handleOnload() {
@ -62,11 +62,11 @@ lots of RAM. If you have trouble, please <a href="browsertrouble.html">check com
<br />
<span id="browsertrouble"></span>
<br />
Hit '>' to zoom in, '<' to zoom out
Keyboard controls: 'z' to zoom in, 'x' to zoom out, 'n' to step the simulation.
<br />
Left-click and drag to scroll around
Mouse controls: Left-click and drag to scroll around (when you're zoomed in.)
<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 />
</span>

View File

@ -88,6 +88,7 @@ function setup_part2(){
function setup_part3(){
loadProgram();
writeTriggers={}; // kiosk mode does not handle I/O
initChip();
document.getElementById('stop').style.visibility = 'hidden';
go();
@ -103,9 +104,9 @@ function setup_part3(){
function handleKey(e){
var c = e.charCode;
c = String.fromCharCode(c);
if('<>?np'.indexOf(c)==-1) return;
if(c=='<' && zoom>1) setZoom(zoom/1.2);
else if(c=='>' && zoom<grMaxZoom) setZoom(zoom*1.2);
if('zx<>?np'.indexOf(c)==-1) return;
if((c=='x' || c=='<') && zoom>1) setZoom(zoom/1.2);
else if((c=='z' || c=='>') && zoom<grMaxZoom) setZoom(zoom*1.2);
else if(c=='?') setZoom(1);
else if(c=='n') stepForward();
else if(c=='p') stepBack();

342
macros.js
View File

@ -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
of this software and associated documentation files (the "Software"), to deal
@ -28,11 +28,12 @@ var running = false;
var logThese=[];
var presetLogLists=[
['cycle'],
['ab','db','rw','sync','pc','a','x','y','s','p'],
['ir','tcstate','pd'],
['ab','db','rw','Fetch','pc','a','x','y','s','p'],
['Execute','State'],
['ir','tcstate','-pd'],
['adl','adh','sb','alu'],
['alucin','alua','alub','alucout','aluvout','dasb'],
['plaOutputs'],
['plaOutputs','DPControl'],
['idb','dor'],
['irq','nmi','res'],
];
@ -209,24 +210,42 @@ function step(){
}
// triggers for breakpoints, watchpoints, input pin events
// almost always are undefined when tested, so minimal impact on performance
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
function halfStep(){
var clk = isNodeHigh(nodenames['clk0']);
eval(clockTriggers[cycle]); // usually undefined, no measurable performance loss
eval(clockTriggers[cycle]);
if (clk) {setLow('clk0'); handleBusRead(); }
else {setHigh('clk0'); handleBusWrite();}
}
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(){
if(!isNodeHigh(nodenames['rw'])){
var a = readAddressBus();
var d = readDataBus();
eval(writeTriggers[a]);
mWrite(a,d);
if(a<0x200) setCellValue(a,d);
}
@ -243,7 +262,7 @@ function readPstring(){
result = (isNodeHigh(nodenames['p7'])?'N':'n') +
(isNodeHigh(nodenames['p6'])?'V':'v') +
'&#8209' + // non-breaking hyphen
(isNodeHigh(nodenames['p3'])?'B':'b') +
(isNodeHigh(nodenames['p4'])?'B':'b') +
(isNodeHigh(nodenames['p3'])?'D':'d') +
(isNodeHigh(nodenames['p2'])?'I':'i') +
(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 readPCH(){return readBits('pch', 8);}
function listActivePlaOutputs(){
// PLA outputs are mostly ^op- but some have a prefix too
// - we'll allow the x and xx prefix but ignore the #
var r=new RegExp('^([x]?x-)?op-');
var pla=[];
// for one-hot or few-hot signal collections we want to list the active ones
// and for brevity we remove the common prefix
function listActiveSignals(pattern){
var r=new RegExp(pattern);
var list=[];
for(var i in nodenamelist){
if(r.test(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,'&#8209'));
}
}
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){
@ -284,6 +316,7 @@ function readBits(name, n){
function busToString(busname){
// takes a signal name or prefix
// returns an appropriate string representation
// some 'signal names' are CPU-specific aliases to user-friendly string output
if(busname=='cycle')
return cycle>>1;
if(busname=='pc')
@ -292,15 +325,34 @@ function busToString(busname){
return readPstring();
if(busname=='tcstate')
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')
return listActivePlaOutputs();
return busToHex(busname);
// 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);
}
}
function busToHex(busname){
// may be passed a bus or a signal, so allow multiple signals
var width=0;
var r=new RegExp('^' + busname + '[0-9]');
var r=new RegExp('^' + busname + '[0-9]+$');
for(var i in nodenamelist){
if(r.test(nodenamelist[i])) {
width++;
@ -407,25 +459,56 @@ function chipStatus(){
' Y:' + hexByte(readY()) +
' SP:' + hexByte(readSP()) +
' ' + readPstring();
var chk='';
if(goldenChecksum != undefined)
chk=" Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
setStatus(machine1, machine2, "Hz: " + estimatedHz().toFixed(1) + 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)
machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
}
setStatus(machine1, machine2, machine3);
if (loglevel>0) {
updateLogbox(logThese);
}
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(){
var n = headlessSteps;
estimatedHz1();
var n = headlessSteps; // a negative value is a request to free-run
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--){
halfStep();
cycle++;
}
estimatedHz1();
instantaneousHz();
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;
@ -434,13 +517,10 @@ var prevHzEstimate1=1;
var prevHzEstimate2=1;
var HzSamplingRate=10;
// return an averaged speed: called periodically during normal running
function estimatedHz(){
if(cycle%HzSamplingRate!=3)
return prevHzEstimate1;
return estimatedHz1();
}
function estimatedHz1(){
var HzTimeStamp = now();
var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01);
HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz
@ -455,12 +535,26 @@ function estimatedHz1(){
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){
var logbox=document.getElementById('logstream');
logbox=document.getElementById('logstream');
if(logbox==null)return;
names=names.map(function(x){return x.replace(/^-/,'')});
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>";
}
@ -469,9 +563,8 @@ var logboxAppend=true;
// can append or prepend new states to the log table
// when we reverse direction we need to reorder the log stream
function updateLogDirection(){
logboxAppend=!logboxAppend;
var logbox=document.getElementById('logstream');
var loglines=[];
logboxAppend=!logboxAppend;
// the first element is the header so we can't reverse()
for (var i=1;i<logStream.length;i++) {
loglines.unshift(logStream[i]);
@ -483,18 +576,27 @@ function updateLogDirection(){
// update the table of signal values, by prepending or appending
function updateLogbox(names){
var logbox=document.getElementById('logstream');
var signals=[];
var odd=true;
var bg;
var row;
for(i in names){
signals.push(busToString(names[i]));
for(var i in names){
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)
logStream.push("<td>" + signals.join("</td><td>") + "</td>");
logStream.push(row);
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(){
@ -519,3 +621,167 @@ function adler32(x){
}
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(/ /,'&nbsp;');
}
// 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",
};

View File

@ -90,13 +90,13 @@ pcl4: 900,
pcl5: 622,
pcl6: 377,
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,
pclp2: 1411,
pclp2: 1079,
pclp3: 868,
pclp4: 15,
pclp4: 39,
pclp5: 1326,
pclp6: 993,
pclp6: 731,
pclp7: 536,
pch0: 1670, // machine state: program counter high (first storage node)
pch1: 292,
@ -107,13 +107,13 @@ pch5: 49,
pch6: 1551,
pch7: 205,
pchp0: 780, // machine state: program counter high (pre-incremented?, second storage node)
pchp1: 126,
pchp1: 113,
pchp2: 114,
pchp3: 1061,
pchp3: 124,
pchp4: 820,
pchp5: 469,
pchp5: 33,
pchp6: 751,
pchp7: 663,
pchp7: 535,
p0: 687, // machine state: status register
p1: 1444,
p2: 1421,
@ -250,22 +250,22 @@ dor4: 1088,
dor5: 1453,
dor6: 1415,
dor7: 63,
pd0: 1622, // internal state: predecode register output (anded with not ClearIR)
pd1: 809,
pd2: 1671,
pd3: 1587,
pd4: 540,
pd5: 667,
pd6: 1460,
pd7: 1410,
notpd0: 758, // internal state: predecode register (storage node)
notpd1: 361,
notpd2: 955,
notpd3: 894,
notpd4: 369,
notpd5: 829,
notpd6: 1669,
notpd7: 1690,
"pd0.clearIR": 1622, // internal state: predecode register output (anded with not ClearIR)
"pd1.clearIR": 809,
"pd2.clearIR": 1671,
"pd3.clearIR": 1587,
"pd4.clearIR": 540,
"pd5.clearIR": 667,
"pd6.clearIR": 1460,
"pd7.clearIR": 1410,
pd0: 758, // internal state: predecode register (storage node)
pd1: 361,
pd2: 955,
pd3: 894,
pd4: 369,
pd5: 829,
pd6: 1669,
pd7: 1690,
notRdy0: 248, // internal signal: global pipeline control
Reset0: 67, // internal signal: retimed reset from pin
C1x5Reset: 926, // retimed and pipelined reset in progress

View File

@ -8,8 +8,29 @@
//
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 = [
0xa9, 0x00, 0x20, 0x10, 0x00, 0x4c, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe8, 0x88, 0xe6, 0x40, 0x38, 0x69, 0x02, 0x60
0xa9, 0x00, // LDA #$00
0x20, 0x10, 0x00, // JSR $0010
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
];