handle special key codes in a serial terminal, and remove unnecessary push/pop operations in asm.S.

This commit is contained in:
okuji 2000-08-25 16:58:44 +00:00
parent 3c5fa0cfe3
commit 16cbb2b422
6 changed files with 216 additions and 106 deletions

View file

@ -1,3 +1,41 @@
2000-08-26 OKUJI Yoshinori <okuji@gnu.org>
Don't save/restore fragile registers unnecessarily.
* stage2/asm.S [!STAGE1_5] (track_int13): Don't save/restore
%ecx, %edx, or %eax.
[!STAGE1_5] (set_int13_handler): Likewise.
(biosdisk_int13_extensions): Likewise.
(biosdisk_standard): Likewise.
(check_int13_extensions): Likewise.
(get_diskinfo_int13_extensions): Likewise.
(get_diskinfo_standard): Likewise.
(get_diskinfo_floppy): Likewise.
[!STAGE1_5] (get_eisamemsize): Likewise.
[!STAGE1_5] (get_mmap_entry): Likewise.
[!STAGE1_5] (console_cls): Likewise.
[!STAGE1_5] (nocursor): Likewise.
[!STAGE1_5] (console_getxy): Likewise.
[!STAGE1_5] (console_gotoxy): Likewise.
[!STAGE1_5] (set_attrib): Likewise.
[!STAGE1_5] (getrtsecs): Likewise.
[!STAGE1_5] (currticks): Likewise, and don't zero %eax
explicitly, since prot_to_real does that.
2000-08-25 OKUJI Yoshinori <okuji@gnu.org>
* stage2/char_io.c [!STAGE1_5] (translate_keycode): New
function. The serial part is stolen from the patch by Christoph
Plattner.
[!STAGE1_5] (get_cmdline): Call translate_keycode instead of
translating special key codes into ASCII characters by itself.
* stage2/stage2.c (run_menu): Wrap getkey with the macro
ASCII_CHAR, when checking if ESC is pressed.
Call translate_keycode as well as getkey, unless checkkey
returns -1. So don't check if C is KEY_DOWN or KEY_UP. And don't
use the macro ASCII_CHAR for C explicitly.
* stage2/shared.h (translate_keycode): Declared.
2000-08-24 OKUJI Yoshinori <okuji@gnu.org> 2000-08-24 OKUJI Yoshinori <okuji@gnu.org>
* stage2/builtins.c [GRUB_UTIL]: Include stdio.h before * stage2/builtins.c [GRUB_UTIL]: Include stdio.h before

View file

@ -432,6 +432,31 @@ getrtsecs (void)
return time (0); return time (0);
} }
int
currticks (void)
{
struct timeval tv;
long csecs;
int ticks_per_csec, ticks_per_usec;
/* Note: 18.2 ticks/sec. */
/* Get current time. */
gettimeofday (&tv, 0);
/* Compute centiseconds. */
csecs = tv.tv_sec / 10;
/* Ticks per centisecond. */
ticks_per_csec = csecs * 182;
/* Ticks per microsecond. */
ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec)
* 182 / 10000000);
/* Sum them. */
return ticks_per_csec + ticks_per_usec;
}
/* low-level character I/O */ /* low-level character I/O */
void void

View file

@ -18,6 +18,23 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/*
* Note: These functions defined in this file may be called from C.
* Be careful of that you must not modify some registers. Quote
* from gcc-2.95.2/gcc/config/i386/i386.h:
1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
The latter must include the registers where values are returned
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like.
ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
*/
#define ASM_FILE #define ASM_FILE
#include "shared.h" #include "shared.h"
@ -258,7 +275,6 @@ ENTRY(track_int13)
pushl %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
pushl %edx
pushl %ebx pushl %ebx
pushl %edi pushl %edi
@ -310,7 +326,6 @@ ENTRY(track_int13)
popl %edi popl %edi
popl %ebx popl %ebx
popl %edx
popl %ebp popl %ebp
ret ret
@ -605,7 +620,6 @@ ENTRY(set_int13_handler)
pushl %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
pushl %ecx
pushl %edi pushl %edi
pushl %esi pushl %esi
@ -649,7 +663,6 @@ ENTRY(set_int13_handler)
popl %esi popl %esi
popl %edi popl %edi
popl %ecx
popl %ebp popl %ebp
ret ret
@ -938,8 +951,6 @@ ENTRY(biosdisk_int13_extensions)
pushl %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
pushl %ecx
pushl %edx
pushl %esi pushl %esi
/* compute the address of disk_address_packet */ /* compute the address of disk_address_packet */
@ -971,8 +982,6 @@ ENTRY(biosdisk_int13_extensions)
movb %dl, %al /* return value in %eax */ movb %dl, %al /* return value in %eax */
popl %esi popl %esi
popl %edx
popl %ecx
popl %ebp popl %ebp
ret ret
@ -991,8 +1000,6 @@ ENTRY(biosdisk_standard)
movl %esp, %ebp movl %esp, %ebp
pushl %ebx pushl %ebx
pushl %ecx
pushl %edx
pushl %edi pushl %edi
pushl %esi pushl %esi
@ -1044,8 +1051,6 @@ ENTRY(biosdisk_standard)
popl %esi popl %esi
popl %edi popl %edi
popl %edx
popl %ecx
popl %ebx popl %ebx
popl %ebp popl %ebp
@ -1064,8 +1069,6 @@ ENTRY(check_int13_extensions)
movl %esp, %ebp movl %esp, %ebp
pushl %ebx pushl %ebx
pushl %ecx
pushl %edx
/* drive */ /* drive */
movb 0x8(%ebp), %dl movb 0x8(%ebp), %dl
@ -1100,8 +1103,6 @@ ENTRY(check_int13_extensions)
movb %bl, %al /* return value in %eax */ movb %bl, %al /* return value in %eax */
popl %edx
popl %ecx
popl %ebx popl %ebx
popl %ebp popl %ebp
@ -1120,7 +1121,6 @@ ENTRY(get_diskinfo_int13_extensions)
movl %esp, %ebp movl %esp, %ebp
pushl %ebx pushl %ebx
pushl %edx
pushl %esi pushl %esi
/* compute the address of drive parameters */ /* compute the address of drive parameters */
@ -1149,7 +1149,6 @@ ENTRY(get_diskinfo_int13_extensions)
movb %bl, %al /* return value in %eax */ movb %bl, %al /* return value in %eax */
popl %esi popl %esi
popl %edx
popl %ebx popl %ebx
popl %ebp popl %ebp
@ -1169,8 +1168,6 @@ ENTRY(get_diskinfo_standard)
movl %esp, %ebp movl %esp, %ebp
pushl %ebx pushl %ebx
pushl %ecx
pushl %edx
pushl %edi pushl %edi
/* drive */ /* drive */
@ -1196,7 +1193,7 @@ ENTRY(get_diskinfo_standard)
.code32 .code32
/* restore %ebp */ /* restore %ebp */
leal 0x10(%esp), %ebp leal 0x8(%esp), %ebp
/* heads */ /* heads */
movb %dh, %al movb %dh, %al
@ -1224,8 +1221,6 @@ ENTRY(get_diskinfo_standard)
movb %bl, %al /* return value in %eax */ movb %bl, %al /* return value in %eax */
popl %edi popl %edi
popl %edx
popl %ecx
popl %ebx popl %ebx
popl %ebp popl %ebp
@ -1245,8 +1240,6 @@ ENTRY(get_diskinfo_floppy)
movl %esp, %ebp movl %esp, %ebp
pushl %ebx pushl %ebx
pushl %ecx
pushl %edx
pushl %esi pushl %esi
/* drive */ /* drive */
@ -1291,7 +1284,7 @@ probe_values:
.code32 .code32
/* restore %ebp */ /* restore %ebp */
leal 0x10(%esp), %ebp leal 0x8(%esp), %ebp
/* cylinders */ /* cylinders */
movl 0xc(%ebp), %eax movl 0xc(%ebp), %eax
@ -1313,8 +1306,6 @@ probe_values:
incl %eax /* %eax = 1 (non-zero) */ incl %eax /* %eax = 1 (non-zero) */
3: 3:
popl %esi popl %esi
popl %edx
popl %ecx
popl %ebx popl %ebx
popl %ebp popl %ebp
@ -1505,8 +1496,6 @@ xdone:
ENTRY(get_eisamemsize) ENTRY(get_eisamemsize)
push %ebp push %ebp
push %ebx push %ebx
push %ecx
push %edx
call EXT_C(prot_to_real) /* enter real mode */ call EXT_C(prot_to_real) /* enter real mode */
.code16 .code16
@ -1527,8 +1516,6 @@ ENTRY(get_eisamemsize)
movl %ebx, %eax movl %ebx, %eax
xnoteisa: xnoteisa:
pop %edx
pop %ecx
pop %ebx pop %ebx
pop %ebp pop %ebp
ret ret
@ -1549,13 +1536,11 @@ xnoteisa:
ENTRY(get_mmap_entry) ENTRY(get_mmap_entry)
push %ebp push %ebp
push %ebx push %ebx
push %ecx
push %edx
push %edi push %edi
push %esi push %esi
/* place address (+4) in ES:DI */ /* place address (+4) in ES:DI */
movl 0x1c(%esp), %eax movl 0x14(%esp), %eax
addl $4, %eax addl $4, %eax
movl %eax, %edi movl %eax, %edi
andl $0xf, %edi andl $0xf, %edi
@ -1563,7 +1548,7 @@ ENTRY(get_mmap_entry)
movl %eax, %esi movl %eax, %esi
/* set continuation value */ /* set continuation value */
movl 0x20(%esp), %ebx movl 0x18(%esp), %ebx
/* set default maximum buffer size */ /* set default maximum buffer size */
movl $0x14, %ecx movl $0x14, %ecx
@ -1599,7 +1584,7 @@ xsmap:
.code32 .code32
/* write length of buffer (zero if error) into "addr" */ /* write length of buffer (zero if error) into "addr" */
movl 0x1c(%esp), %eax movl 0x14(%esp), %eax
movl %ecx, (%eax) movl %ecx, (%eax)
/* set return value to continuation */ /* set return value to continuation */
@ -1607,8 +1592,6 @@ xsmap:
pop %esi pop %esi
pop %edi pop %edi
pop %edx
pop %ecx
pop %ebx pop %ebx
pop %ebp pop %ebp
ret ret
@ -1769,7 +1752,6 @@ ENTRY(multi_boot)
ENTRY(console_cls) ENTRY(console_cls)
push %ebp push %ebp
push %eax
push %ebx /* save EBX */ push %ebx /* save EBX */
call EXT_C(prot_to_real) call EXT_C(prot_to_real)
@ -1784,7 +1766,6 @@ ENTRY(console_cls)
.code32 .code32
pop %ebx pop %ebx
pop %eax
pop %ebp pop %ebp
ret ret
@ -1799,9 +1780,7 @@ ENTRY(console_cls)
ENTRY(nocursor) ENTRY(nocursor)
push %ebp push %ebp
push %eax
push %ebx /* save EBX */ push %ebx /* save EBX */
push %edx
call EXT_C(prot_to_real) call EXT_C(prot_to_real)
.code16 .code16
@ -1813,9 +1792,7 @@ ENTRY(nocursor)
DATA32 call EXT_C(real_to_prot) DATA32 call EXT_C(real_to_prot)
.code32 .code32
pop %edx
pop %ebx pop %ebx
pop %eax
pop %ebp pop %ebp
ret ret
@ -1835,8 +1812,6 @@ ENTRY(nocursor)
ENTRY(console_getxy) ENTRY(console_getxy)
push %ebp push %ebp
push %ebx /* save EBX */ push %ebx /* save EBX */
push %ecx /* save ECX */
push %edx
call EXT_C(prot_to_real) call EXT_C(prot_to_real)
.code16 .code16
@ -1851,8 +1826,6 @@ ENTRY(console_getxy)
movb %dl, %ah movb %dl, %ah
movb %dh, %al movb %dh, %al
pop %edx
pop %ecx
pop %ebx pop %ebx
pop %ebp pop %ebp
ret ret
@ -1870,12 +1843,10 @@ ENTRY(console_getxy)
ENTRY(console_gotoxy) ENTRY(console_gotoxy)
push %ebp push %ebp
push %eax
push %ebx /* save EBX */ push %ebx /* save EBX */
push %edx
movb 0x14(%esp), %dl /* %dl = x */ movb 0xc(%esp), %dl /* %dl = x */
movb 0x18(%esp), %dh /* %dh = y */ movb 0x10(%esp), %dh /* %dh = y */
call EXT_C(prot_to_real) call EXT_C(prot_to_real)
.code16 .code16
@ -1887,9 +1858,7 @@ ENTRY(console_gotoxy)
DATA32 call EXT_C(real_to_prot) DATA32 call EXT_C(real_to_prot)
.code32 .code32
pop %edx
pop %ebx pop %ebx
pop %eax
pop %ebp pop %ebp
ret ret
@ -1931,11 +1900,9 @@ ENTRY(console_gotoxy)
ENTRY(set_attrib) ENTRY(set_attrib)
push %ebp push %ebp
push %eax
push %ebx push %ebx
push %ecx
movl 0x14(%esp), %ecx movl 0xc(%esp), %ecx
xorl %ebx, %ebx xorl %ebx, %ebx
call EXT_C(prot_to_real) call EXT_C(prot_to_real)
@ -1951,9 +1918,7 @@ ENTRY(set_attrib)
DATA32 call EXT_C(real_to_prot) DATA32 call EXT_C(real_to_prot)
.code32 .code32
pop %ecx
pop %ebx pop %ebx
pop %eax
pop %ebp pop %ebp
ret ret
@ -1978,8 +1943,6 @@ ENTRY(set_attrib)
*/ */
ENTRY(getrtsecs) ENTRY(getrtsecs)
push %ebp push %ebp
push %ecx
push %edx
call EXT_C(prot_to_real) /* enter real mode */ call EXT_C(prot_to_real) /* enter real mode */
.code16 .code16
@ -1996,8 +1959,6 @@ gottime:
movb %dh, %al movb %dh, %al
pop %edx
pop %ecx
pop %ebp pop %ebp
ret ret
@ -2009,13 +1970,11 @@ gottime:
*/ */
ENTRY(currticks) ENTRY(currticks)
pushl %ebp pushl %ebp
pushl %ecx
pushl %edx
call EXT_C(prot_to_real) /* enter real mode */ call EXT_C(prot_to_real) /* enter real mode */
.code16 .code16
xorl %eax, %eax /* %ax is already zero */
int $0x1a int $0x1a
DATA32 call EXT_C(real_to_prot) DATA32 call EXT_C(real_to_prot)
@ -2025,8 +1984,6 @@ ENTRY(currticks)
shll $16, %eax shll $16, %eax
movw %dx, %ax movw %dx, %ax
popl %edx
popl %ecx
popl %ebp popl %ebp
ret ret

View file

@ -337,36 +337,8 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r') while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r')
{ {
switch (c) c = translate_keycode (c);
{
case KEY_LEFT:
c = 2;
break;
case KEY_RIGHT:
c = 6;
break;
case KEY_UP:
c = 16;
break;
case KEY_DOWN:
c = 14;
break;
case KEY_HOME:
c = 1;
break;
case KEY_END:
c = 5;
break;
case KEY_DC:
c = 4;
break;
case KEY_BACKSPACE:
c = 8;
break;
}
c = ASCII_CHAR (c);
/* If READLINE is non-zero, handle readline-like key bindings. */ /* If READLINE is non-zero, handle readline-like key bindings. */
if (readline) if (readline)
{ {
@ -618,6 +590,126 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
return 0; return 0;
} }
/* Translate a special key to a common ascii code. */
int
translate_keycode (int c)
{
# ifdef SUPPORT_SERIAL
if (terminal & TERMINAL_SERIAL)
{
/* In a serial terminal, things are complicated, because several
key codes start from the character ESC, while we want to accept
ESC itself. */
if (c == '\e')
{
int start;
/* Get current time. */
start = currticks ();
while (checkkey () == -1)
{
/* Wait for a next character, at least for 0.1 sec
(18.2 ticks/sec). */
int now;
now = currticks ();
if (now - start >= 2)
return c;
}
c = getkey ();
if (c == '[')
{
int c1, c2;
/* To filter illegal states. */
c = 0;
c1 = getkey ();
switch (c1)
{
case 'A': /* KEY_UP */
c = 16;
break;
case 'B': /* KEY_DOWN */
c = 14;
break;
case 'C': /* KEY_RIGHT */
c = 6;
break;
case 'D': /* KEY_LEFT */
c = 2;
break;
case 'F': /* End */
c = 5;
break;
case 'H': /* Home */
c = 1;
break;
case '1':
c2 = getkey ();
if (c2 == '~')
{
/* One of control keys (pos1,....). */
c = 1;
}
break;
case '3':
c2 = getkey ();
if (c2 == '~')
{
/* One of control keys (del,....). */
c = 4;
}
break;
case '4': /* Del */
c = 4;
break;
}
}
/* Drain the input buffer, because so-called VT100-compatible
terminals could send key codes which aren't handled in the
code above. */
while (checkkey () != -1)
(void) getkey ();
}
}
else
# endif /* SUPPORT_SERIAL */
{
switch (c)
{
case KEY_LEFT:
c = 2;
break;
case KEY_RIGHT:
c = 6;
break;
case KEY_UP:
c = 16;
break;
case KEY_DOWN:
c = 14;
break;
case KEY_HOME:
c = 1;
break;
case KEY_END:
c = 5;
break;
case KEY_DC:
c = 4;
break;
case KEY_BACKSPACE:
c = 8;
break;
}
}
return ASCII_CHAR (c);
}
#endif /* STAGE1_5 */ #endif /* STAGE1_5 */
int int

View file

@ -798,6 +798,7 @@ int nul_terminate (char *str);
int get_based_digit (int c, int base); int get_based_digit (int c, int base);
int safe_parse_maxint (char **str_ptr, int *myint_ptr); int safe_parse_maxint (char **str_ptr, int *myint_ptr);
int memcheck (int start, int len); int memcheck (int start, int len);
int translate_keycode (int c);
#ifndef NO_DECOMPRESSION #ifndef NO_DECOMPRESSION
/* Compression support. */ /* Compression support. */

View file

@ -260,7 +260,7 @@ restart:
while (1) while (1)
{ {
/* Check if ESC is pressed. */ /* Check if ESC is pressed. */
if (checkkey () != -1 && getkey () == 27) if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e')
{ {
grub_timeout = -1; grub_timeout = -1;
show_menu = 1; show_menu = 1;
@ -358,7 +358,7 @@ restart:
if (checkkey () != -1) if (checkkey () != -1)
{ {
c = getkey (); c = translate_keycode (getkey ());
if (grub_timeout >= 0) if (grub_timeout >= 0)
{ {
@ -369,7 +369,7 @@ restart:
gotoxy (74, 4 + entryno); gotoxy (74, 4 + entryno);
} }
if ((c == KEY_UP) || (ASCII_CHAR (c) == 16)) if (c == 16)
{ {
if (entryno > 0) if (entryno > 0)
{ {
@ -386,8 +386,7 @@ restart:
set_line_highlight (4, first_entry + entryno, menu_entries); set_line_highlight (4, first_entry + entryno, menu_entries);
} }
} }
if (((c == KEY_DOWN) || (ASCII_CHAR (c) == 14)) if (c == 14 && (first_entry + entryno + 1) < num_entries)
&& (first_entry + entryno + 1) < num_entries)
{ {
if (entryno < 11) if (entryno < 11)
{ {
@ -405,8 +404,6 @@ restart:
} }
} }
c = ASCII_CHAR (c);
if (config_entries) if (config_entries)
{ {
if ((c == '\n') || (c == '\r')) if ((c == '\n') || (c == '\r'))