mirror of
https://github.com/trebonian/visual6502.git
synced 2025-02-06 22:30:02 +00:00
Merge branch 'master' into gh-pages
This commit is contained in:
commit
abf6daef7d
@ -188,6 +188,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){
|
||||||
|
83
macros.js
83
macros.js
@ -29,7 +29,7 @@ var logThese=[];
|
|||||||
var presetLogLists=[
|
var presetLogLists=[
|
||||||
['cycle'],
|
['cycle'],
|
||||||
['ab','db','rw','sync','pc','a','x','y','s','p'],
|
['ab','db','rw','sync','pc','a','x','y','s','p'],
|
||||||
['ir','tcstate','pd'],
|
['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'],
|
||||||
@ -273,18 +273,19 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
function readBit(name){
|
function readBit(name){
|
||||||
@ -311,14 +312,27 @@ function busToString(busname){
|
|||||||
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=='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++;
|
||||||
@ -435,15 +449,40 @@ function chipStatus(){
|
|||||||
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;
|
||||||
@ -452,13 +491,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
|
||||||
@ -473,11 +509,24 @@ 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;
|
var logbox;
|
||||||
function initLogbox(names){
|
function initLogbox(names){
|
||||||
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>" + names.join("</td><td>") + "</td>");
|
||||||
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
||||||
|
48
nodenames.js
48
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,13 +107,13 @@ 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
|
p0: 687, // machine state: status register
|
||||||
p1: 1444,
|
p1: 1444,
|
||||||
p2: 1421,
|
p2: 1421,
|
||||||
@ -250,22 +250,22 @@ 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,
|
||||||
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
|
||||||
|
@ -8,8 +8,16 @@
|
|||||||
//
|
//
|
||||||
testprogramAddress=0x0000;
|
testprogramAddress=0x0000;
|
||||||
|
|
||||||
|
// we want to auto-clear the console if any output is sent by the program
|
||||||
|
var consoleboxStream="";
|
||||||
|
|
||||||
// demonstrate write hook
|
// demonstrate write hook
|
||||||
writeTriggers[0x000c]="consolebox.innerHTML = consolebox.innerHTML + String.fromCharCode(d);";
|
writeTriggers[0x000c]="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, // LDA #$00
|
0xa9, 0x00, // LDA #$00
|
||||||
|
Loading…
x
Reference in New Issue
Block a user