-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlz77.s
155 lines (132 loc) · 3.46 KB
/
lz77.s
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
.section .iwram,"ax", %progbits
.arm
.cpu arm7tdmi
.align 2
.global LZ77UnCompWrite8bit
.type LZ77UnCompWrite8bit STT_FUNC;
LZ77UnCompWrite8bit:
stmfd sp!, {r3 - r7}
@ Read header word:
@ bit0-3: reserved
@ bit4-7: compressed type (1 for LZ77)
@ bit8-31: size of compressed data
ldr r2, [r0], #4
lsrs r2, r2, #8
@ ignore zero-length decompression requests
beq .lz77_8bit_done
.lz77_8bit_loop:
@ read encoder byte, shift to MSB for easier access.
ldrb r3, [r0], #1
orr r3, #0x01000000
.lz77_8bit_encoder_loop:
tst r3, #0x80
bne .lz77_8bit_copy_window
.lz77_8bit_copy_byte:
@ copy byte from current source to current destination
ldrb r4, [r0], #1
strb r4, [r1], #1
@ check if decompressed length has been reached.
subs r2, #1
beq .lz77_8bit_done
@ read next encoder or process next block
lsls r3, #1
bcc .lz77_8bit_encoder_loop
b .lz77_8bit_loop
.lz77_8bit_copy_window:
@ read window tuple {displacement, size}
ldrb r4, [r0], #1
ldrb r5, [r0], #1
@ r5 = window displacement
orr r5, r5, r4, lsl #8
bic r5, #0xF000
add r5, #1
@ r4 = window size
lsr r4, #4
add r4, #3
.lz77_8bit_copy_window_loop:
@ copy byte from window to current destination
ldrb r6, [r1, -r5]
strb r6, [r1], #1
@ check if decompressed length has been reached
subs r2, #1
beq .lz77_8bit_done
@ check if window has been fully copied
subs r4, #1
bne .lz77_8bit_copy_window_loop
@ read next encoder or process next block
lsls r3, #1
bcc .lz77_8bit_encoder_loop
b .lz77_8bit_loop
.lz77_8bit_done:
ldmfd sp!, {r3 - r7}
bx lr
.section .iwram,"ax", %progbits
.arm
.cpu arm7tdmi
.align 2
.global LZ77UnCompWrite16bit
.type LZ77UnCompWrite16bit STT_FUNC;
LZ77UnCompWrite16bit:
stmfd sp!, {r3 - r7}
@ Read header word:
@ bit0-3: reserved
@ bit4-7: compressed type (1 for LZ77)
@ bit8-31: size of compressed data
ldr r2, [r0], #4
lsrs r2, r2, #8
@ ignore zero-length decompression requests
beq .lz77_16bit_done
.lz77_16bit_loop:
@ read encoder byte, shift to MSB for easier access.
ldrb r3, [r0], #1
orr r3, #0x01000000
.lz77_16bit_encoder_loop:
tst r3, #0x80
bne .lz77_16bit_copy_window
.lz77_16bit_copy_byte:
@ copy byte from current source to current destination
ldrb r4, [r0], #1
tst r1, #1
moveq r7, r4
orrne r7, r4, lsl #8
strneh r7, [r1]
add r1, #1
@ check if decompressed length has been reached.
subs r2, #1
beq .lz77_16bit_done
@ read next encoder or process next block
lsls r3, #1
bcc .lz77_16bit_encoder_loop
b .lz77_16bit_loop
.lz77_16bit_copy_window:
@ read window tuple {displacement, size}
ldrb r4, [r0], #1
ldrb r5, [r0], #1
@ r5 = window displacement
orr r5, r5, r4, lsl #8
bic r5, #0xF000
add r5, #1
@ r4 = window size
lsr r4, #4
add r4, #3
.lz77_16bit_copy_window_loop:
@ copy byte from window to current destination
ldrb r6, [r1, -r5]
tst r1, #1
moveq r7, r6
orrne r7, r6, lsl #8
strneh r7, [r1]
add r1, #1
@ check if decompressed length has been reached
subs r2, #1
beq .lz77_16bit_done
@ check if window has been fully copied
subs r4, #1
bne .lz77_16bit_copy_window_loop
@ read next encoder or process next block
lsls r3, #1
bcc .lz77_16bit_encoder_loop
b .lz77_16bit_loop
.lz77_16bit_done:
ldmfd sp!, {r3 - r7}
bx lr