? h300
? h300-sim
? settings_file.patch
? uisimulator
? tools/codepages
? tools/mkboot
? tools/rdf2binary
Index: apps/SOURCES
===================================================================
RCS file: /cvsroot/rockbox/apps/SOURCES,v
retrieving revision 1.57
diff -u -r1.57 SOURCES
--- apps/SOURCES	13 Nov 2006 00:45:19 -0000	1.57
+++ apps/SOURCES	14 Nov 2006 14:34:27 -0000
@@ -20,6 +20,7 @@
 plugin.c
 screens.c
 settings.c
+settings_list.c
 settings_menu.c
 sound_menu.c
 status.c
Index: apps/main.c
===================================================================
RCS file: /cvsroot/rockbox/apps/main.c,v
retrieving revision 1.195
diff -u -r1.195 main.c
--- apps/main.c	7 Nov 2006 19:03:29 -0000	1.195
+++ apps/main.c	14 Nov 2006 14:34:28 -0000
@@ -232,7 +232,6 @@
     screen_access_init();
     gui_syncstatusbar_init(&statusbars);
     settings_reset();
-    settings_calc_config_sector();
     settings_load(SETTINGS_ALL);
     gui_sync_wps_init();
     settings_apply();
@@ -428,7 +427,6 @@
         }
     }
 
-    settings_calc_config_sector();
     
 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IRIVER_H10_PAD)
 #ifdef SETTINGS_RESET
Index: apps/misc.c
===================================================================
RCS file: /cvsroot/rockbox/apps/misc.c,v
retrieving revision 1.74
diff -u -r1.74 misc.c
--- apps/misc.c	11 Nov 2006 01:18:57 -0000	1.74
+++ apps/misc.c	14 Nov 2006 14:34:29 -0000
@@ -713,7 +713,7 @@
     }
 }
 #endif
-
+void write_settings_to_disk(void); /* from settings.c */
 long default_event_handler_ex(long event, void (*callback)(void *), void *parameter)
 {
     switch(event)
@@ -753,6 +753,9 @@
             unplug_change(false);
             return SYS_PHONE_UNPLUGGED;
 #endif
+        case SYS_DUMPSETTINGS:
+            write_settings_to_disk();
+            return SYS_DUMPSETTINGS;
     }
     return 0;
 }
Index: apps/settings.c
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.c,v
retrieving revision 1.437
diff -u -r1.437 settings.c
--- apps/settings.c	13 Nov 2006 00:45:20 -0000	1.437
+++ apps/settings.c	14 Nov 2006 14:34:30 -0000
@@ -26,6 +26,7 @@
 #include "thread.h"
 #include "action.h"
 #include "settings.h"
+#include "settings_list.h"
 #include "disk.h"
 #include "panic.h"
 #include "debug.h"
@@ -115,629 +116,25 @@
 #endif
 
 long lasttime = 0;
-static long config_sector = 0;  /* mark uninitialized */
-static unsigned char config_block[CONFIG_BLOCK_SIZE];
-
-
-/* descriptor for a configuration value */
-/* (watch the struct packing and member sizes to keep this small) */
-struct bit_entry
-{
-    /* how many bits within the bitfield (1-32), MSB set if value is signed */
-    unsigned char bit_size; /* min 6+1 bit */
-    /* how many bytes in the global_settings struct (1,2,4) */
-    unsigned char byte_size; /* min 3 bits */
-    /* store position in global_settings struct */
-    short settings_offset; /* min 9 bit, better 10 */
-    /* default value */
-    int default_val; /* min 15 bit */
-    /* variable name in a .cfg file, NULL if not to be saved */
-    const char* cfg_name;
-    /* set of values, "rgb" for a color, or NULL for a numerical value */
-    const char* cfg_val;
-};
-
-/********************************************
-
-Config block as saved on the battery-packed RTC user RAM memory block
-of 44 bytes, starting at offset 0x14 of the RTC memory space.
-
-offset  abs
-0x00    0x14    "Roc"   header signature: 0x52 0x6f 0x63
-0x03    0x17    <version byte: 0x0>
-0x04    0x18    start of bit-table
-...
-0x28,0x29 unused, not reachable by set_bits() without disturbing the next 2
-0x2A,0x2B <checksum 2 bytes: xor of 0x00-0x29>
-
-Config memory is reset to 0xff and initialized with 'factory defaults' if
-a valid header & checksum is not found. Config version number is only
-increased when information is _relocated_ or space is _reused_ so that old
-versions can read and modify configuration changed by new versions.
-Memory locations not used by a given version should not be
-modified unless the header & checksum test fails.
-
-Rest of config block, only saved to disk:
-0x2C  start of 2nd bit-table
-...
-0xA4  (char[20]) FMR Preset file
-0xB8  (char[20]) WPS file
-0xCC  (char[20]) Lang file
-0xE0  (char[20]) Font file
-...   (char[20]) RWPS file (on targets supporting a Remote WPS)
-...   (char[20]) Main backdrop file (on color LCD targets)
-
-... to 0x200  <unused>
-
-*************************************/
-
-/* The persistence of the global_settings members is now controlled by
-   the two tables below, rtc_bits and hd_bits.
-   New values can just be added to the end, it will be backwards
-   compatible. If you however change order, bitsize, etc. of existing
-   entries, you need to bump CONFIG_BLOCK_VERSION to break compatibility.
-*/
-
-
-/* convenience macro for both size and offset of global_settings member */
-#define S_O(val) sizeof(global_settings.val), offsetof(struct user_settings, val)
-#define SIGNED 0x80 /* for bitsize value with signed attribute */
-
-/* some sets of values which are used more than once, to save memory */
-static const char off_on[] = "off,on";
-static const char off_on_ask[] = "off,on,ask";
-static const char off_number_spell_hover[] = "off,number,spell,hover";
-#ifdef HAVE_LCD_BITMAP
-static const char graphic_numeric[] = "graphic,numeric";
-#endif
-
-#ifdef HAVE_RECORDING
-/* keep synchronous to trig_durations and
-   trigger_times in settings_apply_trigger */
-static const char trig_durations_conf [] =
-                  "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min";
-#endif
-
-#if defined(CONFIG_BACKLIGHT)
-static const char backlight_times_conf [] =
-                  "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
-#endif
-
-/* the part of the settings which ends up in the RTC RAM, where available
-   (those we either need early, save frequently, or without spinup) */
-static const struct bit_entry rtc_bits[] =
-{
-    /* placeholder, containing the size information */
-    {9, 0, 0, 0, NULL, NULL }, /* 9 bit to tell how far this is populated */
-
-    /* # of bits, offset+size, default, .cfg name, .cfg values */
-    /* sound */
-#if CONFIG_CODEC == MAS3507D
-    {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */
-#else
-    {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */
-#endif
-    {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */
-#if CONFIG_CODEC != SWCODEC /* any MAS */
-    {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -15..+15 / -12..+12 */
-    {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -15..+15 / -12..+12 */
-#elif defined HAVE_UDA1380
-    {5, S_O(bass), 0, "bass", NULL }, /* 0..+24 */
-    {3, S_O(treble), 0, "treble", NULL }, /* 0..+6 */
-#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
-   || defined(HAVE_WM8731) || defined(HAVE_WM8721)
-    {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -6..+9 */
-    {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -6..+9 */
-#endif
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
-    {5, S_O(loudness), 0, "loudness", NULL }, /* 0...17 */
-    {3, S_O(avc), 0, "auto volume", "off,20ms,2,4,8" },
-    {1, S_O(superbass), false, "superbass", off_on },
-#endif
-    {3, S_O(channel_config), 0, "channels",
-        "stereo,mono,custom,mono left,mono right,karaoke" },
-    {8, S_O(stereo_width), 100, "stereo width", NULL},
-    /* playback */
-    {1, S_O(resume), false, "resume", off_on },
-    {1, S_O(playlist_shuffle), false, "shuffle", off_on },
-    {16 | SIGNED, S_O(resume_index), -1, NULL, NULL },
-    {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL },
-    {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL },
-    {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL },
-    {3, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle,ab" },
-    /* LCD */
-#ifdef HAVE_LCD_CONTRAST
-    {6, S_O(contrast), DEFAULT_CONTRAST_SETTING, "contrast", NULL },
-#endif
-#ifdef CONFIG_BACKLIGHT
-    {5, S_O(backlight_timeout), 6, "backlight timeout", backlight_times_conf },
-#ifdef CONFIG_CHARGING
-    {5, S_O(backlight_timeout_plugged), 11, "backlight timeout plugged",
-        backlight_times_conf },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-#ifdef HAVE_LCD_BITMAP
-    {1, S_O(invert), false, "invert", off_on },
-    {1, S_O(flip_display), false, "flip display", off_on },
-    /* display */
-    {1, S_O(invert_cursor), true, "invert cursor", off_on },
-    {1, S_O(statusbar), true, "statusbar", off_on },
-    {1, S_O(scrollbar), true, "scrollbar", off_on },
-#if CONFIG_KEYPAD == RECORDER_PAD
-    {1, S_O(buttonbar), true, "buttonbar", off_on },
-#endif
-    {1, S_O(volume_type), 0, "volume display", graphic_numeric },
-    {1, S_O(battery_display), 0, "battery display", graphic_numeric },
-    {1, S_O(timeformat), 0, "time format", "24hour,12hour" },
-#endif /* HAVE_LCD_BITMAP */
-    {1, S_O(show_icons), true, "show icons", off_on },
-    /* system */
-    {4, S_O(poweroff), 10,
-        "idle poweroff", "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60" },
-    {18, S_O(runtime), 0, NULL, NULL },
-    {18, S_O(topruntime), 0, NULL, NULL },
-#if MEM > 1
-    {15, S_O(max_files_in_playlist), 10000,
-        "max files in playlist", NULL }, /* 1000...20000 */
-    {14, S_O(max_files_in_dir), 400,
-        "max files in dir", NULL }, /* 50...10000 */
-#else
-    {15, S_O(max_files_in_playlist), 1000,
-        "max files in playlist", NULL }, /* 1000...20000 */
-    {14, S_O(max_files_in_dir), 200,
-        "max files in dir", NULL }, /* 50...10000 */
-#endif
-    /* battery */
-    {12, S_O(battery_capacity), BATTERY_CAPACITY_DEFAULT, "battery capacity",
-         NULL }, /* 1500...3200 for NiMH, 2200...3200 for LiIon,
-                     500...1500 for Alkaline */
-#ifdef CONFIG_CHARGING
-    {1, S_O(car_adapter_mode), false, "car adapter mode", off_on },
-#endif
-    /* tuner */
-#ifdef CONFIG_TUNER
-    {1, S_O(fm_force_mono), false, "force fm mono", off_on },
-    {9, S_O(last_frequency), 0, NULL, NULL }, /* Default: MIN_FREQ */
-#endif
-
-#if BATTERY_TYPES_COUNT > 1
-    {1, S_O(battery_type), 0, "battery type", "alkaline,nimh" },
-#endif
-
-#ifdef HAVE_REMOTE_LCD
-    /* remote lcd */
-    {6, S_O(remote_contrast), DEFAULT_REMOTE_CONTRAST_SETTING,
-        "remote contrast", NULL },
-    {1, S_O(remote_invert), false, "remote invert", off_on },
-    {1, S_O(remote_flip_display), false, "remote flip display", off_on },
-    {5, S_O(remote_backlight_timeout), 6, "remote backlight timeout",
-        backlight_times_conf },
-#ifdef CONFIG_CHARGING
-    {5, S_O(remote_backlight_timeout_plugged), 11,
-        "remote backlight timeout plugged", backlight_times_conf },
-#endif
-#ifdef HAVE_REMOTE_LCD_TICKING
-    {1, S_O(remote_reduce_ticking), false, "remote reduce ticking", off_on },
-#endif
-#endif
-
-#ifdef CONFIG_BACKLIGHT
-    {1, S_O(bl_filter_first_keypress), false,
-            "backlight filters first keypress", off_on },
-#ifdef HAVE_REMOTE_LCD
-    {1, S_O(remote_bl_filter_first_keypress), false,
-            "backlight filters first remote keypress", off_on },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-
-    /* new stuff to be added here */
-    /* If values are just added to the end, no need to bump the version. */
-
-    /* Current sum of bits: 277 (worst case, but w/o remote lcd) */
-    /* Sum of all bit sizes must not grow beyond 288! */
+struct persistant_vars {
+    short offset;
+    char value[32];
 };
-
-
-/* the part of the settings which ends up in HD sector only */
-static const struct bit_entry hd_bits[] =
+#define MAX_PERSISTANT_VARS 16
+struct persistant_vars persistant_variables[MAX_PERSISTANT_VARS];
+int persistant_vars_count = 0;
+void add_to_persistant(const struct settings_list *item, char* value)
 {
-    /* This table starts after the 44 RTC bytes = 352 bits. */
-    /* Here we need 11 bits to tell how far this is populated. */
-
-    /* placeholder, containing the size information */
-    {11, 0, 0, 0, NULL, NULL }, /* 11 bit to tell how far this is populated */
-
-    /* # of bits, offset+size, default, .cfg name, .cfg values */
-    /* more display */
-#ifdef CONFIG_BACKLIGHT
-    {1, S_O(caption_backlight), false, "caption backlight", off_on },
-#endif
-#ifdef HAVE_REMOTE_LCD
-    {1, S_O(remote_caption_backlight), false,
-        "remote caption backlight", off_on },
-#endif
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-    {4, S_O(brightness), DEFAULT_BRIGHTNESS_SETTING, "brightness", NULL },
-#endif
-#ifdef HAVE_BACKLIGHT_PWM_FADING
-    /* backlight fading */
-    {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"},
-    {3, S_O(backlight_fade_out), 3, "backlight fade out",
-        "off,500ms,1s,2s,3s,4s,5s,10s"},
-#endif
-
-    {4, S_O(scroll_speed), 9, "scroll speed", NULL }, /* 0...15 */
-    {8, S_O(scroll_delay), 100, "scroll delay", NULL }, /* 0...250 */
-    {8, S_O(bidir_limit), 50, "bidir limit", NULL }, /* 0...200 */
-    
-#ifdef HAVE_REMOTE_LCD
-    {4, S_O(remote_scroll_speed), 9, "remote scroll speed", NULL }, /* 0...15 */
-    {8, S_O(remote_scroll_step), 6, "remote scroll step", NULL }, /* 1...160 */
-    {8, S_O(remote_scroll_delay), 100, "remote scroll delay", NULL }, /* 0...250 */
-    {8, S_O(remote_bidir_limit), 50, "remote bidir limit", NULL }, /* 0...200 */
-#endif
-
-#ifdef HAVE_LCD_BITMAP
-    {1, S_O(offset_out_of_view), false, "Screen Scrolls Out Of View", off_on },
-#if LCD_WIDTH > 255
-    {9, S_O(scroll_step), 6, "scroll step", NULL },
-    {9, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#elif LCD_WIDTH > 127
-    {8, S_O(scroll_step), 6, "scroll step", NULL },
-    {8, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#else
-    {7, S_O(scroll_step), 6, "scroll step", NULL },
-    {7, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#endif
-#endif /* HAVE_LCD_BITMAP */
-#ifdef HAVE_LCD_CHARCELLS
-    {3, S_O(jump_scroll), 0, "jump scroll", NULL }, /* 0...5 */
-    {8, S_O(jump_scroll_delay), 50, "jump scroll delay", NULL }, /* 0...250 */
-#endif
-    {1, S_O(scroll_paginated), false, "scroll paginated", off_on },
-
-#ifdef HAVE_LCD_COLOR
-    {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
-    {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
-#endif
-
-    /* more playback */
-    {1, S_O(play_selected), true, "play selected", off_on },
-    {1, S_O(fade_on_stop), true, "volume fade", off_on },
-    {4, S_O(ff_rewind_min_step), FF_REWIND_1000,
-        "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60" },
-    {4, S_O(ff_rewind_accel), 3, "scan accel", NULL },
-#if CONFIG_CODEC == SWCODEC
-    {3, S_O(buffer_margin), 0, "antiskip",
-        "5s,15s,30s,1min,2min,3min,5min,10min" },
-#else
-    {3, S_O(buffer_margin), 0, "antiskip", NULL },
-#endif
-    /* disk */
-#ifndef HAVE_MMC
-#ifdef HAVE_ATA_POWER_OFF
-    {1, S_O(disk_poweroff), false, "disk poweroff", off_on },
-#endif
-    {8, S_O(disk_spindown), 5, "disk spindown", NULL },
-#endif /* HAVE_MMC */
-
-    /* browser */
-    {3, S_O(dirfilter), SHOW_SUPPORTED,
-        "show files", "all,supported,music,playlists"
-#ifdef HAVE_TAGCACHE
-        ",id3 database" 
-#endif
-        },
-    {1, S_O(sort_case), false, "sort case", off_on },
-    {1, S_O(browse_current), false, "follow playlist", off_on },
-    /* playlist */
-    {1, S_O(playlist_viewer_icons), true, "playlist viewer icons", off_on },
-    {1, S_O(playlist_viewer_indices), true,
-        "playlist viewer indices", off_on },
-    {1, S_O(playlist_viewer_track_display), 0,
-        "playlist viewer track display", "track name,full path" },
-    {2, S_O(recursive_dir_insert), RECURSE_OFF,
-        "recursive directory insert", off_on_ask },
-    /* bookmarks */
-    {3, S_O(autocreatebookmark), BOOKMARK_NO, "autocreate bookmarks",
-        "off,on,ask,recent only - on,recent only - ask" },
-    {2, S_O(autoloadbookmark), BOOKMARK_NO,
-        "autoload bookmarks", off_on_ask },
-    {2, S_O(usemrb), BOOKMARK_NO,
-        "use most-recent-bookmarks", "off,on,unique only" },
-#ifdef HAVE_LCD_BITMAP
-    /* peak meter */
-    {5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */
-        "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min,3min,5min,10min,20min,45min,90min" },
-    {5, S_O(peak_meter_hold), 3, "peak meter hold",
-        "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" },
-    {7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */
-    {1, S_O(peak_meter_dbfs), true, "peak meter dbfs", off_on },
-    {7, S_O(peak_meter_min), 60, "peak meter min", NULL }, /* 0...100 */
-    {7, S_O(peak_meter_max), 0, "peak meter max", NULL }, /* 0...100 */
-#endif
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
-    {7, S_O(mdb_strength), 0, "mdb strength", NULL},
-    {7, S_O(mdb_harmonics), 0, "mdb harmonics", NULL},
-    {9, S_O(mdb_center), 0, "mdb center", NULL},
-    {9, S_O(mdb_shape), 0, "mdb shape", NULL},
-    {1, S_O(mdb_enable), 0, "mdb enable", off_on},
-#endif
-#if CONFIG_CODEC == MAS3507D
-    {1, S_O(line_in), false, "line in", off_on },
-#endif
-    /* voice */
-    {2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover },
-    {2, S_O(talk_file), 0, "talk file", off_number_spell_hover },
-    {1, S_O(talk_menu), true, "talk menu", off_on },
-
-    {2, S_O(sort_file), 0, "sort files", "alpha,oldest,newest,type" },
-    {2, S_O(sort_dir), 0, "sort dirs", "alpha,oldest,newest" },
-    {1, S_O(id3_v1_first), 0, "id3 tag priority", "v2-v1,v1-v2"},
-
-#ifdef HAVE_RECORDING
-    /* recording */
-    {1, S_O(recscreen_on), false, "recscreen on", off_on },
-    {1, S_O(rec_startup), false, "rec screen on startup", off_on },
-    {4, S_O(rec_timesplit), 0, "rec timesplit", /* 0...15 */
-        "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" },
-    {4, S_O(rec_sizesplit), 0, "rec sizesplit", /* 0...15 */
-        "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB" },
-    {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" },
-    {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
-    {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
-
+    if (persistant_vars_count<MAX_PERSISTANT_VARS)
     {
-#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN)
-        2,
-#else
-        1,
-#endif
-        S_O(rec_source), 0 /* 0=mic */, "rec source",
-        "mic,line"
-#ifdef HAVE_SPDIF_IN
-        ",spdif"
-#endif
-#ifdef HAVE_FMRADIO_IN
-        ",fmradio"
-#endif
-    },
-    {5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
-    {1, S_O(rec_directory), 0, /* rec_base_directory */
-        "rec directory", REC_BASE_DIR ",current" },
-#ifdef CONFIG_BACKLIGHT
-    {2, S_O(cliplight), 0, "cliplight", "off,main,both,remote" },
-#endif 
-#if CONFIG_CODEC == MAS3587F
-    {4, S_O(rec_mic_gain), 8, "rec mic gain", NULL },
-    {4, S_O(rec_left_gain), 2 /* 0dB */, "rec left gain", NULL }, /* 0...15 */
-    {4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
-    {3, S_O(rec_frequency), 0, /* 0=44.1kHz */
-        "rec frequency", "44,48,32,22,24,16" },
-    {3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL },
-    {1, S_O(rec_editable), false, "editable recordings", off_on },
-#endif /* CONFIG_CODEC == MAS3587F */
-
-#if CONFIG_CODEC == SWCODEC
-#ifdef HAVE_UDA1380
-    {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
-#endif
-#ifdef HAVE_TLV320
-    /* TLV320 only has no mic boost or 20db mic boost */
-    {1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */
-#endif
-    {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
-    {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-    {REC_FREQ_CFG_NUM_BITS, S_O(rec_frequency), REC_FREQ_DEFAULT,
-        "rec frequency", REC_FREQ_CFG_VAL_LIST },
-    {REC_FORMAT_CFG_NUM_BITS ,S_O(rec_format), REC_FORMAT_DEFAULT,
-        "rec format", REC_FORMAT_CFG_VAL_LIST },
-    /** Encoder settings start - keep these together **/
-    /* mp3_enc */
-    {5,S_O(mp3_enc_config.bitrate), MP3_ENC_BITRATE_CFG_DEFAULT,
-        "mp3_enc bitrate", MP3_ENC_BITRATE_CFG_VALUE_LIST },
-    /* wav_enc */
-    /* (no settings yet) */
-    /* wavpack_enc */
-    /* (no settings yet) */
-    /** Encoder settings end **/
-#endif /* CONFIG_CODEC == SWCODEC */
-
-    /* values for the trigger */
-    {8 | SIGNED, S_O(rec_start_thres), -35, "trigger start threshold", NULL},
-    {8 | SIGNED, S_O(rec_stop_thres), -45, "trigger stop threshold", NULL},
-    {4, S_O(rec_start_duration), 0, "trigger start duration", trig_durations_conf},
-    {4, S_O(rec_stop_postrec), 2, "trigger stop postrec", trig_durations_conf},
-    {4, S_O(rec_stop_gap), 1, "trigger min gap", trig_durations_conf},
-    {4, S_O(rec_trigger_mode ), 0, "trigger mode", "off,once,repeat"},
-#endif /* HAVE_RECORDING */
-
-#ifdef HAVE_SPDIF_POWER
-    {1, S_O(spdif_enable), false, "spdif enable", off_on},
-#endif
-
-    {2, S_O(next_folder), false, "folder navigation", "off,on,random" },
-    {1, S_O(runtimedb), false, "gather runtime data", off_on },
-
-#if CONFIG_CODEC == SWCODEC
-    {1, S_O(replaygain), false, "replaygain", off_on },
-    {2, S_O(replaygain_type), REPLAYGAIN_ALBUM, "replaygain type",
-        "track,album,track shuffle" },
-    {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
-    {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
-    {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" },
-    {2, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,always"},
-    {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL},
-    {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL},
-    {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL},
-    {4, S_O(crossfade_fade_out_duration), 0, "crossfade fade out duration", NULL},
-    {1, S_O(crossfade_fade_out_mixmode), 0, "crossfade fade out mode", "crossfade,mix"},
-    {1, S_O(crossfeed), false, "crossfeed", off_on },
-    {6, S_O(crossfeed_direct_gain), 15, "crossfeed direct gain", NULL },
-    {7, S_O(crossfeed_cross_gain), 60, "crossfeed cross gain", NULL },
-    {8, S_O(crossfeed_hf_attenuation), 160, "crossfeed hf attenuation", NULL },
-    {11, S_O(crossfeed_hf_cutoff), 700, "crossfeed hf cutoff", NULL },
-
-    /* equalizer */
-    {1, S_O(eq_enabled), false, "eq enabled", off_on },
-    {8, S_O(eq_precut), 0, "eq precut", NULL },
-    /* 0..32768 Hz */
-    {15, S_O(eq_band0_cutoff), 60, "eq band 0 cutoff", NULL },
-    {15, S_O(eq_band1_cutoff), 200, "eq band 1 cutoff", NULL },
-    {15, S_O(eq_band2_cutoff), 800, "eq band 2 cutoff", NULL },
-    {15, S_O(eq_band3_cutoff), 4000, "eq band 3 cutoff", NULL },
-    {15, S_O(eq_band4_cutoff), 12000, "eq band 4 cutoff", NULL },
-    /* 0..64 (or 0.0 to 6.4) */
-    {6, S_O(eq_band0_q), 7, "eq band 0 q", NULL },
-    {6, S_O(eq_band1_q), 10, "eq band 1 q", NULL },
-    {6, S_O(eq_band2_q), 10, "eq band 2 q", NULL },
-    {6, S_O(eq_band3_q), 10, "eq band 3 q", NULL },
-    {6, S_O(eq_band4_q), 7, "eq band 4 q", NULL },
-    /* -240..240 (or -24db to +24db) */
-    {9|SIGNED, S_O(eq_band0_gain), 0, "eq band 0 gain", NULL },
-    {9|SIGNED, S_O(eq_band1_gain), 0, "eq band 1 gain", NULL },
-    {9|SIGNED, S_O(eq_band2_gain), 0, "eq band 2 gain", NULL },
-    {9|SIGNED, S_O(eq_band3_gain), 0, "eq band 3 gain", NULL },
-    {9|SIGNED, S_O(eq_band4_gain), 0, "eq band 4 gain", NULL },
-
-    /* dithering */
-    {1, S_O(dithering_enabled), false, "dithering enabled", off_on },
-#endif
-
-#ifdef HAVE_DIRCACHE
-    {1, S_O(dircache), false, "dircache", off_on },
-    {22, S_O(dircache_size), 0, NULL, NULL },
-#endif
-
-#ifdef HAVE_TAGCACHE
-#ifdef HAVE_TC_RAMCACHE
-    {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
-#endif
-    {1, S_O(tagcache_autoupdate), 0, "tagcache_autoupdate", off_on },
-#endif
-
-    {4, S_O(default_codepage), 0, "default codepage",
-        "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
-
-    {1, S_O(warnon_erase_dynplaylist), false,
-        "warn when erasing dynamic playlist", off_on },
-
-#ifdef CONFIG_BACKLIGHT
-#ifdef HAS_BUTTON_HOLD
-    {2, S_O(backlight_on_button_hold), 0, "backlight on button hold",
-        "normal,off,on" },
-#endif
-
-#ifdef HAVE_LCD_SLEEP
-    {4, S_O(lcd_sleep_after_backlight_off), 3,
-        "lcd sleep after backlight off",
-        "always,never,5,10,15,20,30,45,60,90" },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-
-#ifdef HAVE_WM8758
-    {1, S_O(eq_hw_enabled), false, "eq hardware enabled", off_on },
-    
-    {2, S_O(eq_hw_band0_cutoff), 1, "eq hardware band 0 cutoff", "80Hz,105Hz,135Hz,175Hz" },
-    {5|SIGNED, S_O(eq_hw_band0_gain), 0, "eq hardware band 0 gain", NULL },
-
-    {2, S_O(eq_hw_band1_center), 1, "eq hardware band 1 center", "230Hz,300Hz,385Hz,500Hz" },
-    {1, S_O(eq_hw_band1_bandwidth), 0, "eq hardware band 1 bandwidth", "narrow,wide" },
-    {5|SIGNED, S_O(eq_hw_band1_gain), 0, "eq hardware band 1 gain", NULL },
-
-    {2, S_O(eq_hw_band2_center), 1, "eq hardware band 2 center", "650Hz,850Hz,1.1kHz,1.4kHz" },
-    {1, S_O(eq_hw_band2_bandwidth), 0, "eq hardware band 2 bandwidth", "narrow,wide" },
-    {5|SIGNED, S_O(eq_hw_band2_gain), 0, "eq hardware band 2 gain", NULL },
-
-    {2, S_O(eq_hw_band3_center), 1, "eq hardware band 3 center", "1.8kHz,2.4kHz,3.2kHz,4.1kHz" },
-    {1, S_O(eq_hw_band3_bandwidth), 0, "eq hardware band 3 bandwidth", "narrow,wide" },
-    {5|SIGNED, S_O(eq_hw_band3_gain), 0, "eq hardware band 3 gain", NULL },
-
-    {2, S_O(eq_hw_band4_cutoff), 1, "eq hardware band 4 cutoff", "5.3kHz,6.9kHz,9kHz,11.7kHz" },
-    {5|SIGNED, S_O(eq_hw_band4_gain), 0, "eq hardware band 4 gain", NULL },
-#endif
-    {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on },
-
-    {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" },
-#ifdef HAVE_AGC
-    {4, S_O(rec_agc_preset_mic), 1, "agc mic preset", NULL}, /* 0...5 */
-    {4, S_O(rec_agc_preset_line), 1, "agc line preset", NULL}, /* 0...5 */
-    {8|SIGNED, S_O(rec_agc_maxgain_mic), 104, "agc maximum mic gain", NULL},
-    {8|SIGNED, S_O(rec_agc_maxgain_line), 96, "agc maximum line gain", NULL},
-    {3, S_O(rec_agc_cliptime), 1, "agc cliptime", "0.2s,0.4s,0.6s,0.8,1s"},
-#endif
-
-#ifdef HAVE_REMOTE_LCD
-#ifdef HAS_REMOTE_BUTTON_HOLD
-    {2, S_O(remote_backlight_on_button_hold), 0, "remote backlight on button hold",
-        "normal,off,on" },
-#endif
-#endif
-
-#ifdef HAVE_HEADPHONE_DETECTION
-    {2, S_O(unplug_mode), 0, "pause on headphone unplug", NULL},
-    {4, S_O(unplug_rw), 0, "rewind duration on pause", NULL},
-    {1, S_O(unplug_autoresume), 0, "disable autoresume if phones not present", off_on },
-#endif
-#ifdef CONFIG_TUNER
-    {2, S_O(fm_region), 0, "fm_region", "eu,us,jp,kr" },
-#endif
-
-    {1, S_O(audioscrobbler), false, "Last.fm Logging", off_on},
-
-    /* If values are just added to the end, no need to bump the version. */
-    /* new stuff to be added at the end */
-#ifdef HAVE_RECORDING
-    {2, S_O(rec_trigger_type), 0, "trigger type", "stop,pause,nf stp"},
-#endif
-
-    /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
-};
-
-/* helper function to extract n (<=32) bits from an arbitrary position
- * counting from LSB to MSB */
-static uint32_t get_bits(
-    const uint32_t *p, /* the start of the bitfield array */
-    unsigned int from, /* bit no. to start reading from */
-    unsigned int size) /* how many bits to read */
-{
-    unsigned int long_index = from / 32;
-    unsigned int bit_index = from % 32;
-    uint32_t result;
-
-    result = p[long_index] >> bit_index;
-
-    if (bit_index + size > 32)     /* crossing longword boundary */
-        result |= p[long_index+1] << (32 - bit_index);
-
-    result &= 0xFFFFFFFF >> (32 - size);
-
-    return result;
+        strcpy(persistant_variables[persistant_vars_count].value,value);
+        persistant_variables[persistant_vars_count].offset = item->setting_offset;
+        persistant_vars_count++;
+    }
 }
 
-/* helper function to set n (<=32) bits to an arbitrary position,
- * counting from LSB to MSB */
-static void set_bits(
-    uint32_t *p,       /* the start of the bitfield array */
-    unsigned int from, /* bit no. to start writing into */
-    unsigned int size, /* how many bits to change */
-    uint32_t value)    /* content (LSBs will be taken) */
-{
-    unsigned int long_index = from / 32;
-    unsigned int bit_index = from % 32;
-    uint32_t mask;
-
-    mask = 0xFFFFFFFF >> (32 - size);
-    value &= mask;
-    mask <<= bit_index;
-
-    if (bit_index + size > 32)
-        p[long_index+1] =
-            (p[long_index+1] & (0xFFFFFFFF << (bit_index + size - 32)))
-            | (value >> (32 - bit_index));
+#define get_pointer_to_gs(v) &((uint8_t *)&global_settings)[v]
 
-    p[long_index] = (p[long_index] & ~mask) | (value << bit_index);
-}
 
 #ifdef HAVE_LCD_COLOR
 /*
@@ -772,301 +169,31 @@
 }
 #endif
 
-/*
- * Calculates the checksum for the config block and returns it
- */
-
-static unsigned short calculate_config_checksum(const unsigned char* buf)
-{
-    unsigned int i;
-    unsigned char cksum[2];
-    cksum[0] = cksum[1] = 0;
-
-    for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) {
-        cksum[0] ^= buf[i];
-        cksum[1] ^= buf[i+1];
-    }
-
-    return (cksum[0] << 8) | cksum[1];
-}
-
-/*
- * initialize the config block buffer
- */
-static void init_config_buffer( void )
-{
-    DEBUGF( "init_config_buffer()\n" );
-
-    /* reset to 0 - all unused */
-    memset(config_block, 0, CONFIG_BLOCK_SIZE);
-    /* insert header */
-    config_block[0] = 'R';
-    config_block[1] = 'o';
-    config_block[2] = 'c';
-    config_block[3] = CONFIG_BLOCK_VERSION;
-}
-
-bool flush_config_block_callback(void)
-{
-    ata_write_sectors(IF_MV2(0,) config_sector, 1, config_block);
-    return true;
-}
-/*
- * save the config block buffer to disk or RTC RAM
- */
-static int save_config_buffer( void )
-{
-    unsigned short chksum;
-#ifdef HAVE_RTC_RAM
-    unsigned int i;
-#endif
-
-    /* update the checksum in the end of the block before saving */
-    chksum = calculate_config_checksum(config_block);
-    config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8;
-    config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff;
-
-#ifdef HAVE_RTC_RAM
-    /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
-       that it would write a number of bytes at a time since the RTC chip
-       supports that, but this will have to do for now 8-) */
-    for (i=0; i < RTC_BLOCK_SIZE; i++ ) {
-        int r = rtc_write(0x14+i, config_block[i]);
-        if (r) {
-            DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
-                    14+i, r );
-            return r;
-        }
-    }
-
-#endif
-
-    if (config_sector != 0)
-        register_ata_idle_func(flush_config_block_callback);
-    else
-        return -1;
-
-    return 0;
-}
-
-/*
- * load the config block buffer from disk or RTC RAM
- */
-static int load_config_buffer(int which)
+void write_settings_to_disk(void)
 {
-    unsigned short chksum;
-    bool correct = false;
-
-
-    DEBUGF( "load_config_buffer()\n" );
-
-    if (which & SETTINGS_HD)
-    {
-        if (config_sector != 0) {
-            ata_read_sectors(IF_MV2(0,) config_sector, 1,  config_block);
-            /* calculate the checksum, check it and the header */
-            chksum = calculate_config_checksum(config_block);
-
-            if (config_block[0] == 'R' &&
-                config_block[1] == 'o' &&
-                config_block[2] == 'c' &&
-                config_block[3] == CONFIG_BLOCK_VERSION &&
-                (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] &&
-                (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1])
-            {
-                DEBUGF( "load_config_buffer: header & checksum test ok\n" );
-                correct = true;
-            }
-        }
-    }
-
-#ifdef HAVE_RTC_RAM
-    if(!correct)
-    {
-        /* If the disk sector was incorrect, reinit the buffer */
-        memset(config_block, 0, CONFIG_BLOCK_SIZE);
-    }
-
-    if (which & SETTINGS_RTC)
-    {
-        unsigned int i;
-        unsigned char rtc_block[RTC_BLOCK_SIZE];
-
-        /* read rtc block */
-        for (i=0; i < RTC_BLOCK_SIZE; i++ )
-            rtc_block[i] = rtc_read(0x14+i);
-
-        chksum = calculate_config_checksum(rtc_block);
-
-        /* if rtc block is ok, use that */
-        if (rtc_block[0] == 'R' &&
-            rtc_block[1] == 'o' &&
-            rtc_block[2] == 'c' &&
-            rtc_block[3] == CONFIG_BLOCK_VERSION &&
-            (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] &&
-            (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1])
-        {
-            memcpy(config_block, rtc_block, RTC_BLOCK_SIZE);
-            correct = true;
-        }
-    }
+#ifndef SIMULATOR
+    if (ata_disk_is_active())
+        settings_save_config(ROCKBOX_CONFIGFILE);
+    else 
 #endif
-
-    if ( !correct ) {
-        /* if checksum is not valid, clear the config buffer */
-        DEBUGF( "load_config_buffer: header & checksum test failed\n" );
-        init_config_buffer();
-        return -1;
-    }
-
-    return 0;
-}
-
-
-/* helper to save content of global_settings into a bitfield,
-   as described per table */
-static void save_bit_table(const struct bit_entry* p_table, int count, int bitstart)
-{
-    uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
-    uint32_t value; /* 32 bit content */
-    int i;
-    const struct bit_entry* p_run = p_table; /* start after the size info */
-    int curr_bit = bitstart + p_table->bit_size;
-    count--; /* first is excluded from loop */
-
-    for (i=0; i<count; i++)
-    {
-        p_run++;
-        /* could do a memcpy, but that would be endian-dependent */
-        switch(p_run->byte_size)
-        {
-        case 1:
-            value = ((uint8_t *)&global_settings)[p_run->settings_offset];
-            break;
-        case 2:
-            value = ((uint16_t *)&global_settings)[p_run->settings_offset/2];
-            break;
-        case 4:
-            value = ((uint32_t *)&global_settings)[p_run->settings_offset/4];
-            break;
-        default:
-            DEBUGF( "save_bit_table: illegal size!\n" );
-            continue;
-        }
-        set_bits(p_bitfield, curr_bit, p_run->bit_size & 0x3F, value);
-        curr_bit += p_run->bit_size & 0x3F;
-    }
-    set_bits(p_bitfield, bitstart, p_table->bit_size, /* write size */
-        curr_bit); /* = position after last element */
+        settings_save();
 }
 
-/*
- * figure out the config sector from the partition table and the
- * mounted file system
- */
-void settings_calc_config_sector(void)
+bool settings_save_ata_cb( void )
 {
-#ifdef SIMULATOR
-    config_sector = 61;
+#ifndef SIMULATOR
+    queue_broadcast(SYS_DUMPSETTINGS,0); /*hopefully only the main thread 
+                                           will accept use this, so it 
+                                           shouldnt stkOv! */
 #else
-    int i;
-    long partition_start;
-    long sector = 0;
-
-    if (fat_startsector(IF_MV(0)) != 0)    /* There is a partition table */
-    {
-        sector = 61;
-        for (i = 0; i < 4; i++)
-        {
-            partition_start = disk_partinfo(i)->start;
-            if (partition_start != 0 && (partition_start - 2) < sector)
-                sector = partition_start - 2;
-        }
-        if (sector < 0)
-            sector = 0;
-    }
-
-    config_sector = sector;
+    write_settings_to_disk();
 #endif
+    return 0;
 }
 
-/*
- * persist all runtime user settings to disk or RTC RAM
- */
 int settings_save( void )
 {
-    int i;
-
-    {
-        int elapsed_secs;
-
-        elapsed_secs = (current_tick - lasttime) / HZ;
-        global_settings.runtime += elapsed_secs;
-        lasttime += (elapsed_secs * HZ);
-
-        if ( global_settings.runtime > global_settings.topruntime )
-            global_settings.topruntime = global_settings.runtime;
-    }
-
-    /* serialize scalar values into RTC and HD sector, specified via table */
-    save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
-    save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8);
-
-    i = 0xb8;
-    strncpy((char *)&config_block[i], (char *)global_settings.wps_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-    strncpy((char *)&config_block[i], (char *)global_settings.lang_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-    strncpy((char *)&config_block[i], (char *)global_settings.font_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-#ifdef HAVE_REMOTE_LCD
-    strncpy((char *)&config_block[i], (char *)global_settings.rwps_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-#endif
-
-#ifdef CONFIG_TUNER
-    strncpy((char *)&config_block[i], (char *)global_settings.fmr_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-#endif
-
-#if LCD_DEPTH > 1
-    strncpy((char *)&config_block[i], (char *)global_settings.backdrop_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-#endif
-#ifdef HAVE_LCD_BITMAP
-    strncpy((char *)&config_block[i], (char *)global_settings.kbd_file,
-            MAX_FILENAME);
-    i+= MAX_FILENAME;
-#endif
-
-    if(save_config_buffer())
-    {
-        lcd_clear_display();
-#ifdef HAVE_REMOTE_LCD
-        lcd_remote_clear_display();
-#endif
-#ifdef HAVE_LCD_CHARCELLS
-        lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER));
-        lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER));
-#else
-        lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
-        lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
-        lcd_update();
-#ifdef HAVE_REMOTE_LCD
-        lcd_remote_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
-        lcd_remote_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
-        lcd_remote_update();
-#endif
-#endif
-        sleep(HZ*2);
-        return -1;
-    }
+    register_ata_idle_func(settings_save_ata_cb);
     return 0;
 }
 
@@ -1126,7 +253,7 @@
 
 void settings_apply(void)
 {
-    char buf[64];
+    char buf[MAX_PATH];
 #if CONFIG_CODEC == SWCODEC
     int i;
 #endif
@@ -1326,130 +453,202 @@
 #endif
 }
 
-
-/* helper to load global_settings from a bitfield, as described per table */
-static void load_bit_table(const struct bit_entry* p_table, int count, int bitstart)
+void save_item_to_gs(const struct settings_list *item, char* new_val)
 {
-    uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
-    uint32_t value; /* 32 bit content */
-    int i;
-    int maxbit; /* how many bits are valid in the saved part */
-    const struct bit_entry* p_run = p_table; /* start after the size info */
-    count--; /* first is excluded from loop */
-    maxbit = get_bits(p_bitfield, bitstart, p_table->bit_size);
-    bitstart += p_table->bit_size;
-
-    for (i=0; i<count; i++)
+    switch (item->flags&F_T_MASK)
     {
-        int size;
-        p_run++;
-
-        size = p_run->bit_size & 0x3F; /* mask off abused bits */
-        if (bitstart + size > maxbit)
-            break; /* exit if this is not valid any more in bitfield */
-
-        value = get_bits(p_bitfield, bitstart, size);
-        bitstart += size;
-        if (p_run->bit_size & SIGNED)
-        {   // sign extend the read value
-            unsigned long mask = 0xFFFFFFFF << (size - 1);
-            if (value & mask) /* true if MSB of value is set */
-                value |= mask;
-        }
-
-        /* could do a memcpy, but that would be endian-dependent */
-        switch(p_run->byte_size)
-        {
-        case 1:
-            ((uint8_t *)&global_settings)[p_run->settings_offset] =
-                (unsigned char)value;
+        case F_T_INT:
+#ifdef HAVE_LCD_COLOR
+            if (item->flags&F_STORERGB)
+            {
+                *(int*)get_pointer_to_gs(item->setting_offset) = hex_to_rgb(new_val);
+            }
+            else 
+#endif
+                 if (item->flags&F_STOREREALVALUE)
+                        *(int*)get_pointer_to_gs(item->setting_offset)
+                        = atoi(new_val);
+            else if (item->flags&F_T_CHOICE)
+            {
+                int i;
+                if (item->flags&F_LANG_STRING)
+                {
+                    for (i=0;i<item->nb_values;i++)
+                    {
+                        if (!strcmp(new_val, item->strings[i]))
+                        {
+                            *(int*)get_pointer_to_gs(item->setting_offset) = i;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    char *start, *end;
+                    int len = strlen(new_val);
+                    start = strchr(item->conf_file_info,',');
+                    if (!start)
+                        break;
+                    end = strchr(++start,',');
+                    i = 0;
+                    while (start)
+                    {
+                        if (!strncmp(start,new_val, MAX(((end?end:0)-start),len)))
+                        {
+                            *(int*)get_pointer_to_gs(item->setting_offset) = i;
+                            break;
+                        }
+                        i++;
+                        start = end+1;
+                        if (end)
+                            end = strchr(++end,',');
+                    }
+                }
+            }
+            else *(int*)get_pointer_to_gs(item->setting_offset) = atoi(new_val);
             break;
-        case 2:
-            ((uint16_t *)&global_settings)[p_run->settings_offset/2] =
-                (unsigned short)value;
+        case F_T_UINT:
+            *(unsigned int*)get_pointer_to_gs(item->setting_offset) = 
+                    (unsigned int)atoi(new_val);
             break;
-        case 4:
-            ((uint32_t *)&global_settings)[p_run->settings_offset/4] =
-                (unsigned int)value;
+        case F_T_BOOL:
+            if (!strcmp(new_val,"on"))
+                *(bool*)get_pointer_to_gs(item->setting_offset) = true;
+            else *(bool*)get_pointer_to_gs(item->setting_offset) = false;
+            break;
+        case F_T_CHARPTR:
+        case F_T_UCHARPTR:
+            if (item->flags&F_FILENAMEONLY && 
+                strrchr(new_val,'/'))
+            {
+                set_file(new_val,
+                         (char*)get_pointer_to_gs(item->setting_offset),MAX_FILENAME);
+            }
+            else strcpy((char*)get_pointer_to_gs(item->setting_offset),new_val);
             break;
-        default:
-            DEBUGF( "load_bit_table: illegal size!\n" );
-            continue;
-        }
     }
 }
+bool check_setting_name(char* from_file, char* in_settings)
+{
+    int len = strlen(from_file);
+    return !strncmp(from_file,in_settings,len) &&
+            ( ( in_settings[len] == ',') ||
+                    ( in_settings[len] == '\0'));
+}
+
+bool settings_load_config(const char* file)
+{
+    int fd;
+    char line[256];
+    char* name;
+    char* value;
+    int pos; /* currently returned position */
+    const struct settings_list *item;
+    bool persistant = false;
+    
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+        return false;
+
+    while (read_line(fd, line, sizeof line) > 0)
+    {
+        if (!settings_parseline(line, &name, &value))
+            continue;
 
+        if (name[0] == '~') /* load the value, and donot save the new value to disk */
+        {
+            persistant = true;
+            name++;
+        }
+        else persistant = false;
+
+        for (pos = 0; pos < nb_settings ; pos++)
+        {
+            item = &settings[pos];
+            
+            if (item->flags&(F_SYSTEMSETTING|F_T_CHARPTR|F_LANG_IS_STRING))
+            {
+                if (!strcmp(name,item->cfg_string))
+                {
+                    if (persistant)
+                        add_to_persistant(item,value);
+                    save_item_to_gs(item,value);
+                    break;
+                }
+            }
+            else if (check_setting_name(name,item->conf_file_info))
+            {
+                if (persistant)
+                    add_to_persistant(item,value);
+                save_item_to_gs(item,value);
+                break;
+            }
+        } /* for (...) */
+    }
 
+    close(fd);
+    settings_apply();
+    return true;
+}
+#ifdef HAVE_RTC_RAM
+bool load_from_rtc(int rtc_item, int *value)
+{
+    if (!rtc_read_multiple(0x14+(rtc_item*4),(char*)value,4))
+        return true;
+    return false;
+}
+    
+bool save_to_rtc(int rtc_item, int value)
+{
+    union { int i; char c[4]; } storage;
+    int j = 0;
+    int ret=0, address = 0x14+(rtc_item*4);
+    storage.i = value;
+    for(j=0; j<4 && ret==0;j++)
+    {
+        ret = rtc_write(address+j, storage.c[j]);
+    }
+    return (ret==0) ? true : false;
+}
+#endif
 /*
  * load settings from disk or RTC RAM
  */
 void settings_load(int which)
 {
-    int i;
     DEBUGF( "reload_all_settings()\n" );
-
-    /* load the buffer from the RTC (resets it to all-unused if the block
-       is invalid) and decode the settings which are set in the block */
-    if (!load_config_buffer(which))
+    if (which&SETTINGS_RTC)
     {
-        /* load scalar values from RTC and HD sector, specified via table */
-        if (which & SETTINGS_RTC)
+        int i, value, rtc_item = 0;
+        bool config_ok = false;
+        if (load_from_rtc(rtc_item,&value) == true)
         {
-            load_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
+            if (value == RTC_RAM_CONFIG_VERSION)
+                config_ok = true;
         }
-        if (which & SETTINGS_HD)
+        rtc_item++;
+        for (i=0; i<nb_settings; i++)
         {
-            load_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]),
-                RTC_BLOCK_SIZE*8);
+            if (settings[i].flags&F_SAVETORTC)
+            {
+                if (config_ok == true)
+                {
+                    if (load_from_rtc(rtc_item++,
+                        (int*)get_pointer_to_gs(settings[i].setting_offset)) == false)
+                    {
+                        *(int*)get_pointer_to_gs(settings[i].setting_offset)
+                                = settings[i].default_val.int_;
+                    }
+                }
+                else *(int*)get_pointer_to_gs(settings[i].setting_offset)
+                            = settings[i].default_val.int_;
+            }
         }
-
-#ifdef HAVE_RECORDING
-    global_settings.recscreen_on = false;
-#endif
-
-#ifdef HAVE_LCD_CONTRAST
-        if ( global_settings.contrast < MIN_CONTRAST_SETTING ||
-             global_settings.contrast > MAX_CONTRAST_SETTING )
-            global_settings.contrast = lcd_default_contrast();
-#endif
-
-#ifdef HAVE_LCD_REMOTE
-        if (global_settings.remote_contrast < MIN_REMOTE_CONTRAST_SETTING ||
-            global_settings.remote_contrast > MAX_REMOTE_CONTRAST_SETTING )
-            global_settings.remote_contrast = lcd_remote_default_contrast();
-#endif
-        i = 0xb8;
-        strncpy((char *)global_settings.wps_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-        strncpy((char *)global_settings.lang_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-        strncpy((char *)global_settings.font_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-#ifdef HAVE_REMOTE_LCD
-        strncpy((char *)global_settings.rwps_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-#endif
-
-#ifdef CONFIG_TUNER
-        strncpy((char *)global_settings.fmr_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-#endif
-
-#if LCD_DEPTH > 1
-        strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
-#endif
-#ifdef HAVE_LCD_BITMAP
-        strncpy((char *)global_settings.kbd_file, (char *)&config_block[i],
-                MAX_FILENAME);
-        i+= MAX_FILENAME;
+    }
 #endif
+    if (which&SETTINGS_HD)
+    {
+        settings_load_config(ROCKBOX_CONFIGFILE);
     }
 }
 
@@ -1480,443 +679,209 @@
 
     strncpy(setting, fptr, len-extlen);
     setting[len-extlen]=0;
-
     settings_save();
 }
 
-/* helper to sort a .cfg file entry into a global_settings member,
-   as described per table. Returns the position if found, else 0. */
-static int load_cfg_table(
-    const struct bit_entry* p_table, /* the table which describes the entries */
-    int count, /* number of entries in the table, including the first */
-    const char* name, /* the item to be searched */
-    const char* value, /* the value which got loaded for that item */
-    int hint) /* position to start looking */
+/*
+ * reset all settings to their default value
+ */
+void settings_reset(void) 
 {
-    int i = hint;
+    int i; 
+    const struct settings_list *item;
+    DEBUGF( "settings_reset()\n" );
 
-    do
+    for (i = 0; i < nb_settings ; i++)
     {
-        if (p_table[i].cfg_name != NULL && !strcasecmp(name, p_table[i].cfg_name))
-        { /* found */
-            int val = 0;
-            if (p_table[i].cfg_val == NULL)
-            {   /* numerical value, just convert the string */
-                val = atoi(value);
-            }
-#if HAVE_LCD_COLOR
-            else if (!strncasecmp(p_table[i].cfg_val,"rgb",4))
-            {
-                val = hex_to_rgb(value);
-            }
-#endif
-            else
-            {   /* set of string values, find the index */
-                const char* item;
-                const char* run;
-                int len = strlen(value);
-
-                item = run = p_table[i].cfg_val;
-
-                while(1)
-                {
-                    /* count the length of the field */
-                    while (*run != ',' && *run != '\0')
-                        run++;
-
-                    if (!strncasecmp(value, item, MAX(run-item, len)))
-                        break; /* match, exit the search */
-
-                    if (*run == '\0') /* reached the end of the choices */
-                        return i; /* return the position, but don't update */
-
-                    val++; /* count the item up */
-                    run++; /* behind the ',' */
-                    item = run;
-                }
-            }
-
-            /* could do a memcpy, but that would be endian-dependent */
-            switch(p_table[i].byte_size)
-            {
-            case 1:
-                ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
-                    (unsigned char)val;
+        item = &settings[i];         
+        if (item->flags&F_T_SOUND)
+        {
+            *(int*)get_pointer_to_gs(item->setting_offset)
+                    = sound_default(item->values[0]);
+            continue;
+        }
+        switch (item->flags&F_T_MASK)
+        {
+            case F_T_INT:
+                *(int*)get_pointer_to_gs(item->setting_offset)
+                        = item->default_val.int_;
                 break;
-            case 2:
-                ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
-                    (unsigned short)val;
+            case F_T_UINT:
+                *(unsigned int*)get_pointer_to_gs(item->setting_offset)
+                        = item->default_val.uint_;
                 break;
-            case 4:
-                ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
-                    (unsigned int)val;
+            case F_T_BOOL:
+                *(bool*)get_pointer_to_gs(item->setting_offset)
+                        = item->default_val.bool_;
+                break;
+            case F_T_CHARPTR:
+            case F_T_UCHARPTR:
+                strcpy((char*)get_pointer_to_gs(item->setting_offset),
+                        item->default_val.charptr);
                 break;
-            default:
-                DEBUGF( "illegal size!" );
-                continue;
-            }
-
-            return i; /* return the position */
         }
-
-        i++;
-        if (i==count)
-            i=1; /* wraparound */
-    } while (i != hint); /* back where we started, all searched */
-
-    return 0; /* indicate not found */
+    } /* for (...) */
 }
 
-
-bool settings_load_config(const char* file)
+bool settings_save_config(const char* filename)
 {
     int fd;
-    char line[128];
+    int i, value = 0, type;
+    int j;
+    bool persistant = false;
+    char name[256], *char_value;
+    const struct settings_list *item;
+    
+#ifdef HAVE_RTC_RAM
+    j = 0;
+    save_to_rtc(j++, RTC_RAM_CONFIG_VERSION);
+    for (i=0; i<nb_settings; i++)
+    {
+        if (settings[i].flags&F_SAVETORTC)
+        {
+            value = *(int*)get_pointer_to_gs(settings[i].setting_offset);
+            save_to_rtc(j++, value);
+        }
+    }
+#endif
 
-    fd = open(file, O_RDONLY);
+    fd = creat(filename, O_WRONLY);
     if (fd < 0)
         return false;
-
-    while (read_line(fd, line, sizeof line) > 0)
+    
+    fdprintf(fd, "#\r\n# .cfg file created by rockbox %s - "
+            "http://www.rockbox.org\r\n#\r\n\r\n", appsversion);
+    
+    for (i=0; i < nb_settings; i++)
     {
-        char* name;
-        char* value;
-        const struct bit_entry* table[2] = { rtc_bits, hd_bits };
-        const int ta_size[2] = {
-            sizeof(rtc_bits)/sizeof(rtc_bits[0]),
-            sizeof(hd_bits)/sizeof(hd_bits[0])
-        };
-        int last_table = 0; /* which table was used last round */
-        int last_pos = 1; /* at which position did we succeed */
-        int pos; /* currently returned position */
-
-        if (!settings_parseline(line, &name, &value))
-            continue;
-
-        /* check for the string values */
-        if (!strcasecmp(name, "wps")) {
-#if LCD_DEPTH > 1
-            unload_wps_backdrop();
-#endif
-            int fd2;
-            if ((fd2 = open(value, O_RDONLY)) >= 0) {
-                close(fd2);
-                set_file(value, (char *)global_settings.wps_file, MAX_FILENAME);
-            }
-        }
-#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
-        else if (!strcasecmp(name, "rwps")) {
-            int fd2;
-            if ((fd2 = open(value, O_RDONLY)) >= 0) {
-                close(fd2);
-                set_file(value, (char *)global_settings.rwps_file, MAX_FILENAME);
-            }
-        }
-#endif
-        else if (!strcasecmp(name, "lang")) {
-            if (!lang_load(value))
+        persistant = false;
+        item = &settings[i];
+        type = item->flags&F_T_MASK;
+        if (item->flags&F_LANG_IS_STRING)
+            strcpy(name,item->cfg_string);
+        else 
+        {
+            char *p = strchr(item->conf_file_info,',');
+            if (p)
             {
-                set_file(value, (char *)global_settings.lang_file, MAX_FILENAME);
-                talk_init(); /* use voice of same language */
+                strncpy(name,item->conf_file_info,p-item->conf_file_info);
+                name[p-item->conf_file_info] = '\0';
             }
+            else strcpy(name,item->conf_file_info);
         }
-#ifdef CONFIG_TUNER
-        else if (!strcasecmp(name, "fmr")) {
-            set_file(value, global_settings.fmr_file, MAX_FILENAME);
-        }
-#endif
-#ifdef HAVE_LCD_BITMAP
-        else if (!strcasecmp(name, "font")) {
-            if (font_load(value))
-                set_file(value, (char *)global_settings.font_file, MAX_FILENAME);
-        }
-#endif
-#if LCD_DEPTH > 1
-        else if (!strcasecmp(name, "backdrop")) {
-            if (load_main_backdrop(value)) {
-                set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME);
-                show_main_backdrop();
-            }
-        }
-#endif
-#ifdef HAVE_LCD_BITMAP
-        else if (!strcasecmp(name, "keyboard")) {
-            if (!load_kbd(value))
-                set_file(value, (char *)global_settings.kbd_file, MAX_FILENAME);
-        }
-#endif
-
-
-        /* check for scalar values, using the two tables */
-        pos = load_cfg_table(table[last_table], ta_size[last_table],
-            name, value, last_pos);
-        if (pos) /* success */
-        {
-            last_pos = pos; /* remember as a position hint for next round */
-            continue;
-        }
-
-        last_table = 1-last_table; /* try other table */
-        last_pos = 1; /* search from start */
-        pos = load_cfg_table(table[last_table], ta_size[last_table],
-            name, value, last_pos);
-        if (pos) /* success */
-        {
-            last_pos = pos; /* remember as a position hint for next round */
-            continue;
-        }
-    }
-
-    close(fd);
-    settings_apply();
-    settings_save();
-    return true;
-}
-
-
-/* helper to save content of global_settings into a file,
-   as described per table */
-static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
-{
-    long value; /* 32 bit content */
-    int i;
-    const struct bit_entry* p_run = p_table; /* start after the size info */
-    count--; /* first is excluded from loop */
-
-    for (i=0; i<count; i++)
-    {
-        p_run++;
-
-        if (p_run->cfg_name == NULL)
-            continue; /* this value is not to be saved */
+        DEBUGF("%d, %s\n",i,name);
+        
+        char_value = NULL;
 
-        /* could do a memcpy, but that would be endian-dependent */
-        switch(p_run->byte_size)
+        for (j=0; j<persistant_vars_count; j++)
         {
-        case 1:
-            if (p_run->bit_size & SIGNED) /* signed? */
-                value = ((char*)&global_settings)[p_run->settings_offset];
-            else
-                value = ((unsigned char*)&global_settings)[p_run->settings_offset];
-            break;
-        case 2:
-            if (p_run->bit_size & SIGNED) /* signed? */
-                value = ((short*)&global_settings)[p_run->settings_offset/2];
-            else
-                value = ((unsigned short*)&global_settings)[p_run->settings_offset/2];
-            break;
-        case 4:
-            value = ((unsigned int*)&global_settings)[p_run->settings_offset/4];
-            break;
-        default:
-            DEBUGF( "illegal size!" );
-            continue;
+            if (persistant_variables[j].offset == item->setting_offset)
+            {
+                persistant = true;
+                char_value = persistant_variables[j].value;
+                break;
+            }
         }
 
-        if (p_run->cfg_val == NULL) /* write as number */
+        if (persistant == false)
         {
-            fdprintf(fd, "%s: %ld\r\n", p_run->cfg_name, value);
-        }
+            switch (type)
+            {
+                case F_T_INT:
+                    value = *(int*)get_pointer_to_gs(item->setting_offset);
+        /*            DEBUGF("%d\n",value);
+                    if ((item->flags&(F_T_CHOICE|F_SYSTEMSETTING|
+                            F_STORERGB|F_T_SOUND|F_STOREREALVALUE)) == 0)
+                        fdprintf(fd,"# %s%s - min=%d, max=%d, step=%d\r\n",
+                            prefix,name,item->values[0],item->values[1],
+                            item->values[2]);
+                    */      break;
+                case F_T_UINT:
+                    value = *(unsigned int*)get_pointer_to_gs(item->setting_offset);
+            /*        if ((item->flags&(F_T_CHOICE|F_SYSTEMSETTING|
+                            F_STORERGB|F_T_SOUND|F_STOREREALVALUE)) == 0)
+                        fdprintf(fd,"# %s%s - min=%d, max=%d, step=%d\r\n",
+                            prefix,name,
+                                item->values[0],item->values[1],item->values[2]);
+                    */    break;
+                case F_T_BOOL:
+                    char_value = 
+                            (*(bool*)get_pointer_to_gs(item->setting_offset)==true)?
+                                    "on":"off";
+            //       fdprintf(fd,"# %s%s - on, off\r\n",prefix,name);
+                    break;
+                case F_T_CHARPTR:
+                case F_T_UCHARPTR:
+                    char_value = (char*)get_pointer_to_gs(item->setting_offset);
+                    break;
+            }
+            if ((item->flags&F_T_CHOICE) && ((item->flags&F_STOREREALVALUE) == 0))
+            {
+        /*      fdprintf(fd,"# %s%s - ",prefix, name);
+                for(j=0; j < item->nb_values; j++)
+                {
+                    fdprintf(fd,"%s%c ",(item->flags&F_LANG_STRING)?item->strings[j]:english_str(item->values[j]),
+                                    (j+1 < item->nb_values)?',':'\0' );
+                }
+                fdprintf(fd,"\r\n");
+                */    
+                if (item->flags&F_LANG_STRING)
+                {
+                    char_value = item->strings[value];
+                }
+                else 
+                {
+                    char *p;
+                    p = strchr(item->conf_file_info,',');
+                    if (p)
+                    {
+                        p++;
+                        for(j=0;j<value && *p;j++)
+                        {
+                            while (*p != ',' && *p)
+                                p++;
+                            if (*p) p++; /* skip over the comma */
+                        }
+                        char_value = p;
+                    }
+                    else char_value = item->conf_file_info;
+                }
+            }
+        } /* if (!persistant) */
+        
 #ifdef HAVE_LCD_COLOR
-        else if (!strcasecmp(p_run->cfg_val, "rgb"))
+        if (item->flags&F_STORERGB && char_value==NULL)
         {
-            fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
-                                                 (int)RGB_UNPACK_RED(value),
-                                                 (int)RGB_UNPACK_GREEN(value),
-                                                 (int)RGB_UNPACK_BLUE(value));
+            fdprintf(fd, "# %s - RRGGBB (hex values)\r\n%s: %02x%02x%02x\r\n",
+                    name,name,
+                    (int)RGB_UNPACK_RED(value),
+                    (int)RGB_UNPACK_GREEN(value),
+                    (int)RGB_UNPACK_BLUE(value));
         }
+        else 
 #endif
-        else /* write as item */
+        if (char_value == NULL)
         {
-            const char* p = p_run->cfg_val;
-
-            fdprintf(fd, "%s: ", p_run->cfg_name);
-
-            while(value >= 0)
+            fdprintf(fd,"%c%s: %d\r\n",(persistant == true)?'~':'\0',
+                     name, value);
+        }
+        else
+        {
+            char *p = strchr(char_value,',');
+            char text[128];
+            if (p)
             {
-                char c = *p++; /* currently processed char */
-                if (c == ',') /* separator */
-                    value--;
-                else if (c == '\0') /* end of string */
-                    break; /* not found */
-                else if (value == 0) /* the right place */
-                    write(fd, &c, 1); /* char by char, this is lame, OK */
+                strncpy(text,char_value,p-char_value);
+                text[p-char_value] = '\0';
             }
-
-            fdprintf(fd, "\r\n");
-            if (p_run->cfg_val != off_on) /* explaination for non-bool */
-                fdprintf(fd, "# (possible values: %s)\r\n", p_run->cfg_val);
-        }
-    }
-}
-
-bool settings_save_config(void)
-{
-    int fd;
-    char filename[MAX_PATH];
-
-    create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2
-                             IF_CNFN_NUM_(, NULL));
-
-    /* allow user to modify filename */
-    while (true) {
-        if (!kbd_input(filename, sizeof filename)) {
-            fd = creat(filename, O_WRONLY);
-            if (fd < 0)
-                gui_syncsplash(HZ, true, str(LANG_FAILED));
-            else
-                break;
-        }
-        else {
-            gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL));
-            return false;
+            else strcpy(text,char_value);
+            fdprintf(fd,"%c%s: %s\r\n",(persistant == true)?'~':'\0',
+                    name, text);
         }
-    }
-
-    fdprintf(fd, "# .cfg file created by rockbox %s - "
-                 "http://www.rockbox.org\r\n#\r\n#\r\n# wps / rwps / language"
-                 " / font / fmpreset / backdrop \r\n#\r\n", appsversion);
-
-    if (global_settings.wps_file[0] != 0)
-        fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR,
-                 global_settings.wps_file);
-
-#ifdef HAVE_REMOTE_LCD
-    if (global_settings.rwps_file[0] != 0)
-        fdprintf(fd, "rwps: %s/%s.rwps\r\n", WPS_DIR,
-                 global_settings.rwps_file);
-#endif
-
-    if (global_settings.lang_file[0] != 0)
-        fdprintf(fd, "lang: %s/%s.lng\r\n", LANG_DIR,
-                 global_settings.lang_file);
-
-#ifdef HAVE_LCD_BITMAP
-    if (global_settings.font_file[0] != 0)
-        fdprintf(fd, "font: %s/%s.fnt\r\n", FONT_DIR,
-                 global_settings.font_file);
-#endif
-
-#if LCD_DEPTH > 1
-    if (global_settings.backdrop_file[0] != 0)
-        fdprintf(fd, "backdrop: %s/%s.bmp\r\n", BACKDROP_DIR,
-                 global_settings.backdrop_file);
-#endif
-
-#ifdef CONFIG_TUNER
-    if (global_settings.fmr_file[0] != 0)
-        fdprintf(fd, "fmr: %s/%s.fmr\r\n", FMPRESET_PATH,
-                 global_settings.fmr_file);
-#endif
-
-#ifdef HAVE_LCD_BITMAP
-    if (global_settings.kbd_file[0] != 0)
-        fdprintf(fd, "keyboard: %s/%s.kbd\r\n", ROCKBOX_DIR,
-                 global_settings.kbd_file);
-#endif
-
-    /* here's the action: write values to file, specified via table */
-    save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd);
-    save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd);
-
+    } /* for(...) */
     close(fd);
-
-    gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
     return true;
 }
-
-
-/* helper to load defaults from table into global_settings members */
-static void default_table(const struct bit_entry* p_table, int count)
-{
-    int i;
-
-    for (i=1; i<count; i++) /* exclude the first, the size placeholder */
-    {
-        /* could do a memcpy, but that would be endian-dependent */
-        switch(p_table[i].byte_size)
-        {
-        case 1:
-            ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
-                (unsigned char)p_table[i].default_val;
-            break;
-        case 2:
-            ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
-                (unsigned short)p_table[i].default_val;
-            break;
-        case 4:
-            ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
-                (unsigned int)p_table[i].default_val;
-            break;
-        default:
-            DEBUGF( "illegal size!" );
-            continue;
-        }
-    }
-}
-
-
-/*
- * reset all settings to their default value
- */
-void settings_reset(void) {
-
-    DEBUGF( "settings_reset()\n" );
-
-    /* read defaults from table(s) into global_settings */
-    default_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]));
-    default_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]));
-
-    /* do some special cases not covered by table */
-    global_settings.volume      = sound_default(SOUND_VOLUME);
-    global_settings.balance     = sound_default(SOUND_BALANCE);
-    global_settings.bass        = sound_default(SOUND_BASS);
-    global_settings.treble      = sound_default(SOUND_TREBLE);
-    global_settings.channel_config = sound_default(SOUND_CHANNELS);
-    global_settings.stereo_width = sound_default(SOUND_STEREO_WIDTH);
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
-    global_settings.loudness    = sound_default(SOUND_LOUDNESS);
-    global_settings.avc         = sound_default(SOUND_AVC);
-    global_settings.mdb_strength = sound_default(SOUND_MDB_STRENGTH);
-    global_settings.mdb_harmonics = sound_default(SOUND_MDB_HARMONICS);
-    global_settings.mdb_center = sound_default(SOUND_MDB_CENTER);
-    global_settings.mdb_shape = sound_default(SOUND_MDB_SHAPE);
-    global_settings.mdb_enable = sound_default(SOUND_MDB_ENABLE);
-    global_settings.superbass = sound_default(SOUND_SUPERBASS);
-#endif
-#ifdef HAVE_LCD_CONTRAST 
-    global_settings.contrast = lcd_default_contrast();
-#endif
-#ifdef HAVE_LCD_REMOTE
-    global_settings.remote_contrast = lcd_remote_default_contrast();
-#endif
-
-#ifdef CONFIG_TUNER
-    global_settings.fmr_file[0] = '\0';
-#endif
-    global_settings.wps_file[0] = '\0';
-#ifdef HAVE_REMOTE_LCD
-    global_settings.rwps_file[0] = '\0';
-#endif
-    global_settings.font_file[0] = '\0';
-    global_settings.lang_file[0] = '\0';
-#if LCD_DEPTH > 1
-    global_settings.backdrop_file[0] = '\0';
-#endif
-#ifdef HAVE_LCD_COLOR
-    global_settings.fg_color = LCD_DEFAULT_FG;
-    global_settings.bg_color = LCD_DEFAULT_BG;
-#endif
-#ifdef HAVE_LCD_BITMAP
-    global_settings.kbd_file[0] = '\0';
-#endif
-    global_settings.hold_lr_for_scroll_in_list = true;
-
-#if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
-    enc_global_settings_reset();
-#endif
-}
-
 bool set_bool(const char* string, bool* variable )
 {
     return set_bool_options(string, variable,
Index: apps/settings.h
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.h,v
retrieving revision 1.254
diff -u -r1.254 settings.h
--- apps/settings.h	13 Nov 2006 00:45:20 -0000	1.254
+++ apps/settings.h	14 Nov 2006 14:34:31 -0000
@@ -54,8 +54,10 @@
 #define REC_BASE_DIR "/recordings"
 #define EQS_DIR     ROCKBOX_DIR "/eqs"
 #define CODECS_DIR  ROCKBOX_DIR"/codecs"
+#define ROCKBOX_CONFIGFILE ROCKBOX_DIR "/config.cfg"
+
+#define MAX_FILENAME MAX_PATH
 
-#define MAX_FILENAME 20
 
 /* data structures */
 
@@ -554,7 +556,7 @@
 void settings_display(void);
 
 bool settings_load_config(const char* file);
-bool settings_save_config(void);
+bool settings_save_config(const char* filename);
 bool set_bool_options(const char* string, bool* variable,
                       const char* yes_str, int yes_voice,
                       const char* no_str, int no_voice,
Index: apps/settings_list.c
===================================================================
RCS file: apps/settings_list.c
diff -N apps/settings_list.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ apps/settings_list.c	14 Nov 2006 14:34:33 -0000
@@ -0,0 +1,956 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id:  $
+ *
+ * Copyright (C) 2006 Jonathan Gordon
+ *
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include "config.h"
+#include "lang.h"
+#include "settings.h"
+#include "sound.h"
+#include "stdio.h"
+#include "lcd.h"
+#include "talk.h"
+#include "settings_list.h"
+#include "splash.h"
+#include "kernel.h"
+
+/* files needed for the variaous option callbacks*/
+#include "playback.h"
+#include "eq_menu.h"
+#include "statusbar.h"
+#include "settings.h"
+
+/* helpful macros for hopefully this file only! */
+#define GS(a) offsetof(struct user_settings, a)
+#define _INT(...) {.values = (int[]){__VA_ARGS__}}
+#define _STR(...) {.strings = (char*[]){__VA_ARGS__}}
+#define _TALKID(...) (int[]){__VA_ARGS__}
+#define _REALVAL(s,v) (void*)s,(void*)v
+
+#define SOUND_ITEM(flags,var,name,setting, cfg)                       \
+    {flags|F_T_INT|F_T_SOUND, GS(var), {0}, {.cfg_lang_id = name}, 1, \
+    _INT(setting), NULL, NULL, cfg }
+    
+#define BOOL_ITEM(flags,var,name,default,cb, cfg)                     \
+    {flags|F_T_BOOL, GS(var), {.bool_ = default},                     \
+    {.cfg_lang_id = name}, 0,{NULL}, NULL, cb, cfg }
+    
+#define INT_ITEM(flags,var,name,default,min,max,step,unit,            \
+    cb,formatter, cfg) {flags|F_T_INT, GS(var), {.int_ = default},    \
+    {name}, 3,_INT(min,max,step,(int)formatter), _TALKID(unit),       \
+    cb, cfg }
+    
+#define SYSTEM_ITEM(type,var,default, cb)                             \
+    {type|F_SYSTEMSETTING|F_LANG_IS_STRING, GS(var), {default},       \
+    {.cfg_string = #var}, 0,{NULL}, NULL, cb ,NULL}
+    
+#define CHOICE_ITEM(flags,var,name, cfg,default, cb,count,...)        \
+    {flags|F_T_INT|F_T_CHOICE, GS(var), {.int_ = default}, {name},    \
+    count, _INT(__VA_ARGS__),NULL, cb, cfg }
+#define STRINGCHOICE_ITEM(flags,var,name,cfg,default,count,           \
+        Strings,talks, cb) {flags|F_T_INT|F_T_CHOICE|F_LANG_STRING,   \
+        GS(var), {.int_ = default}, {name},count, Strings, talks,     \
+        cb, cfg }
+#define STRING_ITEM(flags,var,name,default,cb)                        \
+    {flags|F_T_CHARPTR|F_LANG_IS_STRING, GS(var),                     \
+    {.charptr = default}, {.cfg_string = name},0, {NULL}, NULL,       \
+    cb, name}
+
+
+#if defined(CONFIG_BACKLIGHT)
+/* use me when realvalues are impleneted for backlight and such
+static const char *backlight_times_strings[] = {
+        _REALVAL("on",-1),_REALVAL("off",0),_REALVAL("1",1),_REALVAL("2",2),
+        _REALVAL("3",3),_REALVAL("4",4),_REALVAL("5",5),_REALVAL("6",6),
+        _REALVAL("7",7),_REALVAL("8",8),_REALVAL("9",9),_REALVAL("10",10),
+        _REALVAL("15",15),_REALVAL("20",20),_REALVAL("25",25),_REALVAL("30",30),
+        _REALVAL("45",45),_REALVAL("60",60),_REALVAL("90",90)};
+*/
+static const char *backlight_times_strings[] = {
+                      "off","on","1","2","3","4","5","6","7","8",
+                      "9","10","15","20","25","30","45","60","90"};
+static const int  backlight_times_talks[] =  {
+                LANG_OFF,LANG_ON,TALK_ID(1,UNIT_SEC),TALK_ID(2,UNIT_SEC),
+                TALK_ID(3,UNIT_SEC),TALK_ID(4,UNIT_SEC),TALK_ID(5,UNIT_SEC),
+                TALK_ID(6,UNIT_SEC),TALK_ID(7,UNIT_SEC),TALK_ID(8,UNIT_SEC),
+                TALK_ID(9,UNIT_SEC),TALK_ID(10,UNIT_SEC),TALK_ID(15,UNIT_SEC),
+                TALK_ID(20,UNIT_SEC),TALK_ID(25,UNIT_SEC),TALK_ID(30,UNIT_SEC),
+                TALK_ID(45,UNIT_SEC),TALK_ID(60,UNIT_SEC),TALK_ID(90,UNIT_SEC)};
+#endif
+#ifdef HAVE_RECORDING
+/* keep synchronous to trig_durations and
+   trigger_times in settings_apply_trigger */
+static const char *trig_durations_strings[] = 
+    {"0s","1s","2s","5s","10s","15s","20s",
+    "25s","30s","1min","2min","5min","10min"};
+static const int  trig_durations_talks[] =  {
+    TALK_ID(0,UNIT_SEC),TALK_ID(1,UNIT_SEC),
+    TALK_ID(2,UNIT_SEC),TALK_ID(5,UNIT_SEC),
+    TALK_ID(10,UNIT_SEC),TALK_ID(15,UNIT_SEC),
+    TALK_ID(20,UNIT_SEC),TALK_ID(25,UNIT_SEC),
+    TALK_ID(30,UNIT_SEC),TALK_ID(1,UNIT_MIN),
+    TALK_ID(2,UNIT_MIN),TALK_ID(5,UNIT_MIN),TALK_ID(10,UNIT_MIN)};
+#endif
+
+/* callback functions needed for the settings */
+#if CONFIG_CODEC == SWCODEC
+    /* scrossfeed */
+static void crossfeed_format(char* buffer, int buffer_size, int value,
+                                 const char* unit)
+{
+    snprintf(buffer, buffer_size, "%s%d.%d %s", value == 0 ? " " : "-",
+             value / 10, value % 10, unit);
+}
+#endif /* CONFIG_CODEC == SWCODEC */
+#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
+static void set_mdb_enable(bool value)
+{
+    sound_set_mdb_enable((int)value);
+}
+#endif
+#include "debug.h"
+#ifdef HAVE_DIRCACHE
+static void dircache_cb(bool value)
+{
+    DEBUGF("hi!\n");
+    (void)value;
+    if (!dircache_is_enabled() && global_settings.dircache)
+        gui_syncsplash(HZ, true, str(LANG_DIRCACHE_REBOOT));
+}
+#endif /* HAVE_DIRCACHE */
+
+
+
+
+const struct settings_list  settings[] = {
+    /* sound */
+    SOUND_ITEM(0,volume,LANG_VOLUME,SOUND_VOLUME,"volume"),
+    SOUND_ITEM(0,balance,LANG_BALANCE,SOUND_BALANCE,"balance"),
+    SOUND_ITEM(0,bass,LANG_BASS,SOUND_BASS,"bass"),
+    SOUND_ITEM(0,treble,LANG_TREBLE,SOUND_TREBLE,"treble"),
+#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
+    SOUND_ITEM(0,loudness,LANG_LOUDNESS,SOUND_LOUDNESS,"loudness"),
+    STRINGCHOICE_ITEM(0,avc,LANG_AUTOVOL,"auto volume",0,5,
+                      _STR("off","20ms","2","4","8"),
+                      _TALKID(LANG_OFF,TALK_ID(20, UNIT_MS),TALK_ID(2, UNIT_SEC),
+                              TALK_ID(4, UNIT_SEC),TALK_ID(8, UNIT_SEC)), NULL),
+    BOOL_ITEM(0,superbass,LANG_SUPERBASS,false, NULL,"superbass"),
+#endif
+    CHOICE_ITEM(0,channel_config,LANG_CHANNEL,
+                "channels,stereo,mono,custom,mono left,mono right,karaoke",
+                0, NULL,6,
+                LANG_CHANNEL_STEREO,LANG_CHANNEL_MONO,
+                LANG_CHANNEL_CUSTOM,LANG_CHANNEL_LEFT,
+                LANG_CHANNEL_RIGHT,LANG_CHANNEL_KARAOKE),
+    SOUND_ITEM(0,stereo_width,LANG_STEREO_WIDTH,SOUND_STEREO_WIDTH,"stereo width"),
+    
+    /* playback */
+    BOOL_ITEM(0,resume,LANG_RESUME,false, NULL, "resume"),
+    BOOL_ITEM(0,playlist_shuffle,LANG_SHUFFLE,false, NULL, "shuffle"),
+    SYSTEM_ITEM(F_T_INT,resume_index,-1, NULL),
+    SYSTEM_ITEM(F_T_INT,resume_first_index,0, NULL),
+    SYSTEM_ITEM(F_T_INT,resume_offset,-1, NULL),
+    SYSTEM_ITEM(F_T_INT,resume_seed,-1, NULL),
+    CHOICE_ITEM(0,repeat_mode,LANG_REPEAT, "repeat,off,all,one,shuffle,ab",
+                REPEAT_ALL, NULL,NUM_REPEAT_MODES,
+        LANG_OFF,LANG_REPEAT_ALL,LANG_REPEAT_ONE,LANG_SHUFFLE,LANG_REPEAT_AB),
+    
+    /* LCD */
+#ifdef HAVE_LCD_CONTRAST
+    INT_ITEM(0,contrast,LANG_CONTRAST,DEFAULT_CONTRAST_SETTING,
+             MIN_CONTRAST_SETTING,MAX_CONTRAST_SETTING,1,UNIT_INT,
+             NULL, NULL, "contrast"),
+#endif
+#ifdef CONFIG_BACKLIGHT
+    STRINGCHOICE_ITEM(0,backlight_timeout,LANG_BACKLIGHT,
+                      "backlight timeout",
+                      6,sizeof(backlight_times_strings)/
+                              sizeof(*backlight_times_strings),
+                      {.strings = (char **)backlight_times_strings},
+                      (int*)backlight_times_talks, NULL),
+#ifdef CONFIG_CHARGING
+    STRINGCHOICE_ITEM(0,backlight_timeout_plugged,
+                      LANG_BACKLIGHT_ON_WHEN_CHARGING,
+                      "backlight timeout plugged",11,
+                  sizeof(backlight_times_strings)/
+                          sizeof(*backlight_times_strings),
+                  {.strings = (char **)backlight_times_strings},
+                  (int*)backlight_times_talks, NULL),
+#endif
+#endif /* CONFIG_BACKLIGHT */
+    
+    /* display */
+#ifdef HAVE_LCD_BITMAP
+    CHOICE_ITEM(0,invert,LANG_INVERT, "invert,off,on",
+                0, NULL,2,LANG_INVERT_LCD_NORMAL,LANG_INVERT_LCD_INVERSE),
+    BOOL_ITEM(0,flip_display,LANG_FLIP_DISPLAY,false, NULL, "flip display"),
+    BOOL_ITEM(0,invert_cursor,LANG_INVERT_CURSOR,true, NULL, "invert cursor"),
+    BOOL_ITEM(F_TEMPVARIABLE,statusbar,LANG_STATUS_BAR,true, NULL, "statusbar"),
+    BOOL_ITEM(0,scrollbar,LANG_SCROLL_BAR,true, NULL, "scrollbar"),
+#if CONFIG_KEYPAD == RECORDER_PAD
+    BOOL_ITEM(0,buttonbar,LANG_BUTTON_BAR,true, NULL, "buttonbar"),
+#endif
+    CHOICE_ITEM(0,volume_type,LANG_VOLUME_DISPLAY, "volume display,graphic,numeric",
+                0, NULL,2,LANG_DISPLAY_GRAPHIC,LANG_DISPLAY_NUMERIC),
+    CHOICE_ITEM(0,battery_display,LANG_BATTERY_DISPLAY,
+                "battery display,graphic,numeric",
+                0, NULL,2,LANG_DISPLAY_GRAPHIC,LANG_DISPLAY_NUMERIC),
+    CHOICE_ITEM(0,timeformat,LANG_TIMEFORMAT, 
+                "time format,24hour,12hour", 0, NULL,2,
+                LANG_24_HOUR_CLOCK,LANG_12_HOUR_CLOCK),
+#endif /* HAVE_LCD_BITMAP */
+    BOOL_ITEM(0,show_icons,LANG_SHOW_ICONS,true, NULL, "show icons"),
+    
+    /* system */
+    STRINGCHOICE_ITEM(0,poweroff,LANG_POWEROFF_IDLE,"idle poweroff",
+                      10,15,
+                      _STR("off","1","2","3","4","5","6","7",
+                           "8","9","10","15","30","45","60"),
+                      _TALKID(LANG_OFF,TALK_ID(1, UNIT_MIN),
+                              TALK_ID(2, UNIT_MIN),TALK_ID(3, UNIT_MIN),
+                              TALK_ID(4, UNIT_MIN),TALK_ID(5, UNIT_MIN),
+                              TALK_ID(6, UNIT_MIN),TALK_ID(7, UNIT_MIN),
+                              TALK_ID(8, UNIT_MIN),TALK_ID(9, UNIT_MIN),
+                              TALK_ID(10, UNIT_MIN),TALK_ID(15, UNIT_MIN),
+                              TALK_ID(30, UNIT_MIN),TALK_ID(45, UNIT_MIN),
+                              TALK_ID(60, UNIT_MIN)), NULL),
+    SYSTEM_ITEM(F_T_INT,runtime,0, NULL),
+    SYSTEM_ITEM(F_T_INT,topruntime,0, NULL),
+    INT_ITEM(0,max_files_in_playlist,LANG_MAX_FILES_IN_PLAYLIST,
+#if MEM > 1
+             10000,1000,20000,1000
+#else
+             1000,1000,10000,100
+#endif
+            ,UNIT_INT, NULL, NULL,"max files in playlist"),
+    INT_ITEM(0,max_files_in_dir,LANG_MAX_FILES_IN_DIR,
+#if MEM > 1
+             400,50,10000,50
+#else
+             200,50,10000,50
+#endif
+            ,UNIT_INT, NULL, NULL,"max files in dir"),
+
+    /* battery */
+#ifndef SIMULATOR
+    INT_ITEM(0,battery_capacity,LANG_BATTERY_CAPACITY,BATTERY_CAPACITY_DEFAULT,
+             BATTERY_CAPACITY_MIN,BATTERY_CAPACITY_MAX,BATTERY_CAPACITY_INC,
+             UNIT_INT, NULL, NULL,"battery capacity"),
+#ifdef CONFIG_CHARGING
+    BOOL_ITEM(0,car_adapter_mode,LANG_CAR_ADAPTER_MODE,false,
+              NULL,"car adapter mode"),
+#endif
+#if BATTERY_TYPES_COUNT > 1
+    CHOICE_ITEM(0,battery_type,LANG_BATTERY_TYPE,"battery type,alkaline,nimh",
+                0, NULL,2,LANG_BATTERY_TYPE_ALKALINE,LANG_BATTERY_TYPE_NIMH),
+#endif
+#endif
+#ifdef CONFIG_TUNER
+    /* tuner */
+    BOOL_ITEM(0,fm_force_mono,LANG_FM_MONO_MODE,false, NULL,"force fm mono"),
+    SYSTEM_ITEM(F_T_INT,last_frequency,0, NULL),
+    STRINGCHOICE_ITEM(0,fm_region,LANG_FM_REGION,"fm_region",
+                      10,15,
+                      _STR("eu","us","jp","kr"),
+                      NULL, NULL),
+#endif
+
+#ifdef HAVE_REMOTE_LCD
+    /* remote lcd */
+    INT_ITEM(0,remote_contrast,LANG_CONTRAST,42,
+                   MIN_CONTRAST_SETTING,MAX_CONTRAST_SETTING,1,UNIT_INT,
+                   NULL, NULL,"remote contrast"),
+    CHOICE_ITEM(0,remote_invert,LANG_INVERT, "remote invert,off,on",
+                0, NULL,2,LANG_INVERT_LCD_NORMAL,LANG_INVERT_LCD_INVERSE),
+    BOOL_ITEM(0,remote_flip_display,LANG_FLIP_DISPLAY,false, NULL,
+              "remote flip display"),
+    STRINGCHOICE_ITEM(0,remote_backlight_timeout,LANG_BACKLIGHT,
+                            "remote backlight timeout",
+                            6,sizeof(backlight_times_strings)/
+                                    sizeof(*backlight_times_strings),
+                      {.strings = (char **)backlight_times_strings},
+                      (int*)backlight_times_talks, NULL),
+#ifdef CONFIG_CHARGING
+    STRINGCHOICE_ITEM(0,remote_backlight_timeout_plugged,
+                      LANG_BACKLIGHT_ON_WHEN_CHARGING,
+                            "remote backlight timeout plugged",11,
+                      sizeof(backlight_times_strings)/
+                              sizeof(*backlight_times_strings),
+                      {.strings = (char **)backlight_times_strings},
+                      (int*)backlight_times_talks, NULL),
+#endif
+#ifdef HAVE_REMOTE_LCD_TICKING
+    BOOL_ITEM(0,remote_reduce_ticking,LANG_REDUCE_TICKING,false,
+              NULL, "remote reduce ticking"),
+#endif
+    BOOL_ITEM(0,remote_bl_filter_first_keypress,
+              LANG_BACKLIGHT_FILTER_FIRST_KEYPRESS,false, NULL,
+                    "backlight filters first remote keypress"),
+#endif /* HAVE_REMOTE_LCD */
+#ifdef CONFIG_BACKLIGHT
+    BOOL_ITEM(0,bl_filter_first_keypress,
+              LANG_BACKLIGHT_FILTER_FIRST_KEYPRESS,false, NULL,
+              "backlight filters first keypress"),
+#endif
+
+    /***************   end of old rtc table    ******************/
+    
+    /* display */
+#ifdef CONFIG_BACKLIGHT
+    BOOL_ITEM(0,caption_backlight,LANG_CAPTION_BACKLIGHT,false,
+              NULL, "caption backlight"),
+#endif
+#ifdef HAVE_REMOTE_LCD
+    BOOL_ITEM(0,remote_caption_backlight,LANG_CAPTION_BACKLIGHT,false,
+              NULL,"remote caption backlight"),
+#endif
+#ifdef HAVE_BACKLIGHT_BRIGHTNESS
+    INT_ITEM(0,brightness,LANG_CAPTION_BACKLIGHT,DEFAULT_BRIGHTNESS_SETTING,
+             MIN_BRIGHTNESS_SETTING,MAX_BRIGHTNESS_SETTING,1,UNIT_INT, NULL,
+             NULL, "brightness"),
+#endif
+#ifdef HAVE_BACKLIGHT_PWM_FADING
+    /* backlight fading */
+    STRINGCHOICE_ITEM(0,backlight_fade_in,LANG_BACKLIGHT_FADE_IN,
+                      "backlight fade in",1,4,
+                      _STR("off","500ms","1s","2s"),
+                      _TALKID(LANG_OFF,TALK_ID(500, UNIT_MS),
+                              TALK_ID(1, UNIT_SEC),TALK_ID(2, UNIT_SEC)), NULL),
+    STRINGCHOICE_ITEM(0,backlight_fade_out,LANG_BACKLIGHT_FADE_OUT,
+                      "backlight fade out",4,8,
+                    _STR("off","500ms","1s","2s","3s","4s","5s","10s"),
+                    _TALKID(LANG_OFF,TALK_ID(500, UNIT_MS),TALK_ID(1, UNIT_SEC),
+                            TALK_ID(2, UNIT_SEC),TALK_ID(3, UNIT_SEC),
+                            TALK_ID(4, UNIT_SEC),TALK_ID(5, UNIT_SEC),
+                            TALK_ID(10, UNIT_SEC)), NULL),
+#endif
+    INT_ITEM(0,scroll_speed,LANG_SCROLL_SPEED,9,0,15,1,UNIT_INT,
+             NULL, NULL, "scroll speed"),
+    INT_ITEM(0,scroll_delay,LANG_SCROLL_DELAY,6,0,250,1,UNIT_INT,
+             NULL, NULL, "scroll delay"),
+    INT_ITEM(0,bidir_limit,LANG_BIDIR_SCROLL,50,0,200,1,UNIT_INT,
+             NULL, NULL, "bidir limit"),
+#ifdef HAVE_REMOTE_LCD
+    INT_ITEM(0,remote_scroll_speed,LANG_SCROLL_SPEED,6,0,15,1,
+             UNIT_INT, NULL, NULL, "remote scroll speed"),
+    INT_ITEM(0,remote_scroll_step,LANG_SCROLL_STEP,9,1,160,1,
+             UNIT_INT, NULL, NULL, "remote scroll step"),
+    INT_ITEM(0,remote_scroll_delay,LANG_SCROLL_DELAY,100,0,250,1,
+             UNIT_INT, NULL, NULL, "remote scroll delay"),
+    INT_ITEM(0,remote_bidir_limit,LANG_BIDIR_SCROLL,50,0,200,1,
+             UNIT_INT, NULL, NULL, "remote bidir limit"),
+#endif
+#ifdef HAVE_LCD_BITMAP
+    BOOL_ITEM(0,offset_out_of_view,LANG_SCREEN_SCROLL_VIEW,
+              false, NULL, "Screen Scrolls Out Of View"),
+    INT_ITEM(0,scroll_step,LANG_SCROLL_STEP,6,1,LCD_WIDTH,1,
+             LANG_PIXELS, NULL, NULL, "scroll step"),
+    INT_ITEM(0,screen_scroll_step,LANG_SCREEN_SCROLL_STEP,16,1,
+             LCD_WIDTH,1,LANG_PIXELS, NULL, NULL, "screen scroll step"),
+#endif /* HAVE_LCD_BITMAP */
+#ifdef HAVE_LCD_CHARCELLS
+    STRINGCHOICE_ITEM(0,jump_scroll,LANG_JUMP_SCROLL, "jump scroll",0,6,
+                      _STR(ID2P(LANG_OFF),ID2P(LANG_ON),"2","3","4",
+                           ID2P(LANG_ALWAYS)),
+                      _TALKID(LANG_OFF,LANG_ON,TALK_ID(2, UNIT_INT),
+                              TALK_ID(3, UNIT_INT),
+                              TALK_ID(4, UNIT_INT),LANG_ALWAYS), NULL),
+    INT_ITEM(0,jump_scroll_delay,LANG_JUMP_SCROLL_DELAY,500,0,2500,100,
+             UNIT_MS, NULL, NULL, "jump scroll delay"),
+#endif
+    BOOL_ITEM(0,scroll_paginated,LANG_SCROLL_PAGINATED,false,
+              NULL, "scroll paginated"),
+#ifdef HAVE_LCD_COLOR
+{F_T_INT|F_STORERGB|F_LANG_IS_STRING, GS(fg_color), {LCD_DEFAULT_FG}, 
+    {.cfg_string = "foreground color"}, 0,{NULL}, NULL, NULL ,"foreground color"},
+{F_T_INT|F_STORERGB|F_LANG_IS_STRING, GS(bg_color), {LCD_DEFAULT_BG}, 
+    {.cfg_string = "background color"}, 0,{NULL}, NULL, NULL ,"background color"},
+#endif
+
+    /* more playback */
+    BOOL_ITEM(0,play_selected,LANG_PLAY_SELECTED,true, NULL, "play selected"),
+    BOOL_ITEM(0,party_mode,LANG_PARTY_MODE,false, NULL,"party mode"),
+    BOOL_ITEM(0,fade_on_stop,LANG_FADE_ON_STOP,true, NULL, "volume fade"),
+    INT_ITEM(0,ff_rewind_min_step,LANG_FFRW_STEP,FF_REWIND_1000,0,60,1,
+             UNIT_INT, NULL, NULL,
+             "scan min step"),
+    INT_ITEM(0,ff_rewind_accel,LANG_FFRW_ACCEL,3,0,60,1,UNIT_SEC,
+             NULL, NULL, "scan accel"),
+    STRINGCHOICE_ITEM(0,ff_rewind_accel,LANG_FFRW_ACCEL,
+                      "scan accel",3,16,
+                      _STR("off","2x/1s","2x/2s","2x/3s","2x/4s",
+                           "2x/5s","2x/6s","2x/7s",
+                           "2x/8s","2x/9s","2x/10s","2x/11s","2x/12s",
+                           "2x/13s","2x/14s","2x/15s"),
+                      _TALKID(LANG_OFF,TALK_ID(1, UNIT_INT),TALK_ID(2, UNIT_INT),
+                              TALK_ID(3, UNIT_INT),TALK_ID(4, UNIT_INT),
+                              TALK_ID(5, UNIT_INT),TALK_ID(6, UNIT_INT),
+                              TALK_ID(7, UNIT_INT),TALK_ID(8, UNIT_INT),
+                              TALK_ID(9, UNIT_INT),TALK_ID(10, UNIT_INT),
+                              TALK_ID(11, UNIT_INT),TALK_ID(12, UNIT_INT),
+                              TALK_ID(13, UNIT_INT),TALK_ID(14, UNIT_INT),
+                              TALK_ID(15, UNIT_INT)), NULL),
+#if CONFIG_CODEC == SWCODEC
+    STRINGCHOICE_ITEM(0,buffer_margin,LANG_MP3BUFFER_MARGIN,
+                      "antiskip",0,8,
+                      _STR("5s","15s","30s","1min","2min","3min","5min","10min"),
+                      _TALKID(TALK_ID(5, UNIT_SEC),TALK_ID(15, UNIT_SEC),
+                              TALK_ID(30, UNIT_SEC),TALK_ID(1, UNIT_MIN),
+                              TALK_ID(2, UNIT_MIN),TALK_ID(3, UNIT_MIN),
+                              TALK_ID(5, UNIT_MIN),TALK_ID(10, UNIT_MIN)), NULL),
+#else
+    INT_ITEM(0,buffer_margin,LANG_MP3BUFFER_MARGIN,1,0,7,1,UNIT_SEC,
+             NULL, NULL, "antiskip"),
+#endif
+
+    /* disk */
+#ifndef HAVE_MMC
+#ifdef HAVE_ATA_POWER_OFF
+    BOOL_ITEM(0,disk_poweroff,LANG_POWEROFF_IDLE,false, NULL, "disk poweroff"),
+#endif
+    INT_ITEM(0,disk_spindown,LANG_SPINDOWN,
+             5,1,254,3,UNIT_SEC, NULL, NULL, "disk spindown"),
+#endif /* !HAVE_MMC */
+
+    /* browser */
+    CHOICE_ITEM(0,dirfilter,LANG_FILTER,
+                "show files,all,supported,music,playlists,id3 database",
+                SHOW_SUPPORTED, NULL,5,
+                LANG_FILTER_ALL,LANG_FILTER_SUPPORTED,LANG_FILTER_MUSIC,
+                LANG_FILTER_PLAYLIST,LANG_FILTER_ID3DB),
+    BOOL_ITEM(0,sort_case,LANG_SORT_CASE,false, NULL, "sort case"),
+    BOOL_ITEM(0,browse_current,LANG_FOLLOW,false, NULL, "follow playlist"),
+    
+    /* playlist */
+    BOOL_ITEM(0,playlist_viewer_icons,LANG_SHOW_ICONS,true,
+              NULL, "playlist viewer icons"),
+    BOOL_ITEM(0,playlist_viewer_indices,LANG_SHOW_INDICES,true,
+              NULL, "playlist viewer indices"),
+    CHOICE_ITEM(0,playlist_viewer_track_display,LANG_TRACK_DISPLAY,
+                "playlist viewer track display,track name,full path", 0, NULL,2,
+                LANG_DISPLAY_TRACK_NAME_ONLY,LANG_DISPLAY_FULL_PATH),
+    CHOICE_ITEM(0,recursive_dir_insert,LANG_RECURSE_DIRECTORY,
+                "recursive directory insert,off,on,ask",
+                RECURSE_OFF, NULL,3,
+                LANG_ON,LANG_OFF,LANG_RESUME_SETTING_ASK),
+    
+    /* bookmarks */
+    CHOICE_ITEM(0,autocreatebookmark,LANG_BOOKMARK_SETTINGS_AUTOCREATE, 
+                "autocreate bookmarks,off,on,ask,recent only - on,recent only - ask",
+                BOOKMARK_NO, NULL,5,
+                LANG_OFF,LANG_ON,LANG_RESUME_SETTING_ASK,
+                LANG_BOOKMARK_SETTINGS_RECENT_ONLY_YES,
+                LANG_BOOKMARK_SETTINGS_RECENT_ONLY_ASK),
+    CHOICE_ITEM(0,autoloadbookmark,LANG_BOOKMARK_SETTINGS_AUTOLOAD,
+                "autoload bookmarks,off,on,ask",BOOKMARK_NO, NULL,3,
+                LANG_ON,LANG_OFF,LANG_RESUME_SETTING_ASK),
+    CHOICE_ITEM(0,usemrb,LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS,
+                "use most-recent-bookmarks,off,on,unique only",BOOKMARK_NO, NULL,3,
+                LANG_OFF,LANG_ON,LANG_BOOKMARK_SETTINGS_UNIQUE_ONLY),
+    
+    /* peak meter */
+#ifdef HAVE_LCD_BITMAP
+    STRINGCHOICE_ITEM(0,peak_meter_clip_hold,LANG_PM_CLIP_HOLD,
+                      "peak meter clip hold",
+                      16,24,
+                _STR("on","1s","2s","3s","4s","5s","6s","7s","8s","9s","10s",
+                    "15s","20s","30s","45s","60s","90s","2min","3min","5min","10min",
+                    "20min","45min","90min"),
+                _TALKID(LANG_OFF,TALK_ID(1, UNIT_SEC),TALK_ID(2, UNIT_SEC),
+                        TALK_ID(3, UNIT_SEC),TALK_ID(4, UNIT_SEC),
+                        TALK_ID(5, UNIT_SEC),TALK_ID(6, UNIT_SEC),
+                        TALK_ID(7, UNIT_SEC),TALK_ID(8, UNIT_SEC),
+                        TALK_ID(9, UNIT_SEC),TALK_ID(10, UNIT_SEC),
+                        TALK_ID(15, UNIT_SEC),TALK_ID(20, UNIT_SEC),
+                        TALK_ID(30, UNIT_SEC),TALK_ID(45, UNIT_SEC),
+                        TALK_ID(60, UNIT_SEC),TALK_ID(90, UNIT_SEC),
+                        TALK_ID(2, UNIT_MIN),TALK_ID(3, UNIT_MIN),
+                        TALK_ID(5, UNIT_MIN),TALK_ID(10, UNIT_MIN),
+                        TALK_ID(20, UNIT_MIN),TALK_ID(45, UNIT_MIN),
+                        TALK_ID(90, UNIT_MIN)), NULL),
+    STRINGCHOICE_ITEM(0,peak_meter_hold,LANG_PM_PEAK_HOLD,
+                      "peak meter hold",
+                      3,18,
+                _STR("off","200ms","300ms","500ms","1s","2s","3s","4s",
+                    "5s","6s","7s","8s","9s","10s","15s","20s","30s","60s"),
+                _TALKID(LANG_OFF,TALK_ID(200, UNIT_MS),TALK_ID(300, UNIT_MS),
+                        TALK_ID(500, UNIT_MS),TALK_ID(1, UNIT_SEC),
+                        TALK_ID(2, UNIT_SEC),TALK_ID(3, UNIT_SEC),
+                        TALK_ID(4, UNIT_SEC),TALK_ID(5, UNIT_SEC),
+                        TALK_ID(6, UNIT_SEC),TALK_ID(7, UNIT_SEC),
+                        TALK_ID(8, UNIT_SEC),TALK_ID(9, UNIT_SEC),
+                        TALK_ID(10, UNIT_SEC),TALK_ID(15, UNIT_SEC),
+                        TALK_ID(20, UNIT_SEC),TALK_ID(30, UNIT_SEC),
+                        TALK_ID(60, UNIT_SEC)), NULL),
+    INT_ITEM(0,peak_meter_release,LANG_PM_RELEASE,8,0,126,1,
+             LANG_PM_UNITS_PER_READ, NULL, NULL, "peak meter release"),
+    BOOL_ITEM(0,peak_meter_dbfs,LANG_PM_DBFS,true, NULL, "peak meter dbfs"),
+    INT_ITEM(0,peak_meter_min,LANG_PM_MIN,60,0,100,1,UNIT_INT, NULL,
+             NULL, "peak meter min"),
+    INT_ITEM(0,peak_meter_max,LANG_PM_MAX,0,0,100,1,UNIT_INT, NULL,
+             NULL, "peak meter max"),
+#endif /* HAVE_LCD_BITMAP */
+#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
+    SOUND_ITEM(0,mdb_strength,LANG_MDB_STRENGTH,
+               SOUND_MDB_STRENGTH, "mdb strength"),
+    SOUND_ITEM(0,mdb_harmonics,LANG_MDB_HARMONICS,
+               SOUND_MDB_HARMONICS, "mdb harmonics"),
+    SOUND_ITEM(0,mdb_center,LANG_MDB_CENTER,SOUND_MDB_CENTER, "mdb center"),
+    SOUND_ITEM(0,mdb_shape,LANG_MDB_SHAPE,SOUND_MDB_SHAPE, "mdb shape"),
+    BOOL_ITEM(0,mdb_enable,LANG_MDB_ENABLE, false,set_mdb_enable, "mdb enable"),
+#endif
+#if CONFIG_CODEC == MAS3507D
+    BOOL_ITEM(0,line_in,LANG_LINE_IN, false,NULL, "line in"),
+#endif
+
+    /* voice */
+    CHOICE_ITEM(0,talk_dir,LANG_VOICE_DIR, 
+                "talk dir,off,number,spell,hover",0, NULL,4,
+                LANG_OFF,LANG_VOICE_NUMBER,LANG_VOICE_SPELL,LANG_VOICE_DIR_HOVER),
+    CHOICE_ITEM(0,talk_file,LANG_VOICE_FILE, 
+                "talk file,off,number,spell,hover",0, NULL,4,
+                LANG_OFF,LANG_VOICE_NUMBER,LANG_VOICE_SPELL,LANG_VOICE_DIR_HOVER),
+    BOOL_ITEM(F_TEMPVARIABLE,talk_menu,LANG_VOICE_MENU, false,NULL, "talk menu"),
+    
+    /* file sorting */
+    CHOICE_ITEM(0,sort_file,LANG_SORT_FILE,
+                "sort files,alpha,oldest,newest,type",0, NULL,4,
+                LANG_SORT_ALPHA,LANG_SORT_DATE,
+                LANG_SORT_DATE_REVERSE,LANG_SORT_TYPE),
+    CHOICE_ITEM(0,sort_dir,LANG_SORT_DIR, 
+                "sort dirs,alpha,oldest,newest",0, NULL,3,
+                LANG_SORT_ALPHA,LANG_SORT_DATE,LANG_SORT_DATE_REVERSE),
+/*    CHOICE_ITEM(0,id3_v1_first,LANG_ID3_ORDER, 
+                "id3 tag priority,v2-v1,v1-v2",0, mpeg_id3_options,2,
+                LANG_ID3_V1_FIRST,LANG_ID3_V2_FIRST),
+ */
+#ifdef HAVE_RECORDING
+    /* recording */
+    SYSTEM_ITEM(F_T_BOOL,recscreen_on,0, NULL),
+    BOOL_ITEM(0,rec_startup,LANG_RECORD_STARTUP, 
+              false,NULL, "rec screen on startup"),
+    STRINGCHOICE_ITEM(0,rec_timesplit,LANG_SPLIT_TIME,
+                      "rec timesplit", 0,16,
+                      _STR("off","00:05","00:10","00:15","00:30","01:00","01:14",
+                           "01:20","02:00","04:00","06:00","08:00",
+                           "10:00","12:00","18:00","24:00"),
+                      _TALKID(LANG_OFF,TALK_ID(5, UNIT_MIN),TALK_ID(10, UNIT_MIN),
+                              TALK_ID(15, UNIT_MIN),TALK_ID(30, UNIT_MIN),
+                              TALK_ID(60, UNIT_MIN),TALK_ID(72, UNIT_MIN),
+                              TALK_ID(80, UNIT_MIN),TALK_ID(2, UNIT_HOUR),
+                              TALK_ID(4, UNIT_HOUR),TALK_ID(6, UNIT_HOUR),
+                              TALK_ID(8, UNIT_HOUR),TALK_ID(10, UNIT_HOUR),
+                              TALK_ID(12, UNIT_HOUR),TALK_ID(18, UNIT_HOUR),
+                              TALK_ID(24, UNIT_HOUR)), NULL),
+    STRINGCHOICE_ITEM(0,rec_sizesplit,LANG_SPLIT_SIZE,
+                      "rec sizesplit",0,16,
+                    _STR("off","5MB","10MB","15MB","32MB","64MB","75MB",
+                            "100MB","128MB","256MB","512MB","650MB",
+                            "700MB","1GB","1.5GB","1.75GB"),
+                    _TALKID(LANG_OFF,TALK_ID(5, UNIT_MB),TALK_ID(10, UNIT_MB),
+                            TALK_ID(15, UNIT_MB),TALK_ID(32, UNIT_MB),
+                            TALK_ID(64, UNIT_MB),TALK_ID(75, UNIT_MB),
+                            TALK_ID(100, UNIT_MB),TALK_ID(128, UNIT_MB),
+                            TALK_ID(256, UNIT_MB),TALK_ID(512, UNIT_MB),
+                            TALK_ID(650, UNIT_MB),TALK_ID(700, UNIT_MB),
+                            TALK_ID(1024, UNIT_MB),TALK_ID(1536, UNIT_MB),
+                            TALK_ID(1792, UNIT_MB)),NULL),
+    CHOICE_ITEM(0,rec_channels,LANG_RECORDING_CHANNELS,"rec channels,stereo,mono",
+                0, NULL,2,LANG_CHANNEL_STEREO,LANG_CHANNEL_MONO),
+    CHOICE_ITEM(0,rec_split_type,LANG_SPLIT_TYPE, "rec split type,Split,Stop",
+                0, NULL,2,LANG_START_NEW_FILE,LANG_STOP_RECORDING),
+    CHOICE_ITEM(0,rec_split_method,LANG_SPLIT_MEASURE, "rec split method,Time,Filesize",
+                0, NULL,2,LANG_SPLIT_TIME,LANG_SPLIT_SIZE),
+    CHOICE_ITEM(0,rec_source,LANG_RECORDING_SOURCE, "rec source"
+#if defined(HAVE_SPDIF_IN) && defined(HAVE_FMRADIO_IN)
+                "mic,line,spdif,fmradio", 2,NULL, 4,
+#elif defined(HAVE_SPDIF_IN)
+                "mic,line,spdif", 2,NULL, 3,
+#elif defined(HAVE_FMRADIO_IN)
+                "mic,line,fmradio", 2,NULL, 3,
+#else
+                "mic,line",1,NULL, 2,
+#endif
+                LANG_RECORDING_SRC_MIC,LANG_RECORDING_SRC_LINE
+#if defined(HAVE_SPDIF_IN)
+                ,LANG_RECORDING_SRC_DIGITAL
+#endif
+#if defined(HAVE_FMRADIO_IN)
+                ,LANG_FM_RADIO
+#endif
+               ),
+    INT_ITEM(0,rec_prerecord_time,LANG_RECORD_PRERECORD_TIME,0,0,30,1,UNIT_SEC,
+             NULL, NULL, "prerecording time"),
+    STRINGCHOICE_ITEM(0,rec_directory,LANG_RECORD_DIRECTORY,
+                      "rec directory",0,2,
+                      _STR(REC_BASE_DIR,/*LANG_RECORD_CURRENT_DIR*/"Current Directory"),
+                      _TALKID(-1,LANG_RECORD_CURRENT_DIR),NULL),
+#ifdef CONFIG_BACKLIGHT
+    CHOICE_ITEM(0,cliplight,LANG_CLIP_LIGHT, "cliplight,off,main,both,remote",0,
+                NULL,4,LANG_OFF,LANG_MAIN_UNIT,LANG_REMOTE_MAIN,LANG_REMOTE_UNIT),
+#endif
+#if CONFIG_CODEC == MAS3587F
+    INT_ITEM(0,rec_mic_gain,LANG_RECORDING_GAIN,8,-128,128,1,UNIT_DB, NULL,
+             NULL, "rec mic gain"),
+    INT_ITEM(0,rec_left_gain,LANG_RECORDING_LEFT,8,0,15,1,UNIT_DB, NULL,
+             NULL, "rec left gain"),
+    INT_ITEM(0,rec_right_gain,LANG_RECORDING_RIGHT,8,0,15,1,UNIT_DB, NULL,
+             NULL, "rec right gain"),
+    STRINGCHOICE_ITEM(0,rec_frequency,LANG_RECORDING_FREQUENCY,"rec frequency",0,6,
+                      _STR("44.1kHz","48kHz","32kHz","22.05kHz","24kHz","16kHz"),
+                      _TALKID(TALK_ID(44, UNIT_KHZ),TALK_ID(48, UNIT_KHZ),
+                              TALK_ID(32, UNIT_KHZ),TALK_ID(22, UNIT_KHZ),
+                              TALK_ID(24, UNIT_KHZ),TALK_ID(16, UNIT_KHZ)),NULL),
+    INT_ITEM(0,rec_quality,LANG_RECORDING_QUALITY,5,0,7,1,UNIT_INT, NULL, 
+             NULL, "rec quality"),
+    BOOL_ITEM(0,rec_editable,LANG_RECORDING_EDITABLE, false,NULL, 
+              "editable recordings"),
+#endif /* CONFIG_CODEC == MAS3587F */
+#if CONFIG_CODEC == SWCODEC && defined(HAVE_RECORDING)
+#ifdef HAVE_UDA1380
+    INT_ITEM(0,rec_mic_gain,LANG_RECORDING_GAIN,16,-128,128,1,UNIT_DB, 
+             NULL, NULL, "rec mic gain"),
+#endif
+#ifdef HAVE_TLV320
+    /* TLV320 only has no mic boost or 20db mic boost */
+    INT_ITEM(0,rec_mic_gain,LANG_RECORDING_GAIN,0,0,20,20,UNIT_DB, 
+             NULL, NULL, "rec mic gain"),
+#endif
+    INT_ITEM(0,rec_left_gain,LANG_RECORDING_LEFT,0,-128,96,1,UNIT_DB,
+             NULL, NULL, "rec left gain"),
+    INT_ITEM(0,rec_right_gain,LANG_RECORDING_RIGHT,0,-128,96,1,UNIT_DB,
+             NULL, NULL, "rec right gain"),
+    
+#if 0 /* Till samplerates are added for SWCODEC */
+    STRINGCHOICE_ITEM(0,rec_frequency,LANG_RECORDING_FREQUENCY,"rec frequency",0,6,
+                    _STR("44.1kHz","48kHz","32kHz","22.05kHz","24kHz","16kHz"),
+                    _TALKID(TALK_ID(44, UNIT_KHZ),TALK_ID(48, UNIT_KHZ),
+                            TALK_ID(32, UNIT_KHZ),TALK_ID(22, UNIT_KHZ),
+                            TALK_ID(24, UNIT_KHZ),TALK_ID(16, UNIT_KHZ)),NULL),
+#else
+    STRINGCHOICE_ITEM(0,rec_frequency,LANG_RECORDING_FREQUENCY,
+                      "rec frequency",0,1,
+                    _STR("44.1kHz"), _TALKID(TALK_ID(44, UNIT_KHZ)),NULL),
+#endif
+
+#endif /* CONFIG_CODEC == SWCODEC && defined(HAVE_RECORDING) */
+    /* values for the trigger */
+    INT_ITEM(0,rec_start_thres,LANG_RECORD_START_THRESHOLD,-35,-87,100,1,
+             UNIT_INT, NULL, NULL, "trigger start threshold"),
+    INT_ITEM(0,rec_stop_thres,LANG_RECORD_STOP_THRESHOLD,-45,-87,100,1,
+             UNIT_INT, NULL, NULL, "trigger stop threshold"),
+    STRINGCHOICE_ITEM(0,rec_start_duration,LANG_RECORD_MIN_DURATION, 
+                      "trigger start duration",
+                      0,sizeof(trig_durations_strings)/
+                              sizeof(*trig_durations_strings),
+                      {.strings = (char **)trig_durations_strings},
+                      (int*)trig_durations_talks, NULL),
+    STRINGCHOICE_ITEM(0,rec_stop_postrec,LANG_RECORD_STOP_POSTREC,
+                      "trigger stop postrec",
+                      2,sizeof(trig_durations_strings)/
+                              sizeof(*trig_durations_strings),
+                      {.strings = (char **)trig_durations_strings},
+                      (int*)trig_durations_talks, NULL),
+    STRINGCHOICE_ITEM(0,rec_stop_gap,LANG_RECORD_STOP_GAP,
+                      "trigger min gap",
+                      1,sizeof(trig_durations_strings)/
+                              sizeof(*trig_durations_strings),
+                      {.strings = (char **)trig_durations_strings},
+                      (int*)trig_durations_talks, NULL),
+/*    CHOICE_ITEM(0,rec_trigger_mode,LANG_RECORD_TRIGGER_MODE,
+                "trigger mode,off,once,repeat", 0, NULL,3,
+                LANG_OFF,LANG_ONCE,LANG_REPEAT),*/
+#endif /* HAVE_RECORDING */
+#ifdef HAVE_SPDIF_POWER
+    BOOL_ITEM(0,spdif_enable,LANG_SPDIF_ENABLE, false,NULL, "spdif enable"),
+#endif
+    CHOICE_ITEM(0,next_folder,LANG_NEXT_FOLDER, "folder navigation,off,on,random",
+                0,NULL,3,LANG_OFF,LANG_ON,LANG_RANDOM),
+    BOOL_ITEM(0,runtimedb,LANG_RUNTIMEDB_ACTIVE, false,NULL, "gather runtime data"),
+
+#ifdef HAVE_DIRCACHE
+    /* dircache */
+    BOOL_ITEM(0,dircache,LANG_DIRCACHE_ENABLE, false,dircache_cb, "dircache"),
+    SYSTEM_ITEM(F_T_INT,dircache_size,0, NULL),
+#endif
+    
+    /* tagcache */
+#ifdef HAVE_TC_RAMCACHE
+    BOOL_ITEM(0,tagcache_ram,LANG_TAGCACHE_RAM, false,NULL, "tagcache_ram"),
+#endif
+    BOOL_ITEM(0,tagcache_autoupdate,LANG_TAGCACHE_AUTOUPDATE,
+              false,NULL, "tagcache_autoupdate"),
+    CHOICE_ITEM(0,default_codepage,LANG_DEFAULT_CODEPAGE,
+                "default codepage,iso8859-1,iso8859-7,iso8859-8,cp1251,"
+                "iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,"
+                "gb2312,ksx1001,big5,utf-8,cp1256",
+                0, NULL,13,
+                LANG_CODEPAGE_LATIN1,LANG_CODEPAGE_GREEK,LANG_CODEPAGE_HEBREW,
+                LANG_CODEPAGE_CYRILLIC,LANG_CODEPAGE_THAI,LANG_CODEPAGE_ARABIC,
+                LANG_CODEPAGE_TURKISH,LANG_CODEPAGE_LATIN_EXTENDED,
+                LANG_CODEPAGE_JAPANESE,LANG_CODEPAGE_SIMPLIFIED,
+                LANG_CODEPAGE_KOREAN,LANG_CODEPAGE_TRADITIONAL,LANG_CODEPAGE_UTF8),
+    BOOL_ITEM(0,warnon_erase_dynplaylist,LANG_WARN_ERASEDYNPLAYLIST_MENU,
+              false,NULL,"warn when erasing dynamic playlist"),
+    
+#ifdef CONFIG_BACKLIGHT
+#ifdef HAS_BUTTON_HOLD
+    CHOICE_ITEM(0,backlight_on_button_hold,LANG_BACKLIGHT_ON_BUTTON_HOLD,
+                "backlight on button hold,normal,off,on",0,NULL,3,
+                LANG_BACKLIGHT_ON_BUTTON_HOLD_NORMAL, LANG_OFF,LANG_ON),
+#endif
+#ifdef HAVE_LCD_SLEEP
+    STRINGCHOICE_ITEM(0,lcd_sleep_after_backlight_off,
+                      LANG_LCD_SLEEP_AFTER_BACKLIGHT_OFF,
+                      "lcd sleep after backlight off",3,6,
+                      _STR("always","never","5","10","15","20","30","45","60","90"),
+                      _TALKID(LANG_ALWAYS,LANG_NEVER,TALK_ID(5, UNIT_SEC),
+                              TALK_ID(10, UNIT_SEC),TALK_ID(15, UNIT_SEC),
+                              TALK_ID(20, UNIT_SEC),TALK_ID(30, UNIT_SEC),
+                              TALK_ID(45, UNIT_SEC),TALK_ID(60, UNIT_SEC),
+                              TALK_ID(90, UNIT_SEC)),NULL),
+#endif
+#endif /* CONFIG_BACKLIGHT */
+
+#if CONFIG_CODEC == SWCODEC
+    /* replay gaim */
+    BOOL_ITEM(0,replaygain,LANG_REPLAYGAIN, false,NULL, "replaygain"),
+    CHOICE_ITEM(0,replaygain_type,LANG_REPLAYGAIN_MODE,
+                "replaygain type,track,album,track shuffle", 0,NULL,3,
+                LANG_TRACK_GAIN, LANG_ALBUM_GAIN,LANG_SHUFFLE_GAIN),
+    BOOL_ITEM(0,replaygain_noclip,LANG_REPLAYGAIN_NOCLIP, false,NULL,
+              "replaygain noclip"),
+    INT_ITEM(0,replaygain_preamp,LANG_REPLAYGAIN_PREAMP,0,-120,120,1,
+             UNIT_DB, NULL, NULL, "replaygain preamp"),
+    CHOICE_ITEM(0,beep,LANG_BEEP,"beep,off,weak,moderate,strong", 0,NULL,4,
+                LANG_OFF, LANG_WEAK,LANG_MODERATE,LANG_STRONG),
+    /* crossfade */
+    /* FIXME|FIXME all the cross* settings need checking FIXME|FIXME|FIXME*/
+    CHOICE_ITEM(0,crossfade,LANG_CROSSFADE_ENABLE,
+                "crossfade,off,shuffle,track skip,always", 0,NULL,4,
+                LANG_OFF, LANG_SHUFFLE,LANG_TRACKSKIP,LANG_ALWAYS),
+    INT_ITEM(0,crossfade_fade_in_delay,LANG_CROSSFADE_FADE_IN_DELAY,
+             0,0,7,1,UNIT_SEC, NULL, NULL, "crossfade fade in delay"),
+    INT_ITEM(0,crossfade_fade_out_delay,LANG_CROSSFADE_FADE_OUT_DELAY,
+             0,0,7,1,UNIT_SEC, NULL, NULL, "crossfade fade out delay"),
+    INT_ITEM(0,crossfade_fade_in_duration,LANG_CROSSFADE_FADE_IN_DURATION,
+             0,0,15,1,UNIT_SEC, NULL, NULL, "crossfade fade in duration"),
+    INT_ITEM(0,crossfade_fade_out_duration,LANG_CROSSFADE_FADE_OUT_DURATION,
+             0,0,15,1,UNIT_SEC, NULL, NULL, "crossfade fade out duration"),
+    CHOICE_ITEM(0,crossfade_fade_out_mixmode,LANG_CROSSFADE_FADE_OUT_MODE,
+                "crossfade fade out mode,crossfade,mix", 0,NULL,2,
+                LANG_CROSSFADE, LANG_MIX),
+    BOOL_ITEM(0,crossfeed,LANG_CROSSFEED, false,NULL, "crossfeed"),
+    INT_ITEM(0,crossfeed_direct_gain,LANG_CROSSFEED_DIRECT_GAIN,15,0,
+             60,5,UNIT_DB, NULL, crossfeed_format, "crossfeed direct gain"),
+    INT_ITEM(0,crossfeed_cross_gain,LANG_CROSSFEED_CROSS_GAIN,60,30,
+             120,5,UNIT_DB, NULL, crossfeed_format, "crossfeed cross gain"),
+    INT_ITEM(0,crossfeed_hf_attenuation,LANG_CROSSFEED_HF_ATTENUATION,
+             160,60,240,5,UNIT_DB, NULL, crossfeed_format, 
+             "crossfeed hf attenuation"),
+    INT_ITEM(0,crossfeed_hf_cutoff,LANG_CROSSFEED_HF_CUTOFF,700,500,
+             2000,100,UNIT_DB, NULL, NULL, "crossfeed hf cutoff"),
+#if 0
+    /* / FIXME|FIXME|FIXME|FIXME|FIXME|FIXME|FIXME|FIXME|FIXME|FIXME|FIXME| */
+    /* sw equalizer */
+    BOOL_ITEM(0,eq_enabled,LANG_EQUALIZER_ENABLED, false,NULL, "eq enabled"),
+    INT_ITEM(0,eq_precut,LANG_EQUALIZER_PRECUT,0,0,240,5,UNIT_DB,
+             NULL, NULL, "eq precut"),
+    /* 0..32768 Hz */
+    INT_ITEM(0,eq_band0_cutoff,LANG_EQUALIZER_BAND_CUTOFF,60,
+             EQ_CUTOFF_MIN,EQ_CUTOFF_MAX,EQ_CUTOFF_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 0 cutoff"),
+    INT_ITEM(0,eq_band1_cutoff,LANG_EQUALIZER_BAND_CUTOFF,200,
+             EQ_CUTOFF_MIN,EQ_CUTOFF_MAX,EQ_CUTOFF_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 1 cutoff"),
+    INT_ITEM(0,eq_band2_cutoff,LANG_EQUALIZER_BAND_CUTOFF,800,
+             EQ_CUTOFF_MIN,EQ_CUTOFF_MAX,EQ_CUTOFF_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 2 cutoff"),
+    INT_ITEM(0,eq_band3_cutoff,LANG_EQUALIZER_BAND_CUTOFF,4000,
+             EQ_CUTOFF_MIN,EQ_CUTOFF_MAX,EQ_CUTOFF_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 3 cutoff"),
+    INT_ITEM(0,eq_band4_cutoff,LANG_EQUALIZER_BAND_CUTOFF,12000,
+             EQ_CUTOFF_MIN,EQ_CUTOFF_MAX,EQ_CUTOFF_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 4 cutoff"),
+    /* 0..64 (or 0.0 to 6.4) */
+    INT_ITEM(0,eq_band0_q,LANG_EQUALIZER_BAND_Q,7,
+             EQ_Q_MIN,EQ_Q_MAX,EQ_Q_STEP,UNIT_DB, NULL, NULL,"eq band 0 q"),
+    INT_ITEM(0,eq_band1_q,LANG_EQUALIZER_BAND_Q,10,
+             EQ_Q_MIN,EQ_Q_MAX,EQ_Q_STEP,UNIT_DB, NULL, NULL,"eq band 1 q"),
+    INT_ITEM(0,eq_band2_q,LANG_EQUALIZER_BAND_Q,10,
+             EQ_Q_MIN,EQ_Q_MAX,EQ_Q_STEP,UNIT_DB, NULL, NULL,"eq band 2 q"),
+    INT_ITEM(0,eq_band3_q,LANG_EQUALIZER_BAND_Q,10,
+             EQ_Q_MIN,EQ_Q_MAX,EQ_Q_STEP,UNIT_DB, NULL, NULL,"eq band 3 q"),
+    INT_ITEM(0,eq_band4_q,LANG_EQUALIZER_BAND_Q,7,
+             EQ_Q_MIN,EQ_Q_MAX,EQ_Q_STEP,UNIT_DB, NULL, NULL,"eq band 4 q"),
+    /* -240..240 (or -24db to +24db) */
+    INT_ITEM(0,eq_band0_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_GAIN_MIN,EQ_GAIN_MAX,EQ_GAIN_STEP,UNIT_DB,
+             NULL, NULL,"eq band 0 gain"),
+    INT_ITEM(0,eq_band1_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_GAIN_MIN,EQ_GAIN_MAX,EQ_GAIN_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 1 gain"),
+    INT_ITEM(0,eq_band2_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_GAIN_MIN,EQ_GAIN_MAX,EQ_GAIN_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 2 gain"),
+    INT_ITEM(0,eq_band3_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_GAIN_MIN,EQ_GAIN_MAX,EQ_GAIN_STEP,UNIT_DB, 
+             NULL, NULL,"eq band 3 gain"),
+    INT_ITEM(0,eq_band4_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_GAIN_MIN,EQ_GAIN_MAX,EQ_GAIN_STEP,UNIT_DB,
+             NULL, NULL,"eq band 4 gain"),
+    BOOL_ITEM(0,dithering_enabled,LANG_DITHERING, false,NULL, "dithering enabled"),
+#endif
+#endif /* CONFIG_CODEC == SWCODEC */
+
+#ifdef HAVE_WM8758
+    /* hardware eq */
+    BOOL_ITEM(0,eq_hw_enabled,LANG_EQUALIZER_HARDWARE_ENABLED,
+              false,NULL, "eq hardware enabled"),
+    /* band 0 */
+    STRINGCHOICE_ITEM(0,eq_hw_band0_cutoff,LANG_EQUALIZER_BAND_CUTOFF,
+                      "eq hardware band 0 cutoff",1,4,
+                      _STR("80Hz","105Hz","135Hz","175Hz"),
+                      _TALKID(TALK_ID(80, UNIT_HERTZ),TALK_ID(105, UNIT_HERTZ),
+                              TALK_ID(135, UNIT_HERTZ),TALK_ID(175, UNIT_HERTZ)),
+                      NULL),
+    INT_ITEM(0,eq_band0_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_HW_GAIN_MIN,EQ_HW_GAIN_MAX,EQ_HW_GAIN_STEP,
+             UNIT_DB, NULL, NULL,"eq hardware band 0 gain"),
+    /* band 1 */
+    STRINGCHOICE_ITEM(0,eq_hw_band1_center,LANG_EQUALIZER_BAND_CENTER,
+                      "eq hardware band 1 center",1,4,
+                      _STR("230Hz","300Hz","385Hz","500Hz"),
+                      _TALKID(TALK_ID(230, UNIT_HERTZ),TALK_ID(300, UNIT_HERTZ),
+                              TALK_ID(385, UNIT_HERTZ),TALK_ID(500, UNIT_HERTZ)),
+                      NULL),
+    CHOICE_ITEM(0,eq_hw_band1_bandwidth,LANG_EQUALIZER_BANDWIDTH,
+                "eq hardware band 1 bandwidth,narrow,wide", 0,NULL,2,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE),
+    INT_ITEM(0,eq_hw_band1_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_HW_GAIN_MIN,EQ_HW_GAIN_MAX,EQ_HW_GAIN_STEP,UNIT_DB,
+             NULL, NULL, "eq hardware band 1 gain"),
+    /* band 2 */
+    STRINGCHOICE_ITEM(0,eq_hw_band2_center,LANG_EQUALIZER_BAND_CENTER,
+                      "eq hardware band 2 center",1,4,
+                      _STR("650Hz","850Hz","1100Hz","1400Hz"),
+                      _TALKID(TALK_ID(650, UNIT_HERTZ),TALK_ID(850, UNIT_HERTZ),
+                              TALK_ID(1100, UNIT_HERTZ),
+                              TALK_ID(1400, UNIT_HERTZ)),NULL),
+    CHOICE_ITEM(0,eq_hw_band2_bandwidth,LANG_EQUALIZER_BANDWIDTH,
+                "eq hardware band 2 bandwidth,narrow,wide", 0,NULL,2,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE),
+    INT_ITEM(F_LANG_HARDWARE,eq_hw_band2_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_HW_GAIN_MIN,EQ_HW_GAIN_MAX,EQ_HW_GAIN_STEP,UNIT_DB,
+             NULL, NULL, "eq hardware band 2 gain"),
+    /* band 3 */
+    STRINGCHOICE_ITEM(0,eq_hw_band3_center,LANG_EQUALIZER_BAND_CENTER,
+                      "eq hardware band 3 center",1,4,
+                      _STR("1800Hz","2400Hz","3200Hz","4100Hz"),
+                      _TALKID(TALK_ID(1800, UNIT_HERTZ),TALK_ID(2400, UNIT_HERTZ),
+                              TALK_ID(3200, UNIT_HERTZ),
+                              TALK_ID(4100, UNIT_HERTZ)),NULL),
+    CHOICE_ITEM(0,eq_hw_band3_bandwidth,LANG_EQUALIZER_BANDWIDTH
+            "eq hardware band 3 bandwidth,narrow,wide", 0,NULL,2,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW,
+                LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE),
+    INT_ITEM(F_LANG_HARDWARE,eq_hw_band3_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_HW_GAIN_MIN,EQ_HW_GAIN_MAX,EQ_HW_GAIN_STEP,
+             UNIT_DB, NULL, NULL,"eq hardware band 3 gain"),
+    /* band 4 */
+    STRINGCHOICE_ITEM(0,eq_hw_band4_cutoff,LANG_EQUALIZER_BAND_CUTOFF,
+                      "eq hardware band 4 cutoff",1,4,
+                      _STR("5300Hz","6900Hz","9000Hz","11700Hz"),
+                      _TALKID(TALK_ID(5300, UNIT_HERTZ),TALK_ID(6900, UNIT_HERTZ),
+                              TALK_ID(9000, UNIT_HERTZ),
+                              TALK_ID(11700, UNIT_HERTZ)),NULL),
+    INT_ITEM(0,eq_band4_gain,LANG_EQUALIZER_BAND_GAIN,0,
+             EQ_HW_GAIN_MIN,EQ_HW_GAIN_MAX,EQ_HW_GAIN_STEP,
+             UNIT_DB, NULL, NULL,"eq hardware band 4 gain"),
+#endif /* HAVE_WM8758 */
+
+/*    BOOL_ITEM(0,hold_lr_for_scroll_in_list,
+              LANG_HOLD_DIRECTION_FOR_SCROLL, true,NULL,
+              "hold_lr_for_scroll_in_list"),
+*/    CHOICE_ITEM(0,show_path_in_browser,LANG_SHOW_PATH,
+                "show path in browser,off,current directory,full path",0,NULL,3,
+                LANG_OFF,LANG_SHOW_PATH_CURRENT, LANG_SHOW_PATH_FULL),
+
+#ifdef HAVE_AGC
+    /* active gain control */
+    CHOICE_ITEM(0,rec_agc_preset_mic,LANG_RECORD_AGC_PRESET,
+                "agc mic preset", 1,NULL,6,
+                LANG_OFF,LANG_AGC_SAFETY, LANG_AGC_LIVE,
+                LANG_AGC_DJSET, LANG_AGC_MEDIUM, LANG_AGC_VOICE),
+    CHOICE_ITEM(0,rec_agc_preset_line,LANG_RECORD_AGC_PRESET,
+                "agc line preset", 1,NULL,6,
+                LANG_OFF,LANG_AGC_SAFETY, LANG_AGC_LIVE,
+                LANG_AGC_DJSET, LANG_AGC_MEDIUM, LANG_AGC_VOICE),
+    SYSTEM_ITEM(F_T_INT,rec_agc_maxgain_mic,104, NULL),
+    SYSTEM_ITEM(F_T_INT,rec_agc_maxgain_line,96, NULL),
+    STRINGCHOICE_ITEM(0,rec_agc_cliptime,LANG_RECORD_AGC_CLIPTIME,
+                      "agc cliptime",1,5,
+                      _STR("0.2s","0.4s","0.6s","0.8s","1s"),
+                      _TALKID(TALK_ID(200, UNIT_MS),TALK_ID(400, UNIT_MS),
+                              TALK_ID(600, UNIT_MS),TALK_ID(800, UNIT_MS),
+                              TALK_ID(1, UNIT_SEC)),NULL),
+#endif /* HAVE_AGC */
+
+#ifdef HAVE_REMOTE_LCD
+#ifdef HAS_REMOTE_BUTTON_HOLD
+    CHOICE_ITEM(0,remote_backlight_on_button_hold,LANG_BACKLIGHT_ON_BUTTON_HOLD,
+                      "remote backlight on button hold,normal,off,on",0,NULL,3,
+                  LANG_BACKLIGHT_ON_BUTTON_HOLD_NORMAL,LANG_OFF,LANG_ON),
+#endif
+#endif /* HAVE_REMOTE_LCD */
+
+    /* filename storage */
+#ifdef CONFIG_TUNER
+    STRING_ITEM(F_FILENAMEONLY,fmr_file,"fmr","",NULL),
+#endif
+    STRING_ITEM(F_FILENAMEONLY,font_file,"font","",NULL),
+    STRING_ITEM(F_FILENAMEONLY,wps_file,"wps","",NULL),
+#ifdef HAVE_REMOTE_LCD
+    STRING_ITEM(F_FILENAMEONLY,rwps_file,"rwps","",NULL),
+#endif
+    STRING_ITEM(F_FILENAMEONLY,lang_file,"lang","",NULL),
+#ifdef HAVE_LCD_COLOR
+    STRING_ITEM(F_FILENAMEONLY,backdrop_file,"backdrop","",NULL),
+#endif
+#ifdef HAVE_LCD_BITMAP
+    STRING_ITEM(F_FILENAMEONLY,kbd_file,"keyboard","",NULL),
+#endif
+#ifdef HAVE_HEADPHONE_DETECTION
+    CHOICE_ITEM(0,unplug_mode,LANG_UNPLUG,
+                "pause on headphone unplug,off,pause,resume", 0,NULL,3,
+                LANG_OFF,LANG_PAUSE, LANG_UNPLUG_RESUME),
+    INT_ITEM(0,unplug_rw,LANG_UNPLUG_RW,0,
+             0,15,1,UNIT_SEC, NULL, NULL,"rewind duration on pause"),
+    BOOL_ITEM(0,unplug_autoresume,
+              LANG_UNPLUG_DISABLE_AUTORESUME, false, NULL,
+              "disable autoresume if phones not present"),
+#endif
+    BOOL_ITEM(0,audioscrobbler,
+              LANG_AUDIOSCROBBLER, false, NULL,
+              "Last.fm Logging"),
+
+};
+const int nb_settings = sizeof(settings) / sizeof(*settings);
Index: apps/settings_list.h
===================================================================
RCS file: apps/settings_list.h
diff -N apps/settings_list.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ apps/settings_list.h	14 Nov 2006 14:34:33 -0000
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id:  $
+ *
+ * Copyright (C) 2006 Jonathan Gordon
+ *
+ * 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 __SETTINGSLIST_H
+#define __SETTINGSLIST_H
+#include "config.h"
+
+union storage_type {
+    int int_;
+    unsigned int uint_;
+    bool bool_;
+    char *charptr;
+    unsigned char *ucharptr;
+};
+/* the variable type for the setting */
+#define F_T_INT     1
+#define F_T_UINT    2
+#define F_T_BOOL    3
+#define F_T_CHARPTR 4
+#define F_T_UCHARPTR 5
+#define F_T_MASK    0x7     /* we can go up to 7 types, 3 bits should be enough */
+#define F_T_SOUND   0x8     /* this variable uses the set_sound stuff, | with one of the above types \
+                               values[0] = setting type */
+                            
+#define F_T_CHOICE  0x10    /* this variable is a "choice" type, \
+                               if this is not set then values[0] = min, values[1] = max, values[2] = step   \
+                               talk_id[0] = talk unit                                                       */
+#define F_LANG_STRING 0x20  /* this variable uses *strings in the union for the values, donot try to xlate  \
+                               unless talk_id is NULL it will try to talk the corresponding value there     \
+                               talk_id is only needed to be filled if this is set */
+                               
+#define F_LANG_REMOTE 0x40  /* prepends "Remote " to the setting name in the config file */
+#define F_LANG_HARDWARE 0x80  /* prepends "Hardware " to the setting name in the config file */
+/* F_LANG_REMOTE and F_LANG_HARDWARE are mutually exclusive... */
+
+#define F_LANG_IS_STRING 0x100 /* use this if the cfg_string vairable is used instead of cfg_lang_id */
+#define F_TEMPVARIABLE  0x200 /* set this to have only set the new value after it has been accepted, i.e for lcd mod */
+#define F_STORERGB      0x400 /* save it as rgb in the text file, but store as LCDPACK() */
+#define F_SYSTEMSETTING 0x800 /* if set it will be saved in data.dat not config.cfg */
+
+#define F_STOREREALVALUE 0x1000 /* use this to store a real value instead of the index into the values/strings array */
+#define F_SAVETORTC     0x2000 /* use this if the setting must be saved to non-volatile RAM if the target has */
+#define F_FILENAMEONLY  0x4000 /* use this for string settings which need to have the path removed */
+#define F_NUMBEREDVAR_SHIFT 16
+#define F_NUMBEREDVAR_MASK 0xF0000
+
+struct settings_list {
+    int                 flags;     /* ____ ____ ____ NNNN _FRV SRTS HRSC STTT */
+    short               setting_offset;  /* the variable in global_settings, use GS() macro for this */
+    union storage_type default_val;
+    union {
+        int             cfg_lang_id;  /* lang_id of this variable in the .cfg file */
+        char           *cfg_string;   /* for system settings which are not translated */
+    };
+    int                 nb_values; /* # of values, ignored unless F_T_CHOICE is set */
+    union {
+        int             *values;    /* If F_T_CHOICE is not set and (F_T_MASK!=F_T_BOOL)        */
+        char           **strings;   /*    then values[0] = min, [1]=max, [2]=step. [3]=formatter   */
+    };
+    int                *talk_id;
+    void        (*function)(bool);  /* callback to pass to set_option() */
+    char               *conf_file_info; /* comma seperated list,
+                                           the first item is the setting name, 
+                                    then all the valid options, BOOL and INT only need to setting name */
+    /* If F_T_SOUND is set then default_val, values and nb_values are ignored */ 
+};
+
+#ifndef PLUGIN
+/* not needed for plugins and just causes compile error, possibly fix proberly later */
+extern const int nb_settings;
+extern const struct settings_list  settings[];
+#endif
+    
+    
+#endif
Index: firmware/export/kernel.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/kernel.h,v
retrieving revision 1.28
diff -u -r1.28 kernel.h
--- firmware/export/kernel.h	19 Oct 2006 11:43:13 -0000	1.28
+++ firmware/export/kernel.h	14 Nov 2006 14:34:35 -0000
@@ -48,6 +48,7 @@
 #define SYS_CHARGER_DISCONNECTED  ((SYS_EVENT | ((long)11 << 27)))
 #define SYS_PHONE_PLUGGED         ((SYS_EVENT | ((long)12 << 27)))
 #define SYS_PHONE_UNPLUGGED       ((SYS_EVENT | ((long)13 << 27)))
+#define SYS_DUMPSETTINGS          ((SYS_EVENT | ((long)14 << 27)))
 
 struct event
 {
