Skip to content

Instantly share code, notes, and snippets.

@ISSOtm
Last active December 18, 2024 14:38
Show Gist options
  • Save ISSOtm/2a8575d5357d73afb1e4e0d82dedfd6b to your computer and use it in GitHub Desktop.
Save ISSOtm/2a8575d5357d73afb1e4e0d82dedfd6b to your computer and use it in GitHub Desktop.
Function(s) for rotating a tile clockwise 90 degrees on Game Boy.
INCLUDE "hardware.inc"
SECTION "Size-optimised", ROM0
RotateTileClockwise:
ld hl, wTileBuf.bp0
ld c, 8
.loop
REPT 2 ; Once for each bitplane.
ld a, [de]
scf
adc a, a
.bitplane\@
rr [hl]
inc l
add a, a
jr nz, .bitplane\@
inc de
ENDR
res 4, l ; Go back to first bitplane buffer.
dec c
jr nz, .loop
ret
WriteRotatedTile:
ld de, wTileBuf
.loop
ld a, [de]
ld [hli], a
set 3, e ; Switch to .bp1.
ld a, [de]
ld [hli], a
res 3, e ; Switch back to .bp0.
inc e
bit 3, e
jr z, .loop
ret
SECTION "Speed-optimised", ROM0
RotateTileClockwise_Unrolled:
ld hl, wTileBuf.bp0
FOR Y, 8
REPT 2 ; Once for each bitplane.
ld a, [de]
REPT 8
add a, a
rr [hl]
inc l
ENDR
inc de
ENDR
IF Y != 7
res 4, l ; Go back to first bitplane buffer.
ENDC
ENDR
ret
WriteRotatedTile_Unrolled:
ld de, wTileBuf
FOR Y, 8
ld a, [de]
ld [hli], a
set 3, e ; Switch to .bp1.
ld a, [de]
ld [hli], a
IF Y != 7
res 3, e ; Switch back to .bp0.
inc e
ENDC
ENDR
ret
SECTION "Balanced", ROM0
RotateTileClockwise_Balanced:
ld hl, wTileBuf.bp0
ld c, 8
.loop
FOR BITPLANE, 2
ld a, [de]
FOR X, 8
add a, a
rr [hl]
IF BITPLANE != 1 || X != 7
inc l
ENDC
ENDR
inc de
ENDR
ld l, LOW(wTileBuf.bp0) ; Go back to first bitplane buffer.
dec c
jr nz, .loop
ret
WriteRotatedTile_Balanced:
ld de, wTileBuf
.loop
ld a, [de]
ld [hli], a
set 3, e ; Switch to .bp1.
ld a, [de]
ld [hli], a
res 3, e ; Switch back to .bp0.
inc e
bit 3, e
jr z, .loop
ret
SECTION "Tile rotation buffer", WRAM0
wTileBuf: align 5
.bp0 ds 8 ; Bitplane 0 is stored here contiguously.
.bp1 ds 8 ; Likewise for bitplane 1.
MACRO dbg_msg
ld d, d
jr .skip\@
dw $6464, 1, DbgMsg\@, BANK(DbgMsg\@)
PUSHS
SECTION "Debug message \@", ROMX
DbgMsg\@: db \1, 0
POPS
.skip\@
ENDM
SECTION "Header", ROM0[$100]
jp EntryPoint
ds $150 - @, 0 ; Make room for the header
EntryPoint:
xor a
ldh [rLCDC], a
ld de, TestTile
ld hl, $8000
ld c, $10
call MemcpySmall
ld hl, $9800
:ld a, l
ld [hli], a
bit 2, h
jr z, :-
ld hl, wTileBuf
xor a
REPT 16
ld [hli], a
ENDR
dbg_msg STRFMT("%%ZEROCLKS%%Size-optimized (%u bytes):", SIZEOF("Size-optimised"))
ld de, $8000
call RotateTileClockwise
ld hl, $8010
call WriteRotatedTile
dbg_msg "$%LASTCLKS% 2 MiHz cycles"
dbg_msg STRFMT("%%ZEROCLKS%%Speed-optimized (%u bytes):", SIZEOF("Speed-optimised"))
ld de, $8010
call RotateTileClockwise_Unrolled
ld hl, $8020
call WriteRotatedTile_Unrolled
dbg_msg "$%LASTCLKS% 2 MiHz cycles"
dbg_msg STRFMT("%%ZEROCLKS%%Balanced (%u bytes):", SIZEOF("Balanced"))
ld de, $8020
call RotateTileClockwise_Balanced
ld hl, $8030
call WriteRotatedTile_Balanced
dbg_msg "$%LASTCLKS% 2 MiHz cycles"
ld a, $E4
ldh [rBGP], a
ld a, LCDCF_BG8000 | LCDCF_BGON | LCDCF_ON
ldh [rLCDC], a
di
halt
halt
halt
MemcpySmall:
ld a, [de]
ld [hli], a
inc de
dec c
jr nz, MemcpySmall
ret
TestTile:
dw `22222222
dw `21110002
dw `21310302
dw `21110002
dw `21310302
dw `21333302
dw `21110002
dw `22222222
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment