From c521ed128d1afeea9bfad134358f6c3a7df9f2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Tue, 3 Sep 2002 09:44:08 +0000 Subject: [PATCH] Added Randy Wood's ROLO git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2149 a1c6a512-1295-4272-9138-f99709370657 --- apps/tree.c | 170 +++++++++++++++++++++++++++----------------- firmware/app.lds | 12 +++- firmware/crt0.S | 20 ++++++ firmware/gdb.lds | 12 +++- firmware/player.lds | 12 +++- firmware/rolo.c | 143 +++++++++++++++++++++++++++++++++++++ firmware/rolo.h | 24 +++++++ 7 files changed, 321 insertions(+), 72 deletions(-) create mode 100644 firmware/rolo.c create mode 100644 firmware/rolo.h diff --git a/apps/tree.c b/apps/tree.c index b0a30cdbcf..e5fb3c152d 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); + 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; - /* 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")) { + 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 2e594b6db1..49678d887e 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 99aab83867..0343fd1e23 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 badb7856fc..c214cb2e69 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 2e594b6db1..49678d887e 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 0000000000..ed9fcff931 --- /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 ) \___| < | \_\ ( <_> > < < + * 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