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 www.visual6502.org/JSSim
It includes a general purpose transistor-level simulator, layout browser, It includes a general purpose transistor-level simulator, layout browser,
and the data from a 6502 revD chip. 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. Note the various licenses and Copyright associated with each file.
Enjoy! 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://blog.visual6502.org">Blog</a>&nbsp;
<a href="http://www.visual6502.org/links.html">Links</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://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; <a href="http://www.e-tradition.net/bytes/6502/disassembler.html">e-tradition disassembler</a>&nbsp;
</span> </span>
<div class="frame" id="frame"> <div class="frame" id="frame">
@ -76,7 +76,7 @@ $().ready(function(){
</form> </form>
</div> </div>
<div id="layoutControlPanel"> <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: <form id="updateShow"> Show:
<input type="checkbox" name="1" id="updateShow1" onchange="updateShow(this.name,this.checked)" />(diffusion) <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="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) <input type="checkbox" name="2" id="updateShow2" onchange="updateShow(this.name,this.checked)" />(protection)
</form> </form>
<form action="javascript:hiliteNodeList();"> <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="text" id="HighlightThese" name="HighlightThese" value="" />
<input type="button" value="Clear Highlighting" onclick="clearHighlight();" /> <input type="button" value="Clear Highlighting" onclick="clearHighlight();" />
<span class="animatebox"> <span class="animatebox">

View File

@ -24,6 +24,8 @@ var centerx=300, centery=300;
var zoom=1; var zoom=1;
var dragMouseX, dragMouseY, moved; var dragMouseX, dragMouseY, moved;
var statbox; var statbox;
var findThese;
var labelThese=[];
// Some constants for the graphics presentation // Some constants for the graphics presentation
// the canvas is embedded in an 800x600 clipping div // 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 // which saves a lot of memory and allows us to run on small systems
updateChipLayoutVisibility(true); updateChipLayoutVisibility(true);
} }
setStatus('resetting 6502...'); setStatus('resetting ' + chipname + '...');
setTimeout(setup_part4, 0); setTimeout(setup_part4, 0);
} }
@ -173,6 +175,14 @@ function setupParams(){
} else if(name=="zoom" && parseInt(value)!=NaN){ } else if(name=="zoom" && parseInt(value)!=NaN){
zoom=parseInt(value); zoom=parseInt(value);
} else } 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 // load a test program: Address, Data and Reset
if(name=="a" && parseInt(value,16)!=NaN){ if(name=="a" && parseInt(value,16)!=NaN){
userAddress=parseInt(value,16); userAddress=parseInt(value,16);
@ -185,17 +195,25 @@ function setupParams(){
} else } else
// setup input pin events, breakpoints, watchpoints // setup input pin events, breakpoints, watchpoints
if(name=="reset0" && parseInt(value)!=NaN){ if(name=="reset0" && parseInt(value)!=NaN){
clockTriggers[value]="setLow('res');"; clockTriggers[value]=[clockTriggers[value],"setLow(nodenamereset);"].join("");
} else if(name=="reset1" && parseInt(value)!=NaN){ } 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){ } 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){ } 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){ } 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){ } 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 } else
// run a test program, and optionally check against a golden checksum // run a test program, and optionally check against a golden checksum
if(name=="steps" && parseInt(value)!=NaN){ if(name=="steps" && parseInt(value)!=NaN){
@ -228,7 +246,7 @@ function updateChipLayoutAnimation(isOn){
// these keyboard actions are primarily for the chip display // these keyboard actions are primarily for the chip display
function handleKey(e){ function handleKey(e){
var c = e.charCode; var c = e.charCode || e.keyCode;
c = String.fromCharCode(c); c = String.fromCharCode(c);
if('<>?npZzx'.indexOf(c)==-1) return; if('<>?npZzx'.indexOf(c)==-1) return;
if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2); if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2);
@ -293,35 +311,141 @@ function recenter(){
top: top+'px', top: top+'px',
left: left+'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; var highlightThese;
// flash some set of nodes according to user input // flash some set of nodes according to user input
// also zoom to fit those nodes (not presently optional)
function hiliteNodeList(){ function hiliteNodeList(){
var tmplist = document.getElementById('HighlightThese').value.split(/[\s,]+/); 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 // request to highlight nothing, so switch off any signal highlighting
hiliteNode(-1); hiliteNode(-1);
return; return;
} }
highlightThese = []; highlightThese = [];
var seglist=[];
var report="";
for(var i=0;i<tmplist.length;i++){ for(var i=0;i<tmplist.length;i++){
// get a node number from a signal name or a node number // get a node number from a signal name or a node number
var name = tmplist[i]; var name = tmplist[i];
var value = parseInt(tmplist[i]); var value = parseInt(tmplist[i]);
if((value!=NaN) && (typeof nodes[name] != "undefined")) { if((value!=NaN) && (typeof nodes[value] != "undefined")) {
highlightThese.push(value); 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") { } else if(typeof nodenames[name] != "undefined") {
highlightThese.push(nodenames[name]); 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){ 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; 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) clearHighlight(); // nullify the simulation overlay (orange/purple)
hiliteNode(-1); // unhighlight all nodes hiliteNode(-1); // unhighlight all nodes
setTimeout("hiliteNode(highlightThese);", 400); setTimeout("hiliteNode(highlightThese);", 400);
@ -329,22 +453,53 @@ function hiliteNodeList(){
setTimeout("hiliteNode(highlightThese);", 1200); 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){ function handleClick(e){
var x = localx(hilite, e.clientX)/zoom; var x = localx(hilite, e.clientX)/zoom;
var y = localy(hilite, e.clientY)/zoom; var y = localy(hilite, e.clientY)/zoom;
var w = findNodeNumber(x,y); var w = findNodeNumber(x,y);
if(e.shiftKey) hiliteNode(getNodeGroup(w)); // convert to chip coordinates
else {var a=new Array(); a.push(w); hiliteNode(a);}
var cx = Math.round(x*grChipSize/600); var cx = Math.round(x*grChipSize/600);
var cy = Math.round(y*grChipSize/600); var cy = Math.round(y*grChipSize/600);
if(w==-1) { // prepare two lines of status report
setStatus('x: '+cx, 'y: '+cy);
} else {
var s1='x: ' + cx + ' y: ' + cy; 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); setStatus(s1, s2);
if(ctrace) console.log(s1, s2); if(ctrace) console.log(s1, s2);
}
} }
function updateLoglevel(value){ function updateLoglevel(value){
@ -366,7 +521,7 @@ var consolebox;
function setupConsole(){ function setupConsole(){
consolebox=document.getElementById('consolebox'); consolebox=document.getElementById('consolebox');
consolebox.onkeypress=function(e){consolegetc=e.charCode;}; consolebox.onkeypress=function(e){consolegetc=e.charCode || e.keyCode;};
} }
var chipsurround; var chipsurround;
@ -409,8 +564,19 @@ function setupChipLayoutGraphics(){
refresh(); refresh();
document.getElementById('waiting').style.display = 'none'; document.getElementById('waiting').style.display = 'none';
setStatus('Ready!'); // would prefer chipStatus but it's not idempotent 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) if(moveHereFirst!=null)
moveHere(moveHereFirst); 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 // grant focus to the chip display to enable zoom keys
chipsurround.focus(); chipsurround.focus();
chipsurround.onmousedown = function(e){mouseDown(e);}; 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 /> <br />
Mouse controls: Left-click and drag to scroll around (when you're zoomed in.) Mouse controls: Left-click and drag to scroll around (when you're zoomed in.)
<br /> <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 />
<br /> <br />
</span> </span>
<div class="frame" id="frame"> <div class="frame" id="frame">
<div class="chip" id="chip"> <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="overlay"></canvas>
<canvas class="chip" id="hilite"></canvas> <canvas class="chip" id="hilite"></canvas>
<canvas class="chip" id="hitbuffer"></canvas> <canvas class="chip" id="hitbuffer"></canvas>
</div> </div>
<div class = "buttons"> <div class = "buttons">
<div style="position:relative; float:left;"> <div style="position:relative; float:left;">
<a href ="javascript:stopChip()"id="stop"><img class="navstop" src="images/stop.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"></a> <a href ="javascript:runChip()" id="start"><img class="navplay" src="images/play.png" title="start"></a>
</div> </div>
<div style="float:left;"> <div style="float:left;">
<a href ="javascript:resetChip()"><img class="navbutton" src="images/up.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"></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"></a> <a href ="javascript:stepForward()"><img class="navbutton" src="images/next.png" title="step"></a>
</div> </div>
<div style="float:right; margin-left:20px;">... or try <a href="expert.html">Advanced</a></div> <div style="float:right; margin-left:20px;">... or try <a href="expert.html">Advanced</a></div>
</div> </div>
@ -97,7 +97,7 @@ More information in the <a href="http://visual6502.org/wiki/index.php?title=Jssi
<br /> <br />
<br /> <br />
Source code is available on <a href="http://github.com/trebonian/visual6502">github visual6502</a>. 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 and <a href="http://www.e-tradition.net/bytes/6502/disassembler.html">disassembler</a> from e-tradition.net
<br /> <br />
For in-depth 6502 investigation and some more advanced features, try our <a href="expert.html">Advanced</a> page. 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; height: 600px;
} }
object.chipbg {
position: absolute;
width: 600px;
height: 600px;
}
div.buttons{ div.buttons{
position: absolute; position: absolute;
top: -5px; top: -5px;

View File

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

View File

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

View File

@ -82,7 +82,7 @@ x4: 85,
x5: 589, x5: 589,
x6: 448, x6: 448,
x7: 777, 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, pcl1: 1022,
pcl2: 655, pcl2: 655,
pcl3: 1359, pcl3: 1359,
@ -90,14 +90,30 @@ pcl4: 900,
pcl5: 622, pcl5: 622,
pcl6: 377, pcl6: 377,
pcl7: 1611, pcl7: 1611,
pclp0: 1227, // machine state: program counter low (pre-incremented?, second storage node) pclp0: 488, // machine state: program counter low (pre-incremented?, second storage node)
pclp1: 1102, pclp1: 976,
pclp2: 1079, pclp2: 481,
pclp3: 868, pclp3: 723,
pclp4: 39, pclp4: 208,
pclp5: 1326, pclp5: 72,
pclp6: 731, pclp6: 1458,
pclp7: 536, 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) pch0: 1670, // machine state: program counter high (first storage node)
pch1: 292, pch1: 292,
pch2: 502, pch2: 502,
@ -106,22 +122,50 @@ pch4: 948,
pch5: 49, pch5: 49,
pch6: 1551, pch6: 1551,
pch7: 205, pch7: 205,
pchp0: 780, // machine state: program counter high (pre-incremented?, second storage node) pchp0: 1722, // machine state: program counter high (pre-incremented?, second storage node output)
pchp1: 113, pchp1: 209,
pchp2: 114, pchp2: 1496,
pchp3: 124, pchp3: 141,
pchp4: 820, pchp4: 27,
pchp5: 33, pchp5: 1301,
pchp6: 751, pchp6: 652,
pchp7: 535, pchp7: 1206,
p0: 687, // machine state: status register "#pchp0": 780, // machine state: program counter high (pre-incremented?, inverse second storage node)
p1: 1444, "~pchp0": 780, // automatic alias replacing hash with tilde
p2: 1421, "#pchp1": 113,
p3: 439, "~pchp1": 113, // automatic alias replacing hash with tilde
p4: 1119, // there is no bit4 in the status register! "#pchp2": 114,
p5: -1, // there is no bit5 in the status register! "~pchp2": 114, // automatic alias replacing hash with tilde
p6: 77, "#pchp3": 124,
p7: 1370, "~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 s0: 1403, // machine state: stack pointer
s1: 183, s1: 183,
s2: 81, s2: 81,
@ -146,13 +190,31 @@ notir4: 26,
notir5: 1394, notir5: 1394,
notir6: 895, notir6: 895,
notir7: 1320, notir7: 1320,
irline3: 996, // internal signal: PLA input - ir0 AND ir1 irline3: 996, // internal signal: PLA input - ir0 OR ir1
clock1: 1536, // internal state: timing control clock1: 1536, // internal state: timing control aka #T0
clock2: 156, // internal state: timing control 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 t2: 971, // internal state: timing control
t3: 1567, t3: 1567,
t4: 690, t4: 690,
t5: 909, 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 nots0: 418, // datapath state: not stack pointer
nots1: 1064, nots1: 1064,
nots2: 752, nots2: 752,
@ -185,7 +247,8 @@ sb4: 1405,
sb5: 166, sb5: 166,
sb6: 1336, sb6: 1336,
sb7: 1001, 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, notalu1: 697,
notalu2: 276, notalu2: 276,
notalu3: 495, notalu3: 495,
@ -193,7 +256,7 @@ notalu4: 1490,
notalu5: 893, notalu5: 893,
notalu6: 68, notalu6: 68,
notalu7: 1123, notalu7: 1123,
alu0: 401, // datapath signal: ALU output alu0: 401, // datapath signal: ALU output aka ADD0out
alu1: 872, alu1: 872,
alu2: 1637, alu2: 1637,
alu3: 1414, alu3: 1414,
@ -210,7 +273,7 @@ dasb4: 1405, // same node as sb4
dasb5: 263, dasb5: 263,
dasb6: 679, dasb6: 679,
dasb7: 1494, dasb7: 1494,
adl0: 413, // internal state: address latch low adl0: 413, // internal bus: address low
adl1: 1282, adl1: 1282,
adl2: 1242, adl2: 1242,
adl3: 684, adl3: 684,
@ -218,7 +281,7 @@ adl4: 1437,
adl5: 1630, adl5: 1630,
adl6: 121, adl6: 121,
adl7: 1299, adl7: 1299,
adh0: 407, // internal state: address latch high adh0: 407, // internal bus: address high
adh1: 52, adh1: 52,
adh2: 1651, adh2: 1651,
adh3: 315, adh3: 315,
@ -226,7 +289,7 @@ adh4: 1160,
adh5: 483, adh5: 483,
adh6: 13, adh6: 13,
adh7: 1539, adh7: 1539,
idb0: 1108, // internal state: data buffer idb0: 1108, // internal bus: data bus
idb1: 991, idb1: 991,
idb2: 1473, idb2: 1473,
idb3: 1302, idb3: 1302,
@ -266,16 +329,85 @@ pd4: 369,
pd5: 829, pd5: 829,
pd6: 1669, pd6: 1669,
pd7: 1690, 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: 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 Reset0: 67, // internal signal: retimed reset from pin
C1x5Reset: 926, // retimed and pipelined reset in progress C1x5Reset: 926, // retimed and pipelined reset in progress
notRnWprepad: 187, // internal signal: to pad, yet to be inverted and retimed 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 cp1: 710, // internal signal: clock phase 1
cclk: 943, // unbonded pad: internal non-overlappying phi2 cclk: 943, // unbonded pad: internal non-overlappying phi2
fetch: 879, // internal signal fetch: 879, // internal signal
clearIR: 1077, // internal signal clearIR: 1077, // internal signal
D1x1: 827, // internal signal: interrupt handler related
H1x1: 1042, // internal signal: drive status byte onto databus H1x1: 1042, // internal signal: drive status byte onto databus
// internal signal: pla outputs block 1 (west/left edge of die) // 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) "x-op-push/pull":1050, // pla121 // feeds into pla130 (no normal pla output)
"op-T0-cld/sed":1419, // pla122 "op-T0-cld/sed":1419, // pla122
"#op-branch-bit6":840, // pla123 // IR bit6 used only to detect branch type "#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-T3-mem-abs":607, // pla124
"op-T2-mem-zp":219, // pla125 "op-T2-mem-zp":219, // pla125
"op-T5-mem-ind-idx":1385, // pla126 "op-T5-mem-ind-idx":1385, // pla126
"op-T4-mem-abs-idx":281, // pla127 "op-T4-mem-abs-idx":281, // pla127
"#op-branch-bit7":1174, // pla128 // IR bit7 used only to detect branch type "#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-clv":1164, // pla129
"op-implied":1006, // pla130 // has extra pulldowns: pla121 and ir0 "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 // internal signals: control signals
nnT2BR: 967, // doubly inverted 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) // 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, pipeUNK01: 1530,
pipeUNK02: 974, pipeUNK02: 974,
pipeUNK03: 1436, pipeUNK03: 1436,
@ -477,20 +664,25 @@ pipeUNK34: 56,
pipeUNK35: 1713, pipeUNK35: 1713,
pipeUNK36: 729, pipeUNK36: 729,
pipeUNK37: 197, pipeUNK37: 197,
pipeUNK38: 1131, "pipe#WR.phi2": 1131,
"pipe~WR.phi2": 1131, // automatic alias replacing hash with tilde
pipeUNK39: 151, pipeUNK39: 151,
pipeUNK40: 456, pipeUNK40: 456,
pipeUNK41: 1438, pipeUNK41: 1438,
pipeUNK42: 1104, 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 // internal state: vector address pulldown control
pipeVectorA0: 357, pipeVectorA0: 357,
pipeVectorA1: 170, pipeVectorA1: 170,
pipeVectorA2: 45, pipeVectorA2: 45,
// internal signals: vector address pulldown control
"0/ADL0": 217,
"0/ADL1": 686,
"0/ADL2": 1193,
// internal state: datapath control drivers // internal state: datapath control drivers
pipedpc28: 683, pipedpc28: 683,
@ -512,17 +704,167 @@ alub5: 1678,
alub6: 235, alub6: 235,
alub7: 1535, alub7: 1535,
aluanorb0: 143, // alu carry chain and decimal mode
aluanandb0: 1628, C01: 1285,
aluaorb0: 693, C12: 505,
notaluoutmux0: 957, // alu result latch input 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, // misc alu internals
aluanandb1: 841, "#(AxBxC)0": 371,
aluaorb1: 1021, "~(AxBxC)0": 371, // automatic alias replacing hash with tilde
notaluoutmux1: 250, // alu result latch input "#(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 // 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 dpc0_YSB: 801, // drive sb from y
dpc1_SBY: 325, // load y from sb dpc1_SBY: 325, // load y from sb
dpc2_XSB: 1263, // drive sb from x 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 (?) dpc17_SUMS: 921, // alu op: a plus b (?)
alucin: 910, // alu carry in alucin: 910, // alu carry in
notalucin: 1165, 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 dpc19_ADDSB7: 214, // alu to sb bit 7 only
dpc20_ADDSB06: 129, // alu to sb bits 6-0 only dpc20_ADDSB06: 129, // alu to sb bits 6-0 only
dpc21_ADDADL: 1015, // alu to adl dpc21_ADDADL: 1015, // alu to adl
alurawcout: 808, // alu raw carry out (no decimal adjust) alurawcout: 808, // alu raw carry out (no decimal adjust)
notalucout: 412, // alu carry out (inverted)
alucout: 1146, // alu carry out (latched by phi2) 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 notaluvout: 1308, // alu overflow out
aluvout: 938, // alu overflow out (latched by phi2) 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 dpc23_SBAC: 534, // (optionalls decimal-adjusted) sb to acc
dpc24_ACSB: 1698, // acc to sb 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 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 dpc28_0ADH0: 229, // zero to adh0 bit0 only
dpc29_0ADH17: 203, // zero to adh bits 7-1 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 dpc32_PCHADH: 1235, // drive adh from pch incremented
dpc33_PCHDB: 247, // drive idb from pch incremented dpc33_PCHDB: 247, // drive idb from pch incremented
dpc34_PCLC: 1704, // pch carry in and pcl FF detect? dpc34_PCLC: 1704, // pch carry in and pcl FF detect?
dpc35: 1334, // pcl 0x?F detect - half-carry dpc35_PCHC: 1334, // pcl 0x?F detect - half-carry
dpc36_IPC: 379, // pcl carry in "dpc36_#IPC": 379, // pcl carry in (inverted)
"dpc36_~IPC": 379, // automatic alias replacing hash with tilde
dpc37_PCLDB: 283, // drive idb from pcl incremented dpc37_PCLDB: 283, // drive idb from pcl incremented
dpc38_PCLADL: 438, // drive adl from pcl incremented dpc38_PCLADL: 438, // drive adl from pcl incremented
dpc39_PCLPCL: 898, // load pcl from pcl incremented dpc39_PCLPCL: 898, // load pcl from pcl incremented
dpc40_ADLPCL: 414, // load pcl from adl dpc40_ADLPCL: 414, // load pcl from adl
dpc41: 1564, // pass-connect adl to mux node driven by idl "dpc41_DL/ADL": 1564,// pass-connect adl to mux node driven by idl
dpc42: 41, // pass-connect adh to mux node driven by idl "dpc42_DL/ADH": 41, // pass-connect adh to mux node driven by idl
dpc43: 863, // pass-connect idb 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 frame, chipbg, overlay, hilite, hitbuffer, ctx;
var nodes = new Array(); var nodes = new Array();
var lastState = new Array();
var polyAttr = new Array();
var metalAttr = new Array();
var polyOffFill;
var metalOffFill;
var transistors = {}; var transistors = {};
var nodenamelist=[]; var nodenamelist=[];
@ -29,6 +34,7 @@ var ngnd = nodenames['vss'];
var npwr = nodenames['vcc']; var npwr = nodenames['vcc'];
var chipLayoutIsVisible = true; // only modified in expert mode var chipLayoutIsVisible = true; // only modified in expert mode
var hilited = [];
function setupNodes(){ function setupNodes(){
for(var i in segdefs){ for(var i in segdefs){
@ -39,6 +45,7 @@ function setupNodes(){
state: false, gates: new Array(), c1c2s: new Array()}; state: false, gates: new Array(), c1c2s: new Array()};
if(w==ngnd) continue; if(w==ngnd) continue;
if(w==npwr) continue; if(w==npwr) continue;
lastState[i] = 0;
nodes[w].segs.push(seg.slice(3)); nodes[w].segs.push(seg.slice(3));
} }
} }
@ -50,9 +57,10 @@ function setupTransistors(){
var gate = tdef[1]; var gate = tdef[1];
var c1 = tdef[2]; var c1 = tdef[2];
var c2 = tdef[3]; var c2 = tdef[3];
var bb = tdef[4];
if(c1==ngnd) {c1=c2;c2=ngnd;} if(c1==ngnd) {c1=c2;c2=ngnd;}
if(c1==npwr) {c1=c2;c2=npwr;} 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[gate].gates.push(trans);
nodes[c1].c1c2s.push(trans); nodes[c1].c1c2s.push(trans);
nodes[c2].c1c2s.push(trans); nodes[c2].c1c2s.push(trans);
@ -71,8 +79,20 @@ function setupLayerVisibility(){
function setupBackground(){ function setupBackground(){
chipbg = document.getElementById('chipbg'); chipbg = document.getElementById('chipbg');
chipbg.width = grCanvasSize; chipbg.width = 4000;
chipbg.height = grCanvasSize; 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'); var ctx = chipbg.getContext('2d');
ctx.fillStyle = '#000000'; ctx.fillStyle = '#000000';
ctx.strokeStyle = 'rgba(255,255,255,0.5)'; ctx.strokeStyle = 'rgba(255,255,255,0.5)';
@ -91,10 +111,10 @@ function setupBackground(){
} }
function setupOverlay(){ function setupOverlay(){
overlay = document.getElementById('overlay'); // overlay = document.getElementById('overlay');
overlay.width = grCanvasSize; // overlay.width = grCanvasSize;
overlay.height = grCanvasSize; // overlay.height = grCanvasSize;
ctx = overlay.getContext('2d'); // ctx = overlay.getContext('2d');
} }
function setupHilite(){ function setupHilite(){
@ -135,34 +155,103 @@ function hexdigit(n){return '0123456789ABCDEF'.charAt(n);}
function refresh(){ function refresh(){
if(!chipLayoutIsVisible) return; 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){ 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){ //function overlayNode(w){
ctx.fillStyle = 'rgba(255,0,64,0.4)'; // ctx.fillStyle = 'rgba(255,0,64,0.4)';
for(i in w) { // for(i in w) {
drawSeg(ctx, w[i]); // drawSeg(ctx, w[i]);
ctx.fill(); // ctx.fill();
} // }
} //}
// originally to highlight using a list of node numbers
// but can now include transistor names
function hiliteNode(n){ function hiliteNode(n){
var ctx = hilite.getContext('2d'); var ctx = hilite.getContext('2d');
ctx.clearRect(0,0,grCanvasSize,grCanvasSize); ctx.clearRect(0,0,grCanvasSize,grCanvasSize);
ctx.fillStyle = 'rgba(255,255,255,0.7)';
if(n==-1) return; if(n==-1) return;
if(isNodeHigh(n[0])) hilited = n;
ctx.fillStyle = 'rgba(255,0,0,0.7)';
for(var i in 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; var segs = nodes[n[i]].segs;
for(var s in segs){drawSeg(ctx, segs[s]); ctx.fill();} 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){ function drawSeg(ctx, seg){
var dx = 400; var dx = 400;
ctx.beginPath(); ctx.beginPath();