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
|
@APlib ARM7 decompressor by Dan Weiss, based on the original C version
@Takes in raw apacked data, NOT data created by the 'safe' compressor.
@Code is from the PocketNES NES Emulator for GBA
@Code is formatted for GNU Assembler
src .req r0
dest .req r1
byte .req r2
mask .req r3
gamma .req r4
lwm .req r6
recentoff .req r7
temp .req r8
.global depack
.type depack STT_FUNC
@r0 = src
@r1 = dest
@r2 = byte
@r3 = rotating bit mask
@r4 = increasing gamma
@r6 = lwm
@r7 = recentoff
@r8 = lr copy/scratch
.macro GETBIT @3 instructions
movs mask,mask,ror #1
ldrcsb byte,[src],#1
tst byte,mask
.endm
.macro GETBITGAMMA @5 instructions
mov gamma,gamma,lsl #1
GETBIT
addne gamma,gamma,#1
.endm
@This initilaiztion code can go into slow memory
depack:
stmfd sp!,{r4-r10,lr}
ldrb temp,[src],#1
strb temp,[dest],#1
ldr mask,=0x01010101
b aploop_nolwm
@This inner-loop code should be placed into fast memory
@depack enters here
aploop_nolwm:
mov lwm,#0
aploop:
GETBIT
bne apbranch1
ldrb temp,[src],#1
strb temp,[dest],#1
b aploop_nolwm
apbranch1:
GETBIT
beq apbranch2
GETBIT
beq apbranch3
@get an offset
mov gamma,#0
GETBIT
addne gamma,gamma,#1
GETBITGAMMA
GETBITGAMMA
GETBITGAMMA
cmp gamma,#0
ldrneb gamma,[dest,-gamma]
strb gamma,[dest],#1
b aploop_nolwm
apbranch3:
@use 7 bit offset, length = 2 or 3
@if a zero is encountered here, it's EOF
ldrb gamma,[src],#1
movs recentoff,gamma,lsr #1
beq done
ldrcsb temp,[dest,-recentoff]
strcsb temp,[dest],#1
ldrb temp,[dest,-recentoff]
strb temp,[dest],#1
ldrb temp,[dest,-recentoff]
strb temp,[dest],#1
mov lwm,#1
b aploop
apbranch2:
@use a gamma code * 256 for offset, another gamma code for length
bl ap_getgamma
sub gamma,gamma,#2
cmp lwm,#0
bne ap_is_lwm
mov lwm,#1
cmp gamma,#0
bne ap_not_zero_gamma
@if gamma code is 2, use old recent offset, and a new gamma code for length
bl ap_getgamma
copyloop1:
ldrb temp,[dest,-recentoff]
strb temp,[dest],#1
subs gamma,gamma,#1
bne copyloop1
b aploop
ap_not_zero_gamma:
sub gamma,gamma,#1
ap_is_lwm:
ldrb temp,[src],#1
add recentoff,temp,gamma,lsl #8
bl ap_getgamma
@gamma=length
cmp recentoff,#32000
addge gamma,gamma,#1
cmp recentoff,#1280
addge gamma,gamma,#1
cmp recentoff,#128
addlt gamma,gamma,#2
copyloop2:
ldrb temp,[dest,-recentoff]
strb temp,[dest],#1
subs gamma,gamma,#1
bne copyloop2
b aploop
ap_getgamma:
mov gamma,#1
ap_getgammaloop:
GETBITGAMMA
GETBIT
bne ap_getgammaloop
bx lr
done:
ldmfd sp!,{r4-r10,lr}
bx lr
.unreq src
.unreq dest
.unreq byte
.unreq mask
.unreq gamma
.unreq lwm
.unreq recentoff
.unreq temp
|