aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot-sam460ex/board/ACube/menu
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot-sam460ex/board/ACube/menu
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot-sam460ex/board/ACube/menu')
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/bios_menu.c449
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/bios_menu.h8
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.c112
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.h8
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/cmd_menu.c176
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/creation.c168
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/creation.h20
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/func_items.c118
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/func_items.h7
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/label_items.c47
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/label_items.h6
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/layout.c81
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/layout.h6
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/list.c37
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/list.h39
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/menu.c374
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/menu.h279
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/popup_items.c150
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/popup_items.h6
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/string_edit.c177
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/string_edit.h6
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/string_items.c133
-rw-r--r--roms/u-boot-sam460ex/board/ACube/menu/string_items.h6
23 files changed, 2413 insertions, 0 deletions
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.c b/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.c
new file mode 100644
index 000000000..0f4849aa8
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.c
@@ -0,0 +1,449 @@
+#include "menu.h"
+#include "bios_menu.h"
+#include "creation.h"
+
+/*
+ * These hooks are for usage with popup menus. Assumes that user_data is the name of
+ * the variable to save to / load from.
+ *
+ * entries is the array of entries that may fit. This function returns -1 if none
+ * of the entries fits, indicating that the default should be considered.
+ */
+
+int cvar_popup_load(void *user_data, popup_entry_t *entries)
+{
+ char
+ *var = GETENV((char *)user_data);
+ int
+ i=0;
+
+ while (var && entries->value_text)
+ {
+ if (entries->value_text != (char *)(~0) && (strcmp(var, entries->value_text) == 0))
+ {
+ return i;
+ }
+ i++;
+ entries++;
+ }
+
+ return -1;
+}
+
+void cvar_popup_save(void *user_data, popup_entry_t *entry)
+{
+ SETENV((char *)user_data, entry->value_text);
+}
+
+int cvar_numeric_load(void *user_data, int param2, int def_val)
+{
+ char *var = GETENV((char *)user_data);
+
+ if (var) return atoi(var);
+ else return def_val;
+}
+
+static void cvar_numeric_save(void *user_data, int param2, int value)
+{
+ char buffer[30];
+ sprintf(buffer, "%d", value);
+ SETENV((char *)user_data, buffer);
+}
+
+#define TABLE_END {NULL, NULL, NULL}
+#define LABEL(x) menu_item_create(ITEMTYPE_LABEL, menu, #x)
+#define SPACER menu_item_create(ITEMTYPE_LABEL, menu, " ")
+
+#define MAIN_MENU_NAME "U-BOOT Preferences Menu"
+#ifdef CONFIG_SAM460EX
+#define PCIE_SATA_NAME "PCI-E 1x / SATA-2"
+#endif
+#define BOOTSEQ_NAME "Boot Sequence"
+#define NETBOOT_NAME "Network Boot Options"
+#define SYSTEM_INFO_NAME "System Information"
+#define AMIGABOOT_NAME "OS MultiBoot Options"
+#define VIDEO_NAME "Video Options"
+
+
+/**************************************************************************************
+ MAIN MENU
+ *************************************************************************************/
+
+menu_t *make_main_menu(form_t *form)
+{
+ menu_t
+ *menu = new_menu(MENUTYPE_FORM, MAIN_MENU_NAME, form, NULL);
+
+ if (menu)
+ {
+ item_t *item;
+
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "Video Options", VIDEO_NAME); //TEST_ITEM();
+ menu_item_set_help(item, "Select the current video card");
+
+#ifdef CONFIG_SAM460EX
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "PCI-E 1x / SATA-2", PCIE_SATA_NAME); //TEST_ITEM();
+ menu_item_set_help(item, "Select PCI-E 1x / SATA-2");
+#endif
+
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "Boot Sequence", BOOTSEQ_NAME); //TEST_ITEM();
+ menu_item_set_help(item, "Adjust parameters for booting an OS");
+
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "System Information", SYSTEM_INFO_NAME); //TEST_ITEM();
+ menu_item_set_help(item, "Information about the hardware installed on this machine");
+
+ }
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+/**************************************************************************************
+ PCI-E/SATA Menu
+ *************************************************************************************/
+#ifdef CONFIG_SAM460EX
+popup_entry_t pcie_sata_select_entries[] =
+{
+ {"SATA-2", "sata2", NULL},
+ {"PCI-E 1x", "pci-e", NULL},
+ TABLE_END,
+};
+
+menu_t *make_pcie_sata_menu(form_t *form)
+{
+ menu_t *menu = new_menu(MENUTYPE_FORM, PCIE_SATA_NAME, form, MAIN_MENU_NAME);
+
+ item_t
+ *item;
+
+ if (menu)
+ {
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Select PCI-E 1x / SATA-2", 0, "serdes",
+ cvar_popup_save, cvar_popup_load,
+ pcie_sata_select_entries);
+ menu_item_set_help(item, "Choose to acticate PCI-E 1x slot or the onchip "\
+ "SATA-2 port (requires reboot and changing J16 on motherboard)");
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+#endif
+
+/**************************************************************************************
+ Video Menu
+ *************************************************************************************/
+
+popup_entry_t video_select_entries[] =
+{
+#if defined(CONFIG_SAM440EP_FLEX)
+ {"PCI", "pci", NULL},
+ {"SM502", "sm502", NULL},
+#elif defined(CONFIG_SAM460EX)
+ {"Onboard", "sm502", NULL},
+ {"PCI/PCI-E", "pci", NULL},
+#else
+ {"Internal", "internal", NULL},
+ {"PCI", "pci", NULL},
+#endif
+ TABLE_END,
+};
+
+popup_entry_t silent_select_entries[] =
+{
+ {"Verbose", "0", NULL},
+ {"Silent", "1", NULL},
+ TABLE_END,
+};
+
+menu_t *make_video_menu(form_t *form)
+{
+ menu_t *menu = new_menu(MENUTYPE_FORM, VIDEO_NAME, form, MAIN_MENU_NAME);
+
+ item_t
+ *item;
+
+ if (menu)
+ {
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Boot from graphics card", 0, "video_activate",
+ cvar_popup_save, cvar_popup_load,
+ video_select_entries); //TEST_ITEM();
+
+#if defined(CONFIG_SAM440EP_FLEX)
+ menu_item_set_help(item, "Choose whether the PCI ATI or the SM502 "\
+ "graphics card is activated (requires reboot)");
+#elif defined(CONFIG_SAM460EX)
+ menu_item_set_help(item, "Choose whether the PCI/PCI-E or the onboard "\
+ "graphics card is activated (requires reboot)");
+#else
+ menu_item_set_help(item, "Choose whether the internal ATI M9 or a PCI "\
+ "graphics card is activated (requires reboot)");
+#endif
+
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Console", 2, "hush",
+ cvar_popup_save, cvar_popup_load,
+ silent_select_entries);
+ menu_item_set_help(item, "Suppress most console messages on the screen while booting");
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+/**************************************************************************************
+ Boot Sequence
+ *************************************************************************************/
+
+popup_entry_t boot_seq[] =
+{
+ {"0680 PATA HD", "psii", NULL},
+ {"0680 PATA DVD", "psiicdrom", NULL},
+ {"3x12 SATA HD", "ssii", NULL},
+ {"3x12 SATA DVD", "ssiicdrom", NULL},
+ {"3114 SATA HD", "s4sii", NULL},
+ {"3114 SATA DVD", "s4siicdrom", NULL},
+#ifdef CONFIG_SAM460EX
+ {"460 SATA2 HD", "sata2-460", NULL},
+#endif
+ {"USB DVD", "ucdrom", NULL},
+ {"USB HD", "usb", NULL},
+ {"Network", "net", NULL},
+ {"none", "", NULL},
+ TABLE_END,
+};
+
+menu_t *make_netboot_menu(form_t *form)
+{
+ menu_t
+ *menu = new_menu(MENUTYPE_FORM, NETBOOT_NAME, form, BOOTSEQ_NAME);
+
+ item_t
+ *item;
+
+ if (menu)
+ {
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Local TCP/IP Address", "ipaddr", ""); //TEST_ITEM();
+ menu_item_set_help(item, "Local TCP/IP address for network boot");
+
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Server TCP/IP Address", "serverip", ""); //TEST_ITEM();
+ menu_item_set_help(item, "Server IP address. Server must be running a supported networking boot service");
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+menu_t *make_amigaboot_menu(form_t *form)
+{
+ menu_t
+ *menu = new_menu(MENUTYPE_FORM, AMIGABOOT_NAME, form, BOOTSEQ_NAME);
+
+ item_t
+ *item;
+
+ if (menu)
+ {
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Boot Device 1", 0, "boot1",
+ cvar_popup_save, cvar_popup_load, boot_seq); //TEST_ITEM();
+ menu_item_set_help(item, "Select first boot device");
+
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Boot Device 2", 2, "boot2",
+ cvar_popup_save, cvar_popup_load, boot_seq); //TEST_ITEM();
+ menu_item_set_help(item, "Select second boot device");
+
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Boot Device 3", 4, "boot3",
+ cvar_popup_save, cvar_popup_load, boot_seq); //TEST_ITEM();
+ menu_item_set_help(item, "Select third boot device");
+
+ SPACER;
+
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "OS Selection timeout", "boota_timeout", "3"); //TEST_ITEM();
+ menu_item_set_help(item, "The amount of time the OS selection menu waits before booting");
+
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+menu_t *make_boot_menu(form_t *form)
+{
+ menu_t
+ *menu = new_menu(MENUTYPE_FORM, BOOTSEQ_NAME, form, MAIN_MENU_NAME);
+
+ item_t
+ *item;
+
+ if (menu)
+ {
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Menu Boot delay", "menuboot_delay", "3");
+ menu_item_set_help(item, "The amount of time the menu waits before continuing to boot");
+ SPACER;
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Boot arguments for AOS", "os4_commandline", "debuglevel=0"); //TEST_ITEM();
+ menu_item_set_help(item, "Argument string passed to AOS");
+
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Boot arguments for Linux", "bootargs", "root=/dev/sda3"); //TEST_ITEM();
+ menu_item_set_help(item, "Argument string passed to Linux");
+
+ SPACER;
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "Network Boot Options", NETBOOT_NAME); //TEST_ITEM();
+ item = menu_item_create(ITEMTYPE_SUBMENU, menu,
+ "OS Multiboot Options", AMIGABOOT_NAME);
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+/**************************************************************************************
+ System Information
+ *************************************************************************************/
+static void dummy(void)
+{
+}
+
+char *mystrdup(char *src)
+{
+ int
+ i = strlen(src)+1;
+
+ char
+ *s = malloc(i);
+
+ if (s)
+ {
+ strcpy(s, src);
+ }
+
+ return s;
+}
+
+menu_t *make_sysinfo_menu(form_t *form)
+{
+ char buffer[64];
+
+ menu_t
+ * menu = new_menu(MENUTYPE_FORM, SYSTEM_INFO_NAME, form, MAIN_MENU_NAME);
+
+ item_t
+ * item;
+
+ int cpu_pvr;
+
+
+ sys_info_t
+ sysinfo;
+
+ get_sys_info(&sysinfo);
+
+ if (menu)
+ {
+ {
+ DECLARE_GLOBAL_DATA_PTR;
+ cpu_pvr = get_pvr();
+
+ switch((cpu_pvr&0xffff0000)>>16)
+ {
+#ifdef CONFIG_SAM460EX
+ case 0x1302:
+ sprintf (buffer, "CPU Type : AMCC PowerPC 460ex Rev ");
+ switch (cpu_pvr&0xffff)
+ {
+ case 0x18a3:
+ strcat (buffer, "A");
+ break;
+ case 0x18a4:
+ strcat (buffer, "B");
+ break;
+ default:
+ strcat (buffer, "unknown");
+ break;
+ }
+ break;
+#else
+ case 0x4222:
+ sprintf (buffer, "CPU Type : AMCC PowerPC 440ep Rev ");
+ switch (cpu_pvr&0xffff)
+ {
+ case 0x18d3:
+ strcat (buffer, "B");
+ break;
+ case 0x18d4:
+ strcat (buffer, "C");
+ break;
+ default:
+ strcat (buffer, "unknown");
+ break;
+ }
+ break;
+#endif
+ default:
+ sprintf(buffer, "Unknown: PVR 0x%08X", cpu_pvr);
+ }
+
+ sprintf(buffer, "%s / %ld MHz", buffer, gd->cpu_clk / 1000000);
+ item = menu_item_create(ITEMTYPE_LABEL, menu, mystrdup(buffer));
+
+ sprintf(buffer, "PLB freq : %4ld MHz", sysinfo.freqPLB / 1000000);
+ item = menu_item_create(ITEMTYPE_LABEL, menu, mystrdup(buffer));
+
+#ifdef CONFIG_SAM460EX
+ sprintf(buffer, "DDR2 freq : %4ld MHz", 2 * sysinfo.freqDDR / 1000000);
+ item = menu_item_create(ITEMTYPE_LABEL, menu, mystrdup(buffer));
+#else
+ sprintf(buffer, "DDR freq : %4ld MHz", 2 * sysinfo.freqPLB / 1000000);
+ item = menu_item_create(ITEMTYPE_LABEL, menu, mystrdup(buffer));
+#endif
+
+ /**** DIMM BANK INFO ****/
+ SPACER;
+ item = menu_item_create(ITEMTYPE_LABEL, menu, "Memory");
+ sprintf(buffer, "Total : %ld MB", (gd->bd->bi_memsize) / 1024 / 1024);
+ item = menu_item_create(ITEMTYPE_LABEL, menu, mystrdup(buffer));
+ }
+ }
+
+ menu_form_add_menu(form, menu);
+ return menu;
+}
+
+void restore_func(void)
+{
+
+}
+
+void recover_func(void)
+{
+
+}
+
+/* ********************************************************************************* */
+
+void make_menus(form_t *form)
+{
+ make_video_menu(form);
+#ifdef CONFIG_SAM460EX
+ make_pcie_sata_menu(form);
+#endif
+ make_main_menu(form);
+ make_netboot_menu(form);
+ make_amigaboot_menu(form);
+ make_boot_menu(form);
+ make_sysinfo_menu(form);
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.h b/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.h
new file mode 100644
index 000000000..d32dc8138
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/bios_menu.h
@@ -0,0 +1,8 @@
+#ifndef BIOS_MENU_H
+#define BIOS_MENU_H
+
+extern popup_entry_t boot_seq[];
+extern void make_menus(form_t *form);
+
+
+#endif //BIOS_MENU_H
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.c b/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.c
new file mode 100644
index 000000000..c50b6d1f6
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.c
@@ -0,0 +1,112 @@
+#include "menu.h"
+#include "bios_menu.h" //For boot_seq.
+#include "bootselect_menu.h"
+#include "creation.h"
+
+int return_value = 0;
+
+int cvar_numeric_load(void *user_data, int param2, int def_val);
+void cvar_popup_save(void *user_data, popup_entry_t *entry);
+int cvar_popup_load(void *user_data, popup_entry_t *entries);
+
+#define LABEL(x) menu_item_create(ITEMTYPE_LABEL, menu, #x)
+#define SPACER menu_item_create(ITEMTYPE_LABEL, menu, " ")
+
+#define BOOT_MENU_NAME "U-Boot Boot Select"
+#define EXIT_MENU_NAME "Exit Menu"
+
+#define EXIT_BOOT_CONFIG 0
+#define EXIT_BOOT_NOCONFIG 1
+#define EXIT_GO_MENU 2
+
+void my_leave_func(item_t *item, void *dummy, int arg)
+{
+ setenv("boot2", "");
+ setenv("boot3", "");
+
+ switch (arg)
+ {
+ case EXIT_BOOT_CONFIG:
+ return_value = 0;
+ leave_func(item, dummy, EXIT_AND_SAVE);
+ break;
+ case EXIT_BOOT_NOCONFIG:
+ return_value = 0;
+ leave_func(item, dummy, EXIT_AND_NO_SAVE);
+ break;
+ case EXIT_GO_MENU:
+ return_value = 1;
+ leave_func(item, dummy, EXIT_AND_NO_SAVE);
+ break;
+ }
+}
+
+void make_bootselect_menu(form_t *form)
+{
+ item_t *item;
+ menu_t *menu;
+
+ // Boot Select //
+
+ menu = new_menu(MENUTYPE_FORM, BOOT_MENU_NAME, form, 0);
+
+ item = menu_item_create(ITEMTYPE_POPUP, menu,
+ "Boot Device", 0, "boot1",
+ cvar_popup_save, cvar_popup_load, boot_seq); //TEST_ITEM();
+
+ menu_item_set_help(item, "Choose which boot device should be attempted first");
+
+ SPACER;
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Boot arguments for AOS", "os4_commandline", "debuglevel=0"); //TEST_ITEM();
+ menu_item_set_help(item, "Argument string to be passed to AOS");
+
+ item = menu_item_create(ITEMTYPE_STRING_CVAR, menu,
+ "Boot arguments for Linux", "bootargs", "root=/dev/Sda3"); //TEST_ITEM();
+ menu_item_set_help(item, "Argument string to be passed to Linux");
+
+ SPACER;
+
+ menu_form_add_menu(form, menu);
+
+ // Exit //
+ menu = new_menu(MENUTYPE_POPUP, EXIT_MENU_NAME, form, 0);
+
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Boot this configuration", my_leave_func, NULL, EXIT_BOOT_CONFIG);
+ menu_item_set_help(item, "Temporarily boot this configuration");
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Go to preferences menu", my_leave_func, NULL, EXIT_GO_MENU);
+ menu_item_set_help(item, "Abort the changes and go to the preferences menu");
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Continue normal boot", my_leave_func, NULL, EXIT_BOOT_NOCONFIG);
+ menu_item_set_help(item, "Abort the changes and continue booting the normal configuration");
+ menu_set_position(menu, 6, 6);
+
+ menu_form_add_menu(form, menu);
+}
+
+void boot_establish(void)
+{
+ char *bootfinal = "";
+ char *b1 = "boota";
+ char *mboot = getenv("menuboot_cmd");
+ char *method = getenv("boot_method");
+ char *bootcommand = getenv("boot_command");
+
+ if (method == NULL) method="boota";
+
+ if (mboot && strncmp(mboot, "noboot", 6) == 0)
+ {
+ setenv("menuboot_cmd", " ");
+ return;
+ }
+
+ if (strcmp(method, "boota") == 0)
+ {
+ bootfinal = b1;
+ }
+ else
+ {
+ bootfinal = bootcommand;
+ }
+
+ setenv("menuboot_cmd", bootfinal);
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.h b/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.h
new file mode 100644
index 000000000..7cc1ef811
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/bootselect_menu.h
@@ -0,0 +1,8 @@
+#ifndef BOOTSELECT_MENU
+#define BOOTSELECT_MENU
+
+extern int return_value;
+extern void make_bootselect_menu(form_t *form);
+extern void boot_establish(void);
+
+#endif // BOOTSELECT_MENU
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/cmd_menu.c b/roms/u-boot-sam460ex/board/ACube/menu/cmd_menu.c
new file mode 100644
index 000000000..f89b0e29d
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/cmd_menu.c
@@ -0,0 +1,176 @@
+#include <common.h>
+#include <command.h>
+#include "menu.h"
+#include "bootselect_menu.h"
+#include "creation.h"
+#include "bios_menu.h"
+#include <asm/processor.h>
+
+static form_t *root = 0;
+static form_t *bootselect = 0;
+
+#define MAIN_MENU_NAME "U-BOOT Preferences Menu"
+#define BOOT_MENU_NAME "U-Boot Boot Select"
+
+static void establish_menu_settings(void);
+static int do_menu_countdown(void);
+static int fromsilent = 0;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int show_and_do_boot_select(void)
+{
+ unsigned long delta = TEXT_BASE - gd->relocaddr;
+
+ menu_item_relocate(delta);
+
+ bootselect = new_form(BOOT_MENU_NAME);
+ if (!bootselect) return 0;
+
+ make_bootselect_menu(bootselect);
+ menu_set_form(bootselect);
+ menu_form_switch_menu(bootselect, BOOT_MENU_NAME);
+ menu_do(false);
+
+ return return_value;
+}
+
+void show_and_do_bios_menu(void)
+{
+ unsigned long delta = TEXT_BASE - gd->relocaddr;
+
+ menu_item_relocate(delta);
+
+ root = new_form("U-BOOT Setup Menu");
+ if (!root) return;
+
+ make_menus(root);
+ menu_set_form(root);
+ menu_form_switch_menu(root, MAIN_MENU_NAME);
+ menu_do(true);
+}
+
+static int do_menu_countdown(void)
+{
+ int bootdelay;
+ int current;
+ char *s, c;
+
+ bootdelay = 0;
+ s = GETENV("menuboot_delay");
+
+ if (s) bootdelay = atoi(s);
+
+ if (bootdelay == 0)
+ {
+ if (tstc() != -1) return 1;
+ else return 0;
+ }
+
+ putc('\n');
+ if (fromsilent) puts(" ");
+ puts("Press SPACE for prefs, ENTER for boot select, ESC for prompt\n");
+ if (fromsilent) puts(" ");
+ puts("Booting... ");
+
+ current = 0;
+ while (current < bootdelay)
+ {
+ int i;
+
+ printf("\b\b\b%2d ", bootdelay - current);
+
+ for (i=0; i<1000; i++)
+ {
+ if (tstc())
+ {
+ c = getc();
+
+ // ESC
+ if ((c == 5) || (c == 113)) return -10;
+
+ // ENTER
+ if (c == 13) return show_and_do_boot_select();
+
+ // SPACE
+ if (c == 32) return 1;
+ }
+ udelay(1000);
+ }
+ current++;
+ }
+
+ return 0;
+}
+
+extern u32 *fb_base_phys;
+extern u32 *fb_base_phys_sm502;
+
+int do_menu( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] )
+{
+ int ret = 0;
+
+ // if console was silent, revert it back
+ if (gd->flags & GD_FLG_SILENT) {
+ fromsilent = 1;
+ gd->flags &= ~GD_FLG_SILENT;
+ }
+
+ // only if there is an active vga -------------------------------
+#ifdef CONFIG_SAM440EP
+ if (fb_base_phys)
+#else
+ if ((fb_base_phys) || (fb_base_phys_sm502))
+#endif
+ {
+ if (flag==0)
+ {
+ video_set_color(0);
+ show_and_do_bios_menu();
+ puts("\n");
+ video_set_color(0);
+ return 0;
+ }
+ else
+ {
+ ret = do_menu_countdown();
+
+ if (ret == -10)
+ {
+ puts("\b\b\b break..\n");
+ setenv("menuboot_cmd", " ");
+ return 0;
+ }
+
+ if (ret == 1)
+ {
+ video_set_color(0);
+ show_and_do_bios_menu();
+ }
+
+ video_clear_attr();
+ establish_menu_settings();
+ puts("\n");
+ video_set_color(0);
+ return 0;
+ }
+ }
+ else return -1;
+}
+
+/*
+ * This routine establishes all settings from the menu that aren't already done
+ * by the standard setup.
+ */
+
+static void establish_menu_settings(void)
+{
+ boot_establish();
+
+}
+
+U_BOOT_CMD(
+ menu, 1, 1, do_menu,
+ "Show preferences menu",
+ "Show the preferences menu that is used to boot an OS\n"
+ );
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/creation.c b/roms/u-boot-sam460ex/board/ACube/menu/creation.c
new file mode 100644
index 000000000..314481e94
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/creation.c
@@ -0,0 +1,168 @@
+#include "menu.h"
+#include <stdarg.h>
+#include <malloc.h>
+#include "func_items.h"
+#include "popup_items.h"
+#include "string_items.h"
+#include "label_items.h"
+
+#define SINGLE_BOX 0
+#define DOUBLE_BOX 1
+
+/* -- Forms -- */
+form_t *new_form(char *title)
+{
+ form_t *form = (form_t *)malloc(sizeof(form_t));
+ if (form)
+ {
+ memset(form, 0, sizeof(form_t));
+ form->form_title = title;
+ list_init(& form->menu_list);
+ }
+ return form;
+}
+
+void menu_form_set_menu(form_t *form, menu_t *menu)
+{
+ item_t *item = (item_t *)(menu->item_list.first);
+ while (item)
+ {
+ if (item->f_load) item->f_load(menu, item);
+ item = (item_t *)(item->link.next);
+ }
+
+ form->current_menu = menu;
+ menu_draw_form(form);
+}
+
+void menu_form_add_menu(form_t *form, menu_t *menu)
+{
+ list_add(&(form->menu_list), (node_t *)menu);
+}
+
+menu_t* menu_form_find_menu(form_t *form, char *name)
+{
+ node_t *n;
+ n = form->menu_list.first;
+ while (n)
+ {
+ if (strcmp(name, ((menu_t *)n)->menu_title) == 0)
+ return (menu_t *)n;
+ n = n->next;
+ }
+ return NULL;
+}
+
+/* -- Menus -- */
+menu_t *new_menu(int type, char *title, form_t *parent, char *parent_menu)
+{
+ menu_t *menu = (menu_t *)malloc(sizeof(menu_t));
+ if (menu)
+ {
+ menu->type = type;
+ menu->menu_title = title;
+ menu->parent_form = parent;
+ menu->x = menu->y = 0;
+ menu->w = menu->h = 0;
+ menu->needs_layout = true;
+ menu->item_spacing = 1;
+ menu->parent_menu = parent_menu;
+ menu->current_item = NULL;
+ list_init(&(menu->item_list));
+ }
+ return menu;
+}
+
+void menu_set_position(menu_t *menu, int line, int col)
+{
+ if (menu)
+ {
+ menu->x = col;
+ menu->y = line;
+ }
+}
+
+void menu_add_item(menu_t *menu, item_t *item)
+{
+ list_add(&(menu->item_list), (node_t *)item);
+ menu->needs_layout = true;
+}
+
+/* Items */
+
+typedef struct
+{
+ int type;
+ item_t * (*create)(menu_t *, va_list);
+} itemtype_t;
+
+
+itemtype_t item_types_templates[] =
+{
+ //{ ITEMTYPE_BOOL_CVAR, itemtype_bool_cvar_alloc },
+ { ITEMTYPE_FUNC, itemtype_func_alloc },
+ { ITEMTYPE_SUBMENU, itemtype_submenu_alloc },
+ { ITEMTYPE_POPUP, itemtype_popup_alloc },
+ { ITEMTYPE_STRING_CVAR, itemtype_string_cvar_alloc },
+ { ITEMTYPE_LABEL, itemtype_label_alloc },
+ //{ ITEMTYPE_NUMERIC, itemtype_numeric_alloc },
+ //{ ITEMTYPE_REGISTER, itemtype_register_alloc },
+};
+
+itemtype_t item_types[10];
+
+
+#define NUM_ITEMTYPES (sizeof(item_types) / sizeof(itemtype_t))
+
+void menu_item_relocate(unsigned long offset)
+{
+ int i;
+ for (i=0; i<NUM_ITEMTYPES; i++)
+ {
+ item_types[i].type = item_types_templates[i].type;
+ item_types[i].create =
+ (item_t * (*)(menu_t *, va_list)) ((unsigned char *)item_types_templates[i].create); // - offset);
+ }
+}
+
+item_t *menu_item_create(int type, menu_t *menu, ...)
+{
+ va_list args;
+ int i;
+ item_t *new_item;
+
+ for (i=0; i<NUM_ITEMTYPES; i++)
+ {
+ if (item_types[i].type == type)
+ {
+ va_start(args, menu);
+ new_item = item_types[i].create(menu, args);
+ va_end(args);
+ if (menu)
+ {
+ menu_add_item(menu, new_item);
+ }
+ return new_item;
+ }
+ }
+
+ return NULL;
+}
+
+void menu_item_init(item_t *item)
+{
+ item->disabled = false;
+ item->break_after = false;
+ item->help_text = NULL;
+}
+
+void menu_item_break_after(item_t *item)
+{
+ if (item) item->break_after = true;
+}
+
+void menu_item_set_help(item_t *item, char *help_string)
+{
+ if (item)
+ item->help_text = help_string;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/creation.h b/roms/u-boot-sam460ex/board/ACube/menu/creation.h
new file mode 100644
index 000000000..d5e1668bd
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/creation.h
@@ -0,0 +1,20 @@
+#ifndef CREATION_H
+#define CREATION_H
+
+form_t *new_form(char *title);
+void menu_form_set_menu(form_t *form, menu_t *menu);
+void menu_item_relocate(unsigned long offset);
+void menu_form_add_menu(form_t *form, menu_t *menu);
+menu_t* menu_form_find_menu(form_t *form, char *name);
+menu_t *new_menu(int type, char *title, form_t *parent, char *parent_menu);
+void menu_set_position(menu_t *menu, int line, int col);
+void menu_add_item(menu_t *menu, item_t *item);
+
+item_t* menu_item_create(int type, menu_t *menu, ...);
+void menu_item_set_help(item_t *item, char *help_string);
+void menu_item_init(item_t *item);
+void menu_item_break_after(item_t *item);
+void *mymalloc(size_t size);
+
+#endif // CREATION_H
+
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/func_items.c b/roms/u-boot-sam460ex/board/ACube/menu/func_items.c
new file mode 100644
index 000000000..65a905a4c
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/func_items.c
@@ -0,0 +1,118 @@
+#include "menu.h"
+#include "func_items.h"
+#include <stdarg.h>
+#include "creation.h"
+
+struct func_item
+{
+ item_t item;
+ char *display_text;
+ void *param1;
+ int param2;
+ void (*func)(item_t *,void *, int);
+};
+
+void itemtype_func_render(menu_t *menu, item_t *item, int state)
+{
+ struct func_item *it = (struct func_item *)item;
+ int x,y;
+ x = menu->x + item->x;
+ y = menu->y + item->y;
+
+ video_draw_text(x,y, state, it->display_text, item->w);
+}
+
+void itemtype_func_invoke(menu_t *menu, item_t *item, int key)
+{
+ struct func_item *it = (struct func_item *)item;
+ switch(key)
+ {
+ case KEY_ACTIVATE:
+ if (it->func)
+ {
+ it->func(item, it->param1, it->param2);
+ }
+ break;
+ }
+}
+
+item_t *itemtype_func_alloc(menu_t *menu, va_list args)
+{
+ //char *s;
+ struct func_item *item = (struct func_item *)malloc(sizeof(struct func_item));
+ if (!item) return NULL;
+ menu_item_init(&item->item);
+
+ item->display_text = va_arg(args, char *);
+ item->func = va_arg(args, void *);
+ item->param1 = va_arg(args, void *);
+ item->param2 = va_arg(args, int);
+
+ item->item.f_render = itemtype_func_render;
+ item->item.f_save = NULL;
+ item->item.f_invoke = itemtype_func_invoke;
+ item->item.f_load = NULL;
+
+ item->item.w = item->item.front_width = strlen(item->display_text);
+ item->item.back_width = 0;
+ item->item.h = 1;
+ item->item.disabled = false;
+
+ return (item_t *)item;
+}
+
+struct submenu_item
+{
+ item_t item;
+ char *display_text;
+ char *menu;
+};
+
+void itemtype_submenu_render(menu_t *menu, item_t *item, int state)
+{
+ struct func_item *it = (struct func_item *)item;
+ int x,y;
+ x = menu->x + item->x;
+ y = menu->y + item->y;
+
+ video_draw_text(x,y, state, it->display_text, item->w);
+}
+
+void itemtype_submenu_invoke(menu_t *menu, item_t *item, int key)
+{
+ char *men_name;
+ switch(key)
+ {
+ case KEY_ACTIVATE:
+ case KEY_NEXT_OPTION:
+ case KEY_PREV_OPTION:
+ break;
+ default:
+ return;
+ }
+
+ men_name = ((struct submenu_item *)item)->menu;
+ menu_form_switch_menu(menu->parent_form, men_name);
+}
+
+item_t *itemtype_submenu_alloc(menu_t *menu, va_list args)
+{
+ struct submenu_item *item = (struct submenu_item *)malloc(sizeof(struct submenu_item));
+ if (!item) return NULL;
+ menu_item_init(&item->item);
+
+ item->display_text = va_arg(args, char *);
+ item->menu = va_arg(args, char *);
+
+ item->item.f_render = itemtype_submenu_render;
+ item->item.f_save = NULL;
+ item->item.f_invoke = itemtype_submenu_invoke;
+ item->item.f_load = NULL;
+
+ item->item.w = item->item.front_width = strlen(item->display_text);
+ item->item.back_width = 0;
+ item->item.h = 1;
+ item->item.disabled = false;
+
+ return (item_t *)item;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/func_items.h b/roms/u-boot-sam460ex/board/ACube/menu/func_items.h
new file mode 100644
index 000000000..ae805a9e4
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/func_items.h
@@ -0,0 +1,7 @@
+#ifndef FUNC_ITEMS_H
+#define FUNC_ITEMS_H
+
+item_t *itemtype_func_alloc(menu_t *menu, va_list args);
+item_t *itemtype_submenu_alloc(menu_t *menu, va_list args);
+
+#endif
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/label_items.c b/roms/u-boot-sam460ex/board/ACube/menu/label_items.c
new file mode 100644
index 000000000..a74d4c32b
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/label_items.c
@@ -0,0 +1,47 @@
+#include "menu.h"
+#include <stdarg.h>
+#include "label_items.h"
+#include "creation.h"
+
+struct label_item
+{
+ item_t item;
+ char *display_text;
+};
+
+void itemtype_label_render(menu_t *menu, item_t *item, int state)
+{
+ struct label_item *it = (struct label_item *)item;
+ int x,y;
+ x = menu->x + item->x;
+ y = menu->y + item->y;
+
+ video_draw_text(x,y, state, it->display_text, item->w);
+}
+
+void itemtype_label_invoke(menu_t *menu, item_t *item, int key)
+{
+}
+
+item_t *itemtype_label_alloc(menu_t *menu, va_list args)
+{
+ //char *s;
+ struct label_item *item = (struct label_item *)malloc(sizeof(struct label_item));
+ if (!item) return NULL;
+ menu_item_init(&item->item);
+
+ item->display_text = va_arg(args, char *);
+
+ item->item.f_render = itemtype_label_render;
+ item->item.f_save = NULL;
+ item->item.f_invoke = itemtype_label_invoke;
+ item->item.f_load = NULL;
+
+ item->item.w = strlen(item->display_text);
+ item->item.front_width = item->item.w/2;
+ item->item.back_width = item->item.w - item->item.front_width;
+ item->item.h = 1;
+ item->item.disabled = true;
+
+ return (item_t *)item;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/label_items.h b/roms/u-boot-sam460ex/board/ACube/menu/label_items.h
new file mode 100644
index 000000000..bdc286dbb
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/label_items.h
@@ -0,0 +1,6 @@
+#ifndef LABEL_ITEMS_H
+#define LABEL_ITEMS_H
+
+item_t *itemtype_label_alloc(menu_t *menu, va_list args);
+
+#endif // LABEL_ITEMS_H
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/layout.c b/roms/u-boot-sam460ex/board/ACube/menu/layout.c
new file mode 100644
index 000000000..f2f5bd3a2
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/layout.c
@@ -0,0 +1,81 @@
+#include "menu.h"
+#include "layout.h"
+
+#define MENU_FIRST_COLUMN 3
+#define MENU_SECOND_COLUMN 44
+#define MENU_TOP 4
+#define MENU_BOTTOM 16
+
+void menu_layout(menu_t *menu)
+{
+ int
+ x=MENU_FIRST_COLUMN,
+ y=MENU_TOP,
+
+ max_width = 0,
+ max_front_width = 0,
+ max_back_width = 0;
+
+ int
+ height = 0,
+ //temp_h,
+ temp_l;
+
+ item_t*
+ item;
+
+ if (menu->type == MENUTYPE_POPUP)
+ {
+ x = 0;
+ y = 0;
+ }
+
+ /* Find size maximums */
+ item = (item_t *)(menu->item_list.first);
+ while (item)
+ {
+ if (item->w > max_width)
+ max_width = item->w;
+ if (item->front_width > max_front_width)
+ max_front_width = item->front_width;
+ if (item->back_width > max_back_width)
+ max_back_width = item->back_width;
+
+ item = (item_t *)(item->link.next);
+ }
+
+ /* Layout phase */
+ item = (item_t *)(menu->item_list.first);
+ while (item)
+ {
+ item->x = x;
+ item->y = y;
+ temp_l = menu->item_spacing + item->h - 1;
+ y += temp_l;
+ if (y > MENU_BOTTOM || item->break_after == true)
+ {
+ y = MENU_TOP;
+ x = MENU_SECOND_COLUMN;
+ }
+ height += temp_l;
+ item->w = max_width;
+ item->front_width = max_front_width;
+ item->back_width = max_back_width;
+ item = (item_t *)(item->link.next);
+ }
+
+ height -= menu->item_spacing;
+
+ /* Set the first item to be the acrive one */
+ if (menu->current_item == NULL)
+ {
+ menu->current_item = (item_t *)(menu->item_list.first);
+ while (menu->current_item && menu->current_item->disabled == true)
+ {
+ menu->current_item = (item_t *)(menu->current_item->link.next);
+ }
+ }
+
+ menu->w = max_width;
+ menu->h = height;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/layout.h b/roms/u-boot-sam460ex/board/ACube/menu/layout.h
new file mode 100644
index 000000000..2d04f6504
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/layout.h
@@ -0,0 +1,6 @@
+#ifndef MENU_LAYOUT
+#define MENU_LAYOUT
+
+void menu_layout(menu_t *menu);
+
+#endif // MENU_LAYOUT. Give me a lot of ??? for this work!!
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/list.c b/roms/u-boot-sam460ex/board/ACube/menu/list.c
new file mode 100644
index 000000000..eb9997c8d
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/list.c
@@ -0,0 +1,37 @@
+//#include "menu.h"
+#include "list.h"
+void list_init(mylist_t *l)
+{
+ l->first = NULL;
+ l->last = NULL;
+}
+
+bool list_empty(mylist_t *l)
+{
+ if (l->first == NULL) return true;
+ else return false;
+}
+
+void list_add(mylist_t *l, node_t *n)
+{
+ if (l->first == NULL)
+ {
+ l->first = n;
+ l->last = n;
+ n->prev = NULL;
+ n->next = NULL;
+ }
+ else
+ {
+ node_t *b = l->last;
+ l->last = n;
+
+ n->prev = b;
+ n->next = 0;
+
+ b->next = n;
+ }
+}
+
+
+
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/list.h b/roms/u-boot-sam460ex/board/ACube/menu/list.h
new file mode 100644
index 000000000..d66edc830
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/list.h
@@ -0,0 +1,39 @@
+#ifndef MENU_LIST_H
+#define MENU_LIST_H
+
+#ifndef bool_defined
+#define bool_defined
+typedef int bool;
+#endif
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0L)
+#endif
+
+
+/* List functions */
+typedef struct node_s
+{
+ struct node_s *prev;
+ struct node_s *next;
+} node_t;
+
+typedef struct list_s
+{
+ node_t *first;
+ node_t *last;
+} mylist_t;
+
+//void list_init(mylist_t *list);
+//void list_add(mylist_t *list, node_t *node);
+//bool list_empty(mylist_t *list);
+
+#endif //MENU_LIST_H
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/menu.c b/roms/u-boot-sam460ex/board/ACube/menu/menu.c
new file mode 100644
index 000000000..35a80e871
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/menu.c
@@ -0,0 +1,374 @@
+#include "menu.h"
+#include "creation.h"
+#include "layout.h"
+#include "list.h"
+
+form_t *root_form = 0;
+
+void menu_set_form(form_t *form)
+{
+ root_form = form;
+}
+
+void menu_draw_help(item_t *item)
+{
+ char
+ buffer[80*4],
+ *p_text,
+ *p_break,
+ *p_start;
+
+ int
+ line = 20;
+
+ bool in_word=true;
+
+ if (!item) return;
+
+ video_clear_box(1,20,78,4,' ',MENUATTR_NORMAL);
+
+ if (item->help_text)
+ {
+ /* Reformat help so that it word-wraps */
+ buffer[0] = 0;
+
+ strcpy(buffer, item->help_text);
+
+ p_text = p_break = p_start = buffer;
+ in_word = true;
+
+ for (;;)
+ {
+ if (*p_text == ' ' && in_word == true)
+ {
+ in_word = false;
+ p_break = p_text;
+ }
+ else if (*p_text != ' ')
+ {
+ in_word = true;
+ }
+ if ((p_text - p_start >= 72) || *p_text == 0) // flush
+ {
+ if (*p_text == '\0') p_break = p_text;
+ *p_break = 0;
+ video_draw_text(2,line++, MENUATTR_NORMAL, p_start, -1);
+ if (*p_text == '\0') return;
+ p_break++;
+ while (p_break < p_text && *p_break == ' ')
+ {
+ p_break++;
+ }
+ p_start = p_break;
+ if (*p_break == '\0') return;
+ }
+ else p_text++;
+ }
+ }
+}
+
+void menu_draw(menu_t *menu)
+{
+ if (menu && menu->needs_layout)
+ {
+ menu_layout(menu);
+ }
+ if (menu)
+ {
+ item_t *item = (item_t *)(menu->item_list.first);
+
+ if (menu->type == MENUTYPE_POPUP)
+ {
+ video_clear_box(menu->x-1, menu->y-1, menu->w, menu->h, ' ', MENUATTR_NORMAL);
+ }
+
+ while (item)
+ {
+ item->f_render(menu, item,
+ (item->disabled==true)?MENUATTR_DISABLED:
+ (item == menu->current_item)?MENUATTR_HILITE : MENUATTR_ITEM);
+ item = (item_t *)(item->link.next);
+ }
+ if (menu->type == MENUTYPE_FORM)
+ {
+ menu_draw_help(menu->current_item);
+ }
+ else
+ {
+ video_draw_box(SINGLE_BOX, MENUATTR_NORMAL, NULL, 0, menu->x-1, menu->y-1,
+ menu->w+2, menu->h+3);
+ }
+ }
+}
+
+void menu_draw_form(form_t *form)
+{
+ char
+ *title;
+ menu_t
+ *menu = form->current_menu;
+
+ /* Prefer current menu title if set, otherwise use the form title */
+ if (menu && menu->menu_title) title = menu->menu_title;
+ else if (form->form_title) title = form->form_title;
+ else title = NULL; //"Untitled";
+
+ video_draw_box(SINGLE_BOX, MENUATTR_NORMAL, title, 1, 0,0, 80, 19);
+ video_draw_box(SINGLE_BOX, MENUATTR_NORMAL, NULL, 0, 0, 19, 80, 6);
+
+ /* If we have a menu, draw it too */
+ if (menu)
+ {
+ video_clear_box(1, 3, 78, 15, ' ', MENUATTR_NORMAL);
+ menu_draw(menu);
+ }
+}
+
+void menu_draw_current_form(void)
+{
+ menu_draw_form(root_form);
+}
+
+void menu_form_switch_menu(form_t *form, char *name)
+{
+ menu_t *menu = menu_form_find_menu(form, name);
+ if (!menu)
+ return;
+ menu_form_set_menu(form, menu);
+}
+
+void menu_form_popup(form_t *form, menu_t* menu)
+{
+ if (menu && MENUTYPE_POPUP == menu->type)
+ {
+ form->popup_save = form->current_menu;
+ form->popup_item_save = form->current_menu->current_item;
+ form->current_menu = menu;
+ menu_draw(menu);
+ }
+}
+
+void menu_form_popup_name(form_t *form, char *name)
+{
+ menu_t *menu = menu_form_find_menu(form, name);
+ if (!menu)
+ return;
+ menu_form_popup(form, menu);
+}
+
+void menu_form_popdown(form_t *form)
+{
+ if (form->current_menu && form->current_menu->type == MENUTYPE_POPUP)
+ {
+ form->current_menu = form->popup_save;
+ if (form->current_menu)
+ form->current_menu->current_item = form->popup_item_save;
+ video_clear_box(1, 3, 78, 15, ' ', MENUATTR_NORMAL);
+ if (form->current_menu)
+ menu_draw(form->current_menu);
+ }
+}
+
+void menu_set_active_item(menu_t *menu, int nr)
+{
+ item_t
+ *item = (item_t *)(menu->item_list.first);
+
+ while (item && nr > 0)
+ {
+ nr--;
+ item = (item_t *)(item->link.next);
+ }
+ if (nr == 0)
+ {
+ menu->current_item = item;
+ }
+}
+
+static void menu_perform_save(form_t *form)
+{
+ menu_t
+ *menu;
+
+ menu = (menu_t *)(form->menu_list.first);
+ while (menu)
+ {
+ item_t
+ *item;
+
+ item = (item_t *)(menu->item_list.first);
+ while (item)
+ {
+ if (item->f_save) item->f_save(menu, item);
+ item = (item_t *)(item->link.next);
+ }
+ menu = (menu_t *)(menu->link.next);
+ }
+}
+
+static int leave_select = -1;
+
+void leave_func(item_t *item, void *dummy, int arg)
+{
+ leave_select = arg;
+}
+
+menu_t *make_leave_menu(form_t *form)
+{
+ menu_t
+ *menu = new_menu(MENUTYPE_POPUP, "Exit Menu", form, NULL);
+
+ if (menu)
+ {
+ item_t
+ *item;
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Save settings and exit", leave_func, NULL, EXIT_SAVE_PERMANENT);
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Use settings for this session only", leave_func, NULL, EXIT_AND_SAVE);
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Leave without saving", leave_func, NULL, EXIT_AND_NO_SAVE);
+ //item = menu_item_create(ITEMTYPE_FUNC, menu, "Return to menu", leave_func, NULL, EXIT_NOT);
+ item = menu_item_create(ITEMTYPE_FUNC, menu, "Abort boot and enter U-Boot shell", leave_func, NULL, EXIT_TO_SHELL);
+ }
+
+ menu_form_add_menu(form, menu);
+
+ menu_set_position(menu, 6, 6);
+
+ return menu;
+}
+
+
+bool menu_handle_single_key(form_t *form, int key)
+{
+ /*
+ Keys below 10 or so are specially mapped by us to mean one of the functions
+ of the menu system (like next item, prev item etc). All other keys are verbatim
+ keypresses that might be needed for e.g. string entry
+ */
+ item_t
+ *c_item,
+ *n_item;
+ menu_t
+ *menu = form->current_menu;
+
+ switch(key)
+ {
+ case KEY_NEXT_ITEM:
+ /* Move one item forward */
+ c_item = menu->current_item;
+ n_item = (item_t *)(c_item->link.next);
+ while (n_item && n_item->disabled == true)
+ {
+ n_item = (item_t *)(n_item->link.next);
+ }
+
+ if (n_item)
+ {
+ /* redraw the old item un-highlit */
+ c_item->f_render(menu, c_item, MENUATTR_ITEM);
+ n_item->f_render(menu, n_item, MENUATTR_HILITE);
+ menu_draw_help(n_item);
+ menu->current_item = n_item;
+ }
+ break;
+ case KEY_PREV_ITEM:
+ /* Move one item backward */
+ c_item = menu->current_item;
+ n_item = (item_t *)(c_item->link.prev);
+ while (n_item && n_item->disabled == true)
+ {
+ n_item = (item_t *)(n_item->link.prev);
+ }
+ if (n_item)
+ {
+ /* redraw the old item un-highlit */
+ c_item->f_render(menu, c_item, MENUATTR_ITEM);
+ n_item->f_render(menu, n_item, MENUATTR_HILITE);
+ menu_draw_help(n_item);
+ menu->current_item = n_item;
+ }
+ break;
+ case KEY_ABORT:
+ if (menu->type == MENUTYPE_POPUP)
+ {
+ menu_form_popdown(form);
+ }
+ else
+ {
+ if (menu->parent_menu)
+ {
+ menu_form_switch_menu(menu->parent_form, menu->parent_menu);
+ }
+ else
+ {
+ /* TODO: Implement exit from menu */
+ menu_form_popup_name(root_form, "Exit Menu");
+ return true;
+ }
+ }
+ break;
+ default:
+ if (menu->current_item)
+ {
+ menu->current_item->f_invoke(menu, menu->current_item, key);
+ }
+ if (key == KEY_ACTIVATE && menu->type == MENUTYPE_POPUP)
+ {
+ menu_form_popdown(form);
+ /* Check if we want to exit */
+ if (leave_select != -1)
+ {
+ switch(leave_select)
+ {
+ case EXIT_AND_NO_SAVE:
+ return false;
+ case EXIT_SAVE_PERMANENT:
+ menu_perform_save(form);
+#ifndef SIM
+ saveenv();
+#endif
+ return false;
+ case EXIT_AND_SAVE:
+ menu_perform_save(form);
+ return false;
+ case EXIT_NOT:
+ return true;
+ case EXIT_TO_SHELL:
+ {
+ char *mboot = getenv("menuboot_cmd");
+ if ((mboot) && (strlen(mboot)>2)) SETENV("menuboot_cmd", "noboot");
+ else SETENV("menuboot_cmd", "boota");
+ return false;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return true;
+}
+
+
+void menu_do(bool do_leave_menu)
+{
+ bool running=true;
+ int key;
+
+ running = true;
+ leave_select = -1;
+
+ if (do_leave_menu)
+ make_leave_menu(root_form);
+
+ if (root_form)
+ {
+ menu_draw_form(root_form);
+
+ while (running)
+ {
+ key = video_get_key();
+ running = menu_handle_single_key(root_form, key);
+ }
+ }
+}
+
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/menu.h b/roms/u-boot-sam460ex/board/ACube/menu/menu.h
new file mode 100644
index 000000000..0b5d71733
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/menu.h
@@ -0,0 +1,279 @@
+#ifndef MENU_H
+#define MENU_H
+
+#ifdef SIM
+#include <stdlib.h>
+#else
+#include <common.h>
+#endif
+
+#include "list.h"
+
+#ifdef SIM
+#define GETENV(x) getenv(x)
+#define SETENV(x,y) setenv(x,y,1)
+#else
+#define GETENV(x) getenv(x)
+#define SETENV(x,y) setenv(x,y)
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0L)
+#endif
+
+/* Menu attributes */
+#define MENUATTR_NORMAL 0 /* Attribute used by standard menus */
+#define MENUATTR_ITEM 1 /* Attribute for menu items (normal) */
+#define MENUATTR_HILITE 2 /* Attribute for highlighted menu items */
+#define MENUATTR_DISABLED 3 /* Attribute for disabled menu items */
+
+#ifndef bool_defined
+#define bool_defined
+typedef int bool;
+#endif
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+#define MAX_MENUS 30
+
+#define KEY_NONE 0 /* No or false key pressed */
+#define KEY_NEXT_OPTION 1 /* Page Down, Arrow right */
+#define KEY_PREV_OPTION 2 /* Page Up, Arrow left */
+#define KEY_NEXT_ITEM 3 /* Arrow down */
+#define KEY_PREV_ITEM 4 /* Arrow up */
+#define KEY_ABORT 5 /* ESC */
+#define KEY_ACTIVATE 6 /* Return */
+#define KEY_DELETE 7 /* Backspace */
+#define KEY_F1 8
+
+#define EXIT_AND_SAVE 0
+#define EXIT_AND_NO_SAVE 1
+#define EXIT_NOT 2
+#define EXIT_SAVE_PERMANENT 3
+#define EXIT_TO_SHELL 4
+
+
+#define SINGLE_BOX 0
+#define DOUBLE_BOX 1
+
+#ifdef SIM
+#include "sim.h"
+#endif
+
+struct item_s;
+struct menu_s;
+
+typedef void (*load_func)(struct menu_s *menu, struct item_s *item);
+typedef void (*save_func)(struct menu_s *menu, struct item_s *item);
+typedef void (*render_func)(struct menu_s *menu, struct item_s *item, int state);
+typedef void (*invoke_func)(struct menu_s *menu, struct item_s *item, int key);
+
+typedef struct item_s
+{
+ node_t link; /* Link for chaining */
+ int x,y; /* Position */
+ int w,h; /* Size */
+ char *help_text; /* Help text do display */
+ int front_width; /* Width of front display matter */
+ int back_width; /* Width of option data or 0 */
+ bool disabled; /* Wether this item is active or disabled */
+ bool break_after; /* After this item break to next column */
+ load_func f_load; /* Functio to load the setting */
+ render_func f_render; /* Function to render contents */
+ save_func f_save; /* Function to save the setting */
+ invoke_func f_invoke; /* Function to handle key event */
+} item_t;
+
+
+#define MENUTYPE_FORM 1 /* Form-integrated menu */
+#define MENUTYPE_POPUP 2 /* Popup menu (drawing differs) */
+
+typedef struct menu_s
+{
+ node_t link;
+ char *menu_title; /* Title of the menu */
+ int type; /* Type of menu */
+ bool two_colums; /* True for two-column menus */
+ int x,y,w,h; /* Coordinates and extends */
+ void *user_data; /* User data of menu */
+ bool needs_layout;
+ int item_spacing;
+ item_t *current_item; /* current item */
+ mylist_t item_list;
+
+ char *parent_menu; /* Where to return when ESC is pressed */
+ struct form_s *parent_form; /* Form where this is currently being displayed */
+} menu_t;
+
+typedef struct form_s
+{
+ char *form_title; /* Title of the form */
+ menu_t *current_menu; /* Menu that is active */
+ menu_t *popup_save; /* Backup when popup is active */
+ item_t *popup_item_save; /* Backup which item was active */
+
+ int menu_stack_ptr; /* Stack pointer */
+ menu_t *menu_stack[MAX_MENUS];/* Previous menus */
+
+ mylist_t menu_list;
+} form_t;
+
+void menu_draw_current_form(void);
+void menu_init(void);
+void menu_set_active_item(menu_t *menu, int nr);
+void menu_draw_form(form_t *form);
+void menu_form_switch_menu(form_t *form, char *name);
+void menu_form_popup(form_t *form, menu_t* menu);
+
+/* Utility functions */
+
+
+void leave_func(item_t *item, void *dummy, int arg);
+void menu_draw_help(item_t *item);
+void menu_set_form(form_t *form);
+void menu_do(bool do_leave_menu);
+
+
+/* Item types */
+
+/*
+ * Item: Boolean from a console var
+ * Creation args:
+ * (char *) display name
+ * (char *) variable name
+ * (char *) positive text ("yes", "true", "enabled", "on")
+ * (char *) negative text ("no", "false", "disabled", "off")
+ * int default if unset (0=negative, !0=positive)
+ */
+//#define ITEMTYPE_BOOL_CVAR 0
+
+/*
+ * Item: Invoke-a-function item
+ * Creation args:
+ * (char *) display name
+ * (void *)(item_t *, void *, int)
+ * Function to invoke
+ * (void *) First parameter to be passed
+ * int Second parameter to be passed
+ */
+#define ITEMTYPE_FUNC 1
+
+/*
+ * Item: Submenu
+ * Creation args:
+ * (char *) display name
+ * (char *) menu to change to
+ */
+#define ITEMTYPE_SUBMENU 2
+
+/*
+ * Item: Popup Choice
+ * Creation args:
+ * (char *) display name
+ * int default choice
+ * (void *) hook user data.
+ * (void *) Save hook. See below
+ * (void *) Load hook. See below
+ * (popup_entry_t *) pointer to an array of popup_entry structures.
+ * Terminate with all entries set to NULL.
+ *
+ * Save/Load hook:
+ * Thes functions are called whenever the item needs to be loaded or saved.
+ * The prototypes are:
+ *
+ * int load(void *user_data, popup_entry_t *entries);
+ * void save(void *user_data, popup_entry_t *selected);
+ *
+ * Load: The function is invoked with the third creation argument (user data) and
+ * a pointer to the popup_entry** specified as the sixth argument. It should
+ * return the index of the entry that would become the selected/active entry.
+ *
+ * Save: The function is invoked with the user data and a pointer to the selected
+ * entry in the popup. It should save the value to an appropriate place, e.g.
+ * an environment variable.
+ *
+ */
+#define ITEMTYPE_POPUP 3
+
+typedef struct _popup_entry
+{
+ char *display_text; /* What the entry should display */
+ char *value_text; /* What the entry should represent. For the hooks only */
+ void *user_data; /* Additional hook user data. Use as you wish */
+} popup_entry_t;
+
+
+/*
+ * Item: String from a console variable
+ * Creation args:
+ * (char *) display name
+ * (char *) variable name
+ * (char *) default if unset
+ */
+#define ITEMTYPE_STRING_CVAR 4
+
+/*
+ * Item: Unselectable label
+ * Creatation args:
+ * (char *) display name
+ */
+#define ITEMTYPE_LABEL 5
+
+/*
+ * Item: Numerical value editor
+ * Creation args:
+ * (char *) display name
+ * (int) default value
+ * (int) stepping rate
+ * (int) lower bound
+ * (int) upper bound
+ * (int) 0=decimal, 1=hex
+ * (void *) load hook (see below)
+ * (void *) save hook (see below)
+ * (void *) param 1 for hooks
+ * int param 2 for hooks
+ *
+ * Hooks work similar to popup types. The prototype for the hooks is
+ * int load(void *param1, int param2, int default);
+ * void save(void *param1, int param2, int value);
+ * If load is unable to load, it should return default.
+ */
+//#define ITEMTYPE_NUMERIC 6
+
+/*
+ * Item: Configuration register editor
+ * Creation args:
+ * (char *) Display name
+ * (void *) register descriptor pointer (see below)
+ */
+//#define ITEMTYPE_REGISTER 7
+/*
+typedef struct
+{
+ char *register_name;
+ int config_offset;
+ int config_type;
+ int value_type;
+ int bus;
+ int devfn;
+ void *menu_page;
+} articia_register_t;
+
+typedef struct
+{
+ char *title;
+ articia_register_t *registers;
+} articia_menu_page_t;
+
+enum
+{
+ CONFIG_DWORD = 0, CONFIG_WORD = 1, CONFIG_BYTE = 2, TYPE_HEX = 0, TYPE_DEC = 1
+};
+*/
+#endif
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/popup_items.c b/roms/u-boot-sam460ex/board/ACube/menu/popup_items.c
new file mode 100644
index 000000000..34796533c
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/popup_items.c
@@ -0,0 +1,150 @@
+#include "menu.h"
+#include <stdarg.h>
+#include "popup_items.h"
+#include "creation.h"
+
+#define MAX_POPUP_SIZE 12
+#define MAX_POPUP_STRING 20
+
+struct popup_item
+{
+ item_t item;
+ char *display_text;
+ menu_t *menu_handle;
+ int choice;
+ int max_choice;
+ void (*save_hook)(void *, popup_entry_t *entry);
+ int (*load_hook)(void *, popup_entry_t *);
+ void *hook_user_data;
+ popup_entry_t *entries;
+};
+
+void itemtype_popup_render(menu_t *menu, item_t *item, int state)
+{
+ struct popup_item *it = (struct popup_item *)item;
+ int x,y;
+ x = menu->x + item->x;
+ y = menu->y + item->y;
+
+ video_draw_text(x,y, MENUATTR_NORMAL, it->display_text, item->w);
+ video_draw_text(x+item->front_width,y, MENUATTR_NORMAL, ":", -1);
+ video_draw_text(x+item->front_width+1,y,state,
+ it->choice >= 0 ? it->entries[it->choice].display_text : "<none>",
+ item->back_width);
+}
+
+void itemtype_popup_invoke(menu_t *menu, item_t *item, int key)
+{
+ struct popup_item
+ *it = (struct popup_item *)item;
+
+ switch(key)
+ {
+ case KEY_ACTIVATE:
+ menu_set_active_item(it->menu_handle, it->choice);
+ menu_set_position(it->menu_handle,
+ menu->y+item->y, menu->x+item->x+item->front_width+1);
+ menu_form_popup(menu->parent_form, it->menu_handle);
+ break;
+ case KEY_NEXT_OPTION:
+ if (it->choice < it->max_choice)
+ {
+ itemtype_popup_render(menu, item, MENUATTR_HILITE);
+ it->choice++;
+ itemtype_popup_render(menu, item, MENUATTR_HILITE);
+ }
+ break;
+ case KEY_PREV_OPTION:
+ if (it->choice > 0)
+ {
+ itemtype_popup_render(menu, item, MENUATTR_HILITE);
+ it->choice--;
+ itemtype_popup_render(menu, item, MENUATTR_HILITE);
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+void itemtype_popup_save(menu_t *menu, item_t *item)
+{
+ struct popup_item *it = (struct popup_item *)item;
+ if (it->save_hook)
+ it->save_hook(it->hook_user_data, &it->entries[it->choice]);
+}
+
+void itemtype_popup_load(menu_t *menu, item_t *item)
+{
+ struct popup_item *it = (struct popup_item *)item;
+ if (it->load_hook)
+ {
+ int i = it->load_hook(it->hook_user_data, it->entries);
+ if (i != -1) it->choice = i;
+ }
+ item->f_save = itemtype_popup_save;
+ item->f_load = 0;
+}
+
+
+static void item_func(item_t *item, void *param1, int param2)
+{
+ *(int *)param1 = param2;
+}
+
+item_t *itemtype_popup_alloc(menu_t *menu, va_list args)
+{
+ menu_t
+ *popup;
+ item_t
+ *newitem;
+ popup_entry_t
+ *e;
+ int
+ i,
+ maximum_width = 0,
+ m;
+
+ struct popup_item
+ *item = (struct popup_item *)malloc(sizeof(struct popup_item) + MAX_POPUP_STRING * MAX_POPUP_SIZE );
+
+ if (!item) return NULL;
+ menu_item_init(&item->item);
+
+ item->display_text = va_arg(args, char *);
+ item->choice = va_arg(args, int);
+ item->hook_user_data = va_arg(args, void *);
+ item->save_hook = va_arg(args, void *);
+ item->load_hook = va_arg(args, void *);
+ item->entries = va_arg(args, popup_entry_t*);
+
+ popup = new_menu(MENUTYPE_POPUP, NULL, menu->parent_form, NULL);
+
+ i=0;
+ e = item->entries;
+ do
+ {
+ if (e->display_text == NULL) break;
+ m = strlen(e->display_text);
+ if (m > maximum_width) maximum_width = m;
+ newitem = menu_item_create(ITEMTYPE_FUNC, popup, e->display_text, item_func, &(item->choice),i);
+ i++;
+ e++;
+ } while (1);
+
+ item->max_choice = i-1;
+
+ item->menu_handle = popup;
+
+ item->item.f_render = itemtype_popup_render;
+ item->item.f_save = 0;
+ item->item.f_invoke = itemtype_popup_invoke;
+ item->item.f_load = itemtype_popup_load;
+
+ item->item.w = item->item.front_width = strlen(item->display_text);
+ item->item.back_width = maximum_width;
+ item->item.h = 1;
+ item->item.disabled = false;
+
+ return (item_t *)item;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/popup_items.h b/roms/u-boot-sam460ex/board/ACube/menu/popup_items.h
new file mode 100644
index 000000000..66cb6b0cb
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/popup_items.h
@@ -0,0 +1,6 @@
+#ifndef POPUP_ITEMS_H
+#define POPUP_ITEMS_H
+
+item_t *itemtype_popup_alloc(menu_t *menu, va_list args);
+
+#endif
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/string_edit.c b/roms/u-boot-sam460ex/board/ACube/menu/string_edit.c
new file mode 100644
index 000000000..64d53a019
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/string_edit.c
@@ -0,0 +1,177 @@
+#include "menu.h"
+#include "string_edit.h"
+
+//static int num_lines = 0;
+static int x_pos=0, y_pos=0;
+static int width = 0, height = 0;
+static int cursor_pos = 0;
+static char *buffer;
+static char *prompt;
+static int buffer_length;
+static char backup[1024];
+
+#define STRINGBOX_WIDTH 70
+#define STRINGBOX_HEIGHT 4
+#define STRINGBOX_X 5
+#define STRINGBOX_Y 5
+
+static void string_edit_draw(void)
+{
+ int
+ i,j,
+ length = buffer_length,
+ attr = MENUATTR_NORMAL;
+
+ char
+ c;
+
+ //int cursor_x = 0, cursor_y = 0;
+
+ for (i=0; i<height; i++)
+ {
+ for (j=0; j<width; j++)
+ {
+ int
+ offset = j+i*width;
+
+ if (offset > length)
+ c = ' ';
+ else
+ c = buffer[offset];
+
+ if (offset == cursor_pos)
+#if 1 //def SIM
+ attr = MENUATTR_HILITE;
+ else
+ attr = MENUATTR_NORMAL;
+#else
+ {
+ cursor_x = x_pos+j;
+ cursor_y = y_pos+i;
+ }
+#endif
+ video_draw_text(x_pos + j, y_pos + i, attr, &c, 1);
+ }
+ }
+#if 0 //ndef SIM
+ video_set_cursor(cursor_y, cursor_y);
+#endif
+}
+
+static void string_clear_frame(void)
+{
+ video_clear_box(STRINGBOX_X-2, STRINGBOX_Y-2,
+ STRINGBOX_WIDTH+4, STRINGBOX_HEIGHT+4,
+ ' ', MENUATTR_NORMAL);
+}
+
+static void string_draw_frame(void)
+{
+ string_clear_frame();
+ video_draw_box(SINGLE_BOX, MENUATTR_NORMAL, prompt, 0,
+ STRINGBOX_X-2, STRINGBOX_Y-2,
+ STRINGBOX_WIDTH+4, STRINGBOX_HEIGHT+4);
+}
+
+static void backspace(void)
+{
+ int
+ i;
+
+ char
+ *s;
+
+ if (cursor_pos == 0) return;
+ if (cursor_pos == buffer_length)
+ {
+ buffer_length--;
+ cursor_pos--;
+ buffer[buffer_length] = 0;
+ }
+ else
+ {
+ s = buffer+cursor_pos-1;
+ for (i = 0; i < buffer_length - cursor_pos + 1; i++)
+ {
+ *s = *(s+1);
+ s++;
+ }
+ cursor_pos--;
+ buffer_length--;
+ }
+}
+
+static void insert(int key)
+{
+ int
+ i;
+
+ char
+ *s;
+
+ s = buffer + buffer_length;
+ for (i = 0; i < buffer_length - cursor_pos + 1; i++)
+ {
+ *(s+1) = *s;
+ s--;
+ }
+ *(buffer + cursor_pos) = (char)key;
+ cursor_pos++;
+ buffer_length++;
+}
+
+bool menu_string_edit(char *_prompt, char *string, int buffersize)
+{
+ int
+ key;
+
+ prompt = _prompt;
+ x_pos = STRINGBOX_X;
+ y_pos = STRINGBOX_Y;
+ width = STRINGBOX_WIDTH;
+ height = STRINGBOX_HEIGHT;
+
+ buffer = string;
+ strcpy(backup, string);
+
+ buffer_length = cursor_pos = strlen(buffer);
+
+ string_draw_frame();
+ do
+ {
+ string_edit_draw();
+ key = video_get_key();
+ switch(key)
+ {
+ case KEY_ABORT:
+ strcpy(string, backup);
+ string_clear_frame();
+ menu_draw_current_form();
+ return false;
+ case KEY_ACTIVATE:
+ string_clear_frame();
+ menu_draw_current_form();
+ return true;
+ case KEY_NEXT_OPTION:
+ cursor_pos++;
+ if (cursor_pos > buffer_length) cursor_pos = buffer_length;
+ break;
+ case KEY_PREV_OPTION:
+ cursor_pos--;
+ if (cursor_pos < 0) cursor_pos = 0;
+ break;
+ case KEY_DELETE:
+ /* Backspace */
+ backspace();
+ break;
+ default:
+ if (key >= 32 && key <= 127)
+ {
+ insert(key);
+ }
+ break;
+ }
+ } while (1);
+
+ return false;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/string_edit.h b/roms/u-boot-sam460ex/board/ACube/menu/string_edit.h
new file mode 100644
index 000000000..efd09b97b
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/string_edit.h
@@ -0,0 +1,6 @@
+#ifndef STRING_EDIT_H
+#define STRING_EDIT_H
+
+bool menu_string_edit(char *_prompt, char *string, int buffersize);
+
+#endif
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/string_items.c b/roms/u-boot-sam460ex/board/ACube/menu/string_items.c
new file mode 100644
index 000000000..1f04cbe0c
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/string_items.c
@@ -0,0 +1,133 @@
+#include "menu.h"
+#include <stdarg.h>
+#include "string_items.h"
+#include "string_edit.h"
+#include "creation.h"
+
+#define MAX_DISPLAY_WIDTH 40
+
+void itemtype_string_cvar_save(menu_t *menu, item_t *item);
+void itemtype_string_cvar_load(menu_t *menu, item_t *item);
+
+struct string_cvar_item
+{
+ item_t item;
+ char *display_text;
+ char *var_name;
+ char value[512];
+ char *def_value;
+ int base;
+};
+
+void itemtype_string_cvar_render(menu_t *menu, item_t *item, int state)
+{
+ struct string_cvar_item
+ *it = (struct string_cvar_item *)item;
+
+ int
+ x = menu->x + item->x,
+ y = menu->y + item->y,
+ difference = 0;
+
+ char
+ *buffer = it->value + it->base;
+
+ video_draw_text(x,y, MENUATTR_NORMAL, it->display_text, -1);
+ video_draw_text(x+item->front_width,y, MENUATTR_NORMAL, ":", -1);
+
+ x +=item->front_width+1;
+
+ if (it->base)
+ difference ++;
+
+ if (strlen(it->value + it->base) >= MAX_DISPLAY_WIDTH)
+ difference ++;
+
+ if (it->base)
+ {
+ video_draw_text(x,y,state, "<", 1);
+ x++;
+ }
+
+ video_draw_text(x,y,state, buffer, item->back_width - difference);
+ x += item->back_width - difference;
+
+ if (strlen(it->value + it->base) >= MAX_DISPLAY_WIDTH)
+ {
+ video_draw_text(x, y, state, ">", 1);
+ }
+}
+
+void itemtype_string_cvar_invoke(menu_t *menu, item_t *item, int key)
+{
+ struct string_cvar_item *it = (struct string_cvar_item *)item;
+ switch(key)
+ {
+ case KEY_ACTIVATE:
+ menu_string_edit(it->display_text, it->value, 512);
+ break;
+ case KEY_PREV_OPTION:
+ if (it->base > 0) it->base--;
+ if (it->base == 1) it->base = 0;
+ itemtype_string_cvar_render(menu, item, MENUATTR_HILITE);
+ break;
+ case KEY_NEXT_OPTION:
+ if (strlen(it->value) < MAX_DISPLAY_WIDTH) break;
+ if (it->base <= (strlen(it->value) - MAX_DISPLAY_WIDTH))
+ {
+ if (it->base == 0) it->base = 1;
+ it->base++;
+ itemtype_string_cvar_render(menu, item, MENUATTR_HILITE);
+ }
+ break;
+ }
+}
+
+void itemtype_string_cvar_load(menu_t *menu, item_t *item)
+{
+ struct string_cvar_item *it = (struct string_cvar_item *)item;
+ char *s;
+ s = GETENV(it->var_name);
+ if (s)
+ {
+ strcpy(it->value, s);
+ }
+ else strcpy(it->value, it->def_value);
+ item->f_save = itemtype_string_cvar_save;
+ item->f_load = 0;
+}
+
+void itemtype_string_cvar_save(menu_t *menu, item_t *item)
+{
+ struct string_cvar_item *it = (struct string_cvar_item *)item;
+
+ SETENV(it->var_name, it->value);
+}
+
+item_t *itemtype_string_cvar_alloc(menu_t *menu, va_list args)
+{
+ //int a,b;
+ struct string_cvar_item *item = (struct string_cvar_item *)malloc(sizeof(struct string_cvar_item));
+ if (!item) return NULL;
+
+ menu_item_init(&item->item);
+
+ item->display_text = va_arg(args, char *);
+ item->var_name = va_arg(args, char *);
+ item->def_value = va_arg(args, char *);
+ item->value[0] = 0;
+ item->base = 0;
+
+ item->item.f_render = itemtype_string_cvar_render;
+ item->item.f_save = 0;
+ item->item.f_invoke = itemtype_string_cvar_invoke;
+ item->item.f_load = itemtype_string_cvar_load;
+
+ item->item.front_width = strlen(item->display_text);
+ item->item.back_width = MAX_DISPLAY_WIDTH;
+
+ item->item.w = item->item.back_width + item->item.front_width + 1;
+ item->item.h = 1;
+
+ return (item_t *)item;
+}
diff --git a/roms/u-boot-sam460ex/board/ACube/menu/string_items.h b/roms/u-boot-sam460ex/board/ACube/menu/string_items.h
new file mode 100644
index 000000000..04695763a
--- /dev/null
+++ b/roms/u-boot-sam460ex/board/ACube/menu/string_items.h
@@ -0,0 +1,6 @@
+#ifndef STRING_ITEMS_H
+#define STRING_ITEMS_H
+
+item_t *itemtype_string_cvar_alloc(menu_t *menu, va_list args);
+
+#endif