107 Commits
V0.5 ... svg

Author SHA1 Message Date
020f4f2cb0 Merge branch 'ed' into svg 2013-06-26 17:23:51 -04:00
741e035eb4 Merge branch 'patch-1' of http://github.com/BigEd/visual6502 into ed 2013-06-26 17:23:14 -04:00
f0add78ee5 Merge branch 'ed' into svg 2013-06-25 17:25:09 -04:00
dd2241d3de bugfix - macros.js - pre-apply clock triggers for corrected display 2013-06-25 22:31:53 +02:00
c0809ba34e typo fixup in README 2013-06-24 18:53:07 +02:00
7d90b33187 Merge pull request #28 from BigEd/patch-1
Correcting a comment in nodenames.js
2013-02-04 06:02:05 -08:00
34244661cb Correcting a comment in nodenames.js
Thanks to 'cerebrum' on forum.6502.org
2013-02-03 10:19:22 +00:00
ce74c3f5d3 Swap easy6502 tutorial in for 6502asm emulator/assembler 2012-08-16 07:52:17 +01:00
471fcd6ddc Performance improvements 2012-02-03 22:18:43 -05:00
7ac0424f6c Only redraw if node state changes 2012-02-03 22:05:42 -05:00
050906f305 Use SVG DOM to highlight nodes 2012-02-03 21:42:34 -05:00
ae185ff06b Changed chip layout to use SVGs 2012-01-31 22:58:22 -05:00
cb03b9741a html fixups by Quietust 2011-08-27 03:34:25 +02:00
7b95b5e345 html tidyup by Quietust 2011-08-27 03:29:23 +02:00
de265ecdb8 6502: add nodename aliases to allow more use of the URL interface 2011-05-12 08:54:52 +00:00
e81c9fbe0f update 6800 tracing to include alu and incrementer 2011-04-16 13:03:43 +00:00
c300e6ad01 update 6800 nodenames: ordering, comments, minor corrections 2011-04-16 13:02:46 +00:00
79d0c4c445 import remainder of Segher's 6800 nodename updates and begin process of ordering and commenting 2011-04-16 11:29:53 +00:00
a2d35d54ca 6800 nodename changes from Segher 2011-04-16 10:58:16 +00:00
e20eb08b91 updated 6800 transistor bounding boxes and geometries from Ijor 2011-04-12 18:08:51 +00:00
8487a7a9e1 6800: tweak nodenames and add the Tf state name/node 2011-04-11 18:22:26 +00:00
6c138a4f6b add 6800 timing state to tabulation 2011-04-11 14:07:51 +00:00
658d40646c add 6800 timing state signals 2011-04-11 13:51:37 +00:00
67e15e68c1 fixup comment in transdefs about geometry 2011-04-09 10:33:18 +00:00
a316831100 update comments at head of transdefs 2011-04-09 10:12:53 +00:00
acd7b0310e Edited chip-6800/transdefs.js via GitHub 2011-04-09 17:57:45 +08:00
9331be20fe allow tabulations with loglevel 0 (with only additional signals) 2011-04-06 18:13:04 +00:00
e6d42eb1aa 6800 declutter - remove clock phases from tabulated signals 2011-04-05 19:45:33 +00:00
8ae5c087f6 fixup missing assignments causing errors 2011-04-05 18:29:49 +00:00
c6dd03ba17 fixup 6800 test program 2011-04-05 18:09:53 +00:00
fca2eb5cb6 fixup 6800 pre-reset delay 2011-04-05 18:09:38 +00:00
b5c1759f32 improve 6800 machine state display 2011-04-02 08:01:09 +00:00
6ceae74e4a 6800 fixup single stepping 2011-04-02 07:57:15 +00:00
94b306bace update 6800 machine state readout 2011-04-01 20:57:42 +00:00
9308b26c42 update 6800 loglevel definitions 2011-04-01 20:12:22 +00:00
335cb06832 update 6800 segdefs to add missing pullups 2011-04-01 20:11:51 +00:00
d9440fa160 6800: fixup bus reads, add annotation for unassigned opcodes 2011-04-01 18:44:12 +00:00
10ba01cf12 fixup 6800 disassembly 2011-04-01 17:55:49 +00:00
e8b964a24f fixup 6800 IR nodenames 2011-04-01 17:55:30 +00:00
bbfcf77134 update 6800 nodenames and trace signals 2011-04-01 17:32:01 +00:00
73f21ffc47 update 6800 test program 2011-04-01 17:31:30 +00:00
4e2c84dabc update 6800 test program and add opcode map 2011-04-01 16:05:41 +00:00
ca7124b176 6800: treat dbe as phi2 clock in 2011-04-01 14:40:56 +00:00
b0710a4cda trying to clean up gh-pages 2011-04-01 11:59:22 +00:00
baac06bdc3 Merge branch 'gh-pages' of git@github.com:BigEd/visual6502 into gh-pages 2011-04-01 11:57:47 +00:00
9bb8caa025 update README 2011-04-01 11:50:04 +00:00
b98010206e trying to clean up gh-pages 2011-04-01 11:40:21 +00:00
7049cef9b7 update README 2011-04-01 11:38:37 +00:00
9d23382644 trying to clean up gh-pages 2011-04-01 11:34:02 +00:00
8f5f50d197 first cut of ijor's 6800 2011-04-01 11:19:42 +00:00
1d21f5ae8b few small changes to prepare for multi-chip capability 2011-04-01 11:17:34 +00:00
15b25491b9 nodename adjustments and additions 2011-02-20 20:06:29 +00:00
6033109dc6 adjust pclp and pchp to pickup non inverted state 2011-02-15 20:04:08 +00:00
0e41f0a9a9 [bug]fixup misnumbered node abl7 2011-02-15 19:54:06 +00:00
cb29fb4fad readjust timing of URL-scheduled events to match published version 2011-01-10 10:45:52 +00:00
c02d181d5c add more nodenames from Segher 2011-01-09 20:32:51 +00:00
51d0e99389 add ability to override the databus by URL 2011-01-09 16:18:01 +00:00
d11cf44ae9 add ability to sequence RDY pin from the URL 2011-01-09 13:10:13 +00:00
2e69d3a7c3 fix: allow coincident pin events 2011-01-09 13:09:25 +00:00
f098566335 Hilited nodes toggle state when stepped or run 2011-01-03 15:17:27 -05:00
e25ac6243c fixup merge conflict markers 2010-12-23 19:15:30 +00:00
94e22becb4 fixup expert.html consolidation 2010-12-23 19:00:05 +00:00
a56ee40bd8 attempt to get gh-pages into shape 2010-12-23 18:59:02 +00:00
2ace0e8bad try consolidating into just 2 files for efficient loading 2010-12-23 18:14:58 +00:00
84b005673b give the names of the nodes in a shift-click group, if they have names 2010-12-22 21:16:50 +00:00
09c578e361 shift-click: list members of channel-connected nodegroup 2010-12-21 22:31:38 +00:00
167f93f836 feature: URL can define labels and optional boxes 2010-12-20 19:30:49 +00:00
c88e0749cf feature: add support for box and label in highlight layer 2010-12-20 19:00:44 +00:00
6db8836c5c feature: find matches names on underscore-delimited components 2010-12-19 18:31:10 +00:00
27fb1d539e bugfix: shift-click to highlight a pass-connected node-group should work on gates too 2010-12-19 17:54:37 +00:00
21c7a8ca90 bugfix: zoom-to-fit on found objects needed an x offset 2010-12-19 17:41:16 +00:00
cfb726d0e7 Merge branch 'master' of git://github.com/trebonian/visual6502 2010-12-19 17:24:35 +00:00
d352501c7c update the "link here" to include searched objects 2010-12-19 17:24:14 +00:00
4eb1e4c848 Fix protection bits on some files 2010-12-19 12:04:35 -05:00
c3f0d10199 Merge branches 'ed' and 'master' into ed 2010-12-19 12:01:44 -05:00
4398fdaddf Added Bends and Gate Area to transdefs 2010-12-19 10:38:31 -05:00
4f7930eef3 Fix Shift Click which broke in performance improvement changes 2010-12-19 10:37:51 -05:00
c04f37a3df add feature: click can highlight transistors 2010-12-19 12:45:44 +00:00
fc664c7243 Merge branch 'master' of git://github.com/trebonian/visual6502 2010-12-18 11:30:06 +00:00
8bdb9a0682 New transdefs with Gate Bounding Box and Geometry 2010-12-17 21:35:19 -05:00
ae30a57822 Merge branch 'master' of git://github.com/trebonian/visual6502 2010-12-12 18:22:13 +00:00
8a89310e96 Fix expert mode's keyboard handling too. 2010-12-08 06:53:38 +08:00
1c66a8af28 handleKey(): if .charCode is undefined, use .keyCode (Opera compatible.) 2010-12-08 06:53:37 +08:00
78deb4aaa4 fixup nodenames type 2010-12-07 22:49:38 +00:00
85c8447064 Fix expert mode's keyboard handling too. 2010-12-05 12:34:39 +01:00
6cdbfc0c15 handleKey(): if .charCode is undefined, use .keyCode (Opera compatible.) 2010-12-05 09:50:00 +01:00
8ef98d131f added signal names - mostly ALU - from Segher 2010-12-04 17:05:24 +00:00
e660736204 fixup status message when no find command in URL 2010-12-03 16:28:55 +00:00
fc46e50289 add "find" mechanism to URL 2010-12-03 13:35:01 +00:00
4967b58e7f update status box when find is used 2010-12-03 12:46:10 +00:00
6f7dab7990 more nodenames from Segher: alu internals 2010-12-03 12:27:26 +00:00
04196aa36a more nodenames from Segher: decimal mode and carry chain 2010-12-03 12:14:18 +00:00
94a2b38d27 import more signal names from Segher 2010-11-30 21:15:49 +00:00
e052255c55 add first cut of zooming to fit found objects: transistors and nodes. Renamed "Highlight:" button to "Find:" 2010-11-29 20:07:29 +00:00
15453f4435 Merge branch 'ed' 2010-11-28 16:38:32 -05:00
7572b25453 Hilite transistors 2010-11-28 16:37:02 -05:00
8f2e296ef6 update git project pages with placeholder/redirect empty content 2010-11-22 13:42:46 +00:00
ee2fa1befd removing gh-pages project preview 2010-11-22 13:41:40 +00:00
7c50999c9e Merge branch 'gh-pages' of git@github.com:BigEd/visual6502 into gh-pages 2010-11-22 13:40:15 +00:00
abf6daef7d Merge branch 'master' into gh-pages 2010-11-19 22:42:58 +00:00
3bf9ae1fac Merge branch 'master' into gh-pages 2010-11-09 21:26:10 +00:00
c4af64f5e8 Merge branch 'master' into gh-pages 2010-11-09 20:32:27 +00:00
82daddcfe4 Merge branch 'master' into gh-pages 2010-11-08 22:29:26 +00:00
50ecadaa00 Merge branch 'master' into gh-pages 2010-11-08 22:18:24 +00:00
8a2342d83c Merge branch 'master' into gh-pages 2010-11-08 22:04:12 +00:00
60b4ecab22 Merge branch 'master' into gh-pages 2010-11-08 09:17:38 +00:00
9ff6ae027e note nature of this temporary export branch in the HTML 2010-11-06 17:59:40 +00:00
18 changed files with 34867 additions and 3652 deletions

2
6502N.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.6 MiB

4
README
View File

@ -1,9 +1,11 @@
This is the javascript simulator from the visual5602.org project:
This is the JavaScript simulator from the visual5602.org project:
www.visual6502.org/JSSim
It includes a general purpose transistor-level simulator, layout browser,
and the data from a 6502 revD chip.
Recently added: polygon data for the 6800 chip. The simulation is not yet working,
Note the various licenses and Copyright associated with each file.
Enjoy!

1222
chip-6800/nodenames.js Normal file

File diff suppressed because it is too large Load Diff

9818
chip-6800/segdefs.js Normal file

File diff suppressed because one or more lines are too long

486
chip-6800/support.js Normal file
View File

@ -0,0 +1,486 @@
// chip-specific support functions
//
// may override function definitions made previously
chipname='6800';
grChipSize=7000;
ngnd = nodenames['gnd'];
npwr = nodenames['vcc'];
nodenamereset = 'reset';
presetLogLists=[
['cycle',],
['ab','db','rw','vma','Fetch','pc','acca','accb','ix','sp','p'],
['ir','sync','Execute','State'], // instruction fetch and execution control
['dbi','dbo','tmp','sum','inc'], // internal register-sized state
['idb','abh','abl','ablx'], // internal datapath busses
['irq','nmi',nodenamereset,'tsc','dbe','halt','ba'], // other pins
];
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'); setLow('dbe'); setHigh('phi1'); handleBusRead(); }
else {setHigh('phi1'); setLow('phi1'); setHigh('phi2'); setHigh('dbe'); handleBusWrite();}
}
function goUntilSyncOrWrite(){
halfStep();
cycle++;
while(
!isNodeHigh(nodenames['phi2']) ||
( !isNodeHigh(nodenames['sync']) && isNodeHigh(nodenames['rw']) )
) {
halfStep();
cycle++;
}
chipStatus();
}
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'); setLow('dbe');
setHigh('dbe'); setLow('tsc'); setHigh('halt');
setHigh('irq'); setHigh('nmi');
recalcNodeList(allNodes());
for(var i=0;i<8;i++){
setLow('phi1');
setHigh('phi2'); setHigh('dbe');
setLow('phi2'); setLow('dbe');
setHigh('phi1');
}
setHigh(nodenamereset);
for(var i=0;i<6;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());
if(isNodeHigh(nodenames['sync']))
eval(fetchTriggers[d]);
writeDataBus(d);
}
}
function readAccA(){return readBits('acca', 8);}
function readAccB(){return readBits('accb', 8);}
function readIX(){return (readBits('ixh', 8)<<8) + readBits('ixl', 8);}
function readSP(){return (readBits('sph', 8)<<8) + readBits('spl', 8);}
function readPstring(){
var result;
result = '&#8209' + // non-breaking hyphen
'&#8209' + // non-breaking hyphen
(isNodeHigh(nodenames['flagh'])?'H':'h') +
(isNodeHigh(nodenames['flagi'])?'I':'i') +
(isNodeHigh(nodenames['flagn'])?'N':'n') +
(isNodeHigh(nodenames['flagz'])?'Z':'z') +
(isNodeHigh(nodenames['flagv'])?'V':'v') +
(isNodeHigh(nodenames['flagc'])?'C':'c');
return result;
}
// The 6800 state control is something like a branching shift register
// ... but not quite like that
TCStates=[
"Ts", "Tf",
"Tx0", "Tx1", "Tx2",
"Ta0", "Ta1", "Ta2",
"Td0_0",
"#Te0", "Te1_0",
"Tg0", "Tg1", "Tg2", "Tg3", "Tg4", "Tg5", "Tg6", "Tg7", "Tg8",
"Tr3", "Tr4", "Tr5", "Tr6", "Tr7", "Tr8",
];
function listActiveTCStates() {
var s=[];
for(var i=0;i<TCStates.length;i++){
var t=TCStates[i];
// remove a leading hash, but invert the signal
// in any case, remove any trailing suffix
if(t[0]=="#"){
if(!isNodeHigh(nodenames[t])) s.push(t.slice(1,4));
} else {
if(isNodeHigh(nodenames[t])) s.push(t.slice(0,3));
}
}
return s.join("+");
}
function busToString(busname){
// takes a signal name or prefix
// returns an appropriate string representation
// some 'signal names' are CPU-specific aliases to user-friendly string output
if(busname=='cycle')
return cycle>>1;
if(busname=='pc')
return busToHex('pch') + busToHex('pcl');
if(busname=='sp')
return busToHex('sph') + busToHex('spl');
if(busname=='ix')
return busToHex('ixh') + busToHex('ixl');
if(busname=='inc')
return busToHex('inch') + busToHex('incl');
if(busname=='p')
return readPstring();
if(busname=='State')
return listActiveTCStates();
if(busname=='Execute')
return disassemblytoHTML(readBits('ir',8));
if(busname=='Fetch')
return isNodeHigh(nodenames['sync'])?disassemblytoHTML(readDataBus()):"";
if(busname=='plaOutputs')
// 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);
}
}
function chipStatus(){
var ab = readAddressBus();
var machine1 =
' halfcyc:' + cycle +
' phi0:' + readBit('phi2') +
' AB:' + hexWord(ab) +
' D:' + hexByte(readDataBus()) +
' RnW:' + readBit('rw') +
' VMA:' + readBit('vma');
var machine2 =
' PC:' + hexWord(readPC()) +
' A:' + hexByte(readAccA()) +
' B:' + hexByte(readAccB()) +
' IX:' + hexWord(readIX()) +
' SP:' + hexWord(readSP()) +
' ' + readPstring();
var machine3 =
'Hz: ' + estimatedHz().toFixed(1);
if(typeof expertMode != "undefined") {
machine3 += ' Exec: ' + busToString('Execute'); // no T-state info for 6800 yet
if(isNodeHigh(nodenames['sync']))
machine3 += ' (Fetch: ' + busToString('Fetch') + ')';
if(goldenChecksum != undefined)
machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
}
setStatus(machine1, machine2, machine3);
if (logThese.length>1) {
updateLogbox(logThese);
}
selectCell(ab);
}
// javascript derived from http://segher.ircgeeks.net/6800/OPS
var disassembly={
0x00: "!",
0x01: "nop",
0x02: "!",
0x03: "!",
0x04: "!",
0x05: "!",
0x06: "tap",
0x07: "tpa",
0x10: "sba",
0x11: "cba",
0x12: "!",
0x13: "!",
0x14: "!nba",
0x15: "!",
0x16: "tab",
0x17: "tba",
0x20: "bra N",
0x21: "!",
0x22: "bhi N",
0x23: "bls N",
0x24: "bcc N",
0x25: "bcs N",
0x26: "bne N",
0x27: "beq N",
0x30: "tsx",
0x31: "ins",
0x32: "pul a",
0x33: "pul b",
0x34: "des",
0x35: "txs",
0x36: "psh a",
0x37: "psh b",
0x40: "neg a",
0x41: "!",
0x42: "!",
0x43: "com a",
0x44: "lsr a",
0x45: "!",
0x46: "ror a",
0x47: "asr a",
0x50: "neg b",
0x51: "!",
0x52: "!",
0x53: "com b",
0x54: "lsr b",
0x55: "!",
0x56: "ror b",
0x57: "asr b",
0x60: "neg Nx",
0x61: "!",
0x62: "!",
0x63: "com Nx",
0x64: "lsr Nx",
0x65: "!",
0x66: "ror Nx",
0x67: "asr Nx",
0x70: "neg NN",
0x71: "!",
0x72: "!",
0x73: "com NN",
0x74: "lsr NN",
0x75: "!",
0x76: "ror NN",
0x77: "asr NN",
0x80: "sub a #",
0x81: "cmp a #",
0x82: "sbc a #",
0x83: "!",
0x84: "and a #",
0x85: "bit a #",
0x86: "lda a #",
0x87: "!",
0x90: "sub a N",
0x91: "cmp a N",
0x92: "sbc a N",
0x93: "!",
0x94: "and a N",
0x95: "bit a N",
0x96: "lda a N",
0x97: "sta a N",
0xa0: "sub a Nx",
0xa1: "cmp a Nx",
0xa2: "sbc a Nx",
0xa3: "!",
0xa4: "and a Nx",
0xa5: "bit a Nx",
0xa6: "lda a Nx",
0xa7: "sta a Nx",
0xb0: "sub a NN",
0xb1: "cmp a NN",
0xb2: "sbc a NN",
0xb3: "!",
0xb4: "and a NN",
0xb5: "bit a NN",
0xb6: "lda a NN",
0xb7: "sta a NN",
0xc0: "sub b #",
0xc1: "cmp b #",
0xc2: "sbc b #",
0xc3: "!",
0xc4: "and b #",
0xc5: "bit b #",
0xc6: "lda b #",
0xc7: "!",
0xd0: "sub b N",
0xd1: "cmp b N",
0xd2: "sbc b N",
0xd3: "!",
0xd4: "and b N",
0xd5: "bit b N",
0xd6: "lda b N",
0xd7: "sta b N",
0xe0: "sub b Nx",
0xe1: "cmp b Nx",
0xe2: "sbc b Nx",
0xe3: "!",
0xe4: "and b Nx",
0xe5: "bit b Nx",
0xe6: "lda b Nx",
0xe7: "sta b Nx",
0xf0: "sub b NN",
0xf1: "cmp b NN",
0xf2: "sbc b NN",
0xf3: "!",
0xf4: "and b NN",
0xf5: "bit b NN",
0xf6: "lda b NN",
0xf7: "sta b NN",
0x08: "inx",
0x09: "dex",
0x0a: "clv",
0x0b: "sev",
0x0c: "clc",
0x0d: "sec",
0x0e: "cli",
0x0f: "sei",
0x18: "!",
0x19: "daa",
0x1a: "!",
0x1b: "aba",
0x1c: "!",
0x1d: "!",
0x1e: "!",
0x1f: "!",
0x28: "bvc N",
0x29: "bvs N",
0x2a: "bpl N",
0x2b: "bmi N",
0x2c: "bge N",
0x2d: "blt N",
0x2e: "bgt N",
0x2f: "ble N",
0x38: "!",
0x39: "rts",
0x3a: "!",
0x3b: "rti",
0x3c: "!",
0x3d: "!",
0x3e: "wai",
0x3f: "swi",
0x48: "asl a",
0x49: "rol a",
0x4a: "dec a",
0x4b: "!",
0x4c: "inc a",
0x4d: "tst a",
0x4e: "!",
0x4f: "clr a",
0x58: "asl b",
0x59: "rol b",
0x5a: "dec b",
0x5b: "!",
0x5c: "inc b",
0x5d: "tst b",
0x5e: "!",
0x5f: "clr b",
0x68: "asl Nx",
0x69: "rol Nx",
0x6a: "dec Nx",
0x6b: "!",
0x6c: "inc Nx",
0x6d: "tst Nx",
0x6e: "jmp Nx",
0x6f: "clr Nx",
0x78: "asl NN",
0x79: "rol NN",
0x7a: "dec NN",
0x7b: "!",
0x7c: "inc NN",
0x7d: "tst NN",
0x7e: "jmp NN",
0x7f: "clr NN",
0x88: "eor a #",
0x89: "adc a #",
0x8a: "ora a #",
0x8b: "add a #",
0x8c: "cpx ##",
0x8d: "bsr N",
0x8e: "lds ##",
0x8f: "!",
0x98: "eor a N",
0x99: "adc a N",
0x9a: "ora a N",
0x9b: "add a N",
0x9c: "cpx N",
0x9d: "!hcf",
0x9e: "lds N",
0x9f: "sts N",
0xa8: "eor a Nx",
0xa9: "adc a Nx",
0xaa: "ora a Nx",
0xab: "add a Nx",
0xac: "cpx Nx",
0xad: "jsr Nx",
0xae: "lds Nx",
0xaf: "sts Nx",
0xb8: "eor a NN",
0xb9: "adc a NN",
0xba: "ora a NN",
0xbb: "add a NN",
0xbc: "cpx NN",
0xbd: "jsr NN",
0xbe: "lds NN",
0xbf: "sts NN",
0xc8: "eor b #",
0xc9: "adc b #",
0xca: "ora b #",
0xcb: "add b #",
0xcc: "!",
0xcd: "!",
0xce: "ldx ##",
0xcf: "!",
0xd8: "eor b N",
0xd9: "adc b N",
0xda: "ora b N",
0xdb: "add b N",
0xdc: "!",
0xdd: "!hcf",
0xde: "ldx N",
0xdf: "stx N",
0xe8: "eor b Nx",
0xe9: "adc b Nx",
0xea: "ora b Nx",
0xeb: "add b Nx",
0xec: "!",
0xed: "!",
0xee: "ldx Nx",
0xef: "stx Nx",
0xf8: "eor b NN",
0xf9: "adc b NN",
0xfa: "ora b NN",
0xfb: "add b NN",
0xfc: "!",
0xfd: "!",
0xfe: "ldx NN",
0xff: "stx NN",
};

25
chip-6800/testprogram.js Normal file
View File

@ -0,0 +1,25 @@
// 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 = [
0xce, 0x43, 0x21, // LDX #4321
0x35, // TXS
0xc6, 0xfb, // LDAB #$FB
0xbd, 0x00, 0x10, // JSR $0010
0x7e, 0x00, 0x04, // JMP $0004
0x01, // NOP
0x01, // NOP
0x01, // NOP
0x01, // NOP
0x08, // INX
0x4a, // DECA
0x7c, 0x00, 0x0f, // INC $0F
0x0d, // SEC
0xc9, 0x02, // ADCB #$02
0x39, // RTS
]

4017
chip-6800/transdefs.js Executable file

File diff suppressed because it is too large Load Diff

153
expert-6800.html Normal file
View 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>&nbsp;
<a href="http://blog.visual6502.org">Blog</a>&nbsp;
<a href="http://www.visual6502.org/links.html">Links</a>&nbsp;
<a href="http://github.com/trebonian/visual6502">Source</a>&nbsp;
<a href="ftp://ftp.comlab.ox.ac.uk/pub/Cards/txt/6800.txt">6800 instruction card</a>&nbsp;
<a href="http://www.sbprojects.com/sbasm/6800.htm#model">programming model</a>&nbsp;
</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>
&nbsp;
</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>

14858
expert-allinone.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -56,7 +56,7 @@ $().ready(function(){
<a href="http://blog.visual6502.org">Blog</a>&nbsp;
<a href="http://www.visual6502.org/links.html">Links</a>&nbsp;
<a href="http://github.com/trebonian/visual6502">Source</a>&nbsp;
<a href="http://www.6502asm.com/">6502asm assembler</a>&nbsp;
<a href="http://skilldrick.github.com/easy6502/#first-program">easy6502 assembler</a>&nbsp;
<a href="http://www.e-tradition.net/bytes/6502/disassembler.html">e-tradition disassembler</a>&nbsp;
</span>
<div class="frame" id="frame">
@ -76,7 +76,7 @@ $().ready(function(){
</form>
</div>
<div id="layoutControlPanel">
Use 'z' or '>' to zoom in, 'x' or '<' to zoom out, click to probe signals and drag to pan.
Use 'z' or '&gt;' to zoom in, 'x' or '&lt;' 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)
@ -86,7 +86,7 @@ $().ready(function(){
<input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(protection)
</form>
<form action="javascript:hiliteNodeList();">
<input type="button" value="Highlight:" onclick="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">

View File

@ -24,6 +24,8 @@ var centerx=300, centery=300;
var zoom=1;
var dragMouseX, dragMouseY, moved;
var statbox;
var findThese;
var labelThese=[];
// Some constants for the graphics presentation
// the canvas is embedded in an 800x600 clipping div
@ -94,7 +96,7 @@ function setup_part3(){
// which saves a lot of memory and allows us to run on small systems
updateChipLayoutVisibility(true);
}
setStatus('resetting 6502...');
setStatus('resetting ' + chipname + '...');
setTimeout(setup_part4, 0);
}
@ -173,6 +175,14 @@ function setupParams(){
} else if(name=="zoom" && parseInt(value)!=NaN){
zoom=parseInt(value);
} else
// perform a search, highlight and zoom to object(s)
if(name=="find" && value.length>0){
findThese=value;
} else
// affix label with optional box to highlight an area of interest
if(name=="label" && value.length>0){
labelThese.push(value.split(","));
} else
// load a test program: Address, Data and Reset
if(name=="a" && parseInt(value,16)!=NaN){
userAddress=parseInt(value,16);
@ -185,17 +195,25 @@ function setupParams(){
} else
// setup input pin events, breakpoints, watchpoints
if(name=="reset0" && parseInt(value)!=NaN){
clockTriggers[value]="setLow('res');";
clockTriggers[value]=[clockTriggers[value],"setLow(nodenamereset);"].join("");
} else if(name=="reset1" && parseInt(value)!=NaN){
clockTriggers[value]="setHigh('res');";
clockTriggers[value]=[clockTriggers[value],"setHigh(nodenamereset);"].join("");
} else if(name=="irq0" && parseInt(value)!=NaN){
clockTriggers[value]="setLow('irq');";
clockTriggers[value]=[clockTriggers[value],"setLow('irq');"].join("");
} else if(name=="irq1" && parseInt(value)!=NaN){
clockTriggers[value]="setHigh('irq');";
clockTriggers[value]=[clockTriggers[value],"setHigh('irq');"].join("");
} else if(name=="nmi0" && parseInt(value)!=NaN){
clockTriggers[value]="setLow('nmi');";
clockTriggers[value]=[clockTriggers[value],"setLow('nmi');"].join("");
} else if(name=="nmi1" && parseInt(value)!=NaN){
clockTriggers[value]="setHigh('nmi');";
clockTriggers[value]=[clockTriggers[value],"setHigh('nmi');"].join("");
} else if(name=="rdy0" && parseInt(value)!=NaN){
clockTriggers[value]=[clockTriggers[value],"setLow('rdy');"].join("");
} else if(name=="rdy1" && parseInt(value)!=NaN){
clockTriggers[value]=[clockTriggers[value],"setHigh('rdy');"].join("");
} else if(name=="time" && parseInt(value)!=NaN){
eventTime=value;
} else if(name=="databus" && parseInt(value)!=NaN){
clockTriggers[eventTime]=[clockTriggers[eventTime],"writeDataBus(0x"+value+");"].join("");
} else
// run a test program, and optionally check against a golden checksum
if(name=="steps" && parseInt(value)!=NaN){
@ -228,7 +246,7 @@ function updateChipLayoutAnimation(isOn){
// these keyboard actions are primarily for the chip display
function handleKey(e){
var c = e.charCode;
var c = e.charCode || e.keyCode;
c = String.fromCharCode(c);
if('<>?npZzx'.indexOf(c)==-1) return;
if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2);
@ -293,35 +311,141 @@ function recenter(){
top: top+'px',
left: left+'px',
});
document.getElementById('linkHere').href=location.pathname+"?"+whereAmIAsQuery();
updateLinkHere();
}
function updateLinkHere(){
var target = location.pathname + "?nosim=t&";
var findlist = document.getElementById('HighlightThese').value.split(/[\s,]+/).join(",");
if (findlist != "")
target = target + "find=" + findlist + "&";
target = target + whereAmIAsQuery();
document.getElementById('linkHere').href=target;
}
// place a text label on the highlight layer
// with an optional box around an area of interest
// coordinates used are those reported by a click
// for example:
// boxLabel(['PD', 50, 8424, 3536, 9256, 2464])
// boxLabel(['IR', 50, 8432, 2332, 9124, 984])
// boxLabel(['PLA', 100, 1169, 2328, 8393, 934])
// boxLabel(['Y', 50, 2143, 8820, 2317, 5689])
// boxLabel(['X', 50, 2317, 8820, 2490, 5689])
// boxLabel(['S', 50, 2490, 8820, 2814, 5689])
// boxLabel(['ALU', 50, 2814, 8820, 4525, 5689])
// boxLabel(['DAdj', 40, 4525, 8820, 5040, 5689])
// boxLabel(['A', 50, 5040, 8820, 5328, 5689])
// boxLabel(['PC', 50, 5559, 8820, 6819, 5689])
// boxLabel(['ID', 50, 7365, 8820, 7676, 5689])
// boxLabel(['TimC', 40, 600, 1926, 1174, 604])
function flashBoxLabel(args) {
clearHighlight();
var callBack = function(){boxLabel(args);};
setTimeout(callBack, 400);
setTimeout(clearHighlight, 800);
setTimeout(callBack, 1200);
}
function boxLabel(args) {
var text = args[0];
var textsize = args[1];
var thickness = 1+ textsize / 20;
var boxXmin = args[2] * grCanvasSize / grChipSize;
var boxYmin = args[3] * grCanvasSize / grChipSize;
var boxXmax = args[4] * grCanvasSize / grChipSize;
var boxYmax = args[5] * grCanvasSize / grChipSize;
ctx.lineWidth = thickness;
ctx.font = textsize + 'px sans-serif';
ctx.fillStyle = '#ff0'; // yellow
ctx.fillStyle = '#f8f'; // magenta
ctx.fillStyle = '#fff'; // white
ctx.strokeStyle = '#fff'; // white
if(args.length>4){
ctxDrawBox(ctx, boxXmin, boxYmin, boxXmax, boxYmax);
// offset the text label to the interior of the box
boxYmin -= thickness * 2;
}
ctx.strokeStyle = '#fff'; // white
ctx.strokeStyle = '#000'; // black
ctx.lineWidth = thickness*2;
ctx.strokeText(text, boxXmin, boxYmin);
ctx.fillText(text, boxXmin, boxYmin);
}
var highlightThese;
// flash some set of nodes according to user input
// also zoom to fit those nodes (not presently optional)
function hiliteNodeList(){
var tmplist = document.getElementById('HighlightThese').value.split(/[\s,]+/);
if(tmplist.length==0){
if(tmplist.join("").length==0){
// request to highlight nothing, so switch off any signal highlighting
hiliteNode(-1);
return;
}
highlightThese = [];
var seglist=[];
var report="";
for(var i=0;i<tmplist.length;i++){
// get a node number from a signal name or a node number
var name = tmplist[i];
var value = parseInt(tmplist[i]);
if((value!=NaN) && (typeof nodes[name] != "undefined")) {
if((value!=NaN) && (typeof nodes[value] != "undefined")) {
highlightThese.push(value);
report="node: " + value + ' ' + nodeName(value);
for(var s in nodes[value].segs)
seglist.push(nodes[value].segs[s]);
} else if(typeof nodenames[name] != "undefined") {
highlightThese.push(nodenames[name]);
report="node: " + nodenames[name] + ' ' + name;
for(var s in nodes[nodenames[name]].segs)
seglist.push(nodes[nodenames[name]].segs[s]);
} else if(typeof transistors[name] != "undefined") {
// normally we push numbers: a non-number is a transistor name
highlightThese.push(name);
report="transistor: " + name;
seglist.push([
transistors[name].bb[0],transistors[name].bb[2],
transistors[name].bb[1],transistors[name].bb[3]
]);
} else {
// allow match of underscore-delimited components, so
// SUMS and dpc17 both match the node dpc17_SUMS
for(var i in nodenames){
re=new RegExp("(^" + name + "_|_" + name + "$)");
if (re.test(i)){
value = nodenames[i];
highlightThese.push(value);
report="node: " + value + ' ' + nodeName(value);
for(var s in nodes[value].segs)
seglist.push(nodes[value].segs[s]);
break;
}
}
}
// invalid input: how to tell the user?
}
if(highlightThese.length==0){
// all input rejected: how to tell the user?
setStatus('Find: nothing found!','(Enter a list of nodenumbers, names or transistor names)');
return;
} else if (highlightThese.length==1){
setStatus('Find results:',report);
} else {
setStatus('Find: multiple objects found','(' + highlightThese.length + ' objects)');
}
var xmin=seglist[0][0], xmax=seglist[0][0];
var ymin=seglist[0][1], ymax=seglist[0][1];
for(var s in seglist){
for(var i=0;i<seglist[s].length;i+=2){
if(seglist[s][i]<xmin) xmin=seglist[s][i];
if(seglist[s][i]>xmax) xmax=seglist[s][i];
if(seglist[s][i+1]<ymin) ymin=seglist[s][i+1];
if(seglist[s][i+1]>ymax) ymax=seglist[s][i+1];
}
}
zoomToBox(xmin,xmax,ymin,ymax);
updateLinkHere();
clearHighlight(); // nullify the simulation overlay (orange/purple)
hiliteNode(-1); // unhighlight all nodes
setTimeout("hiliteNode(highlightThese);", 400);
@ -329,23 +453,54 @@ function hiliteNodeList(){
setTimeout("hiliteNode(highlightThese);", 1200);
}
// some notes on coordinates:
// the localx and localy functions return canvas coordinate offsets from the canvas window top left corner
// we divide the results by 'zoom' to get drawn coordinates useful in findNodeNumber
// to convert to reported user chip coordinates we multiply by grChipSize/600
// to compare to segdefs and transdefs coordinates we subtract 400 from x and subtract y from grChipSize
function handleClick(e){
var x = localx(hilite, e.clientX)/zoom;
var y = localy(hilite, e.clientY)/zoom;
var w = findNodeNumber(x,y);
if(e.shiftKey) hiliteNode(getNodeGroup(w));
else {var a=new Array(); a.push(w); hiliteNode(a);}
// convert to chip coordinates
var cx = Math.round(x*grChipSize/600);
var cy = Math.round(y*grChipSize/600);
if(w==-1) {
setStatus('x: '+cx, 'y: '+cy);
} else {
// prepare two lines of status report
var s1='x: ' + cx + ' y: ' + cy;
var s2='node: ' + w + ' ' + nodeName(w);
var s2='node:&nbsp;' + w + '&nbsp;' + nodeName(w);
if(w==-1) {
setStatus(s1); // no node found, so report only coordinates
return;
}
// we have a node, but maybe we clicked over a transistor
var nodelist=[w];
// match the coordinate against transistor gate bounding boxes
x=cx-400;
y=grChipSize-cy;
for(var i=0;i<nodes[w].gates.length;i++){
var xmin=nodes[w].gates[i].bb[0], xmax=nodes[w].gates[i].bb[1];
var ymin=nodes[w].gates[i].bb[2], ymax=nodes[w].gates[i].bb[3];
if((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)){
// only one match at most, so we replace rather than push
nodelist=[nodes[w].gates[i].name];
s2='transistor: ' + nodes[w].gates[i].name + ' on ' + s2;
}
}
// if this is a shift-click, just find and highlight the pass-connected group
// and list the nodes (or nodenames, preferably)
if(e.shiftKey) {
getNodeGroup(w);
nodelist = group;
s2 = "nodegroup from&nbsp;" + s2 +
" (nodes:&nbsp;" +
group.map(function(x){return nodeName(x)?nodeName(x):x;}).join(",") +
")";
}
hiliteNode(nodelist);
setStatus(s1, s2);
if(ctrace) console.log(s1, s2);
}
}
function updateLoglevel(value){
loglevel = value;
@ -366,7 +521,7 @@ var consolebox;
function setupConsole(){
consolebox=document.getElementById('consolebox');
consolebox.onkeypress=function(e){consolegetc=e.charCode;};
consolebox.onkeypress=function(e){consolegetc=e.charCode || e.keyCode;};
}
var chipsurround;
@ -409,8 +564,19 @@ function setupChipLayoutGraphics(){
refresh();
document.getElementById('waiting').style.display = 'none';
setStatus('Ready!'); // would prefer chipStatus but it's not idempotent
// pre-fill the Find box if parameters supplied
if(typeof findThese != "undefined") {
document.getElementById('HighlightThese').value = findThese;
hiliteNodeList(); // will pan and zoom to fit
}
// pre-pan and zoom if requested (will override any zoom-to-fit by hiliteNodeList)
if(moveHereFirst!=null)
moveHere(moveHereFirst);
// draw any URL-requested labels and boxes
if(labelThese.length>0) {
for(var i=0;i<labelThese.length;i+=1)
flashBoxLabel(labelThese[i]);
}
// grant focus to the chip display to enable zoom keys
chipsurround.focus();
chipsurround.onmousedown = function(e){mouseDown(e);};

View File

@ -66,26 +66,26 @@ Keyboard controls: 'z' to zoom in, 'x' to zoom out, 'n' to step the simulation.
<br />
Mouse controls: Left-click and drag to scroll around (when you're zoomed in.)
<br />
More information in the <a href="http://visual6502.org/wiki/index.php?title=JssimUserHelp">User Guide<a>.
More information in the <a href="http://visual6502.org/wiki/index.php?title=JssimUserHelp">User Guide</a>.
<br />
<br />
</span>
<div class="frame" id="frame">
<div class="chip" id="chip">
<canvas class="chip" id="chipbg"></canvas>
<object data="6502N.svg" type="image/svg+xml" id="chipbg" style="position: absolute; width: 600px; height:600px;"></object>
<canvas class="chip" id="overlay"></canvas>
<canvas class="chip" id="hilite"></canvas>
<canvas class="chip" id="hitbuffer"></canvas>
</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="start"></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>
<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>
</div>
<div style="float:right; margin-left:20px;">... or try <a href="expert.html">Advanced</a></div>
</div>
@ -97,7 +97,7 @@ More information in the <a href="http://visual6502.org/wiki/index.php?title=Jssi
<br />
<br />
Source code is available on <a href="http://github.com/trebonian/visual6502">github visual6502</a>.
Use the online <a href="http://www.6502asm.com/">emulator and assembler</a> from 6502asm.com
Use the online <a href="http://skilldrick.github.com/easy6502/#first-program">emulator and assembler</a> from the easy6502 tutorial
and <a href="http://www.e-tradition.net/bytes/6502/disassembler.html">disassembler</a> from e-tradition.net
<br />
For in-depth 6502 investigation and some more advanced features, try our <a href="expert.html">Advanced</a> page.

View File

@ -50,6 +50,13 @@ canvas.chip {
height: 600px;
}
object.chipbg {
position: absolute;
width: 600px;
height: 600px;
}
div.buttons{
position: absolute;
top: -5px;

View File

@ -102,7 +102,7 @@ function setup_part3(){
/////////////////////////
function handleKey(e){
var c = e.charCode;
var c = e.charCode || e.keyCode;
c = String.fromCharCode(c);
if('zx<>?np'.indexOf(c)==-1) return;
if((c=='x' || c=='<') && zoom>1) setZoom(zoom/1.2);
@ -144,12 +144,19 @@ function mouseUp(e){
}
function setZoom(n){
var svg = chipbg.getSVGDocument();
svg = svg.childNodes[0];
zoom = n;
setChipStyle({
width: 600*n+'px',
height: 600*n+'px'
});
svg.style.width = 600*n+'px';
svg.style.height = 600*n+'px';
recenter();
}
function recenter(){
@ -169,7 +176,10 @@ function handleClick(e){
var x = localx(hilite, e.clientX)/zoom;
var y = localy(hilite, e.clientY)/zoom;
var w = findNodeNumber(x,y);
if(e.shiftKey) hiliteNode(getNodeGroup(w));
if(e.shiftKey) {
getNodeGroup(w);
hiliteNode(group);
}
else {var a=new Array(); a.push(w); hiliteNode(a);}
var cx = Math.round(x*grChipSize/600);
var cy = Math.round(y*grChipSize/600);
@ -190,7 +200,7 @@ function handleClick(e){
function setChipStyle(props){
for(var i in props){
chipbg.style[i] = props[i];
overlay.style[i] = props[i];
// overlay.style[i] = props[i];
hilite.style[i] = props[i];
hitbuffer.style[i] = props[i];
}

View File

@ -26,6 +26,8 @@ var trace = Array();
var logstream = Array();
var running = false;
var logThese=[];
var chipname='6502';
var nodenamereset='res';
var presetLogLists=[
['cycle'],
['ab','db','rw','Fetch','pc','a','x','y','s','p'],
@ -35,7 +37,7 @@ var presetLogLists=[
['alucin','alua','alub','alucout','aluvout','dasb'],
['plaOutputs','DPControl'],
['idb','dor'],
['irq','nmi','res'],
['irq','nmi',nodenamereset],
];
function loadProgram(){
@ -147,13 +149,13 @@ function initChip(){
nodes[npwr].state = true;
nodes[npwr].float = false;
for(var tn in transistors) transistors[tn].on = false;
setLow('res');
setLow(nodenamereset);
setLow('clk0');
setHigh('rdy'); setLow('so');
setHigh('irq'); setHigh('nmi');
recalcNodeList(allNodes());
for(var i=0;i<8;i++){setHigh('clk0'), setLow('clk0');}
setHigh('res');
setHigh(nodenamereset);
for(var i=0;i<18;i++){halfStep();} // avoid updating graphics and trace buffer before user code
refresh();
cycle = 0;
@ -224,9 +226,10 @@ fetchTriggers={};
// simulate a single clock phase with no update to graphics or trace
function halfStep(){
var clk = isNodeHigh(nodenames['clk0']);
eval(clockTriggers[cycle]);
if (clk) {setLow('clk0'); handleBusRead(); }
else {setHigh('clk0'); handleBusWrite();}
eval(clockTriggers[cycle+1]); // pre-apply next tick's inputs now, so the updates are displayed
}
function handleBusRead(){
@ -328,9 +331,9 @@ function busToString(busname){
if(busname=='State')
return listActiveTCStates();
if(busname=='Execute')
return dis6502toHTML(readBits('ir',8));
return disassemblytoHTML(readBits('ir',8));
if(busname=='Fetch')
return isNodeHigh(nodenames['sync'])?dis6502toHTML(readDataBus()):"";
return isNodeHigh(nodenames['sync'])?disassemblytoHTML(readDataBus()):"";
if(busname=='plaOutputs')
// PLA outputs are mostly ^op- but some have a prefix too
// - we'll allow the x and xx prefix but ignore the #
@ -424,7 +427,7 @@ function stopChip(){
function resetChip(){
stopChip();
setStatus('resetting 6502...');
setStatus('resetting ' + chipname + '...');
setTimeout(initChip,0);
}
@ -469,7 +472,7 @@ function chipStatus(){
machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match");
}
setStatus(machine1, machine2, machine3);
if (loglevel>0) {
if (logThese.length>1) {
updateLogbox(logThese);
}
selectCell(ab);
@ -507,6 +510,8 @@ function goForN(n){
return;
}
running = false;
var start = document.getElementById('start');
var stop = document.getElementById('stop');
start.style.visibility = 'visible';
stop.style.visibility = 'hidden';
}
@ -623,8 +628,8 @@ function adler32(x){
}
// sanitised opcode for HTML output
function dis6502toHTML(byte){
var opcode=dis6502[byte];
function disassemblytoHTML(byte){
var opcode=disassembly[byte];
if(typeof opcode == "undefined")
return "unknown"
return opcode.replace(/ /,'&nbsp;');
@ -632,7 +637,7 @@ function dis6502toHTML(byte){
// opcode lookup for 6502 - not quite a disassembly
// javascript derived from Debugger.java by Achim Breidenbach
var dis6502={
var disassembly={
0x00:"BRK",
0x01:"ORA (zp,X)",
0x05:"ORA zp",

View File

@ -82,7 +82,7 @@ x4: 85,
x5: 589,
x6: 448,
x7: 777,
pcl0: 1139, // machine state: program counter low (first storage node)
pcl0: 1139, // machine state: program counter low (first storage node output)
pcl1: 1022,
pcl2: 655,
pcl3: 1359,
@ -90,14 +90,30 @@ pcl4: 900,
pcl5: 622,
pcl6: 377,
pcl7: 1611,
pclp0: 1227, // machine state: program counter low (pre-incremented?, second storage node)
pclp1: 1102,
pclp2: 1079,
pclp3: 868,
pclp4: 39,
pclp5: 1326,
pclp6: 731,
pclp7: 536,
pclp0: 488, // machine state: program counter low (pre-incremented?, second storage node)
pclp1: 976,
pclp2: 481,
pclp3: 723,
pclp4: 208,
pclp5: 72,
pclp6: 1458,
pclp7: 1647,
"#pclp0": 1227, // machine state: program counter low (pre-incremented?, inverse second storage node)
"~pclp0": 1227, // automatic alias replacing hash with tilde
"#pclp1": 1102,
"~pclp1": 1102, // automatic alias replacing hash with tilde
"#pclp2": 1079,
"~pclp2": 1079, // automatic alias replacing hash with tilde
"#pclp3": 868,
"~pclp3": 868, // automatic alias replacing hash with tilde
"#pclp4": 39,
"~pclp4": 39, // automatic alias replacing hash with tilde
"#pclp5": 1326,
"~pclp5": 1326, // automatic alias replacing hash with tilde
"#pclp6": 731,
"~pclp6": 731, // automatic alias replacing hash with tilde
"#pclp7": 536,
"~pclp7": 536, // automatic alias replacing hash with tilde
pch0: 1670, // machine state: program counter high (first storage node)
pch1: 292,
pch2: 502,
@ -106,22 +122,50 @@ pch4: 948,
pch5: 49,
pch6: 1551,
pch7: 205,
pchp0: 780, // machine state: program counter high (pre-incremented?, second storage node)
pchp1: 113,
pchp2: 114,
pchp3: 124,
pchp4: 820,
pchp5: 33,
pchp6: 751,
pchp7: 535,
p0: 687, // machine state: status register
p1: 1444,
p2: 1421,
p3: 439,
p4: 1119, // there is no bit4 in the status register!
p5: -1, // there is no bit5 in the status register!
p6: 77,
p7: 1370,
pchp0: 1722, // machine state: program counter high (pre-incremented?, second storage node output)
pchp1: 209,
pchp2: 1496,
pchp3: 141,
pchp4: 27,
pchp5: 1301,
pchp6: 652,
pchp7: 1206,
"#pchp0": 780, // machine state: program counter high (pre-incremented?, inverse second storage node)
"~pchp0": 780, // automatic alias replacing hash with tilde
"#pchp1": 113,
"~pchp1": 113, // automatic alias replacing hash with tilde
"#pchp2": 114,
"~pchp2": 114, // automatic alias replacing hash with tilde
"#pchp3": 124,
"~pchp3": 124, // automatic alias replacing hash with tilde
"#pchp4": 820,
"~pchp4": 820, // automatic alias replacing hash with tilde
"#pchp5": 33,
"~pchp5": 33, // automatic alias replacing hash with tilde
"#pchp6": 751,
"~pchp6": 751, // automatic alias replacing hash with tilde
"#pchp7": 535,
"~pchp7": 535, // automatic alias replacing hash with tilde
// machine state: status register (not the storage nodes)
p0: 32, // C bit of status register (storage node)
p1: 627, // Z bit of status register (storage node)
p2: 1553, // I bit of status register (storage node)
p3: 348, // D bit of status register (storage node)
p4: 1119, // there is no bit4 in the status register! (not a storage node)
p5: -1, // there is no bit5 in the status register! (not a storage node)
p6: 77, // V bit of status register (storage node)
p7: 1370, // N bit of status register (storage node)
// internal bus: status register outputs for push P
Pout0: 687,
Pout1: 1444,
Pout2: 1421,
Pout3: 439,
Pout4: 1119, // there is no bit4 in the status register!
Pout5: -1, // there is no bit5 in the status register!
Pout6: 77,
Pout7: 1370,
s0: 1403, // machine state: stack pointer
s1: 183,
s2: 81,
@ -146,13 +190,31 @@ notir4: 26,
notir5: 1394,
notir6: 895,
notir7: 1320,
irline3: 996, // internal signal: PLA input - ir0 AND ir1
clock1: 1536, // internal state: timing control
clock2: 156, // internal state: timing control
irline3: 996, // internal signal: PLA input - ir0 OR ir1
clock1: 1536, // internal state: timing control aka #T0
clock1: 1536, // automatic alias replacing hash with tilde
clock2: 156, // internal state: timing control aka #T+
clock2: 156, // automatic alias replacing hash with tilde
t2: 971, // internal state: timing control
t3: 1567,
t4: 690,
t5: 909,
noty0: 1025, // datapath state: not Y register
noty1: 1138,
noty2: 1484,
noty3: 184,
noty4: 565,
noty5: 981,
noty6: 1439,
noty7: 1640,
notx0: 987, // datapath state: not X register
notx1: 1434,
notx2: 890,
notx3: 1521,
notx4: 485,
notx5: 1017,
notx6: 730,
notx7: 1561,
nots0: 418, // datapath state: not stack pointer
nots1: 1064,
nots2: 752,
@ -185,7 +247,8 @@ sb4: 1405,
sb5: 166,
sb6: 1336,
sb7: 1001,
notalu0: 394, // datapath state: alu output storage node (inverse)
notalu0: 394, // datapath state: alu output storage node (inverse) aka #ADD0
notalu0: 394, // automatic alias replacing hash with tilde
notalu1: 697,
notalu2: 276,
notalu3: 495,
@ -193,7 +256,7 @@ notalu4: 1490,
notalu5: 893,
notalu6: 68,
notalu7: 1123,
alu0: 401, // datapath signal: ALU output
alu0: 401, // datapath signal: ALU output aka ADD0out
alu1: 872,
alu2: 1637,
alu3: 1414,
@ -210,7 +273,7 @@ dasb4: 1405, // same node as sb4
dasb5: 263,
dasb6: 679,
dasb7: 1494,
adl0: 413, // internal state: address latch low
adl0: 413, // internal bus: address low
adl1: 1282,
adl2: 1242,
adl3: 684,
@ -218,7 +281,7 @@ adl4: 1437,
adl5: 1630,
adl6: 121,
adl7: 1299,
adh0: 407, // internal state: address latch high
adh0: 407, // internal bus: address high
adh1: 52,
adh2: 1651,
adh3: 315,
@ -226,7 +289,7 @@ adh4: 1160,
adh5: 483,
adh6: 13,
adh7: 1539,
idb0: 1108, // internal state: data buffer
idb0: 1108, // internal bus: data bus
idb1: 991,
idb2: 1473,
idb3: 1302,
@ -266,16 +329,85 @@ pd4: 369,
pd5: 829,
pd6: 1669,
pd7: 1690,
// internal signals: predecode latch partial decodes
"PD-xxxx10x0": 1019,
"PD-1xx000x0": 1294,
"PD-0xx0xx0x": 365,
"PD-xxx010x1": 302,
"PD-n-0xx0xx0x": 125,
"#TWOCYCLE": 851,
"~TWOCYCLE": 851, // automatic alias replacing hash with tilde
"#TWOCYCLE.phi1": 792,
"~TWOCYCLE.phi1": 792, // automatic alias replacing hash with tilde
"ONEBYTE": 778,
abl0: 1096, // internal bus: address bus low latched data out (inverse of inverted storage node)
abl1: 376,
abl2: 1502,
abl3: 1250,
abl4: 1232,
abl5: 234,
abl6: 178,
abl7: 567,
"#ABL0": 153, // internal state: address bus low latched data out (storage node, inverted)
"~ABL0": 153, // automatic alias replacing hash with tilde
"#ABL1": 107,
"~ABL1": 107, // automatic alias replacing hash with tilde
"#ABL2": 707,
"~ABL2": 707, // automatic alias replacing hash with tilde
"#ABL3": 825,
"~ABL3": 825, // automatic alias replacing hash with tilde
"#ABL4": 364,
"~ABL4": 364, // automatic alias replacing hash with tilde
"#ABL5": 1513,
"~ABL5": 1513, // automatic alias replacing hash with tilde
"#ABL6": 1307,
"~ABL6": 1307, // automatic alias replacing hash with tilde
"#ABL7": 28,
"~ABL7": 28, // automatic alias replacing hash with tilde
abh0: 1429, // internal bus: address bus high latched data out (inverse of inverted storage node)
abh1: 713,
abh2: 287,
abh3: 422,
abh4: 1143,
abh5: 775,
abh6: 997,
abh7: 489,
"#ABH0": 1062, // internal state: address bus high latched data out (storage node, inverted)
"~ABH0": 1062, // automatic alias replacing hash with tilde
"#ABH1": 907,
"~ABH1": 907, // automatic alias replacing hash with tilde
"#ABH2": 768,
"~ABH2": 768, // automatic alias replacing hash with tilde
"#ABH3": 92,
"~ABH3": 92, // automatic alias replacing hash with tilde
"#ABH4": 668,
"~ABH4": 668, // automatic alias replacing hash with tilde
"#ABH5": 1128,
"~ABH5": 1128, // automatic alias replacing hash with tilde
"#ABH6": 289,
"~ABH6": 289, // automatic alias replacing hash with tilde
"#ABH7": 429,
"~ABH7": 429, // automatic alias replacing hash with tilde
"branch-back": 626, // distinguish forward from backward branches
"branch-forward.phi1": 1110, // distinguish forward from backward branches
"branch-back.phi1": 771, // distinguish forward from backward branches in IPC logic
notRdy0: 248, // internal signal: global pipeline control
"notRdy0.phi1": 1272, // delayed pipeline control
"notRdy0.delay": 770, // global pipeline control latched by phi1 and then phi2
"#notRdy0.delay": 559, // global pipeline control latched by phi1 and then phi2 (storage node)
"~notRdy0.delay": 559, // automatic alias replacing hash with tilde
Reset0: 67, // internal signal: retimed reset from pin
C1x5Reset: 926, // retimed and pipelined reset in progress
notRnWprepad: 187, // internal signal: to pad, yet to be inverted and retimed
RnWstretched: 353, // internal signal: control datapad output drivers
RnWstretched: 353, // internal signal: control datapad output drivers, aka TRISTATE
"#DBE": 1035, // internal signal: formerly from DBE pad (6501)
"~DBE": 1035, // automatic alias replacing hash with tilde
cp1: 710, // internal signal: clock phase 1
cclk: 943, // unbonded pad: internal non-overlappying phi2
fetch: 879, // internal signal
clearIR: 1077, // internal signal
D1x1: 827, // internal signal: interrupt handler related
H1x1: 1042, // internal signal: drive status byte onto databus
// internal signal: pla outputs block 1 (west/left edge of die)
@ -426,20 +558,75 @@ H1x1: 1042, // internal signal: drive status byte onto databus
"x-op-push/pull":1050, // pla121 // feeds into pla130 (no normal pla output)
"op-T0-cld/sed":1419, // pla122
"#op-branch-bit6":840, // pla123 // IR bit6 used only to detect branch type
"~op-branch-bit6":840, // automatic alias replacing hash with tilde
"op-T3-mem-abs":607, // pla124
"op-T2-mem-zp":219, // pla125
"op-T5-mem-ind-idx":1385, // pla126
"op-T4-mem-abs-idx":281, // pla127
"#op-branch-bit7":1174, // pla128 // IR bit7 used only to detect branch type
"~op-branch-bit7":1174, // automatic alias replacing hash with tilde
"op-clv":1164, // pla129
"op-implied":1006, // pla130 // has extra pulldowns: pla121 and ir0
// internal signals: derived from pla outputs
"#op-branch-done": 1048,
"~op-branch-done": 1048, // automatic alias replacing hash with tilde
"#op-T3-branch": 1708,
"~op-T3-branch": 1708, // automatic alias replacing hash with tilde
"op-ANDS": 1228,
"op-EORS": 1689,
"op-ORS": 522,
"op-SUMS": 1196,
"op-SRS": 934,
"#op-store": 925,
"~op-store": 925, // automatic alias replacing hash with tilde
"#WR": 1352,
"~WR": 1352, // automatic alias replacing hash with tilde
"op-rmw": 434,
"short-circuit-idx-add": 1185,
"short-circuit-branch-add": 430,
"#op-set-C": 252,
"~op-set-C": 252, // automatic alias replacing hash with tilde
// internal signals: control signals
nnT2BR: 967, // doubly inverted
BRtaken: 1544,
BRtaken: 1544, // aka #TAKEN
BRtaken: 1544, // automatic alias replacing hash with tilde
// internal signals and state: interrupt and vector related
// segher says:
// "P" are the latched external signals.
// "G" are the signals that actually trigger the interrupt.
// "NMIL" is to do the edge detection -- it's pretty much just a delayed NMIG.
// INTG is IRQ and NMI taken together.
IRQP: 675,
"#IRQP": 888,
"~IRQP": 888, // automatic alias replacing hash with tilde
NMIP: 1032,
"#NMIP": 297,
"~NMIP": 297, // automatic alias replacing hash with tilde
"#NMIG": 264,
"~NMIG": 264, // automatic alias replacing hash with tilde
NMIL: 1374,
RESP: 67,
RESG: 926,
VEC0: 1465,
VEC1: 1481,
"#VEC": 1134,
"~VEC": 1134, // automatic alias replacing hash with tilde
D1x1: 827, // internal signal: interrupt handler related
"brk-done": 1382, // internal signal: interrupt handler related
INTG: 1350, // internal signal: interrupt handler related
// internal state: misc pipeline state clocked by cclk (phi2)
pipeBRtaken: 832,
"pipe#VEC": 1431, // latched #VEC
"pipe~VEC": 1431, // automatic alias replacing hash with tilde
"pipeT-SYNC": 537,
pipeT2out: 40,
pipeT3out: 706,
pipeT4out: 1373,
pipeT5out: 940,
pipeIPCrelated: 832,
pipeUNK01: 1530,
pipeUNK02: 974,
pipeUNK03: 1436,
@ -477,20 +664,25 @@ pipeUNK34: 56,
pipeUNK35: 1713,
pipeUNK36: 729,
pipeUNK37: 197,
pipeUNK38: 1131,
"pipe#WR.phi2": 1131,
"pipe~WR.phi2": 1131, // automatic alias replacing hash with tilde
pipeUNK39: 151,
pipeUNK40: 456,
pipeUNK41: 1438,
pipeUNK42: 1104,
pipeUNK43: 554,
"pipe#T0": 554, // aka #T0.phi2
"pipe~T0": 554, // automatic alias replacing hash with tilde
// internal state: vector address pulldown control
pipeVectorA0: 357,
pipeVectorA1: 170,
pipeVectorA2: 45,
// internal signals: vector address pulldown control
"0/ADL0": 217,
"0/ADL1": 686,
"0/ADL2": 1193,
// internal state: datapath control drivers
pipedpc28: 683,
@ -512,17 +704,167 @@ alub5: 1678,
alub6: 235,
alub7: 1535,
aluanorb0: 143,
aluanandb0: 1628,
aluaorb0: 693,
notaluoutmux0: 957, // alu result latch input
// alu carry chain and decimal mode
C01: 1285,
C12: 505,
C23: 1023,
C34: 78,
C45: 142,
C56: 500,
C67: 1314,
C78: 808,
"C78.phi2": 560,
DC34: 1372, // lower nibble decimal carry
DC78: 333, // carry for decimal mode
"DC78.phi2": 164,
"#C01": 1506,
"~C01": 1506, // automatic alias replacing hash with tilde
"#C12": 1122,
"~C12": 1122, // automatic alias replacing hash with tilde
"#C23": 1003,
"~C23": 1003, // automatic alias replacing hash with tilde
"#C34": 1425,
"~C34": 1425, // automatic alias replacing hash with tilde
"#C45": 1571,
"~C45": 1571, // automatic alias replacing hash with tilde
"#C56": 427,
"~C56": 427, // automatic alias replacing hash with tilde
"#C67": 592,
"~C67": 592, // automatic alias replacing hash with tilde
"#C78": 1327,
"~C78": 1327, // automatic alias replacing hash with tilde
"DA-C01": 623,
"DA-AB2": 216,
"DA-AxB2": 516,
"DA-C45": 1144,
"#DA-ADD1": 901,
"~DA-ADD1": 901, // automatic alias replacing hash with tilde
"#DA-ADD2": 699,
"~DA-ADD2": 699, // automatic alias replacing hash with tilde
aluanorb1: 155,
aluanandb1: 841,
aluaorb1: 1021,
notaluoutmux1: 250, // alu result latch input
// misc alu internals
"#(AxBxC)0": 371,
"~(AxBxC)0": 371, // automatic alias replacing hash with tilde
"#(AxBxC)1": 965,
"~(AxBxC)1": 965, // automatic alias replacing hash with tilde
"#(AxBxC)2": 22,
"~(AxBxC)2": 22, // automatic alias replacing hash with tilde
"#(AxBxC)3": 274,
"~(AxBxC)3": 274, // automatic alias replacing hash with tilde
"#(AxBxC)4": 651,
"~(AxBxC)4": 651, // automatic alias replacing hash with tilde
"#(AxBxC)5": 486,
"~(AxBxC)5": 486, // automatic alias replacing hash with tilde
"#(AxBxC)6": 1197,
"~(AxBxC)6": 1197, // automatic alias replacing hash with tilde
"#(AxBxC)7": 532,
"~(AxBxC)7": 532, // automatic alias replacing hash with tilde
AxB1: 425,
AxB3: 640,
AxB5: 1220,
AxB7: 1241,
"#(AxB)0": 1525,
"~(AxB)0": 1525, // automatic alias replacing hash with tilde
"#(AxB)2": 701,
"~(AxB)2": 701, // automatic alias replacing hash with tilde
"#(AxB)4": 308,
"~(AxB)4": 308, // automatic alias replacing hash with tilde
"#(AxB)6": 1459,
"~(AxB)6": 1459, // automatic alias replacing hash with tilde
"(AxB)0.#C0in": 555,
"(AxB)0.~C0in": 555, // automatic alias replacing hash with tilde
"(AxB)2.#C12": 193,
"(AxB)2.~C12": 193, // automatic alias replacing hash with tilde
"(AxB)4.#C34": 65,
"(AxB)4.~C34": 65, // automatic alias replacing hash with tilde
"(AxB)6.#C56": 174,
"(AxB)6.~C56": 174, // automatic alias replacing hash with tilde
"#(AxB1).C01": 295,
"~(AxB1).C01": 295, // automatic alias replacing hash with tilde
"#(AxB3).C23": 860,
"~(AxB3).C23": 860, // automatic alias replacing hash with tilde
"#(AxB5).C45": 817,
"~(AxB5).C45": 817, // automatic alias replacing hash with tilde
"#(AxB7).C67": 1217,
"~(AxB7).C67": 1217, // automatic alias replacing hash with tilde
"#A.B0": 1628,
"~A.B0": 1628, // automatic alias replacing hash with tilde
"#A.B1": 841,
"~A.B1": 841, // automatic alias replacing hash with tilde
"#A.B2": 681,
"~A.B2": 681, // automatic alias replacing hash with tilde
"#A.B3": 350,
"~A.B3": 350, // automatic alias replacing hash with tilde
"#A.B4": 1063,
"~A.B4": 1063, // automatic alias replacing hash with tilde
"#A.B5": 477,
"~A.B5": 477, // automatic alias replacing hash with tilde
"#A.B6": 336,
"~A.B6": 336, // automatic alias replacing hash with tilde
"#A.B7": 1318,
"~A.B7": 1318, // automatic alias replacing hash with tilde
"A+B0": 693,
"A+B1": 1021,
"A+B2": 110,
"A+B3": 1313,
"A+B4": 918,
"A+B5": 1236,
"A+B6": 803,
"A+B7": 117,
"#(A+B)0": 143,
"~(A+B)0": 143, // automatic alias replacing hash with tilde
"#(A+B)1": 155,
"~(A+B)1": 155, // automatic alias replacing hash with tilde
"#(A+B)2": 1691,
"~(A+B)2": 1691, // automatic alias replacing hash with tilde
"#(A+B)3": 649,
"~(A+B)3": 649, // automatic alias replacing hash with tilde
"#(A+B)4": 404,
"~(A+B)4": 404, // automatic alias replacing hash with tilde
"#(A+B)5": 1632,
"~(A+B)5": 1632, // automatic alias replacing hash with tilde
"#(A+B)6": 1084,
"~(A+B)6": 1084, // automatic alias replacing hash with tilde
"#(A+B)7": 1398,
"~(A+B)7": 1398, // automatic alias replacing hash with tilde
"#(AxB)0": 1525,
"~(AxB)0": 1525, // automatic alias replacing hash with tilde
"#(AxB)2": 701,
"~(AxB)2": 701, // automatic alias replacing hash with tilde
"#(AxB)4": 308,
"~(AxB)4": 308, // automatic alias replacing hash with tilde
"#(AxB)6": 1459,
"~(AxB)6": 1459, // automatic alias replacing hash with tilde
"#(AxB)1": 953,
"~(AxB)1": 953, // automatic alias replacing hash with tilde
"#(AxB)3": 884,
"~(AxB)3": 884, // automatic alias replacing hash with tilde
"#(AxB)5": 1469,
"~(AxB)5": 1469, // automatic alias replacing hash with tilde
"#(AxB)7": 177,
"~(AxB)7": 177, // automatic alias replacing hash with tilde
"#aluresult0": 957, // alu result latch input
"~aluresult0": 957, // automatic alias replacing hash with tilde
"#aluresult1": 250,
"~aluresult1": 250, // automatic alias replacing hash with tilde
"#aluresult2": 740,
"~aluresult2": 740, // automatic alias replacing hash with tilde
"#aluresult3": 1071,
"~aluresult3": 1071, // automatic alias replacing hash with tilde
"#aluresult4": 296,
"~aluresult4": 296, // automatic alias replacing hash with tilde
"#aluresult5": 277,
"~aluresult5": 277, // automatic alias replacing hash with tilde
"#aluresult6": 722,
"~aluresult6": 722, // automatic alias replacing hash with tilde
"#aluresult7": 304,
"~aluresult7": 304, // automatic alias replacing hash with tilde
// internal signals: datapath control signals
"ADL/ABL": 639, // load ABL latches from ADL bus
"ADH/ABH": 821, // load ABH latches from ADH bus
dpc0_YSB: 801, // drive sb from y
dpc1_SBY: 325, // load y from sb
dpc2_XSB: 1263, // drive sb from x
@ -544,21 +886,35 @@ dpc16_EORS: 1666, // alu op: a xor b (?)
dpc17_SUMS: 921, // alu op: a plus b (?)
alucin: 910, // alu carry in
notalucin: 1165,
dpc18_DAA: 1201, // decimal related
"dpc18_#DAA": 1201, // decimal related (inverted)
"dpc18_~DAA": 1201, // automatic alias replacing hash with tilde
dpc19_ADDSB7: 214, // alu to sb bit 7 only
dpc20_ADDSB06: 129, // alu to sb bits 6-0 only
dpc21_ADDADL: 1015, // alu to adl
alurawcout: 808, // alu raw carry out (no decimal adjust)
notalucout: 412, // alu carry out (inverted)
alucout: 1146, // alu carry out (latched by phi2)
"#alucout": 206,
"~alucout": 206, // automatic alias replacing hash with tilde
"##alucout": 465,
"~~alucout": 465, // automatic alias replacing hash with tilde
notaluvout: 1308, // alu overflow out
aluvout: 938, // alu overflow out (latched by phi2)
dpc22_DSA: 725, // decimal related/SBC only
"#DBZ": 1268, // internal signal: not (databus is zero)
"~DBZ": 1268, // automatic alias replacing hash with tilde
DBZ: 744, // internal signal: databus is zero
DBNeg: 1200, // internal signal: databus is negative (top bit of db) aka P-#DB7in
DBNeg: 1200, // automatic alias replacing hash with tilde
"dpc22_#DSA": 725, // decimal related/SBC only (inverted)
"dpc22_~DSA": 725, // automatic alias replacing hash with tilde
dpc23_SBAC: 534, // (optionalls decimal-adjusted) sb to acc
dpc24_ACSB: 1698, // acc to sb
dpc25_SBDB: 1060, // sb pass-connects to idb
dpc25_SBDB: 1060, // sb pass-connects to idb (bi-directionally)
dpc26_ACDB: 1331, // acc to idb
dpc27_SBADH: 140, // sb pass-connects to adh
dpc27_SBADH: 140, // sb pass-connects to adh (bi-directionally)
dpc28_0ADH0: 229, // zero to adh0 bit0 only
dpc29_0ADH17: 203, // zero to adh bits 7-1 only
@ -567,14 +923,24 @@ dpc31_PCHPCH: 741, // load pch from pch incremented
dpc32_PCHADH: 1235, // drive adh from pch incremented
dpc33_PCHDB: 247, // drive idb from pch incremented
dpc34_PCLC: 1704, // pch carry in and pcl FF detect?
dpc35: 1334, // pcl 0x?F detect - half-carry
dpc36_IPC: 379, // pcl carry in
dpc35_PCHC: 1334, // pcl 0x?F detect - half-carry
"dpc36_#IPC": 379, // pcl carry in (inverted)
"dpc36_~IPC": 379, // automatic alias replacing hash with tilde
dpc37_PCLDB: 283, // drive idb from pcl incremented
dpc38_PCLADL: 438, // drive adl from pcl incremented
dpc39_PCLPCL: 898, // load pcl from pcl incremented
dpc40_ADLPCL: 414, // load pcl from adl
dpc41: 1564, // pass-connect adl to mux node driven by idl
dpc42: 41, // pass-connect adh to mux node driven by idl
dpc43: 863, // pass-connect idb to mux node driven by idl
"dpc41_DL/ADL": 1564,// pass-connect adl to mux node driven by idl
"dpc42_DL/ADH": 41, // pass-connect adh to mux node driven by idl
"dpc43_DL/DB": 863, // pass-connect idb to mux node driven by idl
}
/* many bus names taken from Donald F. Hanson's block diagram, found
* http://www.weihenstephan.org/~michaste/pagetable/6502/6502.jpg
* from his paper "A VHDL conversion tool for logic equations with embedded D latches"
* http://portal.acm.org/citation.cfm?id=1275143.1275151
* also available at
* http://www.ncsu.edu/wcae/WCAE1/hanson.pdf
*/

File diff suppressed because it is too large Load Diff

127
wires.js
View File

@ -22,6 +22,11 @@
var frame, chipbg, overlay, hilite, hitbuffer, ctx;
var nodes = new Array();
var lastState = new Array();
var polyAttr = new Array();
var metalAttr = new Array();
var polyOffFill;
var metalOffFill;
var transistors = {};
var nodenamelist=[];
@ -29,6 +34,7 @@ var ngnd = nodenames['vss'];
var npwr = nodenames['vcc'];
var chipLayoutIsVisible = true; // only modified in expert mode
var hilited = [];
function setupNodes(){
for(var i in segdefs){
@ -39,6 +45,7 @@ function setupNodes(){
state: false, gates: new Array(), c1c2s: new Array()};
if(w==ngnd) continue;
if(w==npwr) continue;
lastState[i] = 0;
nodes[w].segs.push(seg.slice(3));
}
}
@ -50,9 +57,10 @@ function setupTransistors(){
var gate = tdef[1];
var c1 = tdef[2];
var c2 = tdef[3];
var bb = tdef[4];
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};
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);
@ -71,8 +79,20 @@ function setupLayerVisibility(){
function setupBackground(){
chipbg = document.getElementById('chipbg');
chipbg.width = grCanvasSize;
chipbg.height = grCanvasSize;
chipbg.width = 4000;
chipbg.height = 4000;
var svg = chipbg.getSVGDocument();
svg = svg.childNodes[0];
var poly = svg.getElementById('poly');
var metal = svg.getElementById('metal');
polyOffFill = poly.getAttribute('fill');
metalOffFill = metal.getAttribute('fill');
for(var i in nodes){
polyAttr[i] = poly.getElementsByClassName(i+'')[0];
metalAttr[i] = metal.getElementsByClassName(i+'')[0];
}
return;
var ctx = chipbg.getContext('2d');
ctx.fillStyle = '#000000';
ctx.strokeStyle = 'rgba(255,255,255,0.5)';
@ -91,10 +111,10 @@ function setupBackground(){
}
function setupOverlay(){
overlay = document.getElementById('overlay');
overlay.width = grCanvasSize;
overlay.height = grCanvasSize;
ctx = overlay.getContext('2d');
// overlay = document.getElementById('overlay');
// overlay.width = grCanvasSize;
// overlay.height = grCanvasSize;
// ctx = overlay.getContext('2d');
}
function setupHilite(){
@ -135,34 +155,103 @@ function hexdigit(n){return '0123456789ABCDEF'.charAt(n);}
function refresh(){
if(!chipLayoutIsVisible) return;
ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
// ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
// for(i in nodes){
// if(isNodeHigh(i)) overlayNode(nodes[i].segs);
// }
for(i in nodes){
if(isNodeHigh(i)) overlayNode(nodes[i].segs);
if(isNodeHigh(i)){
if(lastState[i]==1)continue;
var n = polyAttr[i];
var n2 = metalAttr[i];
if(n!=undefined)
n.setAttribute('fill', 'rgb(0,255,255)');
if(n2!=undefined)
n2.setAttribute('fill', 'rgb(0,255,255)');
lastState[i] = 1;
} else {
if(lastState[i]==0)continue;
var n = polyAttr[i];
var n2 = metalAttr[i];
if(n!=undefined)
n.setAttribute('fill', polyOffFill);
if(n2!=undefined)
n2.setAttribute('fill', metalOffFill);
lastState[i] = 0;
}
}
hiliteNode(hilited);
}
function overlayNode(w){
ctx.fillStyle = 'rgba(255,0,64,0.4)';
for(i in w) {
drawSeg(ctx, w[i]);
ctx.fill();
}
}
//function overlayNode(w){
// ctx.fillStyle = 'rgba(255,0,64,0.4)';
// for(i in w) {
// drawSeg(ctx, w[i]);
// ctx.fill();
// }
//}
// originally to highlight using a list of node numbers
// but can now include transistor names
function hiliteNode(n){
var ctx = hilite.getContext('2d');
ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
ctx.fillStyle = 'rgba(255,255,255,0.7)';
if(n==-1) return;
if(isNodeHigh(n[0]))
ctx.fillStyle = 'rgba(255,0,0,0.7)';
hilited = n;
for(var i in n){
if(typeof n[i] != "number") {
hiliteTrans([n[i]]);
continue;
}
if(isNodeHigh(n[i])) {
ctx.fillStyle = 'rgba(255,0,0,0.7)';
} else {
ctx.fillStyle = 'rgba(255,255,255,0.7)';
}
var segs = nodes[n[i]].segs;
for(var s in segs){drawSeg(ctx, segs[s]); ctx.fill();}
}
}
// highlight a single transistor (additively - does not clear highlighting)
function hiliteTrans(n){
var ctx = hilite.getContext('2d');
ctx.strokeStyle = 'rgba(255,255,255,0.7)';
ctx.lineWidth = 4
for(var t in n){
var bb = transistors[n[t]].bb
var segs = [[bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3]]]
for(var s in segs){drawSeg(ctx, segs[s]); ctx.stroke();}
}
}
function ctxDrawBox(ctx, xMin, yMin, xMax, yMax){
var cap=ctx.lineCap;
ctx.lineCap="square";
ctx.beginPath();
ctx.moveTo(xMin, yMin);
ctx.lineTo(xMin, yMax);
ctx.lineTo(xMax, yMax);
ctx.lineTo(xMax, yMin);
ctx.lineTo(xMin, yMin);
ctx.stroke();
ctx.lineCap=cap;
}
// takes a bounding box in chip coords and centres the display over it
function zoomToBox(xmin,xmax,ymin,ymax){
var xmid=(xmin+xmax)/2;
var ymid=(ymin+ymax)/2;
var x=(xmid+400)/grChipSize*600;
var y=600-ymid/grChipSize*600;
var zoom=5; // pending a more careful calculation
moveHere([x,y,zoom]);
}
function drawSeg(ctx, seg){
var dx = 400;
ctx.beginPath();