new buttons; better DASM listing; fixed dbg btns; removed menu

This commit is contained in:
Steven Hugg 2017-01-16 10:35:19 -05:00
parent 0fca237979
commit 1fa51ae5d4
16 changed files with 92 additions and 81 deletions

View File

@ -366,7 +366,7 @@ span.CodeMirror-selectedtext { background: none; }
.cm-s-mbo span.cm-comment { color: #95958a; }
.cm-s-mbo span.cm-atom { color: #00a8c6; }
.cm-s-mbo span.cm-number { color: #00a8c6; }
.cm-s-mbo span.cm-number { color: #33aadd; }
.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; }
.cm-s-mbo span.cm-keyword { color: #ffb928; }
@ -376,7 +376,7 @@ span.CodeMirror-selectedtext { background: none; }
.cm-s-mbo span.cm-variable { color: #ffffec; }
.cm-s-mbo span.cm-variable-2 { color: #00a8c6; }
.cm-s-mbo span.cm-variable-3 { color: #ffb928; }
.cm-s-mbo span.cm-def { color: #ffff88; }
.cm-s-mbo span.cm-def { color: #88eeff; }
.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; }
.cm-s-mbo span.cm-tag { color: #9ddfe9; }
.cm-s-mbo span.cm-link { color: #f54b07; }
@ -414,3 +414,7 @@ span.CodeMirror-selectedtext { background: none; }
.cm-s-cobalt .CodeMirror-activeline-background { background: #003399; }
.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
/*** FIXES FOR BOOTSTRAP ***/
.CodeMirror-dialog > button { background-color: #333 !important; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

View File

@ -186,6 +186,7 @@ canvas.pixelated {
<li><a class="dropdown-item" href="#" id="item_new_file">New File...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share File...</a></li>
<li><a class="dropdown-item" href="#" id="item_reset_file">Revert to Original...</a></li>
<!--
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
<ul class="dropdown-menu">
@ -195,6 +196,7 @@ canvas.pixelated {
<li><a class="dropdown-item" href="?platform=spaceinv" id="item_platform_spaceinv">Space Invaders</a></li>
</ul>
</li>
-->
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Debug</a>
<ul class="dropdown-menu">
@ -206,15 +208,15 @@ canvas.pixelated {
<select id="preset_select" name="">
</select>
<span id="debug_bar">
<button id="dbg_pause" type="button" title="Pause"><img src="images/pause.png"></button>
<button id="dbg_go" type="button" title="Run"><img src="images/play.png"></button>
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
<button id="dbg_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
<button id="dbg_stepout" type="submit" title="Step Out of Subroutine">RTS</button>
<button id="dbg_stepback" type="submit" title="Step Backwards">&lt;&lt;</button>
<button id="dbg_reset" type="submit" title="Reset and Break"><img src="images/resetandrun.png"></button>
<button id="dbg_timing" type="submit" title="See Timing" style="display:none"><img src="images/timing.png"></button>
<button id="dbg_disasm" type="submit" title="Toggle Disassembly">#</button>
<button id="dbg_reset" type="submit" title="Reset and Break"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
<button id="dbg_pause" type="button" title="Pause"><span class="glyphicon glyphicon-pause" aria-hidden="true"></span></button>
<button id="dbg_go" type="button" title="Run"><span class="glyphicon glyphicon-play" aria-hidden="true"></span></button>
<button id="dbg_step" type="submit" title="Step"><span class="glyphicon glyphicon-step-forward" aria-hidden="true"></span></button>
<button id="dbg_toline" type="submit" title="Run To Line"><span class="glyphicon glyphicon-save" aria-hidden="true"></span></button>
<button id="dbg_stepout" type="submit" title="Step Out of Subroutine"><span class="glyphicon glyphicon-hand-left" aria-hidden="true"></span></button>
<button id="dbg_stepback" type="submit" title="Step Backwards"><span class="glyphicon glyphicon-step-backward" aria-hidden="true"></span></button>
<button id="dbg_timing" type="submit" title="See Timing" style="display:none"><span class="glyphicon glyphicon-time" aria-hidden="true"></span></button>
<button id="dbg_disasm" type="submit" title="Toggle Disassembly" style="display:none"><span class="glyphicon glyphicon-list" aria-hidden="true"></span></button>
</span>
<span class="dbg_info" id="dbg_info"></span>
</div>

View File

@ -1,6 +1,6 @@
{
"name": "8bitworkshop",
"version": "0.0.1",
"version": "0.0.2",
"author": "Steven Hugg",
"dependencies": {},
"devDependencies": {

View File

@ -630,6 +630,8 @@ var BaseZ80Platform = function() {
if (fn.endsWith(".s")) return "sdasz80";
return "z80asm";
}
// TODO
//this.getOpcodeMetadata = function() { }
}
function padBytes(data, len) {

View File

@ -15,7 +15,7 @@ var SpaceInvadersPlatform = function(mainElement) {
this.__proto__ = new BaseZ80Platform();
var cpu, ram, membus, iobus, rom;
var video, audio, timer, pixels, displayPCs;
var video, timer, pixels, displayPCs;
var inputs = [0xe,0x8,0x0];
var bitshift_offset = 0;
var bitshift_register = 0;
@ -38,16 +38,6 @@ var SpaceInvadersPlatform = function(mainElement) {
50:{i:1,b:1}, // 2
}
this.getOpcodeMetadata = function() {
return {
opcode:0,
mnenomic:'?',
minCycles:0,
maxCycles:0,
insnlength:1
};
}
this.getPresets = function() {
return SPACEINV_PRESETS;
}
@ -58,10 +48,10 @@ var SpaceInvadersPlatform = function(mainElement) {
membus = {
read: function(address) {
if (address < 0x2000) {
return rom ? rom[address] : 0;
return (rom ? rom[address] : 0) & 0xff;
} else {
address &= 0x1fff;
return ram.mem[address];
return ram.mem[address] & 0xff;
}
},
write: function(address, value) {
@ -122,7 +112,6 @@ var SpaceInvadersPlatform = function(mainElement) {
ioBus: iobus
});
video = new RasterVideo(mainElement,256,224,{rotate:-90});
audio = new SampleAudio(cpuFrequency);
video.create();
$(video.canvas).click(function(e) {
var x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width());
@ -215,11 +204,9 @@ var SpaceInvadersPlatform = function(mainElement) {
}
this.pause = function() {
timer.stop();
audio.stop();
}
this.resume = function() {
timer.start();
audio.start();
}
this.reset = function() {
cpu.reset();

View File

@ -42,8 +42,6 @@ var VCSPlatform = function() {
this.getPresets = function() { return VCS_PRESETS; }
this.start = function() {
$("#dbg_timing").show();
$("#dbg_disasm").show();
Javatari.start();
}

View File

@ -74,7 +74,7 @@ var SourceFile = function(lines, text) {
}
this.findLineForOffset = function(PC) {
if (this.offset2line) {
for (var i=0; i<256; i++) {
for (var i=0; i<16; i++) {
var line = this.offset2line[PC];
if (line >= 0) {
return line;
@ -200,17 +200,9 @@ function gotoPresetAt(index) {
}
function gotoPresetNamed(id) {
if (id.startsWith("_")) {
var result = eval(id+"()");
console.log(id, result);
if (!result) {
updateSelector();
}
} else {
qs['platform'] = platform_id;
qs['file'] = id;
window.location = "?" + $.param(qs);
}
qs['platform'] = platform_id;
qs['file'] = id;
window.location = "?" + $.param(qs);
}
function _createNewFile(e) {
@ -263,7 +255,7 @@ function _resetPreset(e) {
}
function populateExamples(sel) {
sel.append($("<option />").text("--------- Chapters ---------"));
sel.append($("<option />").text("--------- Chapters ---------").attr('disabled',true));
for (var i=0; i<PRESETS.length; i++) {
var preset = PRESETS[i];
var name = preset.chapter + ". " + preset.name;
@ -272,7 +264,7 @@ function populateExamples(sel) {
}
function populateLocalFiles(sel) {
sel.append($("<option />").text("------- Local Files -------"));
sel.append($("<option />").text("------- Local Files -------").attr('disabled',true));
var filenames = store.getFiles("local/");
for (var i = 0; i < filenames.length; i++) {
var name = filenames[i];
@ -282,7 +274,7 @@ function populateLocalFiles(sel) {
}
function populateSharedFiles(sel) {
sel.append($("<option />").text("--------- Shared ---------"));
sel.append($("<option />").text("--------- Shared ---------").attr('disabled',true));
var filenames = store.getFiles("shared/");
for (var i = 0; i < filenames.length; i++) {
var name = filenames[i];
@ -354,13 +346,15 @@ worker.onmessage = function(e) {
var rom_changed = rom && !arrayCompare(rom, current_output);
if (rom_changed) {
try {
resume();
//console.log("Loading ROM length", rom.length);
platform.loadROM(getCurrentPresetTitle(), rom);
resume();
// TODO: what if loadROM fails?
current_output = rom;
pcvisits = {};
} catch (e) {
console.log(e); // TODO
console.log(e); // TODO: show error
alert("Could not load ROM: " + e);
current_output = null;
}
}
@ -381,10 +375,12 @@ worker.onmessage = function(e) {
editor.setGutterMarker(info.line-1, "gutter-bytes", textel);
if (info.iscode) {
var opcode = parseInt(info.insns.split()[0], 16);
var meta = platform.getOpcodeMetadata(opcode, info.offset);
var clockstr = meta.minCycles+"";
var textel = document.createTextNode(clockstr);
editor.setGutterMarker(info.line-1, "gutter-clock", textel);
if (platform.getOpcodeMetadata) {
var meta = platform.getOpcodeMetadata(opcode, info.offset);
var clockstr = meta.minCycles+"";
var textel = document.createTextNode(clockstr);
editor.setGutterMarker(info.line-1, "gutter-clock", textel);
}
}
}
}
@ -497,8 +493,8 @@ function getCurrentLine() {
function runToCursor() {
setupBreakpoint();
var line = sourcefile.getCurrentLine();
var pc = line2offset[line];
var line = getCurrentLine();
var pc = sourcefile.line2offset[line];
if (pc >= 0) {
console.log("Run to", line, pc.toString(16));
platform.runEval(function(c) {
@ -678,8 +674,8 @@ function showLoopTimingForPC(pc) {
// recurse through all traces
_traceInstructions(pc | platform.getOriginPC(), MAX_CLOCKS, MAX_CLOCKS);
// show the lines
for (var line in line2offset) {
var pc = line2offset[line];
for (var line in sourcefile.line2offset) {
var pc = sourcefile.line2offset[line];
var minclocks = pc2minclocks[pc];
var maxclocks = pc2maxclocks[pc];
if (minclocks>=0 && maxclocks>=0) {
@ -774,8 +770,10 @@ function toggleDisassembly() {
function resetAndDebug() {
clearBreakpoint();
platform.resume();
platform.reset();
platform.breakpointHit();
setupBreakpoint();
platform.runEval(function(c) { return true; });
}
function _breakExpression() {
@ -795,11 +793,13 @@ function setupDebugControls(){
$("#dbg_toline").click(runToCursor);
$("#dbg_stepout").click(runUntilReturn);
$("#dbg_stepback").click(runStepBackwards);
$("#dbg_timing").click(traceTiming);
if (platform.disassemble)
$("#dbg_disasm").click(toggleDisassembly);
else
$("#dbg_disasm").hide();
// TODO: vcs platform seems to show them regardless
if (platform_id == 'vcs') {
$("#dbg_timing").click(traceTiming).show();
}
if (platform.disassemble) {
$("#dbg_disasm").click(toggleDisassembly).show();
}
$("#disassembly").hide();
$(".dropdown-menu").collapse({toggle: false});
$("#item_new_file").click(_createNewFile);
@ -869,17 +869,19 @@ function startPlatform() {
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
store = new FileStore(localStorage, platform_id + '/');
PRESETS = platform.getPresets();
setupDebugControls();
platform.start();
if (qs['file']) {
// load file
// start platform and load file
setupDebugControls();
platform.start();
loadPreset(qs['file']);
updateSelector();
return true;
} else {
// try to load last file
// try to load last file (redirect)
var lastid = localStorage.getItem("__lastid_"+platform_id) || localStorage.getItem("__lastid");
localStorage.removeItem("__lastid");
gotoPresetNamed(lastid || PRESETS[0].id);
return false;
}
}

View File

@ -71,17 +71,18 @@ var print_fn = function(s) {
}
// test.c(6) : warning 85: in function main unreferenced local variable : 'x'
var re_msvc = /(.*?)[(](\d+)[)]\s*:\s*(\w+)\s*(\d+):\s*(.*)/;
var re_msvc2 = /\s*at\s+(\d+)\s*:\s*(.*)/;
// main.a (4): error: Unknown Mnemonic 'xxx'.
var re_msvc = /([^(]+)\s*[(](\d+)[)]\s*:\s*(.+?):\s*(.*)/;
var re_msvc2 = /\s*(at)\s+(\d+)\s*(:)\s*(.*)/;
var msvc_errors;
function match_msvc(s) {
var matches = re_msvc.exec(s) || re_msvc2.exec(s);
if (matches) {
var errline = parseInt(matches[1]);
var errline = parseInt(matches[2]);
msvc_errors.push({
line:errline,
msg:matches[2]
msg:matches[4]
});
}
}
@ -129,9 +130,8 @@ function parseSourceLines(code, lineMatch, offsetMatch) {
}
function parseDASMListing(code, unresolved) {
var errorMatch = /main.a [(](\d+)[)]: error: (.+)/;
// 4 08ee a9 00 start lda #01workermain.js:23:5
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([0-9a-f][0-9a-f ]+)\s+(.+)/;
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([0-9a-f][0-9a-f ]+)?\s+(.+)?/;
var equMatch = /\bequ\b/;
var errors = [];
var lines = [];
@ -157,7 +157,7 @@ function parseDASMListing(code, unresolved) {
lastline = linenum;
} else {
// inside of macro or include file
if (linenum == -DASM_PREAMBLE_LINES) { // start of macro?
if (insns && linem[3] && lastline>0) {
lines.push({
line:lastline+1,
offset:offset,
@ -177,11 +177,11 @@ function parseDASMListing(code, unresolved) {
}
}
}
var errm = errorMatch.exec(line);
var errm = re_msvc.exec(line);
if (errm) {
errors.push({
line:parseInt(errm[1]),
msg:errm[2]
line:parseInt(errm[2]),
msg:errm[4]
})
}
}
@ -204,9 +204,10 @@ function assembleDASM(code) {
});
var FS = Module['FS'];
FS.writeFile(DASM_MAIN_FILENAME, DASM_PREAMBLE + code);
Module.callMain([DASM_MAIN_FILENAME, "-v3", "-la.lst"]);
Module.callMain([DASM_MAIN_FILENAME, "-la.lst"/*, "-v3", "-sa.sym"*/]);
var aout = FS.readFile("a.out");
var alst = FS.readFile("a.lst", {'encoding':'utf8'});
//var asym = FS.readFile("a.sym", {'encoding':'utf8'});
var listing = parseDASMListing(alst, unresolved);
return {
output:aout.slice(2),

View File

@ -80,28 +80,43 @@ describe('Worker', function() {
it('should assemble DASM', function(done) {
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo lda #0\n', 'vcs', done, 2, 1);
});
it('should NOT assemble DASM', function(done) {
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo xxx #0\n', 'vcs', done, 0, 0, 1);
});
it('should assemble ACME', function(done) {
compile('acme', 'foo: lda #0\n', 'vcs', done, 2, 0); // TODO
});
it('should NOT assemble ACME', function(done) {
compile('acme', 'foo: xxx #0\n', 'vcs', done, 0, 0, 2); // TODO
});
it('should compile PLASMA', function(done) {
compile('plasm', 'word x = 0', 'apple2', done, 5, 0);
});
it('should NOT compile PLASMA', function(done) {
compile('plasm', 'word x = ', 'apple2', done, 0, 0, 1);
});
it('should compile CC65', function(done) {
compile('cc65', '#include <stdio.h>\nint main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'apple2', done, 2947, 4);
});
it('should NOT assemble Z80ASM', function(done) {
compile('z80asm', 'ddwiuweq', 'none', done, 0, 0, 1);
it('should NOT compile CC65', function(done) {
compile('cc65', 'int main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'apple2', done, 0, 0, 1);
});
it('should assemble Z80ASM', function(done) {
compile('z80asm', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', 'spaceinv', done, 4, 2, 0);
});
it('should NOT compile SDCC', function(done) {
compile('sdcc', 'foobar', 'spaceinv', done, 0, 0, 1);
it('should NOT assemble Z80ASM', function(done) {
compile('z80asm', 'ddwiuweq', 'none', done, 0, 0, 1);
});
it('should assemble SDASZ80', function(done) {
compile('sdcc', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', 'spaceinv', done, 8192, 2, 1);
compile('sdasz80', '\tld hl,#0\n\tret\n', 'spaceinv', done, 8192, 2);
});
it('should NOT assemble SDASZ80', function(done) {
compile('sdasz80', '\txxx hl,#0\n\tret\n', 'spaceinv', done, 0, 0, 1);
});
it('should compile SDCC', function(done) {
compile('sdcc', 'int foo=0;\nint main(int argc) {\nint x=1;\nint y=2+argc;\nreturn x+y+argc;\n}', 'spaceinv', done, 8192, 3, 0);
});
it('should NOT compile SDCC', function(done) {
compile('sdcc', 'foobar', 'spaceinv', done, 0, 0, 1);
});
});