Browse Source

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.
master
Forest Belton 2 years ago
parent
commit
7f2f61f062
3 changed files with 28 additions and 26 deletions
  1. +1
    -1
      Makefile
  2. +15
    -0
      inc/util.inc
  3. +12
    -25
      src/map.s

+ 1
- 1
Makefile View File

@ -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)

+ 15
- 0
inc/util.inc View File

@ -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

+ 12
- 25
src/map.s View File

@ -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

Loading…
Cancel
Save