-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlz4dec.asm
177 lines (150 loc) · 2.61 KB
/
lz4dec.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;------------------------------------------------------------------------------
;hl=src de=dst
lz4decrunch:
IFDEF DATA_HAS_HEADERS
ld bc,7
add hl,bc
ld c,(hl)
inc hl
ld b,(hl) ;ヘッダから 2byte サイズを取得
inc hl
inc hl
inc hl ;+$0B から展開開始
ld a,l
add a,c
ld (.endL+1),a
ld a,h
adc a,b
ld (.endH+1),a ;圧縮データの終端アドレス
ENDIF
.loop:
ld a,(hl)
inc hl
ld (.litteral+1),a
and $F0
jr z,.copy ;長さ 0 なら既に転送済みのデータをコピー
rrca
rrca
rrca
rrca
ld b,0
ld c,a
cp $0F
call z,.getlength ;長さ $0F なら続けて追加の長さを取得する
ldir ;長さ情報の次から転送開始
.copy:
IFDEF DATA_HAS_HEADERS
ld a,l ;圧縮データが最終アドレスに達したかどうか
.endL:
sub $FF
ld a,h
.endH:
sbc a,$FF
ret nc ;実質 zf=1 チェック
ENDIF
ld c,(hl)
inc hl
ld b,(hl) ;bc=2byte オフセット値を読み込む
inc hl
IFNDEF DATA_HAS_HEADERS
ld a,b
or c
ret z
ENDIF
.litteral:
ld a,0 ;litteral ここは書き換え
and $0F
add a,$04 ;cf=0
push hl
ld h,d
ld l,e
sbc hl,bc ;hl=de-bc 既に展開したデータを転送元とする
ld b,0
ld c,a
cp $0F+$04
ex (sp),hl
call z,.getlength
ex (sp),hl
ldir ;既に展開したデータのコピー転送
pop hl
jp .loop
.getlength: ;転送バイト長を(さらに)取得する bc=現在の転送量
ld a,(hl)
inc hl
cp $FF ;$FF は長さ情報が続くサインを兼ねる
jr nz,.addlen
inc b
dec bc ;bc += 255
jr .getlength
.addlen:
add a,c
ld c,a
adc a,b
sub c
ld b,a ;bc=転送バイト長
ret
end
;------------------------------------------------------------------------------
;in: hl=開始アドレス bc=長さ
;out: bcde=結果
crc32:
push hl
push bc
ld de,$FFFF ;ZIP で使われる CRC32 では 0xFFFFFFFF を初期値とする
ld h,d
ld l,e
ld c,$20 ;短縮
exx
pop hl
dec hl
inc h
inc l
ld b,l
ld c,h
pop hl
.loop1:
ld a,(hl)
inc hl
exx
xor e
ld b,8
.loop2:
srl h
rr l
rr d
rra
jp nc,.skip
ld e,a
ld a,h
xor $ED
ld h,a
ld a,l
xor $B8
ld l,a
ld a,d
xor $83
ld d,a
ld a,e
; xor $20
xor c
.skip:
djnz .loop2
ld e,a
exx
djnz .loop1
dec c
jp nz,.loop1
exx
ld a,h ;ZIP で使われる CRC32 では最後に 0xFFFFFFFF で xor を取る
cpl
ld b,a
ld a,l
cpl
ld c,a
ld a,d
cpl
ld d,a
ld a,e
cpl
ld e,a
ret