Merging changes for testprogram, and various fixes from Ed

This commit is contained in:
Barry Silverman 2010-10-07 08:15:07 -04:00
commit dc0fb1ef06
4 changed files with 92 additions and 23 deletions

View File

@ -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() {

View File

@ -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') +
'-' +
'&#8209' + // 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
View 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
];

View File

@ -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();