diff --git a/css/ui.css b/css/ui.css
index 4ac98a1a..7dabaa9f 100644
--- a/css/ui.css
+++ b/css/ui.css
@@ -138,7 +138,7 @@ div.mem_info a.selected {
color: #ff9933 !important;
}
.btn_recording {
- color: #ff3333;
+ color: #ff6666 !important;
}
.btn_toolbar {
margin:4px;
diff --git a/doc/notes.txt b/doc/notes.txt
index 339f2221..159ac1d7 100644
--- a/doc/notes.txt
+++ b/doc/notes.txt
@@ -110,10 +110,11 @@ TODO:
- throw errors when bad/no refs
- capture so we get mouseUp() out of frame
- per-View keyboard shortcuts
-- crt0.s compiled each time?
-- debug highlight doesn't go away when debugging -> running
- parse labels
- editing too fast refreshes kills the editor
+- crt0.s compiled each time?
+- debug highlight doesn't go away when debugging -> running
+- replay doesn't work for nes
WEB WORKER FORMAT
diff --git a/index.html b/index.html
index 024fc120..dead9a37 100644
--- a/index.html
+++ b/index.html
@@ -137,24 +137,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/presets/nes/flicker.c b/presets/nes/flicker.c
index 3af575a6..96fa5e06 100644
--- a/presets/nes/flicker.c
+++ b/presets/nes/flicker.c
@@ -84,7 +84,7 @@ void setup_graphics() {
}
// number of actors (4 h/w sprites each)
-#define NUM_ACTORS 48
+#define NUM_ACTORS 24
// actor x/y positions
char actor_x[NUM_ACTORS];
@@ -113,14 +113,14 @@ void main() {
oam_id = 0;
// draw and move all actors
// (note we don't reset i each loop iteration)
- while (oam_id < 252) {
+ while (oam_id < 256-4*4) {
// wrap around actor array
if (i >= NUM_ACTORS)
i -= NUM_ACTORS;
oam_id = oam_meta_spr(actor_x[i], actor_y[i], oam_id, playerRunSeq[i&15]);
actor_x[i] += actor_dx[i];
actor_y[i] += actor_dy[i];
- i++;
+ ++i;
}
// hide rest of sprites
oam_hide_rest(oam_id);
diff --git a/presets/nes/irq.c b/presets/nes/irq.c
index b914f304..5b1534df 100644
--- a/presets/nes/irq.c
+++ b/presets/nes/irq.c
@@ -25,14 +25,15 @@ void draw_text(word addr, const char* text) {
vram_write(text, strlen(text));
}
-byte counters[128];
+word counters[128];
byte irqcount = 0;
void __fastcall__ irq_nmi_callback(void) {
- // is this an IRQ? (A == 0xff)
+ // check high bit of A to see if this is an IRQ
if (__A__ & 0x80) {
- // set PPU scroll value
- PPU.scroll = counters[irqcount] >> 5;
+ // it's an IRQ from the MMC3 mapper
+ // change PPU scroll registers
+ PPU.scroll = counters[irqcount & 0x7f] >> 8;
PPU.scroll = 0;
// advance to next scroll value
++irqcount;
@@ -40,7 +41,8 @@ void __fastcall__ irq_nmi_callback(void) {
MMC3_IRQ_DISABLE();
MMC3_IRQ_ENABLE();
} else {
- // this is a NMI, reset IRQ counter
+ // this is a NMI
+ // reload IRQ counter
MMC3_IRQ_RELOAD();
// reset scroll counter
irqcount = 0;
@@ -53,8 +55,9 @@ void main(void)
MMC3_IRQ_SET_VALUE(7);
MMC3_IRQ_RELOAD();
MMC3_IRQ_ENABLE();
- __asm__ ("cli"); // enable IRQ
- // set IRQ
+ // enable CPU IRQ
+ __asm__ ("cli");
+ // set IRQ callback
nmi_set_callback(irq_nmi_callback);
// set palette colors
pal_col(1,0x04);
@@ -63,12 +66,13 @@ void main(void)
// fill vram
vram_adr(NTADR_A(0,0));
vram_fill('A', 32*28);
+ // turn on PPU/interrupts
ppu_on_all();
// loop forever, updating each counter at a different rate
while(1) {
byte i;
for (i=0; i<128; i++) {
- counters[i] += i;
+ counters[i] += i*16;
}
ppu_wait_frame();
}
diff --git a/presets/nes/musicdemo.asm b/presets/nes/musicdemo.asm
index 067b80c6..81ebd0df 100644
--- a/presets/nes/musicdemo.asm
+++ b/presets/nes/musicdemo.asm
@@ -10,13 +10,13 @@
FT_TEMP ds 3 ;3 bytes in zeropage used by the library as a scratchpad
FT_BASE_ADR = $0500 ;page in the RAM used for FT2 variables, should be $xx00
-FT_DPCM_OFF = DMCSamples ;$c000..$ffc0, 64-byte steps
FT_SFX_STREAMS = 4 ;number of sound effects played at once, 1..4
-;FT_DPCM_ENABLE = 1 ;undefine to exclude all DMC code
FT_SFX_ENABLE = 1 ;undefine to exclude all sound effects code
;FT_THREAD = 1 ;undefine if you are calling sound effects from the same thread as the sound update call
FT_PAL_SUPPORT = 1 ;undefine to exclude PAL support
FT_NTSC_SUPPORT = 1 ;undefine to exclude NTSC support
+FT_DPCM_OFF = DMCSamples ;$c000..$ffc0, 64-byte steps
+FT_DPCM_ENABLE = 1 ;undefine to exclude all DMC code
;;;;; NES CARTRIDGE HEADER
@@ -95,9 +95,6 @@ NMIHandler:
;this file for FamiTone2 library generated by text2data tool
-FT_DPCM_OFF = $c000
-FT_DPCM_PTR = (FT_DPCM_OFF&$3fff)>>6
-
music_data: subroutine
_after_the_rain_music_data:
.byte 1
@@ -1204,7 +1201,7 @@ sounds: subroutine
;;;;; SAMPLES
- org $c000
+ org $f000
DMCSamples
hex a97ee93ffc3ff00f0700000000000000
hex 00000000f8ffffffffffffffabaaaaaa
diff --git a/presets/nes/neslib.h b/presets/nes/neslib.h
index a5cd9a86..43116004 100644
--- a/presets/nes/neslib.h
+++ b/presets/nes/neslib.h
@@ -257,7 +257,7 @@ void __fastcall__ oam_clear_fast(void);
void __fastcall__ oam_meta_spr_pal(unsigned char x,unsigned char y,unsigned char pal,const unsigned char *metasprite);
void __fastcall__ oam_meta_spr_clip(signed int x,unsigned char y,const unsigned char *metasprite);
-// set NMI callback
+// set NMI/IRQ callback
void __fastcall__ nmi_set_callback(void (*callback)(void));
diff --git a/presets/nes/shoot2.c b/presets/nes/shoot2.c
index e7324811..e71659df 100644
--- a/presets/nes/shoot2.c
+++ b/presets/nes/shoot2.c
@@ -338,14 +338,7 @@ const byte DIR_TO_CODE[32] = {
6|FLIPY, 6|FLIPY, 5|FLIPY, 4|FLIPY, 3|FLIPY, 2|FLIPY, 1|FLIPY, 0|FLIPY,
};
-const byte SINTBL[32] = {
- 0, 25, 49, 71, 90, 106, 117, 125,
- 127, 125, 117, 106, 90, 71, 49, 25,
- 0, -25, -49, -71, -90, -106, -117, -125,
- -127, -125, -117, -106, -90, -71, -49, -25,
-};
-
-// pre-multiplied by 2
+// sine table, pre-multiplied by 2
const int SINTBL2[32] = {
0, 25*2, 49*2, 71*2, 90*2, 106*2, 117*2, 125*2,
127*2, 125*2, 117*2, 106*2, 90*2, 71*2, 49*2, 25*2,
@@ -356,29 +349,6 @@ const int SINTBL2[32] = {
#define ISIN(x) (SINTBL2[(x) & 31])
#define ICOS(x) ISIN(x+8)
-// Fast 8-bit table lookup macro
-// dest: destination
-// ident: table identifier
-// index: 8-bit index
-#define FASTLUT8(dest,ident,index) \
- __A__ = (index); \
- asm ("tax"); \
- asm ("lda %v,x", ident); \
- (dest) = __AX__;
-
-// Fast 16-bit table lookup (single table of 2-byte words, 128 entries max)
-// dest: destination (16 bits)
-// ident: table identifier
-// index: 8-bit index
-#define FASTLUT16(dest,ident,index) \
- __A__ = (index); \
- asm ("asl"); \
- asm ("tay"); \
- asm ("lda %v+1,y", ident); \
- asm ("tax"); \
- asm ("lda %v,y", ident); \
- (dest) = __AX__;
-
#define FORMATION_X0 0
#define FORMATION_Y0 19
#define FORMATION_XSPACE 24
@@ -432,16 +402,8 @@ void return_attacker(register AttackingEnemy* a) {
}
void fly_attacker(register AttackingEnemy* a) {
-#ifdef USE_FASTLUT
- static int sincos;
- sincos = FASTLUT16(sincos, SINTBL2, a->dir&31);
- a->x += sincos;
- sincos = FASTLUT16(sincos, SINTBL2, (a->dir+8)&31);
- a->y += sincos;
-#else
a->x += ISIN(a->dir);
a->y += ICOS(a->dir);
-#endif
if ((a->y >> 8) == 0) {
a->returning = 1;
}
diff --git a/presets/nes/statusbar.c b/presets/nes/statusbar.c
index 3afb5f06..6d28781b 100644
--- a/presets/nes/statusbar.c
+++ b/presets/nes/statusbar.c
@@ -64,7 +64,7 @@ void main(void) {
// set sprite 0
oam_clear();
- oam_spr(0, 30, 1, 1, 0);
+ oam_spr(1, 30, 0xa0, 1, 0);
// enable PPU rendering (turn on screen)
ppu_on_all();
diff --git a/src/emu.ts b/src/emu.ts
index 2c2d0fba..6d35f2aa 100644
--- a/src/emu.ts
+++ b/src/emu.ts
@@ -501,21 +501,21 @@ export function newAddressDecoder(table : AddressDecoderEntry[], options?:Addres
/// TOOLBAR
export class Toolbar {
- div : JQuery;
+ span : JQuery;
grp : JQuery;
mousetrap;
boundkeys = [];
constructor(parentDiv:HTMLElement) {
this.mousetrap = new Mousetrap(parentDiv);
- this.div = $(document.createElement("div")).addClass("btn_toolbar");
- parentDiv.appendChild(this.div[0]);
+ this.span = $(document.createElement("span")).addClass("btn_toolbar");
+ parentDiv.appendChild(this.span[0]);
this.newGroup();
}
destroy() {
- if (this.div) {
- this.div.remove();
- this.div = null;
+ if (this.span) {
+ this.span.remove();
+ this.span = null;
}
if (this.mousetrap) {
for (var key of this.boundkeys) {
@@ -525,11 +525,12 @@ export class Toolbar {
}
}
newGroup() {
- this.grp = $(document.createElement("span")).addClass("btn_group").appendTo(this.div);
+ return this.grp = $(document.createElement("span")).addClass("btn_group").appendTo(this.span);
}
add(key:string, alttext:string, icon:string, fn:(e,combo) => void) {
+ var btn = null;
if (icon) {
- var btn = $(document.createElement("button")).addClass("btn");
+ btn = $(document.createElement("button")).addClass("btn");
if (icon.startsWith('glyphicon')) {
icon = '';
}
@@ -538,8 +539,12 @@ export class Toolbar {
btn.click(fn);
this.grp.append(btn);
}
- this.mousetrap.bind(key, fn);
- this.boundkeys.push(key);
+ if (key) {
+ this.mousetrap.bind(key, fn);
+ this.boundkeys.push(key);
+ }
+ return btn;
}
+
}
diff --git a/src/ui.ts b/src/ui.ts
index 8ddf0329..cba50402 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -8,7 +8,7 @@ import { CodeProject } from "./project";
import { WorkerResult, WorkerOutput, VerilogOutput, SourceFile, WorkerError, FileData } from "./workertypes";
import { ProjectWindows } from "./windows";
import { Platform, Preset, DebugSymbols, DebugEvalCondition } from "./baseplatform";
-import { PLATFORMS, EmuHalt } from "./emu";
+import { PLATFORMS, EmuHalt, Toolbar } from "./emu";
import * as Views from "./views";
import { createNewPersistentStore } from "./store";
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG,
@@ -30,6 +30,8 @@ export var platform : Platform; // platform object
var toolbar = $("#controls_top");
+var uitoolbar : Toolbar;
+
export var current_project : CodeProject; // current CodeProject object
export var projectWindows : ProjectWindows; // window manager
@@ -478,7 +480,7 @@ function _revertFile(e) {
if (wnd && wnd.setText) {
var fn = fixFilename(projectWindows.getActiveID());
// TODO: .mame
- $.get( "presets/"+platform_id+"/"+fn, function(text) {
+ $.get( "presets/"+getFilenamePrefix(platform_id)+"/"+fn, function(text) {
if (confirm("Reset '" + fn + "' to default?")) {
wnd.setText(text);
}
@@ -488,7 +490,7 @@ function _revertFile(e) {
alert("Can only revert built-in files.");
});
} else {
- alert("Cannot revert the active window.");
+ alert("Cannot revert the active window. Please choose a text file.");
}
}
@@ -1067,49 +1069,33 @@ function _addLinkFile() {
alert("Can't add linked file to this project type (" + tool + ")");
}
-function setupDebugControls(){
-
- $("#dbg_reset").click(resetAndDebug);
- $("#dbg_pause").click(pause);
- $("#dbg_go").click(resume);
- Mousetrap.bindGlobal('ctrl+alt+p', pause);
- Mousetrap.bindGlobal('ctrl+alt+r', resume);
- Mousetrap.bindGlobal('ctrl+alt+.', resetAndDebug);
-
+function setupDebugControls() {
+ // create toolbar buttons
+ uitoolbar = new Toolbar($("#toolbar")[0]);
+ uitoolbar.grp.prop('id','debug_bar');
+ uitoolbar.add('ctrl+alt+.', 'Reset', 'glyphicon-refresh', resetAndDebug).prop('id','dbg_reset');
+ uitoolbar.add('ctrl+alt+P', 'Pause', 'glyphicon-pause', pause).prop('id','dbg_pause');
+ uitoolbar.add('ctrl+alt+R', 'Resume', 'glyphicon-play', resume).prop('id','dbg_go');
if (platform.step) {
- $("#dbg_step").click(singleStep).show();
- Mousetrap.bindGlobal('ctrl+alt+s', singleStep);
- } else
- $("#dbg_step").hide();
-
- if (platform.runToVsync) {
- $("#dbg_tovsync").click(singleFrameStep).show();
- Mousetrap.bindGlobal('ctrl+alt+v', singleFrameStep);
- } else
- $("#dbg_tovsync").hide();
-
- if ((platform.runEval || platform.runToPC) && !platform_id.startsWith('verilog')) {
- $("#dbg_toline").click(runToCursor).show();
- Mousetrap.bindGlobal('ctrl+alt+l', runToCursor);
- } else
- $("#dbg_toline").hide();
-
- if (platform.runUntilReturn) {
- $("#dbg_stepout").click(runUntilReturn).show();
- Mousetrap.bindGlobal('ctrl+alt+o', runUntilReturn);
- } else
- $("#dbg_stepout").hide();
-
- if (platform.stepBack) {
- $("#dbg_stepback").click(runStepBackwards).show();
- Mousetrap.bindGlobal('ctrl+alt+b', runStepBackwards);
- } else
- $("#dbg_stepback").hide();
-
- if (platform.newCodeAnalyzer) {
- $("#dbg_timing").click(traceTiming).show();
+ uitoolbar.add('ctrl+alt+S', 'Single Step', 'glyphicon-step-forward', singleStep).prop('id','dbg_step');
}
- $("#disassembly").hide();
+ if (platform.runToVsync) {
+ uitoolbar.add('ctrl+alt+V', 'Next Frame', 'glyphicon-forward', singleFrameStep).prop('id','dbg_tovsync');
+ }
+ if ((platform.runEval || platform.runToPC) && !platform_id.startsWith('verilog')) {
+ uitoolbar.add('ctrl+alt+L', 'Run To Line', 'glyphicon-save', runToCursor).prop('id','dbg_toline');
+ }
+ if (platform.runUntilReturn) {
+ uitoolbar.add('ctrl+alt+O', 'Step Out of Subroutine', 'glyphicon-hand-up', runUntilReturn).prop('id','dbg_stepout');
+ }
+ if (platform.stepBack) {
+ uitoolbar.add('ctrl+alt+B', 'Step Backwards', 'glyphicon-step-backward', runStepBackwards).prop('id','dbg_stepback');
+ }
+ uitoolbar.newGroup();
+ if (platform.newCodeAnalyzer) {
+ uitoolbar.add(null, 'Analyze CPU Timing', 'glyphicon-time', traceTiming);
+ }
+ // add menu clicks
$(".dropdown-menu").collapse({toggle: false});
$("#item_new_file").click(_createNewFile);
$("#item_upload_file").click(_uploadNewFile);
@@ -1137,12 +1123,13 @@ function setupDebugControls(){
$("#dbg_slowest").click(_slowestFrameRate);
$("#dbg_fastest").click(_fastestFrameRate);
}
- if (platform.showHelp) {
- $("#dbg_help").show().click(_lookupHelp);
- }
$("#item_addfile_include").click(_addIncludeFile);
$("#item_addfile_link").click(_addLinkFile);
updateDebugWindows();
+ // show help button?
+ if (platform.showHelp) {
+ uitoolbar.add('ctrl+alt+?', 'Show Help', 'glyphicon-question-sign', _lookupHelp);
+ }
// setup replay slider
if (platform.setRecorder && platform.advance) {
setupReplaySlider();
@@ -1183,7 +1170,7 @@ function setupReplaySlider() {
$("#replay_back").click(() => { setFrameTo(parseInt(replayslider.val().toString()) - 1); });
$("#replay_fwd").click(() => { setFrameTo(parseInt(replayslider.val().toString()) + 1); });
$("#replay_bar").show();
- $("#dbg_record").click(_toggleRecording).show();
+ uitoolbar.add('ctrl+alt+0', 'Start/Stop Replay Recording', 'glyphicon-record', _toggleRecording).prop('id','dbg_record');
}
@@ -1322,13 +1309,6 @@ function replaceURLState() {
history.replaceState({}, "", "?" + $.param(qs));
}
-function showBookLink() {
- if (platform_id == 'vcs')
- $("#booklink_vcs").show();
- else if (platform_id == 'mw8080bw' || platform_id == 'vicdual' || platform_id == 'galaxian-scramble' || platform_id == 'vector-z80color' || platform_id == 'williams-z80')
- $("#booklink_arcade").show();
-}
-
function addPageFocusHandlers() {
var hidden = false;
document.addEventListener("visibilitychange", function() {
@@ -1375,7 +1355,6 @@ function startPlatform() {
loadProject(qs['file']);
setupDebugControls();
updateSelector();
- showBookLink();
addPageFocusHandlers();
return true;
}