code cleanup

This commit is contained in:
Dennis Brown 2018-03-01 21:30:29 -06:00
parent 824cd8c56b
commit e4f1f9f03f
1 changed files with 185 additions and 185 deletions

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);
} }