mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-29 14:51:17 +00:00
disassembly toggle
This commit is contained in:
parent
3239dd6a19
commit
1ad74168d6
89
index.html
89
index.html
@ -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">
|
||||
☰ <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">
|
||||
☰ <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
250
src/disasm.js
Normal 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 },
|
||||
};
|
||||
|
||||
}
|
30
src/emu.js
30
src/emu.js
@ -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;
|
||||
|
@ -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
|
||||
];
|
||||
|
@ -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);
|
||||
|
@ -42,6 +42,8 @@ var VCSPlatform = function() {
|
||||
this.getPresets = function() { return VCS_PRESETS; }
|
||||
|
||||
this.start = function() {
|
||||
$("#dbg_timing").show();
|
||||
$("#dbg_disasm").show();
|
||||
Javatari.start();
|
||||
}
|
||||
|
||||
|
57
src/ui.js
57
src/ui.js
@ -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);
|
||||
|
5607
src/worker/dasm.js
5607
src/worker/dasm.js
File diff suppressed because one or more lines are too long
@ -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)};
|
||||
|
Loading…
Reference in New Issue
Block a user