├── .gitattributes ├── .gitignore ├── 3rdparty ├── img │ ├── hgrabber.gif │ ├── vdockbar.gif │ ├── vgrabber.gif │ ├── vgrabber2-active.gif │ └── vgrabber2-normal.gif ├── jquery-1.3.2.min.js ├── jquery.cookie.js └── splitter.js ├── README ├── browsertrouble.html ├── chip-6800 ├── nodenames.js ├── segdefs.js ├── support.js ├── testprogram.js └── transdefs.js ├── chip-z80 ├── nodenames.js ├── segdefs.js ├── support.js ├── testprogram.js └── transdefs.js ├── chipsim.js ├── expert-6800.html ├── expert-allinone.js ├── expert-z80.html ├── expert.css ├── expert.html ├── expertWires.js ├── images ├── fastforward.png ├── jssim2.png ├── next.png ├── play.png ├── prev.png ├── singlestep.png ├── stop.png └── up.png ├── index.html ├── kiosk.css ├── kioskWires.js ├── macros.js ├── memtable.js ├── nodenames.js ├── segdefs.js ├── testprogram.js ├── transdefs.js └── wires.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.js text 3 | *.css text 4 | *.html text 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # emacs-style backup files 2 | *~ 3 | # patch detritus 4 | *.orig 5 | *.rej 6 | -------------------------------------------------------------------------------- /3rdparty/img/hgrabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trebonian/visual6502/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/3rdparty/img/hgrabber.gif -------------------------------------------------------------------------------- /3rdparty/img/vdockbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trebonian/visual6502/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/3rdparty/img/vdockbar.gif -------------------------------------------------------------------------------- /3rdparty/img/vgrabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trebonian/visual6502/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/3rdparty/img/vgrabber.gif -------------------------------------------------------------------------------- /3rdparty/img/vgrabber2-active.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trebonian/visual6502/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/3rdparty/img/vgrabber2-active.gif -------------------------------------------------------------------------------- /3rdparty/img/vgrabber2-normal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trebonian/visual6502/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/3rdparty/img/vgrabber2-normal.gif -------------------------------------------------------------------------------- /3rdparty/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cookie plugin 3 | * 4 | * Copyright (c) 2006 Klaus Hartl (stilbuero.de) 5 | * Dual licensed under the MIT and GPL licenses: 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * http://www.gnu.org/licenses/gpl.html 8 | * 9 | */ 10 | 11 | /** 12 | * Create a cookie with the given name and value and other optional parameters. 13 | * 14 | * @example $.cookie('the_cookie', 'the_value'); 15 | * @desc Set the value of a cookie. 16 | * @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true}); 17 | * @desc Create a cookie with all available options. 18 | * @example $.cookie('the_cookie', 'the_value'); 19 | * @desc Create a session cookie. 20 | * @example $.cookie('the_cookie', null); 21 | * @desc Delete a cookie by passing null as value. 22 | * 23 | * @param String name The name of the cookie. 24 | * @param String value The value of the cookie. 25 | * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. 26 | * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. 27 | * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. 28 | * If set to null or omitted, the cookie will be a session cookie and will not be retained 29 | * when the the browser exits. 30 | * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). 31 | * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). 32 | * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will 33 | * require a secure protocol (like HTTPS). 34 | * @type undefined 35 | * 36 | * @name $.cookie 37 | * @cat Plugins/Cookie 38 | * @author Klaus Hartl/klaus.hartl@stilbuero.de 39 | */ 40 | 41 | /** 42 | * Get the value of a cookie with the given name. 43 | * 44 | * @example $.cookie('the_cookie'); 45 | * @desc Get the value of a cookie. 46 | * 47 | * @param String name The name of the cookie. 48 | * @return The value of the cookie. 49 | * @type String 50 | * 51 | * @name $.cookie 52 | * @cat Plugins/Cookie 53 | * @author Klaus Hartl/klaus.hartl@stilbuero.de 54 | */ 55 | jQuery.cookie = function(name, value, options) { 56 | if (typeof value != 'undefined') { // name and value given, set cookie 57 | options = options || {}; 58 | if (value === null) { 59 | value = ''; 60 | options.expires = -1; 61 | } 62 | var expires = ''; 63 | if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { 64 | var date; 65 | if (typeof options.expires == 'number') { 66 | date = new Date(); 67 | date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); 68 | } else { 69 | date = options.expires; 70 | } 71 | expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE 72 | } 73 | var path = options.path ? '; path=' + options.path : ''; 74 | var domain = options.domain ? '; domain=' + options.domain : ''; 75 | var secure = options.secure ? '; secure' : ''; 76 | document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); 77 | } else { // only name given, get cookie 78 | var cookieValue = null; 79 | if (document.cookie && document.cookie != '') { 80 | var cookies = document.cookie.split(';'); 81 | for (var i = 0; i < cookies.length; i++) { 82 | var cookie = jQuery.trim(cookies[i]); 83 | // Does this cookie string begin with the name we want? 84 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 85 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 86 | break; 87 | } 88 | } 89 | } 90 | return cookieValue; 91 | } 92 | }; -------------------------------------------------------------------------------- /3rdparty/splitter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery.splitter.js - two-pane splitter window plugin 3 | * 4 | * version 1.51 (2009/01/09) 5 | * 6 | * Dual licensed under the MIT and GPL licenses: 7 | * http://www.opensource.org/licenses/mit-license.php 8 | * http://www.gnu.org/licenses/gpl.html 9 | */ 10 | 11 | /** 12 | * The splitter() plugin implements a two-pane resizable splitter window. 13 | * The selected elements in the jQuery object are converted to a splitter; 14 | * each selected element should have two child elements, used for the panes 15 | * of the splitter. The plugin adds a third child element for the splitbar. 16 | * 17 | * For more details see: http://methvin.com/splitter/ 18 | * 19 | * 20 | * @example $('#MySplitter').splitter(); 21 | * @desc Create a vertical splitter with default settings 22 | * 23 | * @example $('#MySplitter').splitter({type: 'h', accessKey: 'M'}); 24 | * @desc Create a horizontal splitter resizable via Alt+Shift+M 25 | * 26 | * @name splitter 27 | * @type jQuery 28 | * @param Object options Options for the splitter (not required) 29 | * @cat Plugins/Splitter 30 | * @return jQuery 31 | * @author Dave Methvin (dave.methvin@gmail.com) 32 | */ 33 | ;(function($){ 34 | 35 | $.fn.splitter = function(args){ 36 | args = args || {}; 37 | return this.each(function() { 38 | var zombie; // left-behind splitbar for outline resizes 39 | function startSplitMouse(evt) { 40 | if ( opts.outline ) 41 | zombie = zombie || bar.clone(false).insertAfter(A); 42 | panes.css("-webkit-user-select", "none"); // Safari selects A/B text on a move 43 | bar.addClass(opts.activeClass); 44 | A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos]; 45 | $(document) 46 | .bind("mousemove", doSplitMouse) 47 | .bind("mouseup", endSplitMouse); 48 | } 49 | function doSplitMouse(evt) { 50 | var newPos = A._posSplit+evt[opts.eventPos]; 51 | if ( opts.outline ) { 52 | newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA)); 53 | bar.css(opts.origin, newPos); 54 | } else 55 | resplit(newPos); 56 | } 57 | function endSplitMouse(evt) { 58 | bar.removeClass(opts.activeClass); 59 | var newPos = A._posSplit+evt[opts.eventPos]; 60 | if ( opts.outline ) { 61 | zombie.remove(); zombie = null; 62 | resplit(newPos); 63 | } 64 | panes.css("-webkit-user-select", "text"); // let Safari select text again 65 | $(document) 66 | .unbind("mousemove", doSplitMouse) 67 | .unbind("mouseup", endSplitMouse); 68 | } 69 | function resplit(newPos) { 70 | // Constrain new splitbar position to fit pane size limits 71 | newPos = Math.max(A._min, splitter._DA - B._max, 72 | Math.min(newPos, A._max, splitter._DA - bar._DA - B._min)); 73 | // Resize/position the two panes 74 | bar._DA = bar[0][opts.pxSplit]; // bar size may change during dock 75 | bar.css(opts.origin, newPos).css(opts.fixed, splitter._DF); 76 | A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF); 77 | B.css(opts.origin, newPos+bar._DA) 78 | .css(opts.split, splitter._DA-bar._DA-newPos).css(opts.fixed, splitter._DF); 79 | // IE fires resize for us; all others pay cash 80 | if ( !$.browser.msie ) 81 | panes.trigger("resize"); 82 | } 83 | function dimSum(jq, dims) { 84 | // Opera returns -1 for missing min/max width, turn into 0 85 | var sum = 0; 86 | for ( var i=1; i < arguments.length; i++ ) 87 | sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0); 88 | return sum; 89 | } 90 | 91 | // Determine settings based on incoming opts, element classes, and defaults 92 | var vh = (args.splitHorizontal? 'h' : args.splitVertical? 'v' : args.type) || 'v'; 93 | var opts = $.extend({ 94 | activeClass: 'active', // class name for active splitter 95 | pxPerKey: 8, // splitter px moved per keypress 96 | tabIndex: 0, // tab order indicator 97 | accessKey: '' // accessKey for splitbar 98 | },{ 99 | v: { // Vertical splitters: 100 | keyLeft: 39, keyRight: 37, cursor: "e-resize", 101 | splitbarClass: "vsplitbar", outlineClass: "voutline", 102 | type: 'v', eventPos: "pageX", origin: "left", 103 | split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right", 104 | fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom" 105 | }, 106 | h: { // Horizontal splitters: 107 | keyTop: 40, keyBottom: 38, cursor: "n-resize", 108 | splitbarClass: "hsplitbar", outlineClass: "houtline", 109 | type: 'h', eventPos: "pageY", origin: "top", 110 | split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom", 111 | fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right" 112 | } 113 | }[vh], args); 114 | 115 | // Create jQuery object closures for splitter and both panes 116 | var splitter = $(this).css({position: "relative"}); 117 | var panes = $(">*", splitter[0]).css({ 118 | position: "absolute", // positioned inside splitter container 119 | "z-index": "1", // splitbar is positioned above 120 | "-moz-outline-style": "none" // don't show dotted outline 121 | }); 122 | var A = $(panes[0]); // left or top 123 | var B = $(panes[1]); // right or bottom 124 | 125 | // Focuser element, provides keyboard support; title is shown by Opera accessKeys 126 | var focuser = $('') 127 | .attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass}) 128 | .bind($.browser.opera?"click":"focus", function(){ this.focus(); bar.addClass(opts.activeClass) }) 129 | .bind("keydown", function(e){ 130 | var key = e.which || e.keyCode; 131 | var dir = key==opts["key"+opts.side1]? 1 : key==opts["key"+opts.side2]? -1 : 0; 132 | if ( dir ) 133 | resplit(A[0][opts.pxSplit]+dir*opts.pxPerKey, false); 134 | }) 135 | .bind("blur", function(){ bar.removeClass(opts.activeClass) }); 136 | 137 | // Splitbar element, can be already in the doc or we create one 138 | var bar = $(panes[2] || '
') 139 | .insertAfter(A).css("z-index", "100").append(focuser) 140 | .attr({"class": opts.splitbarClass, unselectable: "on"}) 141 | .css({position: "absolute", "user-select": "none", "-webkit-user-select": "none", 142 | "-khtml-user-select": "none", "-moz-user-select": "none"}) 143 | .bind("mousedown", startSplitMouse); 144 | // Use our cursor unless the style specifies a non-default cursor 145 | if ( /^(auto|default|)$/.test(bar.css("cursor")) ) 146 | bar.css("cursor", opts.cursor); 147 | 148 | // Cache several dimensions for speed, rather than re-querying constantly 149 | bar._DA = bar[0][opts.pxSplit]; 150 | splitter._PBF = $.boxModel? dimSum(splitter, "border"+opts.side3+"Width", "border"+opts.side4+"Width") : 0; 151 | splitter._PBA = $.boxModel? dimSum(splitter, "border"+opts.side1+"Width", "border"+opts.side2+"Width") : 0; 152 | A._pane = opts.side1; 153 | B._pane = opts.side2; 154 | $.each([A,B], function(){ 155 | this._min = opts["min"+this._pane] || dimSum(this, "min-"+opts.split); 156 | this._max = opts["max"+this._pane] || dimSum(this, "max-"+opts.split) || 9999; 157 | this._init = opts["size"+this._pane]===true ? 158 | parseInt($.curCSS(this[0],opts.split)) : opts["size"+this._pane]; 159 | }); 160 | 161 | // Determine initial position, get from cookie if specified 162 | var initPos = A._init; 163 | if ( !isNaN(B._init) ) // recalc initial B size as an offset from the top or left side 164 | initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA; 165 | if ( opts.cookie ) { 166 | if ( !$.cookie ) 167 | alert('jQuery.splitter(): jQuery cookie plugin required'); 168 | var ckpos = parseInt($.cookie(opts.cookie)); 169 | if ( !isNaN(ckpos) ) 170 | initPos = ckpos; 171 | $(window).bind("unload", function(){ 172 | var state = String(bar.css(opts.origin)); // current location of splitbar 173 | $.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365, 174 | path: opts.cookiePath || document.location.pathname}); 175 | }); 176 | } 177 | if ( isNaN(initPos) ) // King Solomon's algorithm 178 | initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA)/2); 179 | 180 | // Resize event propagation and splitter sizing 181 | if ( opts.anchorToWindow ) { 182 | // Account for margin or border on the splitter container and enforce min height 183 | splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom"); 184 | splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20); 185 | $(window).bind("resize", function(){ 186 | var top = splitter.offset().top; 187 | var wh = $(window).height(); 188 | splitter.css("height", Math.max(wh-top-splitter._hadjust, splitter._hmin)+"px"); 189 | if ( !$.browser.msie ) splitter.trigger("resize"); 190 | }).trigger("resize"); 191 | } 192 | else if ( opts.resizeToWidth && !$.browser.msie ) 193 | $(window).bind("resize", function(){ 194 | splitter.trigger("resize"); 195 | }); 196 | 197 | // Resize event handler; triggered immediately to set initial position 198 | splitter.bind("resize", function(e, size){ 199 | // Custom events bubble in jQuery 1.3; don't Yo Dawg 200 | if ( e.target != this ) return; 201 | // Determine new width/height of splitter container 202 | splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF; 203 | splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA; 204 | // Bail if splitter isn't visible or content isn't there yet 205 | if ( splitter._DF <= 0 || splitter._DA <= 0 ) return; 206 | // Re-divvy the adjustable dimension; maintain size of the preferred pane 207 | resplit(!isNaN(size)? size : (!(opts.sizeRight||opts.sizeBottom)? A[0][opts.pxSplit] : 208 | splitter._DA-B[0][opts.pxSplit]-bar._DA)); 209 | }).trigger("resize" , [initPos]); 210 | }); 211 | }; 212 | 213 | })(jQuery); -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the JavaScript simulator from the visual6502.org project: 2 | www.visual6502.org/JSSim 3 | 4 | It includes a general purpose transistor-level simulator, layout browser, 5 | and the data from a 6502 revD chip. 6 | 7 | It also includes a similar simulator for the 6800 chip. 8 | 9 | Note the various licenses and Copyright associated with each file. 10 | 11 | Enjoy! 12 | - The Visual 6502 Team 13 | -------------------------------------------------------------------------------- /browsertrouble.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Visual 6502 in JavaScript 5 | 6 | 7 | 8 | 9 | The Visual 6502 10 | 11 |
12 | Browser Trouble? 13 |
14 | FAQ  15 | Blog  16 | Links  17 |

18 | Our chip simulator makes heavy use of the latest version of HTML5 drawing technology. 19 |

20 | It will only run on recent browsers and on a computer with sufficient memory (we recommend at least 2Gbytes.) 21 |

22 | We've tested it on Chrome, Firefox, Safari and Opera. Unfortunately Internet Explorer isn't yet capable of running the graphics. 23 |

24 | If you're using one of the above browsers and having trouble, please restart the browser. 25 |

26 | If you have a problem report or you're able to help us with compatilibity, please get in touch - our contact details are on the main page. 27 |

28 | In the meantime, here's a picture of what you're missing: 29 |

30 | 31 | 32 | 33 | 41 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /chip-6800/nodenames.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Ijor, Segher Boessenkool, Ed Spittles 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var nodenames ={ 24 | gnd: 663, // pads: ground 25 | vcc: 31, // pads: power 26 | phi1: 1507, // pads: phase 1 clock input 27 | phi2: 1511, // pads: phase 2 clock input 28 | reset: 1461, // pads: reset 29 | 30 | db0: 686, // pads: data bus (should really be called d) 31 | db1: 683, 32 | db2: 677, 33 | db3: 676, 34 | db4: 669, 35 | db5: 670, 36 | db6: 664, 37 | db7: 691, 38 | 39 | ab0: 1854, // pads: address bus (should really be called a) 40 | ab1: 1857, 41 | ab2: 1855, 42 | ab3: 1858, 43 | ab4: 1856, 44 | ab5: 1859, 45 | ab6: 1860, 46 | ab7: 1865, 47 | ab8: 1861, 48 | ab9: 1863, 49 | ab10: 1862, 50 | ab11: 1864, 51 | ab12: 1948, 52 | ab13: 1946, 53 | ab14: 1949, 54 | ab15: 1947, 55 | 56 | irq: 1496, // input pads: interrupt request (active low) 57 | nmi: 1501, // pads: non maskable interrupt (active low) 58 | dbe: 1456, // pads: data bus enable 59 | halt: 1492, // pads: halt (active low) 60 | tsc: 1459, // pads: tristate control 61 | rw: 1965, // output pads: read / not write 62 | vma: 1971, // pads: valid memory address 63 | ba: 1964, // pads: bus available 64 | // 65 | 66 | // major internal busses 67 | 68 | idb0: 610, // internal databus (should be called db) 69 | idb1: 1593, 70 | idb2: 387, 71 | idb3: 386, 72 | idb4: 311, 73 | idb5: 310, 74 | idb6: 393, 75 | idb7: 1651, 76 | 77 | abh0: 267, // internal bus: address bus high 78 | abh1: 258, 79 | abh2: 266, 80 | abh3: 257, 81 | abh4: 265, 82 | abh5: 256, 83 | abh6: 259, 84 | abh7: 255, 85 | 86 | abl0: 1670, // internal bus: address bus low 87 | abl1: 1671, 88 | abl2: 1653, 89 | abl3: 1667, 90 | abl4: 1655, 91 | abl5: 1657, 92 | abl6: 1656, 93 | abl7: 1658, 94 | 95 | ablx0: 1683, // internal bus: extension of abl bus 96 | ablx1: 1682, 97 | ablx2: 1689, 98 | ablx3: 1687, 99 | ablx4: 1694, 100 | ablx5: 1693, 101 | ablx6: 1698, 102 | ablx7: 1697, 103 | 104 | i0: 1271, // pla word lines 105 | i1: 1269, 106 | i2: 1268, 107 | i3: 1267, 108 | i4: 1265, 109 | i5: 1264, 110 | i6: 1263, 111 | i7: 1261, 112 | 113 | // programmer-visible state 114 | 115 | flagc: 1160, // status word flags 116 | flagh: 785, 117 | flagi: 1007, 118 | flagn: 1005, 119 | flagv: 1124, 120 | flagz: 1026, 121 | 122 | acca0: 1934, // a register: accumulator a 123 | acca1: 1688, 124 | acca2: 1700, 125 | acca3: 1699, 126 | acca4: 1701, 127 | acca5: 1702, 128 | acca6: 1703, 129 | acca7: 1784, 130 | 131 | accb0: 1919, // b register: accumulator b 132 | accb1: 1927, 133 | accb2: 1921, 134 | accb3: 1929, 135 | accb4: 1923, 136 | accb5: 1931, 137 | accb6: 1925, 138 | accb7: 1933, 139 | 140 | ixh0: 1910, // index register high 141 | ixh1: 1914, 142 | ixh2: 1911, 143 | ixh3: 1915, 144 | ixh4: 1912, 145 | ixh5: 1916, 146 | ixh6: 1913, 147 | ixh7: 1917, 148 | ixl0: 1918, // index register low 149 | ixl1: 1926, 150 | ixl2: 1920, 151 | ixl3: 1928, 152 | ixl4: 1922, 153 | ixl5: 1930, 154 | ixl6: 1924, 155 | ixl7: 1932, 156 | 157 | pch0: 1878, // program counter high register 158 | pch1: 1882, 159 | pch2: 1879, 160 | pch3: 1883, 161 | pch4: 1880, 162 | pch5: 1884, 163 | pch6: 1881, 164 | pch7: 1885, 165 | pcl0: 1877, // program counter low register 166 | pcl1: 1873, 167 | pcl2: 1876, 168 | pcl3: 1872, 169 | pcl4: 1875, 170 | pcl5: 1871, 171 | pcl6: 1874, 172 | pcl7: 1870, 173 | 174 | sph0: 1909, // stack pointer high register 175 | sph1: 1908, 176 | sph2: 1907, 177 | sph3: 1906, 178 | sph4: 1905, 179 | sph5: 1904, 180 | sph6: 1903, 181 | sph7: 1902, 182 | spl0: 1894, // stack pointer low register 183 | spl1: 1898, 184 | spl2: 1895, 185 | spl3: 1899, 186 | spl4: 1896, 187 | spl5: 1900, 188 | spl6: 1897, 189 | spl7: 1901, 190 | 191 | // datapath state not visible to the programmer 192 | 193 | tmp0: 1893, // non-visible temporary register 194 | tmp1: 1892, 195 | tmp2: 1891, 196 | tmp3: 1890, 197 | tmp4: 1889, 198 | tmp5: 1888, 199 | tmp6: 1887, 200 | tmp7: 1886, 201 | 202 | sum0: 644, // alu output (phi2-latched) 203 | sum1: 643, 204 | sum2: 642, 205 | sum3: 641, 206 | sum4: 640, 207 | sum5: 639, 208 | sum6: 638, 209 | sum7: 412, 210 | 211 | dbi0: 608, // data bus input register 212 | dbi1: 599, 213 | dbi2: 598, 214 | dbi3: 400, 215 | dbi4: 405, 216 | dbi5: 395, 217 | dbi6: 389, 218 | dbi7: 650, 219 | 220 | dbo0: 609, // data bus output latch 221 | dbo1: 602, 222 | dbo2: 601, 223 | dbo3: 402, 224 | dbo4: 406, 225 | dbo5: 397, 226 | dbo6: 390, 227 | dbo7: 649, 228 | 229 | inch0: 198, // incrementer high output port 230 | inch1: 199, 231 | inch2: 200, 232 | inch3: 201, 233 | inch4: 202, 234 | inch5: 203, 235 | inch6: 204, 236 | inch7: 205, 237 | incl0: 154, // incrementer low output port 238 | incl1: 143, 239 | incl2: 144, 240 | incl3: 147, 241 | incl4: 148, 242 | incl5: 151, 243 | incl6: 152, 244 | incl7: 156, 245 | 246 | obl0: 27, // output buffer low (address bus low output latch) 247 | obl1: 30, 248 | obl2: 28, 249 | obl3: 32, 250 | obl4: 29, 251 | obl5: 33, 252 | obl6: 1073, 253 | obl7: 35, 254 | 255 | "#obh0": 1071, // output buffer high (address bus high output latch)) 256 | "#obh1": 819, 257 | "#obh2": 811, 258 | "#obh3": 813, 259 | "#obh4": 817, 260 | "#obh5": 809, 261 | "#obh6": 815, 262 | "#obh7": 574, 263 | 264 | // other internal state 265 | ir0: 1301, // Instruction Register 266 | ir1: 1285, 267 | ir2: 1286, 268 | ir3: 1287, 269 | ir4: 1288, 270 | ir5: 1289, 271 | ir6: 1274, 272 | ir7: 1277, 273 | 274 | // timing state signals 275 | Ts: 1309, 276 | Tf: 849, // aka fetch 277 | Ta0: 879, 278 | Td0_0: 981, 279 | "#Te0": 868, 280 | "Te0.2": 866, 281 | Tg0: 12, 282 | Tx0: 850, 283 | Ta1: 838, 284 | Te1_0: 735, 285 | Tg1: 772, 286 | Tx1: 851, 287 | Ta2: 844, 288 | Tg2: 832, 289 | Tx2: 860, 290 | Tg3: 835, 291 | Tr3: 823, 292 | Tg4: 696, 293 | Tr4: 825, 294 | Tg5: 914, 295 | Tr5: 828, 296 | Tg6: 911, 297 | Tr6: 894, 298 | Tr7: 694, 299 | Tg7: 1081, 300 | Tg8: 891, 301 | Tr8: 697, 302 | 303 | // other internal busses registers and signals 304 | 305 | // internal control signals 306 | sync: 1528, // aka #decode_0 307 | 308 | // ALU signals 309 | adda0: 1680, 310 | adda1: 1681, 311 | adda2: 1685, 312 | adda3: 1686, 313 | adda4: 1691, 314 | adda5: 1692, 315 | adda6: 1695, 316 | adda7: 1696, 317 | adda0in: 1938, 318 | adda1in: 1940, 319 | adda2in: 1939, 320 | adda3in: 1942, 321 | adda4in: 1941, 322 | adda5in: 1944, 323 | adda6in: 1943, 324 | adda7in: 1945, 325 | addb0: 569, 326 | addb1: 568, 327 | addb2: 561, 328 | addb3: 560, 329 | addb4: 553, 330 | addb5: 552, 331 | addb6: 545, 332 | addb7: 544, 333 | addg0: 593, 334 | addg1: 594, 335 | addg2: 589, 336 | addg3: 590, 337 | addg4: 585, 338 | addg5: 586, 339 | addg6: 581, 340 | addg7: 582, 341 | addp0: 564, 342 | addp1: 566, 343 | addp2: 556, 344 | addp3: 558, 345 | addp4: 548, 346 | addp5: 550, 347 | addp6: 541, 348 | addp7: 543, 349 | 350 | decode: 1225, 351 | enrwa: 1318, 352 | fetch: 849, // aka Tf 353 | 354 | ob: 1308, // output buffer (read-not-write output latch) 355 | 356 | resg: 1512, 357 | 358 | xi0: 1303, // half-latch prior to IR 359 | xi1: 1291, 360 | xi2: 1294, 361 | xi3: 1292, 362 | xi4: 1295, 363 | xi5: 1293, 364 | xi6: 1275, 365 | xi7: 1276, 366 | 367 | // signals which are not purely alphabetical 368 | // note that underscore digit represents a logical duplication 369 | acca0_1: 342, 370 | acca1_1: 350, 371 | acca2_1: 344, 372 | acca3_1: 352, 373 | acca4_1: 346, 374 | acca5_1: 354, 375 | acca6_1: 348, 376 | acca7_1: 356, 377 | accb0_1: 343, 378 | accb1_1: 351, 379 | accb2_1: 345, 380 | accb3_1: 353, 381 | accb4_1: 347, 382 | accb5_1: 355, 383 | accb6_1: 349, 384 | accb7_1: 357, 385 | ahd0_0: 237, 386 | ahd1_0: 240, 387 | ahd2_0: 236, 388 | ahd3_0: 239, 389 | ahd4_0: 235, 390 | ahd5_0: 238, 391 | ahd6_0: 234, 392 | ahd7_0: 252, 393 | ald0_0: 74, 394 | ald1_0: 71, 395 | ald2_0: 68, 396 | ald3_0: 65, 397 | ald4_0: 62, 398 | ald5_0: 34, 399 | ald6_0: 56, 400 | ald7_0: 53, 401 | ba_0: 1228, 402 | idb0_2: 521, 403 | idb1_2: 520, 404 | idb2_2: 517, 405 | idb3_2: 516, 406 | idb4_2: 513, 407 | idb5_2: 512, 408 | idb6_2: 509, 409 | idb7_2: 508, 410 | decode_1: 1304, 411 | halt_0: 1491, 412 | inchi0_0: 206, 413 | inchi1_0: 208, 414 | inchi2_0: 207, 415 | inchi4_0: 245, 416 | inchi5_0: 243, 417 | inchi6_0: 242, 418 | incli0_0: 89, 419 | incli1_0: 90, 420 | incli2_0: 88, 421 | incli4_0: 93, 422 | incli5_0: 91, 423 | incli6_0: 92, 424 | ir0_1: 1300, 425 | ir1_1: 1280, 426 | ir2_1: 1281, 427 | ir3_1: 1282, 428 | ir4_1: 1283, 429 | ir5_1: 1284, 430 | ir6_1: 1272, 431 | ir7_1: 1273, 432 | ixh0_1: 365, 433 | ixh1_1: 364, 434 | ixh2_1: 363, 435 | ixh3_1: 362, 436 | ixh4_1: 361, 437 | ixh5_1: 360, 438 | ixh6_1: 359, 439 | ixh7_1: 358, 440 | ixl0_1: 373, 441 | ixl1_1: 372, 442 | ixl2_1: 371, 443 | ixl3_1: 370, 444 | ixl4_1: 369, 445 | ixl5_1: 368, 446 | ixl6_1: 367, 447 | ixl7_1: 366, 448 | pch0_1: 197, 449 | pch1_1: 193, 450 | pch2_1: 196, 451 | pch3_1: 192, 452 | pch4_1: 195, 453 | pch5_1: 191, 454 | pch6_1: 194, 455 | pch7_1: 190, 456 | pcl0_1: 153, 457 | pcl1_1: 141, 458 | pcl2_1: 142, 459 | pcl3_1: 145, 460 | pcl4_1: 146, 461 | pcl5_1: 149, 462 | pcl6_1: 150, 463 | pcl7_1: 155, 464 | reset_0: 1462, 465 | sph0_1: 303, 466 | sph1_1: 302, 467 | sph2_1: 301, 468 | sph3_1: 300, 469 | sph4_1: 299, 470 | sph5_1: 298, 471 | sph6_1: 297, 472 | sph7_1: 296, 473 | spl0_1: 295, 474 | spl1_1: 294, 475 | spl2_1: 293, 476 | spl3_1: 292, 477 | spl4_1: 291, 478 | spl5_1: 290, 479 | spl6_1: 289, 480 | spl7_1: 288, 481 | tmp0_1: 284, 482 | tmp1_1: 283, 483 | tmp2_1: 282, 484 | tmp3_1: 281, 485 | tmp4_1: 280, 486 | tmp5_1: 279, 487 | tmp6_1: 278, 488 | tmp7_1: 254, 489 | vma_0: 1498, 490 | phi2_1: 478, 491 | "#abh0_0": 1070, 492 | "#abh0_1": 277, 493 | "#abh1_0": 818, 494 | "#abh1_1": 271, 495 | "#abh2_0": 810, 496 | "#abh2_1": 276, 497 | "#abh3_0": 812, 498 | "#abh3_1": 270, 499 | "#abh4_0": 816, 500 | "#abh4_1": 275, 501 | "#abh5_0": 808, 502 | "#abh5_1": 269, 503 | "#abh6_0": 814, 504 | "#abh6_1": 272, 505 | "#abh7_0": 572, 506 | "#abh7_1": 268, 507 | "#abl0_0": 76, 508 | "#abl10_0": 500, 509 | "#abl11_0": 501, 510 | "#abl12_0": 498, 511 | "#abl13_0": 499, 512 | "#abl14_0": 496, 513 | "#abl15_0": 497, 514 | "#abl16_0": 494, 515 | "#abl17_0": 495, 516 | "#abl1_0": 73, 517 | "#abl2_0": 70, 518 | "#abl3_0": 67, 519 | "#abl4_0": 64, 520 | "#abl5_0": 61, 521 | "#abl6_0": 58, 522 | "#abl7_0": 55, 523 | "#acca0_0": 1710, 524 | "#acca1_0": 1718, 525 | "#acca2_0": 1711, 526 | "#acca3_0": 1719, 527 | "#acca4_0": 1723, 528 | "#acca5_0": 1727, 529 | "#acca6_0": 1731, 530 | "#acca7_0": 1783, 531 | "#accb0_0": 1704, 532 | "#accb1_0": 1712, 533 | "#accb2_0": 1705, 534 | "#accb3_0": 1713, 535 | "#accb4_0": 1720, 536 | "#accb5_0": 1724, 537 | "#accb6_0": 1728, 538 | "#accb7_0": 1732, 539 | "#addb0_0": 492, 540 | "#addb1_0": 493, 541 | "#addb2_0": 502, 542 | "#addb3_0": 503, 543 | "#addb4_0": 504, 544 | "#addb5_0": 505, 545 | "#addb6_0": 522, 546 | "#addb7_0": 523, 547 | "#addc01": 591, 548 | "#addc12": 588, 549 | "#addc23": 587, 550 | "#addc45": 583, 551 | "#addc56": 580, 552 | "#addc67": 579, 553 | "#ahd0": 264, 554 | "#ahd1": 274, 555 | "#ahd2": 263, 556 | "#ahd3": 273, 557 | "#ahd4": 262, 558 | "#ahd5": 261, 559 | "#ahd6": 260, 560 | "#ahd7": 1780, 561 | "#ald0": 1672, 562 | "#ald1": 1673, 563 | "#ald2": 1654, 564 | "#ald3": 1668, 565 | "#ald4": 1659, 566 | "#ald5": 1661, 567 | "#ald6": 1660, 568 | "#ald7": 1662, 569 | "#ccr/db": 287, 570 | "#d0_0": 607, 571 | "#d1_0": 597, 572 | "#d2_0": 596, 573 | "#d3_0": 399, 574 | "#d4_0": 404, 575 | "#d5_0": 394, 576 | "#d6_0": 388, 577 | "#d7_0": 661, 578 | "#db0_0": 75, 579 | "#db0_1": 519, 580 | "#db1_0": 72, 581 | "#db1_1": 518, 582 | "#db2_0": 69, 583 | "#db2_1": 515, 584 | "#db3_0": 66, 585 | "#db3_1": 514, 586 | "#db4_0": 63, 587 | "#db4_1": 511, 588 | "#db5_0": 60, 589 | "#db5_1": 510, 590 | "#db6_0": 57, 591 | "#db6_1": 507, 592 | "#db7_0": 54, 593 | "#db7_1": 506, 594 | "#dbi0_0": 611, 595 | "#dbi1_0": 605, 596 | "#dbi2_0": 603, 597 | "#dbi3_0": 403, 598 | "#dbi4_0": 407, 599 | "#dbi5_0": 398, 600 | "#dbi6_0": 391, 601 | "#dbi7_0": 654, 602 | // "#decode_0": 1528, aka sync 603 | "#decode_2": 1259, 604 | "#i0": 1270, 605 | "#i1": 1197, 606 | "#i2": 1198, 607 | "#i3": 1266, 608 | "#i4": 1199, 609 | "#i5": 1200, 610 | "#i6": 1262, 611 | "#i7": 1260, 612 | "#inch0_0": 218, 613 | "#inch1_0": 214, 614 | "#inch2_0": 217, 615 | "#inch3_0": 213, 616 | "#inch4_0": 216, 617 | "#inch5_0": 212, 618 | "#inch6_0": 215, 619 | "#inch7_0": 211, 620 | "#inchc01": 1758, 621 | "#inchc12": 1759, 622 | "#inchc23": 1763, 623 | "#inchc34": 1764, 624 | "#inchc45": 1767, 625 | "#inchc56": 1768, 626 | "#inchc67": 1779, 627 | "#inchcin": 186, 628 | "#inchi0": 247, 629 | "#inchi1": 250, 630 | "#inchi2": 246, 631 | "#inchi3": 249, 632 | "#inchi4": 244, 633 | "#inchi5": 248, 634 | "#inchi6": 241, 635 | "#incho0": 225, 636 | "#incho1": 221, 637 | "#incho2": 224, 638 | "#incho3": 220, 639 | "#incho4": 223, 640 | "#incho5": 219, 641 | "#incho6": 222, 642 | "#incho7": 210, 643 | "#incl0_0": 119, 644 | "#incl1_0": 115, 645 | "#incl2_0": 118, 646 | "#incl3_0": 114, 647 | "#incl4_0": 117, 648 | "#incl5_0": 113, 649 | "#incl6_0": 116, 650 | "#incl7_0": 96, 651 | "#inclc01": 1675, 652 | "#inclc12": 1652, 653 | "#inclc23": 1676, 654 | "#inclc34": 1663, 655 | "#inclc45": 1665, 656 | "#inclc56": 1664, 657 | "#inclc67": 1666, 658 | "#inclcin": 1674, 659 | "#incli0": 50, 660 | "#incli1": 46, 661 | "#incli2": 49, 662 | "#incli3": 45, 663 | "#incli4": 48, 664 | "#incli5": 44, 665 | "#incli6": 47, 666 | "#incli7": 43, 667 | "#inclo0": 104, 668 | "#inclo1": 100, 669 | "#inclo2": 103, 670 | "#inclo3": 99, 671 | "#inclo4": 102, 672 | "#inclo5": 98, 673 | "#inclo6": 101, 674 | "#inclo7": 97, 675 | "#ir0_0": 1302, 676 | "#ir1_0": 1290, 677 | "#ir2_0": 1296, 678 | "#ir3_0": 1297, 679 | "#ir4_0": 1298, 680 | "#ir5_0": 1299, 681 | "#ir6_0": 1278, 682 | "#ir7_0": 1279, 683 | "#ixh0_0": 1706, 684 | "#ixh1_0": 1714, 685 | "#ixh2_0": 1707, 686 | "#ixh3_0": 1715, 687 | "#ixh4_0": 1721, 688 | "#ixh5_0": 1725, 689 | "#ixh6_0": 1729, 690 | "#ixh7_0": 1781, 691 | "#ixl0_0": 1708, 692 | "#ixl1_0": 1716, 693 | "#ixl2_0": 1709, 694 | "#ixl3_0": 1717, 695 | "#ixl4_0": 1722, 696 | "#ixl5_0": 1726, 697 | "#ixl6_0": 1730, 698 | "#ixl7_0": 1782, 699 | "#pch0_0": 1760, 700 | "#pch1_0": 1757, 701 | "#pch2_0": 1761, 702 | "#pch3_0": 1762, 703 | "#pch4_0": 1765, 704 | "#pch5_0": 1766, 705 | "#pch6_0": 1769, 706 | "#pch7_0": 1778, 707 | "#pcl0_0": 1770, 708 | "#pcl1_0": 1775, 709 | "#pcl2_0": 1771, 710 | "#pcl3_0": 1776, 711 | "#pcl4_0": 1772, 712 | "#pcl5_0": 1777, 713 | "#pcl6_0": 1773, 714 | "#pcl7_0": 1774, 715 | "#reset_1": 1463, 716 | "#sph0_0": 1735, 717 | "#sph1_0": 1738, 718 | "#sph2_0": 1741, 719 | "#sph3_0": 1744, 720 | "#sph4_0": 1747, 721 | "#sph5_0": 1750, 722 | "#sph6_0": 1753, 723 | "#sph7_0": 1756, 724 | "#spl0_0": 1734, 725 | "#spl1_0": 1737, 726 | "#spl2_0": 1740, 727 | "#spl3_0": 1743, 728 | "#spl4_0": 1746, 729 | "#spl5_0": 1749, 730 | "#spl6_0": 1752, 731 | "#spl7_0": 1755, 732 | "#sum0_0": 616, 733 | "#sum1_0": 632, 734 | "#sum2_0": 615, 735 | "#sum3_0": 627, 736 | "#sum4_0": 614, 737 | "#sum5_0": 622, 738 | "#sum6_0": 613, 739 | "#sum7_0": 617, 740 | "#sumo0": 634, 741 | "#sumo1": 633, 742 | "#sumo2": 629, 743 | "#sumo3": 628, 744 | "#sumo4": 624, 745 | "#sumo5": 623, 746 | "#sumo6": 619, 747 | "#sumo7": 618, 748 | "#tmp0_0": 1733, 749 | "#tmp1_0": 1736, 750 | "#tmp2_0": 1739, 751 | "#tmp3_0": 1742, 752 | "#tmp4_0": 1745, 753 | "#tmp5_0": 1748, 754 | "#tmp6_0": 1751, 755 | "#tmp7_0": 1754, 756 | "#ena": 1646, 757 | "#enrw": 1168, 758 | "#flagc_0": 1129, 759 | "#flagcx": 1128, 760 | "#flagh_0": 787, 761 | "#flaghx": 781, 762 | "#flagi_0": 1576, 763 | "#flagix": 1006, 764 | "#flagn_0": 997, 765 | "#flagnx": 996, 766 | "#flagv_0": 1103, 767 | "#flagvx": 1566, 768 | "#flagz_0": 1579, 769 | "#flagzx": 1024, 770 | "#n0n-0": 1250, 771 | "#n0n-1": 1251, 772 | "#n0n-2": 1252, 773 | "#n0n-3": 1253, 774 | "#n0n-4": 1254, 775 | "#n0n-5": 1247, 776 | "#n0n-6": 1243, 777 | "#n0n-7": 1244, 778 | "#n0n.2-0": 1249, 779 | "#n0n.2-1": 1255, 780 | "#n0n.2-2": 1256, 781 | "#n0n.2-3": 1257, 782 | "#n0n.2-4": 1258, 783 | "#n0n.2-5": 1248, 784 | "#n0n.2-6": 1241, 785 | "#n0n.2-7": 1242, 786 | "#phi2_0": 477, 787 | "#phi2_2": 576, 788 | "#x0/abh": 979, 789 | "#x0/abl1": 438, 790 | "#x0/db0": 127, 791 | "#x0/db1": 129, 792 | "#x0/db2": 132, 793 | "#xab/ix": 456, 794 | "#xab/sp": 167, 795 | "#xabl/abl1": 426, 796 | "#xabl/ald": 82, 797 | "#xacca/abl1": 428, 798 | "#xacca/db": 466, 799 | "#xaccb/abl1": 460, 800 | "#xaccb/db": 760, 801 | "#xaddg0": 571, 802 | "#xaddg1": 570, 803 | "#xaddg2": 563, 804 | "#xaddg3": 562, 805 | "#xaddg4": 555, 806 | "#xaddg5": 554, 807 | "#xaddg6": 547, 808 | "#xaddg7": 546, 809 | "#xda/adda": 434, 810 | "#xdb/acca": 464, 811 | "#xdb/accb": 430, 812 | "#xdb/adda": 436, 813 | "#xdb/ald": 84, 814 | "#xdb/ixh": 454, 815 | "#xdb/ixl": 458, 816 | "#xdb/sph": 739, 817 | "#xdb/spl": 445, 818 | "#xdb/tmp": 448, 819 | "#xinc/ab": 121, 820 | "#xinc/pc": 701, 821 | "#xixh/abh": 421, 822 | "#xixh/abl1": 757, 823 | "#xixh/db": 424, 824 | "#xixl/abl1": 462, 825 | "#xixl/db": 432, 826 | "#xpc/ab": 123, 827 | "#xpch/db": 157, 828 | "#xpcl/db": 125, 829 | "#xsp/ab": 745, 830 | "#xsph/db": 452, 831 | "#xspl/db": 738, 832 | "#xsr/adda": 468, 833 | "#xtmp/abh": 443, 834 | "#xtmp/db": 450, 835 | "#xndb/adda": 471, 836 | "0/abh": 181, 837 | "0/abl1": 316, 838 | "0/db0": 136, 839 | "0/db1": 135, 840 | "0/db2": 134, 841 | "a0-high": 13, 842 | "a0-low": 21, 843 | "a1-high": 16, 844 | "a1-low": 24, 845 | "a10-high": 803, 846 | "a10-low": 39, 847 | "a11-high": 804, 848 | "a11-low": 41, 849 | "a12-high": 806, 850 | "a12-low": 689, 851 | "a13-high": 802, 852 | "a13-low": 687, 853 | "a14-high": 805, 854 | "a14-low": 690, 855 | "a15-high": 801, 856 | "a15-low": 688, 857 | "a2-high": 14, 858 | "a2-low": 22, 859 | "a3-high": 17, 860 | "a3-low": 25, 861 | "a4-high": 15, 862 | "a4-low": 23, 863 | "a5-high": 18, 864 | "a5-low": 26, 865 | "a6-high": 19, 866 | "a6-low": 20, 867 | "a7-high": 37, 868 | "a7-low": 36, 869 | "a8-high": 1072, 870 | "a8-low": 38, 871 | "a9-high": 807, 872 | "a9-low": 40, 873 | "ab/ix": 329, 874 | "ab/ob": 1647, 875 | "ab/sp": 171, 876 | "abh/ahd": 176, 877 | "abl/abl1": 326, 878 | "abl/ald": 6, 879 | "acca/abl1": 325, 880 | "acca/db": 314, 881 | "accb/abl1": 318, 882 | "accb/db": 324, 883 | "ba-high": 1237, 884 | "ba-low": 1227, 885 | "d0-high": 681, 886 | "d0-low": 684, 887 | "d1-high": 682, 888 | "d1-low": 685, 889 | "d2-high": 674, 890 | "d2-low": 679, 891 | "d3-high": 675, 892 | "d3-low": 680, 893 | "d4-high": 666, 894 | "d4-low": 671, 895 | "d5-high": 667, 896 | "d5-low": 672, 897 | "d6-high": 662, 898 | "d6-low": 665, 899 | "d7-high": 653, 900 | "d7-low": 652, 901 | "da/adda": 418, 902 | "db/acca": 315, 903 | "db/accb": 323, 904 | "db/adda": 417, 905 | "db/ald": 7, 906 | "db/ixh": 285, 907 | "db/ixl": 320, 908 | "db/sph": 180, 909 | "db/spl": 177, 910 | "db/tmp": 174, 911 | "dbi0-fb": 612, 912 | "dbi1-fb": 600, 913 | "dbi2-fb": 606, 914 | "dbi3-fb": 401, 915 | "dbi4-fb": 408, 916 | "dbi5-fb": 396, 917 | "dbi6-fb": 392, 918 | "dbi7-fb": 651, 919 | "inc/ab": 140, 920 | "inc/pc": 138, 921 | "ixh/abh": 327, 922 | "ixh/abl1": 319, 923 | "ixh/db": 328, 924 | "ixl/abl1": 317, 925 | "ixl/db": 322, 926 | "pch/abh": 161, 927 | "pch/db": 162, 928 | "pcl/abl": 139, 929 | "pcl/db": 137, 930 | "rw-high": 1306, 931 | "rw-low": 1307, 932 | "sph/abh": 286, 933 | "sph/db": 172, 934 | "spl/abl": 178, 935 | "spl/db": 175, 936 | "sr/adda": 416, 937 | "sum/db": 532, 938 | "tmp/abh": 179, 939 | "tmp/db": 173, 940 | "vma-high": 1500, 941 | "vma-low": 1499, 942 | "flag0/db1": 321, 943 | "flag0/db2": 375, 944 | "flag0/db3": 376, 945 | "flag0/db4": 309, 946 | "flag0/db5": 308, 947 | "ndb/adda": 415, 948 | 949 | // from this point: signals imported from Segher 2011-04-16 and not yet ordered or commented 950 | carry: 646, 951 | dbe_1: 1453, 952 | dec: 163, 953 | halted: 2, 954 | int: 1083, 955 | irq_0: 3, 956 | irqg: 1183, 957 | nmi_0: 1477, 958 | nmig: 1192, 959 | restart: 1186, 960 | 961 | ta0: 879, // timing state signals also seen earlier with mixed-case names 962 | ta1: 838, 963 | ta2: 844, 964 | td0_0: 981, 965 | td0_1: 700, 966 | te1_0: 735, 967 | te1_1: 967, 968 | te1_2: 705, 969 | te1_3: 715, 970 | te1_4: 865, 971 | te1_5: 973, 972 | te1_6: 706, 973 | tg0: 12, 974 | tg1: 772, 975 | tg2: 832, 976 | tg3: 835, 977 | tg4: 696, 978 | tg5: 914, 979 | tg6: 911, 980 | tg7: 1081, 981 | tg8: 891, 982 | tr3: 823, 983 | tr4: 825, 984 | tr5: 828, 985 | tr6: 894, 986 | tr7: 694, 987 | tr8: 697, 988 | ts: 1309, 989 | tsc_0: 1508, 990 | tx0: 850, 991 | tx1: 851, 992 | tx2: 860, 993 | 994 | wait: 1234, 995 | wr: 788, 996 | writing: 1449, 997 | 998 | // the remainder of the imports need quoting 999 | "#alu-cin": 592, 1000 | "#alu-cout": 595, 1001 | "#alu-hin": 584, 1002 | "#alu-hout": 1690, 1003 | "#alu-or": 472, 1004 | "#alu-or-xor": 475, 1005 | "#carry16": 733, 1006 | "#dbe_0": 1452, 1007 | "#dbe_2": 1454, 1008 | "#end": 1574, 1009 | "#flagc_1": 942, 1010 | "#i-ts": 1313, 1011 | "#inc": 712, 1012 | "#inch-cin": 78, 1013 | "#next-cyc-fetch": 4, 1014 | "#nmi_1": 1478, 1015 | "#nmip": 1178, 1016 | "#op-00xxxxxx_0": 945, 1017 | "#op-ta0-a-alu": 1019, 1018 | "#ta0-stx": 796, 1019 | "#ta0.2_0": 873, 1020 | "#ta1-0000100x": 798, 1021 | "#ta1-0000100x.2": 799, 1022 | "#ta1_0": 872, 1023 | "#ta1_1": 1095, 1024 | "#ta1_2": 960, 1025 | "#taken": 1039, 1026 | "#te0": 868, 1027 | "#te0.2_0": 867, 1028 | "#tx0_0": 971, 1029 | "#tx0_1": 926, 1030 | "#tx1_0": 727, 1031 | "#xalu-cin": 943, 1032 | "#xalu-or-xor": 479, 1033 | "#xdbi/db": 536, 1034 | "#xsum/db": 535, 1035 | "alu-and": 473, 1036 | "alu-sl": 578, 1037 | "alu-sr/c": 1110, 1038 | "alu-sub/c": 1144, 1039 | "alu-sub/c_0": 1163, 1040 | "alu-vout": 1058, 1041 | "alu-zout": 645, 1042 | "alu/c": 1147, 1043 | "alu/c_0": 1164, 1044 | "alu/h": 782, 1045 | "alu/nz": 1027, 1046 | "alu/v": 1112, 1047 | "alu2/z": 1049, 1048 | "da-c": 379, 1049 | "da-h": 381, 1050 | "db/ccr": 1107, 1051 | "dbi/db": 531, 1052 | "dec-low-adjust": 385, 1053 | "do-alu-cin": 575, 1054 | "force-wait": 1245, 1055 | "inc16/z": 989, 1056 | "incl-cout": 42, 1057 | "insn/c": 1162, 1058 | "insn/c_0": 1131, 1059 | "insn/i": 1000, 1060 | "insn/v": 1570, 1061 | "irq-dis": 990, 1062 | "irq-new": 1215, 1063 | "ix/ab": 833, 1064 | "nmi-done": 1172, 1065 | "nmi-new": 1174, 1066 | "no-address": 1489, 1067 | "shift-vout": 1057, 1068 | "shift/v": 1568, 1069 | "sr-cin": 765, 1070 | "t-before-fetch-simple": 1149, 1071 | "ta0-two-cycle-insn": 965, 1072 | "ta0.2": 878, 1073 | "ta2-0000100x": 1028, 1074 | "ta2-0000100x_0": 748, 1075 | "ta2-0000100x_1": 759, 1076 | "ta2-1xxx11xx": 1045, 1077 | "ta3-0000100x": 1031, 1078 | "te0.2": 866, 1079 | "tsc-high": 1460, 1080 | "tsc-low": 1476, 1081 | "xalu-and": 483, 1082 | 1083 | // pla outputs (not in physical order) 1084 | "op-0000011x": 1361, 1085 | "op-0000100x": 1332, 1086 | "op-0000100x_0": 1379, 1087 | "op-0000100x_1": 1427, 1088 | "op-0000101x": 1141, 1089 | "op-0000110x": 1130, 1090 | "op-0000xxxx": 1369, 1091 | "op-0000xxxx_0": 1362, 1092 | "op-00010110": 1355, 1093 | "op-0001100x": 1394, 1094 | "op-0001101x": 1346, 1095 | "op-0001xxxx": 1360, 1096 | "op-000x0110": 1391, 1097 | "op-0010xxxx": 1380, 1098 | "op-0010xxxx_0": 1363, 1099 | "op-0010xxxx_1": 1399, 1100 | "op-0010xxxx_2": 1426, 1101 | "op-0011100x": 1381, 1102 | "op-00111011": 1383, 1103 | "op-00xxxxxx": 1342, 1104 | "op-0100xxxx": 1432, 1105 | "op-0101xxxx": 1425, 1106 | "op-011x1101": 1387, 1107 | "op-011x1110": 1398, 1108 | "op-011xxxxx": 1337, 1109 | "op-011xxxxx_0": 1322, 1110 | "op-011xxxxx_1": 1320, 1111 | "op-01xx01xx": 1443, 1112 | "op-01xx01xx_0": 1396, 1113 | "op-01xx0xxx": 1390, 1114 | "op-01xx100x": 1345, 1115 | "op-01xx100x_0": 1094, 1116 | "op-01xx100x_1": 1334, 1117 | "op-01xx1110": 1328, 1118 | "op-01xx1110_0": 1341, 1119 | "op-01xx11x1": 1428, 1120 | "op-01xxx1xx": 1338, 1121 | "op-0x01xxxx": 1343, 1122 | "op-0x0xxxxx_0": 1364, 1123 | "op-0xxxxxxx": 1439, 1124 | "op-0xxxxxxx_0": 1401, 1125 | "op-0xxxxxxx_1": 1437, 1126 | "op-10xx0111": 1339, 1127 | "op-10xx111x": 948, 1128 | "op-10xxxxxx": 1384, 1129 | "op-11xx0111": 1436, 1130 | "op-11xx1110": 1366, 1131 | "op-11xx1111": 1393, 1132 | "op-11xxxxxx": 1327, 1133 | "op-1x001101": 1349, 1134 | "op-1x00xxxx": 1372, 1135 | "op-1x10xxxx": 1350, 1136 | "op-1x11xxxx": 1321, 1137 | "op-1xx01101": 1352, 1138 | "op-1xx0xxxx": 1371, 1139 | "op-1xxx0010": 1354, 1140 | "op-1xxx0111": 1323, 1141 | "op-1xxx10x0": 1438, 1142 | "op-1xxx10x1": 1444, 1143 | "op-1xxx1100": 1378, 1144 | "op-1xxx1100_0": 1442, 1145 | "op-1xxx1101": 1356, 1146 | "op-1xxx1101_0": 1388, 1147 | "op-1xxx1101_1": 1434, 1148 | "op-1xxx1111": 1389, 1149 | "op-1xxx11x0": 1374, 1150 | "op-1xxx11xx": 1431, 1151 | "op-1xxx11xx_0": 1353, 1152 | "op-1xxx11xx_1": 1430, 1153 | "op-1xxx11xx_2": 1392, 1154 | "op-1xxx11xx_3": 1340, 1155 | "op-1xxx11xx_4": 1373, 1156 | "op-1xxxx111": 1435, 1157 | "op-1xxxx111_0": 1348, 1158 | "op-1xxxxxxx": 846, 1159 | "op-1xxxxxxx_0": 1150, 1160 | "op-s-00000110": 1420, 1161 | "op-s-00000111": 1407, 1162 | "op-s-00001001": 1410, 1163 | "op-s-0000100x": 1417, 1164 | "op-s-0000100x_0": 1423, 1165 | "op-s-0000111x": 1001, 1166 | "op-s-00110101": 1411, 1167 | "op-s-00110110": 1413, 1168 | "op-s-00110111": 1414, 1169 | "op-s-0011011x": 1415, 1170 | "op-s-0011x1xx": 1421, 1171 | "op-s-0011xxxx": 1409, 1172 | "op-s-0x0xxxxx": 1419, 1173 | "op-s-0x0xxxxx": 1422, 1174 | "op-s-1x001101": 1412, 1175 | "op-s-1x00xxxx": 1405, 1176 | "op-s-1x01xxxx": 1418, 1177 | "op-s-1x01xxxx_0": 1402, 1178 | "op-s-1x01xxxx_1": 1416, 1179 | "op-s-xx10xxxx": 1408, 1180 | "op-s-xx10xxxx_0": 1403, 1181 | "op-s-xx11xxxx": 1404, 1182 | "op-xx11xxxx": 1357, 1183 | "op-xxx011x": 1375, 1184 | "op-xxx1xxxx": 1336, 1185 | "op-xxxx0000": 1424, 1186 | "op-xxxx000x": 1377, 1187 | "op-xxxx0010": 1344, 1188 | "op-xxxx0011": 1333, 1189 | "op-xxxx001x": 1335, 1190 | "op-xxxx00xx": 1433, 1191 | "op-xxxx00xx_0": 1367, 1192 | "op-xxxx0111": 1330, 1193 | "op-xxxx01xx": 1395, 1194 | "op-xxxx0x01": 1385, 1195 | "op-xxxx0x0x": 1324, 1196 | "op-xxxx0xxx": 1040, 1197 | "op-xxxx0xxx_0": 1351, 1198 | "op-xxxx1001": 1326, 1199 | "op-xxxx100x": 1358, 1200 | "op-xxxx10x1": 1365, 1201 | "op-xxxx10x1_0": 1429, 1202 | "op-xxxx10xx": 1325, 1203 | "op-xxxx1100": 1440, 1204 | "op-xxxx111x": 1359, 1205 | "op-xxxx111x_0": 1400, 1206 | "op-xxxx111x_1": 1368, 1207 | "op-xxxx11xx": 1329, 1208 | "op-xxxx11xx_0": 1382, 1209 | "op-xxxx1xx1": 1386, 1210 | "op-xxxx1xxx": 1397, 1211 | "op-xxxxx11x": 1376, 1212 | "op-xxxxx11x_0": 1441, 1213 | "op-xxxxx1xx": 1370, 1214 | "op-xxxxxx0x": 1041, 1215 | "op-xxxxxx1x": 1446, 1216 | "op-xxxxxxx0": 1138, 1217 | "op-xxxxxxx0_0": 1003, 1218 | "op-xxxxxxx1": 1331, 1219 | "op-xxxxxxx1_0": 11, 1220 | "op-xxxxxxx1_1": 1347, 1221 | "op-xxxxxxx1_2": 1086, 1222 | } 1223 | -------------------------------------------------------------------------------- /chip-6800/support.js: -------------------------------------------------------------------------------- 1 | // chip-specific support functions 2 | // 3 | // may override function definitions made previously 4 | 5 | chipname='6800'; 6 | 7 | grChipSize=6600; 8 | grChipOffsetX=25 9 | grChipOffsetY=-200; 10 | 11 | ngnd = nodenames['gnd']; 12 | npwr = nodenames['vcc']; 13 | 14 | nodenamereset = 'reset'; 15 | 16 | presetLogLists=[ 17 | ['cycle',], 18 | ['ab','db','rw','vma','Fetch','pc','acca','accb','ix','sp','p'], 19 | ['ir','sync','Execute','State'], // instruction fetch and execution control 20 | ['dbi','dbo','tmp','sum','inc'], // internal register-sized state 21 | ['idb','abh','abl','ablx'], // internal datapath busses 22 | ['irq','nmi',nodenamereset,'tsc','dbe','halt','ba'], // other pins 23 | ]; 24 | 25 | function setupTransistors(){ 26 | for(i in transdefs){ 27 | var tdef = transdefs[i]; 28 | var name = tdef[0]; 29 | var gate = tdef[1]; 30 | var c1 = tdef[2]; 31 | var c2 = tdef[3]; 32 | var bb = tdef[4]; 33 | if(tdef[6]) 34 | // just ignore all the 'weak' transistors for now 35 | continue; 36 | if(c1==ngnd) {c1=c2;c2=ngnd;} 37 | if(c1==npwr) {c1=c2;c2=npwr;} 38 | var trans = {name: name, on: false, gate: gate, c1: c1, c2: c2, bb: bb}; 39 | nodes[gate].gates.push(trans); 40 | nodes[c1].c1c2s.push(trans); 41 | nodes[c2].c1c2s.push(trans); 42 | transistors[name] = trans; 43 | } 44 | } 45 | 46 | // simulate a single clock phase with no update to graphics or trace 47 | function halfStep(){ 48 | var clk = isNodeHigh(nodenames['phi2']); 49 | eval(clockTriggers[cycle]); 50 | if (clk) {setLow('phi2'); setLow('dbe'); setHigh('phi1'); handleBusRead(); } 51 | else {setHigh('phi1'); setLow('phi1'); setHigh('phi2'); setHigh('dbe'); handleBusWrite();} 52 | } 53 | 54 | function goUntilSyncOrWrite(){ 55 | halfStep(); 56 | cycle++; 57 | while( 58 | !isNodeHigh(nodenames['phi2']) || 59 | ( !isNodeHigh(nodenames['sync']) && isNodeHigh(nodenames['rw']) ) 60 | ) { 61 | halfStep(); 62 | cycle++; 63 | } 64 | chipStatus(); 65 | } 66 | 67 | function initChip(){ 68 | var start = now(); 69 | for(var nn in nodes) { 70 | nodes[nn].state = false; 71 | nodes[nn].float = true; 72 | } 73 | 74 | nodes[ngnd].state = false; 75 | nodes[ngnd].float = false; 76 | nodes[npwr].state = true; 77 | nodes[npwr].float = false; 78 | for(var tn in transistors) transistors[tn].on = false; 79 | setLow(nodenamereset); 80 | setHigh('phi1'); setLow('phi2'); setLow('dbe'); 81 | setHigh('dbe'); setLow('tsc'); setHigh('halt'); 82 | setHigh('irq'); setHigh('nmi'); 83 | recalcNodeList(allNodes()); 84 | for(var i=0;i<8;i++){ 85 | setLow('phi1'); 86 | setHigh('phi2'); setHigh('dbe'); 87 | setLow('phi2'); setLow('dbe'); 88 | setHigh('phi1'); 89 | } 90 | setHigh(nodenamereset); 91 | for(var i=0;i<6;i++){halfStep();} // avoid updating graphics and trace buffer before user code 92 | refresh(); 93 | cycle = 0; 94 | trace = Array(); 95 | if(typeof expertMode != "undefined") 96 | updateLogList(); 97 | chipStatus(); 98 | if(ctrace)console.log('initChip done after', now()-start); 99 | } 100 | 101 | function handleBusRead(){ 102 | if(isNodeHigh(nodenames['rw'])){ 103 | var a = readAddressBus(); 104 | var d = eval(readTriggers[a]); 105 | if(d == undefined) 106 | d = mRead(readAddressBus()); 107 | if(isNodeHigh(nodenames['sync'])) 108 | eval(fetchTriggers[d]); 109 | writeDataBus(d); 110 | } 111 | } 112 | 113 | function readAccA(){return readBits('acca', 8);} 114 | function readAccB(){return readBits('accb', 8);} 115 | function readIX(){return (readBits('ixh', 8)<<8) + readBits('ixl', 8);} 116 | function readSP(){return (readBits('sph', 8)<<8) + readBits('spl', 8);} 117 | function readPstring(){ 118 | var result; 119 | result = '‑' + // non-breaking hyphen 120 | '‑' + // non-breaking hyphen 121 | (isNodeHigh(nodenames['flagh'])?'H':'h') + 122 | (isNodeHigh(nodenames['flagi'])?'I':'i') + 123 | (isNodeHigh(nodenames['flagn'])?'N':'n') + 124 | (isNodeHigh(nodenames['flagz'])?'Z':'z') + 125 | (isNodeHigh(nodenames['flagv'])?'V':'v') + 126 | (isNodeHigh(nodenames['flagc'])?'C':'c'); 127 | return result; 128 | } 129 | 130 | // The 6800 state control is something like a branching shift register 131 | // ... but not quite like that 132 | TCStates=[ 133 | "Ts", "Tf", 134 | "Tx0", "Tx1", "Tx2", 135 | "Ta0", "Ta1", "Ta2", 136 | "Td0_0", 137 | "#Te0", "Te1_0", 138 | "Tg0", "Tg1", "Tg2", "Tg3", "Tg4", "Tg5", "Tg6", "Tg7", "Tg8", 139 | "Tr3", "Tr4", "Tr5", "Tr6", "Tr7", "Tr8", 140 | ]; 141 | 142 | function listActiveTCStates() { 143 | var s=[]; 144 | for(var i=0;i>1; 163 | if(busname=='pc') 164 | return busToHex('pch') + busToHex('pcl'); 165 | if(busname=='sp') 166 | return busToHex('sph') + busToHex('spl'); 167 | if(busname=='ix') 168 | return busToHex('ixh') + busToHex('ixl'); 169 | if(busname=='inc') 170 | return busToHex('inch') + busToHex('incl'); 171 | if(busname=='p') 172 | return readPstring(); 173 | if(busname=='State') 174 | return listActiveTCStates(); 175 | if(busname=='Execute') 176 | return disassemblytoHTML(readBits('ir',8)); 177 | if(busname=='Fetch') 178 | return isNodeHigh(nodenames['sync'])?disassemblytoHTML(readDataBus()):""; 179 | if(busname=='plaOutputs') 180 | // PLA outputs are mostly ^op- but some have a prefix too 181 | // - we'll allow the x and xx prefix but ignore the # 182 | return listActiveSignals('^([x]?x-)?op-'); 183 | if(busname=='DPControl') 184 | return listActiveSignals('^dpc[0-9]+_'); 185 | if(busname[0]=="-"){ 186 | // invert the value of the bus for display 187 | var value=busToHex(busname.slice(1)) 188 | if(typeof value != "undefined") 189 | return value.replace(/./g,function(x){return (15-parseInt(x,16)).toString(16)}); 190 | else 191 | return undefined;; 192 | } else { 193 | return busToHex(busname); 194 | } 195 | } 196 | 197 | function chipStatus(){ 198 | var ab = readAddressBus(); 199 | var machine1 = 200 | ' halfcyc:' + cycle + 201 | ' phi0:' + readBit('phi2') + 202 | ' AB:' + hexWord(ab) + 203 | ' D:' + hexByte(readDataBus()) + 204 | ' RnW:' + readBit('rw') + 205 | ' VMA:' + readBit('vma'); 206 | var machine2 = 207 | ' PC:' + hexWord(readPC()) + 208 | ' A:' + hexByte(readAccA()) + 209 | ' B:' + hexByte(readAccB()) + 210 | ' IX:' + hexWord(readIX()) + 211 | ' SP:' + hexWord(readSP()) + 212 | ' ' + readPstring(); 213 | var machine3 = 214 | 'Hz: ' + estimatedHz().toFixed(1); 215 | if(typeof expertMode != "undefined") { 216 | machine3 += ' Exec: ' + busToString('Execute'); // no T-state info for 6800 yet 217 | if(isNodeHigh(nodenames['sync'])) 218 | machine3 += ' (Fetch: ' + busToString('Fetch') + ')'; 219 | if(goldenChecksum != undefined) 220 | machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match"); 221 | } 222 | 223 | setStatus(machine1, machine2, machine3); 224 | if (logThese.length>1) { 225 | updateLogbox(logThese); 226 | } 227 | selectCell(ab); 228 | } 229 | 230 | // javascript derived from http://segher.ircgeeks.net/6800/OPS 231 | var disassembly={ 232 | 0x00: "!", 233 | 0x01: "nop", 234 | 0x02: "!", 235 | 0x03: "!", 236 | 0x04: "!", 237 | 0x05: "!", 238 | 0x06: "tap", 239 | 0x07: "tpa", 240 | 0x10: "sba", 241 | 0x11: "cba", 242 | 0x12: "!", 243 | 0x13: "!", 244 | 0x14: "!nba", 245 | 0x15: "!", 246 | 0x16: "tab", 247 | 0x17: "tba", 248 | 0x20: "bra N", 249 | 0x21: "!", 250 | 0x22: "bhi N", 251 | 0x23: "bls N", 252 | 0x24: "bcc N", 253 | 0x25: "bcs N", 254 | 0x26: "bne N", 255 | 0x27: "beq N", 256 | 0x30: "tsx", 257 | 0x31: "ins", 258 | 0x32: "pul a", 259 | 0x33: "pul b", 260 | 0x34: "des", 261 | 0x35: "txs", 262 | 0x36: "psh a", 263 | 0x37: "psh b", 264 | 0x40: "neg a", 265 | 0x41: "!", 266 | 0x42: "!", 267 | 0x43: "com a", 268 | 0x44: "lsr a", 269 | 0x45: "!", 270 | 0x46: "ror a", 271 | 0x47: "asr a", 272 | 0x50: "neg b", 273 | 0x51: "!", 274 | 0x52: "!", 275 | 0x53: "com b", 276 | 0x54: "lsr b", 277 | 0x55: "!", 278 | 0x56: "ror b", 279 | 0x57: "asr b", 280 | 0x60: "neg Nx", 281 | 0x61: "!", 282 | 0x62: "!", 283 | 0x63: "com Nx", 284 | 0x64: "lsr Nx", 285 | 0x65: "!", 286 | 0x66: "ror Nx", 287 | 0x67: "asr Nx", 288 | 0x70: "neg NN", 289 | 0x71: "!", 290 | 0x72: "!", 291 | 0x73: "com NN", 292 | 0x74: "lsr NN", 293 | 0x75: "!", 294 | 0x76: "ror NN", 295 | 0x77: "asr NN", 296 | 0x80: "sub a #", 297 | 0x81: "cmp a #", 298 | 0x82: "sbc a #", 299 | 0x83: "!", 300 | 0x84: "and a #", 301 | 0x85: "bit a #", 302 | 0x86: "lda a #", 303 | 0x87: "!", 304 | 0x90: "sub a N", 305 | 0x91: "cmp a N", 306 | 0x92: "sbc a N", 307 | 0x93: "!", 308 | 0x94: "and a N", 309 | 0x95: "bit a N", 310 | 0x96: "lda a N", 311 | 0x97: "sta a N", 312 | 0xa0: "sub a Nx", 313 | 0xa1: "cmp a Nx", 314 | 0xa2: "sbc a Nx", 315 | 0xa3: "!", 316 | 0xa4: "and a Nx", 317 | 0xa5: "bit a Nx", 318 | 0xa6: "lda a Nx", 319 | 0xa7: "sta a Nx", 320 | 0xb0: "sub a NN", 321 | 0xb1: "cmp a NN", 322 | 0xb2: "sbc a NN", 323 | 0xb3: "!", 324 | 0xb4: "and a NN", 325 | 0xb5: "bit a NN", 326 | 0xb6: "lda a NN", 327 | 0xb7: "sta a NN", 328 | 0xc0: "sub b #", 329 | 0xc1: "cmp b #", 330 | 0xc2: "sbc b #", 331 | 0xc3: "!", 332 | 0xc4: "and b #", 333 | 0xc5: "bit b #", 334 | 0xc6: "lda b #", 335 | 0xc7: "!", 336 | 0xd0: "sub b N", 337 | 0xd1: "cmp b N", 338 | 0xd2: "sbc b N", 339 | 0xd3: "!", 340 | 0xd4: "and b N", 341 | 0xd5: "bit b N", 342 | 0xd6: "lda b N", 343 | 0xd7: "sta b N", 344 | 0xe0: "sub b Nx", 345 | 0xe1: "cmp b Nx", 346 | 0xe2: "sbc b Nx", 347 | 0xe3: "!", 348 | 0xe4: "and b Nx", 349 | 0xe5: "bit b Nx", 350 | 0xe6: "lda b Nx", 351 | 0xe7: "sta b Nx", 352 | 0xf0: "sub b NN", 353 | 0xf1: "cmp b NN", 354 | 0xf2: "sbc b NN", 355 | 0xf3: "!", 356 | 0xf4: "and b NN", 357 | 0xf5: "bit b NN", 358 | 0xf6: "lda b NN", 359 | 0xf7: "sta b NN", 360 | 0x08: "inx", 361 | 0x09: "dex", 362 | 0x0a: "clv", 363 | 0x0b: "sev", 364 | 0x0c: "clc", 365 | 0x0d: "sec", 366 | 0x0e: "cli", 367 | 0x0f: "sei", 368 | 0x18: "!", 369 | 0x19: "daa", 370 | 0x1a: "!", 371 | 0x1b: "aba", 372 | 0x1c: "!", 373 | 0x1d: "!", 374 | 0x1e: "!", 375 | 0x1f: "!", 376 | 0x28: "bvc N", 377 | 0x29: "bvs N", 378 | 0x2a: "bpl N", 379 | 0x2b: "bmi N", 380 | 0x2c: "bge N", 381 | 0x2d: "blt N", 382 | 0x2e: "bgt N", 383 | 0x2f: "ble N", 384 | 0x38: "!", 385 | 0x39: "rts", 386 | 0x3a: "!", 387 | 0x3b: "rti", 388 | 0x3c: "!", 389 | 0x3d: "!", 390 | 0x3e: "wai", 391 | 0x3f: "swi", 392 | 0x48: "asl a", 393 | 0x49: "rol a", 394 | 0x4a: "dec a", 395 | 0x4b: "!", 396 | 0x4c: "inc a", 397 | 0x4d: "tst a", 398 | 0x4e: "!", 399 | 0x4f: "clr a", 400 | 0x58: "asl b", 401 | 0x59: "rol b", 402 | 0x5a: "dec b", 403 | 0x5b: "!", 404 | 0x5c: "inc b", 405 | 0x5d: "tst b", 406 | 0x5e: "!", 407 | 0x5f: "clr b", 408 | 0x68: "asl Nx", 409 | 0x69: "rol Nx", 410 | 0x6a: "dec Nx", 411 | 0x6b: "!", 412 | 0x6c: "inc Nx", 413 | 0x6d: "tst Nx", 414 | 0x6e: "jmp Nx", 415 | 0x6f: "clr Nx", 416 | 0x78: "asl NN", 417 | 0x79: "rol NN", 418 | 0x7a: "dec NN", 419 | 0x7b: "!", 420 | 0x7c: "inc NN", 421 | 0x7d: "tst NN", 422 | 0x7e: "jmp NN", 423 | 0x7f: "clr NN", 424 | 0x88: "eor a #", 425 | 0x89: "adc a #", 426 | 0x8a: "ora a #", 427 | 0x8b: "add a #", 428 | 0x8c: "cpx ##", 429 | 0x8d: "bsr N", 430 | 0x8e: "lds ##", 431 | 0x8f: "!", 432 | 0x98: "eor a N", 433 | 0x99: "adc a N", 434 | 0x9a: "ora a N", 435 | 0x9b: "add a N", 436 | 0x9c: "cpx N", 437 | 0x9d: "!hcf", 438 | 0x9e: "lds N", 439 | 0x9f: "sts N", 440 | 0xa8: "eor a Nx", 441 | 0xa9: "adc a Nx", 442 | 0xaa: "ora a Nx", 443 | 0xab: "add a Nx", 444 | 0xac: "cpx Nx", 445 | 0xad: "jsr Nx", 446 | 0xae: "lds Nx", 447 | 0xaf: "sts Nx", 448 | 0xb8: "eor a NN", 449 | 0xb9: "adc a NN", 450 | 0xba: "ora a NN", 451 | 0xbb: "add a NN", 452 | 0xbc: "cpx NN", 453 | 0xbd: "jsr NN", 454 | 0xbe: "lds NN", 455 | 0xbf: "sts NN", 456 | 0xc8: "eor b #", 457 | 0xc9: "adc b #", 458 | 0xca: "ora b #", 459 | 0xcb: "add b #", 460 | 0xcc: "!", 461 | 0xcd: "!", 462 | 0xce: "ldx ##", 463 | 0xcf: "!", 464 | 0xd8: "eor b N", 465 | 0xd9: "adc b N", 466 | 0xda: "ora b N", 467 | 0xdb: "add b N", 468 | 0xdc: "!", 469 | 0xdd: "!hcf", 470 | 0xde: "ldx N", 471 | 0xdf: "stx N", 472 | 0xe8: "eor b Nx", 473 | 0xe9: "adc b Nx", 474 | 0xea: "ora b Nx", 475 | 0xeb: "add b Nx", 476 | 0xec: "!", 477 | 0xed: "!", 478 | 0xee: "ldx Nx", 479 | 0xef: "stx Nx", 480 | 0xf8: "eor b NN", 481 | 0xf9: "adc b NN", 482 | 0xfa: "ora b NN", 483 | 0xfb: "add b NN", 484 | 0xfc: "!", 485 | 0xfd: "!", 486 | 0xfe: "ldx NN", 487 | 0xff: "stx NN", 488 | }; 489 | -------------------------------------------------------------------------------- /chip-6800/testprogram.js: -------------------------------------------------------------------------------- 1 | // This file testprogram.js can be substituted by one of several tests 2 | testprogramAddress=0x0000; 3 | 4 | // we want to auto-clear the console if any output is sent by the program 5 | var consoleboxStream=""; 6 | 7 | // demonstrate write hook 8 | writeTriggers[0x8000]="consoleboxStream += String.fromCharCode(d);"+ 9 | "consolebox.innerHTML = consoleboxStream;"; 10 | 11 | // demonstrate read hook (not used by this test program) 12 | readTriggers[0x8004]="((consolegetc==undefined)?0:0xff)"; // return zero until we have a char 13 | readTriggers[0x8000]="var c=consolegetc; consolegetc=undefined; (c)"; 14 | 15 | // for opcodes, see http://www.textfiles.com/programming/CARDS/6800 16 | 17 | testprogram = [ 18 | 0xce, 0x43, 0x21, // LDX #4321 19 | 0x35, // TXS 20 | 0xce, 0x80, 0x00, // LDX #8000 21 | 0xc6, 0x40, // LDAB #$40 22 | 0xbd, 0x00, 0x10, // JSR $0010 23 | 0x7e, 0x00, 0x09, // JMP $0009 24 | 0x01, // NOP 25 | 0x4a, // DECA 26 | 0xe7, 0x00, // STAB 0, X 27 | 0x7c, 0x00, 0x0f, // INC $0F 28 | 0x0d, // SEC 29 | 0xc9, 0x02, // ADCB #$02 30 | 0x39, // RTS 31 | ] 32 | -------------------------------------------------------------------------------- /chip-z80/nodenames.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // * This file is automatically generated by Z80Simulator. * 3 | // * Please do not manually edit! Instead, find a transistor * 4 | // * that uses the new signal and use FindTransistor(x,y) in * 5 | // * Z80Simulator to cause that signal to be added. * 6 | // * This seems a pain, but it has two advantages: * 7 | // * - all signals are then available in Z80Simulator * 8 | // * - it avoids renumbering issues if/when the PNGs change * 9 | // *********************************************************** 10 | var nodenames ={ 11 | // Pads 12 | vss: 1, 13 | vcc: 2, 14 | clk: 3, 15 | ab0: 5, 16 | ab1: 6, 17 | ab2: 7, 18 | ab3: 8, 19 | ab4: 9, 20 | ab5: 10, 21 | ab6: 11, 22 | ab7: 12, 23 | ab8: 13, 24 | ab9: 14, 25 | ab10: 15, 26 | ab11: 16, 27 | ab12: 17, 28 | ab13: 18, 29 | ab14: 19, 30 | ab15: 20, 31 | _reset: 21, 32 | _wait: 22, 33 | wait: 22, 34 | _int: 23, 35 | int: 23, 36 | _irq: 23, 37 | irq: 23, 38 | _nmi: 24, 39 | nmi: 24, 40 | _busrq: 25, 41 | busrq: 25, 42 | _m1: 26, 43 | _rd: 27, 44 | _wr: 28, 45 | _mreq: 29, 46 | _iorq: 30, 47 | _rfsh: 31, 48 | db0: 32, 49 | db1: 33, 50 | db2: 34, 51 | db3: 35, 52 | db4: 36, 53 | db5: 37, 54 | db6: 38, 55 | db7: 39, 56 | _halt: 40, 57 | _busak: 41, 58 | // T-States 59 | t1: 115, 60 | t2: 137, 61 | t3: 144, 62 | t4: 166, 63 | t5: 134, 64 | t6: 168, 65 | // Machine cycles 66 | m1: 155, 67 | m2: 173, 68 | m3: 163, 69 | m4: 159, 70 | m5: 209, 71 | m6: 210, 72 | // EXX latches 73 | ex_af: 631, 74 | ex_bcdehl: 1770, 75 | ex_dehl0: 625, 76 | ex_dehl1: 629, 77 | ex_dehl_combined: 626, 78 | // Registers 79 | reg_a0: 2245, 80 | reg_a1: 2319, 81 | reg_a2: 2357, 82 | reg_a3: 2442, 83 | reg_a4: 2463, 84 | reg_a5: 2552, 85 | reg_a6: 2586, 86 | reg_a7: 2656, 87 | reg_f0: 1827, 88 | reg_f1: 1903, 89 | reg_f2: 1928, 90 | reg_f3: 2009, 91 | reg_f4: 2032, 92 | reg_f5: 2107, 93 | reg_f6: 2132, 94 | reg_f7: 2209, 95 | reg_b0: 2242, 96 | reg_b1: 2316, 97 | reg_b2: 2354, 98 | reg_b3: 2439, 99 | reg_b4: 2460, 100 | reg_b5: 2549, 101 | reg_b6: 2583, 102 | reg_b7: 2653, 103 | reg_c0: 1824, 104 | reg_c1: 1900, 105 | reg_c2: 1925, 106 | reg_c3: 2006, 107 | reg_c4: 2029, 108 | reg_c5: 2104, 109 | reg_c6: 2129, 110 | reg_c7: 2206, 111 | reg_d0: 2238, 112 | reg_d1: 2312, 113 | reg_d2: 2350, 114 | reg_d3: 2435, 115 | reg_d4: 2456, 116 | reg_d5: 2545, 117 | reg_d6: 2579, 118 | reg_d7: 2649, 119 | reg_e0: 1820, 120 | reg_e1: 1896, 121 | reg_e2: 1921, 122 | reg_e3: 2002, 123 | reg_e4: 2025, 124 | reg_e5: 2100, 125 | reg_e6: 2125, 126 | reg_e7: 2202, 127 | reg_h0: 2240, 128 | reg_h1: 2314, 129 | reg_h2: 2352, 130 | reg_h3: 2437, 131 | reg_h4: 2458, 132 | reg_h5: 2547, 133 | reg_h6: 2581, 134 | reg_h7: 2651, 135 | reg_l0: 1822, 136 | reg_l1: 1898, 137 | reg_l2: 1923, 138 | reg_l3: 2004, 139 | reg_l4: 2027, 140 | reg_l5: 2102, 141 | reg_l6: 2127, 142 | reg_l7: 2204, 143 | reg_w0: 2234, 144 | reg_w1: 2308, 145 | reg_w2: 2346, 146 | reg_w3: 2431, 147 | reg_w4: 2452, 148 | reg_w5: 2541, 149 | reg_w6: 2575, 150 | reg_w7: 2645, 151 | reg_z0: 1816, 152 | reg_z1: 1892, 153 | reg_z2: 1917, 154 | reg_z3: 1998, 155 | reg_z4: 2021, 156 | reg_z5: 2096, 157 | reg_z6: 2121, 158 | reg_z7: 2198, 159 | reg_pch0: 2232, 160 | reg_pch1: 2306, 161 | reg_pch2: 2344, 162 | reg_pch3: 2429, 163 | reg_pch4: 2450, 164 | reg_pch5: 2539, 165 | reg_pch6: 2573, 166 | reg_pch7: 2643, 167 | reg_pcl0: 1814, 168 | reg_pcl1: 1890, 169 | reg_pcl2: 1915, 170 | reg_pcl3: 1996, 171 | reg_pcl4: 2019, 172 | reg_pcl5: 2094, 173 | reg_pcl6: 2119, 174 | reg_pcl7: 2196, 175 | reg_sph0: 2235, 176 | reg_sph1: 2309, 177 | reg_sph2: 2347, 178 | reg_sph3: 2432, 179 | reg_sph4: 2453, 180 | reg_sph5: 2542, 181 | reg_sph6: 2576, 182 | reg_sph7: 2646, 183 | reg_spl0: 1817, 184 | reg_spl1: 1893, 185 | reg_spl2: 1918, 186 | reg_spl3: 1999, 187 | reg_spl4: 2022, 188 | reg_spl5: 2097, 189 | reg_spl6: 2122, 190 | reg_spl7: 2199, 191 | reg_ixh0: 2237, 192 | reg_ixh1: 2311, 193 | reg_ixh2: 2349, 194 | reg_ixh3: 2434, 195 | reg_ixh4: 2455, 196 | reg_ixh5: 2544, 197 | reg_ixh6: 2578, 198 | reg_ixh7: 2648, 199 | reg_ixl0: 1819, 200 | reg_ixl1: 1895, 201 | reg_ixl2: 1920, 202 | reg_ixl3: 2001, 203 | reg_ixl4: 2024, 204 | reg_ixl5: 2099, 205 | reg_ixl6: 2124, 206 | reg_ixl7: 2201, 207 | reg_iyh0: 2236, 208 | reg_iyh1: 2310, 209 | reg_iyh2: 2348, 210 | reg_iyh3: 2433, 211 | reg_iyh4: 2454, 212 | reg_iyh5: 2543, 213 | reg_iyh6: 2577, 214 | reg_iyh7: 2647, 215 | reg_iyl0: 1818, 216 | reg_iyl1: 1894, 217 | reg_iyl2: 1919, 218 | reg_iyl3: 2000, 219 | reg_iyl4: 2023, 220 | reg_iyl5: 2098, 221 | reg_iyl6: 2123, 222 | reg_iyl7: 2200, 223 | reg_i0: 2233, 224 | reg_i1: 2307, 225 | reg_i2: 2345, 226 | reg_i3: 2430, 227 | reg_i4: 2451, 228 | reg_i5: 2540, 229 | reg_i6: 2574, 230 | reg_i7: 2644, 231 | reg_r0: 1815, 232 | reg_r1: 1891, 233 | reg_r2: 1916, 234 | reg_r3: 1997, 235 | reg_r4: 2020, 236 | reg_r5: 2095, 237 | reg_r6: 2120, 238 | reg_r7: 2197, 239 | reg_aa0: 2244, 240 | reg_aa1: 2318, 241 | reg_aa2: 2356, 242 | reg_aa3: 2441, 243 | reg_aa4: 2462, 244 | reg_aa5: 2551, 245 | reg_aa6: 2585, 246 | reg_aa7: 2655, 247 | reg_ff0: 1826, 248 | reg_ff1: 1902, 249 | reg_ff2: 1927, 250 | reg_ff3: 2008, 251 | reg_ff4: 2031, 252 | reg_ff5: 2106, 253 | reg_ff6: 2131, 254 | reg_ff7: 2208, 255 | reg_bb0: 2243, 256 | reg_bb1: 2317, 257 | reg_bb2: 2355, 258 | reg_bb3: 2440, 259 | reg_bb4: 2461, 260 | reg_bb5: 2550, 261 | reg_bb6: 2584, 262 | reg_bb7: 2654, 263 | reg_cc0: 1825, 264 | reg_cc1: 1901, 265 | reg_cc2: 1926, 266 | reg_cc3: 2007, 267 | reg_cc4: 2030, 268 | reg_cc5: 2105, 269 | reg_cc6: 2130, 270 | reg_cc7: 2207, 271 | reg_dd0: 2239, 272 | reg_dd1: 2313, 273 | reg_dd2: 2351, 274 | reg_dd3: 2436, 275 | reg_dd4: 2457, 276 | reg_dd5: 2546, 277 | reg_dd6: 2580, 278 | reg_dd7: 2650, 279 | reg_ee0: 1821, 280 | reg_ee1: 1897, 281 | reg_ee2: 1922, 282 | reg_ee3: 2003, 283 | reg_ee4: 2026, 284 | reg_ee5: 2101, 285 | reg_ee6: 2126, 286 | reg_ee7: 2203, 287 | reg_hh0: 2241, 288 | reg_hh1: 2315, 289 | reg_hh2: 2353, 290 | reg_hh3: 2438, 291 | reg_hh4: 2459, 292 | reg_hh5: 2548, 293 | reg_hh6: 2582, 294 | reg_hh7: 2652, 295 | reg_ll0: 1823, 296 | reg_ll1: 1899, 297 | reg_ll2: 1924, 298 | reg_ll3: 2005, 299 | reg_ll4: 2028, 300 | reg_ll5: 2103, 301 | reg_ll6: 2128, 302 | reg_ll7: 2205, 303 | // Data buses and control 304 | dp_dl: 82, 305 | dl_dp: 165, 306 | load_ir: 1354, 307 | dlatch0: 123, 308 | dlatch1: 195, 309 | dlatch2: 414, 310 | dlatch3: 930, 311 | dlatch4: 1000, 312 | dlatch5: 872, 313 | dlatch6: 751, 314 | dlatch7: 358, 315 | dl_d: 87, 316 | d_dl: 133, 317 | dbus0: 138, 318 | dbus1: 196, 319 | dbus2: 412, 320 | dbus3: 480, 321 | dbus4: 485, 322 | dbus5: 486, 323 | dbus6: 380, 324 | dbus7: 370, 325 | _instr0: 1350, 326 | _instr1: 1360, 327 | _instr2: 1366, 328 | _instr3: 1380, 329 | _instr4: 1388, 330 | _instr5: 1395, 331 | _instr6: 1370, 332 | _instr7: 1375, 333 | instr0: 1348, 334 | instr1: 1359, 335 | instr2: 1365, 336 | instr3: 1379, 337 | instr4: 1387, 338 | instr5: 1394, 339 | instr6: 1369, 340 | instr7: 1374, 341 | d_u: 546, 342 | ubus0: 545, 343 | ubus1: 528, 344 | ubus2: 526, 345 | ubus3: 770, 346 | ubus4: 779, 347 | ubus5: 790, 348 | ubus6: 716, 349 | ubus7: 525, 350 | u_v: 750, 351 | vbus0: 755, 352 | vbus1: 772, 353 | vbus2: 783, 354 | vbus3: 796, 355 | vbus4: 803, 356 | vbus5: 808, 357 | vbus6: 836, 358 | vbus7: 839, 359 | rl_wr: 678, 360 | rh_wr: 652, 361 | r_u: 692, 362 | r_v: 693, 363 | regbit0: 702, 364 | regbit1: 732, 365 | regbit2: 738, 366 | regbit3: 775, 367 | regbit4: 776, 368 | regbit5: 807, 369 | regbit6: 809, 370 | regbit7: 864, 371 | regbit8: 870, 372 | regbit9: 902, 373 | regbit10: 906, 374 | regbit11: 934, 375 | regbit12: 935, 376 | regbit13: 970, 377 | regbit14: 973, 378 | regbit15: 999, 379 | r_p: 1785, 380 | r_x1: 608, 381 | pcbit0: 703, 382 | pcbit1: 731, 383 | pcbit2: 739, 384 | pcbit3: 774, 385 | pcbit4: 777, 386 | pcbit5: 806, 387 | pcbit6: 810, 388 | pcbit7: 863, 389 | pcbit8: 871, 390 | pcbit9: 901, 391 | pcbit10: 907, 392 | pcbit11: 933, 393 | pcbit12: 936, 394 | pcbit13: 969, 395 | pcbit14: 974, 396 | pcbit15: 998, 397 | // ALU 398 | alubus0: 837, 399 | alubus1: 889, 400 | alubus2: 937, 401 | alubus3: 983, 402 | alubus4: 852, 403 | alubus5: 903, 404 | alubus6: 951, 405 | alubus7: 995, 406 | alua0: 850, 407 | alua1: 899, 408 | alua2: 947, 409 | alua3: 993, 410 | alua4: 868, 411 | alua5: 920, 412 | alua6: 968, 413 | alua7: 1007, 414 | alub0: 845, 415 | alub1: 897, 416 | alub2: 944, 417 | alub3: 988, 418 | alub4: 867, 419 | alub5: 918, 420 | alub6: 966, 421 | alub7: 1005, 422 | aluout0: 2211, 423 | aluout1: 2338, 424 | aluout2: 2504, 425 | aluout3: 816, 426 | alulat0: 865, 427 | alulat1: 912, 428 | alulat2: 960, 429 | alulat3: 1002, 430 | // PLA 431 | pla0: 287, 432 | pla1: 332, 433 | pla2: 314, 434 | pla3: 333, 435 | pla4: 315, 436 | pla5: 334, 437 | pla6: 316, 438 | pla7: 335, 439 | pla8: 317, 440 | pla9: 336, 441 | pla10: 318, 442 | pla11: 361, 443 | pla12: 261, 444 | pla13: 337, 445 | pla14: 319, 446 | pla15: 464, 447 | pla16: 288, 448 | pla17: 338, 449 | pla18: 320, 450 | pla19: 364, 451 | pla20: 325, 452 | pla21: 324, 453 | pla22: 308, 454 | pla23: 289, 455 | pla24: 339, 456 | pla25: 313, 457 | pla26: 340, 458 | pla27: 290, 459 | pla28: 341, 460 | pla29: 291, 461 | pla30: 342, 462 | pla31: 292, 463 | pla32: 365, 464 | pla33: 293, 465 | pla34: 362, 466 | pla35: 294, 467 | pla36: 331, 468 | pla37: 293, 469 | pla38: 343, 470 | pla39: 296, 471 | pla40: 297, 472 | pla41: 298, 473 | pla42: 344, 474 | pla43: 299, 475 | pla44: 269, 476 | pla45: 300, 477 | pla46: 237, 478 | pla47: 301, 479 | pla48: 345, 480 | pla49: 302, 481 | pla50: 346, 482 | pla51: 264, 483 | pla52: 266, 484 | pla53: 347, 485 | pla54: 303, 486 | pla55: 356, 487 | pla56: 227, 488 | pla57: 366, 489 | pla58: 304, 490 | pla59: 305, 491 | pla60: 271, 492 | pla61: 348, 493 | pla62: 306, 494 | pla63: 309, 495 | pla64: 311, 496 | pla65: 312, 497 | pla66: 307, 498 | pla67: 367, 499 | pla68: 272, 500 | pla69: 349, 501 | pla70: 273, 502 | pla71: 350, 503 | pla72: 274, 504 | pla73: 351, 505 | pla74: 275, 506 | pla75: 276, 507 | pla76: 268, 508 | pla77: 352, 509 | pla78: 277, 510 | pla79: 278, 511 | pla80: 279, 512 | pla81: 280, 513 | pla82: 368, 514 | pla83: 281, 515 | pla84: 282, 516 | pla85: 283, 517 | pla86: 284, 518 | pla87: 285, 519 | pla88: 286, 520 | pla89: 321, 521 | pla90: 353, 522 | pla91: 322, 523 | pla92: 354, 524 | pla93: 323, 525 | pla94: 369, 526 | pla95: 258, 527 | pla96: 249, 528 | pla97: 245, 529 | pla98: 355, 530 | } 531 | -------------------------------------------------------------------------------- /chip-z80/testprogram.js: -------------------------------------------------------------------------------- 1 | // This file testprogram.js can be substituted by one of several tests 2 | testprogramAddress=0x0000; 3 | 4 | // we want to auto-clear the console if any output is sent by the program 5 | var consoleboxStream=""; 6 | 7 | // demonstrate write hook 8 | writeTriggers[0x8000]="consoleboxStream += String.fromCharCode(d);"+ 9 | "consolebox.innerHTML = consoleboxStream;"; 10 | 11 | // demonstrate read hook (not used by this test program) 12 | readTriggers[0x8004]="((consolegetc==undefined)?0:0xff)"; // return zero until we have a char 13 | readTriggers[0x8000]="var c=consolegetc; consolegetc=undefined; (c)"; 14 | 15 | // for opcodes, see http://www.textfiles.com/programming/CARDS/6800 16 | 17 | testprogram = [ 18 | 0x00, // NOP 19 | 0x31, 0x00, 0x01, // LD SP,0x0100 20 | 0xCD, 0x0B, 0x00, // CALL $000B 21 | 0x00, // NOP 22 | 0x21, 0x78, 0x56, // LD HL,$5678 23 | 0x21, 0x34, 0x12, // LD HL,$1234 24 | 0xe5, // PUSH HL 25 | 0x00, // NOP 26 | 0x00, // NOP 27 | 0x3C, // INC A 28 | 0x04, // INC B 29 | 0x15, // DEC D 30 | 0x24, // INC H 31 | 0xEB, // EXX DE,HL 32 | 0x00, // NOP 33 | 0x3C, // INC A 34 | 0x04, // INC B 35 | 0x15, // DEC D 36 | 0x24, // INC H 37 | 0xD9, // EXX 38 | 0x00, // NOP 39 | 0x3C, // INC A 40 | 0x04, // INC B 41 | 0x15, // DEC D 42 | 0x24, // INC H 43 | 0xEB, // EXX DE,HL 44 | 0x00, // NOP 45 | 0x3C, // INC A 46 | 0x04, // INC B 47 | 0x15, // DEC D 48 | 0x24, // INC H 49 | 0x08, // EXX AF,AF' 50 | 0x00, // NOP 51 | 0x3C, // INC A 52 | 0x04, // INC B 53 | 0x15, // DEC D 54 | 0x24, // INC H 55 | 0x00, // NOP 56 | 0x00, // NOP 57 | 0x00, // NOP 58 | 0x21, 0x00, 0x01, // LD HL,$0100 59 | 0x36, 0xCC, // LD (HL),$CC 60 | 0x00, // NOP 61 | 0x7E, // LD A, (HL) 62 | 0x00, // NOP 63 | // Pavel's original test program 64 | 0x21, 0x34, 0x12, // LD HL,$1234 65 | 0x31, 0xfe, 0xdc, // LD SP,0xDCFE 66 | 0xe5, // PUSH HL 67 | 0x21, 0x78, 0x56, // LD HL,$5678 68 | 0xe3, // EX (SP),HL 69 | 0xdd, 0x21, 0xbc,0x9a, // LD IX, 0x9ABC 70 | 0xdd, 0xe3, // EX (SP),IX 71 | 0x76, // HALT 72 | 0x00 // NOP 73 | ] 74 | -------------------------------------------------------------------------------- /chipsim.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var ctrace = false; 24 | var traceTheseNodes = []; 25 | var traceTheseTransistors = []; 26 | var loglevel = 0; 27 | var recalclist = new Array(); 28 | var recalcHash = new Array(); 29 | var group = new Array(); 30 | 31 | function recalcNodeList(list){ 32 | var n = list[0]; 33 | recalclist = new Array(); 34 | recalcHash = new Array(); 35 | for(var j=0;j<100;j++){ // loop limiter 36 | if(list.length==0) return; 37 | if(ctrace) { 38 | var i; 39 | for(i=0;i [ "49", 483, 49 ] 152 | ii = Number( i ); 153 | if((ii!=npwr)&&(ii!=ngnd)) res.push(ii); 154 | } 155 | return res; 156 | } 157 | 158 | function stateString(){ 159 | var codes = ['l','h']; 160 | var res = ''; 161 | for(var i=0;i 2 | 3 | 4 | Visual 6800 in JavaScript 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 53 | 54 | 55 | 56 | FAQ  57 | Blog  58 | Links  59 | Source  60 | 6800 instruction card  61 | programming model  62 | 63 |

64 |
65 |
66 |
67 | Please wait, graphics initialising... 68 | 69 | 70 | 71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 | Use 'z' or '>' to zoom in, 'x' or '<' to zoom out, click to probe signals and drag to pan. 81 |
Show: 82 | (diffusion) 83 | (grounded diffusion) 84 | (powered diffusion) 85 | (polysilicon) 86 | (metal) 87 | (protection) 88 |
89 |
90 | 91 | 92 | 93 | 94 | Animate during simulation: 95 | 97 |
98 |
99 | 100 | Link to this location 101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | 109 | 110 |
111 |
112 | 113 | 114 | 115 | 116 | 117 |
118 |
119 | User Guide 120 |   121 |
122 |
123 |

x: 0
y: 0

124 |
125 | 126 |
127 |
128 |
129 |
130 | 131 |
132 | 135 |
136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | 153 | 154 | -------------------------------------------------------------------------------- /expert-z80.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Visual Z80 in JavaScript 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 53 | 54 | 55 | 56 | FAQ  57 | Blog  58 | Links  59 | Source  60 | 61 |
62 |
63 |
64 |
65 | Please wait, graphics initialising... 66 | 67 | 68 | 69 | 70 |
71 |
72 |
73 |
74 | 75 |
76 |
77 |
78 | Use 'z' or '>' to zoom in, 'x' or '<' to zoom out, click to probe signals and drag to pan. 79 |
Show: 80 | (diffusion) 81 | (grounded diffusion) 82 | (powered diffusion) 83 | (polysilicon) 84 | (metal) 85 | (protection) 86 |
87 |
88 | 89 | 90 | 91 | 92 | Animate during simulation: 93 | 95 |
96 |
97 | 98 | Link to this location 99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | 107 | 108 |
109 |
110 | 111 | 112 | 113 | 114 | 115 |
116 |
117 | User Guide 118 |   119 |
120 |
121 |

x: 0
y: 0

122 |
123 | 124 |
125 |
126 |
127 |
128 | 129 |
130 | 133 |
134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | 151 | 152 | -------------------------------------------------------------------------------- /expert.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | body { 24 | background: white; 25 | color: black; 26 | font-family :Verdana, Arial, Helvetica, Sans-Serif; 27 | font-size: 12px; 28 | } 29 | 30 | #title { 31 | font-size: 30px; 32 | font-weight: bold; 33 | } 34 | 35 | div.frame { 36 | margin-left: 10px; 37 | min-width: 1120px; /* ugh - prevent memtable flowing underneath chip */ 38 | } 39 | 40 | div.leftcolumn { 41 | width: 804px; /* ugh - matches the div.chip width + border */ 42 | } 43 | 44 | div.rightcolumn { 45 | padding-left: 8px; 46 | } 47 | 48 | div.footer { 49 | clear: both; 50 | padding-top: 10px; 51 | } 52 | 53 | div.nochip { 54 | display:none; 55 | } 56 | 57 | div#chipsurround { 58 | height: 600px; /* matches the div.chip height */ 59 | } 60 | 61 | div.chip { 62 | background: lightgray; 63 | border: 2px solid gray; 64 | position: absolute; /* must be absolute to contain the canvas */ 65 | width: 800px; 66 | height: 600px; 67 | overflow: hidden; 68 | } 69 | 70 | canvas.chip { 71 | position: absolute; 72 | width: 600px; /* square chip image same height as div.chip */ 73 | height: 600px; /* square */ 74 | } 75 | 76 | div.twobuttons{ 77 | float:left; 78 | } 79 | 80 | div.morebuttons{ 81 | float:left; 82 | } 83 | 84 | div.buttons{ 85 | /* top: -5px; */ 86 | } 87 | 88 | div.status { 89 | clear: left; 90 | padding-top: 10px; 91 | padding-bottom: 10px; 92 | font-family: monospace; 93 | font-size: 12px; 94 | } 95 | 96 | img.navbutton { 97 | border: 0px; 98 | } 99 | 100 | img.navplay { 101 | margin-right: 5px; 102 | border: 0px; 103 | } 104 | 105 | img.navstop { 106 | position: absolute; 107 | border: 0px; 108 | } 109 | 110 | span.expertcheckbox { 111 | margin-left: 20px; 112 | } 113 | 114 | table.memtable { 115 | font-family: monospace; 116 | font-size: 12px; 117 | border-spacing: 0px; 118 | overflow: auto; 119 | } 120 | 121 | div#layoutControlPanel{ 122 | display:none; 123 | margin-top: 2px; 124 | margin-bottom: 2px; 125 | } 126 | 127 | div#expertControlPanel{ 128 | display:none; 129 | } 130 | 131 | span.animatebox{ 132 | border:thin solid; 133 | padding:2px; 134 | border-color:gray; 135 | } 136 | 137 | a#linkHere{ 138 | padding:2px; 139 | } 140 | 141 | textarea#consolebox{ 142 | font-family:courier,monospace; 143 | border: 1px solid gray; 144 | margin: 2px; 145 | padding: 2px; 146 | width: 80em; 147 | } 148 | 149 | div#logstreamscroller{ 150 | overflow:auto; 151 | } 152 | 153 | table.logstream { 154 | font-family: monospace; 155 | font-size: 12px; 156 | border-collapse: collapse; 157 | text-align:center; 158 | } 159 | 160 | td { 161 | padding-left: 3px; 162 | padding-right: 3px; 163 | } 164 | 165 | td.header { 166 | background-color: rgb(187, 204, 255); /* medium-dark blue */ 167 | } 168 | 169 | td.oddcol { 170 | background-color: rgb(227, 233, 255); /* light blue */ 171 | } 172 | 173 | td.oddrow { 174 | background-color: rgb(207, 218, 255); /* medium blue */ 175 | } 176 | 177 | td.oddrowcol { 178 | background-color: rgb(227, 233, 255); /* light blue */ 179 | } 180 | 181 | /* Splitter */ 182 | #frame { 183 | height: 750px; 184 | } 185 | 186 | div.leftcolumn, div.rightcolumn, { 187 | overflow: auto; 188 | } 189 | 190 | div#righttopdiv, div#tracingdiv { 191 | overflow: auto; 192 | background-color: white; 193 | } 194 | 195 | div.rightcolumn { 196 | background-color: white; 197 | } 198 | 199 | .vsplitbar { 200 | width: 5px; 201 | background: #aaa; 202 | } 203 | 204 | .vsplitbar { 205 | width: 6px; 206 | background: #669 url(3rdparty/img/vgrabber.gif) no-repeat center; 207 | } 208 | 209 | .vsplitbar:hover, .vsplitbar.active { 210 | background: #c66 url(3rdparty/img/vgrabber.gif) no-repeat center; 211 | opacity: 0.7; 212 | filter: alpha(opacity=70); /* IE */ 213 | background: #c99; 214 | } 215 | 216 | .hsplitbar { 217 | height: 6px; 218 | background: #669 url(3rdparty/img/hgrabber.gif) no-repeat center; 219 | } 220 | 221 | .hsplitbar.active, .hsplitbar:hover { 222 | background: #c66 url(3rdparty/img/hgrabber.gif) no-repeat center; 223 | } 224 | 225 | span#plain { 226 | display: block; 227 | margin-bottom: 4px; 228 | } 229 | -------------------------------------------------------------------------------- /expert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Visual 6502 in JavaScript 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 50 | 51 | 52 | 53 | 54 | 55 | FAQ  56 | Blog  57 | Links  58 | Source  59 | easy6502 assembler  60 | mass:werk disassembler  61 | 62 |
63 |
64 |
65 |
66 | Please wait, graphics initialising... 67 | 68 | 69 | 70 | 71 |
72 |
73 |
74 |
75 | 76 |
77 |
78 |
79 | Use 'z' or '>' to zoom in, 'x' or '<' to zoom out, click to probe signals and drag to pan. 80 |
Show: 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 |
89 | 90 | 91 | 92 | 93 | 94 | 96 |
97 |
98 | 99 | Link to this location 100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | 108 | 109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 |
117 |
118 | User Guide 119 |   120 |
121 |
122 |

x: 0
y: 0

123 |
124 | 125 |
126 |
127 |
128 |
129 | 130 |
131 | 134 |
135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | 152 | 153 | -------------------------------------------------------------------------------- /expertWires.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var centerx=300, centery=300; 24 | var zoom=1; 25 | var dragMouseX, dragMouseY, moved; 26 | var statbox; 27 | var findThese; 28 | var labelThese=[]; 29 | 30 | // Some constants for the graphics presentation 31 | // the canvas is embedded in an 800x600 clipping div 32 | // which gives rise to some of the 300 and 400 values in the code 33 | // there are also some 600 values 34 | // the 6502D chip coords are in the box (216,179) to (8983,9807) 35 | // we have 4 canvases all the same size, now 2000 pixels square 36 | // chip background - the layout 37 | // overlay - a red/white transparency to show logic high or low 38 | // hilite - to show the selected polygon 39 | // hitbuffer - abusing color values to return which polygon is under a point 40 | // we no longer use a scaling transform - we now scale the chip data at 41 | // the point of drawing line segments 42 | // if the canvas is any smaller than chip coordinates there will be 43 | // rounding artifacts, and at high zoom there will be anti-aliasing on edges. 44 | var grMaxZoom=12; 45 | var grChipSize=10000; 46 | var grChipOffsetX=400; 47 | var grChipOffsetY=0; 48 | var grCanvasSize=2000; 49 | var grLineWidth=1; 50 | 51 | // Index of layerNames corresponds to index into drawLayers 52 | var layernames = ['metal', 'switched diffusion', 'inputdiode', 'grounded diffusion', 'powered diffusion', 'polysilicon']; 53 | var colors = ['rgba(128,128,192,0.4)','#FFFF00','#FF00FF','#4DFF4D', 54 | '#FF4D4D','#801AC0','rgba(128,0,255,0.75)']; 55 | var drawlayers = [true, true, true, true, true, true]; 56 | 57 | // some modes and parameters which can be passed in from the URL query 58 | var moveHereFirst; 59 | var expertMode=true; 60 | var animateChipLayout = true; 61 | var userCode=[]; 62 | var userResetLow; 63 | var userResetHigh; 64 | var headlessSteps=1000; 65 | var noSimulation=false; 66 | var testprogram=[]; 67 | var testprogramAddress; 68 | 69 | ///////////////////////// 70 | // 71 | // Drawing Setup 72 | // 73 | ///////////////////////// 74 | 75 | // try to present a meaningful page before starting expensive work 76 | function setup(){ 77 | statbox = document.getElementById('status'); 78 | setStatus('loading 6502...'); 79 | setTimeout(setup_part2, 0); 80 | } 81 | 82 | function setup_part2(){ 83 | frame = document.getElementById('frame'); 84 | statbox = document.getElementById('status'); 85 | // load the circuit before acting on URL parameters 86 | setupNodes(); 87 | setupTransistors(); 88 | setupParams(); 89 | setupExpertMode(); 90 | detectOldBrowser(); 91 | setStatus('loading graphics...'); 92 | setTimeout(setup_part3, 0); 93 | } 94 | 95 | function setup_part3(){ 96 | if(chipLayoutIsVisible){ 97 | // if user requests no chip layout, we can skip all canvas operations 98 | // which saves a lot of memory and allows us to run on small systems 99 | updateChipLayoutVisibility(true); 100 | } 101 | setStatus('resetting ' + chipname + '...'); 102 | setTimeout(setup_part4, 0); 103 | } 104 | 105 | function setup_part4(){ 106 | setupTable(); 107 | setupNodeNameList(); 108 | logThese=signalSet(loglevel); 109 | loadProgram(); 110 | setupConsole(); 111 | if(noSimulation){ 112 | stopChip(); 113 | running=undefined; 114 | setStatus('Ready!'); 115 | } else { 116 | initChip(); 117 | document.getElementById('stop').style.visibility = 'hidden'; 118 | go(); 119 | } 120 | } 121 | 122 | function detectOldBrowser(){ 123 | if(!("getBoundingClientRect" in document.documentElement)){ 124 | // simplify these functions (and adjust layout window position) 125 | localx= function(el, gx){ 126 | return gx-el.offsetLeft; 127 | } 128 | localy= function(el, gy){ 129 | return gy-el.offsetTop; 130 | } 131 | document.getElementById('plain').style["float"]="right"; 132 | document.getElementById('chip').style.left=0; 133 | document.getElementById('chip').style.top=0; 134 | document.getElementById('chip').style.border=0; 135 | } 136 | } 137 | 138 | function setupParams(){ 139 | if(location.search=="") 140 | return 141 | var queryParts=location.search.slice(1).split('&'); 142 | var panx; 143 | var pany; 144 | var zoom; 145 | var userAddress; 146 | for(var i=0;i0) 150 | console.log('malformed parameters',params); 151 | break; 152 | } 153 | var name=params[0]; 154 | var value=params[1].replace(/\/$/,""); // chrome sometimes adds trailing slash 155 | // be (relatively) forgiving in what we accept 156 | // 157 | // user interface mode control 158 | if(name=="loglevel" && parseInt(value)!=NaN){ 159 | updateLoglevel(value); 160 | } else if(name=="logmore" && value!=""){ 161 | updateLogList(value); 162 | } else if(name=="headlesssteps" && parseInt(value)!=NaN){ 163 | headlessSteps=parseInt(value); 164 | } else if(name=="graphics" && value.indexOf("f")==0){ 165 | updateChipLayoutVisibility(false); 166 | } else if(name=="canvas" && parseInt(value)!=NaN){ 167 | grCanvasSize=value; 168 | // suppress simulation (for layout viewing only on slow browsers) 169 | } else if(name=="nosim" && value.indexOf("t")==0){ 170 | noSimulation=true; 171 | } else 172 | // place the graphics window at a point of interest 173 | if(name=="panx" && parseInt(value)!=NaN){ 174 | panx=parseInt(value); 175 | } else if(name=="pany" && parseInt(value)!=NaN){ 176 | pany=parseInt(value); 177 | } else if(name=="zoom" && parseInt(value)!=NaN){ 178 | zoom=parseInt(value); 179 | } else 180 | // perform a search, highlight and zoom to object(s) 181 | if(name=="find" && value.length>0){ 182 | findThese=value; 183 | } else 184 | // affix label with optional box to highlight an area of interest 185 | if(name=="label" && value.length>0){ 186 | labelThese.push(value.split(",")); 187 | } else 188 | // load a test program: Address, Data and Reset 189 | if(name=="a" && parseInt(value,16)!=NaN){ 190 | userAddress=parseInt(value,16); 191 | } else if(name=="d" && value.match(/[0-9a-fA-F]*/)[0].length==value.length){ 192 | for(var j=0;j>8)%256; 197 | } else 198 | // setup input pin events, breakpoints, watchpoints 199 | if(name=="reset0" && parseInt(value)!=NaN){ 200 | clockTriggers[value]=[clockTriggers[value],"setLow(nodenamereset);"].join(""); 201 | } else if(name=="reset1" && parseInt(value)!=NaN){ 202 | clockTriggers[value]=[clockTriggers[value],"setHigh(nodenamereset);"].join(""); 203 | } else if(name=="irq0" && parseInt(value)!=NaN){ 204 | clockTriggers[value]=[clockTriggers[value],"setLow('irq');"].join(""); 205 | } else if(name=="irq1" && parseInt(value)!=NaN){ 206 | clockTriggers[value]=[clockTriggers[value],"setHigh('irq');"].join(""); 207 | } else if(name=="nmi0" && parseInt(value)!=NaN){ 208 | clockTriggers[value]=[clockTriggers[value],"setLow('nmi');"].join(""); 209 | } else if(name=="nmi1" && parseInt(value)!=NaN){ 210 | clockTriggers[value]=[clockTriggers[value],"setHigh('nmi');"].join(""); 211 | } else if(name=="rdy0" && parseInt(value)!=NaN){ 212 | clockTriggers[value]=[clockTriggers[value],"setLow('rdy');"].join(""); 213 | } else if(name=="rdy1" && parseInt(value)!=NaN){ 214 | clockTriggers[value]=[clockTriggers[value],"setHigh('rdy');"].join(""); 215 | } else if(name=="so0" && parseInt(value)!=NaN){ 216 | clockTriggers[value]=[clockTriggers[value],"setLow('so');"].join(""); 217 | } else if(name=="so1" && parseInt(value)!=NaN){ 218 | clockTriggers[value]=[clockTriggers[value],"setHigh('so');"].join(""); 219 | // Some Z80 inputs - we can refactor if this becomes unwieldy 220 | } else if(name=="int0" && parseInt(value)!=NaN){ 221 | clockTriggers[value]=[clockTriggers[value],"setLow('int');"].join(""); 222 | } else if(name=="int1" && parseInt(value)!=NaN){ 223 | clockTriggers[value]=[clockTriggers[value],"setHigh('int');"].join(""); 224 | } else if(name=="wait0" && parseInt(value)!=NaN){ 225 | clockTriggers[value]=[clockTriggers[value],"setLow('wait');"].join(""); 226 | } else if(name=="wait1" && parseInt(value)!=NaN){ 227 | clockTriggers[value]=[clockTriggers[value],"setHigh('wait');"].join(""); 228 | } else if(name=="busrq0" && parseInt(value)!=NaN){ 229 | clockTriggers[value]=[clockTriggers[value],"setLow('busrq');"].join(""); 230 | } else if(name=="busrq1" && parseInt(value)!=NaN){ 231 | clockTriggers[value]=[clockTriggers[value],"setHigh('busrq');"].join(""); 232 | // 233 | } else if(name=="time" && parseInt(value)!=NaN){ 234 | eventTime=value; 235 | } else if(name=="databus" && parseInt(value)!=NaN){ 236 | clockTriggers[eventTime]=[clockTriggers[eventTime],"writeDataBus(0x"+value+");"].join(""); 237 | } else 238 | // run a test program, and optionally check against a golden checksum 239 | if(name=="steps" && parseInt(value)!=NaN){ 240 | userSteps=parseInt(value); 241 | running=true; 242 | } else if(name=="checksum" && parseInt(value,16)!=NaN){ 243 | goldenChecksum=(0x100000000+parseInt(value,16)).toString(16).slice(-8); 244 | } else { 245 | if(loglevel>0) 246 | console.log('unrecognised parameters:',params); 247 | break; 248 | } 249 | } 250 | if(panx!=null && pany!=null && zoom!=null) 251 | moveHereFirst=[panx,pany,zoom]; 252 | } 253 | 254 | function updateChipLayoutAnimation(isOn){ 255 | // simulation is much faster if we don't update the chip layout on every step 256 | animateChipLayout=isOn; 257 | document.getElementById('animateModeCheckbox').checked = animateChipLayout; 258 | } 259 | 260 | ///////////////////////// 261 | // 262 | // User Interface 263 | // 264 | ///////////////////////// 265 | 266 | 267 | // these keyboard actions are primarily for the chip display 268 | function handleKey(e){ 269 | var c = e.charCode || e.keyCode; 270 | c = String.fromCharCode(c); 271 | if('<>?npZzx'.indexOf(c)==-1) return; 272 | if((c=='Z'||c=='x'||c=='<') && zoom>1) setZoom(zoom/1.2); 273 | else if((c=='z'||c=='>') && zoom0 && zoom>1) setZoom(zoom/1.2); 286 | if(n<0 && zoom4){ 395 | ctxDrawBox(ctx, boxXmin, boxYmin, boxXmax, boxYmax); 396 | // offset the text label to the interior of the box 397 | boxYmin -= thickness * 2; 398 | } 399 | ctx.strokeStyle = '#fff'; // white 400 | ctx.strokeStyle = '#000'; // black 401 | ctx.lineWidth = thickness*2; 402 | ctx.strokeText(text, boxXmin, boxYmin); 403 | ctx.fillText(text, boxXmin, boxYmin); 404 | } 405 | 406 | var highlightThese; 407 | 408 | // flash some set of nodes according to user input 409 | // also zoom to fit those nodes (not presently optional) 410 | function hiliteNodeList(){ 411 | var tmplist = document.getElementById('HighlightThese').value.split(/[\s,]+/); 412 | if(tmplist.join("").length==0){ 413 | // request to highlight nothing, so switch off any signal highlighting 414 | hiliteNode(-1); 415 | return; 416 | } 417 | highlightThese = []; 418 | var seglist=[]; 419 | var report=""; 420 | for(var i=0;ixmax) xmax=seglist[s][i]; 472 | if(seglist[s][i+1]ymax) ymax=seglist[s][i+1]; 474 | } 475 | } 476 | zoomToBox(xmin,xmax,ymin,ymax); 477 | updateLinkHere(); 478 | clearHighlight(); // nullify the simulation overlay (orange/purple) 479 | hiliteNode(-1); // unhighlight all nodes 480 | setTimeout("hiliteNode(highlightThese);", 400); 481 | setTimeout("hiliteNode(-1);", 800); 482 | setTimeout("hiliteNode(highlightThese);", 1200); 483 | } 484 | 485 | // some notes on coordinates: 486 | // the localx and localy functions return canvas coordinate offsets from the canvas window top left corner 487 | // we divide the results by 'zoom' to get drawn coordinates useful in findNodeNumber 488 | // to convert to reported user chip coordinates we multiply by grChipSize/600 489 | // to compare to segdefs and transdefs coordinates we subtract grChipOffsetX from x and subtract y from grChipSize plus grChipOffsetY 490 | 491 | function handleClick(e){ 492 | var x = localx(hilite, e.clientX)/zoom; 493 | var y = localy(hilite, e.clientY)/zoom; 494 | var w = findNodeNumber(x,y); 495 | // convert to chip coordinates 496 | var cx = Math.round(x*grChipSize/600); 497 | var cy = Math.round(y*grChipSize/600); 498 | // prepare two lines of status report 499 | var s1='x: ' + (cx - grChipOffsetX) + ' y: ' + (cy - grChipOffsetY); 500 | var s2='node: ' + w + ' ' + nodeName(w); 501 | if(w==-1) { 502 | setStatus(s1); // no node found, so report only coordinates 503 | return; 504 | } 505 | // we have a node, but maybe we clicked over a transistor 506 | var nodelist=[w]; 507 | // match the coordinate against transistor gate bounding boxes 508 | x=cx-grChipOffsetX; 509 | y=grChipSize+grChipOffsetY-cy; 510 | for(var i=0;i= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)){ 514 | // only one match at most, so we replace rather than push 515 | nodelist=[nodes[w].gates[i].name]; 516 | s2='transistor: ' + nodes[w].gates[i].name + ' on ' + s2; 517 | } 518 | } 519 | // if this is a shift-click, just find and highlight the pass-connected group 520 | // and list the nodes (or nodenames, preferably) 521 | if(e.shiftKey) { 522 | getNodeGroup(w); 523 | nodelist = group; 524 | s2 = "nodegroup from " + s2 + 525 | " (nodes: " + 526 | group.map(function(x){return nodeName(x)?nodeName(x):x;}).join(",") + 527 | ")"; 528 | } 529 | hiliteNode(nodelist); 530 | setStatus(s1, s2); 531 | if(ctrace) console.log(s1, s2); 532 | } 533 | 534 | function updateLoglevel(value){ 535 | loglevel = value; 536 | logThese = signalSet(loglevel); 537 | initLogbox(logThese); 538 | } 539 | 540 | function setupExpertMode(isOn){ 541 | document.getElementById('expertControlPanel').style.display = 'block'; 542 | if(loglevel==0) 543 | updateLoglevel(1); 544 | if(chipLayoutIsVisible) 545 | document.getElementById('layoutControlPanel').style.display = 'block'; 546 | } 547 | 548 | var consolegetc; // global variable to hold last keypress in the console area 549 | var consolebox; 550 | 551 | function setupConsole(){ 552 | consolebox=document.getElementById('consolebox'); 553 | consolebox.onkeypress=function(e){consolegetc=e.charCode || e.keyCode;}; 554 | } 555 | 556 | var chipsurround; 557 | 558 | function updateChipLayoutVisibility(isOn){ 559 | chipLayoutIsVisible=isOn; 560 | if(chipLayoutIsVisible) { 561 | updateChipLayoutAnimation(true); 562 | // resize the two panes appropriately 563 | $("#frame").trigger("resize", [ 810 ]); 564 | $("#rightcolumn").trigger("resize", [ 738 - 180 ]); 565 | // replace the Show Chip button with the chip graphics 566 | chipsurround=document.getElementById('chipsurround'); 567 | chipsurround.style.display = 'block'; 568 | document.getElementById('layoutControlPanel').style.display = 'block'; 569 | document.getElementById('nochip').style.display = 'none'; 570 | // allow the browser to respond while we load the graphics 571 | setStatus('loading graphics...'); 572 | setTimeout(setupChipLayoutGraphics, 0); 573 | } else { 574 | // cannot animate the layout if there is no canvas 575 | updateChipLayoutAnimation(false); 576 | // resize the two panes appropriately 577 | $("#frame").trigger("resize", [ 120 ]); 578 | $("#rightcolumn").trigger("resize", [ 200 ]); 579 | // replace the layout display with a button to show it 580 | document.getElementById('chipsurround').style.display = 'none'; 581 | document.getElementById('layoutControlPanel').style.display = 'none'; 582 | document.getElementById('nochip').style.display = 'block'; 583 | } 584 | } 585 | 586 | function setupChipLayoutGraphics(){ 587 | setupLayerVisibility(); 588 | setupBackground(); 589 | setupOverlay(); 590 | setupHilite(); 591 | setupHitBuffer(); 592 | recenter(); 593 | refresh(); 594 | document.getElementById('waiting').style.display = 'none'; 595 | setStatus('Ready!'); // would prefer chipStatus but it's not idempotent 596 | // pre-fill the Find box if parameters supplied 597 | if(typeof findThese != "undefined") { 598 | document.getElementById('HighlightThese').value = findThese; 599 | hiliteNodeList(); // will pan and zoom to fit 600 | } 601 | // pre-pan and zoom if requested (will override any zoom-to-fit by hiliteNodeList) 602 | if(moveHereFirst!=null) 603 | moveHere(moveHereFirst); 604 | // draw any URL-requested labels and boxes 605 | if(labelThese.length>0) { 606 | for(var i=0;i@import "kiosk.css"; 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 48 | 49 | 50 | 51 | 52 |
53 | The Visual 6502 54 | 55 |
56 | FAQ  57 | Blog  58 | Links  59 |

60 | This simulator uses HTML5 features only found on the latest versions of browsers and needs 61 | lots of RAM. If you have trouble, please check compatibility. 62 |
63 | 64 |
65 | Keyboard controls: 'z' to zoom in, 'x' to zoom out, 'n' to step the simulation. 66 |
67 | Mouse controls: Left-click and drag to scroll around (when you're zoomed in.) 68 |
69 | More information in the User Guide. 70 |
71 |
72 |
73 |
74 |
75 | 76 | 77 | 78 | 79 |
80 |
81 |
82 | 83 | 84 |
85 |
86 | 87 | 88 | 89 |
90 |
... or try Advanced
91 |
92 |

x: 0
y: 0

93 |
94 |
95 |
96 |
97 |
98 |
99 | Source code is available on github visual6502. 100 | Use the online emulator and assembler from the easy6502 tutorial 101 | and disassembler from mass:werk 102 |
103 | For in-depth 6502 investigation and some more advanced features, try our Advanced page. 104 |
105 |
106 | 107 | 115 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /kiosk.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | body { 24 | background: white; 25 | color: black; 26 | /* font-family: cursive;*/ 27 | font-family :Verdana, Arial, Helvetica, Sans-Serif; 28 | font-size: 12px; 29 | } 30 | 31 | div.frame { 32 | margin-left: 10px; 33 | position: relative; 34 | width: 1150px; 35 | height: 600px; 36 | } 37 | 38 | div.chip { 39 | background: lightgray; 40 | border: 2px solid gray; 41 | position: absolute; 42 | width: 800px; 43 | height: 600px; 44 | overflow: hidden; 45 | } 46 | 47 | canvas.chip { 48 | position: absolute; 49 | width: 600px; 50 | height: 600px; 51 | } 52 | 53 | div.buttons{ 54 | position: absolute; 55 | top: -5px; 56 | left: 820px; 57 | } 58 | 59 | p.status { 60 | position: absolute; 61 | left: 820px; 62 | top: 20px; 63 | font-family: monospace; 64 | font-size: 12px; 65 | } 66 | 67 | img.navbutton{ 68 | border: 0px; 69 | } 70 | 71 | img.navplay{ 72 | position: relative; 73 | margin-right: 5px; 74 | border: 0px; 75 | } 76 | 77 | img.navstop{ 78 | position: absolute; 79 | border: 0px; 80 | } 81 | 82 | table.memtable { 83 | position: absolute; 84 | top: 78px; 85 | left: 820px; 86 | font-family: monospace; 87 | font-size: 12px; 88 | border-spacing: 0px; 89 | } 90 | 91 | #title { 92 | font-size:30px; 93 | font-weight:bold; 94 | } -------------------------------------------------------------------------------- /kioskWires.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var centerx=300, centery=300; 24 | var zoom=1; 25 | var dragMouseX, dragMouseY, moved; 26 | var statbox; 27 | var animateChipLayout = true; 28 | var userCode=[]; 29 | var userResetLow; 30 | var userResetHigh; 31 | 32 | // Some constants for the graphics presentation 33 | // the canvas is embedded in an 800x600 clipping div 34 | // which gives rise to some of the 300 and 400 values in the code 35 | // there are also some 600 values 36 | // the 6502D chip coords are in the box (216,179) to (8983,9807) 37 | // we have 4 canvases all the same size, now 2000 pixels square 38 | // chip background - the layout 39 | // overlay - a red/white transparency to show logic high or low 40 | // hilite - to show the selected polygon 41 | // hitbuffer - abusing color values to return which polygon is under a point 42 | // we no longer use a scaling transform - we now scale the chip data at 43 | // the point of drawing line segments 44 | // if the canvas is any smaller than chip coordinates there will be 45 | // rounding artifacts, and at high zoom there will be anti-aliasing on edges. 46 | var grMaxZoom=12; 47 | var grChipSize=10000; 48 | var grChipOffsetX=400; 49 | var grChipOffsetY=0; 50 | var grCanvasSize=2000; 51 | var grLineWidth=1; 52 | 53 | // Index of layerNames corresponds to index into drawLayers 54 | var layernames = ['metal', 'switched diffusion', 'inputdiode', 'grounded diffusion', 'powered diffusion', 'polysilicon']; 55 | var colors = ['rgba(128,128,192,0.4)','#FFFF00','#FF00FF','#4DFF4D', 56 | '#FF4D4D','#801AC0','rgba(128,0,255,0.75)']; 57 | var drawlayers = [true, true, true, true, true, true]; 58 | 59 | ///////////////////////// 60 | // 61 | // Drawing Setup 62 | // 63 | ///////////////////////// 64 | 65 | // try to present a meaningful page before starting expensive work 66 | function setup(){ 67 | statbox = document.getElementById('status'); 68 | setStatus('loading 6502...'); 69 | setTimeout(setup_part2, 0); 70 | } 71 | 72 | function setup_part2(){ 73 | frame = document.getElementById('frame'); 74 | statbox = document.getElementById('status'); 75 | setupNodes(); 76 | setupTransistors(); 77 | setupLayerVisibility(); 78 | setupBackground(); 79 | setupOverlay(); 80 | setupHilite(); 81 | setupHitBuffer(); 82 | recenter(); 83 | refresh(); 84 | setupTable(); 85 | window.onkeypress = function(e){handleKey(e);} 86 | hilite.onmousedown = function(e){mouseDown(e);} 87 | setStatus('resetting 6502...'); 88 | setTimeout(setup_part3, 0); 89 | } 90 | 91 | function setup_part3(){ 92 | loadProgram(); 93 | writeTriggers={}; // kiosk mode does not handle I/O 94 | initChip(); 95 | document.getElementById('stop').style.visibility = 'hidden'; 96 | go(); 97 | } 98 | 99 | 100 | ///////////////////////// 101 | // 102 | // User Interface 103 | // 104 | ///////////////////////// 105 | 106 | function handleKey(e){ 107 | var c = e.charCode || e.keyCode; 108 | c = String.fromCharCode(c); 109 | if('zx<>?np'.indexOf(c)==-1) return; 110 | if((c=='x' || c=='<') && zoom>1) setZoom(zoom/1.2); 111 | else if((c=='z' || c=='>') && zoom','y:',cy); 182 | else { 183 | var s1='x: ' + cx + ' y: ' + cy; 184 | var s2='node: ' + w + ' ' + nodeName(w); 185 | setStatus(s1, s2); 186 | } 187 | } 188 | 189 | ///////////////////////// 190 | // 191 | // Etc. 192 | // 193 | ///////////////////////// 194 | 195 | function setChipStyle(props){ 196 | for(var i in props){ 197 | chipbg.style[i] = props[i]; 198 | overlay.style[i] = props[i]; 199 | hilite.style[i] = props[i]; 200 | hitbuffer.style[i] = props[i]; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /macros.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles, Achim Breidenbach 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var memory = Array(); 24 | var cycle = 0; 25 | var trace = Array(); 26 | var logstream = Array(); 27 | var running = false; 28 | var logThese=[]; 29 | var chipname='6502'; 30 | var nodenamereset='res'; 31 | var presetLogLists=[ 32 | ['cycle'], 33 | ['ab','db','rw','Fetch','pc','a','x','y','s','p'], 34 | ['Execute','State'], 35 | ['ir','tcstate','-pd'], 36 | ['adl','adh','sb','alu'], 37 | ['alucin','alua','alub','alucout','aluvout','dasb'], 38 | ['plaOutputs','DPControl'], 39 | ['idb','dor'], 40 | ['irq','nmi',nodenamereset], 41 | ]; 42 | 43 | function loadProgram(){ 44 | // a moderate size of static testprogram might be loaded 45 | if(testprogram.length!=0 && testprogramAddress != undefined) 46 | for(var i=0;testprogram[i]!=undefined;i++){ 47 | var a=testprogramAddress+i; 48 | mWrite(a, testprogram[i]); 49 | if(a<0x200) 50 | setCellValue(a, testprogram[i]); 51 | } 52 | // a small test program or patch might be passed in the URL 53 | if(userCode.length!=0) 54 | for(var i=0;i>1; 390 | if(busname=='pc') 391 | return busToHex('pch') + busToHex('pcl'); 392 | if(busname=='p') 393 | return readPstring(); 394 | if(busname=='tcstate') 395 | return ['clock1','clock2','t2','t3','t4','t5'].map(busToHex).join(""); 396 | if(busname=='State') 397 | return listActiveTCStates(); 398 | if(busname=='TState') 399 | return allTCStates( true ); 400 | if(busname=='Phi') 401 | // Pretty-printed phase indication based on the state of cp1, 402 | // the internal Phase 1 node 403 | return 'Φ' + 404 | (isNodeHigh( nodenames[ 'cp1' ] ) ? '1' : '2'); 405 | if(busname=='Execute') 406 | return disassemblytoHTML(readBits('ir',8)); 407 | if(busname=='Fetch') 408 | return isNodeHigh(nodenames['sync'])?disassemblytoHTML(readDataBus()):""; 409 | if(busname=='plaOutputs') 410 | // PLA outputs are mostly ^op- but some have a prefix too 411 | // - we'll allow the x and xx prefix but ignore the # 412 | return listActiveSignals('^([x]?x-)?op-'); 413 | if(busname=='DPControl') 414 | return listActiveSignals('^dpc[-]?[0-9]+_'); 415 | if(busname[0]=="-"){ 416 | // invert the value of the bus for display 417 | var value=busToHex(busname.slice(1)) 418 | if(typeof value != "undefined") 419 | return value.replace(/./g,function(x){return (15-parseInt(x,16)).toString(16)}); 420 | else 421 | return undefined;; 422 | } else { 423 | return busToHex(busname); 424 | } 425 | } 426 | 427 | function busToHex(busname){ 428 | // may be passed a bus or a signal, so allow multiple signals 429 | var width=0; 430 | var r=new RegExp('^' + busname + '[0-9]+$'); 431 | for(var i in nodenamelist){ 432 | if(r.test(nodenamelist[i])) { 433 | width++; 434 | } 435 | } 436 | if(width==0) { 437 | // not a bus, so could be a signal, a nodenumber or a mistake 438 | if(typeof nodenames[busname] != "undefined") 439 | return isNodeHigh(nodenames[busname])?"1":"0"; 440 | if((parseInt(busname)!=NaN) && (typeof nodes[busname] != "undefined")) 441 | return isNodeHigh(busname)?"1":"0"; 442 | return undefined; 443 | } 444 | if(width>16) 445 | return undefined; 446 | // finally, convert from logic values to hex 447 | return (0x10000+readBits(busname,width)).toString(16).slice(-(width-1)/4-1); 448 | } 449 | 450 | function writeDataBus(x){ 451 | var recalcs = Array(); 452 | for(var i=0;i<8;i++){ 453 | var nn = nodenames['db'+i]; 454 | var n = nodes[nn]; 455 | if((x%2)==0) {n.pulldown=true; n.pullup=false;} 456 | else {n.pulldown=false; n.pullup=true;} 457 | recalcs.push(nn); 458 | x>>=1; 459 | } 460 | recalcNodeList(recalcs); 461 | } 462 | 463 | function mRead(a){ 464 | if(memory[a]==undefined) return 0; 465 | else return memory[a]; 466 | } 467 | 468 | function mWrite(a, d){memory[a]=d;} 469 | 470 | function clkNodes(){ 471 | var res = Array(); 472 | res.push(943); 473 | for(var i in nodes[943].gates){ 474 | var t = nodes[943].gates[i]; 475 | if(t.c1==npwr) res.push(t.c2); 476 | if(t.c2==npwr) res.push(t.c1); 477 | } 478 | hiliteNode(res); 479 | } 480 | 481 | function runChip(){ 482 | var start = document.getElementById('start'); 483 | var stop = document.getElementById('stop'); 484 | start.style.visibility = 'hidden'; 485 | stop.style.visibility = 'visible'; 486 | if(typeof running == "undefined") 487 | initChip(); 488 | running = true; 489 | go(); 490 | } 491 | 492 | function stopChip(){ 493 | var start = document.getElementById('start'); 494 | var stop = document.getElementById('stop'); 495 | start.style.visibility = 'visible'; 496 | stop.style.visibility = 'hidden'; 497 | running = false; 498 | } 499 | 500 | function resetChip(){ 501 | stopChip(); 502 | setStatus('resetting ' + chipname + '...'); 503 | setTimeout(initChip,0); 504 | } 505 | 506 | function stepForward(){ 507 | if(typeof running == "undefined") 508 | initChip(); 509 | stopChip(); 510 | step(); 511 | } 512 | 513 | function stepBack(){ 514 | if(cycle==0) return; 515 | showState(trace[--cycle].chip); 516 | setMem(trace[cycle].mem); 517 | var clk = isNodeHigh(nodenames['clk0']); 518 | if(!clk) writeDataBus(mRead(readAddressBus())); 519 | chipStatus(); 520 | } 521 | 522 | function chipStatus(){ 523 | var ab = readAddressBus(); 524 | var machine1 = 525 | ' halfcyc:' + cycle + 526 | ' phi0:' + readBit('clk0') + 527 | ' AB:' + hexWord(ab) + 528 | ' D:' + hexByte(readDataBus()) + 529 | ' RnW:' + readBit('rw'); 530 | var machine2 = 531 | ' PC:' + hexWord(readPC()) + 532 | ' A:' + hexByte(readA()) + 533 | ' X:' + hexByte(readX()) + 534 | ' Y:' + hexByte(readY()) + 535 | ' SP:' + hexByte(readSP()) + 536 | ' ' + readPstring(); 537 | var machine3 = 538 | 'Hz: ' + estimatedHz().toFixed(1); 539 | if(typeof expertMode != "undefined") { 540 | machine3 += ' Exec: ' + busToString('Execute') + '(' + busToString('State') + ')'; 541 | if(isNodeHigh(nodenames['sync'])) 542 | machine3 += ' (Fetch: ' + busToString('Fetch') + ')'; 543 | if(goldenChecksum != undefined) 544 | machine3 += " Chk:" + traceChecksum + ((traceChecksum==goldenChecksum)?" OK":" no match"); 545 | } 546 | setStatus(machine1, machine2, machine3); 547 | if (logThese.length>1) { 548 | updateLogbox(logThese); 549 | } 550 | selectCell(ab); 551 | } 552 | 553 | // run for an extended number of cycles, with low overhead, for interactive programs or for benchmarking 554 | // note: to run an interactive program, use an URL like 555 | // http://visual6502.org/JSSim/expert.html?graphics=f&loglevel=-1&headlesssteps=-500 556 | function goFor(){ 557 | var n = headlessSteps; // a negative value is a request to free-run 558 | if(headlessSteps<0) 559 | n=-n; 560 | var start = document.getElementById('start'); 561 | var stop = document.getElementById('stop'); 562 | start.style.visibility = 'hidden'; 563 | stop.style.visibility = 'visible'; 564 | if(typeof running == "undefined") { 565 | initChip(); 566 | } 567 | running = true; 568 | setTimeout("instantaneousHz(); goForN("+n+")",0); 569 | } 570 | 571 | // helper function: allows us to poll 'running' without resetting it when we're re-scheduled 572 | function goForN(n){ 573 | var n2=n; // save our parameter so we can re-submit ourselves 574 | while(n--){ 575 | halfStep(); 576 | cycle++; 577 | } 578 | instantaneousHz(); 579 | chipStatus(); 580 | if((headlessSteps<0) && running){ 581 | setTimeout("goForN("+n2+")",0); // re-submit ourselves if we are meant to free-run 582 | return; 583 | } 584 | running = false; 585 | var start = document.getElementById('start'); 586 | var stop = document.getElementById('stop'); 587 | start.style.visibility = 'visible'; 588 | stop.style.visibility = 'hidden'; 589 | } 590 | 591 | var prevHzTimeStamp=0; 592 | var prevHzCycleCount=0; 593 | var prevHzEstimate1=1; 594 | var prevHzEstimate2=1; 595 | var HzSamplingRate=10; 596 | 597 | // return an averaged speed: called periodically during normal running 598 | function estimatedHz(){ 599 | if(cycle%HzSamplingRate!=3) 600 | return prevHzEstimate1; 601 | var HzTimeStamp = now(); 602 | var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01); 603 | HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz 604 | if(HzEstimate<5) 605 | HzSamplingRate=5; // quicker 606 | if(HzEstimate>10) 607 | HzSamplingRate=10; // smoother 608 | prevHzEstimate2=prevHzEstimate1; 609 | prevHzEstimate1=(HzEstimate+prevHzEstimate1+prevHzEstimate2)/3; // wrong way to average speeds 610 | prevHzTimeStamp=HzTimeStamp; 611 | prevHzCycleCount=cycle; 612 | return prevHzEstimate1 613 | } 614 | 615 | // return instantaneous speed: called twice, before and after a timed run using goFor() 616 | function instantaneousHz(){ 617 | var HzTimeStamp = now(); 618 | var HzEstimate = (cycle-prevHzCycleCount+.01)/(HzTimeStamp-prevHzTimeStamp+.01); 619 | HzEstimate=HzEstimate*1000/2; // convert from phases per millisecond to Hz 620 | prevHzEstimate1=HzEstimate; 621 | prevHzEstimate2=prevHzEstimate1; 622 | prevHzTimeStamp=HzTimeStamp; 623 | prevHzCycleCount=cycle; 624 | return prevHzEstimate1 625 | } 626 | 627 | var logbox; 628 | function initLogbox(names){ 629 | logbox=document.getElementById('logstream'); 630 | if(logbox==null)return; 631 | 632 | names=names.map(function(x){return x.replace(/^-/,'')}); 633 | logStream = []; 634 | logStream.push("" + names.join("") + ""); 635 | logbox.innerHTML = ""+logStream.join("")+""; 636 | } 637 | 638 | var logboxAppend=true; 639 | 640 | // can append or prepend new states to the log table 641 | // when we reverse direction we need to reorder the log stream 642 | function updateLogDirection(){ 643 | var loglines=[]; 644 | logboxAppend=!logboxAppend; 645 | // the first element is the header so we can't reverse() 646 | for (var i=1;i")+""; 652 | } 653 | 654 | // update the table of signal values, by prepending or appending 655 | function updateLogbox(names){ 656 | var signals=[]; 657 | var odd=true; 658 | var bg; 659 | var row; 660 | 661 | for(var i in names){ 662 | if(cycle % 4 < 2){ 663 | bg = odd ? " class=oddcol":""; 664 | } else { 665 | bg = odd ? " class=oddrow":" class=oddrowcol"; 666 | } 667 | signals.push("" + busToString(names[i]) + ""); 668 | odd =! odd; 669 | } 670 | row = "" + signals.join("") + ""; 671 | if(logboxAppend) 672 | logStream.push(row); 673 | else 674 | logStream.splice(1,0,row); 675 | 676 | logbox.innerHTML = logStream.join(""); 677 | } 678 | 679 | function getMem(){ 680 | var res = Array(); 681 | for(var i=0;i<0x200;i++) res.push(mRead(i)); 682 | return res; 683 | } 684 | 685 | function setMem(arr){ 686 | for(var i=0;i<0x200;i++){mWrite(i, arr[i]); setCellValue(i, arr[i]);} 687 | } 688 | 689 | function hexWord(n){return (0x10000+n).toString(16).substring(1)} 690 | function hexByte(n){return (0x100+n).toString(16).substring(1)} 691 | 692 | function adler32(x){ 693 | var a=1; 694 | var b=0; 695 | for(var i=0;i=48)&&(c<58)) setCellValue(selected, getCellValue(selected)*16+c-48); 57 | else if((c>=65)&&(c<71)) setCellValue(selected, getCellValue(selected)*16+c-55); 58 | mWrite(selected, getCellValue(selected)); 59 | } 60 | 61 | function setCellValue(n, val){ 62 | if(val==undefined) 63 | val=0x00; 64 | val%=256; 65 | cellEl(n).val=val; 66 | cellEl(n).innerHTML=hexByte(val); 67 | } 68 | 69 | function getCellValue(n){return cellEl(n).val;} 70 | 71 | function selectCell(n){ 72 | unselectCell(); 73 | if(n>=0x200) return; 74 | cellEl(n).style.background = '#ff8'; 75 | selected = n; 76 | table.onkeydown = function(e){cellKeydown(e);}; 77 | } 78 | 79 | function unselectCell(){ 80 | if(selected==undefined) return; 81 | cellEl(selected).style.background = '#fff'; 82 | selected = undefined; 83 | window.onkeydown = undefined; 84 | } 85 | 86 | function cellEl(n){ 87 | var r = n>>4; 88 | var c = n%16; 89 | var e = table.childNodes[r].childNodes[c+1]; 90 | return e; 91 | } 92 | -------------------------------------------------------------------------------- /nodenames.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman, Ed Spittles, Segher Boessenkool 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var nodenames ={ 24 | res: 159, // pads: reset 25 | rw: 1156, // pads: read not write 26 | db0: 1005, // pads: databus 27 | db1: 82, 28 | db3: 650, 29 | db2: 945, 30 | db5: 175, 31 | db4: 1393, 32 | db7: 1349, 33 | db6: 1591, 34 | ab0: 268, // pads: address bus 35 | ab1: 451, 36 | ab2: 1340, 37 | ab3: 211, 38 | ab4: 435, 39 | ab5: 736, 40 | ab6: 887, 41 | ab7: 1493, 42 | ab8: 230, 43 | ab9: 148, 44 | ab12: 1237, 45 | ab13: 349, 46 | ab10: 1443, 47 | ab11: 399, 48 | ab14: 672, 49 | ab15: 195, 50 | sync: 539, // pads 51 | so: 1672, // pads: set overflow 52 | clk0: 1171, // pads 53 | clk1out: 1163, // pads 54 | clk2out: 421, // pads 55 | rdy: 89, // pads: ready 56 | nmi: 1297, // pads: non maskable interrupt 57 | irq: 103, // pads 58 | vcc: 657, // pads 59 | vss: 558, // pads 60 | 61 | a0: 737, // machine state: accumulator 62 | a1: 1234, 63 | a2: 978, 64 | a3: 162, 65 | a4: 727, 66 | a5: 858, 67 | a6: 1136, 68 | a7: 1653, 69 | y0: 64, // machine state: y index register 70 | y1: 1148, 71 | y2: 573, 72 | y3: 305, 73 | y4: 989, 74 | y5: 615, 75 | y6: 115, 76 | y7: 843, 77 | x0: 1216, // machine state: x index register 78 | x1: 98, 79 | x2: 1, 80 | x3: 1648, 81 | x4: 85, 82 | x5: 589, 83 | x6: 448, 84 | x7: 777, 85 | pcl0: 1139, // machine state: program counter low (first storage node output) 86 | pcl1: 1022, 87 | pcl2: 655, 88 | pcl3: 1359, 89 | pcl4: 900, 90 | pcl5: 622, 91 | pcl6: 377, 92 | pcl7: 1611, 93 | pclp0: 488, // machine state: program counter low (pre-incremented?, second storage node) 94 | pclp1: 976, 95 | pclp2: 481, 96 | pclp3: 723, 97 | pclp4: 208, 98 | pclp5: 72, 99 | pclp6: 1458, 100 | pclp7: 1647, 101 | "#pclp0": 1227, // machine state: program counter low (pre-incremented?, inverse second storage node) 102 | "~pclp0": 1227, // automatic alias replacing hash with tilde 103 | "#pclp1": 1102, 104 | "~pclp1": 1102, // automatic alias replacing hash with tilde 105 | "#pclp2": 1079, 106 | "~pclp2": 1079, // automatic alias replacing hash with tilde 107 | "#pclp3": 868, 108 | "~pclp3": 868, // automatic alias replacing hash with tilde 109 | "#pclp4": 39, 110 | "~pclp4": 39, // automatic alias replacing hash with tilde 111 | "#pclp5": 1326, 112 | "~pclp5": 1326, // automatic alias replacing hash with tilde 113 | "#pclp6": 731, 114 | "~pclp6": 731, // automatic alias replacing hash with tilde 115 | "#pclp7": 536, 116 | "~pclp7": 536, // automatic alias replacing hash with tilde 117 | pch0: 1670, // machine state: program counter high (first storage node) 118 | pch1: 292, 119 | pch2: 502, 120 | pch3: 584, 121 | pch4: 948, 122 | pch5: 49, 123 | pch6: 1551, 124 | pch7: 205, 125 | pchp0: 1722, // machine state: program counter high (pre-incremented?, second storage node output) 126 | pchp1: 209, 127 | pchp2: 1496, 128 | pchp3: 141, 129 | pchp4: 27, 130 | pchp5: 1301, 131 | pchp6: 652, 132 | pchp7: 1206, 133 | "#pchp0": 780, // machine state: program counter high (pre-incremented?, inverse second storage node) 134 | "~pchp0": 780, // automatic alias replacing hash with tilde 135 | "#pchp1": 113, 136 | "~pchp1": 113, // automatic alias replacing hash with tilde 137 | "#pchp2": 114, 138 | "~pchp2": 114, // automatic alias replacing hash with tilde 139 | "#pchp3": 124, 140 | "~pchp3": 124, // automatic alias replacing hash with tilde 141 | "#pchp4": 820, 142 | "~pchp4": 820, // automatic alias replacing hash with tilde 143 | "#pchp5": 33, 144 | "~pchp5": 33, // automatic alias replacing hash with tilde 145 | "#pchp6": 751, 146 | "~pchp6": 751, // automatic alias replacing hash with tilde 147 | "#pchp7": 535, 148 | "~pchp7": 535, // automatic alias replacing hash with tilde 149 | // machine state: status register (not the storage nodes) 150 | p0: 32, // C bit of status register (storage node) 151 | p1: 627, // Z bit of status register (storage node) 152 | p2: 1553, // I bit of status register (storage node) 153 | p3: 348, // D bit of status register (storage node) 154 | p4: 1119, // there is no bit4 in the status register! (not a storage node) 155 | p5: -1, // there is no bit5 in the status register! (not a storage node) 156 | p6: 1625, // V bit of status register (storage node) 157 | p7: 69, // N bit of status register (storage node) 158 | 159 | // internal bus: status register outputs for push P 160 | Pout0: 687, 161 | Pout1: 1444, 162 | Pout2: 1421, 163 | Pout3: 439, 164 | Pout4: 1119, // there is no bit4 in the status register! 165 | Pout5: -1, // there is no bit5 in the status register! 166 | Pout6: 77, 167 | Pout7: 1370, 168 | 169 | s0: 1403, // machine state: stack pointer 170 | s1: 183, 171 | s2: 81, 172 | s3: 1532, 173 | s4: 1702, 174 | s5: 1098, 175 | s6: 1212, 176 | s7: 1435, 177 | ir0: 328, // internal state: instruction register 178 | ir1: 1626, 179 | ir2: 1384, 180 | ir3: 1576, 181 | ir4: 1112, 182 | ir5: 1329, // ir5 distinguishes branch set from branch clear 183 | ir6: 337, 184 | ir7: 1328, 185 | notir0: 194, // internal signal: instruction register inverted outputs 186 | notir1: 702, 187 | notir2: 1182, 188 | notir3: 1125, 189 | notir4: 26, 190 | notir5: 1394, 191 | notir6: 895, 192 | notir7: 1320, 193 | irline3: 996, // internal signal: PLA input - ir0 OR ir1 194 | clock1: 1536, // internal state: timing control aka #T0 195 | clock1: 1536, // automatic alias replacing hash with tilde 196 | clock2: 156, // internal state: timing control aka #T+ 197 | clock2: 156, // automatic alias replacing hash with tilde 198 | t2: 971, // internal state: timing control 199 | t3: 1567, 200 | t4: 690, 201 | t5: 909, 202 | noty0: 1025, // datapath state: not Y register 203 | noty1: 1138, 204 | noty2: 1484, 205 | noty3: 184, 206 | noty4: 565, 207 | noty5: 981, 208 | noty6: 1439, 209 | noty7: 1640, 210 | notx0: 987, // datapath state: not X register 211 | notx1: 1434, 212 | notx2: 890, 213 | notx3: 1521, 214 | notx4: 485, 215 | notx5: 1017, 216 | notx6: 730, 217 | notx7: 1561, 218 | nots0: 418, // datapath state: not stack pointer 219 | nots1: 1064, 220 | nots2: 752, 221 | nots3: 828, 222 | nots4: 1603, 223 | nots5: 601, 224 | nots6: 1029, 225 | nots7: 181, 226 | notidl0: 116, // datapath state: internal data latch (first storage node) 227 | notidl1: 576, 228 | notidl2: 1485, 229 | notidl3: 1284, 230 | notidl4: 1516, 231 | notidl5: 498, 232 | notidl6: 1537, 233 | notidl7: 529, 234 | idl0: 1597, // datapath signal: internal data latch (driven output) 235 | idl1: 870, 236 | idl2: 1066, 237 | idl3: 464, 238 | idl4: 1306, 239 | idl5: 240, 240 | idl6: 1116, 241 | idl7: 391, 242 | sb0: 54, // datapath bus: special bus 243 | sb1: 1150, 244 | sb2: 1287, 245 | sb3: 1188, 246 | sb4: 1405, 247 | sb5: 166, 248 | sb6: 1336, 249 | sb7: 1001, 250 | notalu0: 394, // datapath state: alu output storage node (inverse) aka #ADD0 251 | notalu0: 394, // automatic alias replacing hash with tilde 252 | notalu1: 697, 253 | notalu2: 276, 254 | notalu3: 495, 255 | notalu4: 1490, 256 | notalu5: 893, 257 | notalu6: 68, 258 | notalu7: 1123, 259 | alu0: 401, // datapath signal: ALU output aka ADD0out 260 | alu1: 872, 261 | alu2: 1637, 262 | alu3: 1414, 263 | alu4: 606, 264 | alu5: 314, 265 | alu6: 331, 266 | alu7: 765, 267 | // datapath signal: decimally adjusted special bus 268 | dasb0: 54, // same node as sb0 269 | dasb1: 1009, 270 | dasb2: 450, 271 | dasb3: 1475, 272 | dasb4: 1405, // same node as sb4 273 | dasb5: 263, 274 | dasb6: 679, 275 | dasb7: 1494, 276 | adl0: 413, // internal bus: address low 277 | adl1: 1282, 278 | adl2: 1242, 279 | adl3: 684, 280 | adl4: 1437, 281 | adl5: 1630, 282 | adl6: 121, 283 | adl7: 1299, 284 | adh0: 407, // internal bus: address high 285 | adh1: 52, 286 | adh2: 1651, 287 | adh3: 315, 288 | adh4: 1160, 289 | adh5: 483, 290 | adh6: 13, 291 | adh7: 1539, 292 | idb0: 1108, // internal bus: data bus 293 | idb1: 991, 294 | idb2: 1473, 295 | idb3: 1302, 296 | idb4: 892, 297 | idb5: 1503, 298 | idb6: 833, 299 | idb7: 493, 300 | notdor0: 222, // internal state: data output register (storage node) 301 | notdor1: 527, 302 | notdor2: 1288, 303 | notdor3: 823, 304 | notdor4: 873, 305 | notdor5: 1266, 306 | notdor6: 1418, 307 | notdor7: 158, 308 | dor0: 97, // internal signal: data output register 309 | dor1: 746, 310 | dor2: 1634, 311 | dor3: 444, 312 | dor4: 1088, 313 | dor5: 1453, 314 | dor6: 1415, 315 | dor7: 63, 316 | "pd0.clearIR": 1622, // internal state: predecode register output (anded with not ClearIR) 317 | "pd1.clearIR": 809, 318 | "pd2.clearIR": 1671, 319 | "pd3.clearIR": 1587, 320 | "pd4.clearIR": 540, 321 | "pd5.clearIR": 667, 322 | "pd6.clearIR": 1460, 323 | "pd7.clearIR": 1410, 324 | pd0: 758, // internal state: predecode register (storage node) 325 | pd1: 361, 326 | pd2: 955, 327 | pd3: 894, 328 | pd4: 369, 329 | pd5: 829, 330 | pd6: 1669, 331 | pd7: 1690, 332 | // internal signals: predecode latch partial decodes 333 | "PD-xxxx10x0": 1019, 334 | "PD-1xx000x0": 1294, 335 | "PD-0xx0xx0x": 365, 336 | "PD-xxx010x1": 302, 337 | "PD-n-0xx0xx0x": 125, 338 | "#TWOCYCLE": 851, 339 | "~TWOCYCLE": 851, // automatic alias replacing hash with tilde 340 | "#TWOCYCLE.phi1": 792, 341 | "~TWOCYCLE.phi1": 792, // automatic alias replacing hash with tilde 342 | "ONEBYTE": 778, 343 | 344 | abl0: 1096, // internal bus: address bus low latched data out (inverse of inverted storage node) 345 | abl1: 376, 346 | abl2: 1502, 347 | abl3: 1250, 348 | abl4: 1232, 349 | abl5: 234, 350 | abl6: 178, 351 | abl7: 567, 352 | "#ABL0": 153, // internal state: address bus low latched data out (storage node, inverted) 353 | "~ABL0": 153, // automatic alias replacing hash with tilde 354 | "#ABL1": 107, 355 | "~ABL1": 107, // automatic alias replacing hash with tilde 356 | "#ABL2": 707, 357 | "~ABL2": 707, // automatic alias replacing hash with tilde 358 | "#ABL3": 825, 359 | "~ABL3": 825, // automatic alias replacing hash with tilde 360 | "#ABL4": 364, 361 | "~ABL4": 364, // automatic alias replacing hash with tilde 362 | "#ABL5": 1513, 363 | "~ABL5": 1513, // automatic alias replacing hash with tilde 364 | "#ABL6": 1307, 365 | "~ABL6": 1307, // automatic alias replacing hash with tilde 366 | "#ABL7": 28, 367 | "~ABL7": 28, // automatic alias replacing hash with tilde 368 | abh0: 1429, // internal bus: address bus high latched data out (inverse of inverted storage node) 369 | abh1: 713, 370 | abh2: 287, 371 | abh3: 422, 372 | abh4: 1143, 373 | abh5: 775, 374 | abh6: 997, 375 | abh7: 489, 376 | "#ABH0": 1062, // internal state: address bus high latched data out (storage node, inverted) 377 | "~ABH0": 1062, // automatic alias replacing hash with tilde 378 | "#ABH1": 907, 379 | "~ABH1": 907, // automatic alias replacing hash with tilde 380 | "#ABH2": 768, 381 | "~ABH2": 768, // automatic alias replacing hash with tilde 382 | "#ABH3": 92, 383 | "~ABH3": 92, // automatic alias replacing hash with tilde 384 | "#ABH4": 668, 385 | "~ABH4": 668, // automatic alias replacing hash with tilde 386 | "#ABH5": 1128, 387 | "~ABH5": 1128, // automatic alias replacing hash with tilde 388 | "#ABH6": 289, 389 | "~ABH6": 289, // automatic alias replacing hash with tilde 390 | "#ABH7": 429, 391 | "~ABH7": 429, // automatic alias replacing hash with tilde 392 | 393 | "branch-back": 626, // distinguish forward from backward branches 394 | "branch-forward.phi1": 1110, // distinguish forward from backward branches 395 | "branch-back.phi1": 771, // distinguish forward from backward branches in IPC logic 396 | notRdy0: 248, // internal signal: global pipeline control 397 | "notRdy0.phi1": 1272, // delayed pipeline control 398 | "notRdy0.delay": 770, // global pipeline control latched by phi1 and then phi2 399 | "#notRdy0.delay": 559, // global pipeline control latched by phi1 and then phi2 (storage node) 400 | "~notRdy0.delay": 559, // automatic alias replacing hash with tilde 401 | Reset0: 67, // internal signal: retimed reset from pin 402 | C1x5Reset: 926, // retimed and pipelined reset in progress 403 | notRnWprepad: 187, // internal signal: to pad, yet to be inverted and retimed 404 | RnWstretched: 353, // internal signal: control datapad output drivers, aka TRISTATE 405 | "#DBE": 1035, // internal signal: formerly from DBE pad (6501) 406 | "~DBE": 1035, // automatic alias replacing hash with tilde 407 | cp1: 710, // internal signal: clock phase 1 408 | cclk: 943, // unbonded pad: internal non-overlapping phi2 409 | fetch: 879, // internal signal 410 | clearIR: 1077, // internal signal 411 | H1x1: 1042, // internal signal: drive status byte onto databus 412 | 413 | // internal signal: pla outputs block 1 (west/left edge of die) 414 | // often 130 pla outputs are mentioned - we have 131 here 415 | "op-sty/cpy-mem": 1601, // pla0 416 | "op-T3-ind-y": 60, // pla1 417 | "op-T2-abs-y": 1512, // pla2 418 | "op-T0-iny/dey": 382, // pla3 419 | "x-op-T0-tya": 1173, // pla4 420 | "op-T0-cpy/iny": 1233, // pla5 421 | 422 | // internal signal: pla outputs block 2 423 | "op-T2-idx-x-xy": 258, // pla6 424 | "op-xy": 1562, // pla7 425 | "op-T2-ind-x": 84, // pla8 426 | "x-op-T0-txa": 1543, // pla9 427 | "op-T0-dex": 76, // pla10 428 | "op-T0-cpx/inx": 1658, // pla11 429 | "op-from-x": 1540, // pla12 430 | "op-T0-txs": 245, // pla13 431 | "op-T0-ldx/tax/tsx": 985, // pla14 432 | "op-T+-dex": 786, // pla15 433 | "op-T+-inx": 1664, // pla16 434 | "op-T0-tsx": 682, // pla17 435 | "op-T+-iny/dey": 1482, // pla18 436 | "op-T0-ldy-mem": 665, // pla19 437 | "op-T0-tay/ldy-not-idx": 286, // pla20 438 | 439 | // internal signal: pla outputs block 3 440 | // not pla, feed through 441 | "op-T0-jsr": 271, // pla21 442 | "op-T5-brk": 370, // pla22 443 | "op-T0-php/pha": 552, // pla23 444 | "op-T4-rts": 1612, // pla24 445 | "op-T3-plp/pla": 1487, // pla25 446 | "op-T5-rti": 784, // pla26 447 | "op-ror": 244, // pla27 448 | "op-T2": 788, // pla28 449 | "op-T0-eor": 1623, // pla29 450 | "op-jmp": 764, // pla30 451 | "op-T2-abs": 1057, // pla31 452 | "op-T0-ora": 403, // pla32 453 | "op-T2-ADL/ADD":204, // pla33 454 | "op-T0":1273, // pla34 455 | "op-T2-stack":1582, // pla35 456 | "op-T3-stack/bit/jmp":1031, // pla36 457 | 458 | // internal signal: pla outputs block 4 459 | "op-T4-brk/jsr":804, // pla37 460 | "op-T4-rti":1311, // pla38 461 | "op-T3-ind-x":1428, // pla39 462 | "op-T4-ind-y":492, // pla40 463 | "op-T2-ind-y":1204, // pla41 464 | "op-T3-abs-idx":58, // pla42 465 | "op-plp/pla":1520, // pla43 466 | "op-inc/nop":324, // pla44 467 | "op-T4-ind-x":1259, // pla45 468 | "x-op-T3-ind-y":342, // pla46 469 | "op-rti/rts":857, // pla47 470 | "op-T2-jsr":712, // pla48 471 | "op-T0-cpx/cpy/inx/iny":1337, // pla49 472 | "op-T0-cmp":1355, // pla50 473 | "op-T0-sbc":787, // pla51 // 52:111XXXXX 1 0 T0SBC 474 | "op-T0-adc/sbc":575, // pla52 // 51:X11XXXXX 1 0 T0ADCSBC 475 | "op-rol/ror":1466, // pla53 476 | 477 | // internal signal: pla outputs block 5 478 | "op-T3-jmp":1381, // pla54 479 | "op-shift":546, // pla55 480 | "op-T5-jsr":776, // pla56 481 | "op-T2-stack-access":157, // pla57 482 | "op-T0-tya":257, // pla58 483 | "op-T+-ora/and/eor/adc":1243, // pla59 484 | "op-T+-adc/sbc":822, // pla60 485 | "op-T+-shift-a":1324, // pla61 486 | "op-T0-txa":179, // pla62 487 | "op-T0-pla":131, // pla63 488 | "op-T0-lda":1420, // pla64 489 | "op-T0-acc":1342, // pla65 490 | "op-T0-tay":4, // pla66 491 | "op-T0-shift-a":1396, // pla67 492 | "op-T0-tax":167, // pla68 493 | "op-T0-bit":303, // pla69 494 | "op-T0-and":1504, // pla70 495 | "op-T4-abs-idx":354, // pla71 496 | "op-T5-ind-y":1168, // pla72 497 | 498 | // internal signal: pla outputs block 6 499 | "op-branch-done":1721, // pla73 // has extra non-pla input 500 | "op-T2-pha":1086, // pla74 501 | "op-T0-shift-right-a":1074, // pla75 502 | "op-shift-right":1246, // pla76 503 | "op-T2-brk":487, // pla77 504 | "op-T3-jsr":579, // pla78 505 | "op-sta/cmp":145, // pla79 506 | "op-T2-branch":1239, // pla80 // T2BR, 83 for Balazs 507 | "op-T2-zp/zp-idx":285, // pla81 508 | // not pla, feed through 509 | // not pla, feed through 510 | "op-T2-ind":1524, // pla82 511 | "op-T2-abs-access":273, // pla83 // has extra pulldown: pla97 512 | "op-T5-rts":0, // pla84 513 | "op-T4":341, // pla85 514 | "op-T3":120, // pla86 515 | "op-T0-brk/rti":1478, // pla87 516 | "op-T0-jmp":594, // pla88 517 | "op-T5-ind-x":1210, // pla89 518 | "op-T3-abs/idx/ind":677, // pla90 // has extra pulldown: pla97 519 | 520 | // internal signal: pla outputs block 7 521 | "x-op-T4-ind-y":461, // pla91 522 | "x-op-T3-abs-idx":447, // pla92 523 | "op-T3-branch":660, // pla93 524 | "op-brk/rti":1557, // pla94 525 | "op-jsr":259, // pla95 526 | "x-op-jmp":1052, // pla96 527 | // gap 528 | "op-push/pull":791, // pla97 // feeds into pla83 and pla90 (no normal pla output) 529 | "op-store":517, // pla98 530 | "op-T4-brk":352, // pla99 531 | "op-T2-php":750, // pla100 532 | "op-T2-php/pha":932, // pla101 533 | "op-T4-jmp":1589, // pla102 534 | // gap 535 | "op-T5-rti/rts":446, // pla103 536 | "xx-op-T5-jsr":528, // pla104 537 | 538 | // internal signal: pla outputs block 8 539 | "op-T2-jmp-abs":309, // pla105 540 | "x-op-T3-plp/pla":1430, // pla106 541 | "op-lsr/ror/dec/inc":53, // pla107 542 | "op-asl/rol":691, // pla108 543 | "op-T0-cli/sei":1292, // pla109 544 | // gap 545 | "op-T+-bit":1646, // pla110 546 | "op-T0-clc/sec":1114, // pla111 547 | "op-T3-mem-zp-idx":904, // pla112 548 | "x-op-T+-adc/sbc":1155, // pla113 549 | "x-op-T0-bit":1476, // pla114 550 | "op-T0-plp":1226, // pla115 551 | "x-op-T4-rti":1569, // pla116 552 | "op-T+-cmp":301, // pla117 553 | "op-T+-cpx/cpy-abs":950, // pla118 554 | "op-T+-asl/rol-a":1665, // pla119 555 | 556 | // internal signal: pla outputs block 9 557 | "op-T+-cpx/cpy-imm/zp":1710, // pla120 558 | "x-op-push/pull":1050, // pla121 // feeds into pla130 (no normal pla output) 559 | "op-T0-cld/sed":1419, // pla122 560 | "#op-branch-bit6":840, // pla123 // IR bit6 used only to detect branch type 561 | "~op-branch-bit6":840, // automatic alias replacing hash with tilde 562 | "op-T3-mem-abs":607, // pla124 563 | "op-T2-mem-zp":219, // pla125 564 | "op-T5-mem-ind-idx":1385, // pla126 565 | "op-T4-mem-abs-idx":281, // pla127 566 | "#op-branch-bit7":1174, // pla128 // IR bit7 used only to detect branch type 567 | "~op-branch-bit7":1174, // automatic alias replacing hash with tilde 568 | "op-clv":1164, // pla129 569 | "op-implied":1006, // pla130 // has extra pulldowns: pla121 and ir0 570 | 571 | // internal signals: derived from pla outputs 572 | "#op-branch-done": 1048, 573 | "~op-branch-done": 1048, // automatic alias replacing hash with tilde 574 | "#op-T3-branch": 1708, 575 | "~op-T3-branch": 1708, // automatic alias replacing hash with tilde 576 | "op-ANDS": 1228, 577 | "op-EORS": 1689, 578 | "op-ORS": 522, 579 | "op-SUMS": 1196, 580 | "op-SRS": 934, 581 | "#op-store": 925, 582 | "~op-store": 925, // automatic alias replacing hash with tilde 583 | "#WR": 1352, 584 | "~WR": 1352, // automatic alias replacing hash with tilde 585 | "op-rmw": 434, 586 | "short-circuit-idx-add": 1185, 587 | "short-circuit-branch-add": 430, 588 | "#op-set-C": 252, 589 | "~op-set-C": 252, // automatic alias replacing hash with tilde 590 | 591 | // internal signals: control signals 592 | nnT2BR: 967, // doubly inverted 593 | "#BRtaken": 1544, // aka #TAKEN 594 | "~BRtaken": 1544, // automatic alias replacing hash with tilde 595 | 596 | // internal signals and state: interrupt and vector related 597 | // segher says: 598 | // "P" are the latched external signals. 599 | // "G" are the signals that actually trigger the interrupt. 600 | // "NMIL" is to do the edge detection -- it's pretty much just a delayed NMIG. 601 | // INTG is IRQ and NMI taken together. 602 | IRQP: 675, 603 | "#IRQP": 888, 604 | "~IRQP": 888, // automatic alias replacing hash with tilde 605 | NMIP: 1032, 606 | "#NMIP": 297, 607 | "~NMIP": 297, // automatic alias replacing hash with tilde 608 | "#NMIG": 264, 609 | "~NMIG": 264, // automatic alias replacing hash with tilde 610 | NMIL: 1374, 611 | RESP: 67, 612 | RESG: 926, 613 | VEC0: 1465, 614 | VEC1: 1481, 615 | "#VEC": 1134, 616 | "~VEC": 1134, // automatic alias replacing hash with tilde 617 | D1x1: 827, // internal signal: interrupt handler related 618 | "brk-done": 1382, // internal signal: interrupt handler related 619 | INTG: 1350, // internal signal: interrupt handler related 620 | 621 | // internal state: misc pipeline state clocked by cclk (phi2) 622 | "pipe#VEC": 1431, // latched #VEC 623 | "pipe~VEC": 1431, // automatic alias replacing hash with tilde 624 | "pipeT-SYNC": 537, 625 | pipeT2out: 40, 626 | pipeT3out: 706, 627 | pipeT4out: 1373, 628 | pipeT5out: 940, 629 | pipeIPCrelated: 832, 630 | pipeUNK01: 1530, 631 | pipeUNK02: 974, 632 | pipeUNK03: 1436, 633 | pipeUNK04: 99, 634 | pipeUNK05: 44, 635 | pipeUNK06: 443, 636 | pipeUNK07: 215, 637 | pipeUNK08: 338, 638 | pipeUNK09: 199, 639 | pipeUNK10: 215, 640 | pipeUNK11: 1011, 641 | pipeUNK12: 1283, 642 | pipeUNK13: 1442, 643 | pipeUNK14: 1607, 644 | pipeUNK15: 1577, // inverse of H1x1, write P onto idb (PHP, interrupt) 645 | pipeUNK16: 1051, 646 | pipeUNK17: 1078, 647 | pipeUNK18: 899, 648 | pipeUNK19: 832, 649 | pipeUNK20: 294, 650 | pipeUNK21: 1176, 651 | pipeUNK22: 561, // becomes dpc22 652 | pipeUNK23: 596, 653 | pipephi2Reset0: 449, 654 | pipephi2Reset0x: 1036, // a second copy of the same latch 655 | pipeUNK26: 1321, 656 | pipeUNK27: 73, 657 | pipeUNK28: 685, 658 | pipeUNK29: 1008, 659 | pipeUNK30: 1652, 660 | pipeUNK31: 614, 661 | pipeUNK32: 960, 662 | pipeUNK33: 848, 663 | pipeUNK34: 56, 664 | pipeUNK35: 1713, 665 | pipeUNK36: 729, 666 | pipeUNK37: 197, 667 | "pipe#WR.phi2": 1131, 668 | "pipe~WR.phi2": 1131, // automatic alias replacing hash with tilde 669 | pipeUNK39: 151, 670 | pipeUNK40: 456, 671 | pipeUNK41: 1438, 672 | pipeUNK42: 1104, 673 | "pipe#T0": 554, // aka #T0.phi2 674 | "pipe~T0": 554, // automatic alias replacing hash with tilde 675 | 676 | // internal state: vector address pulldown control 677 | pipeVectorA0: 357, 678 | pipeVectorA1: 170, 679 | pipeVectorA2: 45, 680 | 681 | // internal signals: vector address pulldown control 682 | "0/ADL0": 217, 683 | "0/ADL1": 686, 684 | "0/ADL2": 1193, 685 | 686 | // internal state: datapath control drivers 687 | pipedpc28: 683, 688 | 689 | // internal signals: alu internal (private) busses 690 | alua0: 1167, 691 | alua1: 1248, 692 | alua2: 1332, 693 | alua3: 1680, 694 | alua4: 1142, 695 | alua5: 530, 696 | alua6: 1627, 697 | alua7: 1522, 698 | alub0: 977, 699 | alub1: 1432, 700 | alub2: 704, 701 | alub3: 96, 702 | alub4: 1645, 703 | alub5: 1678, 704 | alub6: 235, 705 | alub7: 1535, 706 | 707 | // alu carry chain and decimal mode 708 | C01: 1285, 709 | C12: 505, 710 | C23: 1023, 711 | C34: 78, 712 | C45: 142, 713 | C56: 500, 714 | C67: 1314, 715 | C78: 808, 716 | "C78.phi2": 560, 717 | DC34: 1372, // lower nibble decimal carry 718 | DC78: 333, // carry for decimal mode 719 | "DC78.phi2": 164, 720 | "#C01": 1506, 721 | "~C01": 1506, // automatic alias replacing hash with tilde 722 | "#C12": 1122, 723 | "~C12": 1122, // automatic alias replacing hash with tilde 724 | "#C23": 1003, 725 | "~C23": 1003, // automatic alias replacing hash with tilde 726 | "#C34": 1425, 727 | "~C34": 1425, // automatic alias replacing hash with tilde 728 | "#C45": 1571, 729 | "~C45": 1571, // automatic alias replacing hash with tilde 730 | "#C56": 427, 731 | "~C56": 427, // automatic alias replacing hash with tilde 732 | "#C67": 592, 733 | "~C67": 592, // automatic alias replacing hash with tilde 734 | "#C78": 1327, 735 | "~C78": 1327, // automatic alias replacing hash with tilde 736 | "DA-C01": 623, 737 | "DA-AB2": 216, 738 | "DA-AxB2": 516, 739 | "DA-C45": 1144, 740 | "#DA-ADD1": 901, 741 | "~DA-ADD1": 901, // automatic alias replacing hash with tilde 742 | "#DA-ADD2": 699, 743 | "~DA-ADD2": 699, // automatic alias replacing hash with tilde 744 | 745 | // misc alu internals 746 | "#(AxBxC)0": 371, 747 | "~(AxBxC)0": 371, // automatic alias replacing hash with tilde 748 | "#(AxBxC)1": 965, 749 | "~(AxBxC)1": 965, // automatic alias replacing hash with tilde 750 | "#(AxBxC)2": 22, 751 | "~(AxBxC)2": 22, // automatic alias replacing hash with tilde 752 | "#(AxBxC)3": 274, 753 | "~(AxBxC)3": 274, // automatic alias replacing hash with tilde 754 | "#(AxBxC)4": 651, 755 | "~(AxBxC)4": 651, // automatic alias replacing hash with tilde 756 | "#(AxBxC)5": 486, 757 | "~(AxBxC)5": 486, // automatic alias replacing hash with tilde 758 | "#(AxBxC)6": 1197, 759 | "~(AxBxC)6": 1197, // automatic alias replacing hash with tilde 760 | "#(AxBxC)7": 532, 761 | "~(AxBxC)7": 532, // automatic alias replacing hash with tilde 762 | AxB1: 425, 763 | AxB3: 640, 764 | AxB5: 1220, 765 | AxB7: 1241, 766 | "#(AxB)0": 1525, 767 | "~(AxB)0": 1525, // automatic alias replacing hash with tilde 768 | "#(AxB)2": 701, 769 | "~(AxB)2": 701, // automatic alias replacing hash with tilde 770 | "#(AxB)4": 308, 771 | "~(AxB)4": 308, // automatic alias replacing hash with tilde 772 | "#(AxB)6": 1459, 773 | "~(AxB)6": 1459, // automatic alias replacing hash with tilde 774 | "(AxB)0.#C0in": 555, 775 | "(AxB)0.~C0in": 555, // automatic alias replacing hash with tilde 776 | "(AxB)2.#C12": 193, 777 | "(AxB)2.~C12": 193, // automatic alias replacing hash with tilde 778 | "(AxB)4.#C34": 65, 779 | "(AxB)4.~C34": 65, // automatic alias replacing hash with tilde 780 | "(AxB)6.#C56": 174, 781 | "(AxB)6.~C56": 174, // automatic alias replacing hash with tilde 782 | "#(AxB1).C01": 295, 783 | "~(AxB1).C01": 295, // automatic alias replacing hash with tilde 784 | "#(AxB3).C23": 860, 785 | "~(AxB3).C23": 860, // automatic alias replacing hash with tilde 786 | "#(AxB5).C45": 817, 787 | "~(AxB5).C45": 817, // automatic alias replacing hash with tilde 788 | "#(AxB7).C67": 1217, 789 | "~(AxB7).C67": 1217, // automatic alias replacing hash with tilde 790 | "#A.B0": 1628, 791 | "~A.B0": 1628, // automatic alias replacing hash with tilde 792 | "#A.B1": 841, 793 | "~A.B1": 841, // automatic alias replacing hash with tilde 794 | "#A.B2": 681, 795 | "~A.B2": 681, // automatic alias replacing hash with tilde 796 | "#A.B3": 350, 797 | "~A.B3": 350, // automatic alias replacing hash with tilde 798 | "#A.B4": 1063, 799 | "~A.B4": 1063, // automatic alias replacing hash with tilde 800 | "#A.B5": 477, 801 | "~A.B5": 477, // automatic alias replacing hash with tilde 802 | "#A.B6": 336, 803 | "~A.B6": 336, // automatic alias replacing hash with tilde 804 | "#A.B7": 1318, 805 | "~A.B7": 1318, // automatic alias replacing hash with tilde 806 | "A+B0": 693, 807 | "A+B1": 1021, 808 | "A+B2": 110, 809 | "A+B3": 1313, 810 | "A+B4": 918, 811 | "A+B5": 1236, 812 | "A+B6": 803, 813 | "A+B7": 117, 814 | "#(A+B)0": 143, 815 | "~(A+B)0": 143, // automatic alias replacing hash with tilde 816 | "#(A+B)1": 155, 817 | "~(A+B)1": 155, // automatic alias replacing hash with tilde 818 | "#(A+B)2": 1691, 819 | "~(A+B)2": 1691, // automatic alias replacing hash with tilde 820 | "#(A+B)3": 649, 821 | "~(A+B)3": 649, // automatic alias replacing hash with tilde 822 | "#(A+B)4": 404, 823 | "~(A+B)4": 404, // automatic alias replacing hash with tilde 824 | "#(A+B)5": 1632, 825 | "~(A+B)5": 1632, // automatic alias replacing hash with tilde 826 | "#(A+B)6": 1084, 827 | "~(A+B)6": 1084, // automatic alias replacing hash with tilde 828 | "#(A+B)7": 1398, 829 | "~(A+B)7": 1398, // automatic alias replacing hash with tilde 830 | "#(AxB)0": 1525, 831 | "~(AxB)0": 1525, // automatic alias replacing hash with tilde 832 | "#(AxB)2": 701, 833 | "~(AxB)2": 701, // automatic alias replacing hash with tilde 834 | "#(AxB)4": 308, 835 | "~(AxB)4": 308, // automatic alias replacing hash with tilde 836 | "#(AxB)6": 1459, 837 | "~(AxB)6": 1459, // automatic alias replacing hash with tilde 838 | "#(AxB)1": 953, 839 | "~(AxB)1": 953, // automatic alias replacing hash with tilde 840 | "#(AxB)3": 884, 841 | "~(AxB)3": 884, // automatic alias replacing hash with tilde 842 | "#(AxB)5": 1469, 843 | "~(AxB)5": 1469, // automatic alias replacing hash with tilde 844 | "#(AxB)7": 177, 845 | "~(AxB)7": 177, // automatic alias replacing hash with tilde 846 | "#aluresult0": 957, // alu result latch input 847 | "~aluresult0": 957, // automatic alias replacing hash with tilde 848 | "#aluresult1": 250, 849 | "~aluresult1": 250, // automatic alias replacing hash with tilde 850 | "#aluresult2": 740, 851 | "~aluresult2": 740, // automatic alias replacing hash with tilde 852 | "#aluresult3": 1071, 853 | "~aluresult3": 1071, // automatic alias replacing hash with tilde 854 | "#aluresult4": 296, 855 | "~aluresult4": 296, // automatic alias replacing hash with tilde 856 | "#aluresult5": 277, 857 | "~aluresult5": 277, // automatic alias replacing hash with tilde 858 | "#aluresult6": 722, 859 | "~aluresult6": 722, // automatic alias replacing hash with tilde 860 | "#aluresult7": 304, 861 | "~aluresult7": 304, // automatic alias replacing hash with tilde 862 | 863 | // internal signals: datapath control signals 864 | 865 | "ADL/ABL": 639, // load ABL latches from ADL bus 866 | "dpc-1_ADL/ABL": 639,// alias for DPControl pseudo-bus 867 | 868 | "ADH/ABH": 821, // load ABH latches from ADH bus 869 | "dpc-2_ADH/ABH": 821,// alias for DPControl pseudo-bus 870 | 871 | dpc0_YSB: 801, // drive sb from y 872 | dpc1_SBY: 325, // load y from sb 873 | dpc2_XSB: 1263, // drive sb from x 874 | dpc3_SBX: 1186, // load x from sb 875 | dpc4_SSB: 1700, // drive sb from stack pointer 876 | dpc5_SADL: 1468, // drive adl from stack pointer 877 | dpc6_SBS: 874, // load stack pointer from sb 878 | dpc7_SS: 654, // recirculate stack pointer 879 | dpc8_nDBADD: 1068, // alu b side: select not-idb input 880 | dpc9_DBADD: 859, // alu b side: select idb input 881 | 882 | dpc10_ADLADD: 437, // alu b side: select adl input 883 | dpc11_SBADD: 549, // alu a side: select sb 884 | dpc12_0ADD: 984, // alu a side: select zero 885 | dpc13_ORS: 59, // alu op: a or b 886 | dpc14_SRS: 362, // alu op: logical right shift 887 | dpc15_ANDS: 574, // alu op: a and b 888 | dpc16_EORS: 1666, // alu op: a xor b (?) 889 | dpc17_SUMS: 921, // alu op: a plus b (?) 890 | alucin: 910, // alu carry in 891 | notalucin: 1165, 892 | "dpc18_#DAA": 1201, // decimal related (inverted) 893 | "dpc18_~DAA": 1201, // automatic alias replacing hash with tilde 894 | dpc19_ADDSB7: 214, // alu to sb bit 7 only 895 | 896 | dpc20_ADDSB06: 129, // alu to sb bits 6-0 only 897 | dpc21_ADDADL: 1015, // alu to adl 898 | alurawcout: 808, // alu raw carry out (no decimal adjust) 899 | notalucout: 412, // alu carry out (inverted) 900 | alucout: 1146, // alu carry out (latched by phi2) 901 | "#alucout": 206, 902 | "~alucout": 206, // automatic alias replacing hash with tilde 903 | "##alucout": 465, 904 | "~~alucout": 465, // automatic alias replacing hash with tilde 905 | notaluvout: 1308, // alu overflow out 906 | aluvout: 938, // alu overflow out (latched by phi2) 907 | 908 | "#DBZ": 1268, // internal signal: not (databus is zero) 909 | "~DBZ": 1268, // automatic alias replacing hash with tilde 910 | DBZ: 744, // internal signal: databus is zero 911 | DBNeg: 1200, // internal signal: databus is negative (top bit of db) aka P-#DB7in 912 | DBNeg: 1200, // automatic alias replacing hash with tilde 913 | 914 | "dpc22_#DSA": 725, // decimal related/SBC only (inverted) 915 | "dpc22_~DSA": 725, // automatic alias replacing hash with tilde 916 | dpc23_SBAC: 534, // (optionalls decimal-adjusted) sb to acc 917 | dpc24_ACSB: 1698, // acc to sb 918 | dpc25_SBDB: 1060, // sb pass-connects to idb (bi-directionally) 919 | dpc26_ACDB: 1331, // acc to idb 920 | dpc27_SBADH: 140, // sb pass-connects to adh (bi-directionally) 921 | dpc28_0ADH0: 229, // zero to adh0 bit0 only 922 | dpc29_0ADH17: 203, // zero to adh bits 7-1 only 923 | 924 | dpc30_ADHPCH: 48, // load pch from adh 925 | dpc31_PCHPCH: 741, // load pch from pch incremented 926 | dpc32_PCHADH: 1235, // drive adh from pch incremented 927 | dpc33_PCHDB: 247, // drive idb from pch incremented 928 | dpc34_PCLC: 1704, // pch carry in and pcl FF detect? 929 | dpc35_PCHC: 1334, // pch 0x?F detect - half-carry 930 | "dpc36_#IPC": 379, // pcl carry in (inverted) 931 | "dpc36_~IPC": 379, // automatic alias replacing hash with tilde 932 | dpc37_PCLDB: 283, // drive idb from pcl incremented 933 | dpc38_PCLADL: 438, // drive adl from pcl incremented 934 | dpc39_PCLPCL: 898, // load pcl from pcl incremented 935 | 936 | dpc40_ADLPCL: 414, // load pcl from adl 937 | "dpc41_DL/ADL": 1564,// pass-connect adl to mux node driven by idl 938 | "dpc42_DL/ADH": 41, // pass-connect adh to mux node driven by idl 939 | "dpc43_DL/DB": 863, // pass-connect idb to mux node driven by idl 940 | 941 | } 942 | 943 | /* many bus names taken from Donald F. Hanson's block diagram, found 944 | * http://www.weihenstephan.org/~michaste/pagetable/6502/6502.jpg 945 | * from his paper "A VHDL conversion tool for logic equations with embedded D latches" 946 | * http://portal.acm.org/citation.cfm?id=1275143.1275151 947 | * also available at 948 | * http://www.ncsu.edu/wcae/WCAE1/hanson.pdf 949 | */ 950 | -------------------------------------------------------------------------------- /testprogram.js: -------------------------------------------------------------------------------- 1 | // This file testprogram.js can be substituted by one of several tests 2 | // which may not be redistributable 3 | // for example 4 | // cbmbasic loaded at 0xa000 with entry point 0xe394 5 | // test6502 (by Bird Computer) loaded at 0x8000 with entry point 0x8000 6 | // 7 | // (can use xxd -i to convert binary into C include syntax, as a starting point) 8 | // 9 | testprogramAddress=0x0000; 10 | 11 | // we want to auto-clear the console if any output is sent by the program 12 | var consoleboxStream=""; 13 | 14 | // demonstrate write hook 15 | writeTriggers[0x000F]="consoleboxStream += String.fromCharCode(d);"+ 16 | "consolebox.innerHTML = consoleboxStream;"; 17 | 18 | // demonstrate read hook (not used by this test program) 19 | readTriggers[0xD011]="((consolegetc==undefined)?0:0xff)"; // return zero until we have a char 20 | readTriggers[0xD010]="var c=consolegetc; consolegetc=undefined; (c)"; 21 | 22 | testprogram = [ 23 | 0xa9, 0x00, // LDA #$00 24 | 0x20, 0x10, 0x00, // JSR $0010 25 | 0x4c, 0x02, 0x00, // JMP $0002 26 | 27 | 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x40, 29 | 30 | 0xe8, // INX 31 | 0x88, // DEY 32 | 0xe6, 0x0F, // INC $0F 33 | 0x38, // SEC 34 | 0x69, 0x02, // ADC #$02 35 | 0x60 // RTS 36 | ]; 37 | -------------------------------------------------------------------------------- /wires.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Brian Silverman, Barry Silverman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | var frame, chipbg, overlay, hilite, hitbuffer, ctx; 24 | var nodes = new Array(); 25 | var transistors = {}; 26 | var nodenamelist=[]; 27 | 28 | var ngnd = nodenames['vss']; 29 | var npwr = nodenames['vcc']; 30 | 31 | var chipLayoutIsVisible = true; // only modified in expert mode 32 | var hilited = []; 33 | 34 | function setupNodes(){ 35 | for(var i in segdefs){ 36 | var seg = segdefs[i]; 37 | var w = seg[0]; 38 | if(nodes[w]==undefined) 39 | nodes[w] = {segs: new Array(), num: w, pullup: seg[1]=='+', 40 | state: false, gates: new Array(), c1c2s: new Array()}; 41 | if(w==ngnd) continue; 42 | if(w==npwr) continue; 43 | nodes[w].segs.push(seg.slice(3)); 44 | } 45 | } 46 | 47 | function setupTransistors(){ 48 | for(i in transdefs){ 49 | var tdef = transdefs[i]; 50 | var name = tdef[0]; 51 | var gate = tdef[1]; 52 | var c1 = tdef[2]; 53 | var c2 = tdef[3]; 54 | var bb = tdef[4]; 55 | if(c1==ngnd) {c1=c2;c2=ngnd;} 56 | if(c1==npwr) {c1=c2;c2=npwr;} 57 | var trans = {name: name, on: false, gate: gate, c1: c1, c2: c2, bb: bb}; 58 | nodes[gate].gates.push(trans); 59 | nodes[c1].c1c2s.push(trans); 60 | nodes[c2].c1c2s.push(trans); 61 | transistors[name] = trans; 62 | } 63 | } 64 | 65 | function setupLayerVisibility(){ 66 | var x=document.getElementById('updateShow'); 67 | for (var i=0;i>4)&0xf); 121 | var high = hexdigit((i>>8)&0xf); 122 | ctx.fillStyle = '#'+high+'F'+mid+'F'+low+'F'; 123 | for(i in w) { 124 | drawSeg(ctx, w[i]); 125 | ctx.fill(); 126 | } 127 | } 128 | 129 | function hexdigit(n){return '0123456789ABCDEF'.charAt(n);} 130 | 131 | 132 | ///////////////////////// 133 | // 134 | // Drawing Runtime 135 | // 136 | ///////////////////////// 137 | 138 | function refresh(){ 139 | if(!chipLayoutIsVisible) return; 140 | ctx.clearRect(0,0,grCanvasSize,grCanvasSize); 141 | for(i in nodes){ 142 | if(isNodeHigh(i)) overlayNode(nodes[i].segs); 143 | } 144 | hiliteNode(hilited); 145 | } 146 | 147 | function overlayNode(w){ 148 | ctx.fillStyle = 'rgba(255,0,64,0.4)'; 149 | for(i in w) { 150 | drawSeg(ctx, w[i]); 151 | ctx.fill(); 152 | } 153 | } 154 | 155 | // originally to highlight using a list of node numbers 156 | // but can now include transistor names 157 | function hiliteNode(n){ 158 | var ctx = hilite.getContext('2d'); 159 | ctx.clearRect(0,0,grCanvasSize,grCanvasSize); 160 | if(n==-1) return; 161 | hilited = n; 162 | 163 | for(var i in n){ 164 | if(typeof n[i] != "number") { 165 | hiliteTrans([n[i]]); 166 | continue; 167 | } 168 | if(isNodeHigh(n[i])) { 169 | ctx.fillStyle = 'rgba(255,0,0,0.7)'; 170 | } else { 171 | ctx.fillStyle = 'rgba(255,255,255,0.7)'; 172 | } 173 | var segs = nodes[n[i]].segs; 174 | for(var s in segs){drawSeg(ctx, segs[s]); ctx.fill();} 175 | } 176 | } 177 | 178 | // highlight a single transistor (additively - does not clear highlighting) 179 | function hiliteTrans(n){ 180 | var ctx = hilite.getContext('2d'); 181 | ctx.strokeStyle = 'rgba(255,255,255,0.7)'; 182 | ctx.lineWidth = 4 183 | for(var t in n){ 184 | var bb = transistors[n[t]].bb 185 | var segs = [[bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3]]] 186 | for(var s in segs){drawSeg(ctx, segs[s]); ctx.stroke();} 187 | } 188 | } 189 | 190 | function ctxDrawBox(ctx, xMin, yMin, xMax, yMax){ 191 | var cap=ctx.lineCap; 192 | ctx.lineCap="square"; 193 | ctx.beginPath(); 194 | ctx.moveTo(xMin, yMin); 195 | ctx.lineTo(xMin, yMax); 196 | ctx.lineTo(xMax, yMax); 197 | ctx.lineTo(xMax, yMin); 198 | ctx.lineTo(xMin, yMin); 199 | ctx.stroke(); 200 | ctx.lineCap=cap; 201 | } 202 | 203 | // takes a bounding box in chip coords and centres the display over it 204 | function zoomToBox(xmin,xmax,ymin,ymax){ 205 | var xmid=(xmin+xmax)/2; 206 | var ymid=(ymin+ymax)/2; 207 | var x=(xmid+grChipOffsetX)/grChipSize*600; 208 | var y=600-(ymid-grChipOffsetY)/grChipSize*600; 209 | // Zoom to fill 80% of the window with the selection 210 | var fillfactor=0.80; 211 | var dx=xmax-xmin; 212 | var dy=ymax-ymin; 213 | if (dx < 1) dx=1; 214 | if (dy < 1) dy=1; 215 | var zx=(800/600)*fillfactor*grChipSize/dx; 216 | var zy=fillfactor*grChipSize/dy; 217 | var zoom=Math.min(zx,zy); 218 | if (zoom < 1) { 219 | zoom = 1; 220 | } 221 | if (zoom > grMaxZoom) { 222 | zoom = grMaxZoom; 223 | } 224 | moveHere([x,y,zoom]); 225 | } 226 | 227 | function drawSeg(ctx, seg){ 228 | var dx = grChipOffsetX; 229 | var dy = grChipOffsetY; 230 | ctx.beginPath(); 231 | ctx.moveTo(grScale(seg[0]+dx), grScale(grChipSize-seg[1]+dy)); 232 | for(var i=2;i>4; 241 | var mid = pixels[1]>>4; 242 | var low = pixels[2]>>4; 243 | return (high<<8)+(mid<<4)+low; 244 | } 245 | 246 | function clearHighlight(){ 247 | // remove red/white overlay according to logic value 248 | // for easier layout navigation 249 | ctx.clearRect(0,0,grCanvasSize,grCanvasSize); 250 | } 251 | 252 | function updateShow(layer, on){ 253 | drawlayers[layer]=on; 254 | setupBackground(); 255 | } 256 | 257 | // we draw the chip data scaled down to the canvas 258 | // and so avoid scaling a large canvas 259 | function grScale(x){ 260 | return Math.round(x*grCanvasSize/grChipSize); 261 | } 262 | 263 | function localx(el, gx){ 264 | return gx-el.getBoundingClientRect().left; 265 | } 266 | 267 | function localy(el, gy){ 268 | return gy-el.getBoundingClientRect().top; 269 | } 270 | 271 | function setStatus(){ 272 | var res = ''; 273 | // pad the arguments to make this a three-line display 274 | // there must be a clean way to do this 275 | if(arguments[1]==undefined)arguments[1]=""; 276 | if(arguments[2]==undefined)arguments[2]=""; 277 | arguments.length=3; 278 | for(var i=0;i'; 279 | statbox.innerHTML = res; 280 | } 281 | 282 | function setupNodeNameList(){ 283 | for(var i in nodenames) 284 | nodenamelist.push(i); 285 | } 286 | 287 | function nodeName(n) { 288 | for(var i in nodenames){ 289 | if(nodenames[i]==n) return i; 290 | } 291 | return ''; 292 | } 293 | 294 | function now(){return new Date().getTime();} 295 | --------------------------------------------------------------------------------