From bea52bc8f99ee6dbcc8154a366560fc18e7b24c8 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 18 Jul 2026 21:56:21 +0200 Subject: term: latch SCY in VBlank - fix ring-scroll shear on live displays The ring-scroll wrote SCY mid-frame; SCY is sampled per scanline (on hardware and in sl0pboy's PPU), so a scroll landing mid-frame rendered the top of the frame at the old offset and the bottom at the new one - a one-frame shear, invisible in frame-sampled GIF captures but ugly on a live sixel view. term_view_update now writes hSCY (HRAM) and a transparent VBlank ISR (push af / apply / pop af / reti, same profile as TimerISR) copies it to rSCY, so the view only ever moves at frame boundaries. The scroll's tile+map writes stay immediate: the new map row is invisible at the old SCY by construction (it's the ring row one past the visible 18). --- src/boot.asm | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/boot.asm') diff --git a/src/boot.asm b/src/boot.asm index 4049f9d..88eb240 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -15,7 +15,7 @@ SECTION "rst30_syscall", ROM0[$30] ; Interrupt vectors ; ----------------------------------------------------------------------------- SECTION "vblank", ROM0[$40] - reti + jp VBlankISR ; applies the latched SCY (see hram.asm hSCY) SECTION "stat", ROM0[$48] reti SECTION "timer", ROM0[$50] @@ -83,7 +83,8 @@ KernelInit: ; system tick: hardware timer at 16384 Hz input, TMA=0 -> TIMA overflow ; IRQ at 64 Hz. TimerISR just counts (wTicks); scheduling stays - ; cooperative. Only the timer bit is enabled in IE. + ; cooperative. VBlank is enabled too, but its ISR is equally + ; transparent: it only applies the latched SCY (terminal ring-scroll). xor a ld [rTIMA], a ld [rTMA], a @@ -91,7 +92,7 @@ KernelInit: ld [rTAC], a xor a ld [rIF], a - ld a, IEF_TIMER + ld a, IEF_TIMER | IEF_VBLANK ld [rIE], a ei @@ -113,3 +114,17 @@ ClearKernelRAM: or c jr nz, .loop ret + +; ----------------------------------------------------------------------------- +; VBlankISR - transparent, like TimerISR: applies the latched SCY so terminal +; ring-scrolls land at frame boundaries. SCY is sampled per scanline, so a +; mid-frame write shears the picture (top at the old offset, bottom at the +; new) - exactly the sixel-view glitch this ISR exists to prevent. +; ----------------------------------------------------------------------------- +SECTION "vblank_isr", ROM0 +VBlankISR: + push af + ldh a, [hSCY] + ldh [$FF42], a ; rSCY + pop af + reti -- cgit v1.3.1-sl0p