toolbar takes entire width; started exidy

This commit is contained in:
Steven Hugg 2017-01-06 21:09:41 -05:00
parent 1e2b489b07
commit 2949a35167
3 changed files with 246 additions and 42 deletions

View File

@ -43,20 +43,24 @@ body {
.tooltipbox:hover .tooltiptext {
visibility: visible;
}
#notebook {
height: 100vh;
width: 50%;
#controls_top {
position: absolute;
padding: 0.5em;
height:3em;
width:100%;
background-color:#999;
}
#controls_top {
padding: 0.5em;
width:100%;
height:3em;
#notebook {
position:absolute;
top:3em;
bottom:0;
left:0;
right:0;
}
div.editor {
position:absolute;
left:0;
top:3em;
top:0;
bottom:0;
right:0;
width:50%;
@ -165,40 +169,41 @@ a.dropdown-toggle {
</head>
<body>
<div id="notebook">
<div id="controls_top">
<span class="dropdown">
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
&#9776; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#" id="item_new_file">New File...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share File...</a></li>
<li><a class="dropdown-item" href="#" id="item_reset_file">Reset to Original...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
</ul>
</li>
</ul>
</span>
<select id="preset_select" name="">
</select>
<span id="debug_bar">
<button id="dbg_pause" type="button" title="Pause"><img src="images/pause.png"></button>
<button id="dbg_go" type="button" title="Run"><img src="images/play.png"></button>
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
<button id="dbg_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
<button id="dbg_reset" type="submit" title="Reset and Run To Line"><img src="images/resetandrun.png"></button>
<div id="controls_top">
<span class="dropdown">
<a class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
&#9776; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#" id="item_new_file">New File...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share File...</a></li>
<li><a class="dropdown-item" href="#" id="item_reset_file">Reset to Original...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
<li><a class="dropdown-item" href="?platform=exidy" id="item_platform_exidy">Exidy</a></li>
</ul>
</li>
</ul>
</span>
<select id="preset_select" name="">
</select>
<span id="debug_bar">
<button id="dbg_pause" type="button" title="Pause"><img src="images/pause.png"></button>
<button id="dbg_go" type="button" title="Run"><img src="images/play.png"></button>
<button id="dbg_step" type="submit" title="Step"><img src="images/singlestep.png"></button>
<button id="dbg_toline" type="submit" title="Run To Line"><img src="images/runtoline.png"></button>
<button id="dbg_reset" type="submit" title="Reset and Run To Line"><img src="images/resetandrun.png"></button>
<!-- <button id="dbg_stepout" type="submit" title="Step Out of Subroutine">O</button>-->
<button id="dbg_timing" type="submit" title="See Timing" style="display:none"><img src="images/timing.png"></button>
<button id="dbg_disasm" type="submit" title="Toggle Disassembly">#</button>
</span>
<span class="dbg_info" id="dbg_info"></span>
</div>
<button id="dbg_timing" type="submit" title="See Timing" style="display:none"><img src="images/timing.png"></button>
<button id="dbg_disasm" type="submit" title="Toggle Disassembly">#</button>
</span>
<span class="dbg_info" id="dbg_info"></span>
</div>
<div id="notebook">
<div id="editor_window">
<div id="disassembly" class="editor">
</div>
@ -253,6 +258,7 @@ a.dropdown-toggle {
<script src="src/platform/vcs.js"></script>
<script src="src/platform/apple2.js"></script>
<script src="src/platform/atarivec.js"></script>
<script src="src/platform/exidy.js"></script>
<script src="src/ui.js"></script>
</body>

195
src/platform/exidy.js Normal file
View File

@ -0,0 +1,195 @@
"use strict";
var EXIDY_PRESETS = [
];
var ExidyPlatform = function(mainElement) {
var self = this;
var cpuFrequency = 705562;
var cyclesPerFrame = Math.round(cpuFrequency/60);
var vblankCyclesPerFrame = Math.round(cpuFrequency*3/(262.5*60));
var cpu, ram, bus, rom;
var video, ap2disp, audio, timer;
var port_dsw = 0;
var PGM_BASE = 0x1000; // where to JMP after pr#6
this.getPresets = function() {
return EXIDY_PRESETS;
}
this.start = function() {
cpu = new jt.M6502();
ram = new RAM(0x200); // 64K + 16K LC RAM - 4K hardware
rom = new RAM(0x1000);
// bus
bus = {
read: function(address) {
address &= 0xffff;
if (address < ram.mem.length) {
return ram.mem[address];
} else if (address >= 0x1000 && address <= 0x1fff) {
return rom.mem[address - 0x1000];
} else if (address >= 0xf000) {
return rom.mem[address - 0xf000];
} else if (address == 0xc000) {
return port_dsw;
}
return 0;
},
write: function(address, val) {
address &= 0xffff;
val &= 0xff;
if (address < ram.mem.length) {
ram.mem[address] = val;
}
}
};
cpu.connectBus(bus);
// create video/audio
video = new RasterVideo(mainElement,256,256);
video.start();
audio = new SampleAudio(cpuFrequency); // TODO
audio.start();
var idata = video.getFrameData();
timer = new AnimationTimer(60, function() {
var clock = 0;
breakClock = -1;
for (var i=0; i<cyclesPerFrame; i++) {
if (debugCondition && breakClock < 0 && debugCondition()) { breakClock = clock; }
clock++;
cpu.clockPulse();
port_dsw = (i < vblankCyclesPerFrame) ? 0x80 : 0x0;
}
video.updateFrame();
});
// TODO: reset debug state
}
// TODO: refactor into base
this.getOpcodeMetadata = function(opcode, offset) {
return Javatari.getOpcodeMetadata(opcode, offset); // TODO
}
this.loadROM = function(title, data) {
this.reset();
if(data.length != 0x1000) {
throw "ROM length must be == 0x1000";
}
rom.mem.set(data);
}
this.getRasterPosition = function() {
return {x:0, y:0};
}
this.isRunning = function() {
return timer.isRunning();
}
this.pause = function() {
timer.stop();
audio.stop();
}
this.resume = function() {
timer.start();
audio.start();
}
this.reset = function() {
cpu.reset();
}
this.getOriginPC = function() {
return (this.readAddress(0xfffc) | (this.readAddress(0xfffd) << 8)) & 0xffff;
}
this.readAddress = function(addr) {
return bus.read(addr);
}
var onBreakpointHit;
var debugCondition;
var debugSavedState = null;
var debugBreakState = null;
var debugTargetClock = 0;
var debugClock = 0;
var debugFrameStartClock = 0;
var breakClock;
this.setDebugCondition = function(debugCond) {
if (debugSavedState) {
self.loadState(debugSavedState);
} else {
debugSavedState = self.saveState();
}
debugClock = 0;
debugCondition = debugCond;
self.resume();
}
this.setupDebug = function(callback) {
onBreakpointHit = callback;
}
this.clearDebug = function() {
debugSavedState = null;
debugTargetClock = 0;
debugClock = 0;
debugFrameStartClock = 0;
onBreakpointHit = null;
debugCondition = null;
}
this.breakpointHit = function() {
debugBreakState = self.saveState();
debugBreakState.c.PC = (debugBreakState.c.PC-1) & 0xffff;
console.log("Breakpoint at clk", debugClock, "PC", debugBreakState.c.PC.toString(16));
this.pause();
if (onBreakpointHit) {
onBreakpointHit(debugBreakState);
}
}
this.step = function() {
var previousPC = -1;
self.setDebugCondition(function() {
if (debugClock++ > debugTargetClock) {
var thisState = cpu.saveState();
if (previousPC < 0) {
previousPC = thisState.PC;
} else {
if (thisState.PC != previousPC && thisState.T == 0) {
//console.log(previousPC.toString(16), thisPC.toString(16));
debugTargetClock = debugClock-1;
self.breakpointHit();
return true;
}
}
}
return false;
});
}
this.runEval = function(evalfunc) {
var self = this;
self.setDebugCondition(function() {
if (debugClock++ > debugTargetClock) {
var cpuState = cpu.saveState();
cpuState.PC = (cpuState.PC-1)&0xffff;
if (evalfunc(cpuState)) {
self.breakpointHit();
debugTargetClock = debugClock;
return true;
} else {
return false;
}
}
});
}
this.loadState = function(state) {
cpu.loadState(state.c);
ram.mem.set(state.b);
}
this.saveState = function() {
return {
c:cpu.saveState(),
b:ram.mem.slice(0),
};
}
this.getRAMForState = function(state) {
return ram.mem;
}
};

View File

@ -263,7 +263,7 @@ function arrayCompare(a,b) {
worker.onmessage = function(e) {
// errors?
var toolbar = $("#notebook");
var toolbar = $("#controls_top");
if (e.data.listing.errors.length > 0) {
toolbar.addClass("has-errors");
editor.clearGutter("gutter-info");
@ -806,6 +806,7 @@ try {
platform_id = qs['platform'] = "vcs";
}
// load and start platform object
// TODO: self-register platforms
if (platform_id == 'vcs') {
platform = new VCSPlatform();
$("#booklink_vcs").show();
@ -813,6 +814,8 @@ try {
platform = new Apple2Platform($("#emulator")[0]);
} else if (platform_id == 'atarivec') {
platform = new AtariVectorPlatform($("#emulator")[0]);
} else if (platform_id == 'exidy') {
platform = new ExidyPlatform($("#emulator")[0]);
} else {
alert("Platform " + platform_id + " not recognized");
}