diff --git a/src/main/fragment/cache/fragment-cache-mos6502.asm b/src/main/fragment/cache/fragment-cache-mos6502.asm index c8f402d23..06affc4ac 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 160b017651 +//KICKC FRAGMENT CACHE 160b015f22 //FRAGMENT vbuz1=vbuc1 lda #{c1} sta {z1} diff --git a/src/main/fragment/cache/fragment-cache-mos6502x.asm b/src/main/fragment/cache/fragment-cache-mos6502x.asm index 8e2321752..529c3fcfe 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502x.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502x.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 160b017651 +//KICKC FRAGMENT CACHE 160b015f22 //FRAGMENT vbuz1=vbuc1 lda #{c1} sta {z1} @@ -8562,6 +8562,52 @@ sty {z1} //FRAGMENT _deref_pbsc1=vbsc2 lda #{c2} sta {c1} +//FRAGMENT vbuz1=_dec_vbuz2 +ldy {z2} +dey +sty {z1} +//FRAGMENT vbuz1=_dec_vbuaa +sec +sbc #1 +sta {z1} +//FRAGMENT vbuz1=_dec_vbuxx +dex +stx {z1} +//FRAGMENT vbuz1=_dec_vbuyy +dey +sty {z1} +//FRAGMENT vbuaa=_dec_vbuz1 +lda {z1} +sec +sbc #1 +//FRAGMENT vbuaa=_dec_vbuxx +txa +sec +sbc #1 +//FRAGMENT vbuaa=_dec_vbuyy +tya +sec +sbc #1 +//FRAGMENT vbuxx=_dec_vbuz1 +ldx {z1} +dex +//FRAGMENT vbuxx=_dec_vbuaa +tax +dex +//FRAGMENT vbuxx=_dec_vbuyy +tya +tax +dex +//FRAGMENT vbuyy=_dec_vbuz1 +ldy {z1} +dey +//FRAGMENT vbuyy=_dec_vbuaa +tay +dey +//FRAGMENT vbuyy=_dec_vbuxx +txa +tay +dey //FRAGMENT vwuz1=vwuz2_bor_vbuz3 lda {z3} ora {z2} @@ -17737,49 +17783,3 @@ sta {c1},x lda #{c2} ora {c1},y sta {c1},y -//FRAGMENT vbuz1=_dec_vbuz2 -ldy {z2} -dey -sty {z1} -//FRAGMENT vbuz1=_dec_vbuaa -sec -sbc #1 -sta {z1} -//FRAGMENT vbuz1=_dec_vbuxx -dex -stx {z1} -//FRAGMENT vbuz1=_dec_vbuyy -dey -sty {z1} -//FRAGMENT vbuaa=_dec_vbuz1 -lda {z1} -sec -sbc #1 -//FRAGMENT vbuaa=_dec_vbuxx -txa -sec -sbc #1 -//FRAGMENT vbuaa=_dec_vbuyy -tya -sec -sbc #1 -//FRAGMENT vbuxx=_dec_vbuz1 -ldx {z1} -dex -//FRAGMENT vbuxx=_dec_vbuaa -tax -dex -//FRAGMENT vbuxx=_dec_vbuyy -tya -tax -dex -//FRAGMENT vbuyy=_dec_vbuz1 -ldy {z1} -dey -//FRAGMENT vbuyy=_dec_vbuaa -tay -dey -//FRAGMENT vbuyy=_dec_vbuxx -txa -tay -dey diff --git a/src/test/kc/complex/lazynes/lazynes.c b/src/test/kc/complex/lazynes/lazynes.c index 9ae0b3cf0..bbb0cf0f9 100644 --- a/src/test/kc/complex/lazynes/lazynes.c +++ b/src/test/kc/complex/lazynes/lazynes.c @@ -58,6 +58,17 @@ struct SpriteData align(0x100) SPRITE_BUFFER[0x40]; // Index of the next SpriteData in SPRITE_BUFFER to write to in lnAddSpr() volatile char add_sprite_idx; +// Counts the vblanks between syncs +volatile char vblank_count; + +// The current mode set by lnSync. +// lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls +// lfSplit = 2 activates split mode, NMI waits for SPR0HIT and sets registers +volatile char sync_mode; + +// Signal when vblank occurs. The NMI sets this to zero. To wait for a vblank set this no non-zero and wait for it to become zero. +volatile char vblank_signal; + // NMI Called when the PPU refreshes the screen (also known as the V-Blank period) interrupt(hardware_stack) void vblank() { // DMA transfer the entire sprite buffer to the PPU @@ -65,36 +76,58 @@ interrupt(hardware_stack) void vblank() { // Set scroll PPU->PPUSCROLL = 0; PPU->PPUSCROLL = 0; - // move all sprites off the screen - //for(char i=0;i!=0x40;i++) - // SPRITE_BUFFER[i].y = 0xff; - // Reset the index of sprites to add - add_sprite_idx = 0; + // count vblanks + vblank_count++; + // send vblank signal + vblank_signal = 0; } // Wait for next vblank // flags: 0, lfBlank or lfSplit (see below) // result: Amount of frames since last sync [0..31], 128 is added on NTSC -// +// lfBlank = 0, disables blank mode (if set), wait for vblank +// lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls +// lfSplit = 2 activates split mode, NMI waits for SPR0HIT and sets registers ubyte lnSync(ubyte flags) { - // Enable video output if lfBlank not set + // Is video output enabled (lfBlank==0) if(!(flags&lfBlank)) { - // Set sprite tileset to upper - enable vblank NMI - PPU->PPUCTRL = 0b10001000; - // Enable sprite and tile rendering - PPU->PPUMASK = 0b00011110; + // Move remaining sprites off the screen + for(char i=add_sprite_idx;i!=0x40;i++) + SPRITE_BUFFER[i].y = 0xff; + // Reset add sprite index + add_sprite_idx = 0; + // Enable video output (if it was disabled) + if(sync_mode&lfBlank) { + // Set sprite tileset to upper - enable vblank NMI + PPU->PPUCTRL = 0b10001000; + // Enable sprite and tile rendering + PPU->PPUMASK = 0b00011110; + } } - // Wait for V-Blank - waitForVBlank(); + // Wait for V-Blank signal from the NMI (if vblank is currently enabled) + if(!(sync_mode&lfBlank)) { + vblank_signal = 0xff; + while(vblank_signal) ; + } + // Disable video output if lfBlank set - if(flags&lfBlank) + if(flags&lfBlank) { // lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls - disableVideoOutput(); + // Disable vertical blank interrupt + PPU->PPUCTRL = 0; + // Disable sprite rendering + PPU->PPUMASK = 0; + } + + // Update the mode + sync_mode = flags; // TODO: Handle lfSplit = 2 : activates split mode, NMI waits for SPR0HIT and sets registers - // TODO: Count frames - return 0; + // Return number of vblank since last sync + char res = vblank_count; + vblank_count = 0; + return res; } // Write data into nametables, palettes, CHRRAM, etc.