summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 b0a30cdbcf..e5fb3c152d 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -42,6 +42,7 @@
42#include "status.h" 42#include "status.h"
43#include "debug.h" 43#include "debug.h"
44#include "ata.h" 44#include "ata.h"
45#include "rolo.h"
45#include "icons.h" 46#include "icons.h"
46 47
47#ifdef HAVE_LCD_BITMAP 48#ifdef HAVE_LCD_BITMAP
@@ -57,7 +58,7 @@
57char name_buffer[NAME_BUFFER_SIZE]; 58char name_buffer[NAME_BUFFER_SIZE];
58int name_buffer_length; 59int name_buffer_length;
59struct entry { 60struct entry {
60 short attr; /* FAT attributes */ 61 short attr; /* FAT attributes + file type flags */
61 char *name; 62 char *name;
62}; 63};
63 64
@@ -126,8 +127,12 @@ extern unsigned char bitmap_icons_6x8[LastIcon][6];
126#define RELEASE_MASK (BUTTON_STOP) 127#define RELEASE_MASK (BUTTON_STOP)
127#endif /* HAVE_RECORDER_KEYPAD */ 128#endif /* HAVE_RECORDER_KEYPAD */
128 129
129#define TREE_ATTR_M3U 0x80 /* unused by FAT attributes */ 130/* using attribute not used by FAT */
130#define TREE_ATTR_MPA 0x40 /* unused by FAT attributes */ 131#define TREE_ATTR_MPA 0x40 /* mpeg audio file */
132#define TREE_ATTR_M3U 0x80 /* playlist */
133#define TREE_ATTR_WPS 0x100 /* wps config file */
134#define TREE_ATTR_MOD 0x200 /* firmware file */
135#define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */
131 136
132static int build_playlist(int start_index) 137static int build_playlist(int start_index)
133{ 138{
@@ -232,9 +237,16 @@ static int showdir(char *path, int start)
232 (!strcasecmp(&entry->d_name[len-4], ".mp2")) || 237 (!strcasecmp(&entry->d_name[len-4], ".mp2")) ||
233 (!strcasecmp(&entry->d_name[len-4], ".mpa"))) 238 (!strcasecmp(&entry->d_name[len-4], ".mpa")))
234 dptr->attr |= TREE_ATTR_MPA; 239 dptr->attr |= TREE_ATTR_MPA;
235 else 240 else if (!strcasecmp(&entry->d_name[len-4], ".m3u"))
236 if (!strcasecmp(&entry->d_name[len-4], ".m3u")) 241 dptr->attr |= TREE_ATTR_M3U;
237 dptr->attr |= TREE_ATTR_M3U; 242 else if (!strcasecmp(&entry->d_name[len-4], ".wps"))
243 dptr->attr |= TREE_ATTR_WPS;
244#ifdef HAVE_RECORDER_KEYPAD
245 else if (!strcasecmp(&entry->d_name[len-4], ".ajz"))
246#else
247 else if (!strcasecmp(&entry->d_name[len-4], ".mod"))
248#endif
249 dptr->attr |= TREE_ATTR_MOD;
238 } 250 }
239 251
240 /* filter non-mp3 or m3u files */ 252 /* filter non-mp3 or m3u files */
@@ -291,17 +303,30 @@ static int showdir(char *path, int start)
291 303
292 len = strlen(dircache[i].name); 304 len = strlen(dircache[i].name);
293 305
294 if ( dircache[i].attr & ATTR_DIRECTORY ) 306 switch ( dircache[i].attr & TREE_ATTR_MASK ) {
295 icon_type = Folder; 307 case ATTR_DIRECTORY:
296 else if ( dircache[i].attr & TREE_ATTR_M3U ) 308 icon_type = Folder;
297 icon_type = Playlist; 309 break;
298 else if ( dircache[i].attr & TREE_ATTR_MPA ) 310
299 icon_type = File; 311 case TREE_ATTR_M3U:
300 else if (!strcasecmp(&dircache[i].name[len-4], ".wps")) 312 icon_type = Playlist;
301 icon_type = Wps; 313 break;
302 else 314
303 icon_type = 0; 315 case TREE_ATTR_MPA:
316 icon_type = File;
317 break;
318
319 case TREE_ATTR_WPS:
320 icon_type = Wps;
321 break;
304 322
323 case TREE_ATTR_MOD:
324 icon_type = Mod_Ajz;
325 break;
326
327 default:
328 icon_type = 0;
329 }
305#ifdef HAVE_LCD_BITMAP 330#ifdef HAVE_LCD_BITMAP
306 if (icon_type) 331 if (icon_type)
307 lcd_bitmap(bitmap_icons_6x8[icon_type], 332 lcd_bitmap(bitmap_icons_6x8[icon_type],
@@ -450,7 +475,6 @@ bool dirbrowse(char *root)
450 int lasti=-1; 475 int lasti=-1;
451 int rc; 476 int rc;
452 int button; 477 int button;
453 int start_index;
454 int tree_max_on_screen; 478 int tree_max_on_screen;
455#ifdef LOADABLE_FONTS 479#ifdef LOADABLE_FONTS
456 int fh; 480 int fh;
@@ -543,68 +567,82 @@ bool dirbrowse(char *root)
543 start=0; 567 start=0;
544 } else { 568 } else {
545 int seed = current_tick; 569 int seed = current_tick;
570 bool play = false;
571 int start_index=0;
546 lcd_stop_scroll(); 572 lcd_stop_scroll();
547 if (file->attr & TREE_ATTR_M3U ) 573 switch ( file->attr & TREE_ATTR_MASK ) {
548 { 574 case TREE_ATTR_M3U:
549 if ( global_settings.resume ) 575 if ( global_settings.resume )
550 snprintf(global_settings.resume_file, 576 snprintf(global_settings.resume_file,
551 MAX_PATH, "%s/%s", 577 MAX_PATH, "%s/%s",
552 currdir, file->name); 578 currdir, file->name);
553 play_list(currdir, file->name, 0, false, 0, seed ); 579 play_list(currdir, file->name, 0, false, 0, seed );
554 start_index = 0; 580 start_index = 0;
555 } 581 play = true;
556 else if (file->attr & TREE_ATTR_MPA ) { 582 break;
557 if ( global_settings.resume ) 583
558 strncpy(global_settings.resume_file, 584 case TREE_ATTR_MPA:
559 currdir, MAX_PATH); 585 if ( global_settings.resume )
560 start_index = build_playlist(dircursor+start); 586 strncpy(global_settings.resume_file,
561 587 currdir, MAX_PATH);
562 /* it is important that we get back the index in 588 start_index = build_playlist(dircursor+start);
563 the (shuffled) list and stor that */ 589
564 start_index = play_list(currdir, NULL, 590 /* it is important that we get back the index in
565 start_index, false, 0, seed); 591 the (shuffled) list and stor that */
566 } 592 start_index = play_list(currdir, NULL,
567 else { 593 start_index, false,
568 /* wps config file? */ 594 0, seed);
569 int len = strlen(file->name); 595 play = true;
570 if (!strcasecmp(&file->name[len-4], ".wps")) { 596 break;
597
598 /* wps config file */
599 case TREE_ATTR_WPS:
571 snprintf(buf, sizeof buf, "%s/%s", 600 snprintf(buf, sizeof buf, "%s/%s",
572 currdir, file->name); 601 currdir, file->name);
573 wps_load_custom(buf); 602 wps_load_custom(buf);
574 restore = true; 603 restore = true;
575 break; 604 break;
576 } 605
577 else 606#ifndef SIMULATOR
607 /* firmware file */
608 case TREE_ATTR_MOD:
609 snprintf(buf, sizeof buf, "%s/%s",
610 currdir, file->name);
611 rolo_load(buf);
578 break; 612 break;
579 } 613#endif
580 if ( global_settings.resume ) {
581 /* the resume_index must always be the index in the
582 shuffled list in case shuffle is enabled */
583 global_settings.resume_index = start_index;
584 global_settings.resume_offset = 0;
585 global_settings.resume_seed = seed;
586 settings_save();
587 } 614 }
588 615
589 status_set_playmode(STATUS_PLAY); 616 if ( play ) {
590 status_draw(); 617 if ( global_settings.resume ) {
591 lcd_stop_scroll(); 618 /* the resume_index must always be the index in the
592 rc = wps_show(); 619 shuffled list in case shuffle is enabled */
593 if(rc == SYS_USB_CONNECTED) 620 global_settings.resume_index = start_index;
594 { 621 global_settings.resume_offset = 0;
595 /* Force a re-read of the root directory */ 622 global_settings.resume_seed = seed;
596 strcpy(currdir, "/"); 623 settings_save();
597 lastdir[0] = 0; 624 }
598 dirlevel = 0; 625
599 dircursor = 0; 626 status_set_playmode(STATUS_PLAY);
600 start = 0; 627 status_draw();
601 global_settings.resume_index = -1; 628 lcd_stop_scroll();
602 } 629 rc = wps_show();
630 if(rc == SYS_USB_CONNECTED)
631 {
632 /* Force a re-read of the root directory */
633 strcpy(currdir, "/");
634 lastdir[0] = 0;
635 dirlevel = 0;
636 dircursor = 0;
637 start = 0;
638 global_settings.resume_index = -1;
639 }
603#ifdef LOADABLE_FONTS 640#ifdef LOADABLE_FONTS
604 tree_max_on_screen = (LCD_HEIGHT - MARGIN_Y) / fh; 641 tree_max_on_screen = (LCD_HEIGHT - MARGIN_Y) / fh;
605#else 642#else
606 tree_max_on_screen = TREE_MAX_ON_SCREEN; 643 tree_max_on_screen = TREE_MAX_ON_SCREEN;
607#endif 644#endif
645 }
608 } 646 }
609 restore = true; 647 restore = true;
610 break; 648 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
39 _stackbegin = .; 39 _stackbegin = .;
40 /* We put the copy of the .iram section here to save space */ 40 /* We put the copy of the .iram section here to save space */
41 _iramcopy = .; 41 _iramcopy = .;
42 . = 0x2000; 42 . += 0x2000;
43 _topramcopy = .;
44 . += 0x300;
43 _stackend = .; 45 _stackend = .;
44 } > DRAM 46 } > DRAM
45 47
@@ -56,11 +58,17 @@ SECTIONS
56 _mp3buf = .; 58 _mp3buf = .;
57 } > DRAM 59 } > DRAM
58 60
59 .mp3end 0x09200000 : 61 .mp3end 0x09200000 - 0x300:
60 { 62 {
61 _mp3end = .; 63 _mp3end = .;
62 } > DRAM 64 } > DRAM
63 65
66 .topram : AT ( _topramcopy ) {
67 _topramstart = .;
68 *(.topcode)
69 _topramend = .;
70 } > DRAM
71
64 .iram 0xf000000 : AT ( _iramcopy ) 72 .iram 0xf000000 : AT ( _iramcopy )
65 { 73 {
66 _iramstart = .; 74 _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:
112 bf copy_l 112 bf copy_l
113 nop 113 nop
114 114
115 /* copy the .topram section */
116 mov.l topramcopy_k,r0
117 mov.l topram_k,r1
118 mov.l topramend_k,r2
119copy_l2:
120 mov.l @r0,r3
121 mov.l r3,@r1
122 add #4,r0
123 add #4,r1
124 cmp/ge r2,r1
125 bf copy_l2
126 nop
127
128
115 /* Munge the main thread stack */ 129 /* Munge the main thread stack */
116 mov.l stack_k,r2 130 mov.l stack_k,r2
117 mov.l deadbeef_k,r0 131 mov.l deadbeef_k,r0
@@ -150,6 +164,12 @@ iram_k:
150 .long _iramstart 164 .long _iramstart
151iramend_k: 165iramend_k:
152 .long _iramend 166 .long _iramend
167topramcopy_k:
168 .long _topramcopy
169topram_k:
170 .long _topramstart
171topramend_k:
172 .long _topramend
153main_k: 173main_k:
154 .long _main 174 .long _main
155vbr_k: 175vbr_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
39 _stackbegin = .; 39 _stackbegin = .;
40 /* We put the copy of the .iram section here to save space */ 40 /* We put the copy of the .iram section here to save space */
41 _iramcopy = .; 41 _iramcopy = .;
42 . = 0x2000; 42 . += 0x2000;
43 _topramcopy = .;
44 . += 0x300;
43 _stackend = .; 45 _stackend = .;
44 } > DRAM 46 } > DRAM
45 47
@@ -63,11 +65,17 @@ SECTIONS
63 _mp3buf = .; 65 _mp3buf = .;
64 } > DRAM 66 } > DRAM
65 67
66 .mp3end 0x09200000 : 68 .mp3end 0x09200000 - 0x300:
67 { 69 {
68 _mp3end = .; 70 _mp3end = .;
69 } > DRAM 71 } > DRAM
70 72
73 .topram : AT ( _topramcopy ) {
74 _topramstart = .;
75 *(.topcode)
76 _topramend = .;
77 } > DRAM
78
71 .iram 0xf000000 : AT ( _iramcopy ) 79 .iram 0xf000000 : AT ( _iramcopy )
72 { 80 {
73 _iramstart = .; 81 _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
39 _stackbegin = .; 39 _stackbegin = .;
40 /* We put the copy of the .iram section here to save space */ 40 /* We put the copy of the .iram section here to save space */
41 _iramcopy = .; 41 _iramcopy = .;
42 . = 0x2000; 42 . += 0x2000;
43 _topramcopy = .;
44 . += 0x300;
43 _stackend = .; 45 _stackend = .;
44 } > DRAM 46 } > DRAM
45 47
@@ -56,11 +58,17 @@ SECTIONS
56 _mp3buf = .; 58 _mp3buf = .;
57 } > DRAM 59 } > DRAM
58 60
59 .mp3end 0x09200000 : 61 .mp3end 0x09200000 - 0x300:
60 { 62 {
61 _mp3end = .; 63 _mp3end = .;
62 } > DRAM 64 } > DRAM
63 65
66 .topram : AT ( _topramcopy ) {
67 _topramstart = .;
68 *(.topcode)
69 _topramend = .;
70 } > DRAM
71
64 .iram 0xf000000 : AT ( _iramcopy ) 72 .iram 0xf000000 : AT ( _iramcopy )
65 { 73 {
66 _iramstart = .; 74 _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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Randy D. Wood
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "lcd.h"
21#include "kernel.h"
22#include "sprintf.h"
23#include "button.h"
24#include "file.h"
25#include "mpeg.h"
26#include "system.h"
27#include "i2c.h"
28#include "string.h"
29
30#define IRQ0_EDGE_TRIGGER 0x80
31
32static void rolo_error(char *text)
33{
34 lcd_clear_display();
35 lcd_puts(0, 0, "ROLO error:");
36 lcd_puts_scroll(0, 1, text);
37 lcd_update();
38 button_get(true);
39 lcd_stop_scroll();
40}
41/***************************************************************************
42 *
43 * Name: rolo_load_app(char *filename,int scrambled)
44 * Filename must be a fully defined filename including the path and extension
45 *
46 ***************************************************************************/
47int rolo_load(char* filename) __attribute__ ((section (".topcode")));
48int rolo_load(char* filename)
49{
50 int fd,slen;
51 unsigned long length,file_length,i;
52 extern unsigned char mp3buf[],mp3end;
53 unsigned short checksum,file_checksum;
54 unsigned char* ramstart = (void*)0x09000000;
55 void (*start_func)(void) = (void*)ramstart + 0x200;
56
57 lcd_clear_display();
58 lcd_puts(0, 0, "ROLO...");
59 lcd_puts(0, 1, "Loading");
60 lcd_update();
61
62 mpeg_stop();
63
64 fd = open(filename, O_RDONLY);
65 if(-1 == fd) {
66 rolo_error("File not found");
67 return -1;
68 }
69
70 /* Read file length from header and compare to real file length */
71 length=lseek(fd,0,SEEK_END)-6;
72 lseek(fd, 0, SEEK_SET);
73 if(read(fd, &file_length, 4) != 4) {
74 rolo_error("Error Reading File Length");
75 return -1;
76 }
77 if (length != file_length) {
78 rolo_error("File length mismatch");
79 return -1;
80 }
81
82 /* Read and save checksum */
83 lseek(fd, 4, SEEK_SET);
84 if (read(fd, &file_checksum, 2) != 2) {
85 rolo_error("Error Reading checksum");
86 return -1;
87 }
88 lseek(fd, 6, SEEK_SET);
89
90 /* verify that file can be read and descrambled */
91 if ((&mp3buf[0] + (2*length)+4) >= &mp3end) {
92 rolo_error("Not enough room to load file");
93 return -1;
94 }
95
96 if (read(fd, &mp3buf[length], length) != (int)length) {
97 rolo_error("Error Reading File");
98 return -1;
99 }
100
101 lcd_puts(0, 1, "Descrambling");
102 lcd_update();
103
104 /* descramble */
105 slen = length/4;
106 for (i = 0; i < length; i++) {
107 unsigned long addr = ((i % slen) << 2) + i/slen;
108 unsigned char data = mp3buf[i+length];
109 data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */
110 mp3buf[addr] = data;
111 }
112
113 /* Compute checksum and verify against checksum from file header */
114 checksum=0;
115 for (i=0; i<length; i++)
116 checksum += mp3buf[i];
117
118 if (checksum != file_checksum) {
119 rolo_error("Checksum Error");
120 return -1;
121 }
122
123 lcd_puts(0, 1, "Executing ");
124 lcd_update();
125
126 /* Disable interrupts */
127 asm("mov #15<<4,r6\n"
128 "ldc r6,sr");
129
130 /* Calling these 2 initialization routines was necessary to get the
131 the origional Archos version of the firmware to load and execute. */
132 system_init(); /* Initialize system for restart */
133 i2c_init(); /* Init i2c bus - it seems like a good idea */
134 ICR = IRQ0_EDGE_TRIGGER; /* Make IRQ0 edge triggered */
135
136 /* move firmware to start of ram */
137 for ( i=0; i < length/4+1; i++ )
138 ((unsigned int*)ramstart)[i] = ((unsigned int*)mp3buf)[i];
139
140 start_func(); /* start new firmware */
141
142 return 0; /* this is never reached */
143}
diff --git a/firmware/rolo.h b/firmware/rolo.h
new file mode 100644
index 0000000000..e2dd814c1a
--- /dev/null
+++ b/firmware/rolo.h
@@ -0,0 +1,24 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Randy D. Wood
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __ROLO_H__
20#define __ROLO_H__
21
22void rolo_load(char* file);
23
24#endif