Index: /soft/giet_vm/applications/shell/shell.c
===================================================================
--- /soft/giet_vm/applications/shell/shell.c	(revision 788)
+++ /soft/giet_vm/applications/shell/shell.c	(revision 789)
@@ -12,8 +12,17 @@
 #include "string.h"
 
-#define BUF_SIZE    (256)        // buffer for one command
+#define MAX_SIZE    (128)        // max number of characters in one command
+#define LOG_DEPTH   (128)        // max number of commands in log
 #define MAX_ARGS    (32)         // max number of arguments in a command
 #define FIFO_SIZE   (1024)       // FIFO depth for recursive ls
 
+////////////////////////////////////////////////////////////////////////////////
+//       Global Variables
+////////////////////////////////////////////////////////////////////////////////
+
+char         log_buf[LOG_DEPTH][MAX_SIZE];   // registered command strings
+unsigned int log_count[LOG_DEPTH];           // registered command lengths
+unsigned int ptw;                            // write pointer in log
+unsigned int ptr;                            // read pointer in log
 
 struct command_t
@@ -24,9 +33,205 @@
 };
 
+// this array initialised afer commands definition
+struct command_t cmd[];
+
 ////////////////////////////////////////////////////////////////////////////////
-//  Shell  Commands
+//       Shell  Commands
 ////////////////////////////////////////////////////////////////////////////////
 
-struct command_t cmd[];
+/////////////////////////////////////////////
+static void cmd_cat(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        giet_tty_printf("  usage : cat pathname \n");
+        return;
+    }
+
+    unsigned int     x,y,p;          // processor coordinates
+    unsigned int     fd;             // file descriptor
+    fat_file_info_t  info;           // file info
+    unsigned int     size;           // buffer size (file_size + 1)
+    unsigned int     bytes;          // number of bytes to be mapped  
+    char*            buf = NULL;     // temporary buffer
+
+    // get processor coordinates 
+    giet_proc_xyp( &x , &y , &p );
+    
+    // open the file to display   
+    fd = giet_fat_open( argv[1] , 0 );
+    if (fd < 0)
+    {
+        giet_tty_printf("  error : cannot open %s\n", argv[1]);
+        goto exit;
+    }
+
+    // get file size
+    giet_fat_file_info( fd, &info );
+    if ( info.is_dir )
+    {
+        giet_tty_printf("  error : %s is a directory\n", argv[1] );
+        goto exit;
+    }
+    size = info.size;  
+
+    // extend size to 4 Kbytes boundary if required
+    if ( (size+1) & 0xFFF)  bytes = (size & 0xFFFFF000) + 0x1000;
+    else                    bytes = size + 1;
+
+    // map local buffer to Cache_file
+    buf = giet_fat_mmap( NULL,
+                         bytes,
+                         MAP_PROT_READ | MAP_PROT_WRITE, 
+                         MAP_SHARED,
+                         fd,
+                         0 ); 
+    if ( buf == NULL )
+    {
+        giet_tty_printf("  error : cannot map %s\n", argv[1] );
+        goto exit;
+    }
+
+    // set terminating '0' 
+    buf[size] = 0;
+
+    // display the file content
+    giet_tty_printf("%s", buf );
+
+exit:
+    if ( fd >= 0 )     giet_fat_close( fd );
+    if ( buf != NULL ) giet_fat_munmap( buf , bytes );
+}  // end cmd_cat()
+
+/////////////////////////////////////////////
+static void cmd_context(int argc, char** argv)
+{
+    if (argc < 3)
+    {
+        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
+        return;
+    }
+
+    giet_pthread_control( THREAD_CMD_CONTEXT , argv[1] , argv[2] );
+}  // end cmd_context()
+
+/////////////////////////////////////////
+static void cmd_cp(int argc, char** argv)
+{
+    if (argc < 3)
+    {
+        giet_tty_printf("  usage : cp src_pathname dst_pathname>\n");
+        return;
+    }
+
+    char buf[1024];
+    int src_fd = -1;
+    int dst_fd = -1;
+    fat_file_info_t info;
+    int size;
+    int i;
+
+    src_fd = giet_fat_open( argv[1] , O_RDONLY );
+    if (src_fd < 0)
+    {
+        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
+        goto exit;
+    }
+
+    giet_fat_file_info(src_fd, &info);
+
+    if (info.is_dir)
+    {
+        giet_tty_printf("  error : %s is a directory\n", argv[1] );
+        goto exit;
+    }
+
+    size = info.size;
+
+    dst_fd = giet_fat_open( argv[2] , O_CREAT | O_TRUNC);
+
+    if (dst_fd < 0)
+    {
+        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
+        goto exit;
+    }
+
+    giet_fat_file_info(dst_fd, &info);
+
+    if (info.is_dir)
+    {
+        giet_tty_printf("  error : %s is a directory\n", argv[2] );  // TODO
+        goto exit;
+    }
+
+    i = 0;
+    while (i < size)
+    {
+        int len = (size - i < 1024 ? size - i : 1024);
+        int wlen;
+
+        len = giet_fat_read(src_fd, &buf, len);
+        wlen = giet_fat_write(dst_fd, &buf, len);
+        if (wlen != len)
+        {
+            giet_tty_printf("  error : cannot write on device\n");
+            goto exit;
+        }
+        i += len;
+    }
+
+exit:
+    if (src_fd >= 0)
+        giet_fat_close(src_fd);
+    if (dst_fd >= 0)
+        giet_fat_close(dst_fd);
+}  // end cmd_cp()
+
+///////////////////////////////////////////
+static void cmd_dump(int argc, char** argv)
+{
+    if ((argc == 2) && (strcmp( argv[1] , "-bs" ) == 0))
+    {
+        giet_fat_dump( DUMP_BS , NULL , 0 );
+    }
+    else if ((argc == 2) && (strcmp( argv[1] , "-fs" ) == 0))
+    {
+        giet_fat_dump( DUMP_FS , NULL , 0 );
+    }
+    else if ((argc == 3) && (strcmp( argv[1] , "-fat" ) == 0))
+    {
+        giet_fat_dump( DUMP_FAT , NULL , atoi( argv[2] ) );
+    }
+    else if ((argc == 4) && (strcmp( argv[1] , "-file" ) == 0))
+    {
+        giet_fat_dump( DUMP_FILE , argv[2] , atoi( argv[3] ) );
+    }
+    else if ((argc == 4) && (strcmp( argv[1] , "-dir" ) == 0))
+    {
+        giet_fat_dump( DUMP_DIR , argv[2] , atoi( argv[3] ) );
+    }
+    else
+    {
+        giet_tty_printf("  usage : dump [-bs] [-fs] [-fat block] "
+                        "[-file pathname block] [-dir pathname block]\n");
+        return;
+    }
+}  // end cmd_dump()
+
+///////////////////////////////////////////
+static void cmd_exec(int argc, char **argv)
+{
+    if (argc < 2)
+    {
+        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
+        return;
+    }
+
+    int ret = giet_exec_application(argv[1]);
+    if ( ret == -1 )
+    {
+        giet_tty_printf("  error : %s not found\n", argv[1] );
+    }
+}  // end cmd_exec()
 
 ///////////////////////////////////////////
@@ -41,12 +246,36 @@
         giet_tty_printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc );
     }
-}
+}  // end cmd_help()
 
 ///////////////////////////////////////////
-static void cmd_time(int argc, char** argv)
-{
-    giet_tty_printf(" cycle = %d\n", giet_proctime());
-}
-
+static void cmd_kill(int argc, char **argv)
+{
+    if (argc < 2)
+    {
+        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
+        return;
+    }
+
+    int ret = giet_kill_application(argv[1]);
+    if ( ret == -1 )
+    {
+        giet_tty_printf("  error : %s not found\n", argv[1] );
+    }
+    if ( ret == -2 )
+    {
+        giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
+    }
+}  // end cmd_kill()
+
+///////////////////////////////////////////
+static void cmd_log( int argc, char** argv)
+{
+    giet_tty_printf("--- registered commands ---\n");
+    unsigned int i;
+    for ( i = 0 ; i < LOG_DEPTH ; i++ )
+    {
+        giet_tty_printf(" - %d\t: %s\n", i , &log_buf[i][0] );
+    }
+}  // end cmd_log()
 
 /////////////////////////////////////////
@@ -100,5 +329,5 @@
 
         // display directory pathname
-        giet_tty_printf("*** %s ***\n", paths[ptr] );
+        giet_tty_printf("--- %s ---\n", paths[ptr] );
 
         // loop on directory entries
@@ -165,77 +394,58 @@
         giet_tty_printf("  error : cannot create directory %s / err = %d\n", argv[1], ret);
     }
-}
+}  // end cmd_mkdir()
 
 /////////////////////////////////////////
-static void cmd_cp(int argc, char** argv)
+static void cmd_mv(int argc, char **argv)
 {
     if (argc < 3)
     {
-        giet_tty_printf("  usage : cp src_pathname dst_pathname>\n");
-        return;
-    }
-
-    char buf[1024];
-    int src_fd = -1;
-    int dst_fd = -1;
-    fat_file_info_t info;
-    int size;
-    int i;
-
-    src_fd = giet_fat_open( argv[1] , O_RDONLY );
-    if (src_fd < 0)
-    {
-        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
-        goto exit;
-    }
-
-    giet_fat_file_info(src_fd, &info);
-
-    if (info.is_dir)
-    {
-        giet_tty_printf("  error : %s is a directory\n", argv[1] );
-        goto exit;
-    }
-
-    size = info.size;
-
-    dst_fd = giet_fat_open( argv[2] , O_CREAT | O_TRUNC);
-
-    if (dst_fd < 0)
-    {
-        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
-        goto exit;
-    }
-
-    giet_fat_file_info(dst_fd, &info);
-
-    if (info.is_dir)
-    {
-        giet_tty_printf("  error : %s is a directory\n", argv[2] );  // TODO
-        goto exit;
-    }
-
-    i = 0;
-    while (i < size)
-    {
-        int len = (size - i < 1024 ? size - i : 1024);
-        int wlen;
-
-        len = giet_fat_read(src_fd, &buf, len);
-        wlen = giet_fat_write(dst_fd, &buf, len);
-        if (wlen != len)
-        {
-            giet_tty_printf("  error : cannot write on device\n");
-            goto exit;
-        }
-        i += len;
-    }
-
-exit:
-    if (src_fd >= 0)
-        giet_fat_close(src_fd);
-    if (dst_fd >= 0)
-        giet_fat_close(dst_fd);
-}
+        giet_tty_printf("  usage : %s src_pathname dst_pathname\n", argv[0]);
+        return;
+    }
+
+    int ret = giet_fat_rename(argv[1], argv[2]);
+    if (ret < 0)
+    {
+        giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
+    }
+}  // end cmd_mv()
+
+////////////////////////////////////////////
+static void cmd_pause(int argc, char** argv)
+{
+    if (argc < 3)
+    {
+        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
+        return;
+    }
+
+    giet_pthread_control( THREAD_CMD_PAUSE , argv[1] , argv[2] );
+}  // end cmd_pause()
+
+/////////////////////////////////////////
+static void cmd_ps(int argc, char** argv)
+{
+    if (argc == 1)
+    {
+        giet_applications_status( NULL );
+    }
+    else
+    {
+        giet_applications_status( argv[1] );
+    }
+}  // end cmd_ps()
+
+/////////////////////////////////////////////
+static void cmd_resume(int argc, char** argv)
+{
+    if (argc < 3)
+    {
+        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
+        return;
+    }
+
+    giet_pthread_control( THREAD_CMD_RESUME , argv[1] , argv[2] );
+}  // end cmd_resume()
 
 /////////////////////////////////////////
@@ -254,5 +464,5 @@
         giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
     }
-}
+}  // end cmd_rm()
 
 ////////////////////////////////////////////
@@ -270,204 +480,14 @@
         giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
     }
+}  // end cmd_rmdir()
+
+///////////////////////////////////////////
+static void cmd_time(int argc, char** argv)
+{
+    giet_tty_printf(" cycle = %d\n", giet_proctime());
 }
 
-/////////////////////////////////////////
-static void cmd_mv(int argc, char **argv)
-{
-    if (argc < 3)
-    {
-        giet_tty_printf("  usage : %s src_pathname dst_pathname\n", argv[0]);
-        return;
-    }
-
-    int ret = giet_fat_rename(argv[1], argv[2]);
-    if (ret < 0)
-    {
-        giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
-    }
-}
-
-///////////////////////////////////////////
-static void cmd_exec(int argc, char **argv)
-{
-    if (argc < 2)
-    {
-        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
-        return;
-    }
-
-    int ret = giet_exec_application(argv[1]);
-    if ( ret == -1 )
-    {
-        giet_tty_printf("  error : %s not found\n", argv[1] );
-    }
-}
-
-///////////////////////////////////////////
-static void cmd_kill(int argc, char **argv)
-{
-    if (argc < 2)
-    {
-        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
-        return;
-    }
-
-    int ret = giet_kill_application(argv[1]);
-    if ( ret == -1 )
-    {
-        giet_tty_printf("  error : %s not found\n", argv[1] );
-    }
-    if ( ret == -2 )
-    {
-        giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
-    }
-}
-
-/////////////////////////////////////////
-static void cmd_ps(int argc, char** argv)
-{
-    if (argc == 1)
-    {
-        giet_applications_status( NULL );
-    }
-    else
-    {
-        giet_applications_status( argv[1] );
-    }
-}
-
-////////////////////////////////////////////
-static void cmd_pause(int argc, char** argv)
-{
-    if (argc < 3)
-    {
-        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
-        return;
-    }
-
-    giet_pthread_control( THREAD_CMD_PAUSE , argv[1] , argv[2] );
-}
-
-/////////////////////////////////////////////
-static void cmd_resume(int argc, char** argv)
-{
-    if (argc < 3)
-    {
-        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
-        return;
-    }
-
-    giet_pthread_control( THREAD_CMD_RESUME , argv[1] , argv[2] );
-}
-
-/////////////////////////////////////////////
-static void cmd_context(int argc, char** argv)
-{
-    if (argc < 3)
-    {
-        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
-        return;
-    }
-
-    giet_pthread_control( THREAD_CMD_CONTEXT , argv[1] , argv[2] );
-}
-
-/////////////////////////////////////////////
-static void cmd_cat(int argc, char** argv)
-{
-    if (argc != 2)
-    {
-        giet_tty_printf("  usage : cat pathname \n");
-        return;
-    }
-
-    unsigned int     x,y,p;          // processor coordinates
-    unsigned int     fd;             // file descriptor
-    fat_file_info_t  info;           // file info
-    unsigned int     size;           // buffer size (file_size + 1)
-    unsigned int     bytes;          // number of bytes to be mapped  
-    char*            buf = NULL;     // temporary buffer
-
-    // get processor coordinates 
-    giet_proc_xyp( &x , &y , &p );
-    
-    // open the file to display   
-    fd = giet_fat_open( argv[1] , 0 );
-    if (fd < 0)
-    {
-        giet_tty_printf("  error : cannot open %s\n", argv[1]);
-        goto exit;
-    }
-
-    // get file size
-    giet_fat_file_info( fd, &info );
-    if ( info.is_dir )
-    {
-        giet_tty_printf("  error : %s is a directory\n", argv[1] );
-        goto exit;
-    }
-    size = info.size;  
-
-    // extend size to 4 Kbytes boundary if required
-    if ( (size+1) & 0xFFF)  bytes = (size & 0xFFFFF000) + 0x1000;
-    else                    bytes = size + 1;
-
-    // map local buffer to Cache_file
-    buf = giet_fat_mmap( NULL,
-                         bytes,
-                         MAP_PROT_READ | MAP_PROT_WRITE, 
-                         MAP_SHARED,
-                         fd,
-                         0 ); 
-    if ( buf == NULL )
-    {
-        giet_tty_printf("  error : cannot map %s\n", argv[1] );
-        goto exit;
-    }
-
-    // set terminating '0' 
-    buf[size] = 0;
-
-    // display the file content
-    giet_tty_printf("%s", buf );
-
-exit:
-    if ( fd >= 0 )     giet_fat_close( fd );
-    if ( buf != NULL ) giet_fat_munmap( buf , bytes );
-}
-
-///////////////////////////////////////////
-static void cmd_dump(int argc, char** argv)
-{
-    if ((argc == 2) && (strcmp( argv[1] , "-bs" ) == 0))
-    {
-        giet_fat_dump( DUMP_BS , NULL , 0 );
-    }
-    else if ((argc == 2) && (strcmp( argv[1] , "-fs" ) == 0))
-    {
-        giet_fat_dump( DUMP_FS , NULL , 0 );
-    }
-    else if ((argc == 3) && (strcmp( argv[1] , "-fat" ) == 0))
-    {
-        giet_fat_dump( DUMP_FAT , NULL , atoi( argv[2] ) );
-    }
-    else if ((argc == 4) && (strcmp( argv[1] , "-file" ) == 0))
-    {
-        giet_fat_dump( DUMP_FILE , argv[2] , atoi( argv[3] ) );
-    }
-    else if ((argc == 4) && (strcmp( argv[1] , "-dir" ) == 0))
-    {
-        giet_fat_dump( DUMP_DIR , argv[2] , atoi( argv[3] ) );
-    }
-    else
-    {
-        giet_tty_printf("  usage : dump [-bs] [-fs] [-fat block] "
-                        "[-file pathname block] [-dir pathname block]\n");
-        return;
-    }
-}
-
-
-////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////////
 struct command_t cmd[] =
 {
@@ -479,5 +499,6 @@
     { "help",       "list available commands",              cmd_help },
     { "kill",       "kill an application (all threads)",    cmd_kill },
-    { "ls",         "list content of a directory",          cmd_ls },
+    { "log",        "list registered commands",             cmd_log },
+    { "ls",         "list directory entries",               cmd_ls },
     { "mkdir",      "create a new directory",               cmd_mkdir },
     { "mv",         "move a file in file system",           cmd_mv },
@@ -490,6 +511,8 @@
     { NULL,         NULL,                                   NULL }
 };
-
-// shell
+/////////////////////////////////////////////////////////////////////////////////////
+
+
+
 
 ///////////////////////////////////////////////////////////////////
@@ -538,14 +561,8 @@
         if (!found)
         {
-            giet_tty_printf("undefined command %s\n", argv[0]);
+            giet_tty_printf("\n  undefined command %s\n", argv[0]);
         }
     }
-}
-
-////////////////////
-static void prompt()
-{
-    giet_tty_printf("# ");
-}
+} // end parse()
 
 //////////////////////////////////////////
@@ -553,11 +570,30 @@
 //////////////////////////////////////////
 {
-    char c;
-    char buf[BUF_SIZE];
-    int count = 0;
+    char         c;                              // read character
+    char         buf[MAX_SIZE];                  // buffer for one command
+    unsigned int count = 0;                      // pointer in buf
+    unsigned int i , j;                          // indexes for loops
+
+    enum fsm_states
+    {
+        NORMAL,
+        ESCAPE,
+        BRAKET,
+    };
 
     // get a private TTY
     giet_tty_alloc( 0 );
     giet_tty_printf( "~~~ shell ~~~\n\n" );
+
+    // log_buf initialisation
+    ptw = 0;
+    ptr = 0;
+    for ( i = 0 ; i < LOG_DEPTH ; i++ )
+    {
+        for ( j = 0 ; j < MAX_SIZE ; j++ )
+        {
+            log_buf[i][j] = 0;
+        }
+    }
 
     // heap initialisation
@@ -568,6 +604,22 @@
     heap_init( x_id , y_id );
 
+    // command buffer initialisation
+    for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
+    count = 0;
+
     // display first prompt
-    prompt();
+    giet_tty_printf("# ");
+
+    // This lexical analyser writes one command line in the buf buffer.
+    // It is implemented as a 3 states FSM to handle the following sequences:
+    // - ESC [ A : up arrow
+    // - ESC [ B : down arrow
+    // - ESC [ C : right arrow
+    // - ESC [ D : left arrow
+    // The thee states have the following semantic:
+    // - NORMAL : no (ESC) character has been found
+    // - ESCAPE : the character (ESC) has been found
+    // - BRAKET : the wo characters (ESC,[) have been found
+    unsigned int state = NORMAL;
 
     while (1)
@@ -575,41 +627,143 @@
         giet_tty_getc(&c);
 
-        switch (c)
-        {
-        case '\b':                       // backspace
-            if (count > 0)
+        switch ( state )
+        {
+            case NORMAL:
+            {  
+                if ( c == '\b' )          // backspace => remove one character from buffer
+                {
+                    if (count > 0)
+                    {
+                        giet_tty_printf("\b \b");
+                        count--;
+                    }
+                }
+                else if ( c == '\n' )     // new line => call parser to execute command
+                {
+                    if (count > 0)
+                    {
+                        // complete commande
+                        buf[count] = '\0';
+
+                        // register command in log arrays        
+                        strcpy( &log_buf[ptw][0] , buf );
+                        log_count[ptw] = count;
+                        ptw = (ptw + 1) % LOG_DEPTH;
+                        ptr = ptw;
+
+                        // execute command
+                        giet_tty_printf("\n");
+                        parse((char*)&buf);
+
+                        // reinitialise buffer and display prompt
+                        for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
+                        count = 0;
+                        giet_tty_printf("# ");
+                    }
+                }
+                else if ( c == '\t' )    // tabulation => do nothing
+                {
+                }
+                else if ( c == 0x1B )    // ESC => start an escape sequence
+                {
+                    state = ESCAPE;
+                }
+                else if ( c == 0x03 )    // ^C  => cancel current command
+                {
+                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
+                    for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
+                    count = 0;
+                }
+                else                     // register character in command buffer
+                {
+                    if (count < sizeof(buf) - 1)
+                    {
+                        giet_tty_printf("%c", c);
+                        buf[count] = c;
+                        count++;
+                    }
+                }
+                break;
+            }
+            case ESCAPE:
             {
-                giet_tty_printf("\b \b");
-                count--;
+                if ( c == '[' )        //  valid sequence => continue
+                {
+                    state = BRAKET;
+                }
+                else                   // invalid sequence => do nothing
+                {
+                    state = NORMAL;
+                }
+                break;
             }
-            break;
-        case '\n':                       // new line
-            giet_tty_printf("\n");
-            if (count > 0)
+            case BRAKET:
             {
-                buf[count] = '\0';
-                parse((char*)&buf);
+                if      ( c == 'D' )   // valid  LEFT sequence => move buf pointer left
+                {
+                    if ( count > 0 )
+                    {
+                        giet_tty_printf("\b");
+                        count--;
+                    }
+
+                    // get next user char
+                    state = NORMAL;
+                }
+                else if ( c == 'C' )   // valid  RIGHT sequence => move buf pointer right
+                {
+                    if ( count < sizeof(buf) - 1)
+                    {
+                        giet_tty_printf("%c", buf[count] );
+                        count++;
+                    }
+
+                    // get next user char
+                    state = NORMAL;
+                }
+                else if ( c == 'A' )   // valid  UP sequence => move log pointer backward
+                {
+                    // cancel current command
+                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
+                    count = 0;
+
+                    // copy log command into buf
+                    ptr = (ptr - 1) % LOG_DEPTH;
+                    strcpy( buf , &log_buf[ptr][0] );
+                    count = log_count[ptr];
+
+                    // display log command 
+                    giet_tty_printf( "%s" , buf );
+
+                    // get next user char
+                    state = NORMAL;
+                }
+                else if ( c == 'B' )   // valid  DOWN sequence => move log pointer forward
+                {
+                    // cancel current command
+                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
+                    count = 0;
+
+                    // copy log command into buf
+                    ptr = (ptr + 1) % LOG_DEPTH;
+                    strcpy( buf , &log_buf[ptr][0] );
+                    count = log_count[ptr];
+
+                    // display log command 
+                    giet_tty_printf( "%s" , buf );
+
+                    // get next user char
+                    state = NORMAL;
+                }
+                else                   // other character => do nothing
+                {
+                    // get next user char
+                    state = NORMAL;
+                }
+                break;
             }
-            prompt();
-            count = 0;
-            break;
-        case '\t':                       // tabulation
-            // do nothing
-            break;
-        case '\03':                      // ^C
-            giet_tty_printf("^C\n");
-            prompt();
-            count = 0;
-            break;
-        default:                         // regular character
-            if (count < sizeof(buf) - 1)
-            {
-                giet_tty_printf("%c", c);
-                buf[count] = c;
-                count++;
-            }
-        }
-    }
-} // end main()
+        }  // end switch on state  
+    }  // end while
+}  // end main()
 
 // Local Variables:
