summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-09-03 09:44:08 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-09-03 09:44:08 +0000
commitc521ed128d1afeea9bfad134358f6c3a7df9f2c0 (patch)
tree0ea712643dabad159946129606393858626f53cc
parent3d641c92a5886554b181cec78b8d83f870154d6d (diff)
downloadrockbox-c521ed128d1afeea9bfad134358f6c3a7df9f2c0.zip
rockbox-c521ed128d1afeea9bfad134358f6c3a7df9f2c0.tar.gz
rockbox-c521ed128d1afeea9bfad134358f6c3a7df9f2c0.tar.bz2
rockbox-c521ed128d1afeea9bfad134358f6c3a7df9f2c0.tar.xz
Added Randy Wood's ROLO
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2149 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/tree.c172
-rw-r--r--firmware/app.lds12
-rw-r--r--firmware/crt0.S20
-rw-r--r--firmware/gdb.lds12
-rw-r--r--firmware/player.lds12
-rw-r--r--firmware/rolo.c143
-rw-r--r--firmware/rolo.h24
7 files changed, 322 insertions, 73 deletions
diff --git a/apps/tree.c b/apps/tree.c
index b0a30cd..e5fb3c1 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -42,6 +42,7 @@
#include "status.h"
#include "debug.h"
#include "ata.h"
+#include "rolo.h"
#include "icons.h"
#ifdef HAVE_LCD_BITMAP
@@ -57,7 +58,7 @@
char name_buffer[NAME_BUFFER_SIZE];
int name_buffer_length;
struct entry {
- short attr; /* FAT attributes */
+ short attr; /* FAT attributes + file type flags */
char *name;
};
@@ -126,8 +127,12 @@ extern unsigned char bitmap_icons_6x8[LastIcon][6];
#define RELEASE_MASK (BUTTON_STOP)
#endif /* HAVE_RECORDER_KEYPAD */
-#define TREE_ATTR_M3U 0x80 /* unused by FAT attributes */
-#define TREE_ATTR_MPA 0x40 /* unused by FAT attributes */
+/* using attribute not used by FAT */
+#define TREE_ATTR_MPA 0x40 /* mpeg audio file */
+#define TREE_ATTR_M3U 0x80 /* playlist */
+#define TREE_ATTR_WPS 0x100 /* wps config file */
+#define TREE_ATTR_MOD 0x200 /* firmware file */
+#define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */
static int build_playlist(int start_index)
{
@@ -232,9 +237,16 @@ static int showdir(char *path, int start)
(!strcasecmp(&entry->d_name[len-4], ".mp2")) ||
(!strcasecmp(&entry->d_name[len-4], ".mpa")))
dptr->attr |= TREE_ATTR_MPA;
- else
- if (!strcasecmp(&entry->d_name[len-4], ".m3u"))
- dptr->attr |= TREE_ATTR_M3U;
+ else if (!strcasecmp(&entry->d_name[len-4], ".m3u"))
+ dptr->attr |= TREE_ATTR_M3U;
+ else if (!strcasecmp(&entry->d_name[len-4], ".wps"))
+ dptr->attr |= TREE_ATTR_WPS;
+#ifdef HAVE_RECORDER_KEYPAD
+ else if (!strcasecmp(&entry->d_name[len-4], ".ajz"))
+#else
+ else if (!strcasecmp(&entry->d_name[len-4], ".mod"))
+#endif
+ dptr->attr |= TREE_ATTR_MOD;
}
/* filter non-mp3 or m3u files */
@@ -291,17 +303,30 @@ static int showdir(char *path, int start)
len = strlen(dircache[i].name);
- if ( dircache[i].attr & ATTR_DIRECTORY )
- icon_type = Folder;
- else if ( dircache[i].attr & TREE_ATTR_M3U )
- icon_type = Playlist;
- else if ( dircache[i].attr & TREE_ATTR_MPA )
- icon_type = File;
- else if (!strcasecmp(&dircache[i].name[len-4], ".wps"))
- icon_type = Wps;
- else
- icon_type = 0;
+ switch ( dircache[i].attr & TREE_ATTR_MASK ) {
+ case ATTR_DIRECTORY:
+ icon_type = Folder;
+ break;
+
+ case TREE_ATTR_M3U:
+ icon_type = Playlist;
+ break;
+
+ case TREE_ATTR_MPA:
+ icon_type = File;
+ break;
+
+ case TREE_ATTR_WPS:
+ icon_type = Wps;
+ break;
+ case TREE_ATTR_MOD:
+ icon_type = Mod_Ajz;
+ break;
+
+ default:
+ icon_type = 0;
+ }
#ifdef HAVE_LCD_BITMAP
if (icon_type)
lcd_bitmap(bitmap_icons_6x8[icon_type],
@@ -450,7 +475,6 @@ bool dirbrowse(char *root)
int lasti=-1;
int rc;
int button;
- int start_index;
int tree_max_on_screen;
#ifdef LOADABLE_FONTS
int fh;
@@ -543,68 +567,82 @@ bool dirbrowse(char *root)
start=0;
} else {
int seed = current_tick;
+ bool play = false;
+ int start_index=0;
lcd_stop_scroll();
- if (file->attr & TREE_ATTR_M3U )
- {
- if ( global_settings.resume )
- snprintf(global_settings.resume_file,
- MAX_PATH, "%s/%s",
- currdir, file->name);
- play_list(currdir, file->name, 0, false, 0, seed );
- start_index = 0;
- }
- else if (file->attr & TREE_ATTR_MPA ) {
- if ( global_settings.resume )
- strncpy(global_settings.resume_file,
- currdir, MAX_PATH);
- start_index = build_playlist(dircursor+start);
-
- /* it is important that we get back the index in
- the (shuffled) list and stor that */
- start_index = play_list(currdir, NULL,
- start_index, false, 0, seed);
- }
- else {
- /* wps config file? */
- int len = strlen(file->name);
- if (!strcasecmp(&file->name[len-4], ".wps")) {
+ switch ( file->attr & TREE_ATTR_MASK ) {
+ case TREE_ATTR_M3U:
+ if ( global_settings.resume )
+ snprintf(global_settings.resume_file,
+ MAX_PATH, "%s/%s",
+ currdir, file->name);
+ play_list(currdir, file->name, 0, false, 0, seed );
+ start_index = 0;
+ play = true;
+ break;
+
+ case TREE_ATTR_MPA:
+ if ( global_settings.resume )
+ strncpy(global_settings.resume_file,
+ currdir, MAX_PATH);
+ start_index = build_playlist(dircursor+start);
+
+ /* it is important that we get back the index in
+ the (shuffled) list and stor that */
+ start_index = play_list(currdir, NULL,
+ start_index, false,
+ 0, seed);
+ play = true;
+ break;
+
+ /* wps config file */
+ case TREE_ATTR_WPS:
snprintf(buf, sizeof buf, "%s/%s",
currdir, file->name);
wps_load_custom(buf);
restore = true;
break;
- }
- else
+
+#ifndef SIMULATOR
+ /* firmware file */
+ case TREE_ATTR_MOD:
+ snprintf(buf, sizeof buf, "%s/%s",
+ currdir, file->name);
+ rolo_load(buf);
break;
- }
- if ( global_settings.resume ) {
- /* the resume_index must always be the index in the
- shuffled list in case shuffle is enabled */
- global_settings.resume_index = start_index;
- global_settings.resume_offset = 0;
- global_settings.resume_seed = seed;
- settings_save();
+#endif
}
- status_set_playmode(STATUS_PLAY);
- status_draw();
- lcd_stop_scroll();
- rc = wps_show();
- if(rc == SYS_USB_CONNECTED)
- {
- /* Force a re-read of the root directory */
- strcpy(currdir, "/");
- lastdir[0] = 0;
- dirlevel = 0;
- dircursor = 0;
- start = 0;
- global_settings.resume_index = -1;
- }
+ if ( play ) {
+ if ( global_settings.resume ) {
+ /* the resume_index must always be the index in the
+ shuffled list in case shuffle is enabled */
+ global_settings.resume_index = start_index;
+ global_settings.resume_offset = 0;
+ global_settings.resume_seed = seed;
+ settings_save();
+ }
+
+ status_set_playmode(STATUS_PLAY);
+ status_draw();
+ lcd_stop_scroll();
+ rc = wps_show();
+ if(rc == SYS_USB_CONNECTED)
+ {
+ /* Force a re-read of the root directory */
+ strcpy(currdir, "/");
+ lastdir[0] = 0;
+ dirlevel = 0;
+ dircursor = 0;
+ start = 0;
+ global_settings.resume_index = -1;
+ }
#ifdef LOADABLE_FONTS
- tree_max_on_screen = (LCD_HEIGHT - MARGIN_Y) / fh;
+ tree_max_on_screen = (LCD_HEIGHT - MARGIN_Y) / fh;
#else
- tree_max_on_screen = TREE_MAX_ON_SCREEN;
+ tree_max_on_screen = TREE_MAX_ON_SCREEN;
#endif
+ }
}
restore = true;
break;
diff --git a/firmware/app.lds b/firmware/app.lds
index 2e594b6..49678d8 100644
--- a/firmware/app.lds
+++ b/firmware/app.lds
@@ -39,7 +39,9 @@ SECTIONS
_stackbegin = .;
/* We put the copy of the .iram section here to save space */
_iramcopy = .;
- . = 0x2000;
+ . += 0x2000;
+ _topramcopy = .;
+ . += 0x300;
_stackend = .;
} > DRAM
@@ -56,11 +58,17 @@ SECTIONS
_mp3buf = .;
} > DRAM
- .mp3end 0x09200000 :
+ .mp3end 0x09200000 - 0x300:
{
_mp3end = .;
} > DRAM
+ .topram : AT ( _topramcopy ) {
+ _topramstart = .;
+ *(.topcode)
+ _topramend = .;
+ } > DRAM
+
.iram 0xf000000 : AT ( _iramcopy )
{
_iramstart = .;
diff --git a/firmware/crt0.S b/firmware/crt0.S
index 99aab83..0343fd1 100644
--- a/firmware/crt0.S
+++ b/firmware/crt0.S
@@ -112,6 +112,20 @@ copy_l:
bf copy_l
nop
+ /* copy the .topram section */
+ mov.l topramcopy_k,r0
+ mov.l topram_k,r1
+ mov.l topramend_k,r2
+copy_l2:
+ mov.l @r0,r3
+ mov.l r3,@r1
+ add #4,r0
+ add #4,r1
+ cmp/ge r2,r1
+ bf copy_l2
+ nop
+
+
/* Munge the main thread stack */
mov.l stack_k,r2
mov.l deadbeef_k,r0
@@ -150,6 +164,12 @@ iram_k:
.long _iramstart
iramend_k:
.long _iramend
+topramcopy_k:
+ .long _topramcopy
+topram_k:
+ .long _topramstart
+topramend_k:
+ .long _topramend
main_k:
.long _main
vbr_k:
diff --git a/firmware/gdb.lds b/firmware/gdb.lds
index badb785..c214cb2 100644
--- a/firmware/gdb.lds
+++ b/firmware/gdb.lds
@@ -39,7 +39,9 @@ SECTIONS
_stackbegin = .;
/* We put the copy of the .iram section here to save space */
_iramcopy = .;
- . = 0x2000;
+ . += 0x2000;
+ _topramcopy = .;
+ . += 0x300;
_stackend = .;
} > DRAM
@@ -63,11 +65,17 @@ SECTIONS
_mp3buf = .;
} > DRAM
- .mp3end 0x09200000 :
+ .mp3end 0x09200000 - 0x300:
{
_mp3end = .;
} > DRAM
+ .topram : AT ( _topramcopy ) {
+ _topramstart = .;
+ *(.topcode)
+ _topramend = .;
+ } > DRAM
+
.iram 0xf000000 : AT ( _iramcopy )
{
_iramstart = .;
diff --git a/firmware/player.lds b/firmware/player.lds
index 2e594b6..49678d8 100644
--- a/firmware/player.lds
+++ b/firmware/player.lds
@@ -39,7 +39,9 @@ SECTIONS
_stackbegin = .;
/* We put the copy of the .iram section here to save space */
_iramcopy = .;
- . = 0x2000;
+ . += 0x2000;
+ _topramcopy = .;
+ . += 0x300;
_stackend = .;
} > DRAM
@@ -56,11 +58,17 @@ SECTIONS
_mp3buf = .;
} > DRAM
- .mp3end 0x09200000 :
+ .mp3end 0x09200000 - 0x300:
{
_mp3end = .;
} > DRAM
+ .topram : AT ( _topramcopy ) {
+ _topramstart = .;
+ *(.topcode)
+ _topramend = .;
+ } > DRAM
+
.iram 0xf000000 : AT ( _iramcopy )
{
_iramstart = .;
diff --git a/firmware/rolo.c b/firmware/rolo.c
new file mode 100644
index 0000000..ed9fcff
--- /dev/null
+++ b/firmware/rolo.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Randy D. Wood
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "lcd.h"
+#include "kernel.h"
+#include "sprintf.h"
+#include "button.h"
+#include "file.h"
+#include "mpeg.h"
+#include "system.h"
+#include "i2c.h"
+#include "string.h"
+
+#define IRQ0_EDGE_TRIGGER 0x80
+
+static void rolo_error(char *text)
+{
+ lcd_clear_display();
+ lcd_puts(0, 0, "ROLO error:");
+ lcd_puts_scroll(0, 1, text);
+ lcd_update();
+ button_get(true);
+ lcd_stop_scroll();
+}
+/***************************************************************************
+ *
+ * Name: rolo_load_app(char *filename,int scrambled)
+ * Filename must be a fully defined filename including the path and extension
+ *
+ ***************************************************************************/
+int rolo_load(char* filename) __attribute__ ((section (".topcode")));
+int rolo_load(char* filename)
+{
+ int fd,slen;
+ unsigned long length,file_length,i;
+ extern unsigned char mp3buf[],mp3end;
+ unsigned short checksum,file_checksum;
+ unsigned char* ramstart = (void*)0x09000000;
+ void (*start_func)(void) = (void*)ramstart + 0x200;
+
+ lcd_clear_display();
+ lcd_puts(0, 0, "ROLO...");
+ lcd_puts(0, 1, "Loading");
+ lcd_update();
+
+ mpeg_stop();
+
+ fd = open(filename, O_RDONLY);
+ if(-1 == fd) {
+ rolo_error("File not found");
+ return -1;
+ }
+
+ /* Read file length from header and compare to real file length */
+ length=lseek(fd,0,SEEK_END)-6;
+ lseek(fd, 0, SEEK_SET);
+ if(read(fd, &file_length, 4) != 4) {
+ rolo_error("Error Reading File Length");
+ return -1;
+ }
+ if (length != file_length) {
+ rolo_error("File length mismatch");
+ return -1;
+ }
+
+ /* Read and save checksum */
+ lseek(fd, 4, SEEK_SET);
+ if (read(fd, &file_checksum, 2) != 2) {
+ rolo_error("Error Reading checksum");
+ return -1;
+ }
+ lseek(fd, 6, SEEK_SET);
+
+ /* verify that file can be read and descrambled */
+ if ((&mp3buf[0] + (2*length)+4) >= &mp3end) {
+ rolo_error("Not enough room to load file");
+ return -1;
+ }
+
+ if (read(fd, &mp3buf[length], length) != (int)length) {
+ rolo_error("Error Reading File");
+ return -1;
+ }
+
+ lcd_puts(0, 1, "Descrambling");
+ lcd_update();
+
+ /* descramble */
+ slen = length/4;
+ for (i = 0; i < length; i++) {
+ unsigned long addr = ((i % slen) << 2) + i/slen;
+ unsigned char data = mp3buf[i+length];
+ data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */
+ mp3buf[addr] = data;
+ }
+
+ /* Compute checksum and verify against checksum from file header */
+ checksum=0;
+ for (i=0; i<length; i++)
+ checksum += mp3buf[i];
+
+ if (checksum != file_checksum) {
+ rolo_error("Checksum Error");
+ return -1;
+ }
+
+ lcd_puts(0, 1, "Executing ");
+ lcd_update();
+
+ /* Disable interrupts */
+ asm("mov #15<<4,r6\n"
+ "ldc r6,sr");
+
+ /* Calling these 2 initialization routines was necessary to get the
+ the origional Archos version of the firmware to load and execute. */
+ system_init(); /* Initialize system for restart */
+ i2c_init(); /* Init i2c bus - it seems like a good idea */
+ ICR = IRQ0_EDGE_TRIGGER; /* Make IRQ0 edge triggered */
+
+ /* move firmware to start of ram */
+ for ( i=0; i < length/4+1; i++ )
+ ((unsigned int*)ramstart)[i] = ((unsigned int*)mp3buf)[i];
+
+ start_func(); /* start new firmware */
+
+ return 0; /* this is never reached */
+}
diff --git a/firmware/rolo.h b/firmware/rolo.h
new file mode 100644
index 0000000..e2dd814
--- /dev/null
+++ b/firmware/rolo.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Randy D. Wood
+ *
+ * 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 __ROLO_H__
+#define __ROLO_H__
+
+void rolo_load(char* file);
+
+#endif