Created
January 31, 2016 20:43
-
-
Save BlockoS/fb927b3cf744a2c74660 to your computer and use it in GitHub Desktop.
LZSS pcengine unpacker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;------------------------------------------------ | |
;; Compressed image loading (lzss) | |
;; (c) 2005,2006 Vincent "MooZ" Cruz | |
;; cruz.vincent@gmail.com | |
;;------------------------------------------------ | |
HUC = 1 | |
;;------------------------------------------------ | |
;; LZSS | |
BUFFER_SIZE .equ 4096 | |
BUFFER_SIZE_MASK .equ 4095 | |
MATCH_LENGTH .equ 18 | |
THRESHOLD .equ 2 | |
;;------------------------------------------------ | |
;; Compressed data size (user defined) | |
DATA_SIZE .equ 17086 | |
;;------------------------------------------------ | |
;; mkit/huc includes | |
.include "startup.asm" | |
.data | |
.bank DATA_BANK | |
.code | |
;;------------------------------------------------ | |
;; Compressed data/palette/bat | |
.data | |
.dw $0 | |
_data: | |
.incbin "love.lzss" | |
.code | |
.data | |
.dw $0 | |
_pal: | |
.incpal "love.pcx",0 | |
.code | |
.data | |
.dw $0 | |
_bat: | |
.incbat "love.pcx",4096,0,0,40,25 | |
;;------------------------------------------------ | |
.code | |
;;------------------------------------------------ | |
;; variables | |
;;------------------------------------------------ | |
.zp | |
;; lzss vars | |
c: .ds 1 | |
j: .ds 1 | |
k: .ds 1 | |
i: .ds 2 | |
size: .ds 2 | |
r: .ds 2 | |
flags: .ds 2 | |
data_ptr: .ds 2 | |
idx: .ds 1 | |
word: .ds 2 | |
;;------------------------------------------------ | |
;; main [begin] | |
;;------------------------------------------------ | |
.code | |
.proc _main | |
main: | |
__ldwi #4096 | |
call _gfx_init | |
__ldwi #1 | |
call _set_screen_size | |
; set horizontale resolution | |
__ldwi #320 | |
__stw _ax | |
call _set_xres.1 | |
; shutdown display | |
; load palette | |
set_bgpal #0, _pal, #16 | |
; load bat | |
batcpy #$0, _bat, #40, #25 | |
; load picture | |
lda #low(DATA_SIZE) | |
sta size | |
lda #high(DATA_SIZE) | |
sta size+1 | |
call load_picture | |
jsr _disp_on | |
; main loop | |
.mainloop: | |
vsync | |
bra .mainloop | |
rts ; a bit useless ;) | |
.endp | |
;;------------------------------------------------ | |
;; main [end] | |
;;------------------------------------------------ | |
;;------------------------------------------------ | |
;; load picture [begin] | |
;;------------------------------------------------ | |
.proc _load_picture | |
load_picture: | |
stz <_di | |
lda #$10 | |
sta <_di+1 | |
jsr set_write | |
; LZSS | |
; clear text_buffer array | |
stz <i | |
stz <i+1 | |
; initialize var | |
; flags = 0 | |
stz <flags | |
stz <flags+1 | |
; data_ptr = 0 | |
stz <data_ptr | |
stz <data_ptr+1 | |
; idx = 0 | |
stz <idx | |
; r = BUFFER_SIZE - MATCH_LENGTH | |
lda #low(4078) | |
sta <r | |
lda #high(4078) | |
sta <r+1 | |
; for(i=0; i<4078; ++i) | |
; text_buffer[i] = 0 | |
tai i, text_buffer, r | |
lzss: | |
; flags >>= 1 | |
lsr <flags+1 | |
ror <flags | |
; if((flags & 256) == 0) | |
bbs0 <flags+1, lzss_1 | |
lzss_0: | |
; if(data_ptr >= DATASIZE) break; | |
lzss_next .macro | |
lda <data_ptr+1 | |
cmp <size+1 | |
bcc lzss_b\@ | |
bne lzss_a\@ | |
lda <data_ptr | |
cmp <size | |
bcc lzss_b\@ | |
lzss_a\@: | |
jmp lzss_end | |
lzss_b\@: | |
.endm | |
lzss_next | |
; c = g_Data[g_DataPtr++] | |
lzss_getbyte .macro | |
__ldw <data_ptr | |
__farptr_i _data | |
__fgetb | |
stx \1 | |
incw <data_ptr | |
.endm | |
lzss_getbyte <c | |
; flags = 0xFF00 | c | |
lda <c | |
sta <flags | |
lda #$ff | |
sta <flags+1 | |
lzss_1: | |
; if(flags & 1) | |
bbs0 <flags, lzss_2 | |
jmp lzss_3 | |
lzss_2: | |
; if(data_ptr => DATASIZE) | |
lzss_next | |
; c = g_Data[g_DataPtr++] | |
lzss_getbyte <c | |
; write word | |
; if(!(idx & 1)) { | |
; ++idx; | |
; word = c; | |
; } | |
; else { | |
; video_data_l = word; | |
; video_data_h = word; | |
; idx = 0; | |
; } | |
lzss_write_word .macro | |
bbs0 <idx,lzss_write_\@ | |
inc <idx | |
lda <c | |
sta <word | |
jmp lzss_nowrite_\@ | |
lzss_write_\@: | |
stz <idx | |
lda <word | |
sta video_data_l | |
lda <c | |
sta video_data_h | |
lzss_nowrite_\@: | |
.endm | |
lzss_write_word | |
; text_buffer[r] = c; | |
__ldwi text_buffer | |
__addw <r | |
__stw <__ptr | |
lda <c | |
sta [__ptr] | |
; ++r; | |
incw <r | |
; r &= BUFFER_SIZE_MASK | |
lda <r+1 | |
and #HIGH(BUFFER_SIZE_MASK) | |
sta <r+1 | |
jmp lzss_4 | |
lzss_3: | |
; if(data_ptr => DATASIZE) | |
lzss_next | |
; i = g_Data[g_DataPtr++] | |
lzss_getbyte <i | |
; if(data_ptr => DATASIZE) | |
lzss_next | |
; j = g_Data[g_DataPtr++] | |
lzss_getbyte <j | |
; i |= (lzssj | 0xF0) << 4 | |
lda <j | |
lsr A | |
lsr A | |
lsr A | |
lsr A | |
sta <i+1 | |
; j = (j & 00F) + THRESHOLD | |
lda <j | |
and #15 | |
inc A | |
inc A | |
sta <j | |
; for(k=0; k<=j; ++k) | |
stz <k | |
lzss_3e: | |
; c = g_TextBuffer[(i + k) & BUFFER_SIZE_MASK]; | |
clx | |
lda <k | |
add <i | |
sax | |
adc <i+1 | |
and #high(4095) | |
sax | |
add #low(text_buffer) | |
sta <__ptr | |
sax | |
adc #high(text_buffer) | |
sta <__ptr+1 | |
lda [__ptr] | |
sta <c | |
; write word | |
lzss_write_word | |
; text_buffer[r] = c; | |
__ldwi text_buffer | |
__addw <r | |
__stw <__ptr | |
lda <c | |
sta [__ptr] | |
; ++r; | |
incw <r | |
; r &= BUFFER_SIZE_MASK | |
lda <r+1 | |
and #HIGH(BUFFER_SIZE_MASK) | |
sta <r+1 | |
inc <k | |
lda <j | |
cmp <k | |
bcc lzss_3g | |
jmp lzss_3e | |
lzss_3g: | |
lzss_4: | |
jmp lzss | |
lzss_end: | |
rts | |
.endp | |
;; load picture [end] | |
;;------------------------------------------------ | |
;;------------------------------------------------ | |
;; Ring buffer declaration | |
;;------------------------------------------------ | |
.bss | |
text_buffer: .ds 4113 ; BUFFER_SIZE + MATCH_LENGTH - 1 | |
__arg: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment