2008-02-21 Pedro Alves <pedro@codesorcery.com>
[external/binutils.git] / gdb / tui / tui-regs.c
1 /* TUI display registers in window.
2
3    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5
6    Contributed by Hewlett-Packard Company.
7
8    This file is part of GDB.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
23 #include "defs.h"
24 #include "tui/tui.h"
25 #include "tui/tui-data.h"
26 #include "symtab.h"
27 #include "gdbtypes.h"
28 #include "gdbcmd.h"
29 #include "frame.h"
30 #include "regcache.h"
31 #include "inferior.h"
32 #include "target.h"
33 #include "gdb_string.h"
34 #include "tui/tui-layout.h"
35 #include "tui/tui-win.h"
36 #include "tui/tui-windata.h"
37 #include "tui/tui-wingeneral.h"
38 #include "tui/tui-file.h"
39 #include "tui/tui-regs.h"
40 #include "reggroups.h"
41 #include "valprint.h"
42
43 #include "gdb_curses.h"
44
45
46 /*****************************************
47 ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
48 ******************************************/
49 static void
50 tui_display_register (struct tui_data_element *data,
51                       struct tui_gen_win_info *win_info);
52
53 static enum tui_status
54 tui_show_register_group (struct gdbarch *gdbarch, 
55                          struct reggroup *group,
56                          struct frame_info *frame, 
57                          int refresh_values_only);
58
59 static enum tui_status
60 tui_get_register (struct gdbarch *gdbarch, 
61                   struct frame_info *frame,
62                   struct tui_data_element *data, 
63                   int regnum, int *changedp);
64 static void tui_register_format (struct gdbarch *, 
65                                  struct frame_info *, 
66                                  struct tui_data_element*, 
67                                  int);
68 static void tui_scroll_regs_forward_command (char *, int);
69 static void tui_scroll_regs_backward_command (char *, int);
70
71
72
73 /*****************************************
74 ** PUBLIC FUNCTIONS                     **
75 ******************************************/
76
77 /* Answer the number of the last line in the regs display.  If there
78    are no registers (-1) is returned.  */
79 int
80 tui_last_regs_line_no (void)
81 {
82   int num_lines = (-1);
83
84   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
85     {
86       num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
87                   TUI_DATA_WIN->detail.data_display_info.regs_column_count);
88       if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
89           TUI_DATA_WIN->detail.data_display_info.regs_column_count)
90         num_lines++;
91     }
92   return num_lines;
93 }
94
95
96 /* Answer the line number that the register element at element_no is
97    on.  If element_no is greater than the number of register elements
98    there are, -1 is returned.  */
99 int
100 tui_line_from_reg_element_no (int element_no)
101 {
102   if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
103     {
104       int i, line = (-1);
105
106       i = 1;
107       while (line == (-1))
108         {
109           if (element_no <
110               (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
111             line = i - 1;
112           else
113             i++;
114         }
115
116       return line;
117     }
118   else
119     return (-1);
120 }
121
122
123 /* Answer the index of the first element in line_no.  If line_no is
124    past the register area (-1) is returned.  */
125 int
126 tui_first_reg_element_no_inline (int line_no)
127 {
128   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
129       <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
130     return ((line_no + 1) *
131             TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
132       TUI_DATA_WIN->detail.data_display_info.regs_column_count;
133   else
134     return (-1);
135 }
136
137
138 /* Answer the index of the last element in line_no.  If line_no is
139    past the register area (-1) is returned.  */
140 int
141 tui_last_reg_element_no_in_line (int line_no)
142 {
143   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <=
144       TUI_DATA_WIN->detail.data_display_info.regs_content_count)
145     return ((line_no + 1) *
146             TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1;
147   else
148     return (-1);
149 }
150
151 /* Show the registers of the given group in the data window
152    and refresh the window.  */
153 void
154 tui_show_registers (struct reggroup *group)
155 {
156   enum tui_status ret = TUI_FAILURE;
157   struct tui_data_info *display_info;
158
159   /* Make sure the curses mode is enabled.  */
160   tui_enable ();
161
162   /* Make sure the register window is visible.  If not, select an
163      appropriate layout.  */
164   if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
165     tui_set_layout_for_display_command (DATA_NAME);
166
167   display_info = &TUI_DATA_WIN->detail.data_display_info;
168   if (group == 0)
169     group = general_reggroup;
170
171   /* Say that registers should be displayed, even if there is a
172      problem.  */
173   display_info->display_regs = TRUE;
174
175   if (target_has_registers && target_has_stack && target_has_memory)
176     {
177       ret = tui_show_register_group (current_gdbarch, group,
178                                      get_current_frame (),
179                                      group == display_info->current_group);
180     }
181   if (ret == TUI_FAILURE)
182     {
183       display_info->current_group = 0;
184       tui_erase_data_content (NO_REGS_STRING);
185     }
186   else
187     {
188       int i;
189
190       /* Clear all notation of changed values.  */
191       for (i = 0; i < display_info->regs_content_count; i++)
192         {
193           struct tui_gen_win_info *data_item_win;
194           struct tui_win_element *win;
195
196           data_item_win = &display_info->regs_content[i]
197             ->which_element.data_window;
198           win = (struct tui_win_element *) data_item_win->content[0];
199           win->which_element.data.highlight = FALSE;
200         }
201       display_info->current_group = group;
202       tui_display_all_data ();
203     }
204 }
205
206
207 /* Set the data window to display the registers of the register group
208    using the given frame.  Values are refreshed only when
209    refresh_values_only is TRUE.  */
210
211 static enum tui_status
212 tui_show_register_group (struct gdbarch *gdbarch, 
213                          struct reggroup *group,
214                          struct frame_info *frame, 
215                          int refresh_values_only)
216 {
217   enum tui_status ret = TUI_FAILURE;
218   int nr_regs;
219   int allocated_here = FALSE;
220   int regnum, pos;
221   char title[80];
222   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
223
224   /* Make a new title showing which group we display.  */
225   snprintf (title, sizeof (title) - 1, "Register group: %s",
226             reggroup_name (group));
227   xfree (TUI_DATA_WIN->generic.title);
228   TUI_DATA_WIN->generic.title = xstrdup (title);
229
230   /* See how many registers must be displayed.  */
231   nr_regs = 0;
232   for (regnum = 0;
233        regnum < gdbarch_num_regs (current_gdbarch)
234                 + gdbarch_num_pseudo_regs (current_gdbarch);
235        regnum++)
236     {
237       /* Must be in the group and have a name.  */
238       if (gdbarch_register_reggroup_p (gdbarch, regnum, group)
239           && gdbarch_register_name (gdbarch, regnum) != 0)
240         nr_regs++;
241     }
242
243   if (display_info->regs_content_count > 0 && !refresh_values_only)
244     {
245       tui_free_data_content (display_info->regs_content,
246                              display_info->regs_content_count);
247       display_info->regs_content_count = 0;
248     }
249
250   if (display_info->regs_content_count <= 0)
251     {
252       display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
253       allocated_here = TRUE;
254       refresh_values_only = FALSE;
255     }
256
257   if (display_info->regs_content != (tui_win_content) NULL)
258     {
259       if (!refresh_values_only || allocated_here)
260         {
261           TUI_DATA_WIN->generic.content = (void*) NULL;
262           TUI_DATA_WIN->generic.content_size = 0;
263           tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
264           display_info->regs_content
265             = (tui_win_content) TUI_DATA_WIN->generic.content;
266           display_info->regs_content_count = nr_regs;
267         }
268
269       /* Now set the register names and values.  */
270       pos = 0;
271       for (regnum = 0;
272            regnum < gdbarch_num_regs (current_gdbarch)
273                     + gdbarch_num_pseudo_regs (current_gdbarch);
274            regnum++)
275         {
276           struct tui_gen_win_info *data_item_win;
277           struct tui_data_element *data;
278           const char *name;
279
280           if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
281             continue;
282
283           name = gdbarch_register_name (gdbarch, regnum);
284           if (name == 0)
285             continue;
286
287           data_item_win =
288             &display_info->regs_content[pos]->which_element.data_window;
289           data =
290             &((struct tui_win_element *) data_item_win->content[0])->which_element.data;
291           if (data)
292             {
293               if (!refresh_values_only)
294                 {
295                   data->item_no = regnum;
296                   data->name = name;
297                   data->highlight = FALSE;
298                 }
299               if (data->value == (void*) NULL)
300                 data->value = (void*) xmalloc (MAX_REGISTER_SIZE);
301
302               tui_get_register (gdbarch, frame, data, regnum, 0);
303             }
304           pos++;
305         }
306
307       TUI_DATA_WIN->generic.content_size =
308         display_info->regs_content_count + display_info->data_content_count;
309       ret = TUI_SUCCESS;
310     }
311
312   return ret;
313 }
314
315 /* Function to display the registers in the content from
316    'start_element_no' until the end of the register content or the end
317    of the display height.  No checking for displaying past the end of
318    the registers is done here.  */
319 void
320 tui_display_registers_from (int start_element_no)
321 {
322   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
323
324   if (display_info->regs_content != (tui_win_content) NULL 
325       && display_info->regs_content_count > 0)
326     {
327       int i = start_element_no;
328       int j, value_chars_wide, item_win_width, cur_y;
329
330       int max_len = 0;
331       for (i = 0; i < display_info->regs_content_count; i++)
332         {
333           struct tui_data_element *data;
334           struct tui_gen_win_info *data_item_win;
335           char *p;
336           int len;
337
338           data_item_win = &display_info->regs_content[i]->which_element.data_window;
339           data = &((struct tui_win_element *)
340                    data_item_win->content[0])->which_element.data;
341           len = 0;
342           p = data->content;
343           if (p != 0)
344             while (*p)
345               {
346                 if (*p++ == '\t')
347                   len = 8 * ((len / 8) + 1);
348                 else
349                   len++;
350               }
351
352           if (len > max_len)
353             max_len = len;
354         }
355       item_win_width = max_len + 1;
356       i = start_element_no;
357
358       display_info->regs_column_count =
359         (TUI_DATA_WIN->generic.width - 2) / item_win_width;
360       if (display_info->regs_column_count == 0)
361         display_info->regs_column_count = 1;
362       item_win_width =
363         (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
364
365       /* Now create each data "sub" window, and write the display into
366          it.  */
367       cur_y = 1;
368       while (i < display_info->regs_content_count 
369              && cur_y <= TUI_DATA_WIN->generic.viewport_height)
370         {
371           for (j = 0;
372                j < display_info->regs_column_count
373                  && i < display_info->regs_content_count;
374                j++)
375             {
376               struct tui_gen_win_info *data_item_win;
377               struct tui_data_element *data_element_ptr;
378
379               /* Create the window if necessary.  */
380               data_item_win = &display_info->regs_content[i]
381                 ->which_element.data_window;
382               data_element_ptr = &((struct tui_win_element *)
383                                  data_item_win->content[0])->which_element.data;
384               if (data_item_win->handle != (WINDOW*) NULL
385                   && (data_item_win->height != 1
386                       || data_item_win->width != item_win_width
387                       || data_item_win->origin.x != (item_win_width * j) + 1
388                       || data_item_win->origin.y != cur_y))
389                 {
390                   tui_delete_win (data_item_win->handle);
391                   data_item_win->handle = 0;
392                 }
393                   
394               if (data_item_win->handle == (WINDOW *) NULL)
395                 {
396                   data_item_win->height = 1;
397                   data_item_win->width = item_win_width;
398                   data_item_win->origin.x = (item_win_width * j) + 1;
399                   data_item_win->origin.y = cur_y;
400                   tui_make_window (data_item_win, DONT_BOX_WINDOW);
401                   scrollok (data_item_win->handle, FALSE);
402                 }
403               touchwin (data_item_win->handle);
404
405               /* Get the printable representation of the register
406                  and display it.  */
407               tui_display_register (data_element_ptr, data_item_win);
408               i++;              /* Next register.  */
409             }
410           cur_y++;              /* Next row.  */
411         }
412     }
413 }
414
415
416 /* Function to display the registers in the content from
417    'start_element_no' on 'start_line_no' until the end of the register
418    content or the end of the display height.  This function checks
419    that we won't display off the end of the register display.  */
420 static void
421 tui_display_reg_element_at_line (int start_element_no,
422                                  int start_line_no)
423 {
424   if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL
425       && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
426     {
427       int element_no = start_element_no;
428
429       if (start_element_no != 0 && start_line_no != 0)
430         {
431           int last_line_no, first_line_on_last_page;
432
433           last_line_no = tui_last_regs_line_no ();
434           first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2);
435           if (first_line_on_last_page < 0)
436             first_line_on_last_page = 0;
437
438           /* If there is no other data displayed except registers, and
439              the element_no causes us to scroll past the end of the
440              registers, adjust what element to really start the
441              display at.  */
442           if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
443               && start_line_no > first_line_on_last_page)
444             element_no = tui_first_reg_element_no_inline (first_line_on_last_page);
445         }
446       tui_display_registers_from (element_no);
447     }
448 }
449
450
451
452 /* Function to display the registers starting at line line_no in the
453    data window.  Answers the line number that the display actually
454    started from.  If nothing is displayed (-1) is returned.  */
455 int
456 tui_display_registers_from_line (int line_no, 
457                                  int force_display)
458 {
459   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
460     {
461       int line, element_no;
462
463       if (line_no < 0)
464         line = 0;
465       else if (force_display)
466         { /* If we must display regs (force_display is true), then
467              make sure that we don't display off the end of the
468              registers.  */
469           if (line_no >= tui_last_regs_line_no ())
470             {
471               if ((line = tui_line_from_reg_element_no (
472                  TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
473                 line = 0;
474             }
475           else
476             line = line_no;
477         }
478       else
479         line = line_no;
480
481       element_no = tui_first_reg_element_no_inline (line);
482       if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
483         tui_display_reg_element_at_line (element_no, line);
484       else
485         line = (-1);
486
487       return line;
488     }
489
490   return (-1);                  /* Nothing was displayed.  */
491 }
492
493
494 /* This function check all displayed registers for changes in values,
495    given a particular frame.  If the values have changed, they are
496    updated with the new value and highlighted.  */
497 void
498 tui_check_register_values (struct frame_info *frame)
499 {
500   if (TUI_DATA_WIN != NULL
501       && TUI_DATA_WIN->generic.is_visible)
502     {
503       struct tui_data_info *display_info
504         = &TUI_DATA_WIN->detail.data_display_info;
505
506       if (display_info->regs_content_count <= 0 
507           && display_info->display_regs)
508         tui_show_registers (display_info->current_group);
509       else
510         {
511           int i, j;
512
513           for (i = 0; (i < display_info->regs_content_count); i++)
514             {
515               struct tui_data_element *data;
516               struct tui_gen_win_info *data_item_win_ptr;
517               int was_hilighted;
518
519               data_item_win_ptr = &display_info->regs_content[i]->
520                 which_element.data_window;
521               data = &((struct tui_win_element *)
522                        data_item_win_ptr->content[0])->which_element.data;
523               was_hilighted = data->highlight;
524
525               tui_get_register (current_gdbarch, frame, data,
526                                 data->item_no, &data->highlight);
527
528               if (data->highlight || was_hilighted)
529                 {
530                   tui_display_register (data, data_item_win_ptr);
531                 }
532             }
533         }
534     }
535 }
536
537 /* Display a register in a window.  If hilite is TRUE, then the value
538    will be displayed in reverse video.  */
539 static void
540 tui_display_register (struct tui_data_element *data,
541                       struct tui_gen_win_info *win_info)
542 {
543   if (win_info->handle != (WINDOW *) NULL)
544     {
545       int i;
546
547       if (data->highlight)
548         wstandout (win_info->handle);
549       
550       wmove (win_info->handle, 0, 0);
551       for (i = 1; i < win_info->width; i++)
552         waddch (win_info->handle, ' ');
553       wmove (win_info->handle, 0, 0);
554       if (data->content)
555         waddstr (win_info->handle, data->content);
556
557       if (data->highlight)
558         wstandend (win_info->handle);
559       tui_refresh_win (win_info);
560     }
561 }
562
563 static void
564 tui_reg_next_command (char *arg, int from_tty)
565 {
566   if (TUI_DATA_WIN != 0)
567     {
568       struct reggroup *group
569         = TUI_DATA_WIN->detail.data_display_info.current_group;
570
571       group = reggroup_next (current_gdbarch, group);
572       if (group == 0)
573         group = reggroup_next (current_gdbarch, 0);
574
575       if (group)
576         tui_show_registers (group);
577     }
578 }
579
580 static void
581 tui_reg_float_command (char *arg, int from_tty)
582 {
583   tui_show_registers (float_reggroup);
584 }
585
586 static void
587 tui_reg_general_command (char *arg, int from_tty)
588 {
589   tui_show_registers (general_reggroup);
590 }
591
592 static void
593 tui_reg_system_command (char *arg, int from_tty)
594 {
595   tui_show_registers (system_reggroup);
596 }
597
598 static struct cmd_list_element *tuireglist;
599
600 static void
601 tui_reg_command (char *args, int from_tty)
602 {
603   printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
604                      "tui reg command.\n"));
605   help_list (tuireglist, "tui reg ", -1, gdb_stdout);
606 }
607
608 /* Provide a prototype to silence -Wmissing-prototypes.  */
609 extern initialize_file_ftype _initialize_tui_regs;
610
611 void
612 _initialize_tui_regs (void)
613 {
614   struct cmd_list_element **tuicmd;
615
616   tuicmd = tui_get_cmd_list ();
617
618   add_prefix_cmd ("reg", class_tui, tui_reg_command,
619                   _("TUI commands to control the register window."),
620                   &tuireglist, "tui reg ", 0,
621                   tuicmd);
622
623   add_cmd ("float", class_tui, tui_reg_float_command,
624            _("Display only floating point registers."),
625            &tuireglist);
626   add_cmd ("general", class_tui, tui_reg_general_command,
627            _("Display only general registers."),
628            &tuireglist);
629   add_cmd ("system", class_tui, tui_reg_system_command,
630            _("Display only system registers."),
631            &tuireglist);
632   add_cmd ("next", class_tui, tui_reg_next_command,
633            _("Display next register group."),
634            &tuireglist);
635
636   if (xdb_commands)
637     {
638       add_com ("fr", class_tui, tui_reg_float_command,
639                _("Display only floating point registers\n"));
640       add_com ("gr", class_tui, tui_reg_general_command,
641                _("Display only general registers\n"));
642       add_com ("sr", class_tui, tui_reg_system_command,
643                _("Display only special registers\n"));
644       add_com ("+r", class_tui, tui_scroll_regs_forward_command,
645                _("Scroll the registers window forward\n"));
646       add_com ("-r", class_tui, tui_scroll_regs_backward_command,
647                _("Scroll the register window backward\n"));
648     }
649 }
650
651
652 /*****************************************
653 ** STATIC LOCAL FUNCTIONS                 **
654 ******************************************/
655
656 extern int pagination_enabled;
657
658 static void
659 tui_restore_gdbout (void *ui)
660 {
661   ui_file_delete (gdb_stdout);
662   gdb_stdout = (struct ui_file*) ui;
663   pagination_enabled = 1;
664 }
665
666 /* Get the register from the frame and make a printable representation
667    of it in the data element.  */
668 static void
669 tui_register_format (struct gdbarch *gdbarch, 
670                      struct frame_info *frame,
671                      struct tui_data_element *data_element, 
672                      int regnum)
673 {
674   struct ui_file *stream;
675   struct ui_file *old_stdout;
676   const char *name;
677   struct cleanup *cleanups;
678   char *p, *s;
679   int pos;
680   struct type *type = register_type (gdbarch, regnum);
681
682   name = gdbarch_register_name (gdbarch, regnum);
683   if (name == 0)
684     {
685       return;
686     }
687   
688   pagination_enabled = 0;
689   old_stdout = gdb_stdout;
690   stream = tui_sfileopen (256);
691   gdb_stdout = stream;
692   cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
693   if (TYPE_VECTOR (type) != 0 && 0)
694     {
695       gdb_byte buf[MAX_REGISTER_SIZE];
696       int len;
697       struct value_print_options opts;
698
699       len = register_size (current_gdbarch, regnum);
700       fprintf_filtered (stream, "%-14s ", name);
701       get_frame_register (frame, regnum, buf);
702       get_formatted_print_options (&opts, 'f');
703       print_scalar_formatted (buf, type, &opts, len, stream);
704     }
705   else
706     {
707       gdbarch_print_registers_info (current_gdbarch, stream,
708                                     frame, regnum, 1);
709     }
710
711   /* Save formatted output in the buffer.  */
712   p = tui_file_get_strbuf (stream);
713
714   /* Remove the possible \n.  */
715   s = strrchr (p, '\n');
716   if (s && s[1] == 0)
717     *s = 0;
718
719   xfree (data_element->content);
720   data_element->content = xstrdup (p);
721   do_cleanups (cleanups);
722 }
723
724 /* Get the register value from the given frame and format it for the
725    display.  When changep is set, check if the new register value has
726    changed with respect to the previous call.  */
727 static enum tui_status
728 tui_get_register (struct gdbarch *gdbarch, 
729                   struct frame_info *frame,
730                   struct tui_data_element *data, 
731                   int regnum, int *changedp)
732 {
733   enum tui_status ret = TUI_FAILURE;
734
735   if (changedp)
736     *changedp = FALSE;
737   if (target_has_registers)
738     {
739       gdb_byte buf[MAX_REGISTER_SIZE];
740       get_frame_register (frame, regnum, buf);
741
742       if (changedp)
743         {
744           int size = register_size (gdbarch, regnum);
745           char *old = (char*) data->value;
746           int i;
747
748           for (i = 0; i < size; i++)
749             if (buf[i] != old[i])
750               {
751                 *changedp = TRUE;
752                 old[i] = buf[i];
753               }
754         }
755
756       /* Reformat the data content if the value changed.  */
757       if (changedp == 0 || *changedp == TRUE)
758         tui_register_format (gdbarch, frame, data, regnum);
759
760       ret = TUI_SUCCESS;
761     }
762   return ret;
763 }
764
765 static void
766 tui_scroll_regs_forward_command (char *arg, int from_tty)
767 {
768   tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
769 }
770
771
772 static void
773 tui_scroll_regs_backward_command (char *arg, int from_tty)
774 {
775   tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
776 }