Index: bootloader/e200.c
===================================================================
RCS file: /cvsroot/rockbox/bootloader/e200.c,v
retrieving revision 1.5
diff -u -r1.5 e200.c
--- bootloader/e200.c	16 Oct 2006 17:21:30 -0000	1.5
+++ bootloader/e200.c	5 Dec 2006 01:27:21 -0000
@@ -5,9 +5,12 @@
  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
- * $Id: e200.c,v 1.5 2006-10-16 17:21:30 dan_a Exp $
+ * $Id: h10.c,v 1.4 2006-08-28 08:11:32 barrywardell Exp $
  *
- * Copyright (C) 2006 Daniel Stenberg
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
+ * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
  *
  * 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.
@@ -32,63 +35,202 @@
 #include "font.h"
 #include "adc.h"
 #include "backlight.h"
+#include "button.h"
 #include "panic.h"
 #include "power.h"
 #include "file.h"
 
-static inline void blink(void)
+/* Size of the buffer to store the loaded Rockbox/Sansa image */
+#define MAX_LOADSIZE (10*1024*1024)
+
+/* A buffer to load the iriver firmware or Rockbox into */
+unsigned char loadbuffer[MAX_LOADSIZE];
+
+char version[] = APPSVERSION;
+
+#define DRAM_START              0x10000000
+
+int line=0;
+
+/* Load original Sandisk firmware. This function expects a file called
+   "/.rockbox/OF.bin" on the player. It should be decrypted
+   and have the header stripped using mi4code. It reads the file in to a memory
+   buffer called buf. The rest of the loading is done in main() and crt0.S
+*/
+int load_sandisk(unsigned char* buf)
 {
-    volatile unsigned int* ptr;
+    int fd;
+    int rc;
+    int len;
+
+    fd = open("/.rockbox/OF.bin", O_RDONLY);
+
+    len = filesize(fd);
+
+    if (len > MAX_LOADSIZE)
+        return -6;
+
+    rc = read(fd, buf, len);
+    if(rc < len)
+        return -4;
+
+    close(fd);
+    return len;
+}
+
+/* Load Rockbox firmware (rockbox.e200) */
+int load_rockbox(unsigned char* buf)
+{
+    int fd;
+    int rc;
+    int len;
+    unsigned long chksum;
+    char model[5];
+    unsigned long sum;
     int i;
-    ptr = (volatile unsigned int*)0x70000020;
+    char str[80];
 
-    *ptr &= ~(1 << 13);
-    for(i = 0; i < 0xfffff; i++)
+    fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
+    if(fd < 0)
     {
+        fd = open("/" BOOTFILE, O_RDONLY);
+        if(fd < 0)
+            return -1;
     }
-    *ptr |= (1 << 13);
-    for(i = 0; i < 0xfffff; i++)
-    {
+
+    len = filesize(fd) - 8;
+
+    snprintf(str, sizeof(str), "Length: %x", len);
+    lcd_puts(0, line++ ,str);
+    lcd_update();
+
+    if (len > MAX_LOADSIZE)
+        return -6;
+
+    lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
+
+    rc = read(fd, &chksum, 4);
+    chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
+    if(rc < 4)
+        return -2;
+
+    snprintf(str, sizeof(str), "Checksum: %x", chksum);
+    lcd_puts(0, line++ ,str);
+    lcd_update();
+
+    rc = read(fd, model, 4);
+    if(rc < 4)
+        return -3;
+
+    model[4] = 0;
+
+    snprintf(str, sizeof(str), "Model name: %s", model);
+    lcd_puts(0, line++ ,str);
+    lcd_update();
+
+    lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
+
+    rc = read(fd, buf, len);
+    if(rc < len)
+        return -4;
+
+    close(fd);
+
+    sum = MODEL_NUMBER;
+
+    for(i = 0;i < len;i++) {
+        sum += buf[i];
     }
+
+    snprintf(str, sizeof(str), "Sum: %x", sum);
+    lcd_puts(0, line++ ,str);
+    lcd_update();
+
+    if(sum != chksum)
+        return -5;
+
+    return len;
 }
 
-static inline void slow_blink(void)
+void* main(void)
 {
-    volatile unsigned int* ptr;
+    char buf[256];
     int i;
-    ptr = (volatile unsigned int*)0x70000020;
+    int rc;
+    unsigned short* identify_info;
+    struct partinfo* pinfo;
 
-    *ptr &= ~(1 << 13);
-    for(i = 0; i < (0xfffff); i++)
-    {
-    }
-    for(i = 0; i < (0xfffff); i++)
-    {
-    }
-    for(i = 0; i < (0xfffff); i++)
-    {
-    }
+    system_init();
+    kernel_init();
+    lcd_init();
+    font_init();
 
-    *ptr |= (1 << 13);
-    for(i = 0; i < (0xfffff); i++)
+    line=0;
+
+    lcd_setfont(FONT_SYSFIXED);
+
+    lcd_puts(0, line++, "Rockbox boot loader");
+    snprintf(buf, sizeof(buf), "Version: 20%s", version);
+    lcd_puts(0, line++, buf);
+    snprintf(buf, sizeof(buf), "Sandisk Sansa E200");
+    lcd_puts(0, line++, buf);
+    lcd_update();
+
+    i=ata_init();
+    if (i==0) {
+      identify_info=ata_get_identify();
+      /* Show model */
+      for (i=0; i < 20; i++) {
+        ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
+      }
+      buf[40]=0;
+      for (i=39; i && buf[i]==' '; i--) {
+        buf[i]=0;
+      }
+      lcd_puts(0, line++, buf);
+      lcd_update();
+    } else {
+      snprintf(buf, sizeof(buf), "ATA: %d", i);
+      lcd_puts(0, line++, buf);
+      lcd_update();
+    }
+
+    disk_init();
+    rc = disk_mount_all();
+    if (rc<=0)
     {
+        lcd_puts(0, line++, "No partition found");
+        lcd_update();
     }
-    for(i = 0; i < (0xfffff); i++)
+
+    pinfo = disk_partinfo(0);
+    snprintf(buf, sizeof(buf), "Partition 0: 0x%02x %ld MB",
+                  pinfo->type, pinfo->size / 2048);
+    lcd_puts(0, line++, buf);
+    lcd_update();
+
+    i=button_read_device();
+    if(i==BUTTON_LEFT)
     {
+        lcd_puts(0, line, "Loading Sandisk firmware...");
+        lcd_update();
+        rc=load_sandisk(loadbuffer);
+        /* Sandisk firmware doesn't like having the cache enabled */
+    } else {
+        lcd_puts(0, line, "Loading Rockbox...");
+        lcd_update();
+        rc=load_rockbox(loadbuffer);
     }
-    for(i = 0; i < (0xfffff); i++)
-    {
+
+    if (rc < 0) {
+            snprintf(buf, sizeof(buf), "Rockbox error: %d",rc);
+            lcd_puts(0, line++, buf);
+            lcd_update();
+            while(1) {}
     }
-}
 
-static inline unsigned long get_pc(void)
-{
-    unsigned long pc;
-    asm volatile (
-        "mov %0, pc\n"
-        : "=r"(pc)
-    );
-    return pc;
+    memcpy((void*)DRAM_START,loadbuffer,rc);
+    return (void*)DRAM_START;
 }
 
 /* These functions are present in the firmware library, but we reimplement
@@ -100,62 +242,7 @@
 
 int dbg_ports(void)
 {
-    unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
-    unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
-    unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
-
-    char buf[128];
-    int line;
-
-    lcd_setmargins(0, 0);
-    lcd_clear_display();
-    lcd_setfont(FONT_SYSFIXED);
-
-    while(1)
-    {
-        gpio_a = GPIOA_INPUT_VAL;
-        gpio_b = GPIOB_INPUT_VAL;
-        gpio_c = GPIOC_INPUT_VAL;
-
-        gpio_g = GPIOG_INPUT_VAL;
-        gpio_h = GPIOH_INPUT_VAL;
-        gpio_i = GPIOI_INPUT_VAL;
-
-        line = 0;
-        snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
-        lcd_puts(0, line++, buf);
-        line++;
-
-        gpio_d = GPIOD_INPUT_VAL;
-        gpio_e = GPIOE_INPUT_VAL;
-        gpio_f = GPIOF_INPUT_VAL;
-
-        gpio_j = GPIOJ_INPUT_VAL;
-        gpio_k = GPIOK_INPUT_VAL;
-        gpio_l = GPIOL_INPUT_VAL;
-
-        snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
-        lcd_puts(0, line++, buf);
-        line++;
-        snprintf(buf, sizeof(buf), "ADC_1: %02x", adc_read(ADC_0));
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "ADC_2: %02x", adc_read(ADC_1));
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "ADC_3: %02x", adc_read(ADC_2));
-        lcd_puts(0, line++, buf);
-        snprintf(buf, sizeof(buf), "ADC_4: %02x", adc_read(ADC_3));
-        lcd_puts(0, line++, buf);
-        lcd_update();
-    }
-    return 0;
+   return 0;
 }
 
 void mpeg_stop(void)
@@ -173,18 +260,3 @@
 void sys_poweroff(void)
 {
 }
-
-void system_reboot(void)
-{
-
-}
-
-void main(void)
-{
-    kernel_init();
-    adc_init();
-    lcd_init_device();
-
-    dbg_ports();
-}
-
Index: firmware/export/config-e200.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/config-e200.h,v
retrieving revision 1.4
diff -u -r1.4 config-e200.h
--- firmware/export/config-e200.h	22 Nov 2006 00:49:15 -0000	1.4
+++ firmware/export/config-e200.h	5 Dec 2006 01:27:24 -0000
@@ -4,7 +4,7 @@
 #define TARGET_TREE /* this target is using the target tree system */
 
 /* For Rolo and boot loader */
-#define MODEL_NUMBER 12
+#define MODEL_NUMBER 16
 
 /* define this if you have recording possibility */
 /*#define HAVE_RECORDING 1*/ /* TODO: add support for this */
Index: firmware/target/arm/crt0-pp.S
===================================================================
RCS file: /cvsroot/rockbox/firmware/target/arm/crt0-pp.S,v
retrieving revision 1.2
diff -u -r1.2 crt0-pp.S
--- firmware/target/arm/crt0-pp.S	22 Nov 2006 00:49:16 -0000	1.2
+++ firmware/target/arm/crt0-pp.S	5 Dec 2006 01:27:24 -0000
@@ -5,7 +5,7 @@
  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
- * $Id: crt0-pp.S,v 1.2 2006-11-22 00:49:16 dan_a Exp $
+ * $Id: crt0-pp.S,v 1.2 2006/11/22 00:49:16 dan_a Exp $
  *
  * Copyright (C) 2002 by Linus Nielsen Feltzing
  *
@@ -52,17 +52,36 @@
 
     msr    cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
 
-#ifndef BOOTLOADER
     b      pad_skip
 
-#if defined(SANSA_E200)
-/* mi4tool writes junk between 0xe0 and 0xeb.  Avoid this. */
-.space 60*4 /* (more than enough) space for exception vectors */
-#else
-.space 50*4
-#endif
+.space 60*4 /* For bootloader builds on targets with mi4 firmware, scramble
+               writes data to 0xe0-0xeb, so jump past that. For normal builds
+               this provides more than enough space for exception vectors */
 
 pad_skip:
+
+#ifdef BOOTLOADER
+/* 1 - Copy the bootloader to IRAM */
+    /* get the high part of our execute address */
+    and    r4, pc, #0xff000000
+
+    /* Copy bootloader to safe area - 0x40000000 */
+    mov    r5, #0x40000000
+    ldr    r6, = _dataend
+    sub    r0, r6, r5       /* length of loader */
+    add    r8, r4, r0       /* r8 points to start of loader */
+1:
+    cmp    r5, r6
+    ldrcc  r2, [r4], #4
+    strcc  r2, [r5], #4
+    bcc    1b
+
+/* 2 - Jump both CPU and COP there */
+    ldr    pc, =start_loc    /* jump to the relocated start_loc:  */
+
+start_loc:
+
+#else /* BOOTLOADER */
 #ifdef SANSA_E200
     /* On the Sansa, copying the vectors fails if the cache is initialised */
     ldr    r1, =CACHE_CTRL
@@ -106,24 +125,63 @@
 L_post_remap: .word remap_end
 remap_end:
 
-    /* After doing the remapping, send the COP to sleep.
-       On wakeup it will go to cop_init */
+#endif
+
+    /* Send the COP to sleep. On wakeup it will go to cop_init */
     ldr    r0, =PROC_ID
     ldr    r0, [r0]
     and    r0, r0, #0xff
     cmp    r0, #0x55
-    beq    1f
+    beq    cpu
     
     /* put us (co-processor) to sleep */
     ldr    r4, =COP_CTRL
     mov    r3, #SLEEP
     str    r3, [r4]
+    ldr    pc, =cop_wake_start
 
-    ldr    pc, =cop_init
+cop_wake_start:
+    /* COP: Invalidate cache */
+    ldr    r0, =0xf000f044
+    ldr    r1, [r0]
+    orr    r1, r1, #0x6
+    str    r1, [r0]
 
+    ldr    r0, =0x6000c000
 1:
+    ldr    r1, [r0]
+    tst    r1, #0x8000
+    bne    1b
+    
+#ifdef BOOTLOADER
+    ldr    r0, =startup_loc
+    ldr    pc, [r0]
+#else
+    /* Setup stack for COP */
+    ldr    sp, =cop_stackend
+    mov    r3, sp
+    ldr    r2, =cop_stackbegin
+    ldr    r4, =0xdeadbeef
+2:
+    cmp    r3, r2
+    strhi  r4, [r2], #4
+    bhi    2b
 
-#ifndef DEBUG
+    ldr    sp, =cop_stackend
+    
+    /* Run cop_main() in apps/main.c */
+    bl     cop_main
+#endif
+
+cpu:
+    /* Wait for COP to be sleeping */
+    ldr    r4, =COP_STATUS
+1:
+    ldr    r3, [r4]
+    ands   r3, r3, #SLEEPING
+    beq    1b
+    
+#ifndef BOOTLOADER
     /* Copy exception handler code to address 0 */
     ldr    r2, =_vectorsstart
     ldr    r3, =_vectorsend
@@ -133,24 +191,18 @@
     ldrhi  r5, [r4], #4
     strhi  r5, [r2], #4
     bhi    1b
-#else
-    ldr    r1, =vectors
-    ldr    r0, =irq_handler
-    str    r0, [r1, #24]
-    ldr    r0, =fiq_handler
-    str    r0, [r1, #28]
 #endif
 
-#ifndef STUB
-    /* Zero out IBSS */
-    ldr    r2, =_iedata
-    ldr    r3, =_iend
+    /* Initialise bss section to zero */
+    ldr    r2, =_edata
+    ldr    r3, =_end
     mov    r4, #0
 1:
     cmp    r3, r2
     strhi  r4, [r2], #4
     bhi    1b
-
+       
+#ifndef BOOTLOADER
     /* Copy the IRAM */
     ldr    r2, =_iramcopy
     ldr    r3, =_iramstart
@@ -160,18 +212,8 @@
     ldrhi  r5, [r2], #4
     strhi  r5, [r3], #4
     bhi    1b
-#endif /* !STUB */
-#endif /* !BOOTLOADER */
+#endif
 
-    /* Initialise bss section to zero */
-    ldr    r2, =_edata
-    ldr    r3, =_end
-    mov    r4, #0
-1:
-    cmp    r3, r2
-    strhi  r4, [r2], #4
-    bhi    1b
-    
     /* Set up some stack and munge it with 0xdeadbeef */
     ldr    sp, =stackend
     mov    r3, sp
@@ -183,76 +225,31 @@
     bhi    1b
 
 #ifdef BOOTLOADER
-    /* TODO: the high part of the address is probably dependent on CONFIG_CPU.
-       Since we tend to use ifdefs for each chipset target
-       anyway, we might as well just hardcode it here.
-     */
-       
-    /* get the high part of our execute address */
-    ldr    r0, =0xff000000
-    and    r8, pc, r0             @ r8 is used later
-
-    /* Find out which processor we are */
-    mov    r0, #PROC_ID
-    ldr    r0, [r0]
-    and    r0, r0, #0xff
-    cmp    r0, #0x55
-    beq    1f
-
-    /* put us (co-processor) to sleep */
-    ldr    r4, =COP_CTRL
-    mov    r3, #SLEEP
-    str    r3, [r4]
-    ldr    pc, =cop_wake_start
-
-cop_wake_start:
-    /* jump the COP to startup */
-    ldr    r0, =startup_loc
-    ldr    pc, [r0]
-
-1:
-    
-    /* get the high part of our execute address */
-    ldr    r2, =0xffffff00
-    and    r4, pc, r2
-
-    /* Copy bootloader to safe area - 0x40000000 */
-    mov    r5, #0x40000000
-    ldr    r6, = _dataend
-    sub    r0, r6, r5       /* length of loader */
-    add    r0, r4, r0     /* r0 points to start of loader */
-1:
-    cmp    r5, r6
-    ldrcc  r2, [r4], #4
-    strcc  r2, [r5], #4
-    bcc    1b
-
-    ldr    pc, =start_loc    /* jump to the relocated start_loc:  */
-    
-start_loc:
+    mov    r0, r8 /* r8 holds the start of the loader - copy this to r0 */
 
     /* execute the loader - this will load an image to 0x10000000 */
     bl     main
 
-    /* Wake up the coprocessor before executing the firmware */
-
-    /* save the startup address for the COP */
     ldr    r1, =startup_loc
     str    r0, [r1]
 
-    /* make sure COP is sleeping */
-    ldr    r4, =COP_STATUS
+    /* Flush cache */
+    ldr    r3, =0xf000f044
+    ldr    r4, [r3]
+    orr    r4, r4, #0x2
+    str    r4, [r3]
+
+    ldr    r3, =0x6000c000
 1:
-    ldr    r3, [r4]
-    ands   r3, r3, #SLEEPING
-    beq    1b
+    ldr    r4, [r3]
+    tst    r4, #0x8000
+    bne    1b
 
-    /* wake up COP */
+    /* Wake up the coprocessor before executing the firmware */
     ldr    r4, =COP_CTRL
     mov    r3, #WAKE
     str    r3, [r4]
 
-    /* jump to start location */
     mov    pc, r0
 
 startup_loc:
@@ -265,7 +262,7 @@
     .space 400
 
 #else /* BOOTLOADER */
-    
+
     /* Set up stack for IRQ mode */ 
     msr    cpsr_c, #0xd2
     ldr    sp, =irq_stack
@@ -288,19 +285,6 @@
     ldr    sp, =stackend
     bl     main
     /* main() should never return */
-
-cop_init:
-    ldr    sp, =cop_stackend
-    mov    r3, sp
-    ldr    r2, =cop_stackbegin
-    ldr    r4, =0xdeadbeef
-2:
-    cmp    r3, r2
-    strhi  r4, [r2], #4
-    bhi    2b
-
-    ldr    sp, =cop_stackend
-    bl     cop_main
     
 /* Exception handlers. Will be copied to address 0 after memory remapping */
     .section .vectors,"aw"
@@ -385,5 +369,4 @@
 /* 256 words of FIQ stack */
     .space 256*4
 fiq_stack:
-
-#endif /* BOOTLOADER */ 
+#endif /* BOOTLOADER */
Index: tools/configure
===================================================================
RCS file: /cvsroot/rockbox/tools/configure,v
retrieving revision 1.245
diff -u -r1.245 configure
--- tools/configure	27 Nov 2006 02:15:39 -0000	1.245
+++ tools/configure	5 Dec 2006 01:27:27 -0000
@@ -1115,10 +1115,10 @@
     target="-DSANSA_E200"
     memory=32 # supposedly
     arm7tdmicc
-    tool="$rootdir/tools/scramble -mi4v3"
+    tool="$rootdir/tools/scramble -add=e200"
     bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
     bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
-    output="PP5022.mi4"
+    output="rockbox.e200"
     appextra="recorder:gui"
     archosrom=""
     flash=""
Index: tools/scramble.c
===================================================================
RCS file: /cvsroot/rockbox/tools/scramble.c,v
retrieving revision 1.35
diff -u -r1.35 scramble.c
--- tools/scramble.c	31 Aug 2006 19:19:35 -0000	1.35
+++ tools/scramble.c	5 Dec 2006 01:27:28 -0000
@@ -89,7 +89,7 @@
            "\t-mi4v3  PortalPlayer .mi4 format (revision 010301)\n"
            "\t-add=X  Rockbox generic \"add-up\" checksum format\n"
            "\t        (X values: h100, h120, h140, h300, ipco, nano, ipvd\n"
-           "\t                   ip3g, ip4g, mini, x5, h10, h10_5gb)\n"
+           "\t                   ip3g, ip4g, mini, x5, h10, h10_5gb, tpj2, e200)\n"
            "\nNo option results in Archos standard player/recorder format.\n");
 
     exit(1);
@@ -207,6 +207,8 @@
             modelnum = 14;
         else if(!strcmp(&argv[1][5], "tpj2"))
             modelnum = 15;
+        else if(!strcmp(&argv[1][5], "e200"))
+            modelnum = 16;
         else {
             fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
             return 2;
