Compare commits

...

44 Commits

Author SHA1 Message Date
Dennis Brown f1d06fa908
Merge pull request #17 from MutableLoss/dependabot/npm_and_yarn/http-cache-semantics-4.1.1
Bump http-cache-semantics from 4.1.0 to 4.1.1
2023-02-28 12:41:56 -10:00
dependabot[bot] 5b6f6d5e04
Bump http-cache-semantics from 4.1.0 to 4.1.1
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-03 10:22:12 +00:00
Dennis Brown 40e46dc4ed
Merge pull request #16 from MutableLoss/dependabot/npm_and_yarn/electron-18.3.7
Bump electron from 13.6.6 to 18.3.7
2022-11-10 15:56:06 -10:00
dependabot[bot] e938df6bf5
Bump electron from 13.6.6 to 18.3.7
---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-10 14:27:08 +00:00
Dennis Brown b3cc4bba70
Merge pull request #14 from MutableLoss/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-03-25 12:10:31 -10:00
dependabot[bot] a0f2a772d2
Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 21:34:34 +00:00
Dennis Brown a7c68787f1
Merge pull request #13 from MutableLoss/dependabot/npm_and_yarn/electron-13.6.6
Bump electron from 11.5.0 to 13.6.6
2022-03-25 11:33:51 -10:00
dependabot[bot] f0844da6e0
Bump electron from 11.5.0 to 13.6.6
Bumps [electron](https://github.com/electron/electron) from 11.5.0 to 13.6.6.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v11.5.0...v13.6.6)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 18:40:29 +00:00
Dennis Brown 4ba0539403
Merge pull request #12 from MutableLoss/dependabot/npm_and_yarn/electron-11.5.0
Bump electron from 9.4.0 to 11.5.0
2021-10-13 14:02:43 -05:00
dependabot[bot] 264acbbb03
Bump electron from 9.4.0 to 11.5.0
Bumps [electron](https://github.com/electron/electron) from 9.4.0 to 11.5.0.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v9.4.0...v11.5.0)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-12 22:14:04 +00:00
Dennis Brown 73fd49d000
Merge pull request #11 from MutableLoss/dependabot/npm_and_yarn/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1
2021-06-10 10:26:02 -05:00
dependabot[bot] 6b6a1de839
Bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-10 15:25:31 +00:00
Dennis Brown 36e7d61d4b
Merge pull request #10 from MutableLoss/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21
2021-06-10 10:25:11 -05:00
dependabot[bot] 2a764cbc8c
Bump lodash from 4.17.19 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-11 19:37:48 +00:00
Dennis Brown 9d470ec1bb
Merge pull request #9 from MutableLoss/dependabot/npm_and_yarn/electron-9.4.0
Bump electron from 7.3.2 to 9.4.0
2021-02-04 10:31:07 -08:00
dependabot[bot] 972b813daa
Bump electron from 7.3.2 to 9.4.0
Bumps [electron](https://github.com/electron/electron) from 7.3.2 to 9.4.0.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v7.3.2...v9.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-28 19:46:23 +00:00
Dennis Brown 9c128b0f77
Merge pull request #8 from MutableLoss/dependabot/npm_and_yarn/ini-1.3.7
Bump ini from 1.3.5 to 1.3.7
2020-12-15 11:22:53 -06:00
dependabot[bot] a1925a1971
Bump ini from 1.3.5 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 04:21:31 +00:00
Dennis Brown 7fc4986f8d update packages 2020-07-08 14:33:35 -05:00
Dennis Brown 9e986e559a
Merge pull request #7 from MutableLoss/dependabot/npm_and_yarn/electron-7.2.4
Bump electron from 6.1.9 to 7.2.4
2020-07-08 14:27:27 -05:00
dependabot[bot] 96ef1698b9
Bump electron from 6.1.9 to 7.2.4
Bumps [electron](https://github.com/electron/electron) from 6.1.9 to 7.2.4.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v6.1.9...v7.2.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-07 05:00:20 +00:00
Dennis Brown a4de1542b3 update electron for security warning 2020-03-16 11:00:56 -05:00
Dennis Brown 3d16673d65
Merge pull request #6 from 3DEsprit/dependabot/npm_and_yarn/extend-3.0.2
Bump extend from 3.0.0 to 3.0.2
2019-10-24 12:30:49 -05:00
Dennis Brown af685c697d
Merge pull request #5 from 3DEsprit/dependabot/npm_and_yarn/stringstream-0.0.6
Bump stringstream from 0.0.5 to 0.0.6
2019-10-24 12:30:39 -05:00
Dennis Brown e9806fc87a
Merge pull request #4 from 3DEsprit/dependabot/npm_and_yarn/tough-cookie-2.3.4
Bump tough-cookie from 2.3.2 to 2.3.4
2019-10-24 12:30:27 -05:00
Dennis Brown 05e15076fc
Merge pull request #3 from 3DEsprit/dependabot/npm_and_yarn/sshpk-1.16.1
Bump sshpk from 1.11.0 to 1.16.1
2019-10-24 12:30:15 -05:00
dependabot[bot] 8d78e5505e
Bump extend from 3.0.0 to 3.0.2
Bumps [extend](https://github.com/justmoon/node-extend) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/justmoon/node-extend/releases)
- [Changelog](https://github.com/justmoon/node-extend/blob/master/CHANGELOG.md)
- [Commits](https://github.com/justmoon/node-extend/compare/v3.0.0...v3.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-22 21:40:23 +00:00
dependabot[bot] 392e1eeb2f
Bump stringstream from 0.0.5 to 0.0.6
Bumps [stringstream](https://github.com/mhart/StringStream) from 0.0.5 to 0.0.6.
- [Release notes](https://github.com/mhart/StringStream/releases)
- [Commits](https://github.com/mhart/StringStream/compare/v0.0.5...v0.0.6)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-22 21:40:18 +00:00
dependabot[bot] f78c5d49a9
Bump tough-cookie from 2.3.2 to 2.3.4
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 2.3.2 to 2.3.4.
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Commits](https://github.com/salesforce/tough-cookie/compare/v2.3.2...v2.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-22 21:40:17 +00:00
dependabot[bot] aad2cb00b8
Bump sshpk from 1.11.0 to 1.16.1
Bumps [sshpk](https://github.com/joyent/node-sshpk) from 1.11.0 to 1.16.1.
- [Release notes](https://github.com/joyent/node-sshpk/releases)
- [Commits](https://github.com/joyent/node-sshpk/compare/v1.11.0...v1.16.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-22 21:40:15 +00:00
Dennis Brown a628ad2004 update packages 2019-06-24 12:48:32 -05:00
Dennis Brown 5cb1005bb6 update electron 2019-06-08 19:32:17 -05:00
Dennis Brown 1791322734 add 64spec for future testing 2018-03-01 21:31:22 -06:00
Dennis Brown 7109f53a5f remove obsolete es5-shim 2018-03-01 21:31:10 -06:00
Dennis Brown 12e51b51c9 add development script 2018-03-01 21:31:00 -06:00
Dennis Brown af7ba72f5e update eslint rules 2018-03-01 21:30:42 -06:00
Dennis Brown e4f1f9f03f code cleanup 2018-03-01 21:30:29 -06:00
Dennis Brown 824cd8c56b Update Links and Information 2017-05-07 22:39:24 -05:00
Dennis Brown 93de55b17c fix Linux/Windows Menus 2017-05-07 22:39:10 -05:00
Dennis Brown 2c3ba3d21e fix build scripts 2017-05-07 22:38:51 -05:00
Dennis Brown b4fafbcb7e update build scripts 2017-05-07 21:40:14 -05:00
Dennis Brown e547439170 fix links and format 2017-03-30 00:18:39 -05:00
Dennis Brown ed18056cf8 Update todos and links 2017-03-30 00:05:59 -05:00
Dennis Brown f96ec3e09a Add screenshot to README 2017-03-30 00:05:20 -05:00
9 changed files with 1840 additions and 2070 deletions

View File

@ -42,7 +42,7 @@ rules:
no-throw-literal: 2 no-throw-literal: 2
no-unused-labels: 2 no-unused-labels: 2
no-useless-call: 2 no-useless-call: 2
no-useless-escape: 2 no-useless-escape: 0
no-void: 2 no-void: 2
no-with: 2 no-with: 2

View File

@ -7,28 +7,51 @@ What would make it even easier is having your own Desktop 6502 Simulator to use.
I went ahead and did exactly that. While I am not finished it is usable, and I plan to do whatever I can to I went ahead and did exactly that. While I am not finished it is usable, and I plan to do whatever I can to
make it a great desktop app in the near future. make it a great desktop app in the near future.
![6502 Desktop Simulator](/assets/6502Desktop_SS.png "6502Desktop on OSX")
## Usage
_At this time there are not any static builds (yet). You will find future builds here in the future._ # Getting Started
First things first, clone the repository!
*yarn install* (or npm install) ## Binary Downloads
*npm start*
[OSX Build 0.3.7](https://github.com/3DEsprit/6502SimDesktop/releases/download/0.3.7/6502Desktop-OSX_0.3.7.zip)
[Windows Build 0.3.7](https://github.com/3DEsprit/6502SimDesktop/releases/download/0.3.7/6502Desktop-Win_0.3.7.zip)
[Linux Build 0.3.7](https://github.com/3DEsprit/6502SimDesktop/releases/download/0.3.7/6502Desktop-Linux_0.3.7.zip)
## Install Manually
_If there is not a build for your OS or if you would like to compile from source, you can install manually:_
First things first, clone the repository by downloading with the Green Download button above, or cloning on your system.
`git clone https://github.com/3DEsprit/6502SimDesktop.git`
`yarn install` (or `npm install` without [Yarn](https://github.com/yarnpkg/yarn))
`npm start`
Have fun!
## ToDo List ## ToDo List
* Fix Hexdump * Finish Memory Monitor *In Progress*
* Add Menu/Hotkey Support for functions
* Update Register/Flag Viewing
* Addition of UI Animations
* Create Snazzy Icon (In process) * Create Snazzy Icon (In process)
* Test on Windows/Linux * Test on Linux
* Build Packages for Win/Linux Platforms (Mac build done) * Build Packages for Win/Linux Platforms
* Reactive CSS with the window size * ~~Reactive CSS with the window size~~
* Make the the sim integration more desktop-ish (hotkeys/menu items for assemble debug, and other options). * Make the the sim integration more desktop-ish *In Progress*.
* Various Colored Themes * Various Colored Themes
* Look at options to offer on Mac App Store, and Windows App Store * Look at options to offer on Mac App Store, and Windows App Store
* Switch to Electron-Builder for Builds
* Change Linux Builds to AppImage
## License ## License
The simulator used in this Electron app was created by [Nick Morgon](https://twitter.com/skilldrick), and you can find the original code in the [6502js Repo](https://github.com/skilldrick/6502js). The base simulator used in this app was created by [Nick Morgon](https://twitter.com/skilldrick), and you can find the original code in the [6502js Repo](https://github.com/skilldrick/6502js).

View File

@ -33,7 +33,7 @@ function SimulatorWidget(node) {
$node.find('.runButton').click(simulator.runBinary); $node.find('.runButton').click(simulator.runBinary);
$node.find('.runButton').click(simulator.stopDebugger); $node.find('.runButton').click(simulator.stopDebugger);
$node.find('.resetButton').click(simulator.reset); $node.find('.resetButton').click(simulator.reset);
$node.find('.hexdumpButton').click(assembler.hexdump); $node.find('.hexdumpButton').click(assembler.hexdump).trigger('keydown', {which: 65});
$node.find('.disassembleButton').click(assembler.disassemble); $node.find('.disassembleButton').click(assembler.disassemble);
$node.find('.debug').on('click', function () { $node.find('.debug').on('click', function () {
$(this).toggleClass('active'); $(this).toggleClass('active');
@ -49,7 +49,7 @@ function SimulatorWidget(node) {
$node.find('.monitoring').on('click', function () { $node.find('.monitoring').on('click', function () {
$(this).toggleClass('active'); $(this).toggleClass('active');
if($(this).hasClass('active')) { if($(this).hasClass('active')) {
} }
ui.toggleMonitor(); ui.toggleMonitor();
simulator.toggleMonitor(); simulator.toggleMonitor();
@ -177,10 +177,10 @@ function SimulatorWidget(node) {
// Insert tab at caret position (instead of losing focus) // Insert tab at caret position (instead of losing focus)
var caretStart = this.selectionStart, var caretStart = this.selectionStart,
caretEnd = this.selectionEnd, caretEnd = this.selectionEnd,
currentValue = this.value; currentValue = this.value;
this.value = currentValue.substring(0, caretStart) + "\t" + currentValue.substring(caretEnd); this.value = currentValue.substring(0, caretStart) + '\t' + currentValue.substring(caretEnd);
// Move cursor forwards one (after tab) // Move cursor forwards one (after tab)
this.selectionStart = this.selectionEnd = caretStart + 1; this.selectionStart = this.selectionEnd = caretStart + 1;
@ -204,10 +204,10 @@ function SimulatorWidget(node) {
function Display() { function Display() {
var displayArray = []; var displayArray = [];
var palette = [ var palette = [
"#000000", "#ffffff", "#880000", "#aaffee", '#000000', '#ffffff', '#880000', '#aaffee',
"#cc44cc", "#00cc55", "#0000aa", "#eeee77", '#cc44cc', '#00cc55', '#0000aa', '#eeee77',
"#dd8855", "#664400", "#ff7777", "#333333", '#dd8855', '#664400', '#ff7777', '#333333',
"#777777", "#aaff66", "#0088ff", "#bbbbbb" '#777777', '#aaff66', '#0088ff', '#bbbbbb'
]; ];
var ctx; var ctx;
var width; var width;
@ -226,7 +226,7 @@ function SimulatorWidget(node) {
} }
function reset() { function reset() {
ctx.fillStyle = "black"; ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
} }
@ -279,14 +279,14 @@ function SimulatorWidget(node) {
for (var x = 0; x < length; x++) { for (var x = 0; x < length; x++) {
if ((x & 15) === 0) { if ((x & 15) === 0) {
if (x > 0) { html += "\n"; } if (x > 0) { html += '\n'; }
n = (start + x); n = (start + x);
html += num2hex(((n >> 8) & 0xff)); html += num2hex(((n >> 8) & 0xff));
html += num2hex((n & 0xff)); html += num2hex((n & 0xff));
html += ": "; html += ': ';
} }
html += num2hex(memory.get(start + x)); html += num2hex(memory.get(start + x));
html += " "; html += ' ';
} }
return html; return html;
} }
@ -871,7 +871,7 @@ function SimulatorWidget(node) {
i58: function () { i58: function () {
regP &= ~0x04; regP &= ~0x04;
throw new Error("Interrupts not implemented"); throw new Error('Interrupts not implemented');
//CLI //CLI
}, },
@ -1006,7 +1006,7 @@ function SimulatorWidget(node) {
i78: function () { i78: function () {
regP |= 0x04; regP |= 0x04;
throw new Error("Interrupts not implemented"); throw new Error('Interrupts not implemented');
//SEI //SEI
}, },
@ -1499,7 +1499,7 @@ function SimulatorWidget(node) {
}, },
ierr: function () { ierr: function () {
message("Address $" + addr2hex(regPC) + " - unknown opcode"); message('Address $' + addr2hex(regPC) + ' - unknown opcode');
codeRunning = false; codeRunning = false;
} }
}; };
@ -1509,7 +1509,7 @@ function SimulatorWidget(node) {
regSP--; regSP--;
if (regSP < 0) { if (regSP < 0) {
regSP &= 0xff; regSP &= 0xff;
message("6502 Stack filled! Wrapping..."); message('6502 Stack filled! Wrapping...');
} }
} }
@ -1518,7 +1518,7 @@ function SimulatorWidget(node) {
regSP++; regSP++;
if (regSP >= 0x100) { if (regSP >= 0x100) {
regSP &= 0xff; regSP &= 0xff;
message("6502 Stack emptied! Wrapping..."); message('6502 Stack emptied! Wrapping...');
} }
value = memory.get(regSP + 0x100); value = memory.get(regSP + 0x100);
return value; return value;
@ -1582,7 +1582,7 @@ function SimulatorWidget(node) {
if ((regPC === 0) || (!codeRunning && !debugging)) { if ((regPC === 0) || (!codeRunning && !debugging)) {
stop(); stop();
message("Program end at PC=$" + addr2hex(regPC - 1)); message('Program end at PC=$' + addr2hex(regPC - 1));
ui.stop(); ui.stop();
} }
} }
@ -1611,10 +1611,10 @@ function SimulatorWidget(node) {
function handleMonitorRangeChange() { function handleMonitorRangeChange() {
var $start = $node.find('.start'), var $start = $node.find('.start'),
$length = $node.find('.length'), $length = $node.find('.length'),
start = parseInt($start.val(), 16), start = parseInt($start.val(), 16),
length = parseInt($length.val(), 16), length = parseInt($length.val(), 16),
end = start + length - 1; end = start + length - 1;
$start.removeClass('monitor-invalid'); $start.removeClass('monitor-invalid');
$length.removeClass('monitor-invalid'); $length.removeClass('monitor-invalid');
@ -1632,15 +1632,15 @@ function SimulatorWidget(node) {
// Execute one instruction and print values // Execute one instruction and print values
function debugExec() { function debugExec() {
//if (codeRunning) { //if (codeRunning) {
execute(true); execute(true);
//} //}
updateDebugInfo(); updateDebugInfo();
} }
function updateDebugInfo() { function updateDebugInfo() {
var html = "A=$" + num2hex(regA) + " X=$" + num2hex(regX) + " Y=$" + num2hex(regY) + var html = 'A=$' + num2hex(regA) + ' X=$' + num2hex(regX) + ' Y=$' + num2hex(regY) +
" SP=$" + num2hex(regSP) + " PC=$" + addr2hex(regPC) + " NV-BDIZC: "; ' SP=$' + num2hex(regSP) + ' PC=$' + addr2hex(regPC) + ' NV-BDIZC: ';
for (var i = 7; i >=0; i--) { for (var i = 7; i >= 0; i--) {
html += regP >> i & 1; html += regP >> i & 1;
} }
$node.find('.minidebugger').html(html); $node.find('.minidebugger').html(html);
@ -1649,21 +1649,21 @@ function SimulatorWidget(node) {
// gotoAddr() - Set PC to address (or address of label) // gotoAddr() - Set PC to address (or address of label)
function gotoAddr() { function gotoAddr() {
var inp = prompt("Enter address or label", ""); var inp = prompt('Enter address or label', '');
var addr = 0; var addr = 0;
if (labels.find(inp)) { if (labels.find(inp)) {
addr = labels.getPC(inp); addr = labels.getPC(inp);
} else { } else {
if (inp.match(/^0x[0-9a-f]{1,4}$/i)) { if (inp.match(/^0x[0-9a-f]{1,4}$/i)) {
inp = inp.replace(/^0x/, ""); inp = inp.replace(/^0x/, '');
addr = parseInt(inp, 16); addr = parseInt(inp, 16);
} else if (inp.match(/^\$[0-9a-f]{1,4}$/i)) { } else if (inp.match(/^\$[0-9a-f]{1,4}$/i)) {
inp = inp.replace(/^\$/, ""); inp = inp.replace(/^\$/, '');
addr = parseInt(inp, 16); addr = parseInt(inp, 16);
} }
} }
if (addr === 0) { if (addr === 0) {
message("Unable to find/parse given address/label"); message('Unable to find/parse given address/label');
} else { } else {
regPC = addr; regPC = addr;
} }
@ -1698,7 +1698,7 @@ function SimulatorWidget(node) {
function stop() { function stop() {
codeRunning = false; codeRunning = false;
clearInterval(executeId); clearInterval(executeId);
message("\nStopped\n"); message('\nStopped\n');
} }
function toggleMonitor() { function toggleMonitor() {
@ -1725,7 +1725,7 @@ function SimulatorWidget(node) {
function indexLines(lines, symbols) { function indexLines(lines, symbols) {
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
if (!indexLine(lines[i], symbols)) { if (!indexLine(lines[i], symbols)) {
message("**Label already defined at line " + (i + 1) + ":** " + lines[i]); message('**Label already defined at line ' + (i + 1) + ':** ' + lines[i]);
return false; return false;
} }
} }
@ -1735,21 +1735,21 @@ function SimulatorWidget(node) {
// Extract label if line contains one and calculate position in memory. // Extract label if line contains one and calculate position in memory.
// Return false if label already exists. // Return false if label already exists.
function indexLine(input, symbols) { function indexLine(input, symbols) {
// Figure out how many bytes this instruction takes // Figure out how many bytes this instruction takes
var currentPC = assembler.getCurrentPC(); var currentPC = assembler.getCurrentPC();
assembler.assembleLine(input, 0, symbols); //TODO: find a better way for Labels to have access to assembler assembler.assembleLine(input, 0, symbols); //TODO: find a better way for Labels to have access to assembler
// Find command or label // Find command or label
if (input.match(/^\w+:/)) { if (input.match(/^\w+:/)) {
var label = input.replace(/(^\w+):.*$/, "$1"); var label = input.replace(/(^\w+):.*$/, '$1');
if (symbols.lookup(label)) { if (symbols.lookup(label)) {
message("**Label " + label + "is already used as a symbol; please rename one of them**"); message('**Label ' + label + 'is already used as a symbol; please rename one of them**');
return false; return false;
} }
return push(label + "|" + currentPC); return push(label + '|' + currentPC);
} }
return true; return true;
} }
@ -1759,7 +1759,7 @@ function SimulatorWidget(node) {
if (find(name)) { if (find(name)) {
return false; return false;
} }
labelIndex.push(name + "|"); labelIndex.push(name + '|');
return true; return true;
} }
@ -1767,7 +1767,7 @@ function SimulatorWidget(node) {
function find(name) { function find(name) {
var nameAndAddr; var nameAndAddr;
for (var i = 0; i < labelIndex.length; i++) { for (var i = 0; i < labelIndex.length; i++) {
nameAndAddr = labelIndex[i].split("|"); nameAndAddr = labelIndex[i].split('|');
if (name === nameAndAddr[0]) { if (name === nameAndAddr[0]) {
return true; return true;
} }
@ -1779,9 +1779,9 @@ function SimulatorWidget(node) {
function setPC(name, addr) { function setPC(name, addr) {
var nameAndAddr; var nameAndAddr;
for (var i = 0; i < labelIndex.length; i++) { for (var i = 0; i < labelIndex.length; i++) {
nameAndAddr = labelIndex[i].split("|"); nameAndAddr = labelIndex[i].split('|');
if (name === nameAndAddr[0]) { if (name === nameAndAddr[0]) {
labelIndex[i] = name + "|" + addr; labelIndex[i] = name + '|' + addr;
return true; return true;
} }
} }
@ -1792,7 +1792,7 @@ function SimulatorWidget(node) {
function getPC(name) { function getPC(name) {
var nameAndAddr; var nameAndAddr;
for (var i = 0; i < labelIndex.length; i++) { for (var i = 0; i < labelIndex.length; i++) {
nameAndAddr = labelIndex[i].split("|"); nameAndAddr = labelIndex[i].split('|');
if (name === nameAndAddr[0]) { if (name === nameAndAddr[0]) {
return (nameAndAddr[1]); return (nameAndAddr[1]);
} }
@ -1801,11 +1801,11 @@ function SimulatorWidget(node) {
} }
function displayMessage() { function displayMessage() {
var str = "Found " + labelIndex.length + " label"; var str = 'Found ' + labelIndex.length + ' label';
if (labelIndex.length !== 1) { if (labelIndex.length !== 1) {
str += "s"; str += 's';
} }
message(str + "."); message(str + '.');
} }
function reset() { function reset() {
@ -1830,86 +1830,86 @@ function SimulatorWidget(node) {
var Opcodes = [ var Opcodes = [
/* Name, Imm, ZP, ZPX, ZPY, ABS, ABSX, ABSY, IND, INDX, INDY, SNGL, BRA */ /* Name, Imm, ZP, ZPX, ZPY, ABS, ABSX, ABSY, IND, INDX, INDY, SNGL, BRA */
["ADC", 0x69, 0x65, 0x75, null, 0x6d, 0x7d, 0x79, null, 0x61, 0x71, null, null], ['ADC', 0x69, 0x65, 0x75, null, 0x6d, 0x7d, 0x79, null, 0x61, 0x71, null, null],
["AND", 0x29, 0x25, 0x35, null, 0x2d, 0x3d, 0x39, null, 0x21, 0x31, null, null], ['AND', 0x29, 0x25, 0x35, null, 0x2d, 0x3d, 0x39, null, 0x21, 0x31, null, null],
["ASL", null, 0x06, 0x16, null, 0x0e, 0x1e, null, null, null, null, 0x0a, null], ['ASL', null, 0x06, 0x16, null, 0x0e, 0x1e, null, null, null, null, 0x0a, null],
["BIT", null, 0x24, null, null, 0x2c, null, null, null, null, null, null, null], ['BIT', null, 0x24, null, null, 0x2c, null, null, null, null, null, null, null],
["BPL", null, null, null, null, null, null, null, null, null, null, null, 0x10], ['BPL', null, null, null, null, null, null, null, null, null, null, null, 0x10],
["BMI", null, null, null, null, null, null, null, null, null, null, null, 0x30], ['BMI', null, null, null, null, null, null, null, null, null, null, null, 0x30],
["BVC", null, null, null, null, null, null, null, null, null, null, null, 0x50], ['BVC', null, null, null, null, null, null, null, null, null, null, null, 0x50],
["BVS", null, null, null, null, null, null, null, null, null, null, null, 0x70], ['BVS', null, null, null, null, null, null, null, null, null, null, null, 0x70],
["BCC", null, null, null, null, null, null, null, null, null, null, null, 0x90], ['BCC', null, null, null, null, null, null, null, null, null, null, null, 0x90],
["BCS", null, null, null, null, null, null, null, null, null, null, null, 0xb0], ['BCS', null, null, null, null, null, null, null, null, null, null, null, 0xb0],
["BNE", null, null, null, null, null, null, null, null, null, null, null, 0xd0], ['BNE', null, null, null, null, null, null, null, null, null, null, null, 0xd0],
["BEQ", null, null, null, null, null, null, null, null, null, null, null, 0xf0], ['BEQ', null, null, null, null, null, null, null, null, null, null, null, 0xf0],
["BRK", null, null, null, null, null, null, null, null, null, null, 0x00, null], ['BRK', null, null, null, null, null, null, null, null, null, null, 0x00, null],
["CMP", 0xc9, 0xc5, 0xd5, null, 0xcd, 0xdd, 0xd9, null, 0xc1, 0xd1, null, null], ['CMP', 0xc9, 0xc5, 0xd5, null, 0xcd, 0xdd, 0xd9, null, 0xc1, 0xd1, null, null],
["CPX", 0xe0, 0xe4, null, null, 0xec, null, null, null, null, null, null, null], ['CPX', 0xe0, 0xe4, null, null, 0xec, null, null, null, null, null, null, null],
["CPY", 0xc0, 0xc4, null, null, 0xcc, null, null, null, null, null, null, null], ['CPY', 0xc0, 0xc4, null, null, 0xcc, null, null, null, null, null, null, null],
["DEC", null, 0xc6, 0xd6, null, 0xce, 0xde, null, null, null, null, null, null], ['DEC', null, 0xc6, 0xd6, null, 0xce, 0xde, null, null, null, null, null, null],
["EOR", 0x49, 0x45, 0x55, null, 0x4d, 0x5d, 0x59, null, 0x41, 0x51, null, null], ['EOR', 0x49, 0x45, 0x55, null, 0x4d, 0x5d, 0x59, null, 0x41, 0x51, null, null],
["CLC", null, null, null, null, null, null, null, null, null, null, 0x18, null], ['CLC', null, null, null, null, null, null, null, null, null, null, 0x18, null],
["SEC", null, null, null, null, null, null, null, null, null, null, 0x38, null], ['SEC', null, null, null, null, null, null, null, null, null, null, 0x38, null],
["CLI", null, null, null, null, null, null, null, null, null, null, 0x58, null], ['CLI', null, null, null, null, null, null, null, null, null, null, 0x58, null],
["SEI", null, null, null, null, null, null, null, null, null, null, 0x78, null], ['SEI', null, null, null, null, null, null, null, null, null, null, 0x78, null],
["CLV", null, null, null, null, null, null, null, null, null, null, 0xb8, null], ['CLV', null, null, null, null, null, null, null, null, null, null, 0xb8, null],
["CLD", null, null, null, null, null, null, null, null, null, null, 0xd8, null], ['CLD', null, null, null, null, null, null, null, null, null, null, 0xd8, null],
["SED", null, null, null, null, null, null, null, null, null, null, 0xf8, null], ['SED', null, null, null, null, null, null, null, null, null, null, 0xf8, null],
["INC", null, 0xe6, 0xf6, null, 0xee, 0xfe, null, null, null, null, null, null], ['INC', null, 0xe6, 0xf6, null, 0xee, 0xfe, null, null, null, null, null, null],
["JMP", null, null, null, null, 0x4c, null, null, 0x6c, null, null, null, null], ['JMP', null, null, null, null, 0x4c, null, null, 0x6c, null, null, null, null],
["JSR", null, null, null, null, 0x20, null, null, null, null, null, null, null], ['JSR', null, null, null, null, 0x20, null, null, null, null, null, null, null],
["LDA", 0xa9, 0xa5, 0xb5, null, 0xad, 0xbd, 0xb9, null, 0xa1, 0xb1, null, null], ['LDA', 0xa9, 0xa5, 0xb5, null, 0xad, 0xbd, 0xb9, null, 0xa1, 0xb1, null, null],
["LDX", 0xa2, 0xa6, null, 0xb6, 0xae, null, 0xbe, null, null, null, null, null], ['LDX', 0xa2, 0xa6, null, 0xb6, 0xae, null, 0xbe, null, null, null, null, null],
["LDY", 0xa0, 0xa4, 0xb4, null, 0xac, 0xbc, null, null, null, null, null, null], ['LDY', 0xa0, 0xa4, 0xb4, null, 0xac, 0xbc, null, null, null, null, null, null],
["LSR", null, 0x46, 0x56, null, 0x4e, 0x5e, null, null, null, null, 0x4a, null], ['LSR', null, 0x46, 0x56, null, 0x4e, 0x5e, null, null, null, null, 0x4a, null],
["NOP", null, null, null, null, null, null, null, null, null, null, 0xea, null], ['NOP', null, null, null, null, null, null, null, null, null, null, 0xea, null],
["ORA", 0x09, 0x05, 0x15, null, 0x0d, 0x1d, 0x19, null, 0x01, 0x11, null, null], ['ORA', 0x09, 0x05, 0x15, null, 0x0d, 0x1d, 0x19, null, 0x01, 0x11, null, null],
["TAX", null, null, null, null, null, null, null, null, null, null, 0xaa, null], ['TAX', null, null, null, null, null, null, null, null, null, null, 0xaa, null],
["TXA", null, null, null, null, null, null, null, null, null, null, 0x8a, null], ['TXA', null, null, null, null, null, null, null, null, null, null, 0x8a, null],
["DEX", null, null, null, null, null, null, null, null, null, null, 0xca, null], ['DEX', null, null, null, null, null, null, null, null, null, null, 0xca, null],
["INX", null, null, null, null, null, null, null, null, null, null, 0xe8, null], ['INX', null, null, null, null, null, null, null, null, null, null, 0xe8, null],
["TAY", null, null, null, null, null, null, null, null, null, null, 0xa8, null], ['TAY', null, null, null, null, null, null, null, null, null, null, 0xa8, null],
["TYA", null, null, null, null, null, null, null, null, null, null, 0x98, null], ['TYA', null, null, null, null, null, null, null, null, null, null, 0x98, null],
["DEY", null, null, null, null, null, null, null, null, null, null, 0x88, null], ['DEY', null, null, null, null, null, null, null, null, null, null, 0x88, null],
["INY", null, null, null, null, null, null, null, null, null, null, 0xc8, null], ['INY', null, null, null, null, null, null, null, null, null, null, 0xc8, null],
["ROR", null, 0x66, 0x76, null, 0x6e, 0x7e, null, null, null, null, 0x6a, null], ['ROR', null, 0x66, 0x76, null, 0x6e, 0x7e, null, null, null, null, 0x6a, null],
["ROL", null, 0x26, 0x36, null, 0x2e, 0x3e, null, null, null, null, 0x2a, null], ['ROL', null, 0x26, 0x36, null, 0x2e, 0x3e, null, null, null, null, 0x2a, null],
["RTI", null, null, null, null, null, null, null, null, null, null, 0x40, null], ['RTI', null, null, null, null, null, null, null, null, null, null, 0x40, null],
["RTS", null, null, null, null, null, null, null, null, null, null, 0x60, null], ['RTS', null, null, null, null, null, null, null, null, null, null, 0x60, null],
["SBC", 0xe9, 0xe5, 0xf5, null, 0xed, 0xfd, 0xf9, null, 0xe1, 0xf1, null, null], ['SBC', 0xe9, 0xe5, 0xf5, null, 0xed, 0xfd, 0xf9, null, 0xe1, 0xf1, null, null],
["STA", null, 0x85, 0x95, null, 0x8d, 0x9d, 0x99, null, 0x81, 0x91, null, null], ['STA', null, 0x85, 0x95, null, 0x8d, 0x9d, 0x99, null, 0x81, 0x91, null, null],
["TXS", null, null, null, null, null, null, null, null, null, null, 0x9a, null], ['TXS', null, null, null, null, null, null, null, null, null, null, 0x9a, null],
["TSX", null, null, null, null, null, null, null, null, null, null, 0xba, null], ['TSX', null, null, null, null, null, null, null, null, null, null, 0xba, null],
["PHA", null, null, null, null, null, null, null, null, null, null, 0x48, null], ['PHA', null, null, null, null, null, null, null, null, null, null, 0x48, null],
["PLA", null, null, null, null, null, null, null, null, null, null, 0x68, null], ['PLA', null, null, null, null, null, null, null, null, null, null, 0x68, null],
["PHP", null, null, null, null, null, null, null, null, null, null, 0x08, null], ['PHP', null, null, null, null, null, null, null, null, null, null, 0x08, null],
["PLP", null, null, null, null, null, null, null, null, null, null, 0x28, null], ['PLP', null, null, null, null, null, null, null, null, null, null, 0x28, null],
["STX", null, 0x86, null, 0x96, 0x8e, null, null, null, null, null, null, null], ['STX', null, 0x86, null, 0x96, 0x8e, null, null, null, null, null, null, null],
["STY", null, 0x84, 0x94, null, 0x8c, null, null, null, null, null, null, null], ['STY', null, 0x84, 0x94, null, 0x8c, null, null, null, null, null, null, null],
["WDM", 0x42, 0x42, null, null, null, null, null, null, null, null, null, null], ['WDM', 0x42, 0x42, null, null, null, null, null, null, null, null, null, null],
["---", null, null, null, null, null, null, null, null, null, null, null, null] ['---', null, null, null, null, null, null, null, null, null, null, null, null]
]; ];
// Assembles the code into memory // Assembles the code into memory
function assembleCode() { function assembleCode() {
var BOOTSTRAP_ADDRESS = 0x600; var BOOTSTRAP_ADDRESS = 0x600;
wasOutOfRangeBranch = false; wasOutOfRangeBranch = false;
simulator.reset(); simulator.reset();
labels.reset(); labels.reset();
defaultCodePC = BOOTSTRAP_ADDRESS; defaultCodePC = BOOTSTRAP_ADDRESS;
$node.find('.messages code').empty(); $node.find('.messages code').empty();
var code = $node.find('.code').val(); var code = $node.find('.code').val();
code += "\n\n"; code += '\n\n';
var lines = code.split("\n"); var lines = code.split('\n');
codeAssembledOK = true; codeAssembledOK = true;
message("Preprocessing ..."); message('Preprocessing ...');
var symbols = preprocess(lines); var symbols = preprocess(lines);
message("Indexing labels ..."); message('Indexing labels ...');
defaultCodePC = BOOTSTRAP_ADDRESS; defaultCodePC = BOOTSTRAP_ADDRESS;
if (!labels.indexLines(lines, symbols)) { if (!labels.indexLines(lines, symbols)) {
return false; return false;
@ -1917,8 +1917,8 @@ function SimulatorWidget(node) {
labels.displayMessage(); labels.displayMessage();
defaultCodePC = BOOTSTRAP_ADDRESS; defaultCodePC = BOOTSTRAP_ADDRESS;
message("Assembling code ..."); message('Assembling code ...');
codeLen = 0; codeLen = 0;
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
if (!assembleLine(lines[i], i, symbols)) { if (!assembleLine(lines[i], i, symbols)) {
@ -1929,7 +1929,7 @@ function SimulatorWidget(node) {
if (codeLen === 0) { if (codeLen === 0) {
codeAssembledOK = false; codeAssembledOK = false;
message("No code to run."); message('No code to run.');
} }
if (codeAssembledOK) { if (codeAssembledOK) {
@ -1937,10 +1937,10 @@ function SimulatorWidget(node) {
memory.set(defaultCodePC, 0x00); //set a null byte at the end of the code memory.set(defaultCodePC, 0x00); //set a null byte at the end of the code
} else { } else {
var str = lines[i].replace("<", "&lt;").replace(">", "&gt;"); var str = lines[i].replace('<', '&lt;').replace('>', '&gt;');
if(!wasOutOfRangeBranch) { if(!wasOutOfRangeBranch) {
message("**Syntax error line " + (i + 1) + ": " + str + "**"); message('**Syntax error line ' + (i + 1) + ': ' + str + '**');
} else { } else {
message('**Out of range branch on line ' + (i + 1) + ' (branches are limited to -128 to +127): ' + str + '**'); message('**Out of range branch on line ' + (i + 1) + ' (branches are limited to -128 to +127): ' + str + '**');
} }
@ -1949,51 +1949,51 @@ function SimulatorWidget(node) {
return false; return false;
} }
message("Code assembled successfully, " + codeLen + " bytes."); message('Code assembled successfully, ' + codeLen + ' bytes.');
return true; return true;
} }
// Sanitize input: remove comments and trim leading/trailing whitespace // Sanitize input: remove comments and trim leading/trailing whitespace
function sanitize(line) { function sanitize(line) {
// remove comments // remove comments
var no_comments = line.replace(/^(.*?);.*/, "$1"); var no_comments = line.replace(/^(.*?);.*/, '$1');
// trim line // trim line
return no_comments.replace(/^\s+/, "").replace(/\s+$/, ""); return no_comments.replace(/^\s+/, '').replace(/\s+$/, '');
} }
function preprocess(lines) { function preprocess(lines) {
var table = []; var table = [];
var PREFIX = "__"; // Using a prefix avoids clobbering any predefined properties var PREFIX = '__'; // Using a prefix avoids clobbering any predefined properties
function lookup(key) { function lookup(key) {
if (table.hasOwnProperty(PREFIX + key)) return table[PREFIX + key]; if (table.hasOwnProperty(PREFIX + key)) return table[PREFIX + key];
else return undefined; else return undefined;
} }
function add(key, value) { function add(key, value) {
var valueAlreadyExists = table.hasOwnProperty(PREFIX + key) var valueAlreadyExists = table.hasOwnProperty(PREFIX + key)
if (!valueAlreadyExists) { if (!valueAlreadyExists) {
table[PREFIX + key] = value; table[PREFIX + key] = value;
} }
} }
// Build the substitution table // Build the substitution table
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
lines[i] = sanitize(lines[i]); lines[i] = sanitize(lines[i]);
var match_data = lines[i].match(/^define\s+(\w+)\s+(\S+)/); var match_data = lines[i].match(/^define\s+(\w+)\s+(\S+)/);
if (match_data) { if (match_data) {
add(match_data[1], sanitize(match_data[2])); add(match_data[1], sanitize(match_data[2]));
lines[i] = ""; // We're done with this preprocessor directive, so delete it lines[i] = ''; // We're done with this preprocessor directive, so delete it
} }
} }
// Callers will only need the lookup function // Callers will only need the lookup function
return { return {
lookup: lookup lookup: lookup
} }
} }
// Assembles one line of code. // Assembles one line of code.
// Returns true if it assembled successfully, false otherwise. // Returns true if it assembled successfully, false otherwise.
function assembleLine(input, lineno, symbols) { function assembleLine(input, lineno, symbols) {
@ -2001,19 +2001,19 @@ function SimulatorWidget(node) {
// Find command or label // Find command or label
if (input.match(/^\w+:/)) { if (input.match(/^\w+:/)) {
label = input.replace(/(^\w+):.*$/, "$1"); label = input.replace(/(^\w+):.*$/, '$1');
if (input.match(/^\w+:[\s]*\w+.*$/)) { if (input.match(/^\w+:[\s]*\w+.*$/)) {
input = input.replace(/^\w+:[\s]*(.*)$/, "$1"); input = input.replace(/^\w+:[\s]*(.*)$/, '$1');
command = input.replace(/^(\w+).*$/, "$1"); command = input.replace(/^(\w+).*$/, '$1');
} else { } else {
command = ""; command = '';
} }
} else { } else {
command = input.replace(/^(\w+).*$/, "$1"); command = input.replace(/^(\w+).*$/, '$1');
} }
// Nothing to do for blank lines // Nothing to do for blank lines
if (command === "") { if (command === '') {
return true; return true;
} }
@ -2021,15 +2021,15 @@ function SimulatorWidget(node) {
if (input.match(/^\*\s*=\s*\$?[0-9a-f]*$/)) { if (input.match(/^\*\s*=\s*\$?[0-9a-f]*$/)) {
// equ spotted // equ spotted
param = input.replace(/^\s*\*\s*=\s*/, ""); param = input.replace(/^\s*\*\s*=\s*/, '');
if (param[0] === "$") { if (param[0] === '$') {
param = param.replace(/^\$/, ""); param = param.replace(/^\$/, '');
addr = parseInt(param, 16); addr = parseInt(param, 16);
} else { } else {
addr = parseInt(param, 10); addr = parseInt(param, 10);
} }
if ((addr < 0) || (addr > 0xffff)) { if ((addr < 0) || (addr > 0xffff)) {
message("Unable to relocate code outside 64k memory"); message('Unable to relocate code outside 64k memory');
return false; return false;
} }
defaultCodePC = addr; defaultCodePC = addr;
@ -2037,16 +2037,16 @@ function SimulatorWidget(node) {
} }
if (input.match(/^\w+\s+.*?$/)) { if (input.match(/^\w+\s+.*?$/)) {
param = input.replace(/^\w+\s+(.*?)/, "$1"); param = input.replace(/^\w+\s+(.*?)/, '$1');
} else if (input.match(/^\w+$/)) { } else if (input.match(/^\w+$/)) {
param = ""; param = '';
} else { } else {
return false; return false;
} }
param = param.replace(/[ ]/g, ""); param = param.replace(/[ ]/g, '');
if (command === "DCB") { if (command === 'DCB') {
return DCB(param); return DCB(param);
} }
for (var o = 0; o < Opcodes.length; o++) { for (var o = 0; o < Opcodes.length; o++) {
@ -2065,22 +2065,22 @@ function SimulatorWidget(node) {
if (checkBranch(param, Opcodes[o][12])) { return true; } if (checkBranch(param, Opcodes[o][12])) { return true; }
} }
} }
return false; // Unknown syntax return false; // Unknown syntax
} }
function DCB(param) { function DCB(param) {
var values, number, str, ch; var values, number, str, ch;
values = param.split(","); values = param.split(',');
if (values.length === 0) { return false; } if (values.length === 0) { return false; }
for (var v = 0; v < values.length; v++) { for (var v = 0; v < values.length; v++) {
str = values[v]; str = values[v];
if (str) { if (str) {
ch = str.substring(0, 1); ch = str.substring(0, 1);
if (ch === "$") { if (ch === '$') {
number = parseInt(str.replace(/^\$/, ""), 16); number = parseInt(str.replace(/^\$/, ''), 16);
pushByte(number); pushByte(number);
} else if (ch >= "0" && ch <= "9") { } else if (ch >= '0' && ch <= '9') {
number = parseInt(str, 10); number = parseInt(str, 10);
pushByte(number); pushByte(number);
} else { } else {
@ -2090,7 +2090,7 @@ function SimulatorWidget(node) {
} }
return true; return true;
} }
// Try to parse the given parameter as a byte operand. // Try to parse the given parameter as a byte operand.
// Returns the (positive) value if successful, otherwise -1 // Returns the (positive) value if successful, otherwise -1
function tryParseByteOperand(param, symbols) { function tryParseByteOperand(param, symbols) {
@ -2100,9 +2100,9 @@ function SimulatorWidget(node) {
param = lookupVal; param = lookupVal;
} }
} }
var value; var value;
// Is it a hexadecimal operand? // Is it a hexadecimal operand?
var match_data = param.match(/^\$([0-9a-f]{1,2})$/i); var match_data = param.match(/^\$([0-9a-f]{1,2})$/i);
if (match_data) { if (match_data) {
@ -2114,15 +2114,15 @@ function SimulatorWidget(node) {
value = parseInt(match_data[1], 10); value = parseInt(match_data[1], 10);
} }
} }
// Validate range // Validate range
if (value >= 0 && value <= 0xff) { if (value >= 0 && value <= 0xff) {
return value; return value;
} else { } else {
return -1; return -1;
} }
} }
// Try to parse the given parameter as a word operand. // Try to parse the given parameter as a word operand.
// Returns the (positive) value if successful, otherwise -1 // Returns the (positive) value if successful, otherwise -1
function tryParseWordOperand(param, symbols) { function tryParseWordOperand(param, symbols) {
@ -2132,9 +2132,9 @@ function SimulatorWidget(node) {
param = lookupVal; param = lookupVal;
} }
} }
var value; var value;
// Is it a hexadecimal operand? // Is it a hexadecimal operand?
var match_data = param.match(/^\$([0-9a-f]{3,4})$/i); var match_data = param.match(/^\$([0-9a-f]{3,4})$/i);
if (match_data) { if (match_data) {
@ -2146,7 +2146,7 @@ function SimulatorWidget(node) {
value = parseInt(match_data[1], 10); value = parseInt(match_data[1], 10);
} }
} }
// Validate range // Validate range
if (value >= 0 && value <= 0xffff) { if (value >= 0 && value <= 0xffff) {
return value; return value;
@ -2170,8 +2170,8 @@ function SimulatorWidget(node) {
var distance = addr - defaultCodePC - 1; var distance = addr - defaultCodePC - 1;
if(distance < -128 || distance > 127) { if(distance < -128 || distance > 127) {
wasOutOfRangeBranch = true; wasOutOfRangeBranch = true;
return false; return false;
} }
pushByte(distance); pushByte(distance);
@ -2182,7 +2182,7 @@ function SimulatorWidget(node) {
function checkImmediate(param, opcode, symbols) { function checkImmediate(param, opcode, symbols) {
var value, label, hilo, addr; var value, label, hilo, addr;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^#([\w\$]+)$/i); var match_data = param.match(/^#([\w\$]+)$/i);
if (match_data) { if (match_data) {
var operand = tryParseByteOperand(match_data[1], symbols); var operand = tryParseByteOperand(match_data[1], symbols);
@ -2192,30 +2192,30 @@ function SimulatorWidget(node) {
return true; return true;
} }
} }
// Label lo/hi // Label lo/hi
if (param.match(/^#[<>]\w+$/)) { if (param.match(/^#[<>]\w+$/)) {
label = param.replace(/^#[<>](\w+)$/, "$1"); label = param.replace(/^#[<>](\w+)$/, '$1');
hilo = param.replace(/^#([<>]).*$/, "$1"); hilo = param.replace(/^#([<>]).*$/, '$1');
pushByte(opcode); pushByte(opcode);
if (labels.find(label)) { if (labels.find(label)) {
addr = labels.getPC(label); addr = labels.getPC(label);
switch(hilo) { switch(hilo) {
case ">": case '>':
pushByte((addr >> 8) & 0xff); pushByte((addr >> 8) & 0xff);
return true; return true;
case "<": case '<':
pushByte(addr & 0xff); pushByte(addr & 0xff);
return true; return true;
default: default:
return false; return false;
} }
} else { } else {
pushByte(0x00); pushByte(0x00);
return true; return true;
} }
} }
return false; return false;
} }
@ -2223,7 +2223,7 @@ function SimulatorWidget(node) {
function checkIndirect(param, opcode, symbols) { function checkIndirect(param, opcode, symbols) {
var value; var value;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^\(([\w\$]+)\)$/i); var match_data = param.match(/^\(([\w\$]+)\)$/i);
if (match_data) { if (match_data) {
var operand = tryParseWordOperand(match_data[1], symbols); var operand = tryParseWordOperand(match_data[1], symbols);
@ -2240,7 +2240,7 @@ function SimulatorWidget(node) {
function checkIndirectX(param, opcode, symbols) { function checkIndirectX(param, opcode, symbols) {
var value; var value;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^\(([\w\$]+),X\)$/i); var match_data = param.match(/^\(([\w\$]+),X\)$/i);
if (match_data) { if (match_data) {
var operand = tryParseByteOperand(match_data[1], symbols); var operand = tryParseByteOperand(match_data[1], symbols);
@ -2257,7 +2257,7 @@ function SimulatorWidget(node) {
function checkIndirectY(param, opcode, symbols) { function checkIndirectY(param, opcode, symbols) {
var value; var value;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^\(([\w\$]+)\),Y$/i); var match_data = param.match(/^\(([\w\$]+)\),Y$/i);
if (match_data) { if (match_data) {
var operand = tryParseByteOperand(match_data[1], symbols); var operand = tryParseByteOperand(match_data[1], symbols);
@ -2274,7 +2274,7 @@ function SimulatorWidget(node) {
function checkSingle(param, opcode) { function checkSingle(param, opcode) {
if (opcode === null) { return false; } if (opcode === null) { return false; }
// Accumulator instructions are counted as single-byte opcodes // Accumulator instructions are counted as single-byte opcodes
if (param !== "" && param !== "A") { return false; } if (param !== '' && param !== 'A') { return false; }
pushByte(opcode); pushByte(opcode);
return true; return true;
} }
@ -2290,7 +2290,7 @@ function SimulatorWidget(node) {
pushByte(operand); pushByte(operand);
return true; return true;
} }
return false; return false;
} }
@ -2298,7 +2298,7 @@ function SimulatorWidget(node) {
function checkAbsoluteX(param, opcode, symbols) { function checkAbsoluteX(param, opcode, symbols) {
var number, value, addr; var number, value, addr;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^([\w\$]+),X$/i); var match_data = param.match(/^([\w\$]+),X$/i);
if (match_data) { if (match_data) {
var operand = tryParseWordOperand(match_data[1], symbols); var operand = tryParseWordOperand(match_data[1], symbols);
@ -2311,7 +2311,7 @@ function SimulatorWidget(node) {
// it could be a label too.. // it could be a label too..
if (param.match(/^\w+,X$/i)) { if (param.match(/^\w+,X$/i)) {
param = param.replace(/,X$/i, ""); param = param.replace(/,X$/i, '');
pushByte(opcode); pushByte(opcode);
if (labels.find(param)) { if (labels.find(param)) {
addr = labels.getPC(param); addr = labels.getPC(param);
@ -2331,7 +2331,7 @@ function SimulatorWidget(node) {
function checkAbsoluteY(param, opcode, symbols) { function checkAbsoluteY(param, opcode, symbols) {
var number, value, addr; var number, value, addr;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^([\w\$]+),Y$/i); var match_data = param.match(/^([\w\$]+),Y$/i);
if (match_data) { if (match_data) {
var operand = tryParseWordOperand(match_data[1], symbols); var operand = tryParseWordOperand(match_data[1], symbols);
@ -2344,7 +2344,7 @@ function SimulatorWidget(node) {
// it could be a label too.. // it could be a label too..
if (param.match(/^\w+,Y$/i)) { if (param.match(/^\w+,Y$/i)) {
param = param.replace(/,Y$/i, ""); param = param.replace(/,Y$/i, '');
pushByte(opcode); pushByte(opcode);
if (labels.find(param)) { if (labels.find(param)) {
addr = labels.getPC(param); addr = labels.getPC(param);
@ -2363,7 +2363,7 @@ function SimulatorWidget(node) {
function checkZeroPageX(param, opcode, symbols) { function checkZeroPageX(param, opcode, symbols) {
var number, value; var number, value;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^([\w\$]+),X$/i); var match_data = param.match(/^([\w\$]+),X$/i);
if (match_data) { if (match_data) {
var operand = tryParseByteOperand(match_data[1], symbols); var operand = tryParseByteOperand(match_data[1], symbols);
@ -2373,7 +2373,7 @@ function SimulatorWidget(node) {
return true; return true;
} }
} }
return false; return false;
} }
@ -2381,7 +2381,7 @@ function SimulatorWidget(node) {
function checkZeroPageY(param, opcode, symbols) { function checkZeroPageY(param, opcode, symbols) {
var number, value; var number, value;
if (opcode === null) { return false; } if (opcode === null) { return false; }
var match_data = param.match(/^([\w\$]+),Y$/i); var match_data = param.match(/^([\w\$]+),Y$/i);
if (match_data) { if (match_data) {
var operand = tryParseByteOperand(match_data[1], symbols); var operand = tryParseByteOperand(match_data[1], symbols);
@ -2391,7 +2391,7 @@ function SimulatorWidget(node) {
return true; return true;
} }
} }
return false; return false;
} }
@ -2637,7 +2637,7 @@ function SimulatorWidget(node) {
} }
function num2hex(nr) { function num2hex(nr) {
var str = "0123456789abcdef"; var str = '0123456789abcdef';
var hi = ((nr & 0xf0) >> 4); var hi = ((nr & 0xf0) >> 4);
var lo = (nr & 15); var lo = (nr & 15);
return str.substring(hi, hi + 1) + str.substring(lo, lo + 1); return str.substring(hi, hi + 1) + str.substring(lo, lo + 1);
@ -2645,7 +2645,7 @@ function SimulatorWidget(node) {
// Prints text in the message window // Prints text in the message window
function message(text) { function message(text) {
if (text.length>1) if (text.length > 1)
text += '\n'; // allow putc operations from the simulator (WDM opcode) text += '\n'; // allow putc operations from the simulator (WDM opcode)
$node.find('.messages code').append(text).scrollTop(10000); $node.find('.messages code').append(text).scrollTop(10000);
} }

File diff suppressed because it is too large Load Diff

1194
app/lib/64spec.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
assets/6502Desktop_SS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -19,7 +19,7 @@ function createWindow () {
if(process.platform === 'darwin') { if(process.platform === 'darwin') {
Menu.setApplicationMenu(Menu.buildFromTemplate(OSXtemplate)) Menu.setApplicationMenu(Menu.buildFromTemplate(OSXtemplate))
} else if(process.platform !== 'darwin') { } else if(process.platform !== 'darwin') {
BrowserWindow.setMenu(Menu.buildFromTemplate(PCtemplate)) mainWindow.setMenu(Menu.buildFromTemplate(PCtemplate))
} }
mainWindow.on('closed', function () { mainWindow.on('closed', function () {

View File

@ -6,16 +6,15 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"start": "electron .", "start": "electron .",
"dev": "NODE_ENV='development' electron .",
"pack-mac": "electron-packager . 6502Desktop --asar.unpack=protocol-link.html --overwrite --platform=darwin --arch=x64 --icon=assets/mac/app.icns --out=out --osx-sign.identity='Developer ID Application: 3DEsprit' --appBundleId='6502Desktop' appCategoryType=public.app-category.education", "pack-mac": "electron-packager . 6502Desktop --asar.unpack=protocol-link.html --overwrite --platform=darwin --arch=x64 --icon=assets/mac/app.icns --out=out --osx-sign.identity='Developer ID Application: 3DEsprit' --appBundleId='6502Desktop' appCategoryType=public.app-category.education",
"pack-win": "electron-packager . --asar.unpack=protocol-link.html --overwrite --platform=win32 --arch=ia32 --icon=assets/win/app.ico --out=out --version-string.CompanyName='3DEsprit' --version-string.FileDescription='6502 Simulator Desktop' --version-string.ProductName='6502 Simulator Desktop'", "pack-win": "electron-packager . 6502Desktop --asar.unpack=protocol-link.html --overwrite --platform=win32 --arch=x64 --icon=assets/win/app.ico --out=out",
"pack-linux": "electron-packager . --asar.unpack=protocol-link.html --overwrite --platform=linux --arch=x64 --out=out" "pack-linux": "electron-packager . 6502Desktop --asar.unpack=protocol-link.html --overwrite --platform=linux --arch=x64 --out=out --prune=true"
}, },
"author": "DBrown", "author": "DBrown",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"electron": "^1.6.2", "electron": "^18.3.7"
"electron-debug": "^1.1.0",
"electron-prebuilt": "^1.4.13"
}, },
"devDependencies": {} "devDependencies": {}
} }

1183
yarn.lock

File diff suppressed because it is too large Load Diff