added base_z80 platform and viz.html example
This commit is contained in:
parent
1f45dfdd74
commit
5ae8d28922
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,204 @@
|
||||||
|
.dbg_info {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
.gutter-offset {
|
||||||
|
width: 3em;
|
||||||
|
}
|
||||||
|
.gutter-bytes {
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
.gutter-clock {
|
||||||
|
width: 0.5em;
|
||||||
|
}
|
||||||
|
.gutter-info {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
.tooltipbox {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
border-bottom: 1px dotted black;
|
||||||
|
}
|
||||||
|
.tooltipbox .tooltiptext {
|
||||||
|
visibility: hidden;
|
||||||
|
width: 120px;
|
||||||
|
background-color: black;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 5px 0;
|
||||||
|
|
||||||
|
/* Position the tooltip */
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
.tooltipbox:hover .tooltiptext {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#controls_top {
|
||||||
|
position: absolute;
|
||||||
|
padding: 0.5em;
|
||||||
|
height:3em;
|
||||||
|
width:100%;
|
||||||
|
background-color:#999;
|
||||||
|
}
|
||||||
|
#notebook {
|
||||||
|
position:absolute;
|
||||||
|
top:3em;
|
||||||
|
bottom:0;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
background-color: #666;
|
||||||
|
overflow: hidden;;
|
||||||
|
}
|
||||||
|
div.workspace {
|
||||||
|
background-color:#999;
|
||||||
|
}
|
||||||
|
div.editor {
|
||||||
|
width:50%;
|
||||||
|
line-height:1.25;
|
||||||
|
font-size:12pt;
|
||||||
|
}
|
||||||
|
div.emulator {
|
||||||
|
position:absolute;
|
||||||
|
left:50%;
|
||||||
|
top:0;
|
||||||
|
width:50%;
|
||||||
|
background-color: #666;
|
||||||
|
margin-top: 20px auto 0;
|
||||||
|
}
|
||||||
|
div.debugwindow {
|
||||||
|
position:absolute;
|
||||||
|
left:50%;
|
||||||
|
top:0;
|
||||||
|
width:50%;
|
||||||
|
background-color: #666;
|
||||||
|
color: #66ff66;
|
||||||
|
white-space: pre;
|
||||||
|
margin-top: 20px auto 0;
|
||||||
|
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
div.mem_info {
|
||||||
|
position: fixed;
|
||||||
|
left: 51%;
|
||||||
|
bottom: 10px;
|
||||||
|
background-color: #333;
|
||||||
|
color: #66ff66;
|
||||||
|
white-space: pre;
|
||||||
|
padding: 20px;
|
||||||
|
z-index: 12;
|
||||||
|
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
.btn_group {
|
||||||
|
border-radius:6px;
|
||||||
|
padding:6px;
|
||||||
|
margin-left:8px;
|
||||||
|
background-color: #666;
|
||||||
|
}
|
||||||
|
.btn_group.debug_group {
|
||||||
|
}
|
||||||
|
.btn_group.view_group {
|
||||||
|
}
|
||||||
|
.seg_code { color: #ff9966; }
|
||||||
|
.seg_data { color: #66ff66; }
|
||||||
|
.seg_stack { color: #ffff66; }
|
||||||
|
.seg_unknown { color: #cccccc; }
|
||||||
|
span.hilite {
|
||||||
|
color: #ff66ff;
|
||||||
|
}
|
||||||
|
div.has-errors {
|
||||||
|
background-color: #ff6666 !important;
|
||||||
|
}
|
||||||
|
div.is-busy-unused {
|
||||||
|
background-color: #8888bb !important;
|
||||||
|
}
|
||||||
|
div.menu_div {
|
||||||
|
position: absolute;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
div.booklink {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 6px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
div.twitbtn {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color:#333399;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
a.dropdown-toggle {
|
||||||
|
color:#66ee66;
|
||||||
|
padding:3px;
|
||||||
|
}
|
||||||
|
// http://stackoverflow.com/questions/18023493/bootstrap-3-dropdown-sub-menu-missing
|
||||||
|
.dropdown-submenu {
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
.dropdown-submenu>.dropdown-menu {
|
||||||
|
top:0;
|
||||||
|
left:100%;
|
||||||
|
margin-top:-6px;
|
||||||
|
margin-left:-1px;
|
||||||
|
-webkit-border-radius:0 6px 6px 6px;
|
||||||
|
-moz-border-radius:0 6px 6px 6px;
|
||||||
|
border-radius:0 6px 6px 6px;
|
||||||
|
}
|
||||||
|
.dropdown-submenu:hover>.dropdown-menu {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.dropdown-submenu>a:after {
|
||||||
|
display:block;
|
||||||
|
content:" ";
|
||||||
|
float:right;
|
||||||
|
width:0;
|
||||||
|
height:0;
|
||||||
|
border-color:transparent;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:5px 0 5px 5px;
|
||||||
|
border-left-color:#cccccc;
|
||||||
|
margin-top:5px;
|
||||||
|
margin-right:-10px;
|
||||||
|
}
|
||||||
|
.dropdown-submenu:hover>a:after {
|
||||||
|
border-left-color:#ffffff;
|
||||||
|
}
|
||||||
|
.dropdown-submenu.pull-left {
|
||||||
|
float:none;
|
||||||
|
}
|
||||||
|
.dropdown-submenu.pull-left>.dropdown-menu {
|
||||||
|
left:-100%;
|
||||||
|
margin-left:10px;
|
||||||
|
-webkit-border-radius:6px 0 6px 6px;
|
||||||
|
-moz-border-radius:6px 0 6px 6px;
|
||||||
|
border-radius:6px 0 6px 6px;
|
||||||
|
}
|
||||||
|
.emubevel {
|
||||||
|
padding:4%;
|
||||||
|
background:#333;
|
||||||
|
}
|
||||||
|
.emuvideo {
|
||||||
|
border-radius:20px;
|
||||||
|
border: 4px solid #222;
|
||||||
|
padding: 30px;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background: #000;
|
||||||
|
outline-color: #666;
|
||||||
|
}
|
||||||
|
canvas.pixelated {
|
||||||
|
image-rendering: optimizeSpeed; /* Older versions of FF */
|
||||||
|
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
||||||
|
image-rendering: -webkit-optimize-contrast; /* Safari */
|
||||||
|
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
|
||||||
|
image-rendering: pixelated; /* Awesome future-browsers */
|
||||||
|
-ms-interpolation-mode: nearest-neighbor; /* IE */
|
||||||
|
}
|
205
index.html
205
index.html
|
@ -7,211 +7,8 @@ body {
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
.dbg_info {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
.gutter-offset {
|
|
||||||
width: 3em;
|
|
||||||
}
|
|
||||||
.gutter-bytes {
|
|
||||||
width: 6em;
|
|
||||||
}
|
|
||||||
.gutter-clock {
|
|
||||||
width: 0.5em;
|
|
||||||
}
|
|
||||||
.gutter-info {
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
.tooltipbox {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
border-bottom: 1px dotted black;
|
|
||||||
}
|
|
||||||
.tooltipbox .tooltiptext {
|
|
||||||
visibility: hidden;
|
|
||||||
width: 120px;
|
|
||||||
background-color: black;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 5px 0;
|
|
||||||
|
|
||||||
/* Position the tooltip */
|
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.tooltipbox:hover .tooltiptext {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
#controls_top {
|
|
||||||
position: absolute;
|
|
||||||
padding: 0.5em;
|
|
||||||
height:3em;
|
|
||||||
width:100%;
|
|
||||||
background-color:#999;
|
|
||||||
}
|
|
||||||
#notebook {
|
|
||||||
position:absolute;
|
|
||||||
top:3em;
|
|
||||||
bottom:0;
|
|
||||||
left:0;
|
|
||||||
right:0;
|
|
||||||
background-color: #666;
|
|
||||||
overflow: hidden;;
|
|
||||||
}
|
|
||||||
div.workspace {
|
|
||||||
background-color:#999;
|
|
||||||
}
|
|
||||||
div.editor {
|
|
||||||
width:50%;
|
|
||||||
line-height:1.25;
|
|
||||||
font-size:12pt;
|
|
||||||
}
|
|
||||||
div.emulator {
|
|
||||||
position:absolute;
|
|
||||||
left:50%;
|
|
||||||
top:0;
|
|
||||||
width:50%;
|
|
||||||
background-color: #666;
|
|
||||||
margin-top: 20px auto 0;
|
|
||||||
}
|
|
||||||
div.debugwindow {
|
|
||||||
position:absolute;
|
|
||||||
left:50%;
|
|
||||||
top:0;
|
|
||||||
width:50%;
|
|
||||||
background-color: #666;
|
|
||||||
color: #66ff66;
|
|
||||||
white-space: pre;
|
|
||||||
margin-top: 20px auto 0;
|
|
||||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
div.mem_info {
|
|
||||||
position: fixed;
|
|
||||||
left: 51%;
|
|
||||||
bottom: 10px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #66ff66;
|
|
||||||
white-space: pre;
|
|
||||||
padding: 20px;
|
|
||||||
z-index: 12;
|
|
||||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
|
||||||
font-size: 12pt;
|
|
||||||
}
|
|
||||||
.btn_group {
|
|
||||||
border-radius:6px;
|
|
||||||
padding:6px;
|
|
||||||
margin-left:8px;
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
.btn_group.debug_group {
|
|
||||||
}
|
|
||||||
.btn_group.view_group {
|
|
||||||
}
|
|
||||||
.seg_code { color: #ff9966; }
|
|
||||||
.seg_data { color: #66ff66; }
|
|
||||||
.seg_stack { color: #ffff66; }
|
|
||||||
.seg_unknown { color: #cccccc; }
|
|
||||||
span.hilite {
|
|
||||||
color: #ff66ff;
|
|
||||||
}
|
|
||||||
div.has-errors {
|
|
||||||
background-color: #ff6666 !important;
|
|
||||||
}
|
|
||||||
div.is-busy-unused {
|
|
||||||
background-color: #8888bb !important;
|
|
||||||
}
|
|
||||||
div.menu_div {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
div.booklink {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 6px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
div.twitbtn {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color:#333399;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
a.dropdown-toggle {
|
|
||||||
color:#66ee66;
|
|
||||||
padding:3px;
|
|
||||||
}
|
|
||||||
// http://stackoverflow.com/questions/18023493/bootstrap-3-dropdown-sub-menu-missing
|
|
||||||
.dropdown-submenu {
|
|
||||||
position:relative;
|
|
||||||
}
|
|
||||||
.dropdown-submenu>.dropdown-menu {
|
|
||||||
top:0;
|
|
||||||
left:100%;
|
|
||||||
margin-top:-6px;
|
|
||||||
margin-left:-1px;
|
|
||||||
-webkit-border-radius:0 6px 6px 6px;
|
|
||||||
-moz-border-radius:0 6px 6px 6px;
|
|
||||||
border-radius:0 6px 6px 6px;
|
|
||||||
}
|
|
||||||
.dropdown-submenu:hover>.dropdown-menu {
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
.dropdown-submenu>a:after {
|
|
||||||
display:block;
|
|
||||||
content:" ";
|
|
||||||
float:right;
|
|
||||||
width:0;
|
|
||||||
height:0;
|
|
||||||
border-color:transparent;
|
|
||||||
border-style:solid;
|
|
||||||
border-width:5px 0 5px 5px;
|
|
||||||
border-left-color:#cccccc;
|
|
||||||
margin-top:5px;
|
|
||||||
margin-right:-10px;
|
|
||||||
}
|
|
||||||
.dropdown-submenu:hover>a:after {
|
|
||||||
border-left-color:#ffffff;
|
|
||||||
}
|
|
||||||
.dropdown-submenu.pull-left {
|
|
||||||
float:none;
|
|
||||||
}
|
|
||||||
.dropdown-submenu.pull-left>.dropdown-menu {
|
|
||||||
left:-100%;
|
|
||||||
margin-left:10px;
|
|
||||||
-webkit-border-radius:6px 0 6px 6px;
|
|
||||||
-moz-border-radius:6px 0 6px 6px;
|
|
||||||
border-radius:6px 0 6px 6px;
|
|
||||||
}
|
|
||||||
.emubevel {
|
|
||||||
padding:4%;
|
|
||||||
background:#333;
|
|
||||||
}
|
|
||||||
.emuvideo {
|
|
||||||
border-radius:20px;
|
|
||||||
border: 4px solid #222;
|
|
||||||
padding: 30px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
background: #000;
|
|
||||||
outline-color: #666;
|
|
||||||
}
|
|
||||||
canvas.pixelated {
|
|
||||||
image-rendering: optimizeSpeed; /* Older versions of FF */
|
|
||||||
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
|
||||||
image-rendering: -webkit-optimize-contrast; /* Safari */
|
|
||||||
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
|
|
||||||
image-rendering: pixelated; /* Awesome future-browsers */
|
|
||||||
-ms-interpolation-mode: nearest-neighbor; /* IE */
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
<link rel="stylesheet" href="css/ui.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
int Fibonacci(int n)
|
||||||
|
{
|
||||||
|
if ( n == 0 )
|
||||||
|
return 0;
|
||||||
|
else if ( n == 1 )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return ( Fibonacci(n-1) + Fibonacci(n-2) );
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef signed char sbyte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
|
||||||
|
byte __at (0x2400) vidmem[224][32]; // 256x224x1 video memory
|
||||||
|
|
||||||
|
void clrscr() {
|
||||||
|
memset(vidmem, 0, sizeof(vidmem));
|
||||||
|
}
|
||||||
|
|
||||||
|
void xor_pixel(byte x, byte y) {
|
||||||
|
byte* dest = &vidmem[x][y>>3];
|
||||||
|
*dest ^= 0x1 << (y&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte xor_sprite(const byte* src, byte x, byte y) {
|
||||||
|
byte i,j;
|
||||||
|
byte result = 0;
|
||||||
|
byte* dest = &vidmem[x][y];
|
||||||
|
byte w = *src++;
|
||||||
|
byte h = *src++;
|
||||||
|
for (j=0; j<h; j++) {
|
||||||
|
for (i=0; i<w; i++) {
|
||||||
|
result |= (*dest++ ^= *src++);
|
||||||
|
}
|
||||||
|
dest += 32-w;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
unsigned int lfsr = 1;
|
||||||
|
|
||||||
|
unsigned int rand() {
|
||||||
|
char lsb = lfsr & 1;
|
||||||
|
lfsr >>= 1;
|
||||||
|
if (lsb) lfsr ^= 0xd400;
|
||||||
|
return lfsr;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
int func(int x) {
|
||||||
|
return x * 2;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
int func(int x) {
|
||||||
|
return x / 4;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var BASEZ80_PRESETS = [
|
||||||
|
{id:'simple1.c', name:'Multiply by 2'},
|
||||||
|
{id:'simple2.c', name:'Divide by 4'},
|
||||||
|
{id:'prng.c', name:'Pseudorandom Numbers'},
|
||||||
|
{id:'fib.c', name:'Fibonacci'},
|
||||||
|
{id:'gfx.c', name:'Graphics'},
|
||||||
|
{id:'empty.c', name:'Your Code Here...'},
|
||||||
|
];
|
||||||
|
|
||||||
|
var Base_Z80Platform = function(mainElement) {
|
||||||
|
var self = this;
|
||||||
|
this.__proto__ = new BaseZ80Platform();
|
||||||
|
|
||||||
|
var cpu, ram, membus, iobus, rom, timer;
|
||||||
|
|
||||||
|
this.getPresets = function() {
|
||||||
|
return BASEZ80_PRESETS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.start = function() {
|
||||||
|
ram = new RAM(0x8000);
|
||||||
|
membus = {
|
||||||
|
read: new AddressDecoder([
|
||||||
|
[0x0000, 0x7fff, 0x7fff, function(a) { return rom ? rom[a] : null; }],
|
||||||
|
[0x8000, 0xffff, 0x7fff, function(a) { return ram.mem[a]; }],
|
||||||
|
]),
|
||||||
|
write: new AddressDecoder([
|
||||||
|
[0x8000, 0xffff, 0x7fff, function(a,v) { ram.mem[a] = v; }],
|
||||||
|
]),
|
||||||
|
isContended: function() { return false; },
|
||||||
|
};
|
||||||
|
this.readAddress = membus.read;
|
||||||
|
iobus = {
|
||||||
|
read: function(addr) {
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
write: function(addr, val) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cpu = this.newCPU(membus, iobus);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadROM = function(title, data) {
|
||||||
|
rom = padBytes(data, 0x8000);
|
||||||
|
self.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadState = function(state) {
|
||||||
|
cpu.loadState(state.c);
|
||||||
|
ram.mem.set(state.b);
|
||||||
|
}
|
||||||
|
this.saveState = function() {
|
||||||
|
return {
|
||||||
|
c:self.getCPUState(),
|
||||||
|
b:ram.mem.slice(0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.getCPUState = function() {
|
||||||
|
return cpu.saveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isRunning = function() {
|
||||||
|
return timer && timer.isRunning();
|
||||||
|
}
|
||||||
|
this.pause = function() {
|
||||||
|
if (timer) timer.stop();
|
||||||
|
}
|
||||||
|
this.resume = function() {
|
||||||
|
if (timer) timer.start();
|
||||||
|
}
|
||||||
|
this.reset = function() {
|
||||||
|
cpu.reset();
|
||||||
|
if (!this.getDebugCallback()) cpu.setTstates(0); // TODO?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORMS['base_z80'] = Base_Z80Platform;
|
94
src/ui.js
94
src/ui.js
|
@ -111,6 +111,7 @@ var TOOL_TO_SOURCE_STYLE = {
|
||||||
}
|
}
|
||||||
|
|
||||||
var worker = new Worker("./src/worker/workermain.js");
|
var worker = new Worker("./src/worker/workermain.js");
|
||||||
|
var main_editor;
|
||||||
var current_output;
|
var current_output;
|
||||||
var current_preset_index = -1;
|
var current_preset_index = -1;
|
||||||
var current_preset_id;
|
var current_preset_id;
|
||||||
|
@ -173,8 +174,10 @@ function getCurrentPresetTitle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLastPreset(id) {
|
function setLastPreset(id) {
|
||||||
localStorage.setItem("__lastplatform", platform_id);
|
if (platform_id != 'base_z80') { // TODO
|
||||||
localStorage.setItem("__lastid_"+platform_id, id);
|
localStorage.setItem("__lastplatform", platform_id);
|
||||||
|
localStorage.setItem("__lastid_"+platform_id, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePreset(current_preset_id, text) {
|
function updatePreset(current_preset_id, text) {
|
||||||
|
@ -185,7 +188,7 @@ function updatePreset(current_preset_id, text) {
|
||||||
|
|
||||||
function loadCode(text, fileid) {
|
function loadCode(text, fileid) {
|
||||||
var tool = platform.getToolForFilename(fileid);
|
var tool = platform.getToolForFilename(fileid);
|
||||||
newEditor(tool && TOOL_TO_SOURCE_STYLE[tool]);
|
main_editor = newEditor(tool && TOOL_TO_SOURCE_STYLE[tool]);
|
||||||
editor.setValue(text); // calls setCode()
|
editor.setValue(text); // calls setCode()
|
||||||
editor.clearHistory();
|
editor.clearHistory();
|
||||||
current_output = null;
|
current_output = null;
|
||||||
|
@ -314,7 +317,7 @@ function _downloadROMImage(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateExamples(sel) {
|
function populateExamples(sel) {
|
||||||
sel.append($("<option />").text("--------- Chapters ---------").attr('disabled',true));
|
sel.append($("<option />").text("--------- Examples ---------").attr('disabled',true));
|
||||||
for (var i=0; i<PRESETS.length; i++) {
|
for (var i=0; i<PRESETS.length; i++) {
|
||||||
var preset = PRESETS[i];
|
var preset = PRESETS[i];
|
||||||
var name = preset.chapter ? (preset.chapter + ". " + preset.name) : preset.name;
|
var name = preset.chapter ? (preset.chapter + ". " + preset.name) : preset.name;
|
||||||
|
@ -341,8 +344,10 @@ function populateFiles(sel, name, prefix) {
|
||||||
|
|
||||||
function updateSelector() {
|
function updateSelector() {
|
||||||
var sel = $("#preset_select").empty();
|
var sel = $("#preset_select").empty();
|
||||||
populateFiles(sel, "Local Files", "local/");
|
if (platform_id != 'base_z80') { // TODO
|
||||||
populateFiles(sel, "Shared", "shared/");
|
populateFiles(sel, "Local Files", "local/");
|
||||||
|
populateFiles(sel, "Shared", "shared/");
|
||||||
|
}
|
||||||
populateExamples(sel);
|
populateExamples(sel);
|
||||||
// set click handlers
|
// set click handlers
|
||||||
sel.off('change').change(function(e) {
|
sel.off('change').change(function(e) {
|
||||||
|
@ -464,6 +469,7 @@ function setCompileOutput(data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateDisassembly();
|
||||||
if (trace_pending_at_pc) {
|
if (trace_pending_at_pc) {
|
||||||
showLoopTimingForPC(trace_pending_at_pc);
|
showLoopTimingForPC(trace_pending_at_pc);
|
||||||
}
|
}
|
||||||
|
@ -664,7 +670,12 @@ function updateDisassembly() {
|
||||||
var state = lastDebugState || platform.saveState();
|
var state = lastDebugState || platform.saveState();
|
||||||
var pc = state.c.PC;
|
var pc = state.c.PC;
|
||||||
if (assemblyfile && assemblyfile.text) {
|
if (assemblyfile && assemblyfile.text) {
|
||||||
disasmview.setValue(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();
|
var findPC = platform.getDebugCallback() ? pc : getCurrentPC();
|
||||||
if (findPC) {
|
if (findPC) {
|
||||||
var lineno = assemblyfile.findLineForOffset(findPC);
|
var lineno = assemblyfile.findLineForOffset(findPC);
|
||||||
|
@ -673,43 +684,44 @@ function updateDisassembly() {
|
||||||
jumpToLine(disasmview, lineno-1);
|
jumpToLine(disasmview, lineno-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
var curline = 0;
|
else if (platform.disassemble) {
|
||||||
var selline = 0;
|
var curline = 0;
|
||||||
// TODO: not perfect disassembler
|
var selline = 0;
|
||||||
function disassemble(start, end) {
|
// TODO: not perfect disassembler
|
||||||
if (start < 0) start = 0;
|
function disassemble(start, end) {
|
||||||
if (end > 0xffff) end = 0xffff;
|
if (start < 0) start = 0;
|
||||||
// TODO: use pc2visits
|
if (end > 0xffff) end = 0xffff;
|
||||||
var a = start;
|
// TODO: use pc2visits
|
||||||
var s = "";
|
var a = start;
|
||||||
while (a < end) {
|
var s = "";
|
||||||
var disasm = platform.disassemble(a, platform.readAddress);
|
while (a < end) {
|
||||||
var srclinenum = sourcefile.offset2line[a];
|
var disasm = platform.disassemble(a, platform.readAddress);
|
||||||
if (srclinenum) {
|
var srclinenum = sourcefile.offset2line[a];
|
||||||
var srcline = editor.getLine(srclinenum-1);
|
if (srclinenum) {
|
||||||
if (srcline && srcline.trim().length) {
|
var srcline = editor.getLine(srclinenum-1);
|
||||||
s += "; " + srclinenum + ":\t" + srcline + "\n";
|
if (srcline && srcline.trim().length) {
|
||||||
|
s += "; " + srclinenum + ":\t" + srcline + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
var bytes = "";
|
return s;
|
||||||
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);
|
||||||
}
|
}
|
||||||
var text = disassemble(pc-96, pc) + disassemble(pc, pc+96);
|
|
||||||
disasmview.setValue(text);
|
|
||||||
disasmview.setCursor(selline, 0);
|
|
||||||
jumpToLine(disasmview, selline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,6 +1097,7 @@ function showWelcomeMessage() {
|
||||||
tour.init();
|
tour.init();
|
||||||
setTimeout(function() { tour.start(); }, 2000);
|
setTimeout(function() { tour.start(); }, 2000);
|
||||||
}
|
}
|
||||||
|
if (qs['redir']) delete qs['redir'];
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
|
@ -1125,7 +1138,6 @@ function startPlatform() {
|
||||||
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
|
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
|
||||||
PRESETS = platform.getPresets();
|
PRESETS = platform.getPresets();
|
||||||
if (qs['file']) {
|
if (qs['file']) {
|
||||||
showWelcomeMessage();
|
|
||||||
// start platform and load file
|
// start platform and load file
|
||||||
preloadWorker(qs['file']);
|
preloadWorker(qs['file']);
|
||||||
platform.start();
|
platform.start();
|
||||||
|
@ -1192,9 +1204,11 @@ function startUI(loadplatform) {
|
||||||
$.getScript(scriptfn, function() {
|
$.getScript(scriptfn, function() {
|
||||||
console.log("loaded platform", platform_id);
|
console.log("loaded platform", platform_id);
|
||||||
startPlatform();
|
startPlatform();
|
||||||
|
showWelcomeMessage();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
startPlatform();
|
startPlatform();
|
||||||
|
showWelcomeMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,13 @@ var PLATFORM_PARAMS = {
|
||||||
data_size: 0x400,
|
data_size: 0x400,
|
||||||
stack_end: 0x8000,
|
stack_end: 0x8000,
|
||||||
},
|
},
|
||||||
|
'base_z80': {
|
||||||
|
code_start: 0x0,
|
||||||
|
code_size: 0x8000,
|
||||||
|
data_start: 0x8000,
|
||||||
|
data_size: 0x8000,
|
||||||
|
stack_end: 0x0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var loaded = {}
|
var loaded = {}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>8bitworkshop ~ Z80 Compiler Visualization</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/ui.css">
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
div.CodeMirror {
|
||||||
|
line-height:1.25;
|
||||||
|
font-size:12pt;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
height: 600pt;
|
||||||
|
}
|
||||||
|
#preset_select {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="jquery/jquery-2.2.3.min.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="bootstrap/css/bootstrap-darkly.min.css">
|
||||||
|
<script src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<script src="codemirror/lib/codemirror.js"></script>
|
||||||
|
<script src="codemirror/mode/clike/clike.js"></script>
|
||||||
|
<script src="codemirror/mode/6502/6502.js"></script>
|
||||||
|
<script src="codemirror/mode/z80/z80.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/codemirror.css">
|
||||||
|
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
<script src="codemirror/addon/selection/active-line.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="page-header">
|
||||||
|
<p class="lead">
|
||||||
|
Edit a C source file, and see the Z80 assembly output update in real-time.
|
||||||
|
</p>
|
||||||
|
<h6>Powered by <a target="_new" href="https://twitter.com/8bitworkshop">@8bitworkshop</a> and the Small Device C Compiler.</h6>
|
||||||
|
<select id="preset_select" name="">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div id="editor" class="editor2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div id="disassembly">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Javatari = {};
|
||||||
|
PLATFORMS = {};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="src/cpu/z80.js"></script>
|
||||||
|
<script src="src/util.js"></script>
|
||||||
|
<script src="src/emu.js"></script>
|
||||||
|
<script src="src/ui.js"></script>
|
||||||
|
<script src="src/platform/base_z80.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
platform_id = 'base_z80';
|
||||||
|
startPlatform();
|
||||||
|
$('#disassembly').show();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue