support multiple workspace windows; //#link "file"

This commit is contained in:
Steven Hugg 2018-07-02 07:34:20 -06:00
parent 4595ab7a31
commit 19a38a3c5e
11 changed files with 835 additions and 380 deletions

View File

@ -60,12 +60,20 @@ div.editor {
line-height:1.25;
font-size:12pt;
}
div.memdump {
background-color: #333;
color: #66ff66;
white-space: pre;
margin-top: 20px auto 0;
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
font-size: 10pt;
}
div.debugwindow {
position:absolute;
left:50%;
top:0;
width:50%;
background-color: #666;
background-color: #333;
color: #66ff66;
white-space: pre;
margin-top: 20px auto 0;
@ -133,9 +141,9 @@ div.booklink {
}
div.twitbtn {
position: fixed;
bottom: 0;
left: 50%;
padding: 6px;
bottom: 0%;
right: 0%;
padding: 10px;
}
a {
color:#333399;
@ -200,7 +208,7 @@ div.emulator {
width:100%;
height:100%;
padding:5%;
background:#333;
background:#555;
}
.emuvideo {
border-radius:20px;
@ -247,3 +255,19 @@ canvas.pixelated {
border-style:solid;
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
}
.nav-tabs > li > a.tab {
line-height: 1.0;
}
.twitter-follow-button,
.twitter-follow-button:focus {
border-width:3px;
border-color:#9999ff;
background-color:#333399;
border-style:solid;
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
color:#77aaaa;
padding:6px;
}
.twitter-follow-button:hover {
color:#99ffff;
}

View File

@ -11,6 +11,7 @@ TODO:
- debugging inside of bank switching??? relocated segs?
- support 6502 test cases
- DASM: macro forward refs
- asm: support macro expansion (need addr2line map)
- support narrow screens
- show other TIA internal values
- case sensisitvity looking for mismatch variables
@ -25,6 +26,7 @@ TODO:
- watchpoints
- breakpoints
- debug inspector
- better debug buttons
- MAME single step (?)
- step over
- slowdown beam for all platforms?
@ -33,6 +35,9 @@ TODO:
- show errors in list
- can't see 1st line in editor sometimes
- online help
- show self-modifying code insns left of editor
- facade/kbd shortcuts for emulators, focus
- checkmarks in pulldown menus
WEB WORKER FORMAT

View File

@ -81,8 +81,18 @@ ga('send', 'pageview');
</li>
</ul>
</span>
<select id="preset_select" name="">
</select>
<span class="dropdown">
<a class="btn btn-secondary dropdown-toggle" id="windowMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
&#9775; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="windowMenuButton" id="windowMenuList">
</ul>
</span>
<img id="compile_spinner" src="images/spinner.gif" height="20em" style="visibility:hidden;margin-left:8px;margin-right:8px">
<span class="btn_group debug_group" id="debug_bar">
<button id="dbg_reset" type="submit" title="Reset and Break"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
@ -106,8 +116,6 @@ ga('send', 'pageview');
<button id="dbg_disasm" type="submit" title="Show Disassembly" style="display:none"><span class="glyphicon glyphicon-list" aria-hidden="true"></span></button>
<button id="dbg_memory" type="submit" title="Show Memory" style="display:none"><span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span></button>
<button id="dbg_profile" type="submit" title="Show Profile" style="display:none"><span class="glyphicon glyphicon-stats" aria-hidden="true"></span></button>
</span>
<span class="btn_group view_group" id="tools_bar">
<button id="dbg_bitmap" type="submit" title="Edit Bitmap"><span class="glyphicon glyphicon-camera" aria-hidden="true"></span></button>
</span>
<span class="dropdown" style="float:right">
@ -135,10 +143,6 @@ ga('send', 'pageview');
</div>
<div id="notebook">
<div id="workspace">
<div id="disassembly" class="editor">
</div>
<div id="editor" class="editor">
</div>
</div>
<div class="emulator" id="emulator">
<div id="javatari-div" style="margin:10px; display:none">
@ -148,13 +152,9 @@ ga('send', 'pageview');
</div>
<div id="mem_info" class="mem_info" style="display:none">
</div>
<div id="profileview" class="debugwindow" style="display:none;z-index:10">
</div>
<div id="memoryview" class="debugwindow" style="display:none;z-index:10">
</div>
</div>
<div class="twitbtn">
<a href="https://twitter.com/8bitworkshop" class="twitter-follow-button" data-show-count="false">Follow @8bitworkshop</a>
<a target="_new" href="https://twitter.com/8bitworkshop" class="twitter-follow-button" data-show-count="false">Follow @8bitworkshop</a>
<!--<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>-->
</div>
<div id="pixeditback" class="pixeditback" style="display:none">

261
presets/vicdual/pc437.c Normal file
View File

@ -0,0 +1,261 @@
// PC font (code page 437)
const unsigned char font8x8[0x100][8] = {/*{w:8,h:8,bpp:1,count:256,xform:"scaleX(-1) rotate(90deg)"}*/
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x7e,0x81,0x95,0xb1,0xb1,0x95,0x81,0x7e },
{ 0x7e,0xff,0xeb,0xcf,0xcf,0xeb,0xff,0x7e },
{ 0x0e,0x1f,0x3f,0x7e,0x3f,0x1f,0x0e,0x00 },
{ 0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00 },
{ 0x38,0x3a,0x9f,0xff,0x9f,0x3a,0x38,0x00 },
{ 0x10,0x38,0xbc,0xff,0xbc,0x38,0x10,0x00 },
{ 0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00 },
{ 0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff },
{ 0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00 },
{ 0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff },
{ 0x70,0xf8,0x88,0x88,0xfd,0x7f,0x07,0x0f },
{ 0x00,0x4e,0x5f,0xf1,0xf1,0x5f,0x4e,0x00 },
{ 0xc0,0xe0,0xff,0x7f,0x05,0x05,0x07,0x07 },
{ 0xc0,0xff,0x7f,0x05,0x05,0x65,0x7f,0x3f },
{ 0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99 },
{ 0x7f,0x3e,0x3e,0x1c,0x1c,0x08,0x08,0x00 },
{ 0x08,0x08,0x1c,0x1c,0x3e,0x3e,0x7f,0x00 },
{ 0x00,0x24,0x66,0xff,0xff,0x66,0x24,0x00 },
{ 0x00,0x5f,0x5f,0x00,0x00,0x5f,0x5f,0x00 },
{ 0x06,0x0f,0x09,0x7f,0x7f,0x01,0x7f,0x7f },
{ 0xda,0xbf,0xa5,0xa5,0xfd,0x59,0x03,0x02 },
{ 0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00 },
{ 0x80,0x94,0xb6,0xff,0xff,0xb6,0x94,0x80 },
{ 0x00,0x04,0x06,0x7f,0x7f,0x06,0x04,0x00 },
{ 0x00,0x10,0x30,0x7f,0x7f,0x30,0x10,0x00 },
{ 0x08,0x08,0x08,0x2a,0x3e,0x1c,0x08,0x00 },
{ 0x08,0x1c,0x3e,0x2a,0x08,0x08,0x08,0x00 },
{ 0x3c,0x3c,0x20,0x20,0x20,0x20,0x20,0x00 },
{ 0x08,0x1c,0x3e,0x08,0x08,0x3e,0x1c,0x08 },
{ 0x30,0x38,0x3c,0x3e,0x3e,0x3c,0x38,0x30 },
{ 0x06,0x0e,0x1e,0x3e,0x3e,0x1e,0x0e,0x06 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x06,0x5f,0x5f,0x06,0x00,0x00,0x00 },
{ 0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00 },
{ 0x14,0x7f,0x7f,0x14,0x7f,0x7f,0x14,0x00 },
{ 0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00,0x00 },
{ 0x46,0x66,0x30,0x18,0x0c,0x66,0x62,0x00 },
{ 0x30,0x7a,0x4f,0x5d,0x37,0x7a,0x48,0x00 },
{ 0x04,0x07,0x03,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x1c,0x3e,0x63,0x41,0x00,0x00,0x00 },
{ 0x00,0x41,0x63,0x3e,0x1c,0x00,0x00,0x00 },
{ 0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08 },
{ 0x08,0x08,0x3e,0x3e,0x08,0x08,0x00,0x00 },
{ 0x00,0xa0,0xe0,0x60,0x00,0x00,0x00,0x00 },
{ 0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00 },
{ 0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00 },
{ 0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00 },
{ 0x3e,0x7f,0x59,0x4d,0x7f,0x3e,0x00,0x00 },
{ 0x42,0x42,0x7f,0x7f,0x40,0x40,0x00,0x00 },
{ 0x62,0x73,0x59,0x49,0x6f,0x66,0x00,0x00 },
{ 0x22,0x63,0x49,0x49,0x7f,0x36,0x00,0x00 },
{ 0x18,0x1c,0x16,0x13,0x7f,0x7f,0x10,0x00 },
{ 0x27,0x67,0x45,0x45,0x7d,0x39,0x00,0x00 },
{ 0x3c,0x7e,0x4b,0x49,0x79,0x30,0x00,0x00 },
{ 0x03,0x63,0x71,0x19,0x0f,0x07,0x00,0x00 },
{ 0x36,0x7f,0x49,0x49,0x7f,0x36,0x00,0x00 },
{ 0x06,0x4f,0x49,0x69,0x3f,0x1e,0x00,0x00 },
{ 0x00,0x00,0x6c,0x6c,0x00,0x00,0x00,0x00 },
{ 0x00,0xa0,0xec,0x6c,0x00,0x00,0x00,0x00 },
{ 0x08,0x1c,0x36,0x63,0x41,0x00,0x00,0x00 },
{ 0x14,0x14,0x14,0x14,0x14,0x14,0x00,0x00 },
{ 0x00,0x41,0x63,0x36,0x1c,0x08,0x00,0x00 },
{ 0x02,0x03,0x51,0x59,0x0f,0x06,0x00,0x00 },
{ 0x3e,0x7f,0x41,0x5d,0x5d,0x1f,0x1e,0x00 },
{ 0x7c,0x7e,0x13,0x13,0x7e,0x7c,0x00,0x00 },
{ 0x41,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00 },
{ 0x1c,0x3e,0x63,0x41,0x41,0x63,0x22,0x00 },
{ 0x41,0x7f,0x7f,0x41,0x63,0x7f,0x1c,0x00 },
{ 0x41,0x7f,0x7f,0x49,0x5d,0x41,0x63,0x00 },
{ 0x41,0x7f,0x7f,0x49,0x1d,0x01,0x03,0x00 },
{ 0x1c,0x3e,0x63,0x41,0x51,0x73,0x72,0x00 },
{ 0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00,0x00 },
{ 0x00,0x41,0x7f,0x7f,0x41,0x00,0x00,0x00 },
{ 0x30,0x70,0x40,0x41,0x7f,0x3f,0x01,0x00 },
{ 0x41,0x7f,0x7f,0x08,0x1c,0x77,0x63,0x00 },
{ 0x41,0x7f,0x7f,0x41,0x40,0x60,0x70,0x00 },
{ 0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f,0x00 },
{ 0x7f,0x7f,0x06,0x0c,0x18,0x7f,0x7f,0x00 },
{ 0x1c,0x3e,0x63,0x41,0x63,0x3e,0x1c,0x00 },
{ 0x41,0x7f,0x7f,0x49,0x09,0x0f,0x06,0x00 },
{ 0x1e,0x3f,0x21,0x71,0x7f,0x5e,0x00,0x00 },
{ 0x41,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00 },
{ 0x26,0x67,0x4d,0x59,0x7b,0x32,0x00,0x00 },
{ 0x03,0x41,0x7f,0x7f,0x41,0x03,0x00,0x00 },
{ 0x7f,0x7f,0x40,0x40,0x7f,0x7f,0x00,0x00 },
{ 0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00,0x00 },
{ 0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f,0x00 },
{ 0x63,0x77,0x1c,0x08,0x1c,0x77,0x63,0x00 },
{ 0x07,0x4f,0x78,0x78,0x4f,0x07,0x00,0x00 },
{ 0x67,0x73,0x59,0x4d,0x47,0x63,0x71,0x00 },
{ 0x00,0x7f,0x7f,0x41,0x41,0x00,0x00,0x00 },
{ 0x01,0x03,0x06,0x0c,0x18,0x30,0x60,0x00 },
{ 0x00,0x41,0x41,0x7f,0x7f,0x00,0x00,0x00 },
{ 0x08,0x0c,0x06,0x03,0x06,0x0c,0x08,0x00 },
{ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 },
{ 0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00 },
{ 0x20,0x74,0x54,0x54,0x3c,0x78,0x40,0x00 },
{ 0x41,0x3f,0x7f,0x44,0x44,0x7c,0x38,0x00 },
{ 0x38,0x7c,0x44,0x44,0x6c,0x28,0x00,0x00 },
{ 0x30,0x78,0x48,0x49,0x3f,0x7f,0x40,0x00 },
{ 0x38,0x7c,0x54,0x54,0x5c,0x18,0x00,0x00 },
{ 0x48,0x7e,0x7f,0x49,0x03,0x02,0x00,0x00 },
{ 0x98,0xbc,0xa4,0xa4,0xf8,0x7c,0x04,0x00 },
{ 0x41,0x7f,0x7f,0x08,0x04,0x7c,0x78,0x00 },
{ 0x00,0x44,0x7d,0x7d,0x40,0x00,0x00,0x00 },
{ 0x40,0xc4,0x84,0xfd,0x7d,0x00,0x00,0x00 },
{ 0x41,0x7f,0x7f,0x10,0x38,0x6c,0x44,0x00 },
{ 0x00,0x41,0x7f,0x7f,0x40,0x00,0x00,0x00 },
{ 0x7c,0x7c,0x0c,0x18,0x0c,0x7c,0x78,0x00 },
{ 0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00,0x00 },
{ 0x38,0x7c,0x44,0x44,0x7c,0x38,0x00,0x00 },
{ 0x84,0xfc,0xf8,0xa4,0x24,0x3c,0x18,0x00 },
{ 0x18,0x3c,0x24,0xa4,0xf8,0xfc,0x84,0x00 },
{ 0x44,0x7c,0x78,0x44,0x1c,0x18,0x00,0x00 },
{ 0x48,0x5c,0x54,0x54,0x74,0x24,0x00,0x00 },
{ 0x00,0x04,0x3e,0x7f,0x44,0x24,0x00,0x00 },
{ 0x3c,0x7c,0x40,0x40,0x3c,0x7c,0x40,0x00 },
{ 0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00,0x00 },
{ 0x3c,0x7c,0x60,0x30,0x60,0x7c,0x3c,0x00 },
{ 0x44,0x6c,0x38,0x10,0x38,0x6c,0x44,0x00 },
{ 0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00,0x00 },
{ 0x4c,0x64,0x74,0x5c,0x4c,0x64,0x00,0x00 },
{ 0x08,0x08,0x3e,0x77,0x41,0x41,0x00,0x00 },
{ 0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00 },
{ 0x41,0x41,0x77,0x3e,0x08,0x08,0x00,0x00 },
{ 0x02,0x03,0x01,0x03,0x02,0x03,0x01,0x00 },
{ 0x78,0x7c,0x46,0x43,0x46,0x7c,0x78,0x00 },
{ 0x0e,0x9f,0x91,0xb1,0xfb,0x4a,0x00,0x00 },
{ 0x3a,0x7a,0x40,0x40,0x7a,0x7a,0x40,0x00 },
{ 0x38,0x7c,0x54,0x55,0x5d,0x19,0x00,0x00 },
{ 0x02,0x23,0x75,0x55,0x55,0x7d,0x7b,0x42 },
{ 0x21,0x75,0x54,0x54,0x7d,0x79,0x40,0x00 },
{ 0x21,0x75,0x55,0x54,0x7c,0x78,0x40,0x00 },
{ 0x20,0x74,0x57,0x57,0x7c,0x78,0x40,0x00 },
{ 0x18,0x3c,0xa4,0xa4,0xa4,0xe4,0x40,0x00 },
{ 0x02,0x3b,0x7d,0x55,0x55,0x5d,0x1b,0x02 },
{ 0x39,0x7d,0x54,0x54,0x5d,0x19,0x00,0x00 },
{ 0x39,0x7d,0x55,0x54,0x5c,0x18,0x00,0x00 },
{ 0x01,0x45,0x7c,0x7c,0x41,0x01,0x00,0x00 },
{ 0x02,0x03,0x45,0x7d,0x7d,0x43,0x02,0x00 },
{ 0x01,0x45,0x7d,0x7c,0x40,0x00,0x00,0x00 },
{ 0x79,0x7d,0x26,0x26,0x7d,0x79,0x00,0x00 },
{ 0x70,0x78,0x2b,0x2b,0x78,0x70,0x00,0x00 },
{ 0x44,0x7c,0x7c,0x55,0x55,0x45,0x00,0x00 },
{ 0x20,0x74,0x54,0x54,0x7c,0x7c,0x54,0x54 },
{ 0x7c,0x7e,0x0b,0x09,0x7f,0x7f,0x49,0x00 },
{ 0x32,0x7b,0x49,0x49,0x7b,0x32,0x00,0x00 },
{ 0x32,0x7a,0x48,0x48,0x7a,0x32,0x00,0x00 },
{ 0x32,0x7a,0x4a,0x48,0x78,0x30,0x00,0x00 },
{ 0x3a,0x7b,0x41,0x41,0x7b,0x7a,0x40,0x00 },
{ 0x3a,0x7a,0x42,0x40,0x78,0x78,0x40,0x00 },
{ 0xba,0xba,0xa0,0xa0,0xfa,0x7a,0x00,0x00 },
{ 0x19,0x3d,0x66,0x66,0x66,0x3d,0x19,0x00 },
{ 0x3d,0x7d,0x40,0x40,0x7d,0x3d,0x00,0x00 },
{ 0x18,0x3c,0x24,0xe7,0xe7,0x24,0x24,0x00 },
{ 0x68,0x7e,0x7f,0x49,0x43,0x66,0x20,0x00 },
{ 0x2b,0x2f,0x7c,0x7c,0x2f,0x2b,0x00,0x00 },
{ 0x7f,0x7f,0x09,0x2f,0xf6,0xf8,0xa0,0x00 },
{ 0x40,0xc8,0x88,0xfe,0x7f,0x09,0x0b,0x02 },
{ 0x20,0x74,0x54,0x55,0x7d,0x79,0x40,0x00 },
{ 0x00,0x44,0x7d,0x7d,0x41,0x00,0x00,0x00 },
{ 0x30,0x78,0x48,0x4a,0x7a,0x32,0x00,0x00 },
{ 0x38,0x78,0x40,0x42,0x7a,0x7a,0x40,0x00 },
{ 0x7a,0x7a,0x0a,0x0a,0x7a,0x70,0x00,0x00 },
{ 0x7d,0x7d,0x19,0x31,0x7d,0x7d,0x00,0x00 },
{ 0x00,0x26,0x2f,0x29,0x2f,0x2f,0x28,0x00 },
{ 0x00,0x26,0x2f,0x29,0x29,0x2f,0x26,0x00 },
{ 0x30,0x78,0x4d,0x45,0x60,0x20,0x00,0x00 },
{ 0x38,0x38,0x08,0x08,0x08,0x08,0x00,0x00 },
{ 0x08,0x08,0x08,0x08,0x38,0x38,0x00,0x00 },
{ 0x67,0x37,0x18,0xcc,0xee,0xab,0xb9,0x90 },
{ 0x6f,0x3f,0x18,0x4c,0x66,0x73,0xf9,0xf8 },
{ 0x00,0x00,0x60,0xfa,0xfa,0x60,0x00,0x00 },
{ 0x08,0x1c,0x36,0x22,0x08,0x1c,0x36,0x22 },
{ 0x22,0x36,0x1c,0x08,0x22,0x36,0x1c,0x08 },
{ 0xaa,0x00,0x55,0x00,0xaa,0x00,0x55,0x00 },
{ 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55 },
{ 0x55,0xff,0xaa,0xff,0x55,0xff,0xaa,0xff },
{ 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00 },
{ 0x10,0x10,0x10,0xff,0xff,0x00,0x00,0x00 },
{ 0x14,0x14,0x14,0xff,0xff,0x00,0x00,0x00 },
{ 0x10,0x10,0xff,0xff,0x00,0xff,0xff,0x00 },
{ 0x10,0x10,0xf0,0xf0,0x10,0xf0,0xf0,0x00 },
{ 0x14,0x14,0x14,0xfc,0xfc,0x00,0x00,0x00 },
{ 0x14,0x14,0xf7,0xf7,0x00,0xff,0xff,0x00 },
{ 0x00,0x00,0xff,0xff,0x00,0xff,0xff,0x00 },
{ 0x14,0x14,0xf4,0xf4,0x04,0xfc,0xfc,0x00 },
{ 0x14,0x14,0x17,0x17,0x10,0x1f,0x1f,0x00 },
{ 0x10,0x10,0x1f,0x1f,0x10,0x1f,0x1f,0x00 },
{ 0x14,0x14,0x14,0x1f,0x1f,0x00,0x00,0x00 },
{ 0x10,0x10,0x10,0xf0,0xf0,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x1f,0x1f,0x10,0x10,0x10 },
{ 0x10,0x10,0x10,0x1f,0x1f,0x10,0x10,0x10 },
{ 0x10,0x10,0x10,0xf0,0xf0,0x10,0x10,0x10 },
{ 0x00,0x00,0x00,0xff,0xff,0x10,0x10,0x10 },
{ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 },
{ 0x10,0x10,0x10,0xff,0xff,0x10,0x10,0x10 },
{ 0x00,0x00,0x00,0xff,0xff,0x14,0x14,0x14 },
{ 0x00,0x00,0xff,0xff,0x00,0xff,0xff,0x10 },
{ 0x00,0x00,0x1f,0x1f,0x10,0x17,0x17,0x14 },
{ 0x00,0x00,0xfc,0xfc,0x04,0xf4,0xf4,0x14 },
{ 0x14,0x14,0x17,0x17,0x10,0x17,0x17,0x14 },
{ 0x14,0x14,0xf4,0xf4,0x04,0xf4,0xf4,0x14 },
{ 0x00,0x00,0xff,0xff,0x00,0xf7,0xf7,0x14 },
{ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14 },
{ 0x14,0x14,0xf7,0xf7,0x00,0xf7,0xf7,0x14 },
{ 0x14,0x14,0x14,0x17,0x17,0x14,0x14,0x14 },
{ 0x10,0x10,0x1f,0x1f,0x10,0x1f,0x1f,0x10 },
{ 0x14,0x14,0x14,0xf4,0xf4,0x14,0x14,0x14 },
{ 0x10,0x10,0xf0,0xf0,0x10,0xf0,0xf0,0x10 },
{ 0x00,0x00,0x1f,0x1f,0x10,0x1f,0x1f,0x10 },
{ 0x00,0x00,0x00,0x1f,0x1f,0x14,0x14,0x14 },
{ 0x00,0x00,0x00,0xfc,0xfc,0x14,0x14,0x14 },
{ 0x00,0x00,0xf0,0xf0,0x10,0xf0,0xf0,0x10 },
{ 0x10,0x10,0xff,0xff,0x00,0xff,0xff,0x10 },
{ 0x14,0x14,0x14,0xf7,0xf7,0x14,0x14,0x14 },
{ 0x10,0x10,0x10,0x1f,0x1f,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0xf0,0xf0,0x10,0x10,0x10 },
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
{ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0 },
{ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff },
{ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f },
{ 0x38,0x7c,0x44,0x6c,0x38,0x6c,0x44,0x00 },
{ 0xfc,0xfe,0x2a,0x2a,0x3e,0x14,0x00,0x00 },
{ 0x7e,0x7e,0x02,0x02,0x02,0x06,0x06,0x00 },
{ 0x02,0x7e,0x7e,0x02,0x7e,0x7e,0x02,0x00 },
{ 0x41,0x63,0x77,0x5d,0x49,0x63,0x63,0x00 },
{ 0x38,0x7c,0x44,0x44,0x7c,0x3c,0x04,0x00 },
{ 0x80,0xfe,0x7e,0x20,0x20,0x3e,0x1e,0x00 },
{ 0x04,0x06,0x02,0x7e,0x7c,0x06,0x02,0x00 },
{ 0x99,0xbd,0xe7,0xe7,0xbd,0x99,0x00,0x00 },
{ 0x1c,0x3e,0x6b,0x49,0x6b,0x3e,0x1c,0x00 },
{ 0x4c,0x7e,0x73,0x01,0x73,0x7e,0x4c,0x00 },
{ 0x30,0x78,0x4a,0x4f,0x7d,0x39,0x00,0x00 },
{ 0x18,0x3c,0x24,0x3c,0x3c,0x24,0x3c,0x18 },
{ 0x98,0xfc,0x64,0x3c,0x3e,0x27,0x3d,0x18 },
{ 0x1c,0x3e,0x6b,0x49,0x49,0x49,0x00,0x00 },
{ 0x7e,0x7f,0x01,0x01,0x7f,0x7e,0x00,0x00 },
{ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x00,0x00 },
{ 0x44,0x44,0x5f,0x5f,0x44,0x44,0x00,0x00 },
{ 0x40,0x51,0x5b,0x4e,0x44,0x40,0x00,0x00 },
{ 0x40,0x44,0x4e,0x5b,0x51,0x40,0x00,0x00 },
{ 0x00,0x00,0x00,0xfe,0xff,0x01,0x07,0x06 },
{ 0x60,0xe0,0x80,0xff,0x7f,0x00,0x00,0x00 },
{ 0x08,0x08,0x6b,0x6b,0x08,0x08,0x00,0x00 },
{ 0x24,0x12,0x12,0x36,0x24,0x24,0x12,0x00 },
{ 0x00,0x06,0x0f,0x09,0x0f,0x06,0x00,0x00 },
{ 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00 },
{ 0x10,0x30,0x70,0xc0,0xff,0xff,0x01,0x01 },
{ 0x00,0x1f,0x1f,0x01,0x1f,0x1e,0x00,0x00 },
{ 0x00,0x19,0x1d,0x15,0x17,0x12,0x00,0x00 },
{ 0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
};

File diff suppressed because one or more lines are too long

View File

@ -29,6 +29,9 @@ function SourceFile(lines, text) {
function CodeProject(worker, platform_id, platform, store) {
var self = this;
var filedata = {};
var listings;
self.callbackResendFiles = function() { }; // TODO?
self.callbackBuildResult = function(result) { };
@ -46,36 +49,41 @@ function CodeProject(worker, platform_id, platform, store) {
}
// TODO: get local file as well as presets?
self.loadFiles = function(filenames, callback) {
self.loadFiles = function(paths, callback) {
var result = [];
function loadNext() {
var fn = filenames.shift();
if (!fn) {
var path = paths.shift();
if (!path) {
callback(null, result); // TODO?
} else {
store.getItem(fn, function(err, value) {
store.getItem(path, function(err, value) {
if (err) {
callback(err);
} else if (value) {
result.push({
path:fn,
path:path,
filename:getFilenameForPath(path),
data:value
});
filedata[path] = value;
loadNext();
} else {
var webpath = "presets/" + platform_id + "/" + fn;
if (platform_id == 'vcs' && fn.indexOf('.') <= 0)
var webpath = "presets/" + platform_id + "/" + path;
if (platform_id == 'vcs' && path.indexOf('.') <= 0)
webpath += ".a"; // legacy stuff
// TODO: cache files
$.get( webpath, function( text ) {
console.log("GET",webpath,text.length,'bytes');
result.push({
path:fn,
path:path,
filename:getFilenameForPath(path),
data:text
});
filedata[path] = text;
loadNext();
}, 'text')
.fail(function() {
callback("Could not load preset " + fn);
callback("Could not load preset " + path);
});
}
});
@ -83,34 +91,28 @@ function CodeProject(worker, platform_id, platform, store) {
}
loadNext(); // load first file
}
// TODO: merge with loadFiles()
function loadFileDependencies(text, callback) {
var filenames = [];
function parseFileDependencies(text) {
var files = [];
if (platform_id == 'verilog') {
var re = /^(`include|[.]include)\s+"(.+?)"/gm;
var m;
while (m = re.exec(text)) {
filenames.push(m[2]);
files.push(m[2]);
}
} else {
var re = /^([;#]|[/][/][#])link\s+"(.+?)"/gm;
var m;
while (m = re.exec(text)) {
files.push(m[2]);
}
}
var result = [];
function loadNextDependency() {
var fn = filenames.shift();
if (!fn) {
callback(result);
} else {
store.getItem(fn, function(err, value) {
result.push({
filename:fn,
prefix:platform_id,
text:value // might be null, that's ok
});
loadNextDependency();
});
}
}
loadNextDependency(); // load first dependency
return files;
}
function loadFileDependencies(text, callback) {
var paths = parseFileDependencies(text);
self.loadFiles(paths, callback);
}
function okToSend() {
@ -124,27 +126,65 @@ function CodeProject(worker, platform_id, platform, store) {
store.setItem(path, text);
}
}
// TODO: test duplicate files, local paths mixed with presets
function buildWorkerMessage(mainpath, maintext, depends) {
var msg = {updates:[], buildsteps:[]};
// TODO: add preproc directive for __MAINFILE__
msg.updates.push({path:getFilenameForPath(mainpath), data:maintext});
msg.buildsteps.push({path:getFilenameForPath(mainpath), platform:platform_id, tool:platform.getToolForFilename(mainpath), mainfile:true});
for (var i=0; i<depends.length; i++) {
var dep = depends[i];
if (dep.data) {
msg.updates.push({path:dep.filename, data:dep.data});
msg.buildsteps.push({path:dep.filename, platform:platform_id, tool:platform.getToolForFilename(dep.path)});
}
}
return msg;
}
self.getFile = function(path) {
return filedata[path];
}
self.iterateFiles = function(callback) {
for (var path in filedata) {
callback(path, self.getFile(path));
}
}
self.updateFile = function(path, text, isBinary) {
updateFileInStore(path, text); // TODO: isBinary
filedata[path] = text;
if (okToSend()) {
self.callbackBuildStatus(true);
preloadWorker(path);
loadFileDependencies(text, function(depends) {
worker.postMessage({
code:text,
dependencies:depends,
platform:platform_id,
tool:platform.getToolForFilename(path)
});
loadFileDependencies(text, function(err, depends) {
if (err) {
console.log(err); // TODO?
}
if (platform_id != 'verilog') {
var workermsg = buildWorkerMessage(path, text, depends);
worker.postMessage(workermsg);
} else {
// TODO: should get rid of this msg format
worker.postMessage({
code:text,
dependencies:depends,
platform:platform_id,
tool:platform.getToolForFilename(path)
});
}
});
}
};
self.processBuildResult = function(data) {
if (data.listings) {
for (var lstname in data.listings) {
var lst = data.listings[lstname];
// TODO: link listings with source files
listings = data.listings;
if (listings) {
for (var lstname in listings) {
var lst = listings[lstname];
if (lst.lines)
lst.sourcefile = new SourceFile(lst.lines);
if (lst.asmlines)
@ -152,6 +192,10 @@ function CodeProject(worker, platform_id, platform, store) {
}
}
}
self.getListings = function() {
return listings;
}
worker.onmessage = function(e) {
if (pendingWorkerMessages > 1) {
@ -166,7 +210,5 @@ function CodeProject(worker, platform_id, platform, store) {
self.callbackBuildResult(e.data); // call with data when changed
}
};
// TODO: parse output, listings, files, etc
}

685
src/ui.js
View File

@ -56,14 +56,6 @@ function newWorker() {
return new Worker("./src/worker/workermain.js");
}
var disasmview = CodeMirror(document.getElementById('disassembly'), {
mode: 'z80',
theme: 'cobalt',
tabSize: 8,
readOnly: true,
styleActiveLine: true
});
var userPaused;
var active_editor;
@ -77,15 +69,11 @@ var addr2symbol;
var compparams;
var trace_pending_at_pc;
var store;
//scrollProfileView(disasmview);
var currentDebugLine;
var lastDebugInfo;
var lastDebugState;
var memorylist;
var dumplines;
function inspectVariable(ed, name) {
var val;
if (platform.inspect) {
@ -110,10 +98,12 @@ function setLastPreset(id) {
function initProject() {
current_project = new CodeProject(newWorker(), platform_id, platform, store);
current_project.callbackResendFiles = function() {
setCode(getActiveEditor().getValue()); // TODO
current_project.updateFile(getActiveEditor().getPath(), getActiveEditor().getValue(), false);
// TODO: let CodeProject handle this
};
current_project.callbackBuildResult = function(result) {
setCompileOutput(result);
refreshWindowList();
};
current_project.callbackBuildStatus = function(busy) {
if (busy) {
@ -128,21 +118,23 @@ function initProject() {
}
// TODO: remove some calls of global functions
function SourceEditor(path) {
function SourceEditor(path, mode) {
var self = this;
var editor;
function deleteEditor() {
if (editor) {
$("#editor").empty();
editor = null;
}
self.createDiv = function(parent, text) {
var div = document.createElement('div');
div.setAttribute("class", "editor");
parent.appendChild(div);
newEditor(div);
if (text)
self.setText(text); // TODO: this calls setCode() and builds... it shouldn't
return div;
}
function newEditor(mode) {
deleteEditor();
function newEditor(parent) {
var isAsm = mode=='6502' || mode =='z80' || mode=='verilog' || mode=='gas'; // TODO
editor = CodeMirror(document.getElementById('editor'), {
editor = CodeMirror(parent, {
theme: 'mbo',
lineNumbers: true,
matchBrackets: true,
@ -155,7 +147,7 @@ function SourceEditor(path) {
editor.on('changes', function(ed, changeobj) {
clearTimeout(timer);
timer = setTimeout(function() {
setCode(editor.getValue());
current_project.updateFile(path, editor.getValue(), false);
}, 200);
});
editor.on('cursorActivity', function(ed) {
@ -173,18 +165,16 @@ function SourceEditor(path) {
}
self.setText = function(text) {
// TODO: refactor out all of this
var tool = platform.getToolForFilename(path);
newEditor(tool && TOOL_TO_SOURCE_STYLE[tool]);
editor.setValue(text); // calls setCode()
editor.clearHistory();
current_output = null;
setLastPreset(path);
current_output = null; // TODO?
}
self.getValue = function() {
return editor.getValue();
}
self.getPath = function() { return path; }
var lines2errmsg = [];
self.addErrorMarker = function(line, msg) {
@ -276,6 +266,19 @@ function SourceEditor(path) {
currentDebugLine = 0;
}
}
self.refresh = function() {
var state = lastDebugState;
if (state && state.c) {
var PC = state.c.PC;
var line = sourcefile.findLineForOffset(PC);
if (line >= 0) {
console.log("BREAKPOINT", hex(PC), line);
getActiveEditor().setCurrentLine(line);
// TODO: switch to disasm
}
}
}
self.getLine = function(line) {
return editor.getLine(line-1);
@ -358,11 +361,360 @@ function SourceEditor(path) {
}
// TODO: support multiple editors
function DisassemblerView() {
var self = this;
var disasmview;
self.createDiv = function(parent) {
var div = document.createElement('div');
div.setAttribute("class", "editor");
parent.appendChild(div);
newEditor(div);
return div;
}
function newEditor(parent) {
disasmview = CodeMirror(parent, {
mode: 'z80',
theme: 'cobalt',
tabSize: 8,
readOnly: true,
styleActiveLine: true
});
}
// TODO: too many globals
self.refresh = function() {
var state = lastDebugState || platform.saveState();
var pc = state.c ? state.c.PC : 0;
// do we have an assembly listing?
if (assemblyfile && assemblyfile.text) {
var asmtext = assemblyfile.text;
if (platform_id == 'base_z80') { // TODO
asmtext = asmtext.replace(/[ ]+\d+\s+;.+\n/g, '');
asmtext = asmtext.replace(/[ ]+\d+\s+.area .+\n/g, '');
}
disasmview.setValue(asmtext);
var findPC = platform.getDebugCallback() ? pc : -1;
if (findPC >= 0) {
var lineno = assemblyfile.findLineForOffset(findPC);
if (lineno) {
// set cursor while debugging
if (platform.getDebugCallback())
disasmview.setCursor(lineno-1, 0);
jumpToLine(disasmview, lineno-1);
return; // success, don't disassemble in next step
}
}
}
// TODO: fall through to platform disassembler?
else if (platform.disassemble) {
var curline = 0;
var selline = 0;
// TODO: not perfect disassembler
function disassemble(start, end) {
if (start < 0) start = 0;
if (end > 0xffff) end = 0xffff;
// TODO: use pc2visits
var a = start;
var s = "";
while (a < end) {
var disasm = platform.disassemble(a, platform.readAddress);
var srclinenum = sourcefile.offset2line[a];
if (srclinenum) {
var srcline = getActiveEditor().getLine(srclinenum); // TODO!
if (srcline && srcline.trim().length) {
s += "; " + srclinenum + ":\t" + srcline + "\n";
curline++;
}
}
var bytes = "";
for (var i=0; i<disasm.nbytes; i++)
bytes += hex(platform.readAddress(a+i));
while (bytes.length < 14)
bytes += ' ';
var dline = hex(parseInt(a)) + "\t" + bytes + "\t" + disasm.line + "\n";
s += dline;
if (a == pc) selline = curline;
curline++;
a += disasm.nbytes || 1;
}
return s;
}
var text = disassemble(pc-96, pc) + disassemble(pc, pc+96);
disasmview.setValue(text);
disasmview.setCursor(selline, 0);
jumpToLine(disasmview, selline);
} else if (current_output && current_output.code) {
// show verilog javascript
disasmview.setValue(current_output.code);
}
}
}
function MemoryView() {
var self = this;
var memorylist;
var dumplines;
var div;
// TODO?
function getVisibleEditorLineHeight() {
return $(".CodeMirror-line:visible").first().height();
}
self.createDiv = function(parent) {
div = document.createElement('div');
div.setAttribute("class", "memdump");
parent.appendChild(div);
showMemoryWindow(div);
return div;
}
function showMemoryWindow(parent) {
memorylist = new VirtualList({
w:$("#workspace").width(),
h:$("#workspace").height(),
itemHeight: getVisibleEditorLineHeight(),
totalRows: 0x1000,
generatorFn: function(row) {
var s = getMemoryLineAt(row);
var div = document.createElement("div");
if (dumplines) {
var dlr = dumplines[row];
if (dlr) div.classList.add('seg_' + getMemorySegment(dumplines[row].a));
}
div.appendChild(document.createTextNode(s));
return div;
}
});
$(parent).append(memorylist.container);
self.tick();
if (compparams && dumplines)
memorylist.scrollToItem(findMemoryWindowLine(compparams.data_start));
}
self.tick = function() {
if (memorylist) {
$(div).find('[data-index]').each(function(i,e) {
var div = $(e);
var row = div.attr('data-index');
var oldtext = div.text();
var newtext = getMemoryLineAt(row);
if (oldtext != newtext)
div.text(newtext);
});
}
}
function getMemoryLineAt(row) {
var offset = row * 16;
var n1 = 0;
var n2 = 16;
var sym;
if (getDumpLines()) {
var dl = dumplines[row];
if (dl) {
offset = dl.a & 0xfff0;
n1 = dl.a - offset;
n2 = n1 + dl.l;
sym = dl.s;
} else {
return '.';
}
}
var s = hex(offset,4) + ' ';
for (var i=0; i<n1; i++) s += ' ';
if (n1 > 8) s += ' ';
for (var i=n1; i<n2; i++) {
var read = platform.readAddress(offset+i);
if (i==8) s += ' ';
s += ' ' + (read>=0?hex(read,2):'??');
}
for (var i=n2; i<16; i++) s += ' ';
if (sym) s += ' ' + sym;
return s;
}
function getDumpLineAt(line) {
var d = dumplines[line];
if (d) {
return d.a + " " + d.s;
}
}
var IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
// TODO: addr2symbol for ca65; and make it work without symbols
function getDumpLines() {
if (!dumplines && addr2symbol) {
dumplines = [];
var ofs = 0;
var sym;
for (var nextofs in addr2symbol) {
nextofs |= 0;
var nextsym = addr2symbol[nextofs];
if (sym) {
if (IGNORE_SYMS[sym]) {
ofs = nextofs;
} else {
while (ofs < nextofs) {
var ofs2 = (ofs + 16) & 0xffff0;
if (ofs2 > nextofs) ofs2 = nextofs;
//if (ofs < 1000) console.log(ofs, ofs2, nextofs, sym);
dumplines.push({a:ofs, l:ofs2-ofs, s:sym});
ofs = ofs2;
}
}
}
sym = nextsym;
}
}
return dumplines;
}
function getMemorySegment(a) {
if (!compparams) return 'unknown';
if (a >= compparams.data_start && a < compparams.data_start+compparams.data_size) {
if (platform.getSP && a >= platform.getSP() - 15)
return 'stack';
else
return 'data';
}
else if (a >= compparams.code_start && a < compparams.code_start+compparams.code_size)
return 'code';
else
return 'unknown';
}
function findMemoryWindowLine(a) {
for (var i=0; i<dumplines.length; i++)
if (dumplines[i].a >= a)
return i;
}
}
/////
function ProjectWindows(containerdiv) {
var id2window = {};
var id2createfn = {};
var id2div = {};
var activewnd;
var activediv;
this.setCreateFunc = function(id, createfn) {
id2createfn[id] = createfn;
}
this.createOrShow = function(id) {
var wnd = id2window[id];
if (!wnd) {
wnd = id2window[id] = id2createfn[id](id);
}
var div = id2div[id];
if (!div) {
div = id2div[id] = wnd.createDiv(containerdiv, current_project.getFile(id));
}
if (activewnd != wnd) {
if (activediv)
$(activediv).hide();
activediv = div;
activewnd = wnd;
$(div).show();
this.refresh();
}
return wnd;
}
this.put = function(id, window, category) {
id2window[id] = window;
if (!categories[category])
categories[category] = [];
// TODO: remove/replace window
if (!(id in categories[category]))
categories[category].push(id);
}
this.filesForCategory = function(id) {
return categories[id] || [];
}
this.refresh = function() {
if (activewnd && activewnd.refresh)
activewnd.refresh();
}
this.tick = function() {
if (activewnd && activewnd.tick)
activewnd.tick();
}
};
var projectWindows = new ProjectWindows($("#workspace")[0]);
// TODO: support multiple editors, this might should go
function getActiveEditor() {
return active_editor;
}
function refreshWindowList() {
var ul = $("#windowMenuList").empty();
var separate = false;
function addWindowItem(id, name, createfn) {
if (separate) {
ul.append(document.createElement("hr"));
separate = false;
}
var li = document.createElement("li");
var a = document.createElement("a");
a.setAttribute("class", "dropdown-item");
a.setAttribute("href", "#");
a.appendChild(document.createTextNode(name));
li.appendChild(a);
ul.append(li);
if (createfn) {
projectWindows.setCreateFunc(id, createfn);
$(a).click(function() {
projectWindows.createOrShow(id);
});
}
}
function loadEditor(path) {
var tool = platform.getToolForFilename(path);
var mode = tool && TOOL_TO_SOURCE_STYLE[tool];
return new SourceEditor(path, mode, current_project.getFile(path));
}
// add main file editor
var id = current_file_id;
addWindowItem(id, getFilenameForPath(id), loadEditor);
// add other files
separate = true;
current_project.iterateFiles(function(id, text) {
if (id != current_file_id)
addWindowItem(id, getFilenameForPath(id), loadEditor);
});
// add other tools
separate = true;
if (platform.saveState) { // TODO: only show if listing or disasm available
addWindowItem("#disasm", "Disassembly", function() {
return new DisassemblerView();
});
}
// TODO
if (platform.readAddress && platform_id != 'vcs') {
addWindowItem("#memory", "Memory Browser", function() {
return new MemoryView();
});
}
}
// can pass integer or string id
function loadProject(preset_id) {
var index = parseInt(preset_id+""); // might fail -1
@ -377,13 +729,15 @@ function loadProject(preset_id) {
}
// set current file ID
current_file_id = preset_id;
setLastPreset(preset_id);
// load files from storage or web URLs
current_project.loadFiles([preset_id], function(err, result) {
if (err) {
alert(err);
} else if (result && result.length) {
active_editor = new SourceEditor(preset_id);
active_editor.setText(result[0].data); // TODO
refreshWindowList();
// show main file (need create window list first)
active_editor = projectWindows.createOrShow(preset_id);
}
});
}
@ -400,8 +754,8 @@ function getSkeletonFile(fileid, callback) {
callback(null, text);
}, 'text')
.fail(function() {
alert("Could not load skeleton for " + platform_id + "/" + ext);
callback(null, '');
alert("Could not load skeleton for " + platform_id + "/" + ext + "; using blank file");
callback(null, '\n');
});
}
@ -415,10 +769,10 @@ function _createNewFile(e) {
getSkeletonFile(path, function(err, result) {
if (result) {
store.setItem(path, result, function(err, result) {
if (err) alert(err+"");
if (result) {
if (err)
alert(err+"");
if (result != null)
reloadPresetNamed("local/" + filename);
}
});
}
});
@ -560,14 +914,10 @@ function updateSelector() {
});
}
// TODO
function setCode(text) {
current_project.updateFile(current_file_id, text, false);
}
function setCompileOutput(data) {
// TODO: support multiple edit windows
var sed = getActiveEditor();
// errors?
// errors? mark them in editor
if (data.errors && data.errors.length > 0) {
sed.markErrors(data.errors);
} else {
@ -619,7 +969,7 @@ function setCompileOutput(data) {
if (rom_changed || trace_pending_at_pc) {
sed.updateListing(sourcefile);
}
updateDisassembly();
projectWindows.refresh();
if (trace_pending_at_pc) {
showLoopTimingForPC(trace_pending_at_pc);
}
@ -650,19 +1000,8 @@ function setupBreakpoint() {
// TODO
platform.setupDebug(function(state) {
lastDebugState = state;
if (state.c) {
var PC = state.c.PC;
var line = sourcefile.findLineForOffset(PC);
if (line >= 0) {
console.log("BREAKPOINT", hex(PC), line);
getActiveEditor().setCurrentLine(line); // TODO
} else {
console.log("BREAKPOINT", hex(PC));
// TODO: switch to disasm
}
}
showMemory(state);
updateDisassembly();
projectWindows.refresh();
});
}
@ -709,7 +1048,7 @@ function singleFrameStep() {
platform.runToVsync();
}
// TODO: fix these
function getDisasmViewPC() {
var line = disasmview.getCursor().line;
if (line >= 0) {
@ -720,7 +1059,8 @@ function getDisasmViewPC() {
}
}
function getCurrentPC() {
// TODO: fix this
function getEditorPC() {
var line = getActiveEditor().getCurrentLine(); // TODO
while (line >= 0) {
// TODO: what if in disassembler?
@ -733,7 +1073,7 @@ function getCurrentPC() {
function runToCursor() {
setupBreakpoint();
var pc = getCurrentPC();
var pc = getEditorPC();
if (pc >= 0) {
console.log("Run to", pc.toString(16));
if (platform.runToPC) {
@ -773,82 +1113,6 @@ function getVisibleSourceFile() {
return div.is(':visible') ? assemblyfile : sourcefile;
}
function updateDisassembly() {
var div = $("#disassembly");
if (div.is(':visible')) {
var state = lastDebugState || platform.saveState();
var pc = state.c ? state.c.PC : 0;
// do we have an assembly listing?
if (assemblyfile && assemblyfile.text) {
var asmtext = assemblyfile.text;
if (platform_id == 'base_z80') { // TODO
asmtext = asmtext.replace(/[ ]+\d+\s+;.+\n/g, '');
asmtext = asmtext.replace(/[ ]+\d+\s+.area .+\n/g, '');
}
disasmview.setValue(asmtext);
var findPC = platform.getDebugCallback() ? pc : getCurrentPC();
if (findPC) {
var lineno = assemblyfile.findLineForOffset(findPC);
if (lineno) {
// set cursor while debugging
if (platform.getDebugCallback()) disasmview.setCursor(lineno-1, 0);
jumpToLine(disasmview, lineno-1);
return; // success, don't disassemble in next step
}
}
}
// TODO: fall through to platform disassembler?
else if (platform.disassemble) {
var curline = 0;
var selline = 0;
// TODO: not perfect disassembler
function disassemble(start, end) {
if (start < 0) start = 0;
if (end > 0xffff) end = 0xffff;
// TODO: use pc2visits
var a = start;
var s = "";
while (a < end) {
var disasm = platform.disassemble(a, platform.readAddress);
var srclinenum = sourcefile.offset2line[a];
if (srclinenum) {
var srcline = getActiveEditor().getLine(srclinenum);
if (srcline && srcline.trim().length) {
s += "; " + srclinenum + ":\t" + srcline + "\n";
curline++;
}
}
var bytes = "";
for (var i=0; i<disasm.nbytes; i++)
bytes += hex(platform.readAddress(a+i));
while (bytes.length < 14)
bytes += ' ';
var dline = hex(parseInt(a)) + "\t" + bytes + "\t" + disasm.line + "\n";
s += dline;
if (a == pc) selline = curline;
curline++;
a += disasm.nbytes || 1;
}
return s;
}
var text = disassemble(pc-96, pc) + disassemble(pc, pc+96);
disasmview.setValue(text);
disasmview.setCursor(selline, 0);
jumpToLine(disasmview, selline);
} else if (current_output && current_output.code) {
// show verilog javascript
disasmview.setValue(current_output.code);
}
}
}
function toggleDisassembly() {
$("#disassembly").toggle();
$("#editor").toggle();
updateDisassembly();
//if (profilelist) createProfileWindow();
}
function resetAndDebug() {
if (platform.setupDebug && platform.readAddress) { // TODO??
clearBreakpoint();
@ -885,153 +1149,14 @@ function getSymbolAtAddress(a) {
return '';
}
// TODO
function updateDebugWindows() {
if (platform.isRunning()) {
updateMemoryWindow();
//updateProfileWindow();
projectWindows.tick();
}
setTimeout(updateDebugWindows, 200);
}
function updateMemoryWindow() {
if (memorylist) {
$("#memoryview").find('[data-index]').each(function(i,e) {
var div = $(e);
var row = div.attr('data-index');
var oldtext = div.text();
var newtext = getMemoryLineAt(row);
if (oldtext != newtext)
div.text(newtext);
});
}
}
function getMemoryLineAt(row) {
var offset = row * 16;
var n1 = 0;
var n2 = 16;
var sym;
if (getDumpLines()) {
var dl = dumplines[row];
if (dl) {
offset = dl.a & 0xfff0;
n1 = dl.a - offset;
n2 = n1 + dl.l;
sym = dl.s;
} else {
return '.';
}
}
var s = hex(offset,4) + ' ';
for (var i=0; i<n1; i++) s += ' ';
if (n1 > 8) s += ' ';
for (var i=n1; i<n2; i++) {
var read = platform.readAddress(offset+i);
if (i==8) s += ' ';
s += ' ' + (read>=0?hex(read,2):'??');
}
for (var i=n2; i<16; i++) s += ' ';
if (sym) s += ' ' + sym;
return s;
}
function getVisibleEditorLineHeight() {
return $(".CodeMirror-line:visible").first().height();
}
function getDumpLineAt(line) {
var d = dumplines[line];
if (d) {
return d.a + " " + d.s;
}
}
var IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
// TODO: addr2symbol for ca65; and make it work without symbols
function getDumpLines() {
if (!dumplines && addr2symbol) {
dumplines = [];
var ofs = 0;
var sym;
for (var nextofs in addr2symbol) {
nextofs |= 0;
var nextsym = addr2symbol[nextofs];
if (sym) {
if (IGNORE_SYMS[sym]) {
ofs = nextofs;
} else {
while (ofs < nextofs) {
var ofs2 = (ofs + 16) & 0xffff0;
if (ofs2 > nextofs) ofs2 = nextofs;
//if (ofs < 1000) console.log(ofs, ofs2, nextofs, sym);
dumplines.push({a:ofs, l:ofs2-ofs, s:sym});
ofs = ofs2;
}
}
}
sym = nextsym;
}
}
return dumplines;
}
function getMemorySegment(a) {
if (!compparams) return 'unknown';
if (a >= compparams.data_start && a < compparams.data_start+compparams.data_size) {
if (platform.getSP && a >= platform.getSP() - 15)
return 'stack';
else
return 'data';
}
else if (a >= compparams.code_start && a < compparams.code_start+compparams.code_size)
return 'code';
else
return 'unknown';
}
function findMemoryWindowLine(a) {
for (var i=0; i<dumplines.length; i++)
if (dumplines[i].a >= a)
return i;
}
function showMemoryWindow() {
memorylist = new VirtualList({
w:$("#emulator").width(),
h:$("#emulator").height(),
itemHeight: getVisibleEditorLineHeight(),
totalRows: 0x1000,
generatorFn: function(row) {
var s = getMemoryLineAt(row);
var div = document.createElement("div");
if (dumplines) {
var dlr = dumplines[row];
if (dlr) div.classList.add('seg_' + getMemorySegment(dumplines[row].a));
}
div.appendChild(document.createTextNode(s));
return div;
}
});
$("#memoryview").empty().append(memorylist.container);
updateMemoryWindow();
if (compparams && dumplines)
memorylist.scrollToItem(findMemoryWindowLine(compparams.data_start));
}
function toggleMemoryWindow() {
//if ($("#profileview").is(':visible')) toggleProfileWindow();
if ($("#memoryview").is(':visible')) {
memorylist = null;
$("#emulator").show();
$("#memoryview").hide();
} else {
showMemoryWindow();
$("#emulator").hide();
$("#memoryview").show();
}
}
function _recordVideo() {
var canvas = $("#emulator").find("canvas")[0];
if (!canvas) {
@ -1137,14 +1262,6 @@ function setupDebugControls(){
if (window.traceTiming) {
$("#dbg_timing").click(traceTiming).show();
} else if (platform.readAddress) {
$("#dbg_memory").click(toggleMemoryWindow).show();
}
/*if (platform.getProbe) {
$("#dbg_profile").click(toggleProfileWindow).show();
}*/
if (platform.saveState) { // TODO: only show if listing or disasm available
$("#dbg_disasm").click(toggleDisassembly).show();
}
$("#disassembly").hide();
$("#dbg_bitmap").click(_openBitmapEditor);

View File

@ -7,6 +7,11 @@ function byte2signed(b) {
return (b < 0x80) ? b : -(256-b);
}
function getFilenameForPath(s) {
var toks = s.split('/');
return toks[toks.length-1];
}
function hex(v, nd) {
try {
if (!nd) nd = 2;

View File

@ -183,7 +183,6 @@ function gatherFiles(step, options) {
var path = step.path ? step.path : options.mainFilePath;
if (!path) throw "need path or mainFilePath";
var code = step.code;
if (options.transform) code = options.transform(code);
var entry = putWorkFile(path, code);
step.path = path;
step.files = [path];
@ -302,9 +301,6 @@ function setupFS(FS, name) {
}, '/share');
}
var DASM_PREAMBLE = "\tprocessor 6502\n";
var DASM_PREAMBLE_LINES = 1;
var print_fn = function(s) {
console.log(s);
//console.log(new Error().stack);
@ -410,7 +406,7 @@ function parseDASMListing(code, unresolved, mainFilename) {
for (var line of code.split(/\r?\n/)) {
var linem = lineMatch.exec(line);
if (linem && linem[1]) {
var linenum = parseInt(linem[1]) - DASM_PREAMBLE_LINES;
var linenum = parseInt(linem[1]);
var filename = linem[2];
var offset = parseInt(linem[3], 16);
var insns = linem[4];
@ -475,25 +471,34 @@ function assembleDASM(step) {
});
var FS = Module['FS'];
populateFiles(step, FS, {
mainFilePath:'main.a',
transform:function(code) { return DASM_PREAMBLE + code; }
mainFilePath:'main.a'
});
var binpath = step.prefix+'.bin';
var lstpath = step.prefix+'.lst';
execMain(step, Module, [step.path, "-l"+lstpath, "-o"+binpath /*, "-v3", "-sa.sym"*/ ]);
var sympath = step.prefix+'.sym';
execMain(step, Module, [step.path, "-l"+lstpath, "-o"+binpath, "-s"+sympath ]);
var aout = FS.readFile(binpath);
var alst = FS.readFile(lstpath, {'encoding':'utf8'});
var asym = FS.readFile(lstpath, {'encoding':'utf8'});
putWorkFile(binpath, aout);
putWorkFile(lstpath, alst);
//var asym = FS.readFile("a.sym", {'encoding':'utf8'});
putWorkFile(sympath, asym);
var listing = parseDASMListing(alst, unresolved, step.path);
var listings = {};
listings[lstpath] = {lines:listing.lines};
var symbolmap = {};
for (var s of asym.split("\n")) {
var toks = s.split(" ");
if (toks && toks.length >= 2 && !toks[0].startsWith('-')) {
symbolmap[toks[0]] = parseInt(toks[1], 16);
}
}
return {
output:aout.slice(2),
listings:listings,
errors:listing.errors,
intermediate:{listing:alst},
symbolmap:symbolmap,
intermediate:{listing:alst, symbols:asym},
};
}
@ -1003,22 +1008,7 @@ function writeDependencies(depends, FS, errors, callback) {
if (depends) {
for (var i=0; i<depends.length; i++) {
var d = depends[i];
var text;
if (d.text) {
text = d.text;
} else {
// load from network (hopefully cached)
// TODO: get from indexeddb?
var path = '../../presets/' + d.prefix + '/' + d.filename;
var xhr = new XMLHttpRequest();
xhr.open("GET", path, false); // synchronous request
xhr.send(null);
if (xhr.response) {
text = xhr.response;
} else {
console.log("Could not load " + path);
}
}
var text = d.data;
if (callback)
text = callback(d, text);
if (text && FS)

View File

@ -45,6 +45,7 @@ global.localStorage = {
};
includeInThisContext("localForage/dist/localforage.js");
includeInThisContext("src/util.js");
includeInThisContext("src/store.js");
includeInThisContext("src/project.js");
@ -76,7 +77,7 @@ describe('Store', function() {
var project = new CodeProject(worker, test_platform_id, platform, store);
project.loadFiles(['test'], function(err, result) {
assert.equal(null, err);
assert.deepEqual([ { path: 'test', data: 'a' } ], result);
assert.deepEqual([ { path: 'test', filename: 'test', data: 'a' } ], result);
done();
});
});
@ -89,10 +90,14 @@ describe('Store', function() {
var expectmsgs = [
true,
{ preload: 'dasm', platform: '_TEST' },
{ code: ' lda #0',
dependencies: [],
platform: '_TEST',
tool: 'dasm' }
{
buildsteps: [
{ path: "test.a", platform: "_TEST", tool: "dasm", mainfile:true },
],
updates: [
{ path: "test.a", data: " lda #0" }
]
}
];
var store = createNewPersistentStore(test_platform_id);
var worker = {

View File

@ -138,10 +138,17 @@ describe('Worker', function() {
var dependfiles = ["hvsync_generator.v", "font_cp437_8x8.v", "ram.v", "tile_renderer.v", "sprite_scanline_renderer.v", "lfsr.v", "sound_generator.v", "cpu16.v", "cpu_platform.v"];
var depends = [];
for (var dfile of dependfiles) {
depends.push({filename:dfile, prefix:"verilog"});
var code = ab2str(fs.readFileSync('presets/verilog/' + dfile));
depends.push({filename:dfile, data:code, prefix:"verilog"});
}
var msgs = [{code:csource, platform:"verilog", tool:"jsasm", dependencies:depends}];
doBuild(msgs, done, 2782, 0, 0);
var done2 = function(err, msg) {
var jscode = msg.output.code;
var fn = new Function(jscode);
assert.ok(fn);
done(err, msg);
};
doBuild(msgs, done2, 253177, 0, 0);
});
it('should NOT preprocess SDCC', function(done) {
compile('sdcc', 'int x=0\n#bah\n', 'mw8080bw', done, 0, 0, 1);