diff --git a/src/map.s b/src/map.s index b0aabe1..64e5bf0 100644 --- a/src/map.s +++ b/src/map.s @@ -171,8 +171,6 @@ Map_Scroll:: jr .loop .write_up: - ; halt - ; call write_map_row call enqueue_row_write ld a, [PAGEY] @@ -306,3 +304,159 @@ enqueue_row_write: dec c jr nz, .zero_row_loop ret + +; TODO: Deduplicate with enqueue_row_write? This version is needed when +; loading a map, which happens synchronously while LCD is disabled +; +; Write a row of map data into map RAM +; @param b Map X coordinate (signed) +; @param c Map Y coordinate (signed) +; @param hl Pointer into map VRAM +write_map_row: + push bc + push de + + ; If Y < 0, write a row of 0s + bit 7, c + jr nz, .zero_row + + ; If Y >= MAP_HEIGHT, write a row of 0s + ld a, [CURRENT_MAP_HEIGHT] + dec a + cp c + jr nc, .begin_writing + +.zero_row: + ld d, SCRN_VX_B + xor a +.zero_row_loop: + ld a, [hl+] + dec d + jr nz, .zero_row_loop +.zero_row_done: + pop de + pop bc + ret + +.begin_writing: + push hl + + ; Allocate 2 bytes for map pointer + ; Allocate 1 byte for number of tiles left + add sp, -3 + + ; left = number of tiles left to write + ld hl, sp + STACK_OFFSET_LEFT + ld [hl], SCRN_VX_B + + ; HL = CURRENT_MAP_PTR + Y * CURRENT_MAP_HEIGHT + ld a, [CURRENT_MAP_PTR] + ld l, a + ld a, [CURRENT_MAP_PTR + 1] + ld h, a + +.compute_map_row: + ld a, c + or a + jr z, .compute_map_row_done + + ld a, [CURRENT_MAP_HEIGHT] + ADD16 HL + dec c + jr .compute_map_row + + ; map = HL +.compute_map_row_done: + LD16 de, hl + ld hl, sp + STACK_OFFSET_MAP + ld a, e + ld [hl+], a + ld a, d + ld [hl], a + + ld hl, sp + STACK_OFFSET_LEFT + + ; While X < 0 and left > 0, write 0 to the row +.pad_left: + bit 7, b + jr z, .copy_center + + ld a, [hl] + or a + jr z, .done + + ; *row = 0 + ZERO_ROW_TILE + + ; row++ + INC_STACK16 STACK_OFFSET_ROW + + ; X++, left-- + inc b + ld hl, sp + STACK_OFFSET_LEFT + dec [hl] + jr .pad_left + + ; While X < MAP_WIDTH and [SP] > 0, copy from map +.copy_center: + ld a, [CURRENT_MAP_WIDTH] + dec a + cp b + jr z, .pad_right + + ld a, [hl] + or a + jr z, .done + + ; A = *map_ptr + ld hl, sp + STACK_OFFSET_MAP + ld a, [hl+] + ld e, a + ld d, [hl] + ld a, [de] + + ; map_ptr++ + INC_STACK16 STACK_OFFSET_MAP + + ; *row = A + ld hl, sp + STACK_OFFSET_ROW + ld e, [hl] + inc hl + ld d, [hl] + ld [de], a + + ; row++ + INC_STACK16 3 + + ; X++, [SP]-- +.copy_center_inc: + inc b + ld hl, sp + STACK_OFFSET_LEFT + dec [hl] + jr .copy_center + + ; While [SP] > 0, write 0 to the row +.pad_right: + ld a, [hl] + or a + jr z, .done + + ; *row = 0 + ZERO_ROW_TILE + + ; row++ + INC_STACK16 STACK_OFFSET_ROW + + ; [SP]-- +.pad_right_inc: + ld hl, sp + STACK_OFFSET_ROW + dec [hl] + jr .pad_right + +.done: + add sp, 3 + pop hl + pop de + pop bc + + ret