Copy Tiles with vblank safety

This commit is contained in:
Shoofle 2025-01-07 11:34:53 -05:00
parent 4b100cf2a2
commit 2edbb942f4
5 changed files with 503 additions and 95 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

195
CopyRangeSafe.inc Normal file
View File

@ -0,0 +1,195 @@
CopyRangeSafe:
; hl is source
; de is destination
; bc is length to copy
; copy an array of bytes to a destination in memory.
; this is completely different from CopyRangeUnsafe.
; this initiates an asynchronous, interrupt-driven copy of BC bytes of memory
; from HL to DE.
; it may return a memory address to look at for progress of the transfer,
; or else it's just going to do it with a hard-coded address.
; check the transfer status address for zero; when it's zero, the transfer is done!
; this works by using the STAT interrupt in LYC mode to interrupt its own execution at
; two scanlines inside the vblank interval to know when to start and stop.
; stash arguments in memory
di
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a
ld a, c
ldh [vSafeCopyCount], a
ld a, b
ldh [vSafeCopyCount+1], a
; stash interrupt state in memory
ldh a, [$ff41]
ldh [vSafeCopySTAT], a ; stashes $FF41, the STAT register
ldh a, [$ff45]
ldh [vSafeCopyLYC], a ; stashes $FF45, the LYC register
ld a, [INTERRUPT_LCD]
ld [vSafeCopyInterruptFirst], a
ld a, [INTERRUPT_LCD + 1]
ld [vSafeCopyInterruptSecond], a ; stashes the current STAT interrupt handler
ld a, [$ffff]
and a, %0000_0010
ld [vSafeCopyInterruptEnable], a ; stashes whether LCD interrupt are enabled
ld hl, CopyRangeSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a
ld hl, $ffff
set 1, [hl]
ld a, %0100_0000
ld [$ff41], a
ld hl, vSafeCopyCount
ld a, 0
ld [$ff0f], a
nop
nop
nop
ei
nop
nop
nop
ret ; return address of bytes remaining to copy
CopyRangeSafe_EnterSafeMode:
push hl
push bc
push de
push af
ld hl, CopyRangeSafe_ExitSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 153 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
ldh a, [vSafeCopySource]
ld l, a
ldh a, [vSafeCopySource+1]
ld h, a ; fetch the source
ldh a, [vSafeCopyDest]
ld e, a
ldh a, [vSafeCopyDest+1]
ld d, a ; fetch the dest
ldh a, [vSafeCopyCount]
ld c, a
ldh a, [vSafeCopyCount+1]
ld b, a ; fetch the count
; before starting transfer, make sure the zero flag is false.
ld a, 1
cp a, 0
CopyRangeSafe_TransferLoop:
ei
nop ; ei only sets the flag one instruction later apparently. safety nop!
nop
di ; process interrupts
jp z, CopyRangeSafe_CleanUp ; zero flag will only be set if the exitsafemode handler fired
ld a, [hl+]
ld [de], a ;
inc de
dec bc
ld a, b
or a, c
jp nz, CopyRangeSafe_TransferLoop
jp CopyRangeSafe_Done
CopyRangeSafe_ExitSafeMode:
ld a, 0
cp a, 0 ; set the zero flag, which we're using as a signal to stop transferring
reti ; set a to zero and set the zero flag true. now the transfer loop will end
CopyRangeSafe_CleanUp:
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a ; store new source
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a ; store new dest
ld a, c
ldh [vSafeCopyCount], a
ld a, b
ldh [vSafeCopyCount+1], a ; store new count
ld hl, CopyRangeSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
pop af
pop de
pop bc
pop hl
reti ; we're done with this memcpy cycle so we return from interrupt.
CopyRangeSafe_Done: ; called when the complete transfer is finished,
; this restores interrupts to how they were.
; stash interrupt state in memory
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a ; store new source
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a ; store new dest
ld a, c
ldh [vSafeCopyCount], a
ld a, b
ldh [vSafeCopyCount+1], a ; store new count
ld hl, CopyRangeSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
pop af
pop de
pop bc
pop hl
ldh a, [vSafeCopySTAT]
ldh [$ff41], a
ldh a, [vSafeCopyLYC]
ldh [$ff45], a
ldh a, [vSafeCopyInterruptFirst]
ld [INTERRUPT_LCD], a
ldh a, [vSafeCopyInterruptSecond]
ldh [INTERRUPT_LCD+1], a
ld hl, $ffff
ld a, [hl]
cpl
set 1, a
cpl ; turn off the lcd interrupt enable
ld [hl], a
ld a, [vSafeCopyInterruptEnable]
cp a, 0 ; if the stashed enable was 0 return. if the stashed enable was 1 then turn it on
jp z, CopyRangeSafe_Return
set 1, [hl] ; turn on the lcd interrupt
CopyRangeSafe_Return:
reti

212
CopyTilesSafe.inc Normal file
View File

@ -0,0 +1,212 @@
CopyTilesSafe:
; hl is source
; de is destination
; bc is length to copy
; copy an array of bytes to the bgmap in vram.
; this is the safe-copy analogue of CopyTilesToMap
; stash arguments in memory
di
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a
ld a, c
ldh [vSafeCopyCount], a
ldh [vSafeCopyOriginalCount], a
ld a, b
ldh [vSafeCopyCount+1], a
ldh [vSafeCopyOriginalCount+1], a
; stash interrupt state in memory
ldh a, [$ff41]
ldh [vSafeCopySTAT], a ; stashes $FF41, the STAT register
ldh a, [$ff45]
ldh [vSafeCopyLYC], a ; stashes $FF45, the LYC register
ld a, [INTERRUPT_LCD]
ld [vSafeCopyInterruptFirst], a
ld a, [INTERRUPT_LCD + 1]
ld [vSafeCopyInterruptSecond], a ; stashes the current STAT interrupt handler
ld a, [$ffff]
and a, %0000_0010
ld [vSafeCopyInterruptEnable], a ; stashes whether LCD interrupt are enabled
ld hl, CopyTilesSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a
ld hl, $ffff
set 1, [hl]
ld a, %0100_0000
ld [$ff41], a
ld hl, vSafeCopyCount
ld a, 0
ld [$ff0f], a
ei
ret ; return address of bytes remaining to copy
CopyTilesSafe_EnterSafeMode:
push hl ; stash registers! we just took over as an interrupt!
push bc
push de
push af
ld hl, CopyTilesSafe_ExitSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 153 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
ldh a, [vSafeCopySource]
ld l, a
ldh a, [vSafeCopySource+1]
ld h, a ; fetch the source
ldh a, [vSafeCopyDest]
ld e, a
ldh a, [vSafeCopyDest+1]
ld d, a ; fetch the dest
ldh a, [vSafeCopyCount]
ld c, a
ldh a, [vSafeCopyCount+1]
ld b, a ; fetch the count
; before starting transfer, make sure the zero flag is false.
ld a, 1
cp a, 0
CopyTilesSafe_TransferLoop:
ei
nop ; ei only sets the flag one instruction later apparently. safety nop!
nop ; we're processing interrupts here
di
jp z, CopyTilesSafe_CleanUp ; zero flag will only be set if the exit handler fired
ld a, [hl] ; load from the tile map into a
ld [de], a ; load from a into the destination
inc hl ; this is slower than using hli but i'm trying to work with this here
inc de
dec c
; check if we've completed a line?
ld a, 0
or a, c ; check if c is zero, if it's not zero go back and copy more bytes
jp nz, CopyTilesSafe_TransferLoop
CopyTilesSafe_DoneWithLine:
ldh a, [vSafeCopyOriginalCount]
ld c, a
ldh a, [vSafeCopyOriginalCount+1]
ld b, a
ld a, e
add a, 32
ld e, a
ld a, d
adc a, 0
ld d, a
ld a, e
sub a, c
ld e, a
ld a, d
sbc a, 0
ld d, a
dec b
ld a, b
cp a, 0
ldh [vSafeCopyOriginalCount+1], a ; store the decremented line count
jp nz, CopyTilesSafe_TransferLoop
jp CopyTilesSafe_Done
CopyTilesSafe_ExitSafeMode:
ld a, 0
cp a, 0 ; set the zero flag, which we're using as a signal to stop transferring
reti ; set a to zero and set the zero flag true. now the transfer loop will end
CopyTilesSafe_CleanUp:
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a ; store new source
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a ; store new dest
ld a, c
ldh [vSafeCopyCount], a
ld a, b
ldh [vSafeCopyCount+1], a ; store new count
ld hl, CopyTilesSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
pop af
pop de
pop bc
pop hl
reti ; we're done with this memcpy cycle so we return from interrupt.
CopyTilesSafe_Done: ; called when the complete transfer is finished,
; this restores interrupts to how they were.
; stash interrupt state in memory
ld a, l
ldh [vSafeCopySource], a
ld a, h
ldh [vSafeCopySource+1], a ; store new source
ld a, e
ldh [vSafeCopyDest], a
ld a, d
ldh [vSafeCopyDest+1], a ; store new dest
ld a, 0
ldh [vSafeCopyCount], a
ld a, 0
ldh [vSafeCopyCount+1], a ; store new count
ld hl, CopyRangeSafe_EnterSafeMode
ld a, l
ld [INTERRUPT_LCD], a
ld a, h
ld [INTERRUPT_LCD+1], a
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
pop af
pop de
pop bc
pop hl
ldh a, [vSafeCopySTAT]
ldh [$ff41], a
ldh a, [vSafeCopyLYC]
ldh [$ff45], a
ldh a, [vSafeCopyInterruptFirst]
ld [INTERRUPT_LCD], a
ldh a, [vSafeCopyInterruptSecond]
ldh [INTERRUPT_LCD+1], a
ld hl, $ffff
ld a, [hl]
cpl
set 1, a
cpl ; turn off the lcd interrupt enable
ld [hl], a
ld a, [vSafeCopyInterruptEnable]
cp a, 0 ; check if the stat interrupt was active before we took over
jp z, CopyRangeSafe_Return
set 1, [hl] ; turn on the lcd interrupt
CopyTilesSafe_Return:
reti

View File

@ -4,101 +4,101 @@
littleletters:
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$00,$00,$04,$04
db $28,$28,$28,$28,$28,$28,$08,$08,$00,$00,$00,$00,$00,$00,$00,$00
db $04,$04,$24,$24,$2c,$2c,$28,$28,$fc,$fc,$28,$28,$fe,$fe,$28,$28
db $38,$38,$60,$60,$e0,$e0,$70,$70,$30,$30,$20,$20,$e0,$e0,$60,$60
db $e0,$e0,$b0,$b0,$b2,$b2,$e4,$e4,$08,$08,$16,$16,$35,$35,$27,$27
db $1c,$1c,$74,$74,$60,$60,$38,$38,$3d,$3d,$37,$37,$3e,$3e,$3c,$3c
db $00,$00,$18,$18,$10,$10,$10,$10,$00,$00,$00,$00,$00,$00,$00,$00
db $08,$08,$10,$10,$20,$20,$20,$20,$20,$20,$20,$20,$30,$30,$10,$10
db $00,$00,$00,$00,$0e,$0e,$02,$02,$02,$02,$06,$06,$0c,$0c,$18,$18
db $02,$02,$46,$46,$6c,$6c,$78,$78,$7c,$7c,$68,$68,$0c,$0c,$00,$00
db $08,$08,$08,$08,$08,$08,$08,$08,$7c,$7c,$08,$08,$08,$08,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$18,$18,$10,$10
db $00,$00,$00,$00,$00,$00,$3c,$3c,$20,$20,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$20,$20,$00,$00
db $00,$00,$00,$00,$02,$02,$04,$04,$0c,$0c,$08,$08,$10,$10,$10,$10
db $00,$00,$00,$00,$3c,$3c,$24,$24,$24,$24,$3c,$3c,$00,$00,$00,$00
db $00,$00,$04,$04,$04,$04,$04,$04,$04,$04,$0c,$0c,$08,$08,$00,$00
db $00,$00,$0c,$0c,$12,$12,$12,$12,$02,$02,$0e,$0e,$07,$07,$00,$00
db $00,$00,$00,$00,$38,$38,$08,$08,$18,$18,$18,$18,$00,$00,$00,$00
db $02,$02,$32,$32,$26,$26,$3e,$3e,$24,$24,$04,$04,$00,$00,$00,$00
db $00,$00,$00,$00,$3e,$3e,$20,$20,$38,$38,$08,$08,$38,$38,$20,$20
db $00,$00,$00,$00,$30,$30,$20,$20,$58,$58,$68,$68,$7c,$7c,$3c,$3c
db $00,$00,$1e,$1e,$03,$03,$03,$03,$02,$02,$04,$04,$04,$04,$00,$00
db $00,$00,$3c,$3c,$24,$24,$38,$38,$18,$18,$1c,$1c,$38,$38,$00,$00
db $00,$00,$00,$00,$3e,$3e,$64,$64,$7c,$7c,$0c,$0c,$08,$08,$10,$10
db $00,$00,$00,$00,$10,$10,$00,$00,$00,$00,$10,$10,$10,$10,$00,$00
db $00,$00,$08,$08,$00,$00,$00,$00,$0c,$0c,$04,$04,$0c,$0c,$18,$18
db $00,$00,$04,$04,$1c,$1c,$30,$30,$60,$60,$78,$78,$1e,$1e,$02,$02
db $00,$00,$00,$00,$00,$00,$3c,$3c,$40,$40,$78,$78,$00,$00,$00,$00
db $00,$00,$20,$20,$30,$30,$18,$18,$0c,$0c,$1c,$1c,$30,$30,$00,$00
db $0c,$0c,$3c,$3c,$24,$24,$0c,$0c,$08,$08,$08,$08,$00,$00,$08,$08
db $00,$00,$04,$04,$1e,$1e,$3f,$3f,$36,$36,$3e,$3e,$1c,$1c,$00,$00
db $00,$00,$10,$10,$28,$28,$28,$28,$7c,$7c,$44,$44,$82,$82,$82,$82
db $00,$00,$7c,$7c,$22,$22,$22,$22,$3c,$3c,$22,$22,$22,$22,$7c,$7c
db $00,$00,$3c,$3c,$42,$42,$40,$40,$40,$40,$40,$40,$42,$42,$3c,$3c
db $00,$00,$78,$78,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$78,$78
db $00,$00,$7c,$7c,$44,$44,$40,$40,$78,$78,$40,$40,$44,$44,$7c,$7c
db $00,$00,$7c,$7c,$24,$24,$20,$20,$38,$38,$20,$20,$20,$20,$20,$20
db $00,$00,$38,$38,$44,$44,$40,$40,$4c,$4c,$44,$44,$44,$44,$38,$38
db $00,$00,$44,$44,$44,$44,$44,$44,$7c,$7c,$44,$44,$44,$44,$44,$44
db $00,$00,$38,$38,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$38,$38
db $00,$00,$0e,$0e,$04,$04,$04,$04,$04,$04,$04,$04,$44,$44,$38,$38
db $00,$00,$48,$48,$50,$50,$60,$60,$60,$60,$50,$50,$48,$48,$44,$44
db $00,$00,$70,$70,$20,$20,$20,$20,$20,$20,$20,$20,$22,$22,$7e,$7e
db $00,$00,$42,$42,$66,$66,$5a,$5a,$42,$42,$42,$42,$42,$42,$42,$42
db $00,$00,$64,$64,$64,$64,$54,$54,$54,$54,$4c,$4c,$4c,$4c,$44,$44
db $00,$00,$38,$38,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$38,$38
db $00,$00,$78,$78,$44,$44,$44,$44,$44,$44,$78,$78,$40,$40,$40,$40
db $00,$00,$38,$38,$44,$44,$44,$44,$44,$44,$4c,$4c,$44,$44,$3a,$3a
db $00,$00,$78,$78,$44,$44,$44,$44,$7c,$7c,$48,$48,$48,$48,$44,$44
db $00,$00,$1c,$1c,$22,$22,$20,$20,$1c,$1c,$02,$02,$62,$62,$1c,$1c
db $00,$00,$7c,$7c,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10
db $00,$00,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$3c,$3c
db $00,$00,$44,$44,$44,$44,$28,$28,$28,$28,$28,$28,$10,$10,$10,$10
db $00,$00,$82,$82,$82,$82,$44,$44,$54,$54,$54,$54,$28,$28,$28,$28
db $00,$00,$44,$44,$28,$28,$28,$28,$10,$10,$28,$28,$28,$28,$44,$44
db $00,$00,$44,$44,$28,$28,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10
db $00,$00,$7c,$7c,$08,$08,$08,$08,$10,$10,$20,$20,$20,$20,$7c,$7c
db $00,$00,$3c,$3c,$20,$20,$20,$20,$20,$20,$20,$20,$3c,$3c,$00,$00
db $00,$00,$c0,$c0,$c0,$c0,$40,$40,$60,$60,$20,$20,$10,$10,$18,$18
db $18,$18,$0f,$0f,$03,$03,$02,$02,$02,$02,$02,$02,$12,$12,$1e,$1e
db $08,$08,$1c,$1c,$34,$34,$04,$04,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$3e,$3e,$00,$00
db $20,$20,$18,$18,$0c,$0c,$04,$04,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$38,$38,$04,$04,$3c,$3c,$44,$44,$3a,$3a,$00,$00
db $00,$00,$20,$20,$20,$20,$3c,$3c,$22,$22,$22,$22,$3c,$3c,$00,$00
db $00,$00,$00,$00,$1c,$1c,$20,$20,$20,$20,$20,$20,$1c,$1c,$00,$00
db $00,$00,$04,$04,$04,$04,$3c,$3c,$44,$44,$44,$44,$3c,$3c,$00,$00
db $00,$00,$00,$00,$38,$38,$44,$44,$78,$78,$40,$40,$3c,$3c,$00,$00
db $00,$00,$0c,$0c,$10,$10,$38,$38,$10,$10,$10,$10,$10,$10,$00,$00
db $00,$00,$00,$00,$3c,$3c,$44,$44,$44,$44,$3c,$3c,$04,$04,$38,$38
db $00,$00,$40,$40,$40,$40,$78,$78,$44,$44,$44,$44,$44,$44,$00,$00
db $00,$00,$10,$10,$00,$00,$30,$30,$10,$10,$10,$10,$38,$38,$00,$00
db $00,$00,$04,$04,$00,$00,$04,$04,$04,$04,$04,$04,$24,$24,$18,$18
db $00,$00,$20,$20,$28,$28,$28,$28,$30,$30,$28,$28,$24,$24,$00,$00
db $00,$00,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$0c,$0c,$00,$00
db $00,$00,$00,$00,$68,$68,$54,$54,$54,$54,$54,$54,$54,$54,$00,$00
db $00,$00,$00,$00,$78,$78,$44,$44,$44,$44,$44,$44,$44,$44,$00,$00
db $00,$00,$00,$00,$38,$38,$44,$44,$44,$44,$44,$44,$38,$38,$00,$00
db $00,$00,$00,$00,$78,$78,$44,$44,$44,$44,$78,$78,$40,$40,$40,$40
db $00,$00,$00,$00,$3c,$3c,$44,$44,$44,$44,$3c,$3c,$04,$04,$06,$06
db $00,$00,$00,$00,$1c,$1c,$20,$20,$20,$20,$20,$20,$20,$20,$00,$00
db $00,$00,$00,$00,$38,$38,$40,$40,$38,$38,$04,$04,$78,$78,$00,$00
db $00,$00,$10,$10,$38,$38,$10,$10,$10,$10,$10,$10,$0c,$0c,$00,$00
db $00,$00,$00,$00,$44,$44,$44,$44,$44,$44,$44,$44,$3c,$3c,$00,$00
db $00,$00,$00,$00,$44,$44,$44,$44,$44,$44,$28,$28,$10,$10,$00,$00
db $00,$00,$00,$00,$44,$44,$54,$54,$54,$54,$54,$54,$28,$28,$00,$00
db $00,$00,$00,$00,$44,$44,$28,$28,$10,$10,$28,$28,$44,$44,$00,$00
db $00,$00,$00,$00,$44,$44,$44,$44,$44,$44,$3c,$3c,$04,$04,$38,$38
db $00,$00,$00,$00,$7c,$7c,$08,$08,$10,$10,$20,$20,$7c,$7c,$00,$00
db $0e,$0e,$18,$18,$0c,$0c,$0c,$0c,$38,$38,$08,$08,$18,$18,$1c,$1c
db $20,$20,$30,$30,$20,$20,$10,$10,$10,$10,$10,$10,$00,$00,$00,$00
db $30,$30,$38,$38,$10,$10,$10,$10,$10,$10,$18,$18,$18,$18,$30,$30
db $00,$00,$00,$00,$32,$32,$3c,$3c,$78,$78,$00,$00,$00,$00,$00,$00
db $06,$06,$7c,$7c,$5f,$5f,$5b,$5b,$5e,$5e,$72,$72,$03,$03,$00,$00
db $03,$03,$07,$07,$0f,$0f,$0e,$0e,$1c,$1c,$30,$30,$c0,$c0,$c0,$c0
db $24,$24,$6c,$6c,$6c,$6c,$48,$48,$00,$00,$00,$00,$00,$00,$00,$00
db $1a,$1a,$1a,$1a,$7f,$7f,$34,$34,$34,$34,$fe,$fe,$68,$68,$68,$68
db $08,$08,$3c,$3c,$6a,$6a,$68,$68,$3c,$3c,$0a,$0a,$6a,$6a,$3c,$3c
db $63,$63,$a6,$a6,$ac,$ac,$d8,$d8,$1b,$1b,$35,$35,$65,$65,$c6,$c6
db $18,$18,$24,$24,$28,$28,$18,$18,$2c,$2c,$66,$66,$67,$67,$39,$39
db $18,$18,$18,$18,$18,$18,$30,$30,$00,$00,$00,$00,$00,$00,$00,$00
db $04,$04,$0c,$0c,$18,$18,$10,$10,$10,$10,$18,$18,$0c,$0c,$04,$04
db $20,$20,$30,$30,$18,$18,$08,$08,$08,$08,$18,$18,$30,$30,$20,$20
db $00,$00,$08,$08,$28,$28,$1e,$1e,$78,$78,$14,$14,$10,$10,$00,$00
db $00,$00,$00,$00,$18,$18,$18,$18,$7e,$7e,$18,$18,$18,$18,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$0c,$0c,$0c,$0c,$0c,$0c,$18,$18
db $00,$00,$00,$00,$00,$00,$1c,$1c,$38,$38,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$18,$18,$00,$00
db $04,$04,$0c,$0c,$0c,$0c,$18,$18,$18,$18,$30,$30,$30,$30,$20,$20
db $00,$00,$38,$38,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64,$38,$38
db $08,$08,$18,$18,$38,$38,$18,$18,$18,$18,$18,$18,$18,$18,$3c,$3c
db $00,$00,$38,$38,$4c,$4c,$0c,$0c,$0c,$0c,$18,$18,$30,$30,$7c,$7c
db $00,$00,$3c,$3c,$06,$06,$06,$06,$1c,$1c,$06,$06,$06,$06,$3c,$3c
db $00,$00,$04,$04,$26,$26,$26,$26,$3e,$3e,$06,$06,$06,$06,$04,$04
db $00,$00,$7c,$7c,$64,$64,$60,$60,$78,$78,$44,$44,$04,$04,$38,$38
db $00,$00,$20,$20,$30,$30,$30,$30,$3c,$3c,$32,$32,$32,$32,$1c,$1c
db $00,$00,$7c,$7c,$4c,$4c,$0c,$0c,$3e,$3e,$18,$18,$30,$30,$20,$20
db $00,$00,$78,$78,$64,$64,$64,$64,$38,$38,$64,$64,$64,$64,$3c,$3c
db $00,$00,$38,$38,$4c,$4c,$4c,$4c,$3c,$3c,$0c,$0c,$0c,$0c,$18,$18
db $00,$00,$00,$00,$18,$18,$18,$18,$00,$00,$18,$18,$18,$18,$00,$00
db $00,$00,$00,$00,$0c,$0c,$0c,$0c,$00,$00,$0c,$0c,$0c,$0c,$18,$18
db $00,$00,$0c,$0c,$18,$18,$30,$30,$60,$60,$30,$30,$18,$18,$0c,$0c
db $00,$00,$00,$00,$3c,$3c,$3c,$3c,$00,$00,$3c,$3c,$3c,$3c,$00,$00
db $00,$00,$30,$30,$18,$18,$0c,$0c,$06,$06,$0c,$0c,$18,$18,$30,$30
db $38,$38,$6c,$6c,$24,$24,$0c,$0c,$18,$18,$18,$18,$00,$00,$18,$18
db $3c,$3c,$62,$62,$59,$59,$45,$45,$5d,$5d,$5d,$5d,$63,$63,$38,$38
db $00,$00,$38,$38,$34,$34,$32,$32,$3e,$3e,$32,$32,$32,$32,$32,$32
db $00,$00,$7c,$7c,$32,$32,$32,$32,$3c,$3c,$32,$32,$32,$32,$1c,$1c
db $00,$00,$3c,$3c,$72,$72,$62,$62,$60,$60,$60,$60,$62,$62,$3c,$3c
db $00,$00,$f8,$f8,$64,$64,$62,$62,$62,$62,$62,$62,$62,$62,$3c,$3c
db $00,$00,$fc,$fc,$60,$60,$60,$60,$78,$78,$60,$60,$60,$60,$3c,$3c
db $00,$00,$fc,$fc,$60,$60,$60,$60,$78,$78,$60,$60,$60,$60,$20,$20
db $00,$00,$78,$78,$64,$64,$60,$60,$60,$60,$6e,$6e,$64,$64,$3c,$3c
db $00,$00,$40,$40,$62,$62,$62,$62,$7e,$7e,$62,$62,$62,$62,$22,$22
db $00,$00,$10,$10,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$08,$08
db $00,$00,$08,$08,$0c,$0c,$0c,$0c,$0c,$0c,$4c,$4c,$6c,$6c,$3c,$3c
db $00,$00,$40,$40,$64,$64,$68,$68,$70,$70,$68,$68,$64,$64,$22,$22
db $00,$00,$20,$20,$30,$30,$30,$30,$30,$30,$30,$30,$32,$32,$1e,$1e
db $00,$00,$3e,$3e,$6a,$6a,$6a,$6a,$6a,$6a,$62,$62,$62,$62,$22,$22
db $00,$00,$72,$72,$6a,$6a,$6a,$6a,$6a,$6a,$66,$66,$62,$62,$22,$22
db $00,$00,$3c,$3c,$66,$66,$62,$62,$62,$62,$62,$62,$32,$32,$1e,$1e
db $00,$00,$f8,$f8,$64,$64,$64,$64,$7c,$7c,$60,$60,$60,$60,$20,$20
db $00,$00,$38,$38,$64,$64,$62,$62,$62,$62,$6a,$6a,$64,$64,$3b,$3b
db $00,$00,$f8,$f8,$64,$64,$64,$64,$7c,$7c,$68,$68,$64,$64,$23,$23
db $00,$00,$38,$38,$64,$64,$60,$60,$38,$38,$04,$04,$64,$64,$38,$38
db $00,$00,$7e,$7e,$5a,$5a,$18,$18,$18,$18,$18,$18,$18,$18,$08,$08
db $00,$00,$40,$40,$62,$62,$62,$62,$62,$62,$62,$62,$62,$62,$3c,$3c
db $00,$00,$40,$40,$62,$62,$62,$62,$62,$62,$24,$24,$34,$34,$18,$18
db $00,$00,$c3,$c3,$62,$62,$62,$62,$6a,$6a,$6a,$6a,$6a,$6a,$34,$34
db $00,$00,$42,$42,$62,$62,$34,$34,$18,$18,$3c,$3c,$66,$66,$42,$42
db $00,$00,$4c,$4c,$4c,$4c,$4c,$4c,$3c,$3c,$0c,$0c,$4c,$4c,$78,$78
db $00,$00,$7e,$7e,$46,$46,$0c,$0c,$18,$18,$30,$30,$62,$62,$7e,$7e
db $7c,$7c,$60,$60,$60,$60,$60,$60,$60,$60,$60,$60,$60,$60,$7c,$7c
db $20,$20,$30,$30,$30,$30,$18,$18,$18,$18,$0c,$0c,$0c,$0c,$04,$04
db $3e,$3e,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$3e,$3e
db $18,$18,$3c,$3c,$66,$66,$42,$42,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$7c,$3e,$3e
db $30,$30,$18,$18,$0c,$0c,$04,$04,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$38,$38,$0c,$0c,$3c,$3c,$4c,$4c,$3a,$3a,$00,$00
db $00,$00,$30,$30,$30,$30,$3c,$3c,$32,$32,$32,$32,$3c,$3c,$00,$00
db $00,$00,$00,$00,$1c,$1c,$30,$30,$30,$30,$30,$30,$1c,$1c,$00,$00
db $00,$00,$0c,$0c,$0c,$0c,$3c,$3c,$4c,$4c,$4c,$4c,$3c,$3c,$00,$00
db $00,$00,$00,$00,$38,$38,$64,$64,$78,$78,$60,$60,$3c,$3c,$00,$00
db $00,$00,$0e,$0e,$18,$18,$3c,$3c,$18,$18,$18,$18,$18,$18,$00,$00
db $00,$00,$00,$00,$3c,$3c,$4c,$4c,$4c,$4c,$3c,$3c,$0c,$0c,$38,$38
db $00,$00,$60,$60,$60,$60,$78,$78,$64,$64,$64,$64,$64,$64,$00,$00
db $00,$00,$10,$10,$00,$00,$38,$38,$18,$18,$18,$18,$3c,$3c,$00,$00
db $00,$00,$08,$08,$00,$00,$0c,$0c,$0c,$0c,$0c,$0c,$2c,$2c,$18,$18
db $00,$00,$60,$60,$68,$68,$68,$68,$70,$70,$68,$68,$64,$64,$00,$00
db $00,$00,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$18,$18,$00,$00
db $00,$00,$00,$00,$74,$74,$6a,$6a,$6a,$6a,$6a,$6a,$6a,$6a,$00,$00
db $00,$00,$00,$00,$78,$78,$64,$64,$64,$64,$64,$64,$64,$64,$00,$00
db $00,$00,$00,$00,$38,$38,$64,$64,$64,$64,$64,$64,$38,$38,$00,$00
db $00,$00,$00,$00,$78,$78,$64,$64,$64,$64,$78,$78,$60,$60,$60,$60
db $00,$00,$00,$00,$3c,$3c,$4c,$4c,$4c,$4c,$3c,$3c,$0c,$0c,$0e,$0e
db $00,$00,$00,$00,$1c,$1c,$30,$30,$30,$30,$30,$30,$30,$30,$00,$00
db $00,$00,$00,$00,$38,$38,$60,$60,$38,$38,$0c,$0c,$78,$78,$00,$00
db $00,$00,$30,$30,$78,$78,$30,$30,$30,$30,$30,$30,$1c,$1c,$00,$00
db $00,$00,$00,$00,$64,$64,$64,$64,$64,$64,$64,$64,$3c,$3c,$00,$00
db $00,$00,$00,$00,$64,$64,$64,$64,$64,$64,$28,$28,$10,$10,$00,$00
db $00,$00,$00,$00,$62,$62,$6a,$6a,$6a,$6a,$6a,$6a,$34,$34,$00,$00
db $00,$00,$00,$00,$64,$64,$38,$38,$18,$18,$2c,$2c,$46,$46,$00,$00
db $00,$00,$00,$00,$4c,$4c,$4c,$4c,$4c,$4c,$3c,$3c,$0c,$0c,$38,$38
db $00,$00,$00,$00,$7e,$7e,$0c,$0c,$18,$18,$30,$30,$7e,$7e,$00,$00
db $3c,$3c,$60,$60,$30,$30,$60,$60,$60,$60,$30,$30,$60,$60,$3c,$3c
db $20,$20,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$10,$10
db $3c,$3c,$06,$06,$0c,$0c,$06,$06,$06,$06,$0c,$0c,$06,$06,$3c,$3c
db $00,$00,$00,$00,$31,$31,$7b,$7b,$de,$de,$8c,$8c,$00,$00,$00,$00
db $c0,$c0,$a0,$a0,$b8,$b8,$b0,$b0,$da,$da,$12,$12,$1a,$1a,$03,$03

Binary file not shown.