Index: tools/configure
===================================================================
--- tools/configure	(revision 13102)
+++ tools/configure	(working copy)
@@ -1115,7 +1115,7 @@
     target="-DGIGABEAT_F"
     memory=32 # always
     arm9tdmicc
-    tool="cp"
+    tool="$rootdir/tools/scramble -add=giga"
     bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
     bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
     output="rockbox.gigabeat"
Index: tools/scramble.c
===================================================================
--- tools/scramble.c	(revision 13102)
+++ tools/scramble.c	(working copy)
@@ -224,6 +224,8 @@
             modelnum = 16;
         else if(!strcmp(&argv[1][5], "iam5"))
             modelnum = 17;
+        else if(!strcmp(&argv[1][5], "giga"))
+            modelnum = 18;
         else {
             fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
             return 2;
Index: apps/debug_menu.c
===================================================================
--- apps/debug_menu.c	(revision 13102)
+++ apps/debug_menu.c	(working copy)
@@ -83,6 +83,9 @@
 #ifdef IRIVER_H300_SERIES
 #include "pcf50606.h"   /* for pcf50606_read */
 #endif
+#if CONFIG_CPU == S3C2440
+#include "s3c2440.h"
+#endif
 #ifdef IAUDIO_X5
 #include "ds2411.h"
 #endif
@@ -403,6 +406,8 @@
 
 #ifndef SIMULATOR
 #ifdef HAVE_LCD_BITMAP
+
+extern int clockalarm;
 static bool dbg_hw_info(void)
 {
 #if CONFIG_CPU == SH7034
@@ -584,7 +589,72 @@
         if (action_userabort(TIMEOUT_BLOCK))
             return false;
     }
-#endif /* CONFIG_CPU */
+#elif CONFIG_CPU == S3C2440
+    char buf[50];
+    lcd_setmargins(0, 0);
+    lcd_setfont(FONT_SYSFIXED);
+    lcd_clear_display();
+    
+    lcd_puts(0, 0, "[Hardware info]");
+
+    while(1)
+    {
+        lcd_puts(0, 1, "Alarm Registers:");
+        snprintf(buf, sizeof(buf),"RTCALM: 0x%x", RTCALM);
+        lcd_puts(0, 2, buf);
+        snprintf(buf, sizeof(buf),"ALMHOUR: 0x%x", ALMHOUR);
+        lcd_puts(0, 3, buf);
+        snprintf(buf, sizeof(buf),"ALMMIN: 0x%x", ALMMIN);
+        lcd_puts(0, 4, buf);
+        
+        lcd_puts(0, 6, "RTC Registers:");
+        snprintf(buf, sizeof(buf),"RTCCON: 0x%x", RTCCON);
+        lcd_puts(0, 7, buf);
+        snprintf(buf, sizeof(buf),"BCDHOUR: 0x%x", BCDHOUR);
+        lcd_puts(0, 8, buf);
+        snprintf(buf, sizeof(buf),"BCDMIN: 0x%x", BCDMIN);
+        lcd_puts(0, 9, buf);
+        snprintf(buf, sizeof(buf),"BCDSEC: 0x%x", BCDSEC);
+        lcd_puts(0, 10, buf);
+        
+        lcd_puts(0, 12, "Interupt Registers:");
+        snprintf(buf, sizeof(buf),"EINTMASK: 0x%x", EINTMASK);
+        lcd_puts(0, 13, buf);
+        snprintf(buf, sizeof(buf),"INTMSK: 0x%x", INTMSK);
+        lcd_puts(0, 14, buf);
+        snprintf(buf, sizeof(buf),"SRCPND: 0x%x", SRCPND);
+        lcd_puts(0, 15, buf);
+
+        lcd_puts(0, 17, "GPIO Registers:");
+        snprintf(buf, sizeof(buf),"GPGCON: 0x%x", GPGCON);
+        lcd_puts(0, 18, buf);
+        snprintf(buf, sizeof(buf),"GPGDAT: 0x%x", GPGDAT);
+        lcd_puts(0, 19, buf);
+        snprintf(buf, sizeof(buf),"GPGUP: 0x%x", GPGUP);
+        lcd_puts(0, 20, buf);
+        
+        int regread;
+
+        asm volatile(
+            "MRC p15, 0, %r0, c1, c0, 0\n"  /* Read reg1, control register */
+        : /* outputs */
+            "=r"(regread)
+        : /* inputs */
+        : /* clobbers */
+            "r0"
+        );
+        
+        snprintf(buf, sizeof(buf),"CACHE_CTL: 0x%x", regread);
+        lcd_puts(0, 21, buf);
+
+        lcd_update();
+
+        if (action_userabort(TIMEOUT_BLOCK))
+            return false;
+        yield();
+    }
+
+#endif /* CONFIG_CPU */ 
     return false;
 }
 #else /* !HAVE_LCD_BITMAP */
Index: apps/main.c
===================================================================
--- apps/main.c	(revision 13102)
+++ apps/main.c	(working copy)
@@ -309,6 +309,7 @@
 #ifdef CPU_PP
     COP_CTL = PROC_WAKE;
 #endif
+
     system_init();
     kernel_init();
 
@@ -332,12 +333,8 @@
     lcd_remote_init();
 #endif
     font_init();
-    
-#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR)
+
     show_logo();
-#else
-    sleep(1);  /* Weird.  We crash w/o this tiny delay. */
-#endif    
     lang_init();
 
 #ifdef DEBUG
Index: bootloader/gigabeat.c
===================================================================
--- bootloader/gigabeat.c	(revision 13102)
+++ bootloader/gigabeat.c	(working copy)
@@ -20,7 +20,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
+#include "inttypes.h"
+#include "string.h"
 #include "cpu.h"
 #include "system.h"
 #include "lcd.h"
@@ -32,250 +33,118 @@
 #include "font.h"
 #include "adc.h"
 #include "backlight.h"
+#include "backlight-target.h"
+#include "button.h"
 #include "panic.h"
 #include "power.h"
 #include "file.h"
-#include "button-target.h"
 #include "common.h"
+#include "rbunicode.h"
+#include "usb.h"
 
-extern void map_memory(void);
+#include <stdarg.h>
 
+extern void memory_init(void);
+
 char version[] = APPSVERSION;
 
-static void go_usb_mode(void)
+void main(void)
 {
-    /* Drop into USB mode.  This does not check for disconnection. */
-    int i;
-
-    GPBDAT &= 0x7EF;
-    GPBCON |= 1<<8;
-
-    GPGDAT &= 0xE7FF;
-    GPGDAT |= 1<<11;
-
-    for(i = 0; i < 10000000; i++) {
-        continue;
-    }
-
-    GPBCON &= 0x2FFCFF;
-    GPBDAT |= 1<<5;
-    GPBDAT |= 1<<6;
-}
-
-
-/* Restores a factory kernel/bootloader from a known location                   */
-/* Restores the FWIMG01.DAT file back in the case of a bootloader failure       */
-/* The factory or "good" bootloader must be in /GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG */
-/* Returns non-zero on failure */
-int restore_fwimg01dat(void)
-{
-    int orig_file = 0, dest_file = 0;
-    int size = 0, size_read;
-    static char buf[4096];
-    
-    orig_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG", O_RDONLY);
-    if(orig_file < 0) {
-        /* Couldn't open source file */
-        printf("Couldn't open FWIMG01.DAT.ORIG for reading");
-        return(1);
-    }
-
-    printf("FWIMG01.DAT.ORIG opened for reading");
-
-    dest_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT", O_RDWR);
-    if(dest_file < 0) {
-        /* Couldn't open destination file */
-        printf("Couldn't open FWIMG01.DAT.ORIG for writing");
-        close(orig_file);
-        return(2);
-    }
-
-    printf("FWIMG01.DAT opened for writing");
-
-    do {
-        /* Copy in chunks */
-        size_read = read(orig_file, buf, sizeof(buf));
-        if(size_read != write(dest_file, buf, size_read)) {
-            close(orig_file);
-            close(dest_file);
-            return(3);
-        }
-        size += size_read;
-
-    } while(size_read > 0);
-
-    close(orig_file);
-    close(dest_file);
-
-    printf("Finished copying %ld bytes from", size);
-    printf("FWIMG01.DAT.ORIG to FWIMG01.DAT");
-
-    return(0);
-}
-
-char buf[256];
-
-void display_instructions(void)
-{
-    lcd_setfont(FONT_SYSFIXED);
-    printf("Hold MENU when booting for rescue mode.");
-    printf("  \"VOL+\" button to restore original kernel");
-    printf("  \"A\" button to load original firmware");
-    printf("");
-    printf("FRAME %x TTB %x", FRAME, TTB_BASE);
-}
-
-void * main(void)
-{
-    int i;
-    struct partinfo* pinfo;
-    unsigned short* identify_info;
     unsigned char* loadbuffer;
     int buffer_size;
-    bool load_original = false;
     int rc;
     int(*kernel_entry)(void);
 
-    bool show_bootsplash = true;
+    power_init();
 
-    if(GPGDAT & 2)
-        show_bootsplash = false;
+    system_init();
+    kernel_init();
+    adc_init();
+    button_init();
+    backlight_init();
+    
+    /* Show debug messages if button is pressed */
+    if(button_read_device())
+        verbose = true;
 
-    if(!show_bootsplash) {
-        lcd_init();
-        display_instructions();
-        sleep(2*HZ);
-    }
-    if(GPGDAT & 2) {
-        lcd_init();
-        printf("Entering rescue mode..");
-        go_usb_mode();
-        while(1);
-    }
-    if(GPGDAT & 0x10) {
-        lcd_init();
-        load_original = true;
-        printf("Loading original firmware...");
-    }
+    lcd_init();
+    
+    font_init();
 
-    i = ata_init();
-    i = disk_mount_all();
-    if(!show_bootsplash) {
-        printf("disk_mount_all: %d", i);
-    }
-    if(show_bootsplash) {
-        int fd = open("/bootsplash.raw", O_RDONLY);
-        if(fd < 0)  {
-            show_bootsplash = false;
-            lcd_init();
-            display_instructions();
-        }
-        else {
-            read(fd, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
-            close(fd);
-            lcd_update();
-            lcd_init();
-        }
-    } 
-    /* hold VOL+ to enter rescue mode to copy old image */
-    /* needs to be after ata_init and disk_mount_all    */
-    if(GPGDAT & 4) {
+    lcd_setfont(FONT_SYSFIXED);
 
-        /* Try to restore the original kernel/bootloader if a copy is found */
-        printf("Restoring FWIMG01.DAT...");
+    printf("Rockbox boot loader");
+    printf("Version %s", version);
 
-        if(!restore_fwimg01dat()) {
-            printf("Restoring FWIMG01.DAT successful.");
-        } else {
-            printf("Restoring FWIMG01.DAT failed.");
-        }
+    usb_init();
 
-        printf("Now power cycle to boot original");
-        while(1);
-    }
+    /* A hack to enter USB mode without using the USB thread */
+    if(usb_detect())
+    {
+        const char msg[] = "Bootloader USB mode";
+        int w, h;
+        font_getstringsize(msg, &w, &h, FONT_SYSFIXED);
+        reset_screen();
+        lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, msg);
+        lcd_update();
 
-    if(!show_bootsplash) {
-        identify_info = ata_get_identify();
+        ide_power_enable(true);
+        ata_enable(false);
+        sleep(HZ/20);
+        usb_enable(true);
 
-        for(i=0; i < 20; i++)
-            ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
+        while (usb_detect())
+        {
+            ata_spin(); /* Prevent the drive from spinning down */
+            sleep(HZ);
+        }
 
-        buf[40]=0;
+        usb_enable(false);
 
-        /* kill trailing space */
-        for(i=39; i && buf[i]==' '; i--)
-            buf[i] = 0;
-
-        printf("Model");
-        printf(buf);
-
-        for(i=0; i < 4; i++)
-            ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
-
-        buf[8]=0;
-
-        printf("Firmware");
-        printf(buf);
-
-        pinfo = disk_partinfo(0);
-        printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048);
+        reset_screen();
+        lcd_update();
     }
-    /* Load original firmware */
-    if(load_original) {
-        loadbuffer = (unsigned char*)0x30008000;
-        buffer_size =(unsigned char*)0x31000000 - loadbuffer;
-        rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size);
-        if(rc < EOK) {
-            printf("Error!");
-            printf("Failed to load original firmware:");
-            printf(strerror(rc));
-            printf("Loading rockbox");
-            sleep(2*HZ);
-            goto load_rockbox;
-        }
+    
+    rc = ata_init();
+    if(rc)
+    {
+        reset_screen();
+        printf("ATA error: %d", rc);
+        printf("Insert USB cable and press");
+        printf("a button");
+        while(!(button_get(true) & BUTTON_REL));
+    }
 
-        printf("Loaded: %d", rc);
-        sleep(2*HZ);
+    disk_init();
 
-        (*((int*)0x7000000)) = 333;
-        rc = *((int*)0x7000000+0x8000000);
-        printf("Bank0 mem test: %d", rc);
-        sleep(3*HZ);
-
-        printf("Woops, should not return from firmware!");
-        goto usb;
+    rc = disk_mount_all();
+    if (rc<=0)
+    {
+        reset_screen();
+        printf("No partition found");
+        while(button_get(true) != SYS_USB_CONNECTED) {};
     }
 
-load_rockbox:
-    map_memory();
-    if(!show_bootsplash) {
-        printf("Loading Rockbox...");
-    }
+    memory_init();
+    printf("Loading firmware");
 
     loadbuffer = (unsigned char*) 0x100;
     buffer_size = (unsigned char*)0x400000 - loadbuffer;
-    rc = load_raw_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size);
-    if(rc < EOK) {
-        rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size);      
-    }
-    if(rc < EOK) {
-        printf("Error!");
-        printf("Can't load rockbox.gigabeat:");
-        printf(strerror(rc));
-    } else {
-        if(!show_bootsplash) {
-            printf("Rockbox loaded.");
-        }
+
+    rc = load_firmware(loadbuffer, BOOTFILE, buffer_size);
+    if(rc < 0)
+        printf("Error: %d", strerror(rc));
+
+    if (rc == EOK)
+    {
         kernel_entry = (void*) loadbuffer;
         rc = kernel_entry();
-        printf("Woops, should not return from firmware: %d", rc);
-        goto usb;
     }
-usb:
-    /* now wait in USB mode so the bootloader can be updated */
-    go_usb_mode();
-    while(1);
-
-    return((void *)0);
+    else
+    {
+        printf("No firmware found on disk - Switch off player");
+        sleep(HZ*2);
+        while(1);
+    }
 }
 
Index: bootloader/common.c
===================================================================
--- bootloader/common.c	(revision 13102)
+++ bootloader/common.c	(working copy)
@@ -31,7 +31,7 @@
 /* TODO: Other bootloaders need to be adjusted to set this variable to true
    on a button press - currently only the ipod, H10 and Sansa versions do. */
 #if defined(IPOD_ARCH) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
-    defined(SANSA_E200)
+    defined(SANSA_E200) || defined(GIGABEAT_F)
 bool verbose = false;
 #else
 bool verbose = true;
Index: firmware/export/config-gigabeat.h
===================================================================
--- firmware/export/config-gigabeat.h	(revision 13102)
+++ firmware/export/config-gigabeat.h	(working copy)
@@ -6,7 +6,7 @@
 #define TOSHIBA_GIGABEAT_F 1
 
 /* For Rolo and boot loader */
-#define MODEL_NUMBER 1
+#define MODEL_NUMBER 18
 
 /* define this if you have a bitmap LCD display */
 #define HAVE_LCD_BITMAP
Index: firmware/rolo.c
===================================================================
--- firmware/rolo.c	(revision 13102)
+++ firmware/rolo.c	(working copy)
@@ -30,8 +30,7 @@
 #include "string.h"
 #include "buffer.h"
 
-#if !defined(IRIVER_IFP7XX_SERIES) && \
-    (CONFIG_CPU != PP5002) && (CONFIG_CPU != S3C2440)
+#if !defined(IRIVER_IFP7XX_SERIES) && (CONFIG_CPU != PP5002)
 /* FIX: this doesn't work on iFP, 3rd Gen ipods */
 
 #define IRQ0_EDGE_TRIGGER 0x80
@@ -113,6 +112,11 @@
         "jmp     (%0)        \n"
         : : "a"(dest)
     );
+#elif defined(CPU_ARM)
+    asm volatile(
+        "mov   r0, #0x00000000   \n"
+        "mov   pc, r0            \n"
+    );
 #elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
 
     /* Tell the COP that we've finished loading and started rebooting */
@@ -153,7 +157,7 @@
 {
     int fd;
     long length;
-#if defined(CPU_COLDFIRE) || defined(CPU_PP)
+#if defined(CPU_COLDFIRE) || defined(CPU_PP) || defined(CPU_ARM)
     int i;
     unsigned long checksum,file_checksum;
 #else
@@ -183,7 +187,7 @@
 
     length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA;
 
-#if defined(CPU_COLDFIRE) || defined(CPU_PP)
+#if defined(CPU_COLDFIRE) || defined(CPU_PP) || defined(CPU_ARM)
     /* Read and save checksum */
     lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
     if (read(fd, &file_checksum, 4) != 4) {
@@ -290,7 +294,7 @@
     PAIOR = 0x0FA0;
 #endif
 #endif
-    rolo_restart(audiobuf, ramstart, length);
+    rolo_restart(audiobuf, ramstart+100, length);
 
     return 0; /* this is never reached */
 }
Index: firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c
===================================================================
--- firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c	(revision 13102)
+++ firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.c	(working copy)
@@ -3,7 +3,7 @@
 #include "mmu-meg-fx.h"
 #include "panic.h"
 
-void map_memory(void);
+void memory_init(void);
 static void enable_mmu(void);
 static void set_ttb(void);
 static void set_page_tables(void);
@@ -15,7 +15,7 @@
 #define BUFFERED (1 << 2)
 #define MB (1 << 20)
 
-void map_memory(void) {
+void memory_init(void) {
     set_ttb();
     set_page_tables();
     enable_mmu();
@@ -69,6 +69,20 @@
 }
 
 static void enable_mmu(void) {
+    int regread;
+
+    asm volatile(
+        "MRC p15, 0, %r0, c1, c0, 0\n"  /* Read reg1, control register */
+    : /* outputs */
+        "=r"(regread)
+    : /* inputs */
+    : /* clobbers */
+        "r0"
+    );
+
+    if ( !(regread & 0x04) || !(regread & 0x00001000) ) /* Was the ICache or DCache Enabled? */
+        clean_dcache(); /* If so we need to clean the DCache before invalidating below */
+
     asm volatile("mov r0, #0\n"
         "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */
 
Index: firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
===================================================================
--- firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c	(revision 13102)
+++ firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c	(working copy)
@@ -53,6 +53,23 @@
 /* LCD init */
 void lcd_init_device(void)
 {
+#ifdef BOOTLOADER
+    /* When the Rockbox bootloader starts, we are changing framebuffer address,
+       but we don't want what's shown on the LCD to change until we do an
+       lcd_update(), so copy the data from the old framebuffer to the new one */
+    int i;
+    unsigned short *buf = (unsigned short*)FRAME;
+
+    memcpy(FRAME, (short *)((LCDSADDR1)<<1), 320*240*2);
+
+    /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode
+       so convert the frambuffer data accordingly */
+    for(i=0; i< 320*240; i++){
+        *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0);
+        buf++;
+    }
+#endif
+
     LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME));
     LCDSADDR2 = LCDBASEL((unsigned)FRAME);
     LCDSADDR3 = 0x000000F0;
Index: firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.h
===================================================================
--- firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.h	(revision 13102)
+++ firmware/target/arm/gigabeat/meg-fx/mmu-meg-fx.h	(working copy)
@@ -32,4 +32,4 @@
 /* Cleans entire DCache */
 void clean_dcache(void);
 
-
+void memory_init(void);
