diff --git a/engine/video.asm b/engine/video.asm new file mode 100644 index 000000000..0d0aa272d --- /dev/null +++ b/engine/video.asm @@ -0,0 +1,487 @@ +; Functions dealing with VRAM. + +DMATransfer: ; 15d8 +; Return carry if the transfer is completed. + + ld a, [hDMATransfer] + and a + ret z + +; Start transfer + ld [rHDMA5], a + +; Execution is halted until the transfer is complete. + + xor a + ld [hDMATransfer], a + scf + ret +; 15e3 + + +UpdateBGMapBuffer: ; 15e3 +; Copy [$ffdc] 16x8 tiles from BGMapBuffer +; to bg map addresses in BGMapBufferPtrs. + +; [$ffdc] must be even since this is done in pairs. + +; Return carry on success. + + ld a, [hBGMapUpdate] + and a + ret z + + ld a, [rVBK] + push af + ld [hSPBuffer], sp + + ld hl, BGMapBufferPtrs + ld sp, hl + +; We can now pop the addresses of affected spots on the BG Map + + ld hl, BGMapPalBuffer + ld de, BGMapBuffer + + +.next +; Copy a pair of 16x8 blocks (one 16x16 block) + +rept 2 +; Get our BG Map address + pop bc + +; Palettes + ld a, 1 + ld [rVBK], a + + ld a, [hli] + ld [bc], a + inc c + ld a, [hli] + ld [bc], a + dec c + +; Tiles + ld a, 0 + ld [rVBK], a + + ld a, [de] + inc de + ld [bc], a + inc c + ld a, [de] + inc de + ld [bc], a +endr + +; We've done 2 16x8 blocks + ld a, [$ffdc] + dec a + dec a + ld [$ffdc], a + + jr nz, .next + + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + + pop af + ld [rVBK], a + + xor a + ld [hBGMapUpdate], a + scf + ret +; 163a + + +WaitTop: ; 163a +; Wait until the top third of the BG Map is being updated. + + ld a, [hBGMapMode] + and a + ret z + + ld a, [hBGMapThird] + and a + jr z, .done + + call DelayFrame + jr WaitTop + +.done + xor a + ld [hBGMapMode], a + ret +; 164c + + +UpdateBGMap: ; 164c +; Update the BG Map, in thirds, from TileMap and AttrMap. + + ld a, [hBGMapMode] + and a + ret z + +; BG Map 0 + dec a ; 1 + jr z, .Tiles + dec a ; 2 + jr z, .Attr + +; BG Map 1 + dec a + + ld a, [hBGMapAddress] + ld l, a + ld a, [hBGMapAddress + 1] + ld h, a + push hl + + xor a + ld [hBGMapAddress], a + ld a, VBGMap1 >> 8 + ld [hBGMapAddress + 1], a + + ld a, [hBGMapMode] + push af + cp 3 + call z, .Tiles + pop af + cp 4 + call z, .Attr + + pop hl + ld a, l + ld [hBGMapAddress], a + ld a, h + ld [hBGMapAddress + 1], a + ret + + +.Attr + ld a, 1 + ld [rVBK], a + + ld hl, AttrMap + call .update + + ld a, 0 + ld [rVBK], a + ret + + +.Tiles + ld hl, TileMap + + +.update + ld [hSPBuffer], sp + +; Which third? + ld a, [hBGMapThird] + and a ; 0 + jr z, .top + dec a ; 1 + jr z, .middle + ; 2 + + +THIRD_HEIGHT EQU SCREEN_HEIGHT / 3 + + +.bottom + ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH + add hl, de + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + + ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH + add hl, de + +; Next time: top third + xor a + jr .start + + +.middle + ld de, THIRD_HEIGHT * SCREEN_WIDTH + add hl, de + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + + ld de, THIRD_HEIGHT * BG_MAP_WIDTH + add hl, de + +; Next time: bottom third + ld a, 2 + jr .start + + +.top + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + +; Next time: middle third + ld a, 1 + + +.start +; Which third to update next time + ld [hBGMapThird], a + +; Rows of tiles in a third + ld a, SCREEN_HEIGHT / 3 + +; Discrepancy between TileMap and BGMap + ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1) + + +.row +; Copy a row of 20 tiles +rept SCREEN_WIDTH / 2 - 1 + pop de + ld [hl], e + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], d + + add hl, bc + dec a + jr nz, .row + + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 170a + + +Serve1bppRequest: ; 170a +; Only call during the first fifth of VBlank + + ld a, [Requested1bpp] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 146 + ret nc + +; Copy [Requested1bpp] 1bpp tiles from [Requested1bppSource] to [Requested1bppDest] + + ld [hSPBuffer], sp + +; Source + ld hl, Requested1bppSource + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + +; Destination + ld hl, Requested1bppDest + ld a, [hli] + ld h, [hl] + ld l, a + +; # tiles to copy + ld a, [Requested1bpp] + ld b, a + + xor a + ld [Requested1bpp], a + +.next + +rept 3 + pop de + ld [hl], e + inc l + ld [hl], e + inc l + ld [hl], d + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], e + inc l + ld [hl], d + inc l + ld [hl], d + + inc hl + dec b + jr nz, .next + + + ld a, l + ld [Requested1bppDest], a + ld a, h + ld [Requested1bppDest + 1], a + + ld [Requested1bppSource], sp + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 1769 + + +Serve2bppRequest: ; 1769 +; Only call during the first fifth of VBlank + + ld a, [Requested2bpp] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 146 + ret nc + jr _Serve2bppRequest + + +Serve2bppRequest@VBlank: ; 1778 + + ld a, [Requested2bpp] + and a + ret z + +_Serve2bppRequest: ; 177d +; Copy [Requested2bpp] 2bpp tiles from [Requested2bppSource] to [Requested2bppDest] + + ld [hSPBuffer], sp + +; Source + ld hl, Requested2bppSource + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + +; Destination + ld hl, Requested2bppDest + ld a, [hli] + ld h, [hl] + ld l, a + +; # tiles to copy + ld a, [Requested2bpp] + ld b, a + + xor a + ld [Requested2bpp], a + +.next + +rept 7 + pop de + ld [hl], e + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], d + + inc hl + dec b + jr nz, .next + + + ld a, l + ld [Requested2bppDest], a + ld a, h + ld [Requested2bppDest + 1], a + + ld [Requested2bppSource], sp + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 17d3 + + +AnimateTileset: ; 17d3 +; Only call during the first fifth of VBlank + + ld a, [$ffde] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 151 + ret nc + + ld a, [hROMBank] + push af + ld a, BANK(_AnimateTileset) + rst Bankswitch + + ld a, [rSVBK] + push af + ld a, 1 + ld [rSVBK], a + + ld a, [rVBK] + push af + ld a, 0 + ld [rVBK], a + + call _AnimateTileset + + pop af + ld [rVBK], a + pop af + ld [rSVBK], a + pop af + rst Bankswitch + ret +; 17ff + diff --git a/main.asm b/main.asm index e78027753..51007a1bd 100644 --- a/main.asm +++ b/main.asm @@ -54,493 +54,7 @@ INCLUDE "engine/decompress.asm" INCLUDE "engine/palettes.asm" INCLUDE "engine/copy.asm" INCLUDE "engine/text.asm" - - -DMATransfer: ; 15d8 -; Return carry if the transfer is completed. - - ld a, [hDMATransfer] - and a - ret z - -; Start transfer - ld [rHDMA5], a - -; Execution is halted until the transfer is complete. - - xor a - ld [hDMATransfer], a - scf - ret -; 15e3 - - -UpdateBGMapBuffer: ; 15e3 -; Copy [$ffdc] 16x8 tiles from BGMapBuffer -; to bg map addresses in BGMapBufferPtrs. - -; [$ffdc] must be even since this is done in pairs. - -; Return carry on success. - - ld a, [hBGMapUpdate] - and a - ret z - - ld a, [rVBK] - push af - ld [hSPBuffer], sp - - ld hl, BGMapBufferPtrs - ld sp, hl - -; We can now pop the addresses of affected spots on the BG Map - - ld hl, BGMapPalBuffer - ld de, BGMapBuffer - - -.next -; Copy a pair of 16x8 blocks (one 16x16 block) - -rept 2 -; Get our BG Map address - pop bc - -; Palettes - ld a, 1 - ld [rVBK], a - - ld a, [hli] - ld [bc], a - inc c - ld a, [hli] - ld [bc], a - dec c - -; Tiles - ld a, 0 - ld [rVBK], a - - ld a, [de] - inc de - ld [bc], a - inc c - ld a, [de] - inc de - ld [bc], a -endr - -; We've done 2 16x8 blocks - ld a, [$ffdc] - dec a - dec a - ld [$ffdc], a - - jr nz, .next - - - ld a, [hSPBuffer] - ld l, a - ld a, [hSPBuffer + 1] - ld h, a - ld sp, hl - - pop af - ld [rVBK], a - - xor a - ld [hBGMapUpdate], a - scf - ret -; 163a - - -WaitTop: ; 163a -; Wait until the top third of the BG Map is being updated. - - ld a, [hBGMapMode] - and a - ret z - - ld a, [hBGMapThird] - and a - jr z, .done - - call DelayFrame - jr WaitTop - -.done - xor a - ld [hBGMapMode], a - ret -; 164c - - -UpdateBGMap: ; 164c -; Update the BG Map, in thirds, from TileMap and AttrMap. - - ld a, [hBGMapMode] - and a - ret z - -; BG Map 0 - dec a ; 1 - jr z, .Tiles - dec a ; 2 - jr z, .Attr - -; BG Map 1 - dec a - - ld a, [hBGMapAddress] - ld l, a - ld a, [hBGMapAddress + 1] - ld h, a - push hl - - xor a - ld [hBGMapAddress], a - ld a, VBGMap1 >> 8 - ld [hBGMapAddress + 1], a - - ld a, [hBGMapMode] - push af - cp 3 - call z, .Tiles - pop af - cp 4 - call z, .Attr - - pop hl - ld a, l - ld [hBGMapAddress], a - ld a, h - ld [hBGMapAddress + 1], a - ret - - -.Attr - ld a, 1 - ld [rVBK], a - - ld hl, AttrMap - call .update - - ld a, 0 - ld [rVBK], a - ret - - -.Tiles - ld hl, TileMap - - -.update - ld [hSPBuffer], sp - -; Which third? - ld a, [hBGMapThird] - and a ; 0 - jr z, .top - dec a ; 1 - jr z, .middle - ; 2 - - -THIRD_HEIGHT EQU SCREEN_HEIGHT / 3 - - -.bottom - ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH - add hl, de - ld sp, hl - - ld a, [hBGMapAddress + 1] - ld h, a - ld a, [hBGMapAddress] - ld l, a - - ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH - add hl, de - -; Next time: top third - xor a - jr .start - - -.middle - ld de, THIRD_HEIGHT * SCREEN_WIDTH - add hl, de - ld sp, hl - - ld a, [hBGMapAddress + 1] - ld h, a - ld a, [hBGMapAddress] - ld l, a - - ld de, THIRD_HEIGHT * BG_MAP_WIDTH - add hl, de - -; Next time: bottom third - ld a, 2 - jr .start - - -.top - ld sp, hl - - ld a, [hBGMapAddress + 1] - ld h, a - ld a, [hBGMapAddress] - ld l, a - -; Next time: middle third - ld a, 1 - - -.start -; Which third to update next time - ld [hBGMapThird], a - -; Rows of tiles in a third - ld a, SCREEN_HEIGHT / 3 - -; Discrepancy between TileMap and BGMap - ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1) - - -.row -; Copy a row of 20 tiles -rept SCREEN_WIDTH / 2 - 1 - pop de - ld [hl], e - inc l - ld [hl], d - inc l -endr - pop de - ld [hl], e - inc l - ld [hl], d - - add hl, bc - dec a - jr nz, .row - - - ld a, [hSPBuffer] - ld l, a - ld a, [hSPBuffer + 1] - ld h, a - ld sp, hl - ret -; 170a - - -Serve1bppRequest: ; 170a -; Only call during the first fifth of VBlank - - ld a, [Requested1bpp] - and a - ret z - -; Back out if we're too far into VBlank - ld a, [rLY] - cp 144 - ret c - cp 146 - ret nc - -; Copy [Requested1bpp] 1bpp tiles from [Requested1bppSource] to [Requested1bppDest] - - ld [hSPBuffer], sp - -; Source - ld hl, Requested1bppSource - ld a, [hli] - ld h, [hl] - ld l, a - ld sp, hl - -; Destination - ld hl, Requested1bppDest - ld a, [hli] - ld h, [hl] - ld l, a - -; # tiles to copy - ld a, [Requested1bpp] - ld b, a - - xor a - ld [Requested1bpp], a - -.next - -rept 3 - pop de - ld [hl], e - inc l - ld [hl], e - inc l - ld [hl], d - inc l - ld [hl], d - inc l -endr - pop de - ld [hl], e - inc l - ld [hl], e - inc l - ld [hl], d - inc l - ld [hl], d - - inc hl - dec b - jr nz, .next - - - ld a, l - ld [Requested1bppDest], a - ld a, h - ld [Requested1bppDest + 1], a - - ld [Requested1bppSource], sp - - ld a, [hSPBuffer] - ld l, a - ld a, [hSPBuffer + 1] - ld h, a - ld sp, hl - ret -; 1769 - - -Serve2bppRequest: ; 1769 -; Only call during the first fifth of VBlank - - ld a, [Requested2bpp] - and a - ret z - -; Back out if we're too far into VBlank - ld a, [rLY] - cp 144 - ret c - cp 146 - ret nc - jr _Serve2bppRequest - - -Serve2bppRequest@VBlank: ; 1778 - - ld a, [Requested2bpp] - and a - ret z - -_Serve2bppRequest: ; 177d -; Copy [Requested2bpp] 2bpp tiles from [Requested2bppSource] to [Requested2bppDest] - - ld [hSPBuffer], sp - -; Source - ld hl, Requested2bppSource - ld a, [hli] - ld h, [hl] - ld l, a - ld sp, hl - -; Destination - ld hl, Requested2bppDest - ld a, [hli] - ld h, [hl] - ld l, a - -; # tiles to copy - ld a, [Requested2bpp] - ld b, a - - xor a - ld [Requested2bpp], a - -.next - -rept 7 - pop de - ld [hl], e - inc l - ld [hl], d - inc l -endr - pop de - ld [hl], e - inc l - ld [hl], d - - inc hl - dec b - jr nz, .next - - - ld a, l - ld [Requested2bppDest], a - ld a, h - ld [Requested2bppDest + 1], a - - ld [Requested2bppSource], sp - - ld a, [hSPBuffer] - ld l, a - ld a, [hSPBuffer + 1] - ld h, a - ld sp, hl - ret -; 17d3 - - -AnimateTileset: ; 17d3 -; Only call during the first fifth of VBlank - - ld a, [$ffde] - and a - ret z - -; Back out if we're too far into VBlank - ld a, [rLY] - cp 144 - ret c - cp 151 - ret nc - - ld a, [hROMBank] - push af - ld a, BANK(_AnimateTileset) - rst Bankswitch - - ld a, [rSVBK] - push af - ld a, 1 - ld [rSVBK], a - - ld a, [rVBK] - push af - ld a, 0 - ld [rVBK], a - - call _AnimateTileset - - pop af - ld [rVBK], a - pop af - ld [rSVBK], a - pop af - rst Bankswitch - ret -; 17ff - +INCLUDE "engine/video.asm" GetSpritePalette: ; 17ff push hl