Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
cgb_boot: Compress logo with PB8
The logo is compressed using PB8, a form of RLE with unary-coded
run lengths.  Each block representing 8 bytes consists of a control
byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat
previous, followed by the literals in that block.

PB8 compression is also used in a few NES games.  A variant called
PB16, where 1 means repeat 2 bytes back, is used in the Game Boy
port of 240p Test Suite and in Libbet and the Magic Floor.

Switching from logo-compress RLE to PB8 decreases the compressed
logo data size from 287 bytes to 253 bytes, saving 34 bytes.
The decompression code is also about 10 bytes smaller.
  • Loading branch information
pinobatch committed Jul 16, 2019
1 parent eb95f1d commit 4504de8
Show file tree
Hide file tree
Showing 3 changed files with 386 additions and 40 deletions.
72 changes: 43 additions & 29 deletions BootROMs/cgb_boot.asm
Expand Up @@ -532,7 +532,7 @@ TrademarkSymbol:
db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c

SameBoyLogo:
incbin "SameBoyLogo.rle"
incbin "SameBoyLogo.pb8"

AnimationColors:
dw $7FFF ; White
Expand Down Expand Up @@ -634,41 +634,55 @@ ReadCGBLogoHalfTile:
ld a, e
ret

LoadTileset:
; Copy SameBoy Logo
ld de, SameBoyLogo
ld hl, $8080
.sameboyLogoLoop
ld a, [de]
inc de
; LoadTileset using PB8 codec, 2019 Damian Yerrick
;
; The logo is compressed using PB8, a form of RLE with unary-coded
; run lengths. Each block representing 8 bytes consists of a control
; byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat
; previous, followed by the literals in that block.

ld b, a
and $0f
jr z, .skipLiteral
ld c, a
SameBoyLogo_dst = $8080
SameBoyLogo_length = (128 * 24) / 64

.literalLoop
ld a, [de]
ldi [hl], a
LoadTileset:
ld hl, SameBoyLogo
ld de, SameBoyLogo_dst
ld c, SameBoyLogo_length
.pb8BlockLoop:
; Register map for PB8 decompression
; HL: source address in boot ROM
; DE: destination address in VRAM
; A: Current literal value
; B: Repeat bits, terminated by 1000...
; C: Number of 8-byte blocks left in this block
; Source address in HL lets the repeat bits go straight to B,
; bypassing A and avoiding spilling registers to the stack.
ld b, [hl]
inc hl

; Shift a 1 into lower bit of shift value. Once this bit
; reaches the carry, B becomes 0 and the byte is over
scf
rl b

.pb8BitLoop:
; If not a repeat, load a literal byte
jr c,.pb8Repeat
ld a, [hli]
.pb8Repeat:
; Decompressed data uses colors 0 and 1, so write once, inc twice
ld [de], a
inc de
dec c
jr nz, .literalLoop
.skipLiteral
swap b
ld a, b
and $0f
jr z, .sameboyLogoEnd
ld c, a
ld a, [de]
inc de
sla b
jr nz, .pb8BitLoop

.repeatLoop
ldi [hl], a
inc hl
dec c
jr nz, .repeatLoop
jr .sameboyLogoLoop
jr nz, .pb8BlockLoop

; End PB8 decoding. The rest uses HL as the destination
ld h, d
ld l, e

.sameboyLogoEnd
; Copy (unresized) ROM logo
Expand Down

0 comments on commit 4504de8

Please sign in to comment.