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>
|
<title>8bitworkshop ~ Atari 2600</title>
|
||||||
<style type="text/css" media="screen">
|
<style type="text/css" media="screen">
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden !important;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
.dbg_info {
|
.dbg_info {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
#controls_top {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
.gutter-offset {
|
.gutter-offset {
|
||||||
width: 3em;
|
width: 3em;
|
||||||
}
|
}
|
||||||
@ -47,17 +44,23 @@ body {
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
#notebook {
|
#notebook {
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
width: 100%;
|
width: 50%;
|
||||||
|
background-color:#999;
|
||||||
|
}
|
||||||
|
#controls_top {
|
||||||
|
padding: 0.5em;
|
||||||
|
width:100vh;
|
||||||
|
height:3em;
|
||||||
}
|
}
|
||||||
div.editor {
|
div.editor {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
left:0;
|
left:0;
|
||||||
top:0;
|
top:3em;
|
||||||
bottom:0;
|
bottom:0;
|
||||||
right:0;
|
right:0;
|
||||||
width:50%;
|
width:50%;
|
||||||
height:120vh;
|
height:95vh;
|
||||||
background-color:#999;
|
background-color:#999;
|
||||||
line-height:1.25;
|
line-height:1.25;
|
||||||
font-size:12pt;
|
font-size:12pt;
|
||||||
@ -67,7 +70,7 @@ div.emulator {
|
|||||||
left:50%;
|
left:50%;
|
||||||
top:0;
|
top:0;
|
||||||
width:50%;
|
width:50%;
|
||||||
height:120vh;
|
height:100vh;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
margin-top: 20px auto 0;
|
margin-top: 20px auto 0;
|
||||||
@ -163,37 +166,42 @@ a.dropdown-toggle {
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="notebook">
|
<div id="notebook">
|
||||||
<div id="editor" class="editor">
|
<div id="controls_top">
|
||||||
<div id="controls_top">
|
<span class="dropdown">
|
||||||
<span class="dropdown">
|
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
☰ <span class="caret"></span>
|
||||||
☰ <span class="caret"></span>
|
</a>
|
||||||
</a>
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||||
<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_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_share_file">Share File...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_reset_file">Reset to Original...</a></li>
|
||||||
<li><a class="dropdown-item" href="#" id="item_reset_file">Reset to Original...</a></li>
|
<li class="dropdown dropdown-submenu">
|
||||||
<li class="dropdown dropdown-submenu">
|
<a tabindex="-1" href="#">Platform</a>
|
||||||
<a tabindex="-1" href="#">Platform</a>
|
<ul class="dropdown-menu">
|
||||||
<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=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=apple2" id="item_platform_apple2">Apple ][</a></li>
|
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
|
</ul>
|
||||||
</ul>
|
</li>
|
||||||
</li>
|
</ul>
|
||||||
</ul>
|
</span>
|
||||||
</span>
|
<select id="preset_select" name="">
|
||||||
<select id="preset_select" name="">
|
</select>
|
||||||
</select>
|
<span id="debug_bar">
|
||||||
<span id="debug_bar">
|
<button id="dbg_pause" type="button" title="Pause"><img src="images/pause.png"></button>
|
||||||
<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_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_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_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_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_timing" type="submit" title="See Timing"><img src="images/timing.png"></button>
|
<button id="dbg_disasm" type="submit" title="Toggle Disassembly">#</button>
|
||||||
</span>
|
</span>
|
||||||
<span class="dbg_info" id="dbg_info"></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>
|
</div>
|
||||||
<div class="emulator" id="emulator">
|
<div class="emulator" id="emulator">
|
||||||
@ -240,6 +248,7 @@ a.dropdown-toggle {
|
|||||||
<script src="javatari.js/release/javatari/javatari.js"></script>
|
<script src="javatari.js/release/javatari/javatari.js"></script>
|
||||||
<script src="src/emu.js"></script>
|
<script src="src/emu.js"></script>
|
||||||
<script src="src/util.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/vcs.js"></script>
|
||||||
<script src="src/platform/apple2.js"></script>
|
<script src="src/platform/apple2.js"></script>
|
||||||
<script src="src/platform/atarivec.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
|
// 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) {
|
function __createCanvas(mainElement, width, height) {
|
||||||
// TODO
|
// TODO
|
||||||
var fsElement = document.createElement('div');
|
var fsElement = document.createElement('div');
|
||||||
@ -36,6 +40,18 @@ var RasterVideo = function(mainElement, width, height, options) {
|
|||||||
datau32 = new Uint32Array(buf);
|
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() {
|
this.getFrameData = function() {
|
||||||
return datau32;
|
return datau32;
|
||||||
}
|
}
|
||||||
@ -104,10 +120,13 @@ var VectorVideo = function(mainElement, width, height) {
|
|||||||
|
|
||||||
this.setKeyboardEvents = function(callback) {
|
this.setKeyboardEvents = function(callback) {
|
||||||
canvas.onkeydown = function(e) {
|
canvas.onkeydown = function(e) {
|
||||||
callback(e.key, 1);
|
callback(e.which, 0, 1|_metakeyflags(e));
|
||||||
};
|
};
|
||||||
canvas.onkeyup = function(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];
|
buffer = bufferlist[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.stop = function() {
|
||||||
|
if (this.context) {
|
||||||
|
this.context.close();
|
||||||
|
this.context = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.feedSample = function(value, count) {
|
this.feedSample = function(value, count) {
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
accum += value;
|
accum += value;
|
||||||
|
@ -40,6 +40,7 @@ var Apple2Platform = function(mainElement) {
|
|||||||
ram = new RAM(0x13000); // 64K + 16K LC RAM - 4K hardware
|
ram = new RAM(0x13000); // 64K + 16K LC RAM - 4K hardware
|
||||||
// ROM
|
// ROM
|
||||||
var rom = new lzgmini().decode(APPLEIIGO_LZG).slice(0,0x3000);
|
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);
|
ram.mem.set(rom, 0xd000);
|
||||||
// bus
|
// bus
|
||||||
bus = {
|
bus = {
|
||||||
@ -134,6 +135,18 @@ var Apple2Platform = function(mainElement) {
|
|||||||
audio = new SampleAudio(cpuFrequency);
|
audio = new SampleAudio(cpuFrequency);
|
||||||
video.start();
|
video.start();
|
||||||
audio.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 idata = video.getFrameData();
|
||||||
var grparams = {dirty:grdirty, grswitch:grswitch, mem:ram.mem};
|
var grparams = {dirty:grdirty, grswitch:grswitch, mem:ram.mem};
|
||||||
ap2disp = new Apple2Display(idata, grparams);
|
ap2disp = new Apple2Display(idata, grparams);
|
||||||
@ -156,6 +169,7 @@ var Apple2Platform = function(mainElement) {
|
|||||||
grparams.grswitch = grswitch;
|
grparams.grswitch = grswitch;
|
||||||
ap2disp.updateScreen();
|
ap2disp.updateScreen();
|
||||||
video.updateFrame();
|
video.updateFrame();
|
||||||
|
// TODO: reset debug state
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,24 +227,29 @@ var Apple2Platform = function(mainElement) {
|
|||||||
writeinhibit = false;
|
writeinhibit = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// reset language card constants
|
setupLanguageCardConstants();
|
||||||
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
|
|
||||||
return noise();
|
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) {
|
this.getOpcodeMetadata = function(opcode, offset) {
|
||||||
return Javatari.getOpcodeMetadata(opcode, offset); // TODO
|
return Javatari.getOpcodeMetadata(opcode, offset); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadROM = function(title, data) {
|
this.loadROM = function(title, data) {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
//console.log('loadROM',hex(data.length));
|
||||||
ram.mem.set(data, PGM_BASE);
|
ram.mem.set(data, PGM_BASE);
|
||||||
/*
|
/*
|
||||||
if(data.length != 0x3000) {
|
if(data.length != 0x3000) {
|
||||||
@ -249,9 +268,11 @@ var Apple2Platform = function(mainElement) {
|
|||||||
}
|
}
|
||||||
this.pause = function() {
|
this.pause = function() {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
audio.stop();
|
||||||
}
|
}
|
||||||
this.resume = function() {
|
this.resume = function() {
|
||||||
timer.start();
|
timer.start();
|
||||||
|
audio.start();
|
||||||
}
|
}
|
||||||
this.reset = function() {
|
this.reset = function() {
|
||||||
cpu.reset();
|
cpu.reset();
|
||||||
@ -295,6 +316,7 @@ var Apple2Platform = function(mainElement) {
|
|||||||
}
|
}
|
||||||
this.breakpointHit = function() {
|
this.breakpointHit = function() {
|
||||||
debugBreakState = self.saveState();
|
debugBreakState = self.saveState();
|
||||||
|
debugBreakState.c.PC = (debugBreakState.c.PC-1) & 0xffff;
|
||||||
console.log("Breakpoint at clk", debugClock, "PC", debugBreakState.c.PC.toString(16));
|
console.log("Breakpoint at clk", debugClock, "PC", debugBreakState.c.PC.toString(16));
|
||||||
this.pause();
|
this.pause();
|
||||||
if (onBreakpointHit) {
|
if (onBreakpointHit) {
|
||||||
@ -304,7 +326,7 @@ var Apple2Platform = function(mainElement) {
|
|||||||
this.step = function() {
|
this.step = function() {
|
||||||
var previousPC = -1;
|
var previousPC = -1;
|
||||||
self.setDebugCondition(function() {
|
self.setDebugCondition(function() {
|
||||||
if (debugClock++ >= debugTargetClock) {
|
if (debugClock++ > debugTargetClock) {
|
||||||
var thisState = cpu.saveState();
|
var thisState = cpu.saveState();
|
||||||
if (previousPC < 0) {
|
if (previousPC < 0) {
|
||||||
previousPC = thisState.PC;
|
previousPC = thisState.PC;
|
||||||
@ -339,11 +361,20 @@ var Apple2Platform = function(mainElement) {
|
|||||||
this.loadState = function(state) {
|
this.loadState = function(state) {
|
||||||
cpu.loadState(state.c);
|
cpu.loadState(state.c);
|
||||||
ram.mem.set(state.b);
|
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() {
|
this.saveState = function() {
|
||||||
return {
|
return {
|
||||||
c:cpu.saveState(),
|
c:cpu.saveState(),
|
||||||
b:ram.mem.slice(0),
|
b:ram.mem.slice(0),
|
||||||
|
kbd:kbdlatch,
|
||||||
|
gr:grswitch,
|
||||||
|
lc:{s:auxRAMselected,b:auxRAMbank,w:writeinhibit},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
this.getRAMForState = function(state) {
|
||||||
@ -928,50 +959,52 @@ var apple2_charset = [
|
|||||||
|
|
||||||
// public domain ROM
|
// public domain ROM
|
||||||
var APPLEIIGO_LZG = [
|
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,
|
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,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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
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,
|
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,
|
||||||
25,62,27,52,30,52,14,245,3,251,3,98,250,98,250
|
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();
|
//cpu.executeInstruction();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
video.setKeyboardEvents(function(key,flags) {
|
video.setKeyboardEvents(function(key,code,flags) {
|
||||||
var KEY2ADDR = {
|
var KEY2ADDR = {
|
||||||
"Shift": 3,
|
16: 3, // shift
|
||||||
" ": 4,
|
32: 4, // space
|
||||||
"5": 8+0,
|
53: 8+0, // 5
|
||||||
"6": 8+1,
|
54: 8+1, // 6
|
||||||
"7": 8+2,
|
55: 8+2, // 7
|
||||||
"1": 8+3,
|
49: 8+3, // 1
|
||||||
"2": 8+4,
|
50: 8+4, // 2
|
||||||
ArrowUp: 8+5,
|
38: 8+5,
|
||||||
ArrowRight: 8+6,
|
39: 8+6,
|
||||||
ArrowLeft: 8+7,
|
37: 8+7,
|
||||||
};
|
};
|
||||||
var addr = KEY2ADDR[key];
|
var addr = KEY2ADDR[key];
|
||||||
console.log(key,flags,addr);
|
console.log(key,flags,addr);
|
||||||
|
@ -42,6 +42,8 @@ var VCSPlatform = function() {
|
|||||||
this.getPresets = function() { return VCS_PRESETS; }
|
this.getPresets = function() { return VCS_PRESETS; }
|
||||||
|
|
||||||
this.start = function() {
|
this.start = function() {
|
||||||
|
$("#dbg_timing").show();
|
||||||
|
$("#dbg_disasm").show();
|
||||||
Javatari.start();
|
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 current_preset_id = null;
|
||||||
var offset2line = null;
|
var offset2line = null;
|
||||||
var line2offset = null;
|
var line2offset = null;
|
||||||
|
var pcvisits;
|
||||||
var trace_pending_at_pc;
|
var trace_pending_at_pc;
|
||||||
var store;
|
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) {
|
function setCode(text) {
|
||||||
if (current_preset_id.endsWith(".pla"))
|
worker.postMessage({code:text, tool:getToolForFilename(current_preset_id)});
|
||||||
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'});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function arrayCompare(a,b) {
|
function arrayCompare(a,b) {
|
||||||
@ -261,11 +262,10 @@ function arrayCompare(a,b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
worker.onmessage = function(e) {
|
||||||
//console.log(e.data);
|
|
||||||
// errors?
|
// errors?
|
||||||
var gutters = $("#editor"); //.find(".CodeMirror-linenumber");
|
var toolbar = $("#notebook");
|
||||||
if (e.data.listing.errors.length > 0) {
|
if (e.data.listing.errors.length > 0) {
|
||||||
gutters.addClass("has-errors");
|
toolbar.addClass("has-errors");
|
||||||
editor.clearGutter("gutter-info");
|
editor.clearGutter("gutter-info");
|
||||||
for (info of e.data.listing.errors) {
|
for (info of e.data.listing.errors) {
|
||||||
var div = document.createElement("div");
|
var div = document.createElement("div");
|
||||||
@ -280,10 +280,10 @@ worker.onmessage = function(e) {
|
|||||||
}
|
}
|
||||||
current_output = null;
|
current_output = null;
|
||||||
} else {
|
} else {
|
||||||
gutters.removeClass("has-errors");
|
toolbar.removeClass("has-errors");
|
||||||
updatePreset(current_preset_id, editor.getValue()); // update persisted entry
|
updatePreset(current_preset_id, editor.getValue()); // update persisted entry
|
||||||
// load ROM
|
// load ROM
|
||||||
var rom = e.data.output.slice(2);
|
var rom = e.data.output;
|
||||||
var rom_changed = rom && !arrayCompare(rom, current_output);
|
var rom_changed = rom && !arrayCompare(rom, current_output);
|
||||||
if (rom_changed) {
|
if (rom_changed) {
|
||||||
try {
|
try {
|
||||||
@ -291,6 +291,7 @@ worker.onmessage = function(e) {
|
|||||||
//console.log("Loading ROM length", rom.length);
|
//console.log("Loading ROM length", rom.length);
|
||||||
platform.loadROM(getCurrentPresetTitle(), rom);
|
platform.loadROM(getCurrentPresetTitle(), rom);
|
||||||
current_output = rom;
|
current_output = rom;
|
||||||
|
pcvisits = {};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e); // TODO
|
console.log(e); // TODO
|
||||||
current_output = null;
|
current_output = null;
|
||||||
@ -382,6 +383,7 @@ function getTIAPosString() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lastDebugInfo;
|
var lastDebugInfo;
|
||||||
|
var lastDebugState;
|
||||||
|
|
||||||
function highlightDifferences(s1, s2) {
|
function highlightDifferences(s1, s2) {
|
||||||
var split1 = s1.split(/(\S+\s+)/).filter(function(n) {return n});
|
var split1 = s1.split(/(\S+\s+)/).filter(function(n) {return n});
|
||||||
@ -436,13 +438,16 @@ function showMemory(state) {
|
|||||||
function setupBreakpoint() {
|
function setupBreakpoint() {
|
||||||
// TODO
|
// TODO
|
||||||
platform.setupDebug(function(state) {
|
platform.setupDebug(function(state) {
|
||||||
|
lastDebugState = state;
|
||||||
var PC = state.c.PC;
|
var PC = state.c.PC;
|
||||||
var line = findLineForOffset(PC);
|
var line = findLineForOffset(PC);
|
||||||
if (line) {
|
if (line) {
|
||||||
console.log("BREAKPOINT", hex(PC), line);
|
console.log("BREAKPOINT", hex(PC), line);
|
||||||
setCurrentLine(line);
|
setCurrentLine(line);
|
||||||
}
|
}
|
||||||
|
pcvisits[PC] = pcvisits[PC] ? pcvisits[PC]+1 : 1;
|
||||||
showMemory(state);
|
showMemory(state);
|
||||||
|
updateDisassembly();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,6 +486,7 @@ function runToCursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearBreakpoint() {
|
function clearBreakpoint() {
|
||||||
|
lastDebugState = null;
|
||||||
platform.clearDebug();
|
platform.clearDebug();
|
||||||
$("#dbg_info").empty();
|
$("#dbg_info").empty();
|
||||||
showMemory();
|
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() {
|
function resetAndDebug() {
|
||||||
platform.reset();
|
platform.reset();
|
||||||
runToCursor();
|
runToCursor();
|
||||||
@ -685,6 +714,8 @@ function setupDebugControls(){
|
|||||||
$("#dbg_step").click(singleStep);
|
$("#dbg_step").click(singleStep);
|
||||||
$("#dbg_toline").click(runToCursor);
|
$("#dbg_toline").click(runToCursor);
|
||||||
$("#dbg_timing").click(traceTiming);
|
$("#dbg_timing").click(traceTiming);
|
||||||
|
$("#dbg_disasm").click(toggleDisassembly);
|
||||||
|
$("#disassembly").hide();
|
||||||
$(".dropdown-menu").collapse({toggle: false});
|
$(".dropdown-menu").collapse({toggle: false});
|
||||||
$("#item_new_file").click(_createNewFile);
|
$("#item_new_file").click(_createNewFile);
|
||||||
$("#item_share_file").click(_shareFile);
|
$("#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.open("GET", "fs65.js.metadata", false); // synchronous request
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
fsMeta = xhr.response;
|
fsMeta = xhr.response;
|
||||||
console.log("Fetched", fsMeta, fsBlob);
|
console.log("Loaded filesystem", fsMeta.files.length, 'files', fsBlob.size, 'bytes');
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupFS(FS) {
|
function setupFS(FS) {
|
||||||
@ -133,7 +133,7 @@ function assembleDASM(code) {
|
|||||||
var alst = FS.readFile("a.lst", {'encoding':'utf8'});
|
var alst = FS.readFile("a.lst", {'encoding':'utf8'});
|
||||||
//console.log(alst);
|
//console.log(alst);
|
||||||
var listing = parseDASMListing(alst, unresolved);
|
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
|
// TODO: not quite done
|
||||||
@ -160,7 +160,7 @@ function assembleACME(code) {
|
|||||||
console.log(alst);
|
console.log(alst);
|
||||||
console.log(asym);
|
console.log(asym);
|
||||||
var listing = parseDASMListing(alst, unresolved);
|
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) {
|
function compilePLASMA(code) {
|
||||||
@ -196,7 +196,7 @@ function parseCA65Listing(code, unresolved) {
|
|||||||
var linenum = parseInt(linem[4]);
|
var linenum = parseInt(linem[4]);
|
||||||
lines.push({
|
lines.push({
|
||||||
line:linenum,
|
line:linenum,
|
||||||
offset:offset + 0x6000, //TODO
|
offset:offset + 0x6048, //TODO: use map file
|
||||||
insns:null
|
insns:null
|
||||||
});
|
});
|
||||||
//console.log(linem, lastlinenum, lines[lines.length-1]);
|
//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']);
|
'-t', platform, '-o', 'main', '-m', 'main.map', 'main.o', platform+'.lib']);
|
||||||
var aout = FS.readFile("main", {encoding:'binary'});
|
var aout = FS.readFile("main", {encoding:'binary'});
|
||||||
var mapout = FS.readFile("main.map", {encoding:'utf8'});
|
var mapout = FS.readFile("main.map", {encoding:'utf8'});
|
||||||
|
// CODE 00603E 00637C 00033F 00001
|
||||||
console.log(lstout);
|
console.log(lstout);
|
||||||
console.log(mapout);
|
console.log(mapout);
|
||||||
return {exitstatus:LD65.EXITSTATUS, output:aout.slice(4), listing:parseCA65Listing(lstout)};
|
return {exitstatus:LD65.EXITSTATUS, output:aout.slice(4), listing:parseCA65Listing(lstout)};
|
||||||
|
Loading…
Reference in New Issue
Block a user