diff --git a/doc/notes.txt b/doc/notes.txt
index cb50e293..d0426e19 100644
--- a/doc/notes.txt
+++ b/doc/notes.txt
@@ -49,6 +49,7 @@ TODO:
- go to error in include files
- BOM in upload/download?
- stack view for Z80 platforms using memory map
+- online tools for music etc
FYI: Image links for the books on http://8bitworkshop.com/ are broken
On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional?
diff --git a/editstorage.html b/editstorage.html
deleted file mode 100644
index 0474a9ec..00000000
--- a/editstorage.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-8bitworkshop
-
-
-
-
-8bitworkshop Local Storage Editor
-
-
-
-
-Delete Selected Item
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/index.html b/index.html
index 79ea5563..ee21718f 100644
--- a/index.html
+++ b/index.html
@@ -159,10 +159,11 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
+
-
+
diff --git a/presets/nes/scrollrt.asm b/presets/nes/scrollrt.asm
new file mode 100644
index 00000000..441bb05b
--- /dev/null
+++ b/presets/nes/scrollrt.asm
@@ -0,0 +1,176 @@
+
+ include "nesdefs.asm"
+
+;;;;; VARIABLES
+
+ seg.u ZEROPAGE
+ org $0
+
+
+ seg.u RAM
+ org $300
+
+LineXLo ds 224
+LineXHi ds 224
+
+;;;;; NES CARTRIDGE HEADER
+
+ NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, horiz. mirror
+
+;;;;; START OF CODE
+
+Start:
+ NES_INIT ; set up stack pointer, turn off PPU
+ jsr WaitSync ; wait for VSYNC
+ jsr ClearRAM ; clear RAM
+ jsr WaitSync ; wait for VSYNC (and PPU warmup)
+
+ jsr SetPalette ; set palette colors
+ jsr FillVRAM ; set PPU video RAM
+ lda #0
+ sta PPU_ADDR
+ sta PPU_ADDR ; PPU addr = $0000
+ sta PPU_SCROLL
+ sta PPU_SCROLL ; scroll = $0000
+ lda #CTRL_NMI
+ sta PPU_CTRL ; enable NMI
+ lda #MASK_BG
+ sta PPU_MASK ; enable rendering
+.endless
+ jmp .endless ; endless loop
+
+; fill video RAM
+FillVRAM: subroutine
+ txa
+ ldy #$20
+ sty PPU_ADDR
+ sta PPU_ADDR
+ ldy #$10
+.loop:
+ sta PPU_DATA
+ adc #7
+ inx
+ bne .loop
+ dey
+ bne .loop
+ rts
+
+; set palette colors
+SetPalette: subroutine
+ ldy #$00
+ lda #$3f
+ sta PPU_ADDR
+ sty PPU_ADDR
+ ldx #32
+.loop:
+ lda Palette,y
+ sta PPU_DATA
+ iny
+ dex
+ bne .loop
+ rts
+
+
+;;;;; COMMON SUBROUTINES
+
+ include "nesppu.asm"
+
+;;;;; INTERRUPT HANDLERS
+
+NMIHandler: subroutine
+ SAVE_REGS
+ ldy #0
+.loop
+ tya
+ sec
+ adc LineXLo,y
+ sta LineXLo,y
+ lda LineXHi,y
+ adc #0
+ sta LineXHi,y
+ sta PPU_SCROLL ; horiz byte
+ lda #0
+ sta PPU_SCROLL ; vert byte
+ ldx #15
+.delay
+ dex
+ bne .delay
+ iny
+ cpy #224
+ bne .loop
+ RESTORE_REGS
+ rti
+
+;;;;; CONSTANT DATA
+
+ align $100
+Palette:
+ hex 1f ;background
+ hex 09092c00 ;bg0
+ hex 09091900 ;bg1
+ hex 09091500 ;bg2
+ hex 09092500 ;bg3
+
+;;;;; CPU VECTORS
+
+ NES_VECTORS
+
+;;;;; TILE SETS
+
+ org $10000
+; background (tile) pattern table
+ REPEAT 10
+;;{w:8,h:8,bpp:1,count:48,brev:1,np:2,pofs:8,remap:[0,1,2,4,5,6,7,8,9,10,11,12]};;
+ hex 00000000000000000000000000000000
+ hex 7e42424646467e007e42424646467e00
+ hex 08080818181818000808081818181800
+ hex 3e22023e30303e003e22023e30303e00
+ hex 3c24041e06263e003c24041e06263e00
+ hex 4444447e0c0c0c004444447e0c0c0c00
+ hex 3c20203e06263e003c20203e06263e00
+ hex 3e22203e26263e003e22203e26263e00
+ hex 3e020206060606003e02020606060600
+ hex 3c24247e46467e003c24247e46467e00
+ hex 3e22223e060606003e22223e06060600
+ hex 3c24247e626262003c24247e62626200
+ hex 7c44447e62627e007c44447e62627e00
+ hex 7e42406060627e007e42406060627e00
+ hex 7e42426262627e007e42426262627e00
+ hex 7c40407c60607c007c40407c60607c00
+ hex 3c20203c303030003c20203c30303000
+ hex 7e42406e62627e007e42406e62627e00
+ hex 4242427e626262004242427e62626200
+ hex 10101018181818001010101818181800
+ hex 0404040606467e000404040606467e00
+ hex 4444447e626262004444447e62626200
+ hex 2020203030303e002020203030303e00
+ hex fe9292d2d2d2d200fe9292d2d2d2d200
+ hex 7e424262626262007e42426262626200
+ hex 7e46464242427e007e46464242427e00
+ hex 7e42427e606060007e42427e60606000
+ hex 7e424242424e7e007e424242424e7e00
+ hex 7c44447e626262007c44447e62626200
+ hex 7e42407e06467e007e42407e06467e00
+ hex 7e101018181818007e10101818181800
+ hex 4242426262627e004242426262627e00
+ hex 646464642c2c3c00646464642c2c3c00
+ hex 4949494969697f004949494969697f00
+ hex 4242423c626262004242423c62626200
+ hex 4242427e181818004242427e18181800
+ hex 7e42027e60627e007e42027e60427e00
+ hex 10101818180018001010181818001800
+ hex 187e407e067e1800187e407e067e1800
+ hex 00180018180000000018001818000000
+ hex 00003c3c0000000000003c3c00000000
+ hex 00000018180000000000001818000000
+ hex 18180810000000001818081000000000
+ hex 00000018180810000000001818081000
+ hex 7c7c7c7c7c7c7c007c7c7c7c7c7c7c00
+ hex 0000000000007c000000000000007c00
+ hex 00000000000000000000000000000000
+ hex 00000000000000000000000000000000
+;;
+ REPEND
+ REPEAT 32
+ hex 00000000000000000000000000000000
+ REPEND
diff --git a/presets/nes/skeleton.dasm b/presets/nes/skeleton.dasm
index 09f6d651..86531e79 100644
--- a/presets/nes/skeleton.dasm
+++ b/presets/nes/skeleton.dasm
@@ -8,11 +8,11 @@
;;;;; NES CARTRIDGE HEADER
- NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, vertical
+ NES_HEADER 0,2,1,NES_MIRR_HORIZ ; mapper 0, 2 PRGs, 1 CHR
;;;;; START OF CODE
-Start:
+Start: subroutine
NES_INIT ; set up stack pointer, turn off PPU
jsr WaitSync ; wait for VSYNC
jsr ClearRAM ; clear RAM
@@ -37,7 +37,9 @@ Start:
;;;;; INTERRUPT HANDLERS
-NMIHandler:
+NMIHandler: subroutine
+ SAVE_REGS
+ RESTORE_REGS
rti
;;;;; CPU VECTORS
diff --git a/include/macro.h b/presets/vcs/macro.h
similarity index 100%
rename from include/macro.h
rename to presets/vcs/macro.h
diff --git a/include/vcs.h b/presets/vcs/vcs.h
similarity index 100%
rename from include/vcs.h
rename to presets/vcs/vcs.h
diff --git a/presets/vcs/xmacro.h b/presets/vcs/xmacro.h
new file mode 100644
index 00000000..dffb20a5
--- /dev/null
+++ b/presets/vcs/xmacro.h
@@ -0,0 +1,24 @@
+
+;-------------------------------------------------------
+; Usage: TIMER_SETUP lines
+; where lines is the number of scanlines to skip (> 2).
+; The timer will be set so that it expires before this number
+; of scanlines. A WSYNC will be done first.
+
+ MAC TIMER_SETUP
+.lines SET {1}
+ lda #(((.lines-1)*76-14)/64)
+ sta WSYNC
+ sta TIM64T
+ ENDM
+
+;-------------------------------------------------------
+; Use with TIMER_SETUP to wait for timer to complete.
+; You may want to do a WSYNC afterwards, since the timer
+; is not accurate to the beginning/end of a scanline.
+
+ MAC TIMER_WAIT
+.waittimer
+ lda INTIM
+ bne .waittimer
+ ENDM
diff --git a/src/baseplatform.ts b/src/baseplatform.ts
index 690bf5ed..82b4b383 100644
--- a/src/baseplatform.ts
+++ b/src/baseplatform.ts
@@ -99,7 +99,7 @@ abstract class BaseDebugPlatform {
clearDebug() {
this.debugSavedState = null;
this.debugBreakState = null;
- this.debugTargetClock = 0;
+ this.debugTargetClock = -1;
this.debugClock = 0;
this.onBreakpointHit = null;
this.debugCondition = null;
@@ -144,7 +144,7 @@ abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
}
runEval(evalfunc : DebugEvalCondition) {
this.setDebugCondition( () => {
- if (this.debugClock++ >= this.debugTargetClock) {
+ if (this.debugClock++ > this.debugTargetClock) {
var cpuState = this.getCPUState();
cpuState.PC = (cpuState.PC + this.debugPCDelta) & 0xffff;
if (evalfunc(cpuState)) {
diff --git a/src/emu.ts b/src/emu.ts
index 2ac47983..85bcc00a 100644
--- a/src/emu.ts
+++ b/src/emu.ts
@@ -439,7 +439,7 @@ export function padBytes(data, len) {
type AddressReadWriteFn = ((a:number) => number) | ((a:number,v:number) => void);
type AddressDecoderEntry = [number, number, number, AddressReadWriteFn];
-type AddressDecoderOptions = {gmask:number}
+type AddressDecoderOptions = {gmask?:number};
// TODO: better performance, check values
export function AddressDecoder(table : AddressDecoderEntry[], options?:AddressDecoderOptions) {