; bg update queue
- ; this is called once during blank
- ; it processess all tile updates
- ; until the bg_update_index is 0
+ ; loads update_start tile address
+ ; and updates tiles until the STOP flag is read
+ ; of the loop countr is BGE_MAX
bg_update_queue_process:
- ; read index
- ld a, [bg_update_index]
- ld e, a
- ld a, [bg_update_index+1]
- ld d, a
+ ld de, bg_update_queue ; load initial entry
+ ld b, BGE_MAX ; b == loop counter
+ ; hl = target address
- ; skip if index is already 0
- ld a, d
- xor a, e
- jp z, @done
-
- ld a, BG_UPDATE_MAX
@loop:
- push af
- ; index--
- ; sub length of an entry
- dec de
- dec de
- dec de
- dec de
-
- ; write to vram
- ld hl, bg_update_queue
- add hl, de ; hl = next index to process
-
- ld a, [hl+]
- ld c, a
- ld a, [hl+]
- ld b, a
- ; bc = vram address
+ ld a, [de] ; load flags
+ ; thest big 1 (STOP)
+ cp a, 0
+ jr z, @skip REL ; skip this entry
- ld a, [hl]
- ld [bc], a
-
-
- ; a--
- pop af
- dec a
+ ; first test address set mode
+ bit 2, a
+ jr z, @no_addr_set REL
+ push de
+ ; load addr from entry
+ inc de
+ inc de
+ ; get to addr
+ ld a, [de]
+ ld l, a
+ inc de
+ ld a, [de]
+ ld h, a
+ ; hl = new target address
+
+ pop de
+@no_addr_set:
+ ; test tile set bit
+ bit 1, a
+ jr z, @no_tile_wirte REL
+ inc de
+
+ ; write new tile and inc hl
+ ld a, [de]
+ ld [hl+], a
+
+ dec de
- ld b, a ; save a for after
- cp a, 0
- jr z, @done REL
-
- ld a, d
- xor a, e
- jr z, @done REL
-
- ld a, b ; restore a
- jr @loop REL
+@no_tile_wirte:
+@skip:
+ ; advance to next entry
+ inc de
+ inc de
+ inc de
+ inc de
+ dec b ; b--
+ jr nz, @loop REL
-@done:
- ; write index
- ld a, e
- ld [bg_update_index], a
- ld a, d
- ld [bg_update_index+1], a
-
- ret
-
+ ; advance to queue clear
; clears the bg update queue
; sets update index to 0
bg_update_queue_clear:
+ xor a, a
+ ld [bg_update_index], a
ret
-
; pushes a new bg update to the queue
; inputs:
- ; hl: ptr to tile
- ; a: tile data
- ; b: unused (set to 0 it may be used eventually)
+ ; b: tile data
+ ; a: entry flags
+ ; de: address (unused unless in BGEF_ADDR mode)
+ ; returns:
+ ; a == 1: if update was queued
+ ; a == 0: if queue is full
bg_update_queue_push:
- push hl
- pop bc ; move hl to bc
- push af
- ld hl, bg_update_queue
ld a, [bg_update_index]
- ld e, a
- ld a, [bg_update_index+1]
- ld d, a
- add hl, de ; hl = update queue + current offset
+ add a, a
+ add a, a
+ add a, a
+ add a, a
+ ; a * 4
+ ld b, 0
+ ld c, a ; de = index offset
- inc de ; offset += bgu_size
- inc de
- inc de
+ ld hl, bg_update_queue
+ add hl, bc
- ld a, e
- ld [bg_update_index], a
- ld a, d
- ld [bg_update_index+1], a
-
- ; store ptr
- ld a, c
+ ; write flags
ld [hl+], a
- ld a, b
+ ld b, a
+ ; write tile data
ld [hl+], a
-
- ; store new tile
- pop af
+
+ ; write address
+ ld a, e
+ ld [hl+], a
+ ld a, d
ld [hl], a
+ xor a, a ; queue was full
ret