From 7f2f61f06215fbd6d2f3c6d5f3ae0317c0137a35 Mon Sep 17 00:00:00 2001 From: Forest Belton Date: Tue, 13 Jul 2021 00:24:31 -0400 Subject: [PATCH] Optimize scroll-up/down routines In order to calculate the VRAM destination for these routines, we need to compute the row pointer into map RAM: ``` HL = _SCRN0 + 32 * (SCY/8 - 2) ``` The obvious approach of shifting `SCY/8 - 2` right 5 times won't work since overflow is possible. The first implementation worked by adding `SCY/8-2` to `_SCRN0` 32 times in a loop. Now, `SCY/8 - 2` is loaded into a 16-bit register and a 16-bit shift macro is expanded 5 times before being added to HL. The first approach took 802 * 4 cycles. This has been reduced to 25 * 4 cycles. --- Makefile | 2 +- inc/util.inc | 15 +++++++++++++++ src/map.s | 37 ++++++++++++------------------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 3530a25..3a3ea7f 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ OFILES := $(SFILES:%.s=%.o) $(MAP_S:%.s=%.o) is.gb is.gb.sym: $(OFILES) @echo "[LINK] is.gb" @rgblink -o $@ -n $@.sym $(OFILES) - @rgbfix -v $@ + @rgbfix -v -p 0 $@ $(OFILES): $(MAP_INC) $(OFILES): $(SPRITE_2BPP) diff --git a/inc/util.inc b/inc/util.inc index 4eebde5..40ecf05 100644 --- a/inc/util.inc +++ b/inc/util.inc @@ -49,3 +49,18 @@ MACRO LD16 ld HIGH(\1), HIGH(\2) ld LOW(\1), LOW(\2) ENDM + +MACRO SLA16 + sla LOW(\1) + rl HIGH(\1) +ENDM + +; Performs SLA on a register N times +; \1 8-bit register +; \2 N, a value 1-8 +MACRO slan + ASSERT 1 <= \2 && \2 <= 8 + REPT \2 + sla \1 + ENDR +ENDM diff --git a/src/map.s b/src/map.s index fbf655a..2545302 100644 --- a/src/map.s +++ b/src/map.s @@ -115,20 +115,12 @@ Map_Scroll:: ld c, a ; HL = _SCRN0 + 32 * (SCY/8 - 2) -.find_vram_ptr: ld a, [rSCY] sub 16 srl a srl a srl a - ld d, a - ld e, 32 - ld hl, _SCRN0 -.0: - ld a, d - ADD16 hl - dec e - jr nz, .0 + call get_row_ptr call enqueue_row_write @@ -151,8 +143,7 @@ Map_Scroll:: srl a srl a dec a - ld e, a - call compute_vram_ptr + call get_row_ptr ; B = CAMERA_X - SCX/8 ld a, [rSCX] @@ -297,22 +288,18 @@ Map_Update:: ret ; Computes the offset into map RAM -; @param e The map RAM y-coordinate +; @param a The map RAM y-coordinate ; @return hl Pointer into map RAM -compute_vram_ptr: - push bc +get_row_ptr: + push de + ld d, 0 + ld e, a + REPT 5 + SLA16 de + ENDR ld hl, _SCRN0 - ld b, 0 - ld c, SCRN_VX_B - ld a, e -.loop: - or a - jr z, .done - add hl, bc - dec a - jr .loop -.done: - pop bc + add hl, de + pop de ret ; Write a row of map data into row buffer