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/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,112 @@
 #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;
+    memory_init();
+    power_init();
+    system_init();
+    lcd_init();
+    backlight_init();
+    font_init();
 
-    if(GPGDAT & 2)
-        show_bootsplash = false;
+    lcd_setfont(FONT_SYSFIXED);
 
-    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...");
-    }
+    usb_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) {
+    /* Enter USB mode without 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();
 
-        /* Try to restore the original kernel/bootloader if a copy is found */
-        printf("Restoring FWIMG01.DAT...");
+        ata_enable(false);
+        sleep(HZ/20);
+        usb_enable(true);
 
-        if(!restore_fwimg01dat()) {
-            printf("Restoring FWIMG01.DAT successful.");
-        } else {
-            printf("Restoring FWIMG01.DAT failed.");
-        }
+        while (usb_detect())
+            sleep(HZ);
 
-        printf("Now power cycle to boot original");
-        while(1);
+        usb_enable(false);
+
+        reset_screen();
+        lcd_update();
     }
+    
+    kernel_init();
+    adc_init();
+    button_init();
 
-    if(!show_bootsplash) {
-        identify_info = ata_get_identify();
+    /* Show debug messages if button is pressed */
+    if(button_read_device())
+        verbose = true;
 
-        for(i=0; i < 20; i++)
-            ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
+    printf("Rockbox boot loader");
+    printf("Version %s", version);
 
-        buf[40]=0;
-
-        /* 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);
+    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));
     }
-    /* 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;
-        }
 
-        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...");
-    }
+    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/target/arm/gigabeat/meg-fx/system-meg-fx.c
===================================================================
--- firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c	(revision 13102)
+++ firmware/target/arm/gigabeat/meg-fx/system-meg-fx.c	(working copy)
@@ -1,6 +1,7 @@
 #include "kernel.h"
 #include "system.h"
 #include "panic.h"
+#include "mmu-meg-fx.h"
 
 #include "lcd.h"
 #include <stdio.h>
@@ -11,6 +12,7 @@
 const int DMA1_MASK   = (1 << 18);
 const int DMA2_MASK   = (1 << 19);
 const int DMA3_MASK   = (1 << 20);
+const int ALARM_MASK  = (1 << 30);
 
 int system_memory_guard(int newmode)
 {
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);
