diff options
| -rw-r--r-- | include/gbos.inc | 3 | ||||
| -rw-r--r-- | src/boot.asm | 21 | ||||
| -rw-r--r-- | src/hram.asm | 4 | ||||
| -rw-r--r-- | src/term.asm | 5 |
4 files changed, 27 insertions, 6 deletions
diff --git a/include/gbos.inc b/include/gbos.inc index be6009f..cbd2670 100644 --- a/include/gbos.inc +++ b/include/gbos.inc @@ -13,7 +13,8 @@ DEF rIE EQU $FFFF ; interrupt enable DEF rTIMA EQU $FF05 ; timer counter DEF rTMA EQU $FF06 ; timer modulo (reload) DEF rTAC EQU $FF07 ; timer control (bit2 = enable, bits1-0 = clock) -DEF IEF_TIMER EQU %00000100 +DEF IEF_TIMER EQU %00000100 +DEF IEF_VBLANK EQU %00000001 DEF rDIV EQU $FF04 ; divider register: free-running 8-bit @ 16384 Hz DEF rSVBK EQU $FF70 ; CGB WRAM bank select ($D000-$DFFF): 1..7 DEF wCurMask EQU $D589 ; term/osk: cursor underline bits OR'd into a tile's last row 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 diff --git a/src/hram.asm b/src/hram.asm index 9e65982..facccd0 100644 --- a/src/hram.asm +++ b/src/hram.asm @@ -17,6 +17,10 @@ SECTION "hram_vars", HRAM hCurBankRAM: DS 1 ; shadow of active cart-RAM bank hCurBankWRAM: DS 1 ; shadow of active SVBK bank hSwitchTgt: DS 2 ; &incoming PCB (set before the pushes clobber DE) +hSCY:: DS 1 ; VBlank-latched SCY: term_view_update writes this, + ; the VBlank ISR applies it - a mid-frame SCY write + ; would shear the picture (SCY is sampled per + ; scanline), so ring-scrolls land at frame boundaries ; ----------------------------------------------------------------------------- ; Source image (lives in ROM0); CopyHramCode blits it to HRAM at boot. diff --git a/src/term.asm b/src/term.asm index 6a94024..46cd23e 100644 --- a/src/term.asm +++ b/src/term.asm @@ -60,6 +60,7 @@ term_init:: ld [rLCDC], a ; LCD off ld [rSCX], a ld [rSCY], a + ldh [hSCY], a ; keep the VBlank latch in sync ; Load all 8 CGB BG palettes from PalData (see tools/gencolor.py). Palettes ; 0 and 2..7 are the 7 Fano-plane text palettes (each = bg + 3 of our 7 @@ -168,8 +169,8 @@ term_view_update:: add a add a add a ; *8 px - ld [rSCY], a - ret + ldh [hSCY], a ; latched: the VBlank ISR applies it, so the + ret ; view never moves mid-frame (no shear) ; ----------------------------------------------------------------------------- ; map_row_one - write the BG-map row for logical row A (0..17): tile indices |
