diff --git a/src/flash/flash.c b/src/flash/flash.c
index 1332e1235077d314e2535e904273f29fc1aff1d5..8224e50f46fd4eaaf99a4300998ce1692132708b 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -48,7 +48,6 @@ extern Jim_Interp *interp;
 
 /* command handlers */
 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -186,8 +185,6 @@ int flash_init_drivers(struct command_context_s *cmd_ctx)
 	{
 		Jim_CreateCommand(interp, "flash_banks", Jim_Command_flash_banks, NULL, NULL );
 		
-		register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC,
-						 "list configured flash banks ");
 		register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,
 						 "print info about flash bank <num>");
 		register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC,
@@ -340,26 +337,6 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
 	return ERROR_OK;
 }
 
-int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-	flash_bank_t *p;
-	int i = 0;
-
-	if (!flash_banks)
-	{
-		command_print(cmd_ctx, "no flash banks configured");
-		return ERROR_OK;
-	}
-
-	for (p = flash_banks; p; p = p->next)
-	{
-		command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
-					  i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
-	}
-
-	return ERROR_OK;
-}
-
 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
 	flash_bank_t *p;
diff --git a/src/helper/command.c b/src/helper/command.c
index 42ff199bcc870a91589afcd437f2dbaa88e1dd80..79d64ba7d6472f5743e91d17a063c79b43437253 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -465,25 +465,13 @@ int command_run_line_internal(command_context_t *context, char *line)
 
 int command_run_line(command_context_t *context, char *line)
 {
-	int retval;
-	
-	if ((!context) || (!line))
-		return ERROR_INVALID_ARGUMENTS;
-	
-	if ((retval = command_run_line_internal(context, line)) == ERROR_COMMAND_NOTFOUND)
-	{
-		/* If we can't find a command, then try the interpreter. 
-		 * If there is no interpreter implemented, then this will
-		 * simply print a syntax error.
-		 * 
-		 * These hooks were left in to reduce patch size for 
-		 * wip to add scripting language.
-		 */
-		
-		return jim_command(context, line);
-	}
-	
-	return retval;
+	/* if a command is unknown to the "unknown" proc in tcl/commands.tcl will
+	 * redirect it to OpenOCD.
+	 * 
+	 * This avoids having to type the "openocd" prefix and makes OpenOCD
+	 * commands "native" to Tcl.
+	 */
+	return jim_command(context, line);
 }
 
 int command_run_file(command_context_t *context, FILE *file, enum command_mode mode)
diff --git a/src/openocd.c b/src/openocd.c
index 4698fc1603af30e3ee429df0cc115a4d5333b624..b2a8ade561065d5c97b1e5c79dcb83dd5b1b5fc5 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -379,6 +379,12 @@ int jim_command(command_context_t *context, char *line)
 			line = Jim_GetString(objPtr, NULL);
 			LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL, proc, file, line);
 	    }
+	    long t;
+	    if (Jim_GetLong(interp, Jim_GetVariableStr(interp, "openocd_result", JIM_ERRMSG), &t)==JIM_OK)
+	    {
+	    	return t;
+	    }
+	    return ERROR_FAIL;
 	} else if (retcode == JIM_EXIT) {
 		/* ignore. */
 	/* exit(Jim_GetExitCode(interp)); */
@@ -419,6 +425,13 @@ static int Jim_Command_openocd_ignore(Jim_Interp *interp, int argc, Jim_Obj *con
 	
 	log_add_callback(tcl_output, tclOutput);
 	retval=command_run_line_internal(active_cmd_ctx, cmd);
+
+	/* we need to be able to get at the retval, so we store in a variable
+	 */
+	Jim_Obj *resultvar=Jim_NewIntObj(interp, retval);
+	Jim_IncrRefCount(resultvar);
+	Jim_SetGlobalVariableStr(interp, "openocd_result", resultvar);
+	Jim_DecrRefCount(interp, resultvar);
 	
 	if (startLoop)
 	{
diff --git a/src/tcl/commands.tcl b/src/tcl/commands.tcl
index a2cf0812df22e504f1af2f80d9f4a910e499ce33..a25badcc8151f673aa786e3cc452840b34fd6980 100644
--- a/src/tcl/commands.tcl
+++ b/src/tcl/commands.tcl
@@ -12,3 +12,49 @@ proc board_produce {filename serialnumber} {
 proc board_test {} {
 	echo "Production test not implemented"
 }
+
+# Show flash in human readable form
+# This is an example of a human readable form of a low level fn
+proc flash_banks_pretty {} { 
+	set i 0 	
+	set result ""
+	foreach {a} [flash_banks] {
+		if {$i > 0} {
+			set result "$result\n"
+		}
+		set result [format "$result#%d: %s at 0x%08x, size 0x%08x, buswidth %d, chipwidth %d" $i [lindex $a 0] [lindex $a 1] [lindex $a 2] [lindex $a 3] [lindex $a 4]]
+		set i [expr $i+1]	
+	}	
+	return $result
+}
+
+# We need to explicitly redirect this to the OpenOCD command
+# as Tcl defines the exit proc
+proc exit {} {
+	openocd_throw exit
+}
+
+# If a fn is unknown to Tcl, we try to execute it as an OpenOCD command
+proc unknown {args} {
+
+	# This is uglier than it needs to be since the "flash banks" is really
+	# a single command. For now only "flash banks" has been converted from
+	# C to Tcl as an example, but if we do decide to go down this path, then
+	# some more generic scheme will be put in place here.
+	#
+	# Help texts need a makeover. There needs to be help texts for
+	# tcl procs + perhaps some work w.r.t. making the help command
+	# format things prettier.
+	if {[string compare [lindex $args 0] flash]==0 && [string compare [lindex $args 1] banks]==0} {
+		return [flash_banks_pretty]
+	}  
+
+	# We print out as we run the command
+	if {[string length $args]>0} {
+		openocd_throw "$args"
+	}
+	# The primary return value have been set by "openocd" above,
+	# so we need to clear it, lest we print out the output from
+	# the command twice.
+	return ""
+}