--- a/rules.mk
+++ b/rules.mk
@@ -19,7 +19,7 @@ parser_test = test/parser-test
 daemons = $(pb_discover)
 #parsers = kboot native yaboot (todo)
 parsers = kboot
-uis = $(pb_test) $(cond_pb_twin)
+uis = $(pb_cui) $(pb_test) $(cond_pb_twin)
 tests = $(parser_test)
 
 # other to install
--- /dev/null
+++ b/ui/ncurses/ps3-cui.c
@@ -0,0 +1,257 @@
+/*
+ * Petitboot cui bootloader for the PS3 game console
+ *
+ *  Copyright (C) 2009 Sony Computer Entertainment Inc.
+ *  Copyright 2009 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define DEBUG
+
+/*
+ * TODO
+ * option editor
+ * read/write flash values
+ * timeout
+ * test type_cmd, type_kexec
+ * test set-video-mode, boot-to-game-os
+ * conv libs
+ * credits menu
+ */
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pb-ncurses.h"
+
+#define DBG(fmt, args...) pb_log("DBG: " fmt, ## args)
+#define DBGS(fmt, args...) pb_log("DBG:%s:%d: " fmt, __func__, __LINE__, ## args)
+
+/**
+ * struct ps3_cui - Main cui program instance.
+ * @mm: Main menu.
+ * @vm: Video mode selection menu.
+ * @cui: The cui instance.
+ */
+
+struct ps3_cui {
+	struct menu *mm;
+	struct menu *vm;
+	struct cui *cui;
+};
+
+#define to_ps3_cui(_arg) \
+	(assert(((struct ps3_cui *)(_arg))->cui->c_sig == cui_sig), \
+	((struct ps3_cui *)(_arg)))
+
+/**
+ * ps3_cui_mm_video_cb - Switch to the video mode menu.
+ */
+
+static int ps3_cui_mm_video_cb(void *arg)
+{
+	struct ps3_cui *ps3 = to_ps3_cui(arg);
+	struct menu *old;
+
+	DBGS("\n");
+
+	old = cui_menu_set_current(ps3->cui, ps3->vm);
+	assert(old == ps3->mm);
+
+	return 0;
+}
+
+/**
+ * ps3_cui_vm_exit_cb - Switch to the main menu.
+ */
+
+static int ps3_cui_vm_exit_cb(void *arg)
+{
+	struct ps3_cui *ps3 = to_ps3_cui(arg);
+	struct menu *old;
+
+	DBGS("\n");
+
+	old = cui_menu_set_current(ps3->cui, ps3->mm);
+	assert(old == ps3->vm);
+
+	return 0;
+}
+
+/**
+ * ps3_cui_mm_init - Setup the main menu instance.
+ */
+
+static struct menu *ps3_cui_mm_init(struct ps3_cui *ps3_cui)
+{
+	static struct menu_item_callback exit_cb;
+	static struct menu_item_callback video_cb;
+	struct menu *m;
+	struct menu_item *i;
+
+	m = cui_menu_init(ps3_cui->cui);
+
+	if (!m) {
+		pb_log("%s: failed\n", __func__);
+		return NULL;
+	}
+
+	i = menu_item_init(m, type_text, state_visable,
+		" Petitboot - CUI Boot Loader");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		"-----------------------------");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		" [No Boot Options Available] ");
+	list_add_tail(&m->items, &i->list);
+
+	m->insert_start = i;
+	m->insert_end = i;
+
+	i = menu_item_init(m, type_cmd, state_visable,
+		" Boot GameOS ");
+	i->cmd = "ps3-boot-game-os";
+	i->status = " Reboot the PS3 into the GameOS";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_callback, state_visable,
+		" Set Video Mode ");
+	video_cb.fn = ps3_cui_mm_video_cb;
+	video_cb.arg = ps3_cui;
+	i->cb = &video_cb;
+	i->status = " Display a video mode selection menu";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_callback, state_selected,
+		" Exit to Shell ");
+	exit_cb.fn = cui_menu_exit_cb;
+	exit_cb.arg = ps3_cui->cui;
+	i->cb = &exit_cb;
+	i->status = " Exit petitboot and return to a shell prompt";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		"-----------------------------");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		" Enter=select, E,e=edit");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		" Welcome to petitboot");
+	list_add_tail(&m->items, &i->list);
+
+	menu_set_status_item(m, i);
+
+	return m;
+}
+
+/**
+ * ps3_cui_mm_init - Setup the video mode menu instance.
+ */
+
+static struct menu *ps3_cui_vm_init(struct ps3_cui *ps3_cui)
+{
+	static struct menu_item_callback exit_cb;
+	struct menu *m;
+	struct menu_item *i;
+
+	m = cui_menu_init(ps3_cui->cui);
+
+	if (!m) {
+		pb_log("%s: failed\n", __func__);
+		return NULL;
+	}
+
+	i = menu_item_init(m, type_text, state_visable,
+		"Petitboot - Set Video Mode");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		"---------------------------");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_cmd, state_visable,
+		" safe mode ");
+	i->cmd = "ps3-video-mode -m 0";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_cmd, state_visable,
+		" 720p ");
+	i->cmd = "ps3-video-mode -m 3";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_cmd, state_visable,
+		" 1080p ");
+	i->cmd = "ps3-video-mode -m 5";
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_callback, state_selected,
+		" Return to Main ");
+	exit_cb.fn = ps3_cui_vm_exit_cb;
+	exit_cb.arg = ps3_cui;
+	i->cb = &exit_cb;
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		"---------------------------");
+	list_add_tail(&m->items, &i->list);
+
+	i = menu_item_init(m, type_text, state_visable,
+		" Enter=select");
+	list_add_tail(&m->items, &i->list);
+
+	return m;
+}
+
+/**
+ * main - cui bootloader main routine.
+ *
+ * Returns 0 on success, 1 on error.
+ */
+
+int main(int argc, char **argv)
+{
+	static struct ps3_cui ps3;
+	FILE *log;
+
+	log = fopen("pb-cui.log", "a");
+	assert(log);
+	pb_log_set_stream(log);
+
+#if defined(DEBUG)
+	pb_log_always_flush(1);
+#endif
+
+	pb_log("--- pb-cui ---\n");
+
+	ps3.cui = cui_init(NULL);
+
+	if (!ps3.cui)
+		return 1;
+
+	ps3.mm = ps3_cui_mm_init(&ps3);
+	ps3.vm = ps3_cui_vm_init(&ps3);
+
+	cui_run(ps3.cui, ps3.mm, NULL);
+
+	return 0;
+}
