mirror of
https://github.com/trebonian/visual6502.git
synced 2024-06-15 09:29:38 +00:00
first cut of ijor's 6800
This commit is contained in:
parent
1d21f5ae8b
commit
8f5f50d197
71
chip-6800/nodenames.js
Normal file
71
chip-6800/nodenames.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011 Ijor, Segher Boessenkool, Ed Spittles
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var nodenames ={
|
||||||
|
gnd: 663, // pads: ground
|
||||||
|
vcc: 31, // pads: power
|
||||||
|
phi1: 1507, // pads: phase 1 clock input
|
||||||
|
phi2: 1511, // pads: phase 2 clock input
|
||||||
|
reset: 1461, // pads: reset
|
||||||
|
db0: 686, // pads: data bus
|
||||||
|
db1: 683,
|
||||||
|
db2: 677,
|
||||||
|
db3: 676,
|
||||||
|
db4: 669,
|
||||||
|
db5: 670,
|
||||||
|
db6: 664,
|
||||||
|
db7: 691,
|
||||||
|
ab0: 1854, // pads: address bus
|
||||||
|
ab1: 1857,
|
||||||
|
ab2: 1855,
|
||||||
|
ab3: 1858,
|
||||||
|
ab4: 1856,
|
||||||
|
ab5: 1859,
|
||||||
|
ab6: 1860,
|
||||||
|
ab7: 1865,
|
||||||
|
ab8: 1861,
|
||||||
|
ab9: 1863,
|
||||||
|
ab10: 1862,
|
||||||
|
ab11: 1864,
|
||||||
|
ab12: 1948,
|
||||||
|
ab13: 1946,
|
||||||
|
ab14: 1949,
|
||||||
|
ab15: 1947,
|
||||||
|
irq: 1496, // input pads: interrupt request (active low)
|
||||||
|
nmi: 1501, // pads: non maskable interrupt (active low)
|
||||||
|
dbe: 1456, // pads: data bus enable
|
||||||
|
halt: 1492, // pads: halt (active low)
|
||||||
|
tsc: 1459, // pads: tristate control
|
||||||
|
rw: 1965, // output pads: read / not write
|
||||||
|
vma: 1971, // pads: valid memory address
|
||||||
|
ba: 1964, // pads: bus available
|
||||||
|
//
|
||||||
|
|
||||||
|
ir0: 1302, // internal state: Instruction Register
|
||||||
|
ir1: 1290,
|
||||||
|
ir2: 1296,
|
||||||
|
ir3: 1297,
|
||||||
|
ir4: 1298,
|
||||||
|
ir5: 1299,
|
||||||
|
ir6: 1278,
|
||||||
|
ir7: 1279,
|
||||||
|
}
|
9818
chip-6800/segdefs.js
Normal file
9818
chip-6800/segdefs.js
Normal file
File diff suppressed because one or more lines are too long
128
chip-6800/support.js
Normal file
128
chip-6800/support.js
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// chip-specific support functions
|
||||||
|
//
|
||||||
|
// may override function definitions made previously
|
||||||
|
|
||||||
|
chipname='6800';
|
||||||
|
|
||||||
|
grChipSize=7000;
|
||||||
|
|
||||||
|
ngnd = nodenames['gnd'];
|
||||||
|
npwr = nodenames['vcc'];
|
||||||
|
|
||||||
|
nodenamereset = 'reset';
|
||||||
|
|
||||||
|
presetLogLists=[
|
||||||
|
['cycle','phi1','phi2'],
|
||||||
|
['ab','db','rw','pc','a','b'],
|
||||||
|
['ir'],
|
||||||
|
['irq','nmi',nodenamereset],
|
||||||
|
];
|
||||||
|
|
||||||
|
function setupTransistors(){
|
||||||
|
for(i in transdefs){
|
||||||
|
var tdef = transdefs[i];
|
||||||
|
var name = tdef[0];
|
||||||
|
var gate = tdef[1];
|
||||||
|
var c1 = tdef[2];
|
||||||
|
var c2 = tdef[3];
|
||||||
|
var bb = tdef[4];
|
||||||
|
if(tdef[6])
|
||||||
|
// just ignore all the 'weak' transistors for now
|
||||||
|
continue;
|
||||||
|
if(c1==ngnd) {c1=c2;c2=ngnd;}
|
||||||
|
if(c1==npwr) {c1=c2;c2=npwr;}
|
||||||
|
var trans = {name: name, on: false, gate: gate, c1: c1, c2: c2, bb: bb};
|
||||||
|
nodes[gate].gates.push(trans);
|
||||||
|
nodes[c1].c1c2s.push(trans);
|
||||||
|
nodes[c2].c1c2s.push(trans);
|
||||||
|
transistors[name] = trans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// simulate a single clock phase with no update to graphics or trace
|
||||||
|
function halfStep(){
|
||||||
|
var clk = isNodeHigh(nodenames['phi2']);
|
||||||
|
eval(clockTriggers[cycle]);
|
||||||
|
if (clk) {setLow('phi2'); handleBusRead(); setHigh('phi1'); }
|
||||||
|
else {setHigh('phi1'); setLow('phi1'); setHigh('phi2'); handleBusWrite();}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initChip(){
|
||||||
|
var start = now();
|
||||||
|
for(var nn in nodes) {
|
||||||
|
nodes[nn].state = false;
|
||||||
|
nodes[nn].float = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes[ngnd].state = false;
|
||||||
|
nodes[ngnd].float = false;
|
||||||
|
nodes[npwr].state = true;
|
||||||
|
nodes[npwr].float = false;
|
||||||
|
for(var tn in transistors) transistors[tn].on = false;
|
||||||
|
setLow(nodenamereset);
|
||||||
|
setHigh('phi1'); setLow('phi2');
|
||||||
|
setHigh('dbe'); setLow('tsc'); setHigh('halt');
|
||||||
|
setHigh('irq'); setHigh('nmi');
|
||||||
|
recalcNodeList(allNodes());
|
||||||
|
for(var i=0;i<8;i++){setLow('phi1'); setHigh('phi2'); setLow('phi2'); setHigh('phi1');}
|
||||||
|
setHigh(nodenamereset);
|
||||||
|
for(var i=0;i<18;i++){halfStep();} // avoid updating graphics and trace buffer before user code
|
||||||
|
refresh();
|
||||||
|
cycle = 0;
|
||||||
|
trace = Array();
|
||||||
|
if(typeof expertMode != "undefined")
|
||||||
|
updateLogList();
|
||||||
|
chipStatus();
|
||||||
|
if(ctrace)console.log('initChip done after', now()-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBusRead(){
|
||||||
|
if(isNodeHigh(nodenames['rw'])){
|
||||||
|
var a = readAddressBus();
|
||||||
|
var d = eval(readTriggers[a]);
|
||||||
|
if(d == undefined)
|
||||||
|
d = mRead(readAddressBus());
|
||||||
|
// we have no SYNC pin on 6800
|
||||||
|
// if(isNodeHigh(nodenames['sync']))
|
||||||
|
// eval(fetchTriggers[d]);
|
||||||
|
writeDataBus(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function chipStatus(){
|
||||||
|
var ab = readAddressBus();
|
||||||
|
var machine1 =
|
||||||
|
' halfcyc:' + cycle +
|
||||||
|
' phi0:' + readBit('phi2') +
|
||||||
|
' AB:' + hexWord(ab) +
|
||||||
|
' D:' + hexByte(readDataBus()) +
|
||||||
|
' RnW:' + readBit('rw');
|
||||||
|
/* 6800 machine state names are not in place yet */
|
||||||
|
var machine2 = ''
|
||||||
|
var machine3 = ''
|
||||||
|
/*
|
||||||
|
var machine2 =
|
||||||
|
' PC:' + hexWord(readPC()) +
|
||||||
|
' A:' + hexByte(readA()) +
|
||||||
|
' X:' + hexByte(readX()) +
|
||||||
|
' Y:' + hexByte(readY()) +
|
||||||
|
' SP:' + hexByte(readSP()) +
|
||||||
|
' ' + readPstring();
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
35
chip-6800/testprogram.js
Normal file
35
chip-6800/testprogram.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// This file testprogram.js can be substituted by one of several tests
|
||||||
|
testprogramAddress=0x0000;
|
||||||
|
|
||||||
|
// we want to auto-clear the console if any output is sent by the program
|
||||||
|
var consoleboxStream="";
|
||||||
|
|
||||||
|
// for opcodes, see ftp://ftp.comlab.ox.ac.uk/pub/Cards/txt/6800.txt
|
||||||
|
|
||||||
|
testprogram = [
|
||||||
|
0x86, 0x00, 0x9d, 0x10, 0x7e, 0x00, 0x02, 0x08, 0x5a, 0x7c, 0x00,
|
||||||
|
0x0f, 0x0d, 0x89, 0x02, 0x39,
|
||||||
|
]
|
||||||
|
|
||||||
|
// Crasm LYB 1.3: page 1
|
||||||
|
// 1 CPU 6800
|
||||||
|
// 2
|
||||||
|
// 0000 3 * = 0
|
||||||
|
// 4
|
||||||
|
// 5 CODE
|
||||||
|
// 6
|
||||||
|
// 0000 8600 7 LDAA #$00
|
||||||
|
// 0002 9D10 8 JSR $0010
|
||||||
|
// 0004 7E0002 9 JMP $0002
|
||||||
|
// 0007 08 10 INX
|
||||||
|
// 0008 5A 11 DECB
|
||||||
|
// 0009 7C000F 12 INC $0F
|
||||||
|
// 000C 0D 13 SEC
|
||||||
|
// 000D 8902 14 ADCA #$02
|
||||||
|
// 000F 39 15 RTS
|
||||||
|
// 16
|
||||||
|
// ERRORS: 0
|
||||||
|
// WARNINGS: 0
|
||||||
|
// Successful assembly...
|
||||||
|
// Last address f (15)
|
||||||
|
// Code length 20 (32)
|
3598
chip-6800/transdefs.js
Normal file
3598
chip-6800/transdefs.js
Normal file
File diff suppressed because it is too large
Load Diff
153
expert-6800.html
Normal file
153
expert-6800.html
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Visual 6800 in JavaScript</title>
|
||||||
|
<style type="text/css">@import "expert.css";</style>
|
||||||
|
<script src="chip-6800/segdefs.js"></script>
|
||||||
|
<script src="chip-6800/transdefs.js"></script>
|
||||||
|
<script src="chip-6800/nodenames.js"></script>
|
||||||
|
<script src="wires.js"></script>
|
||||||
|
<script src="expertWires.js"></script>
|
||||||
|
<script src="chipsim.js"></script>
|
||||||
|
<script src="memtable.js"></script>
|
||||||
|
<script src="macros.js"></script>
|
||||||
|
<script src="chip-6800/support.js"></script>
|
||||||
|
<script src="chip-6800/testprogram.js"></script>
|
||||||
|
<script src="3rdparty/jquery-1.3.2.min.js"></script>
|
||||||
|
<script src="3rdparty/jquery.cookie.js"></script>
|
||||||
|
<script src="3rdparty/splitter.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function handleOnload() {
|
||||||
|
/MSIE (\d+\.\d+);/.test(navigator.appVersion);
|
||||||
|
IEVersion=Number(RegExp.$1);
|
||||||
|
if((navigator.appName == 'Microsoft Internet Explorer') && (IEVersion<9)){
|
||||||
|
document.getElementById('browsertrouble').innerHTML=
|
||||||
|
'<p>Sorry, '+navigator.appName+' not supported - showing you a picture instead!</p>';
|
||||||
|
document.getElementById('frame').innerHTML='<a href="browsertrouble.html"><img src="images/jssim2.png" style="border:10px"></a>';
|
||||||
|
}else{
|
||||||
|
setTimeout(setup,200);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// initialise splitter (built on jquery)
|
||||||
|
$().ready(function(){
|
||||||
|
$("#frame").splitter({
|
||||||
|
type: "v",
|
||||||
|
outline: true,
|
||||||
|
minLeft: 20,
|
||||||
|
sizeLeft: 810,
|
||||||
|
resizeToWidth: true,
|
||||||
|
anchorToWindow: true,
|
||||||
|
});
|
||||||
|
$("#rightcolumn").splitter({
|
||||||
|
type: "h",
|
||||||
|
outline: true,
|
||||||
|
sizeBottom: 180,
|
||||||
|
minTop: 100,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="handleOnload();">
|
||||||
|
<span id="plain">
|
||||||
|
<a href="http://www.visual6502.org/faq.html">FAQ</a>
|
||||||
|
<a href="http://blog.visual6502.org">Blog</a>
|
||||||
|
<a href="http://www.visual6502.org/links.html">Links</a>
|
||||||
|
<a href="http://github.com/trebonian/visual6502">Source</a>
|
||||||
|
<a href="ftp://ftp.comlab.ox.ac.uk/pub/Cards/txt/6800.txt">6800 instruction card</a>
|
||||||
|
<a href="http://www.sbprojects.com/sbasm/6800.htm#model">programming model</a>
|
||||||
|
</span>
|
||||||
|
<div class="frame" id="frame">
|
||||||
|
<div class="leftcolumn" id="leftcolumn">
|
||||||
|
<div id="chipsurround" tabindex="1">
|
||||||
|
<div class="chip" id="chip">
|
||||||
|
<span id="waiting">Please wait, graphics initialising...</span>
|
||||||
|
<canvas class="chip" id="chipbg"></canvas>
|
||||||
|
<canvas class="chip" id="overlay"></canvas>
|
||||||
|
<canvas class="chip" id="hilite"></canvas>
|
||||||
|
<canvas class="chip" id="hitbuffer"></canvas>
|
||||||
|
</div>
|
||||||
|
</div> <!-- chipsurround -->
|
||||||
|
<div class="nochip" id="nochip">
|
||||||
|
<form>
|
||||||
|
<input type="button" value="Show chip layout" onclick="updateChipLayoutVisibility(true)" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="layoutControlPanel">
|
||||||
|
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)
|
||||||
|
<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="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();">
|
||||||
|
<input type="button" value="Find:" onclick="hiliteNodeList();" />
|
||||||
|
<input type="text" id="HighlightThese" name="HighlightThese" value="" />
|
||||||
|
<input type="button" value="Clear Highlighting" onclick="clearHighlight();" />
|
||||||
|
<span class="animatebox">
|
||||||
|
Animate during simulation:
|
||||||
|
<input type="checkbox" id="animateModeCheckbox" onchange="updateChipLayoutAnimation(this.checked)"
|
||||||
|
/></span>
|
||||||
|
</form>
|
||||||
|
<form>
|
||||||
|
<input type="button" value="Hide Chip Layout" onclick="updateChipLayoutVisibility(false)" />
|
||||||
|
<a href="" id="linkHere" >Link to this location</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div> <!-- closing leftcolumn -->
|
||||||
|
<div class="rightcolumn" id="rightcolumn">
|
||||||
|
<div id="righttopdiv">
|
||||||
|
<div class = "buttons">
|
||||||
|
<div class="twobuttons">
|
||||||
|
<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 class="morebuttons">
|
||||||
|
<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="forward"></a>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div> <!-- buttons -->
|
||||||
|
<div class="status" id="status"><p>x: 0<br>y: 0</p>
|
||||||
|
</div> <!-- status -->
|
||||||
|
|
||||||
|
<div id="memtablediv">
|
||||||
|
<table class="memtable" id="memtable" tabindex="2"></table>
|
||||||
|
</div>
|
||||||
|
</div> <!-- righttopdiv -->
|
||||||
|
|
||||||
|
<div id="tracingdiv">
|
||||||
|
<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)" />
|
||||||
|
<input type="button" value="Trace these too:" onclick="updateLogList()" />
|
||||||
|
<input type="text" id="LogThese" name="LogThese" value="" />
|
||||||
|
<input type="button" value="Log Up/Down" onclick="updateLogDirection();" />
|
||||||
|
<input type="button" value="Clear Log" onclick="updateLoglevel(loglevel)" />
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
<div id="logstreamscroller">
|
||||||
|
<table class="logstream" id="logstream"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- closing rightcolumn -->
|
||||||
|
</div> <!-- closing 'frame' div -->
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user