mirror of
https://github.com/trebonian/visual6502.git
synced 2024-12-22 12:29:20 +00:00
[dev]enhancements to expert mode
This commit is contained in:
parent
46976519fe
commit
730312e594
35
index.html
35
index.html
@ -58,32 +58,37 @@ Enter your own program into the array of RAM
|
||||
</div>
|
||||
<div class = "buttons">
|
||||
<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>
|
||||
<a href ="javascript:stopChip()"id="stop"><img class="navstop" src="images/stop.png" title="stop"></a>
|
||||
<a href ="javascript:runChip()" id="start"><img class="navplay" src="images/play.png" title="run"></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 id="expertMode" style="float:left;">Expert:
|
||||
<a href ="javascript:resetChip()"><img class="navbutton" src="images/up.png" title="reset"></a>
|
||||
<a href ="javascript:stepBack()"><img class="navbutton" src="images/prev.png" title="back"></a>
|
||||
<a href ="javascript:stepForward()"><img class="navbutton" src="images/next.png" title="step"></a>
|
||||
<span id="expertMode">Expert:
|
||||
<input type="checkbox" name="0" onchange="updateExpertMode(this.checked)" />
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="status" id="status">x: 0<br>y: 0</p>
|
||||
<table class="memtable" id="memtable"></table>
|
||||
</div>
|
||||
<div id="controlPanel" style="visibility:hidden">
|
||||
<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)" />(switched diffusion)
|
||||
<div id="controlPanel" style="display:none">
|
||||
<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)
|
||||
<input type="checkbox" name="4" id="updateShow4" onchange="updateShow(this.name,this.checked)" />(powered diffusion)
|
||||
<input type="checkbox" name="5" id="updateShow5" onchange="updateShow(this.name,this.checked)" />(polysilicon)
|
||||
<input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(diode)
|
||||
</div>
|
||||
<br />
|
||||
<table class="logstream" id="logstream"></table>
|
||||
<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>
|
||||
<input type="button" value="Clear Highlighting" onclick="clearHighlight()" />
|
||||
<input type="button" value="Trace more" onclick="updateLoglevel(1)" />
|
||||
<input type="button" value="Trace less" onclick="updateLoglevel(-1)" />
|
||||
</form>
|
||||
<br />
|
||||
<table class="logstream" id="logstream"></table>
|
||||
</div>
|
||||
<br />
|
||||
Source code is available on GitHub: <a href="http://github.com/trebonian/visual6502">http://github.com/trebonian/visual6502</a>
|
||||
|
100
macros.js
100
macros.js
@ -99,35 +99,49 @@ function initChip(){
|
||||
recalcNodeList(allNodes());
|
||||
for(var i=0;i<8;i++){setHigh('clk0'), setLow('clk0');}
|
||||
setHigh('res');
|
||||
for(var i=0;i<18;i++){resetStep();}
|
||||
for(var i=0;i<18;i++){halfStep();}
|
||||
refresh();
|
||||
cycle = 0;
|
||||
trace = Array();
|
||||
initLogbox(logThese);
|
||||
initLogbox(signalSet(loglevel));
|
||||
chipStatus();
|
||||
if(ctrace)console.log('initChip done after', now()-start);
|
||||
}
|
||||
|
||||
var logThese=['cycle','sync','irq','nmi','ab','db','rw','pc','a','x','y','s','p'];
|
||||
var logThese=[
|
||||
['cycle'],
|
||||
['sync','irq','nmi'],
|
||||
['ab','db','rw','pc','a','x','y','s','p'],
|
||||
['adl','adh','sb','alu'],
|
||||
['notalucin','alucout','alua','alub','dasb'],
|
||||
['idb','dor'],
|
||||
['ir','tcstate','pd'],
|
||||
];
|
||||
|
||||
function signalSet(n){
|
||||
var signals=[];
|
||||
for (var i=0; i<=n; i++){
|
||||
for (var j=0; j<logThese[i].length; j++){
|
||||
signals.push(logThese[i][j]);
|
||||
}
|
||||
}
|
||||
return signals;
|
||||
}
|
||||
|
||||
// simulate a single clock phase, updating trace and highlighting layout
|
||||
function step(){
|
||||
trace[cycle]= {chip: stateString(), mem: getMem()};
|
||||
halfStep();
|
||||
refresh();
|
||||
cycle++;
|
||||
chipStatus();
|
||||
}
|
||||
|
||||
// simulate a single clock phase with no update to graphics or trace
|
||||
function halfStep(){
|
||||
var clk = isNodeHigh(nodenames['clk0']);
|
||||
if (clk) {setLow('clk0'); handleBusRead(); }
|
||||
else {setHigh('clk0'); handleBusWrite();}
|
||||
refresh();
|
||||
}
|
||||
|
||||
function resetStep(){
|
||||
var clk = isNodeHigh(nodenames['clk0']);
|
||||
if (clk) {setLow('clk0'); handleBusRead(); }
|
||||
else {setHigh('clk0'); handleBusWrite();}
|
||||
}
|
||||
|
||||
function handleBusRead(){
|
||||
@ -181,26 +195,54 @@ function readBits(name, n){
|
||||
function busToString(busname){
|
||||
// takes a signal name or prefix
|
||||
// returns an appropriate string representation
|
||||
if(busname=='cycle')
|
||||
return cycle>>1;
|
||||
if(busname=='pc')
|
||||
return busToHex('pch') + busToHex('pcl');
|
||||
if(busname=='p')
|
||||
return readPstring();
|
||||
if(busname=='cycle')
|
||||
return cycle>>1;
|
||||
if(busname=='tcstate')
|
||||
return busToHex('clock1') + busToHex('clock2') +
|
||||
busToHex('t2') + busToHex('t3') + busToHex('t4') + busToHex('t5');
|
||||
return busToHex(busname);
|
||||
}
|
||||
|
||||
function busToHex(busname){
|
||||
// may be passed a bus or a signal, so allow multiple signals
|
||||
// signals may have multi-part names like pla51_T0SBC which should match either part
|
||||
// this is quite difficult to deal with, perhaps indicating that it is not such a good idea
|
||||
var width=0;
|
||||
var hit=-1;
|
||||
var r=new RegExp('(\\b|_)' + busname + '([_0-9]|\\b)');
|
||||
for(var i in nodenamelist){
|
||||
if(nodenamelist[i].search("^"+busname+"[0-9]")==0)
|
||||
if(r.test(nodenamelist[i])) {
|
||||
width++;
|
||||
hit=i;
|
||||
}
|
||||
}
|
||||
if(width==0)
|
||||
return isNodeHigh(nodenames[busname])?1:0;
|
||||
if(width>16)
|
||||
return -1;
|
||||
return (0x10000+readBits(busname,width)).toString(16).slice(-width/4);
|
||||
if(hit<0)
|
||||
return -1;
|
||||
// we may have a partial match, so find the full name of the last match
|
||||
// we might have matched the first part, second part, or the whole thing (maybe with a numeric suffix)
|
||||
var match1 = '^(' + busname + '_.*[^0-9])([0-9]*$|$)';
|
||||
var match2 = '^(.*_' + busname + ')([0-9]*$|$)';
|
||||
var match3 = '^(' + busname + ')([0-9]*$|$)';
|
||||
r=new RegExp(match1);
|
||||
var fullname=r.exec(nodenamelist[hit]);
|
||||
if(fullname==undefined){
|
||||
r=new RegExp(match2);
|
||||
fullname=r.exec(nodenamelist[hit]);
|
||||
if(fullname==undefined){
|
||||
r=new RegExp(match3);
|
||||
fullname=r.exec(nodenamelist[hit]);
|
||||
}
|
||||
}
|
||||
// finally, convert from logic values to hex
|
||||
if(width==1)
|
||||
return isNodeHigh(nodenames[fullname[1]])?1:0;
|
||||
return (0x10000+readBits(fullname[1],width)).toString(16).slice(-(width-1)/4-1);
|
||||
}
|
||||
|
||||
function writeDataBus(x){
|
||||
@ -288,15 +330,17 @@ function chipStatus(){
|
||||
' SP:' + hexByte(readSP()) +
|
||||
' ' + readPstring();
|
||||
setStatus(machine1 + "<br>" + machine2);
|
||||
if (loglevel>1) {
|
||||
updateLogbox(logThese);
|
||||
if (loglevel>0) {
|
||||
updateLogbox(signalSet(loglevel));
|
||||
}
|
||||
selectCell(ab);
|
||||
}
|
||||
|
||||
function initLogbox(names){
|
||||
var logbox=document.getElementById('logstream');
|
||||
logStream = [];
|
||||
logStream.push("<td>" + names.join("</td><td>") + "</td>");
|
||||
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
||||
}
|
||||
|
||||
function updateLogbox(names){
|
||||
@ -309,26 +353,6 @@ function updateLogbox(names){
|
||||
logStream.push("<td>" + signals.join("</td><td>") + "</td>");
|
||||
|
||||
logbox.innerHTML = "<tr>"+logStream.join("</tr><tr>")+"</tr>";
|
||||
|
||||
|
||||
var machine3 =
|
||||
' Sync:' + readBit('sync') +
|
||||
' IRQ:' + readBit('irq') +
|
||||
' NMI:' + readBit('nmi');
|
||||
var machine4 =
|
||||
' IR:' + hexByte(readBits('ir', 8)) +
|
||||
' TCstate:' + readBit('clock1') + readBit('clock2') +
|
||||
readBit('t2') + readBit('t3') + readBit('t4') + readBit('t5');
|
||||
var machine5 =
|
||||
' idl:' + hexByte(readBits('idl', 8)) +
|
||||
' alu:' + hexByte(readBits('alu', 8)) +
|
||||
' idb:' + hexByte(readBits('idb',8)) +
|
||||
' dor:' + hexByte(readBits('dor',8));
|
||||
var machine6 =
|
||||
' notRdy0:' + readBit('notRdy0') +
|
||||
' fetch:' + readBit('fetch') +
|
||||
' clearIR:' + readBit('clearIR') +
|
||||
' D1x1:' + readBit('D1x1');
|
||||
}
|
||||
|
||||
function getMem(){
|
||||
|
@ -83,7 +83,7 @@ table.logstream {
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
border-spacing: 2px;
|
||||
text-align:center
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
table.memtable {
|
||||
|
18
wires.js
18
wires.js
@ -321,16 +321,28 @@ function findNodeNumber(x,y){
|
||||
return (high<<8)+(mid<<4)+low;
|
||||
}
|
||||
|
||||
function updateLoglevel(delta){
|
||||
loglevel += delta;
|
||||
initLogbox(signalSet(loglevel));
|
||||
}
|
||||
|
||||
function updateExpertMode(on){
|
||||
if(on){
|
||||
document.getElementById('controlPanel').style.visibility = 'visible';
|
||||
loglevel=4;
|
||||
document.getElementById('controlPanel').style.display = 'block';
|
||||
loglevel=1;
|
||||
initLogbox(signalSet(loglevel));
|
||||
} else {
|
||||
document.getElementById('controlPanel').style.visibility = 'hidden';
|
||||
document.getElementById('controlPanel').style.display = 'none';
|
||||
loglevel=0;
|
||||
}
|
||||
}
|
||||
|
||||
function clearHighlight(){
|
||||
// remove red/white overlay according to logic value
|
||||
// for easier layout navigation
|
||||
ctx.clearRect(0,0,10000,10000);
|
||||
}
|
||||
|
||||
function updateShow(layer, on){
|
||||
drawlayers[layer]=on;
|
||||
setupBackground();
|
||||
|
Loading…
Reference in New Issue
Block a user