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