fuzev2: prevent button light flickering when accessing µSD
[kugel-rb.git] / firmware / decompressor / sh_nrv2e_d8.S
blob6a050834a95434f7eab4c4ceb980dbd81f912a30
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2008 by Jens Arnold
11  *
12  * based on  arm_nrv2e_d8.S -- ARM decompressor for NRV2E
13  * Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer
14  * Copyright (C) 1996-2008 Laszlo Molnar
15  * Copyright (C) 2000-2008 John F. Reiser
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23  * KIND, either express or implied.
24  *
25  ****************************************************************************/
27 #define src  r4
28 #define dst  r5
29 #define len  r6  /* overlaps 'cnt' */
30 #define cnt  r6  /* overlaps 'len' while reading an offset */
31 #define tmp  r7
33 #define off  r0  /* must be r0 because of indexed addressing */
34 #define bits r1
35 #define bitmask r2
36 #define wrnk r3  /* -0x500  -M2_MAX_OFFSET before "wrinkle" */
39 #define GETBIT             \
40     tst     bits, bitmask; \
41     bf      1f;            \
42     bsr     get1_n2e;      \
43 1:                         \
44     shll    bits  /* using the delay slot on purpose */
46 #define getnextb(reg) GETBIT; rotcl   reg
47 #define   jnextb0     GETBIT; bf
48 #define   jnextb1     GETBIT; bt
50     .section  .icode,"ax",@progbits
51     .align  2
52     .global _ucl_nrv2e_decompress_8
53     .type   _ucl_nrv2e_decompress_8,@function
55 /* src_len = ucl_nrv2e_decompress_8(const unsigned char *src,
56  *                                  unsigned char *dst,
57  *                                  unsigned long *dst_len)
58  */
60 _ucl_nrv2e_decompress_8:
61     sts.l   pr, @-r15
62     mov     #-1, off     ! off = -1 initial condition
63     mov.l   r6, @-r15
64     mov     #-5, wrnk
65     mov.l   r5, @-r15
66     shll8   wrnk         ! nrv2e -M2_MAX_OFFSET
67     mov.l   r4, @-r15
68     mov     #-1, bitmask
69     shlr    bitmask      ! 0x7fffffff for testing before shifting
70     bra     top_n2e
71     not     bitmask, bits ! refill next time (MSB must be set)
73 eof_n2e:
74     mov.l   @r15+, r0    ! r0 = orig_src
75     mov.l   @r15+, r1    ! r1 = orig_dst
76     sub     r0, src
77     mov.l   @r15+, r2    ! r2 = plen_dst
78     sub     r1, dst
79     mov.l   dst, @r2
80     lds.l   @r15+, pr
81     rts
82     mov     src, r0
84 lit_n2e:
85     mov.b   @src, tmp
86     add     #1, src     ! Need to fill the pipeline latency anyway
87     mov.b   tmp, @dst
88     add     #1, dst
89 top_n2e:
90     jnextb1 lit_n2e
91     bra     getoff_n2e
92     mov     #1, cnt
94 off_n2e:
95     add     #-1, cnt
96     getnextb(cnt)
97 getoff_n2e:
98     getnextb(cnt)
99     jnextb0 off_n2e
101     mov     #-4, tmp    ! T=1 on entry, so this does
102     addc    cnt, tmp    !   tmp = cnt - 3, T = (cnt >= 3)
103     mov     #0, len     ! cnt and len share a reg!
104     bf      offprev_n2e ! cnt was 2
105     mov.b   @src+, off  ! low 7+1 bits
106     shll8   tmp
107     extu.b  off, off
108     or      tmp, off
109     not     off, off    ! off = ~off
110     tst     off, off
111     bt      eof_n2e
112     shar    off
113     bt      lenlast_n2e
114     bf      lenmore_n2e ! always taken if the preceding bt isn't
116 offprev_n2e:
117     jnextb1 lenlast_n2e
118 lenmore_n2e:
119     mov     #1, len
120     jnextb1 lenlast_n2e
121 len_n2e:
122     getnextb(len)
123     jnextb0 len_n2e
124     bra     gotlen_n2e
125     mov     #6-2, tmp
127 get1_n2e:               ! in: T bit set
128     mov.b   @src+, bits ! SH1 sign-extends on load
129     rotcl   bits        ! LSB = T, T = MSB
130     shll16  bits
131     rts
132     shll8   bits
134 lenlast_n2e:
135     getnextb(len)       ! 0,1,2,3
136     mov     #2, tmp
137 gotlen_n2e:
138     cmp/gt  off, wrnk   ! too far away, so minimum match length is 3
139     addc    tmp, len
140 copy_n2e:
141     add     #-1, len
142     mov.b   @(off,dst), tmp
143     tst     len, len
144     mov.b   tmp, @dst
145     add     #1, dst
146     bf      copy_n2e
147     bt      top_n2e     ! always taken if the preceding bf isn't
149     .size ucl_nrv2e_decompress_8, .-ucl_nrv2e_decompress_8