mirror of
https://github.com/trebonian/visual6502.git
synced 2024-12-21 06:29:46 +00:00
Merging changes for testprogram, and various fixes from Ed
This commit is contained in:
commit
dc0fb1ef06
@ -10,6 +10,7 @@
|
||||
<script src="chipsim.js"></script>
|
||||
<script src="memtable.js"></script>
|
||||
<script src="macros.js"></script>
|
||||
<script src="testprogram.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function handleOnload() {
|
||||
|
69
macros.js
69
macros.js
@ -21,27 +21,34 @@
|
||||
*/
|
||||
|
||||
var memory = Array();
|
||||
var code = [0xa9, 0x00, 0x20, 0x10, 0x00, 0x4c, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe8, 0x88, 0xe6, 0x40, 0x38, 0x69, 0x02, 0x60];
|
||||
var cycle = 0;
|
||||
var trace = Array();
|
||||
var logstream = Array();
|
||||
var running = false;
|
||||
|
||||
function loadProgram(){
|
||||
// a moderate size of static testprogram might be loaded
|
||||
if(testprogram.length!=0 && testprogramAddress != undefined)
|
||||
for(var i=0;testprogram[i]!=undefined;i++){
|
||||
var a=testprogramAddress+i;
|
||||
mWrite(a, testprogram[i]);
|
||||
if(a<0x200)
|
||||
setCellValue(a, testprogram[i]);
|
||||
}
|
||||
// a small test program or patch might be passed in the URL
|
||||
if(userCode.length!=0)
|
||||
code=userCode;
|
||||
for(var i=0;i<userCode.length;i++){
|
||||
if(userCode[i] != undefined){
|
||||
mWrite(i, userCode[i]);
|
||||
if(i<0x200)
|
||||
setCellValue(i, userCode[i]);
|
||||
}
|
||||
}
|
||||
// default reset vector will be 0x0000 because undefined memory reads as zero
|
||||
if(userResetLow!=undefined)
|
||||
mWrite(0xfffc, userResetLow);
|
||||
if(userResetHigh!=undefined)
|
||||
mWrite(0xfffd, userResetHigh);
|
||||
for(var i=0;i<code.length;i++){
|
||||
mWrite(i, code[i]);
|
||||
if(i<0x200)
|
||||
setCellValue(i, code[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function go(){
|
||||
@ -57,6 +64,21 @@ function go(){
|
||||
}
|
||||
}
|
||||
|
||||
function goUntilSync(){
|
||||
halfStep();
|
||||
while(!isNodeHigh(nodenames['sync']) || isNodeHigh(nodenames['clk0']))
|
||||
halfStep();
|
||||
}
|
||||
|
||||
function goUntilSyncOrWrite(){
|
||||
halfStep();
|
||||
while(
|
||||
!isNodeHigh(nodenames['clk0']) ||
|
||||
( !isNodeHigh(nodenames['sync']) && isNodeHigh(nodenames['rw']) )
|
||||
)
|
||||
halfStep();
|
||||
}
|
||||
|
||||
function testNMI(n){
|
||||
initChip();
|
||||
|
||||
@ -139,9 +161,16 @@ function signalSet(n){
|
||||
return signals;
|
||||
}
|
||||
|
||||
var traceChecksum='';
|
||||
var goldenChecksum;
|
||||
|
||||
// simulate a single clock phase, updating trace and highlighting layout
|
||||
function step(){
|
||||
trace[cycle]= {chip: stateString(), mem: getMem()};
|
||||
var s=stateString();
|
||||
var m=getMem();
|
||||
trace[cycle]= {chip: s, mem: m};
|
||||
if(goldenChecksum != undefined)
|
||||
traceChecksum=adler32(traceChecksum+s+m.slice(0,511).toString(16));
|
||||
halfStep();
|
||||
if(animateChipLayout)
|
||||
refresh();
|
||||
@ -179,7 +208,7 @@ function readPstring(){
|
||||
var result;
|
||||
result = (isNodeHigh(nodenames['p7'])?'N':'n') +
|
||||
(isNodeHigh(nodenames['p6'])?'V':'v') +
|
||||
'-' +
|
||||
'‑' + // non-breaking hyphen
|
||||
(isNodeHigh(nodenames['p3'])?'B':'b') +
|
||||
(isNodeHigh(nodenames['p3'])?'D':'d') +
|
||||
(isNodeHigh(nodenames['p2'])?'I':'i') +
|
||||
@ -214,8 +243,7 @@ function busToString(busname){
|
||||
if(busname=='p')
|
||||
return readPstring();
|
||||
if(busname=='tcstate')
|
||||
return busToHex('clock1') + busToHex('clock2') +
|
||||
busToHex('t2') + busToHex('t3') + busToHex('t4') + busToHex('t5');
|
||||
return ['clock1','clock2','t2','t3','t4','t5'].map(busToHex).join("");
|
||||
return busToHex(busname);
|
||||
}
|
||||
|
||||
@ -341,7 +369,10 @@ function chipStatus(){
|
||||
' Y:' + hexByte(readY()) +
|
||||
' SP:' + hexByte(readSP()) +
|
||||
' ' + readPstring();
|
||||
setStatus(machine1, machine2, "Hz: " + estimatedHz().toFixed(1));
|
||||
var chk='';
|
||||
if(goldenChecksum != undefined)
|
||||
chk=" Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
|
||||
setStatus(machine1, machine2, "Hz: " + estimatedHz().toFixed(1) + chk);
|
||||
if (loglevel>0) {
|
||||
updateLogbox(signalSet(loglevel));
|
||||
}
|
||||
@ -401,3 +432,13 @@ function setMem(arr){
|
||||
|
||||
function hexWord(n){return (0x10000+n).toString(16).substring(1)}
|
||||
function hexByte(n){return (0x100+n).toString(16).substring(1)}
|
||||
|
||||
function adler32(x){
|
||||
var a=1;
|
||||
var b=0;
|
||||
for(var i=0;i<x.length;i++){
|
||||
a=(a+x.charCodeAt(i))%65521;
|
||||
b=(b+a)%65521;
|
||||
}
|
||||
return (0x100000000+(b<<16)+a).toString(16).slice(-8);
|
||||
}
|
||||
|
15
testprogram.js
Normal file
15
testprogram.js
Normal file
@ -0,0 +1,15 @@
|
||||
// This file testprogram.js can be substituted by one of several tests
|
||||
// which may not be redistributable
|
||||
// for example
|
||||
// cbmbasic loaded at 0xa000 with entry point 0xe394
|
||||
// test6502 (by Bird Computer) loaded at 0x8000 with entry point 0x8000
|
||||
//
|
||||
// (can use xxd -i to convert binary into C include syntax, as a starting point)
|
||||
//
|
||||
testprogramAddress=0x0000;
|
||||
|
||||
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
|
||||
];
|
30
wires.js
30
wires.js
@ -67,6 +67,8 @@ var userCode=[];
|
||||
var userResetLow;
|
||||
var userResetHigh;
|
||||
var userSteps;
|
||||
var testprogram=[];
|
||||
var testprogramAddress;
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
@ -125,22 +127,25 @@ function setupParams(){
|
||||
var name=params[0];
|
||||
var value=params[1].replace(/\/$/,""); // chrome sometimes adds trailing slash
|
||||
// be (relatively) forgiving in what we accept
|
||||
if(name=="loglevel" && parseInt(value)>0){
|
||||
//
|
||||
// user interface mode control
|
||||
if(name=="loglevel" && parseInt(value)!=NaN){
|
||||
updateLoglevel(value);
|
||||
} else if(name=="expert" && value.indexOf("t")==0){
|
||||
updateExpertMode(true);
|
||||
} else if(name=="graphics" && value.indexOf("f")==0){
|
||||
updateChipLayoutVisibility(false);
|
||||
} else if(name=="panx" && parseInt(value)!=NaN){
|
||||
} else
|
||||
// place the graphics window at a point of interest
|
||||
if(name=="panx" && parseInt(value)!=NaN){
|
||||
panx=parseInt(value);
|
||||
} else if(name=="pany" && parseInt(value)!=NaN){
|
||||
pany=parseInt(value);
|
||||
} else if(name=="zoom" && parseInt(value)!=NaN){
|
||||
zoom=parseInt(value);
|
||||
} else if(name=="steps" && parseInt(value)!=NaN){
|
||||
userSteps=parseInt(value);
|
||||
running=true;
|
||||
} else if(name=="a" && parseInt(value,16)!=NaN){
|
||||
} else
|
||||
// load a test program: Address, Data and Reset
|
||||
if(name=="a" && parseInt(value,16)!=NaN){
|
||||
userAddress=parseInt(value,16);
|
||||
} else if(name=="d" && value.match(/[0-9a-fA-F]*/)[0].length==value.length){
|
||||
for(var j=0;j<value.length;j+=2)
|
||||
@ -148,6 +153,13 @@ function setupParams(){
|
||||
} else if(name=="r" && parseInt(value,16)!=NaN){
|
||||
userResetLow=parseInt(value,16)%256;
|
||||
userResetHigh=(parseInt(value,16)>>8)%256;
|
||||
} else
|
||||
// run a test program, and optionally check against a golden checksum
|
||||
if(name=="steps" && parseInt(value)!=NaN){
|
||||
userSteps=parseInt(value);
|
||||
running=true;
|
||||
} else if(name=="checksum" && parseInt(value,16)!=NaN){
|
||||
goldenChecksum=(0x100000000+parseInt(value,16)).toString(16).slice(-8);
|
||||
} else {
|
||||
if(loglevel>0)
|
||||
console.log('unrecognised parameters:',params);
|
||||
@ -313,9 +325,9 @@ function drawSeg(ctx, seg){
|
||||
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('<>?npZzx'.indexOf(c)==-1) return;
|
||||
if((c=='Z'||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();
|
||||
|
Loading…
Reference in New Issue
Block a user