1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-12-26 22:31:14 +00:00

disassembly toggle

This commit is contained in:
Steven Hugg 2017-01-06 09:49:07 -05:00
parent 3239dd6a19
commit 1ad74168d6
10 changed files with 3315 additions and 2898 deletions

View File

@ -4,15 +4,12 @@
<title>8bitworkshop ~ Atari 2600</title>
<style type="text/css" media="screen">
body {
overflow: hidden;
overflow: hidden !important;
font-size: 11px;
}
.dbg_info {
font-size: 0.8em;
}
#controls_top {
padding: 0.5em;
}
.gutter-offset {
width: 3em;
}
@ -47,17 +44,23 @@ body {
visibility: visible;
}
#notebook {
height: 100%;
width: 100%;
height: 100vh;
width: 50%;
background-color:#999;
}
#controls_top {
padding: 0.5em;
width:100vh;
height:3em;
}
div.editor {
position:absolute;
left:0;
top:0;
top:3em;
bottom:0;
right:0;
width:50%;
height:120vh;
height:95vh;
background-color:#999;
line-height:1.25;
font-size:12pt;
@ -67,7 +70,7 @@ div.emulator {
left:50%;
top:0;
width:50%;
height:120vh;
height:100vh;
overflow-y: scroll;
background-color: #666;
margin-top: 20px auto 0;
@ -163,37 +166,42 @@ a.dropdown-toggle {
<body>
<div id="notebook">
<div id="editor" class="editor">
<div id="controls_top">
<span class="dropdown">
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
&#9776; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<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">Reset to Original...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
</ul>
</li>
</ul>
</span>
<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_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
<button id="dbg_reset" type="submit" title="Reset and Run To Line"><img src="images/resetandrun.png"></button>
<button id="dbg_timing" type="submit" title="See Timing"><img src="images/timing.png"></button>
</span>
<span class="dbg_info" id="dbg_info"></span>
<div id="controls_top">
<span class="dropdown">
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
&#9776; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<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">Reset to Original...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
</ul>
</li>
</ul>
</span>
<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_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
<button id="dbg_reset" type="submit" title="Reset and Run To Line"><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>
</span>
<span class="dbg_info" id="dbg_info"></span>
</div>
<div id="editor_window">
<div id="disassembly" class="editor">
</div>
<div id="editor" class="editor">
</div>
</div>
<div class="emulator" id="emulator">
@ -240,6 +248,7 @@ a.dropdown-toggle {
<script src="javatari.js/release/javatari/javatari.js"></script>
<script src="src/emu.js"></script>
<script src="src/util.js"></script>
<script src="src/disasm.js"></script>
<script src="src/platform/vcs.js"></script>
<script src="src/platform/apple2.js"></script>
<script src="src/platform/atarivec.js"></script>

@ -1 +1 @@
Subproject commit 531e945457a1714c11b7cf71aafc4216d14992bb
Subproject commit 46d2ca39cc016a0ec826ec1bf0fd8c422985209c

250
src/disasm.js Normal file
View File

@ -0,0 +1,250 @@
var Disassembler6502 = function() {
this.disassemble = function(mem, start, end, ips) {
var i;
var lines = [];
function print_func(s) {
lines[i] = s;
}
for (i = start; i < end;) {
var opcode = OPS[mem[i]];
if (!opcode) {
print_func("#" + formatHex(mem[i], 2));
i += 1;
} else {
var bytes = opcode.bytes;
var args = mem.slice(i+1, i+1+bytes);
//console.log(opcode, bytes, args);
print_func(opcode.toString.call(opcode, args));
i += bytes;
}
}
return lines;
};
function formatHex(number, len) {
if (typeof number === "undefined" || number === null || isNaN(number)) {
throw new Error("Invalid value \"" + number + "\" passed to formatHex()");
}
var str = number.toString(16).toUpperCase();
if (!len) {
if (str.length % 2 == 1) {
len = str.length+1;
}
}
while (str.length < len) {
str = "0" + str;
}
return str;
}
function formatImmediate (args) {
return this.name + " #$" + formatHex(args[0]);
}
function formatZeroPage (args) {
return this.name + " $" + formatHex(args[0]);
}
function formatZeroPageIndexedX (args) {
return formatZeroPage.call(this, args) + ",X";
}
function formatZeroPageIndexedY (args) {
return formatZeroPage.call(this, args) + ",Y";
}
function formatAbsolute (args) {
return this.name + " $" + formatHex(args[1], 2) + formatHex(args[0], 2);
}
function formatAbsoluteIndexedX (args) {
return formatAbsolute.call(this, args) + ",X";
}
function formatAbsoluteIndexedY (args) {
return formatAbsolute.call(this, args) + ",Y";
}
function formatIndirect (args) {
return this.name + " ($" + formatHex(args[0], 2) + ")";
}
function formatIndirectIndexedX (args) {
return this.name + " ($" + formatHex(args[0], 2) + ",X)";
}
function formatIndirectIndexedY (args) {
return this.name + " ($" + formatHex(args[0], 2) + "),Y";
}
function formatName() {
return this.name;
}
function formatRelative (args) {
return this.name + " $" + formatHex(args[0], 2);
}
function formatAccumulator (args) {
return this.name + " A";
}
var OPS = {
0xA0 : { name: "LDY", bytes: 2, toString: formatImmediate },
0xA4 : { name: "LDY", bytes: 2, toString: formatZeroPage },
0xB4 : { name: "LDY", bytes: 2, toString: formatZeroPageIndexedX },
0xAC : { name: "LDY", bytes: 3, toString: formatAbsolute },
0xBC : { name: "LDY", bytes: 3, toString: formatAbsoluteIndexedX },
0xA2 : { name: "LDX", bytes: 2, toString: formatImmediate },
0xA6 : { name: "LDX", bytes: 2, toString: formatZeroPage },
0xB6 : { name: "LDX", bytes: 2, toString: formatZeroPageIndexedY },
0xAE : { name: "LDX", bytes: 3, toString: formatAbsolute },
0xBE : { name: "LDX", bytes: 3, toString: formatAbsoluteIndexedY },
0xA9 : { name: "LDA", bytes: 2, toString: formatImmediate },
0xA5 : { name: "LDA", bytes: 2, toString: formatZeroPage },
0xB5 : { name: "LDA", bytes: 2, toString: formatZeroPageIndexedX },
0xAD : { name: "LDA", bytes: 3, toString: formatAbsolute },
0xBD : { name: "LDA", bytes: 3, toString: formatAbsoluteIndexedX },
0xB9 : { name: "LDA", bytes: 3, toString: formatAbsoluteIndexedY },
0xA1 : { name: "LDA", bytes: 2, toString: formatIndirectIndexedX },
0xB1 : { name: "LDA", bytes: 2, toString: formatIndirectIndexedY },
0x86 : { name: "STX", bytes: 2, toString: formatZeroPage },
0x96 : { name: "STX", bytes: 2, toString: formatZeroPageIndexedY },
0x8E : { name: "STX", bytes: 3, toString: formatAbsolute },
0x84 : { name: "STY", bytes: 2, toString: formatZeroPage },
0x94 : { name: "STY", bytes: 2, toString: formatZeroPageIndexedX },
0x8C : { name: "STY", bytes: 3, toString: formatAbsolute },
0x85 : { name: "STA", bytes: 2, toString: formatZeroPage },
0x95 : { name: "STA", bytes: 2, toString: formatZeroPageIndexedX },
0x8D : { name: "STA", bytes: 3, toString: formatAbsolute },
0x9D : { name: "STA", bytes: 3, toString: formatAbsoluteIndexedX },
0x99 : { name: "STA", bytes: 3, toString: formatAbsoluteIndexedY },
0x81 : { name: "STA", bytes: 2, toString: formatIndirectIndexedX },
0x91 : { name: "STA", bytes: 2, toString: formatIndirectIndexedY },
0xE8 : { name: "INX", bytes: 1, toString: formatName },
0xC8 : { name: "INY", bytes: 1, toString: formatName },
0xCA : { name: "DEX", bytes: 1, toString: formatName },
0x88 : { name: "DEY", bytes: 1, toString: formatName },
0xE6 : { name: "INC", bytes: 2, toString: formatZeroPage },
0xF6 : { name: "INC", bytes: 2, toString: formatZeroPageIndexedX },
0xEE : { name: "INC", bytes: 3, toString: formatAbsolute },
0xFE : { name: "INC", bytes: 3, toString: formatAbsoluteIndexedX },
0xC6 : { name: "DEC", bytes: 2, toString: formatZeroPage },
0xD6 : { name: "DEC", bytes: 2, toString: formatZeroPageIndexedX },
0xCE : { name: "DEC", bytes: 3, toString: formatAbsolute },
0xDE : { name: "DEC", bytes: 3, toString: formatAbsoluteIndexedX },
0x38 : { name: "SEC", bytes: 1, toString: formatName },
0xF8 : { name: "SED", bytes: 1, toString: formatName },
0x78 : { name: "SEI", bytes: 1, toString: formatName },
0x18 : { name: "CLC", bytes: 1, toString: formatName },
0xD8 : { name: "CLD", bytes: 1, toString: formatName },
0x58 : { name: "CLI", bytes: 1, toString: formatName },
0xB8 : { name: "CLV", bytes: 1, toString: formatName },
0xAA : { name: "TAX", bytes: 1, toString: formatName },
0x8A : { name: "TXA", bytes: 1, toString: formatName },
0xA8 : { name: "TAY", bytes: 1, toString: formatName },
0x98 : { name: "TYA", bytes: 1, toString: formatName },
0xBA : { name: "TSX", bytes: 1, toString: formatName },
0x9A : { name: "TXS", bytes: 1, toString: formatName },
0x48 : { name: "PHA", bytes: 1, toString: formatName },
0x08 : { name: "PHP", bytes: 1, toString: formatName },
0x68 : { name: "PLA", bytes: 1, toString: formatName },
0x28 : { name: "PLP", bytes: 1, toString: formatName },
0x29 : { name: "AND", bytes: 2, toString: formatImmediate },
0x25 : { name: "AND", bytes: 2, toString: formatZeroPage },
0x35 : { name: "AND", bytes: 2, toString: formatZeroPageIndexedX },
0x2D : { name: "AND", bytes: 3, toString: formatAbsolute },
0x3D : { name: "AND", bytes: 3, toString: formatAbsoluteIndexedX },
0x39 : { name: "AND", bytes: 3, toString: formatAbsoluteIndexedY },
0x21 : { name: "AND", bytes: 2, toString: formatIndirectIndexedX },
0x31 : { name: "AND", bytes: 2, toString: formatIndirectIndexedY },
0x09 : { name: "ORA", bytes: 2, toString: formatImmediate },
0x05 : { name: "ORA", bytes: 2, toString: formatZeroPage },
0x15 : { name: "ORA", bytes: 2, toString: formatZeroPageIndexedX },
0x0D : { name: "ORA", bytes: 3, toString: formatAbsolute },
0x1D : { name: "ORA", bytes: 3, toString: formatAbsoluteIndexedX },
0x19 : { name: "ORA", bytes: 3, toString: formatAbsoluteIndexedY },
0x01 : { name: "ORA", bytes: 2, toString: formatIndirectIndexedX },
0x11 : { name: "ORA", bytes: 2, toString: formatIndirectIndexedY },
0x49 : { name: "EOR", bytes: 2, toString: formatImmediate },
0x45 : { name: "EOR", bytes: 2, toString: formatZeroPage },
0x55 : { name: "EOR", bytes: 2, toString: formatZeroPageIndexedX },
0x4D : { name: "EOR", bytes: 3, toString: formatAbsolute },
0x5D : { name: "EOR", bytes: 3, toString: formatAbsoluteIndexedX },
0x59 : { name: "EOR", bytes: 3, toString: formatAbsoluteIndexedY },
0x41 : { name: "EOR", bytes: 2, toString: formatIndirectIndexedX },
0x51 : { name: "EOR", bytes: 2, toString: formatIndirectIndexedY },
0x4C : { name: "JMP", bytes: 3, toString: formatAbsolute },
0x6C : { name: "JMP", bytes: 3, toString: formatIndirect },
0x20 : { name: "JSR", bytes: 3, toString: formatAbsolute },
0x60 : { name: "RTS", bytes: 1, toString: formatName },
0x40 : { name: "RTI", bytes: 1, toString: formatName },
0x90 : { name: "BCC", bytes: 2, toString: formatRelative },
0xB0 : { name: "BCS", bytes: 2, toString: formatRelative },
0xF0 : { name: "BEQ", bytes: 2, toString: formatRelative },
0xD0 : { name: "BNE", bytes: 2, toString: formatRelative },
0x10 : { name: "BPL", bytes: 2, toString: formatRelative },
0x30 : { name: "BMI", bytes: 2, toString: formatRelative },
0x50 : { name: "BVC", bytes: 2, toString: formatRelative },
0x70 : { name: "BVS", bytes: 2, toString: formatRelative },
0x2A : { name: "ROL", bytes: 1, toString: formatAccumulator },
0x26 : { name: "ROL", bytes: 2, toString: formatZeroPage },
0x36 : { name: "ROL", bytes: 2, toString: formatZeroPageIndexedX },
0x2E : { name: "ROL", bytes: 3, toString: formatAbsolute },
0x3E : { name: "ROL", bytes: 3, toString: formatAbsoluteIndexedX },
0x6A : { name: "ROR", bytes: 1, toString: formatAccumulator },
0x66 : { name: "ROR", bytes: 2, toString: formatZeroPage },
0x76 : { name: "ROR", bytes: 2, toString: formatZeroPageIndexedX },
0x6E : { name: "ROR", bytes: 3, toString: formatAbsolute },
0x7E : { name: "ROR", bytes: 3, toString: formatAbsoluteIndexedX },
0x4A : { name: "LSR", bytes: 1, toString: formatAccumulator },
0x46 : { name: "LSR", bytes: 2, toString: formatZeroPage },
0x56 : { name: "LSR", bytes: 2, toString: formatZeroPageIndexedX },
0x4E : { name: "LSR", bytes: 3, toString: formatAbsolute },
0x5E : { name: "LSR", bytes: 3, toString: formatAbsoluteIndexedX },
0x0A : { name: "ASL", bytes: 1, toString: formatAccumulator },
0x06 : { name: "ASL", bytes: 2, toString: formatZeroPage },
0x16 : { name: "ASL", bytes: 2, toString: formatZeroPageIndexedX },
0x0E : { name: "ASL", bytes: 3, toString: formatAbsolute },
0x1E : { name: "ASL", bytes: 3, toString: formatAbsoluteIndexedX },
0xC9 : { name: "CMP", bytes: 2, toString: formatImmediate },
0xC5 : { name: "CMP", bytes: 2, toString: formatZeroPage },
0xD5 : { name: "CMP", bytes: 2, toString: formatZeroPageIndexedX },
0xCD : { name: "CMP", bytes: 3, toString: formatAbsolute },
0xDD : { name: "CMP", bytes: 3, toString: formatAbsoluteIndexedX },
0xD9 : { name: "CMP", bytes: 3, toString: formatAbsoluteIndexedY },
0xC1 : { name: "CMP", bytes: 2, toString: formatIndirectIndexedX },
0xD1 : { name: "CMP", bytes: 2, toString: formatIndirectIndexedY },
0xE0 : { name: "CPX", bytes: 2, toString: formatImmediate },
0xE4 : { name: "CPX", bytes: 2, toString: formatZeroPage },
0xEC : { name: "CPX", bytes: 3, toString: formatAbsolute },
0xC0 : { name: "CPY", bytes: 2, toString: formatImmediate },
0xC4 : { name: "CPY", bytes: 2, toString: formatZeroPage },
0xCC : { name: "CPY", bytes: 3, toString: formatAbsolute },
0x24 : { name: "BIT", bytes: 2, toString: formatZeroPage },
0x2C : { name: "BIT", bytes: 3, toString: formatAbsolute },
0x69 : { name: "ADC", bytes: 2, toString: formatImmediate },
0x65 : { name: "ADC", bytes: 2, toString: formatZeroPage },
0x75 : { name: "ADC", bytes: 2, toString: formatZeroPageIndexedX },
0x6D : { name: "ADC", bytes: 3, toString: formatAbsolute },
0x7D : { name: "ADC", bytes: 3, toString: formatAbsoluteIndexedX },
0x79 : { name: "ADC", bytes: 3, toString: formatAbsoluteIndexedY },
0x61 : { name: "ADC", bytes: 2, toString: formatIndirectIndexedX },
0x71 : { name: "ADC", bytes: 2, toString: formatIndirectIndexedY },
0xE9 : { name: "SBC", bytes: 2, toString: formatImmediate },
0xE5 : { name: "SBC", bytes: 2, toString: formatZeroPage },
0xF5 : { name: "SBC", bytes: 2, toString: formatZeroPageIndexedX },
0xED : { name: "SBC", bytes: 3, toString: formatAbsolute },
0xFD : { name: "SBC", bytes: 3, toString: formatAbsoluteIndexedX },
0xF9 : { name: "SBC", bytes: 3, toString: formatAbsoluteIndexedY },
0xE1 : { name: "SBC", bytes: 2, toString: formatIndirectIndexedX },
0xF1 : { name: "SBC", bytes: 2, toString: formatIndirectIndexedY },
0xEA : { name: "NOP", bytes: 1, toString: formatName },
0x00 : { name: "BRK", bytes: 1, toString: formatName },
};
}

View File

@ -2,6 +2,10 @@
// Emulator classes
function _metakeyflags(e) {
return (e.shiftKey?2:0) | (e.ctrlKey?4:0) | (e.altKey?8:0) | (e.metaKey?16:0);
}
function __createCanvas(mainElement, width, height) {
// TODO
var fsElement = document.createElement('div');
@ -36,6 +40,18 @@ var RasterVideo = function(mainElement, width, height, options) {
datau32 = new Uint32Array(buf);
}
this.setKeyboardEvents = function(callback) {
canvas.onkeydown = function(e) {
callback(e.which, 0, 1|_metakeyflags(e));
};
canvas.onkeyup = function(e) {
callback(e.which, 0, 0|_metakeyflags(e));
};
canvas.onkeypress = function(e) {
callback(e.which, e.charCode, 1|_metakeyflags(e));
};
}
this.getFrameData = function() {
return datau32;
}
@ -104,10 +120,13 @@ var VectorVideo = function(mainElement, width, height) {
this.setKeyboardEvents = function(callback) {
canvas.onkeydown = function(e) {
callback(e.key, 1);
callback(e.which, 0, 1|_metakeyflags(e));
};
canvas.onkeyup = function(e) {
callback(e.key, 0);
callback(e.which, 0, 0|_metakeyflags(e));
};
canvas.onkeypress = function(e) {
callback(e.which, e.charCode, 1|_metakeyflags(e));
};
}
@ -259,6 +278,13 @@ var SampleAudio = function(clockfreq) {
buffer = bufferlist[0];
}
this.stop = function() {
if (this.context) {
this.context.close();
this.context = null;
}
}
this.feedSample = function(value, count) {
while (count-- > 0) {
accum += value;

View File

@ -40,6 +40,7 @@ var Apple2Platform = function(mainElement) {
ram = new RAM(0x13000); // 64K + 16K LC RAM - 4K hardware
// ROM
var rom = new lzgmini().decode(APPLEIIGO_LZG).slice(0,0x3000);
//var rom = new lzgmini().decode(APPLEII_ROM).slice(0,0x3000);
ram.mem.set(rom, 0xd000);
// bus
bus = {
@ -134,6 +135,18 @@ var Apple2Platform = function(mainElement) {
audio = new SampleAudio(cpuFrequency);
video.start();
audio.start();
video.setKeyboardEvents(function(key,code,flags) {
// since we're an Apple II+, we don't do lowercase
if (flags & 1) {
if (code) {
if (code >= 0xe1 && code <= 0xfa)
code -= 0x20;
kbdlatch = (code | 0x80) & 0xff;
} else if (key) {
kbdlatch = (key | 0x80) & 0xff;
}
}
});
var idata = video.getFrameData();
var grparams = {dirty:grdirty, grswitch:grswitch, mem:ram.mem};
ap2disp = new Apple2Display(idata, grparams);
@ -156,6 +169,7 @@ var Apple2Platform = function(mainElement) {
grparams.grswitch = grswitch;
ap2disp.updateScreen();
video.updateFrame();
// TODO: reset debug state
});
}
@ -213,24 +227,29 @@ var Apple2Platform = function(mainElement) {
writeinhibit = false;
break;
}
// reset language card constants
if (auxRAMbank == 2)
bank2rdoffset = -0x1000; // map 0xd000-0xdfff -> 0xc000-0xcfff
else
bank2rdoffset = 0x3000; // map 0xd000-0xdfff -> 0x10000-0x10fff
if (auxRAMbank == 2)
bank2wroffset = -0x1000; // map 0xd000-0xdfff -> 0xc000-0xcfff
else
bank2wroffset = 0x3000; // map 0xd000-0xdfff -> 0x10000-0x10fff
setupLanguageCardConstants();
return noise();
}
function setupLanguageCardConstants() {
// reset language card constants
if (auxRAMbank == 2)
bank2rdoffset = -0x1000; // map 0xd000-0xdfff -> 0xc000-0xcfff
else
bank2rdoffset = 0x3000; // map 0xd000-0xdfff -> 0x10000-0x10fff
if (auxRAMbank == 2)
bank2wroffset = -0x1000; // map 0xd000-0xdfff -> 0xc000-0xcfff
else
bank2wroffset = 0x3000; // map 0xd000-0xdfff -> 0x10000-0x10fff
}
this.getOpcodeMetadata = function(opcode, offset) {
return Javatari.getOpcodeMetadata(opcode, offset); // TODO
}
this.loadROM = function(title, data) {
this.reset();
//console.log('loadROM',hex(data.length));
ram.mem.set(data, PGM_BASE);
/*
if(data.length != 0x3000) {
@ -249,9 +268,11 @@ var Apple2Platform = function(mainElement) {
}
this.pause = function() {
timer.stop();
audio.stop();
}
this.resume = function() {
timer.start();
audio.start();
}
this.reset = function() {
cpu.reset();
@ -295,6 +316,7 @@ var Apple2Platform = function(mainElement) {
}
this.breakpointHit = function() {
debugBreakState = self.saveState();
debugBreakState.c.PC = (debugBreakState.c.PC-1) & 0xffff;
console.log("Breakpoint at clk", debugClock, "PC", debugBreakState.c.PC.toString(16));
this.pause();
if (onBreakpointHit) {
@ -304,7 +326,7 @@ var Apple2Platform = function(mainElement) {
this.step = function() {
var previousPC = -1;
self.setDebugCondition(function() {
if (debugClock++ >= debugTargetClock) {
if (debugClock++ > debugTargetClock) {
var thisState = cpu.saveState();
if (previousPC < 0) {
previousPC = thisState.PC;
@ -339,11 +361,20 @@ var Apple2Platform = function(mainElement) {
this.loadState = function(state) {
cpu.loadState(state.c);
ram.mem.set(state.b);
kbdlatch = state.kbd;
grswitch = state.gr;
auxRAMselected = state.lc.s;
auxRAMbank = state.lc.b;
writeinhibit = state.lc.w;
setupLanguageCardConstants();
}
this.saveState = function() {
return {
c:cpu.saveState(),
b:ram.mem.slice(0),
kbd:kbdlatch,
gr:grswitch,
lc:{s:auxRAMselected,b:auxRAMbank,w:writeinhibit},
};
}
this.getRAMForState = function(state) {
@ -928,50 +959,52 @@ var apple2_charset = [
// public domain ROM
var APPLEIIGO_LZG = [
76,90,71,0,0,48,0,0,0,5,159,47,60,46,159,1,21,25,30,52,65,80,80,76,69,73,73,71,79,32,82,79,
77,49,46,48,0,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,28,52,6,32,0,224,25,30,67,52,
30,52,28,25,31,174,52,31,52,30,52,28,52,6,25,63,107,52,31,52,30,52,28,25,63,101,52,19,25,31,139,52,
31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,25,160,32,52,28,32,32,160,
25,14,40,1,16,16,12,5,19,15,6,20,32,14,15,20,32,1,22,1,9,12,1,2,12,5,25,16,40,198,207,210,
160,205,207,210,197,160,201,206,30,3,205,193,212,201,207,206,160,208,204,197,193,211,197,160,195,204,201,195,203,160,30,8,
160,25,8,40,212,200,197,160,193,208,30,25,201,201,199,207,160,204,207,52,129,194,197,204,207,215,30,28,52,10,25,29,
224,52,22,76,3,224,32,88,252,162,39,189,0,223,157,128,4,202,16,247,30,3,48,223,157,0,5,30,195,30,78,25,
5,3,96,30,3,6,30,195,144,30,25,7,30,3,76,64,224,52,65,25,30,131,52,31,52,31,52,31,52,31,52,31,
52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,
52,31,52,24,201,206,176,238,201,201,144,234,201,204,240,230,208,232,234,52,11,72,74,41,3,9,4,133,41,104,41,24,
144,2,105,127,133,40,10,10,5,40,133,40,96,25,30,116,0,165,37,32,193,251,101,32,25,29,75,52,21,165,34,72,
32,36,252,165,40,133,42,165,41,133,43,164,33,136,104,105,1,197,35,176,13,30,78,177,40,145,42,136,16,249,48,225,
160,0,32,158,252,176,134,164,36,169,160,145,40,200,196,33,144,249,25,30,199,52,27,164,36,177,40,72,41,63,9,64,
145,40,104,108,56,25,19,27,32,12,253,32,165,251,52,161,201,155,240,243,25,28,141,52,6,32,142,253,165,51,32,237,
253,162,1,138,240,243,202,32,53,253,201,149,208,2,177,40,201,224,144,2,41,223,157,0,2,201,141,208,178,32,156,252,
169,141,208,91,164,61,166,60,30,39,32,64,249,160,0,169,173,76,237,253,25,28,87,52,31,52,31,52,31,52,31,52,
31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,28,52,7,169,0,133,28,165,230,133,27,160,0,132,26,165,
28,145,26,32,126,244,200,208,246,230,27,165,27,41,31,208,238,96,133,226,134,224,132,225,72,41,192,133,38,74,74,5,
38,133,38,104,133,39,10,10,10,38,39,52,66,102,38,165,39,41,31,5,230,133,39,138,192,0,240,5,160,35,105,4,
200,233,7,176,251,132,229,170,189,185,244,133,48,152,74,165,228,133,28,176,21,28,0,35,52,4,10,201,192,16,6,165,
28,73,127,133,28,25,254,218,52,31,52,31,52,31,52,31,52,31,52,31,52,28,52,10,74,8,32,71,248,40,169,15,
144,2,105,224,133,46,177,38,69,48,37,46,81,38,145,38,96,32,0,248,196,44,176,17,200,32,14,248,144,246,105,1,
72,30,8,104,197,45,144,245,96,160,47,208,2,160,39,132,45,160,39,169,0,133,48,32,40,248,136,16,246,96,21,5,
4,126,39,21,6,4,126,38,10,10,25,130,52,96,165,48,24,105,3,41,15,133,48,10,52,1,5,48,133,48,25,103,
223,144,4,74,52,1,41,15,25,107,240,168,74,144,9,106,176,16,201,162,240,12,41,135,74,170,189,98,249,32,121,248,
208,4,160,128,169,0,170,189,166,249,133,46,41,3,133,47,152,41,143,170,152,160,3,224,138,240,11,74,144,8,74,74,
9,32,136,208,250,200,136,208,242,25,159,59,52,31,52,31,52,20,216,32,132,254,32,47,251,32,147,254,32,137,254,173,
88,192,173,90,192,173,93,192,173,95,192,173,255,207,44,16,192,216,32,58,255,32,96,251,169,0,133,0,169,198,133,1,
108,25,30,111,52,29,21,3,19,108,221,219,199,207,25,10,13,173,112,192,160,0,234,234,189,100,192,16,4,200,208,248,
136,96,169,0,133,72,173,86,192,173,84,192,173,81,192,169,0,240,11,173,80,192,173,83,192,32,54,248,169,20,133,34,
30,22,32,169,40,133,33,169,24,133,35,169,23,133,37,76,34,252,32,88,252,160,9,185,8,251,153,14,4,136,208,247,
96,173,243,3,73,165,141,244,3,96,201,141,208,24,172,0,192,16,19,192,147,208,15,44,16,192,30,68,251,192,131,240,
3,30,4,76,253,251,25,12,148,21,29,7,248,40,133,40,96,201,135,208,18,169,64,32,168,252,160,192,169,12,52,193,
173,48,192,136,208,245,96,164,36,145,40,230,36,165,36,197,33,176,102,96,201,160,176,239,168,16,236,201,141,240,90,201,
138,52,97,136,208,201,198,36,16,232,165,33,133,36,198,36,165,34,197,37,176,11,198,37,21,28,7,248,0,72,32,36,
252,32,158,252,160,0,104,105,0,197,35,144,240,176,202,165,34,133,37,160,0,132,36,240,228,169,0,133,36,230,30,62,
30,16,182,198,37,21,29,7,248,21,6,7,248,56,72,233,1,208,252,104,52,129,246,96,230,66,208,2,230,67,165,60,
197,62,165,61,229,63,230,60,30,6,61,25,125,244,52,18,21,13,7,248,230,78,208,2,230,79,44,0,192,16,245,145,
40,173,0,192,44,16,192,96,21,10,7,248,254,96,165,50,72,169,255,133,50,189,0,2,32,237,253,104,30,129,201,136,
240,29,201,152,240,10,224,248,144,3,32,58,255,232,208,19,169,220,30,21,21,10,7,248,254,21,30,7,248,52,27,0,
72,25,162,88,32,229,253,104,41,15,9,176,201,186,144,2,105,6,108,54,0,201,160,144,2,37,50,132,53,72,32,120,
251,104,164,53,25,49,47,64,25,10,5,25,11,24,177,60,145,66,32,180,252,144,247,25,190,97,52,1,160,63,208,2,
160,255,132,50,25,98,82,62,162,56,160,27,208,8,30,130,54,160,240,165,62,41,15,240,6,9,192,160,0,240,2,169,
253,148,0,149,1,96,234,234,76,21,31,30,67,52,7,169,135,76,237,253,165,72,72,165,69,166,70,164,71,25,110,22,
25,62,27,52,30,52,14,245,3,251,3,98,250,98,250
76,90,71,0,0,48,0,0,0,5,231,30,202,84,84,1,21,25,30,52,65,80,80,76,69,73,73,71,79,32,82,79,
77,49,46,49,255,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,3,133,109,132,110,56,165,150,229,155,133,94,
168,165,151,229,156,170,232,152,240,35,165,150,56,229,94,133,150,176,3,198,151,56,165,148,30,3,148,176,8,198,149,144,
4,177,150,145,148,136,208,249,52,194,198,151,198,149,202,208,242,96,25,30,128,52,27,255,255,32,0,224,25,30,67,52,
30,52,28,25,31,174,52,31,52,30,52,28,52,4,25,63,105,52,31,52,30,52,28,52,2,25,63,103,52,15,25,31,
137,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,26,160,32,52,28,32,
32,160,0,52,5,25,6,40,1,16,16,12,5,19,15,6,20,32,14,15,20,32,1,22,1,9,12,1,2,12,5,25,
16,40,198,207,210,160,205,207,210,197,160,201,206,30,3,205,193,212,201,207,206,160,208,204,197,193,211,197,160,195,204,201,
195,203,160,30,8,160,25,8,40,212,200,197,160,193,208,30,25,201,201,199,207,160,204,207,52,129,194,197,204,207,215,30,
28,52,10,25,6,40,52,29,52,14,76,3,224,32,88,252,162,39,189,0,223,157,128,4,202,16,247,30,3,48,223,157,
0,5,30,195,30,78,25,5,3,96,30,3,6,30,195,144,30,25,7,30,3,76,64,224,52,65,25,30,131,52,31,52,
31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,
31,52,31,52,31,52,31,52,31,52,24,201,206,176,238,201,201,144,234,201,204,240,230,208,232,234,52,11,72,74,41,3,
9,4,133,41,104,41,24,144,2,105,127,133,40,10,10,5,40,133,40,96,25,30,116,0,165,37,32,193,251,101,32,25,
29,75,52,21,165,34,72,32,36,252,165,40,133,42,165,41,133,43,164,33,136,104,105,1,197,35,176,13,30,78,177,40,
145,42,136,16,249,48,225,160,0,32,158,252,176,134,164,36,169,160,145,40,200,196,33,144,249,25,30,199,52,27,164,36,
177,40,72,41,63,9,64,145,40,104,108,56,25,19,27,32,12,253,32,165,251,52,161,201,155,240,243,25,28,141,52,6,
32,142,253,165,51,32,237,253,162,1,138,240,243,202,32,53,253,201,149,208,2,177,40,201,224,144,2,41,223,157,0,2,
201,141,208,178,32,156,252,169,141,208,91,164,61,166,60,30,39,32,64,249,160,0,169,173,76,237,253,25,28,87,52,31,
52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,31,52,28,52,7,169,0,133,28,165,230,
133,27,160,0,132,26,165,28,145,26,32,126,244,200,208,246,230,27,165,27,41,31,208,238,96,133,226,134,224,132,225,72,
41,192,133,38,74,74,5,38,133,38,104,133,39,10,10,10,38,39,52,66,102,38,165,39,41,31,5,230,133,39,138,192,
0,240,5,160,35,105,4,200,233,7,176,251,132,229,170,189,185,244,133,48,152,74,165,228,133,28,176,21,28,0,35,52,
4,10,201,192,16,6,165,28,73,127,133,28,25,254,218,52,31,52,31,52,31,52,31,52,31,52,31,52,28,52,10,74,
8,32,71,248,40,169,15,144,2,105,224,133,46,177,38,69,48,37,46,81,38,145,38,96,32,0,248,196,44,176,17,200,
32,14,248,144,246,105,1,72,30,8,104,197,45,144,245,96,160,47,208,2,160,39,132,45,160,39,169,0,133,48,32,40,
248,136,16,246,96,21,5,4,126,39,21,6,4,126,38,10,10,25,130,52,96,165,48,24,105,3,41,15,133,48,10,52,
1,5,48,133,48,25,103,223,144,4,74,52,1,41,15,25,107,240,168,74,144,9,106,176,16,201,162,240,12,41,135,74,
170,189,98,249,32,121,248,208,4,160,128,169,0,170,189,166,249,133,46,41,3,133,47,152,41,143,170,152,160,3,224,138,
240,11,74,144,8,74,74,9,32,136,208,250,200,136,208,242,25,159,59,52,31,52,31,52,20,216,32,132,254,32,47,251,
32,147,254,32,137,254,173,88,192,173,90,192,173,93,192,173,95,192,173,255,207,44,16,192,216,32,58,255,32,96,251,169,
0,133,0,169,198,133,1,108,25,30,111,52,29,21,3,19,108,221,219,199,207,25,10,13,173,112,192,160,0,234,234,189,
100,192,16,4,200,208,248,136,96,169,0,133,72,173,86,192,173,84,192,173,81,192,169,0,240,11,173,80,192,173,83,192,
32,54,248,169,20,133,34,30,22,32,169,40,133,33,169,24,133,35,169,23,133,37,76,34,252,32,88,252,160,9,185,8,
251,153,14,4,136,208,247,96,173,243,3,73,165,141,244,3,96,201,141,208,24,172,0,192,16,19,192,147,208,15,44,16,
192,30,68,251,192,131,240,3,30,4,76,253,251,25,12,148,21,29,7,248,40,133,40,96,201,135,208,18,169,64,32,168,
252,160,192,169,12,52,193,173,48,192,136,208,245,96,164,36,145,40,230,36,165,36,197,33,176,102,96,201,160,176,239,168,
16,236,201,141,240,90,201,138,52,97,136,208,201,198,36,16,232,165,33,133,36,198,36,165,34,197,37,176,11,198,37,21,
28,7,248,0,72,32,36,252,32,158,252,160,0,104,105,0,197,35,144,240,176,202,165,34,133,37,160,0,132,36,240,228,
169,0,133,36,230,30,62,30,16,182,198,37,21,29,7,248,21,6,7,248,56,72,233,1,208,252,104,52,129,246,96,230,
66,208,2,230,67,165,60,197,62,165,61,229,63,230,60,30,6,61,25,125,244,52,18,21,13,7,248,230,78,208,2,230,
79,44,0,192,16,245,145,40,173,0,192,44,16,192,96,21,10,7,248,254,96,165,50,72,169,255,133,50,189,0,2,32,
237,253,104,30,129,201,136,240,29,201,152,240,10,224,248,144,3,32,58,255,232,208,19,169,220,30,21,21,10,7,248,254,
21,30,7,248,52,27,0,72,25,162,88,32,229,253,104,41,15,9,176,201,186,144,2,105,6,108,54,0,201,160,144,2,
37,50,132,53,72,32,120,251,104,164,53,25,49,47,64,25,10,5,25,11,24,177,60,145,66,32,180,252,144,247,25,190,
97,52,1,160,63,208,2,160,255,132,50,25,98,82,62,162,56,160,27,208,8,30,130,54,160,240,165,62,41,15,240,6,
9,192,160,0,240,2,169,253,148,0,149,1,96,234,234,76,0,21,31,22,104,52,6,169,135,76,237,253,165,72,72,165,
69,166,70,164,71,25,110,22,25,62,27,52,30,52,14,245,3,251,3,98,250,98,250
];

View File

@ -86,18 +86,18 @@ var AtariVectorPlatform = function(mainElement) {
//cpu.executeInstruction();
}
});
video.setKeyboardEvents(function(key,flags) {
video.setKeyboardEvents(function(key,code,flags) {
var KEY2ADDR = {
"Shift": 3,
" ": 4,
"5": 8+0,
"6": 8+1,
"7": 8+2,
"1": 8+3,
"2": 8+4,
ArrowUp: 8+5,
ArrowRight: 8+6,
ArrowLeft: 8+7,
16: 3, // shift
32: 4, // space
53: 8+0, // 5
54: 8+1, // 6
55: 8+2, // 7
49: 8+3, // 1
50: 8+4, // 2
38: 8+5,
39: 8+6,
37: 8+7,
};
var addr = KEY2ADDR[key];
console.log(key,flags,addr);

View File

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

View File

@ -37,6 +37,7 @@ var current_preset_index = -1; // TODO: use URL
var current_preset_id = null;
var offset2line = null;
var line2offset = null;
var pcvisits;
var trace_pending_at_pc;
var store;
@ -238,15 +239,15 @@ function updateSelector() {
});
}
function getToolForFilename(fn) {
if (fn.endsWith(".pla")) return "plasm";
if (fn.endsWith(".c")) return "cc65";
if (fn.endsWith(".s")) return "ca65";
return "dasm";
}
function setCode(text) {
if (current_preset_id.endsWith(".pla"))
worker.postMessage({code:text, tool:'plasm'});
else if (current_preset_id.endsWith(".c"))
worker.postMessage({code:text, tool:'cc65'});
else if (current_preset_id.endsWith(".s"))
worker.postMessage({code:text, tool:'ca65'});
else
worker.postMessage({code:text, tool:'dasm'});
worker.postMessage({code:text, tool:getToolForFilename(current_preset_id)});
}
function arrayCompare(a,b) {
@ -261,11 +262,10 @@ function arrayCompare(a,b) {
}
worker.onmessage = function(e) {
//console.log(e.data);
// errors?
var gutters = $("#editor"); //.find(".CodeMirror-linenumber");
var toolbar = $("#notebook");
if (e.data.listing.errors.length > 0) {
gutters.addClass("has-errors");
toolbar.addClass("has-errors");
editor.clearGutter("gutter-info");
for (info of e.data.listing.errors) {
var div = document.createElement("div");
@ -280,10 +280,10 @@ worker.onmessage = function(e) {
}
current_output = null;
} else {
gutters.removeClass("has-errors");
toolbar.removeClass("has-errors");
updatePreset(current_preset_id, editor.getValue()); // update persisted entry
// load ROM
var rom = e.data.output.slice(2);
var rom = e.data.output;
var rom_changed = rom && !arrayCompare(rom, current_output);
if (rom_changed) {
try {
@ -291,6 +291,7 @@ worker.onmessage = function(e) {
//console.log("Loading ROM length", rom.length);
platform.loadROM(getCurrentPresetTitle(), rom);
current_output = rom;
pcvisits = {};
} catch (e) {
console.log(e); // TODO
current_output = null;
@ -382,6 +383,7 @@ function getTIAPosString() {
}
var lastDebugInfo;
var lastDebugState;
function highlightDifferences(s1, s2) {
var split1 = s1.split(/(\S+\s+)/).filter(function(n) {return n});
@ -436,13 +438,16 @@ function showMemory(state) {
function setupBreakpoint() {
// TODO
platform.setupDebug(function(state) {
lastDebugState = state;
var PC = state.c.PC;
var line = findLineForOffset(PC);
if (line) {
console.log("BREAKPOINT", hex(PC), line);
setCurrentLine(line);
}
pcvisits[PC] = pcvisits[PC] ? pcvisits[PC]+1 : 1;
showMemory(state);
updateDisassembly();
});
}
@ -481,6 +486,7 @@ function runToCursor() {
}
function clearBreakpoint() {
lastDebugState = null;
platform.clearDebug();
$("#dbg_info").empty();
showMemory();
@ -673,6 +679,29 @@ function showLoopTimingForCurrentLine() {
}
*/
function updateDisassembly() {
var div = $("#disassembly");
if (div.is(':visible')) {
div.empty();
var state = lastDebugState || platform.saveState();
var mem = state.b;
var pc = state.c.PC;
var disasm = new Disassembler6502().disassemble(mem, pc, pc+128, pcvisits);
var s = "";
for (a in disasm) {
var line = hex(parseInt(a)) + " " + disasm[a] + "\n";
s += line;
}
$("<pre></pre>").appendTo(div).text(s);
}
}
function toggleDisassembly() {
$("#disassembly").toggle();
$("#editor").toggle();
updateDisassembly();
}
function resetAndDebug() {
platform.reset();
runToCursor();
@ -685,6 +714,8 @@ function setupDebugControls(){
$("#dbg_step").click(singleStep);
$("#dbg_toline").click(runToCursor);
$("#dbg_timing").click(traceTiming);
$("#dbg_disasm").click(toggleDisassembly);
$("#disassembly").hide();
$(".dropdown-menu").collapse({toggle: false});
$("#item_new_file").click(_createNewFile);
$("#item_share_file").click(_shareFile);

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@ var fsMeta, fsBlob;
xhr.open("GET", "fs65.js.metadata", false); // synchronous request
xhr.send(null);
fsMeta = xhr.response;
console.log("Fetched", fsMeta, fsBlob);
console.log("Loaded filesystem", fsMeta.files.length, 'files', fsBlob.size, 'bytes');
}
function setupFS(FS) {
@ -133,7 +133,7 @@ function assembleDASM(code) {
var alst = FS.readFile("a.lst", {'encoding':'utf8'});
//console.log(alst);
var listing = parseDASMListing(alst, unresolved);
return {exitstatus:Module.EXITSTATUS, output:aout, listing:listing};
return {exitstatus:Module.EXITSTATUS, output:aout.slice(2), listing:listing};
}
// TODO: not quite done
@ -160,7 +160,7 @@ function assembleACME(code) {
console.log(alst);
console.log(asym);
var listing = parseDASMListing(alst, unresolved);
return {exitstatus:Module.EXITSTATUS, output:aout, listing:listing};
return {exitstatus:Module.EXITSTATUS, output:aout.slice(2), listing:listing};
}
function compilePLASMA(code) {
@ -196,7 +196,7 @@ function parseCA65Listing(code, unresolved) {
var linenum = parseInt(linem[4]);
lines.push({
line:linenum,
offset:offset + 0x6000, //TODO
offset:offset + 0x6048, //TODO: use map file
insns:null
});
//console.log(linem, lastlinenum, lines[lines.length-1]);
@ -239,6 +239,7 @@ function assemblelinkCA65(code, platform) {
'-t', platform, '-o', 'main', '-m', 'main.map', 'main.o', platform+'.lib']);
var aout = FS.readFile("main", {encoding:'binary'});
var mapout = FS.readFile("main.map", {encoding:'utf8'});
// CODE 00603E 00637C 00033F 00001
console.log(lstout);
console.log(mapout);
return {exitstatus:LD65.EXITSTATUS, output:aout.slice(4), listing:parseCA65Listing(lstout)};