summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_scroll_up.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2004-06-23 22:15:50 +0000
committerJens Arnold <amiconn@rockbox.org>2004-06-23 22:15:50 +0000
commit7c6bdd64935452464b21f99198896c34569105e5 (patch)
treebecd4aeb5498966aea5629f1e692ba5131192b5e /apps/plugins/lib/gray_scroll_up.c
parent8877ad943eb077d10a0725b47c55a8b2f55f319a (diff)
downloadrockbox-7c6bdd64935452464b21f99198896c34569105e5.zip
rockbox-7c6bdd64935452464b21f99198896c34569105e5.tar.gz
rockbox-7c6bdd64935452464b21f99198896c34569105e5.tar.bz2
rockbox-7c6bdd64935452464b21f99198896c34569105e5.tar.xz
Split grayscale library into several files to make up a real function library. Significantly decreases binary size for plugins using it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4802 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib/gray_scroll_up.c')
-rw-r--r--apps/plugins/lib/gray_scroll_up.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/apps/plugins/lib/gray_scroll_up.c b/apps/plugins/lib/gray_scroll_up.c
new file mode 100644
index 0000000..4a4657b
--- /dev/null
+++ b/apps/plugins/lib/gray_scroll_up.c
@@ -0,0 +1,135 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Grayscale framework
+* gray_scroll_up() function
+*
+* This is a generic framework to use grayscale display within Rockbox
+* plugins. It obviously does not work for the player.
+*
+* Copyright (C) 2004 Jens Arnold
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#ifndef SIMULATOR /* not for simulator by now */
+#include "plugin.h"
+
+#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
+#include "gray.h"
+
+/*---------------------------------------------------------------------------
+ Scroll the whole grayscale buffer up by <count> pixels (<= 7)
+ ----------------------------------------------------------------------------
+ black_border determines if the pixels scrolled in at the bottom are black
+ or white
+
+ Scrolling up/down pixel-wise is significantly slower than scrolling
+ left/right or scrolling up/down byte-wise because it involves bit
+ shifting. That's why it is asm optimized.
+ */
+void gray_scroll_up(int count, bool black_border)
+{
+ unsigned filler;
+
+ if ((unsigned) count > 7)
+ return;
+
+ filler = black_border ? 0xFFu : 0;
+
+ /* scroll column by column to minimize flicker */
+ asm volatile (
+ "mov #0,r6 \n" /* x = 0 */
+ "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
+ "mov.b @(r0,%6),%6 \n" /* shift amount from table */
+ "bra .su_cloop \n" /* skip table */
+ "add r0,%6 \n"
+
+ ".align 2 \n"
+ ".su_shifttbl: \n" /* shift jump offset table */
+ ".byte .su_shift0 - .su_shifttbl \n"
+ ".byte .su_shift1 - .su_shifttbl \n"
+ ".byte .su_shift2 - .su_shifttbl \n"
+ ".byte .su_shift3 - .su_shifttbl \n"
+ ".byte .su_shift4 - .su_shifttbl \n"
+ ".byte .su_shift5 - .su_shifttbl \n"
+ ".byte .su_shift6 - .su_shifttbl \n"
+ ".byte .su_shift7 - .su_shifttbl \n"
+
+ ".su_cloop: \n" /* repeat for every column */
+ "mov %1,r2 \n" /* get start address */
+ "mov #0,r3 \n" /* current_plane = 0 */
+
+ ".su_oloop: \n" /* repeat for every bitplane */
+ "mov r2,r4 \n" /* get start address */
+ "mov #0,r5 \n" /* current_row = 0 */
+ "mov %5,r1 \n" /* get filler bits */
+
+ ".su_iloop: \n" /* repeat for all rows */
+ "sub %2,r4 \n" /* address -= width */
+ "mov.b @r4,r0 \n" /* get data byte */
+ "shll8 r1 \n" /* old data to 2nd byte */
+ "extu.b r0,r0 \n" /* extend unsigned */
+ "or r1,r0 \n" /* combine old data */
+ "jmp @%6 \n" /* jump into shift "path" */
+ "extu.b r0,r1 \n" /* store data for next round */
+
+ ".su_shift6: \n" /* shift right by 0..7 bits */
+ "shlr2 r0 \n"
+ ".su_shift4: \n"
+ "shlr2 r0 \n"
+ ".su_shift2: \n"
+ "bra .su_shift0 \n"
+ "shlr2 r0 \n"
+ ".su_shift7: \n"
+ "shlr2 r0 \n"
+ ".su_shift5: \n"
+ "shlr2 r0 \n"
+ ".su_shift3: \n"
+ "shlr2 r0 \n"
+ ".su_shift1: \n"
+ "shlr r0 \n"
+ ".su_shift0: \n"
+
+ "mov.b r0,@r4 \n" /* store data */
+ "add #1,r5 \n" /* current_row++ */
+ "cmp/hi r5,%3 \n" /* current_row < bheight ? */
+ "bt .su_iloop \n"
+
+ "add %4,r2 \n" /* start_address += plane_size */
+ "add #1,r3 \n" /* current_plane++ */
+ "cmp/hi r3,%0 \n" /* current_plane < depth ? */
+ "bt .su_oloop \n"
+
+ "add #1,%1 \n" /* start_address++ */
+ "add #1,r6 \n" /* x++ */
+ "cmp/hi r6,%2 \n" /* x < width ? */
+ "bt .su_cloop \n"
+ : /* outputs */
+ : /* inputs */
+ /* %0 */ "r"(_graybuf->depth),
+ /* %1 */ "r"(_graybuf->data + _graybuf->plane_size),
+ /* %2 */ "r"(_graybuf->width),
+ /* %3 */ "r"(_graybuf->bheight),
+ /* %4 */ "r"(_graybuf->plane_size),
+ /* %5 */ "r"(filler),
+ /* %6 */ "r"(count)
+ : /* clobbers */
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6"
+ );
+}
+
+#endif // #ifdef HAVE_LCD_BITMAP
+#endif // #ifndef SIMULATOR
+