c/2819: ICE in reload_cse_simplify_operands, at reload1.c:8347

etienne.Lorrain@nextstar.masroudeau.com etienne.Lorrain@nextstar.masroudeau.com
Mon May 14 08:26:00 GMT 2001


>Number:         2819
>Category:       c
>Synopsis:       register allocation problem in ull_div_ul() ?
>Confidential:   no
>Severity:       critical
>Priority:       low
>Responsible:    unassigned
>State:          open
>Class:          ice-on-legal-code
>Submitter-Id:   net
>Arrival-Date:   Mon May 14 08:26:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Etienne Lorrain
>Release:        3.1 20010427 (experimental)
>Organization:
The bootloader debugger -:)
>Environment:
System: Linux nextstar.masroudeau.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: avr-unknown-none
configured with: ./configure --target=avr --enable-languages=c --disable-nls
>Description:
   GCC do no more like this inline function:
extern inline const unsigned long
ull_div_ul (unsigned long long ull, unsigned long ul, unsigned long *remainder)
  {
  unsigned long result;

  asm /* const */ (" divl %3 "
        : "=a" (result), "=d" (*remainder)
        : "A" (ull), "rm" (ul) : "cc" );

  return result;
  }
   Happen with GCC from RedHat 7.1 and on 2001-05-12 with
http://www.codesourcery.com/gcc-compile.shtml
>How-To-Repeat:
gcc -fomit-frame-pointer -Os 
  of this file: (sorry quite long - reducing it too much hide the bug)
-------------------
extern inline void _memset (void *buffer, int value, unsigned size)
  {
  size++;
  while (--size)
      *((unsigned char *)buffer)++ = value;
  }

extern inline void _memcpy (void *dst, const void *src, unsigned size)
  {
  size++;
  while (--size)
      *((unsigned char *)dst)++ = *((unsigned char *)src)++;
  }

extern inline int _memcmp (const void *s1, const void *s2, unsigned nb)
  {

  nb++;
  while (--nb != 0) {
      if (*(unsigned char *)s1 != *(unsigned char *)s2)
          break;
      ((unsigned char *)s1)++;
      ((unsigned char *)s2)++;
      }

  return (*(unsigned char *)s1 > *(unsigned char *)s2)? 1
                : ((*(unsigned char *)s1 < *(unsigned char *)s2)? -1
                : 0);
  }


extern inline const char *_strnchr (const char *str, char c, unsigned size)
  {

  while (*str++ != c && size--) ;

  return str - 1;
  }

extern inline void _strncpy (char *dst, const char *src, unsigned nb)
  {

  do {
      if (nb-- == 0)
          break;
      *dst++ = *src;
      } while (*src++);
  *dst = '\0';
  }

extern inline int _strncmp (const char *s1, const char *s2, unsigned nb)
  {

  while (*s1) {
      if (--nb == 0)
          break;
      if (*s1 != *s2)
          break;
      s1++; s2++;
      }
  return (*s1 > *s2)? 1 : ((*s1 < *s2)? -1 : 0);

  }

extern inline void *memcpy (void *dst, const void *src, unsigned size)
  {
  if (__builtin_constant_p (size)) {
      if (size == 1) {
          ((unsigned char *)dst)[0] = ((const unsigned char *)src)[0];
          return dst;
          }
        else if (size == 2) {
          ((unsigned short *)dst)[0] = ((const unsigned short *)src)[0];
          return dst;
          }
        else if (size == 3) {
          ((unsigned short *)dst)[0] = ((const unsigned short *)src)[0];
          ((unsigned char *)dst)[2] = ((const unsigned char *)src)[2];
          return dst;
          }
        else if (size == 4) {
          ((unsigned *)dst)[0] = ((const unsigned *)src)[0];
          return dst;
          }
        else if (size == 5) {
          ((unsigned *)dst)[0] = ((const unsigned *)src)[0];
          ((unsigned char *)dst)[4] = ((const unsigned char *)src)[4];
          return dst;
          }
        else if (size == 6) {
          ((unsigned *)dst)[0] = ((const unsigned *)src)[0];
          ((unsigned short *)dst)[2] = ((const unsigned short *)src)[2];
          return dst;
          }
        else if (size == 8) {
          ((unsigned *)dst)[0] = ((const unsigned *)src)[0];
          ((unsigned *)dst)[1] = ((const unsigned *)src)[1];
          return dst;
          }
      }
  _memcpy (dst, src, size);
  return dst;
  }


extern inline unsigned memeql (const void *dst, const void *src, unsigned size)
  {
  if (__builtin_constant_p (size)) {
      if (size == 1) {
          return ((const unsigned char *)dst)[0] == ((const unsigned char *)src)[0];
          }
        else if (size == 2) {
          return ((const unsigned short *)dst)[0] == ((const unsigned short *)src)[0];
          }
        else if (size == 3) {
          return ((const unsigned short *)dst)[0] == ((const unsigned short *)src)[0]
              && ((const unsigned char *)dst)[2] == ((const unsigned char *)src)[2];
          }
        else if (size == 4) {
          return ((const unsigned *)dst)[0] == ((const unsigned *)src)[0];
          }
        else if (size == 5) {
          return ((const unsigned *)dst)[0] == ((const unsigned *)src)[0]
              && ((const unsigned char *)dst)[4] == ((const unsigned char *)src)[4];
          }
        else if (size == 6) {
          return ((const unsigned *)dst)[0] == ((const unsigned *)src)[0]
              && ((const unsigned short *)dst)[2] == ((const unsigned short *)src)[2];
          }
        else if (size == 8) {
          return ((const unsigned *)dst)[0] == ((const unsigned *)src)[0]
              && ((const unsigned *)dst)[1] == ((const unsigned *)src)[1];
          }
      }
  return !_memcmp (dst, src, size);
  }

extern inline void *memset (void *dst, int value, unsigned size)
  {
  if (__builtin_constant_p (size)) {
      if (size == 1) {
          ((unsigned char *)dst)[0] = value;
          return dst;
          }
        else if (size == 2) {
          unsigned short val = (value & 0xFF) | (value << 8);
          ((unsigned short *)dst)[0] = val;
          return dst;
          }
        else if (size == 3) {
          unsigned short val = (value & 0xFF) | (value << 8);
          ((unsigned short *)dst)[0] = val;
          ((unsigned char *)dst)[2] = val;
          return dst;
          }
        else if (size == 4) {
          unsigned val = value & 0xFF;
          val |= val << 8;
          val |= val << 16;
          ((unsigned *)dst)[0] = val;
          return dst;
          }
        else if (size == 5) {
          unsigned val = value & 0xFF;
          val |= val << 8;
          val |= val << 16;
          ((unsigned *)dst)[0] = val;
          ((unsigned char *)dst)[4] = val;
          return dst;
          }
        else if (size == 6) {
          unsigned val = value & 0xFF;
          val |= val << 8;
          val |= val << 16;
          ((unsigned *)dst)[0] = val;
          ((unsigned short *)dst)[2] = val;
          return dst;
          }
        else if (size == 8) {
          unsigned val = value & 0xFF;
          val |= val << 8;
          val |= val << 16;
          ((unsigned *)dst)[0] = val;
          ((unsigned *)dst)[1] = val;
          return dst;
          }
      }
  _memset (dst, value, size);
  return dst;
  }

extern inline int memcmp (const void *s1, const void *s2, unsigned nb)
  {
  return _memcmp (s1, s2, nb);
  }


extern inline void *_bzero (void *buffer, unsigned size)
  {
  _memset (buffer, 0, size);
  return buffer;
  }

extern inline unsigned strlen (const char *str)
  {
  return _strnchr (str, '\0', 4096) - str;
  }

extern inline char *strcat (char *dst, const char *src)
  {
  _strncpy ((char *) _strnchr (dst, '\0', 4096), src, 4096);
  return dst;
  }

extern inline char *strncpy (char *dst, const char *src, unsigned nb)
  {
  _strncpy (dst, src, nb);
  return dst;
  }

extern inline char *strcpy (char *dst, const char *src)
  {
  _strncpy (dst, src, 4096);
  return dst;
  }

extern inline int strncmp (const char *s1, const char *s2, unsigned nb)
  {
  return _strncmp (s1, s2, nb);
  }

extern inline int strcmp (const char *s1, const char *s2)
  {
  return _strncmp (s1, s2, 4096);
  }

extern inline int stricmp (const char *s1, const char *s2)
  {
  unsigned char tmp1 = *s1, tmp2 = *s2;

  if (!tmp1)
      return (tmp2 == 0)? 0 : 1;

  while (tmp1) {
      if (tmp1 >= 'a')
          tmp1 -= 'a' - 'A';
      if (tmp2 >= 'a')
          tmp2 -= 'a' - 'A';
      if (tmp1 != tmp2)
          break;
      tmp1 = *++s1;
      tmp2 = *++s2;
      }
  return (tmp1 > tmp2)? 1 : ((tmp1 < tmp2)? -1 : 0);
  }

extern inline const unsigned my_ffs (unsigned val)
  {
  unsigned result;
  asm (" bsf	%1,%0 " : "=g" (result) : "g" (val) : "cc");
  return result + 1;
  }

enum detect_memory_enum {
    mem_E801 = 0, mem_AMI, mem_Phoenix, mem_8800, mem_nvram
    };
enum detect_memory_enum detect_memory (unsigned *basemem, unsigned *extendmem);

extern const char *const mem_name[];


char *prtf (char *buffer, char *endbuffer, const char *format, void **param);
int printf (const char *format, ...);
void print (const char *msg);
void puts (const char *msg);
int sprintf (char *dest, const char *format, ...);

void restore_vectors (void);


void BIOS_killme (void);

extern unsigned _etext[], _srodata[], _end[], _sbss[], _edata[];
extern unsigned char deltaseg[];


extern unsigned _eextra[];
extern unsigned char extraseg[];






void __ERROR(void);

extern inline void setds (unsigned short val) { asm volatile (" movw %w0,%%""ds"" " : : "r" (val)); }
extern inline void setes (unsigned short val) { asm volatile (" movw %w0,%%""es"" " : : "r" (val)); }
extern inline void setfs (unsigned short val) { asm volatile (" movw %w0,%%""fs"" " : : "r" (val)); }
extern inline void setgs (unsigned short val) { asm volatile (" movw %w0,%%""gs"" " : : "r" (val)); }
extern inline void setss (unsigned short val) { asm volatile (" movw %w0,%%""ss"" " : : "r" (val)); }

extern inline unsigned short getcs (void) { unsigned short returned; asm volatile (" movw %%""cs"",%w0 " : "=r" (returned)); return returned; }
extern inline unsigned short getds (void) { unsigned short returned; asm volatile (" movw %%""ds"",%w0 " : "=r" (returned)); return returned; }
extern inline unsigned short getes (void) { unsigned short returned; asm volatile (" movw %%""es"",%w0 " : "=r" (returned)); return returned; }
extern inline unsigned short getfs (void) { unsigned short returned; asm volatile (" movw %%""fs"",%w0 " : "=r" (returned)); return returned; }
extern inline unsigned short getgs (void) { unsigned short returned; asm volatile (" movw %%""gs"",%w0 " : "=r" (returned)); return returned; }
extern inline unsigned short getss (void) { unsigned short returned; asm volatile (" movw %%""ss"",%w0 " : "=r" (returned)); return returned; }

extern inline void update_ds (void) { asm volatile (" movw %%""ds"":(0),%%ax " : : : "ax"); }
extern inline void update_es (void) { asm volatile (" movw %%""es"":(0),%%ax " : : : "ax"); }
extern inline void update_fs (void) { asm volatile (" movw %%""fs"":(0),%%ax " : : : "ax"); }
extern inline void update_gs (void) { asm volatile (" movw %%""gs"":(0),%%ax " : : : "ax"); }
extern inline void update_ss (void) { asm volatile (" movw %%""ss"":(0),%%ax " : : : "ax"); }

extern inline void trydoor_peek_ds (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""ds"":(%0),%0 ; nop " : "+a" (dummy)); }
extern inline void trydoor_peek_es (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""es"":(%0),%0 ; nop " : "+a" (dummy)); }
extern inline void trydoor_peek_fs (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""fs"":(%0),%0 ; nop " : "+a" (dummy)); }
extern inline void trydoor_peek_gs (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""gs"":(%0),%0 ; nop " : "+a" (dummy)); }
extern inline void trydoor_peek_cs (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""cs"":(%0),%0 ; nop " : "+a" (dummy)); }
extern inline void trydoor_peek_ss (void) { unsigned dummy = 0x10000; asm volatile (" movl  %%""ss"":(%0),%0 ; nop " : "+a" (dummy)); }




typedef unsigned long farptr;


extern inline const farptr linear2farptr (unsigned addr)
  {

  return (addr & 0xFFFF) + ((addr >> 16) << 28);
  }

extern inline const farptr data_adr (const void *data)
  {
  extern const unsigned dataseg_adr;

      return (farptr)(dataseg_adr | (unsigned) data);
  }

extern inline const farptr stack_adr (const void *data)
  {
  extern const unsigned dataseg_adr;

  return (farptr)(dataseg_adr | (unsigned) data);
  }

extern inline const farptr code_adr (const void *data)
  {
  extern const unsigned codeseg_adr;

  return (farptr)(codeseg_adr | (unsigned) data);
  }

extern inline const farptr extra_adr (const void *data)
  {
  extern const unsigned extraseg_adr;

  return (farptr)(extraseg_adr | (unsigned) data);
  }

extern inline const unsigned linear2dsrelative (unsigned addr)
  {
  extern const unsigned dataseg_adr;

  return addr - (dataseg_adr >> 12);
  }

extern inline const unsigned dsrelative2linear (unsigned addr)
  {
  extern const unsigned dataseg_adr;

  return addr + (dataseg_adr >> 12);
  }


extern inline unsigned char inb (unsigned short port)
  {
  unsigned char result;
  asm volatile (" inb %1,%0 " : "=a" (result) : "dN" (port));
  return result;
  }

extern inline unsigned short inw (unsigned short port)
  {
  unsigned short result;
  asm volatile (" inw %1,%0 " : "=a" (result) : "dN" (port));
  return result;
  }

extern inline unsigned inl (unsigned short port)
  {
  unsigned result;
  asm volatile (" inl %1,%0 " : "=a" (result) : "dN" (port));
  return result;
  }

extern inline void outb (unsigned short port, unsigned char data)
  {
  asm volatile (" outb %0,%1 " : : "a" (data), "dN" (port));
  }

extern inline void outw (unsigned short port, unsigned short data)
  {
  asm volatile (" outw %0,%1 " : : "a" (data), "dN" (port));
  }

extern inline void outl (unsigned short port, unsigned data)
  {
  asm volatile (" outl %0,%1 " : : "a" (data), "dN" (port));
  }


extern inline unsigned getflags (void)
  {
  unsigned returned;

  asm volatile (" pushfl ; popl %0 " : "=r" (returned) );
  return returned;
  }

extern inline void setflags (unsigned value)
  {
  asm volatile (" pushl %0 ; popfl " : : "r" (value) );
  }

extern inline void setTFflag (void)
  {
  setflags (getflags () | 0x100);
  }

extern inline void clearTFflag (void)
  {
  setflags (getflags () & ~0x100);
  }

extern inline unsigned is_80486 (void)
  {
  unsigned returned, flags = getflags(),
           mask = 1 << 18;

  setflags (flags ^ mask);
  returned = ((getflags() & mask) != (flags & mask));
  setflags (flags & ~mask);
  return returned;
  }

extern inline unsigned has_cpuid (void)
  {
  unsigned returned, flags = getflags(), mask = 1 << 21;

  setflags (flags ^ mask);
  returned = ((getflags() & mask) != (flags & mask));
  setflags (flags & ~mask);
  return returned;
  }

extern inline unsigned cpuid0 (char string[13])
  {
  unsigned returned;
  unsigned char0to3, char4to7, char8to12;

  asm volatile ( " cpuid "
        : "=a" (returned), "=b" (char0to3), "=d" (char4to7), "=c" (char8to12)
        : "a" (0));
  *(unsigned *)string = char0to3;
  *(unsigned *)(string+4) = char4to7;
  *(unsigned *)(string+8) = char8to12;
  string[12] = 0;
  return returned;
  }

extern inline unsigned short getsw (void)
  {
  unsigned short returned;

  asm volatile (" smsw %0 " : "=r" (returned) );
  return returned;
  }

extern inline void setsw (unsigned short SW)
  {
  asm volatile (" lmsw %0 " : : "r" (SW) );
  }

extern inline void disable_interrupt (void)
  {
  asm volatile (" cli ");
  }

extern inline void enable_interrupt (void)
  {
  asm volatile (" sti ");
  }

extern inline unsigned interrupt_enabled (void)
  {
  return (getflags() & 0x200);
  }

extern inline unsigned peekb_doorclosed (farptr adr)
  {
  unsigned returned;
  unsigned short scratch;

  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movzbl	%%fs:(%w0),%1	\n"
        : "=bSDB" (scratch), "=r" (returned) : "g" (adr));
  return returned;
  }

extern inline unsigned peekw_doorclosed (farptr adr)
  {
  unsigned returned;
  unsigned short scratch;

  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movzwl	%%fs:(%w0),%1	\n"
        : "=bSDB" (scratch), "=r" (returned) : "g" (adr));
  return returned;
  }

extern inline unsigned peekl_doorclosed (farptr adr)
  {
  unsigned returned;
  unsigned short scratch;

  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movl	%%fs:(%w0),%1	\n"
        : "=bSDB" (scratch), "=r" (returned) : "g" (adr));
  return returned;
  }

extern inline void pokeb_doorclosed (farptr adr, unsigned char value)
  {
  unsigned short scratch;
  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movb	%1,%%fs:(%w0)	\n"
        : "=&bSDB" (scratch)
        : "qi" (value), "g" (adr) : "memory");
  }

extern inline void pokew_doorclosed (farptr adr, unsigned short value)
  {
  unsigned short scratch;
  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movw	%1,%%fs:(%w0)	\n"
        : "=&bSDB" (scratch)
        : "qi" (value), "g" (adr) : "memory");
  }

extern inline void pokel_doorclosed (farptr adr, unsigned value)
  {
  unsigned short scratch;
  asm volatile (
"	pushl	%2		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	movl	%1,%%fs:(%w0)	\n"
        : "=&bSDB" (scratch)
        : "ri" (value), "g" (adr) : "memory");
  }

extern inline unsigned xchl_doorclosed (farptr adr, unsigned value)
  {
  unsigned short scratch;

  asm volatile (
"	pushl	%3		\n"
"	popw	%w0		\n"
"	popw	%%fs		\n"
"	xchgl	%%fs:(%w0),%1	\n"
        : "=bSDB" (scratch), "=r" (value)
        : "1" (value), "g" (adr) : "memory");
  return value;
  }

extern inline unsigned codeseg_peekb (void *offset)
  {
  unsigned returned;

  asm volatile (" movzbl	%%cs:%a1,%0 "
        : "=r" (returned) : "g" (offset));
  return returned;

  }

extern inline unsigned codeseg_peekw (void *offset)
  {
  unsigned returned;

  asm volatile (" movzwl	%%cs:%a1,%0 "
        : "=r" (returned) : "g" (offset));
  return returned;

  }

extern inline unsigned codeseg_peekl (void *offset)
  {
  unsigned returned;

  asm volatile (" movl	%%cs:%a1,%0 "
        : "=r" (returned) : "g" (offset));
  return returned;

  }

extern inline void codeseg_pokeb (void *offset, unsigned char value)
  {
  asm volatile (" movb	%0,%%cs:%a1 "
        : : "qi" (value), "g" (offset) : "memory");

  }

extern inline void codeseg_pokew (void *offset, unsigned short value)
  {
  asm volatile (" movw	%0,%%cs:%a1 "
        : : "qi" (value), "g" (offset) : "memory");

  }

extern inline void codeseg_pokel (void *offset, unsigned value)
  {
  asm volatile (" movl	%0,%%cs:%a1 "
        : : "ri" (value), "g" (offset) : "memory");

  }

extern inline unsigned char peekb (farptr adr)
  {
  return peekb_doorclosed (adr);
  }

extern inline unsigned short peekw (farptr adr)
  {
  return peekw_doorclosed (adr);
  }

extern inline unsigned peekl (farptr adr)
  {
  return peekl_doorclosed (adr);
  }

extern inline void pokeb (farptr adr, unsigned char value)
  {
  pokeb_doorclosed (adr, value);
  }

extern inline void pokew (farptr adr, unsigned short value)
  {
  pokew_doorclosed (adr, value);
  }

extern inline void pokel (farptr adr, unsigned value)
  {
  pokel_doorclosed (adr, value);
  }

extern inline unsigned xchgl (farptr adr, unsigned value)
  {
  return xchl_doorclosed (adr, value);
  }


extern inline unsigned long long rdtsc (void)
  {
  unsigned long long returned;

  asm volatile (" rdtsc " : "=A" (returned) );
  return returned;
  }

extern inline const unsigned long
ull_div_ul (unsigned long long ull, unsigned long ul, unsigned long *remainder)
  {
  unsigned long result;

  asm /* const */ (" divl %3 "
        : "=a" (result), "=d" (*remainder)
        : "A" (ull), "rm" (ul) : "cc" );

  return result;
  }

extern volatile unsigned segment_door_key;

unsigned segment_door (unsigned open);

typedef struct {
    unsigned char eightbit :1;
    unsigned char constant_1 :1;
    unsigned char doublestop :1;
    unsigned char parity :1;
    unsigned char even :1;
    enum { B110 = 0, B150, B300, B600, B1200, B2400, B4800, B9600 }
                        speed :3;
    unsigned char constant_0;
    signed short port;
    } __attribute__ ((packed, aligned(1))) serialconf_type;

struct registers {
        unsigned edi, esi, ebp, initsp;
        unsigned ebx, edx, ecx, eax;
        unsigned short gs, fs, aligngap, es, ds;
        unsigned short ip, cs, flags;
        } __attribute__ ((packed));

struct gujin_param_str {
    unsigned magic;
    char dot_msg[4];
    char go_msg[8];
    char extra_cmdline[64];
    unsigned short version;
    unsigned short default_video_mode;
    unsigned short default_text_video_mode, default_graphic_video_mode;
    unsigned char last_loaded, total_loadable, timeout_load;
    unsigned char default_runlevel;
    struct gujin_param_attrib {
        unsigned short refuse_8x14font : 1;
        unsigned short read_only_param : 1;
        unsigned short probe_bootsect : 1;
        unsigned short available : 9;
        unsigned short reserved : 2;
        unsigned short bios_only : 1;
        unsigned short vga_support : 1;
        } __attribute__ ((packed)) attrib;
    unsigned char VGA_valid_mode[16];
    struct vga_mode_str {
        unsigned isgraphic : 1;
        unsigned number : 7;
        unsigned bpp : 4;
        unsigned heigh : 11;
        unsigned width_div8 : 9;
        } __attribute__ ((packed)) vga_mode[30];
    unsigned short partial_checksum;
    } __attribute__ ((packed));

void BOOT1_putstr (const char *str);
void BOOT1_initdisks (unsigned char drive);

extern const unsigned char dos_running;

extern const serialconf_type copy_boot1param_serialconf;

extern inline unsigned getTFflagCounter (void)
  {
  extern unsigned TFflagCounter;

  return codeseg_peekl (&TFflagCounter);
  }

extern inline void setTFflagCounter (unsigned val)
  {
  extern unsigned TFflagCounter;

  codeseg_pokel (&TFflagCounter, val);
  }

extern inline unsigned VIDEO_mode_is_valid (unsigned char mode)
  {
  extern struct gujin_param_str gujin_param;
  unsigned char shift;
  void *adr;

  adr = &gujin_param.VGA_valid_mode[divrem8 (mode, &shift)];
  return !!(codeseg_peekb (adr) & (1 << shift));
  }

extern inline unsigned VIDEO_mode_max (void)
  {
  extern struct gujin_param_str gujin_param;
  return 8 * sizeof (gujin_param.VGA_valid_mode) - 1;
  }

extern inline void bound_stack (void) { }

enum stdcolor_enum {
    black, blue, green, cyan,
    red, magenta, brown, lightgray,
    darkgray, lightblue, lightgreen, lightcyan,
    lightred, lightmagenta, yellow, white
    };

struct DAC_str {
    unsigned char blue, green, red, align;
    };

typedef struct {
    unsigned short x, y;
    } __attribute__ ((packed)) coord;

struct user_interface_str {
    unsigned (*getkey) (void);

    unsigned fgcolor, bgcolor;
    unsigned stdcolor[16];
    struct {
        struct attribute_str {
            unsigned char underline :1;
            unsigned char reverse :1;
            unsigned char blink :1;
            unsigned char brighter :1;
            unsigned char darker :1;
            unsigned char transparent :1;
            unsigned char reserved :2;
            } __attribute__ ((packed)) current, valid;
        } attributes;
    unsigned short monitor;

    unsigned char nbmode;
    struct videomode_str {
        unsigned short number;
        unsigned short width;
        unsigned short heigh;
        unsigned char bpp;
        unsigned char text : 1;
        unsigned char attr : 1;
        unsigned char vesa : 1;
        } *mode;
    union {
        struct {
            unsigned short version;
            unsigned short memory_64Kb;
            unsigned char cardname[40];
            } vesa;
        struct {
            unsigned max_mode;
            unsigned char terminalname[40];
            } serial;
        } info;
    struct edid_str {
        unsigned short horizontal_resolution;
        unsigned short vertical_resolution;
        unsigned short frequency;
        unsigned char Hsize_cm, Vsize_cm;
        } edid;
    unsigned short ProtectedModeIO[32];
    struct {
        unsigned address;
        unsigned short length;
        } ProtectedModeMem[4];
    struct video_parameter_str {
        unsigned identification;
        unsigned nbcolor;
        unsigned short width, heigh;
        unsigned base_address;
        unsigned char row, col;
        unsigned char nbrow, nbcol;
        unsigned char charwidth, charheigh;
        unsigned char isgraphic;
        unsigned char nbimage;
        unsigned char red_mask_size;
        unsigned char red_field_pos;
        unsigned char green_mask_size;
        unsigned char green_field_pos;
        unsigned char blue_mask_size;
        unsigned char blue_field_pos;
        farptr font;
        unsigned winadr;
        unsigned winsize;
        unsigned short linelength;
        unsigned char bitperpixel;
        unsigned char nbplane;
        unsigned char memtype;
        unsigned char EGA_compatible;
        unsigned char BIOS_compatible;
        unsigned char NbWin;
        unsigned char winNo;
        unsigned short *offsetarray;
        struct hardwindow_str {
            unsigned short instruction;
            unsigned short port;
            unsigned data;
            } *hardwindow;
        unsigned char wingranul;
        unsigned winreadadr;
        unsigned readdelta;
        unsigned short *readoffsetarray;
        struct hardwindow_str *readhardwindow;
        unsigned addrpositionfarfct;
        } parameter;

    struct user_interface_fct_str {
        unsigned (*getsize) (unsigned mode, struct video_parameter_str *param);
        unsigned (*setmode) (unsigned mode);
        unsigned (*getmode) (void);
        void (*clearscreen) (void);


        unsigned (*setcursor) (unsigned char row, unsigned char col);
        unsigned (*getcursor) (unsigned char *row, unsigned char *col);

        unsigned (*setfgcolor) (unsigned color);
        unsigned (*setbgcolor) (unsigned color);
        unsigned (*getcolor) (unsigned *fgcolor, unsigned *bgcolor);
        void (*setattribute) (struct attribute_str attr);

        void (*putstr) (const char *str);

        void (*setpixel) (coord xy, unsigned color) __attribute__ (( regparm(1) ));
        unsigned (*getpixel) (coord xy) __attribute__ (( regparm(1) ));
        void (*plotHline) (coord xy, unsigned short xend, unsigned color);

        unsigned (*setDACblock) (unsigned short startindex, unsigned short nb,
                                 const struct DAC_str *palette);
        } function;
    };

extern struct user_interface_str UI;

void UI_init (unsigned serial);

unsigned BIOS_probemonitor (void);
unsigned __attribute__ ((const))
VESA_color (unsigned char _red, unsigned char _green, unsigned char _blue);

unsigned VGA_init (void);

unsigned VESA_init (void);

unsigned SERIAL_init (void);


typedef unsigned long lba_t;
typedef unsigned long nbsector_t;

struct diskparam_str {
    enum { bios_chs, ebios_lba, hardide_chs, hardide_lba, dos_part }
                        access : 8;
    unsigned char disknb;

    unsigned short bytepersector;
    unsigned short nbhead;
    unsigned nbcylinder;
    nbsector_t nbtotalsector;
    unsigned short nbsectorpertrack;

    unsigned short ideIOadr;
    unsigned char multiplemode;
    unsigned char ebiosversion;
    unsigned char irq;
    unsigned char ismaster;

    unsigned char bootable;
    unsigned char OSdisknumber;

    unsigned short nbpartition;
    unsigned short nbOSnumber;
    struct partition_str {
        unsigned start, length;
        unsigned char type, OSnumber;
        struct {
            unsigned char order : 7;
            unsigned char maybe_root : 1;
            } __attribute__ ((packed)) misc;

        enum {part_invalid = 0, part_active, part_inactive} active;

        char name[(32-12)];

        } *partition;


    unsigned nbfreelist;
    struct freelist_str {
        unsigned start, length;
        } *freelist;

    };

extern struct disk_interface_str {
    unsigned nbdisk;
    struct diskparam_str *param;
    } DI;

__attribute__ ((section (".cross_text2extra")))
unsigned char codeseg_DISK_readsector (struct diskparam_str *dp,
                                lba_t lba,
                                unsigned char number,
                                farptr buffer);

__attribute__ ((section (".cross_text2extra")))
void codeseg_diskname (struct diskparam_str *dp, char name[30]);


extern inline unsigned
_BIOS_nbtick (void)
  {
  return peekl (0x0040006C);
  }

extern inline void
_BIOS_failedboot (void)
  {

  asm volatile (" int $0x18 # _BIOS_failedboot" : : "a" (0));
  }

extern inline void
_DOS_stop_exe (void)
  {
  asm volatile (" int $0x21 # _DOS_stop_exe" : : "a" (0x4C00));
  }

extern inline void
_DOS_stop_com (void)
  {
  asm volatile (" int $0x20 # _DOS_stop_com");
  }

extern inline void
_BIOS_sigsegv (void)
  {
  asm volatile (" movw %%cs:(0xFFFF),%%ax " : : : "ax");
  }

extern inline void
_BIOS_halt (void)
  {
  asm volatile (" hlt ");
  }

  
typedef void allocmem __attribute__((aligned(32)));

allocmem *malloc (unsigned size);
void free (allocmem *ptr);
allocmem *realloc (allocmem *ptr, unsigned size);

extern inline void listmode (struct user_interface_str *ui)
  {
  unsigned short start = 0, cpt, firsttime = 1,
                 valid = VIDEO_mode_is_valid(0);

  for (cpt = 1; cpt <= VIDEO_mode_max(); cpt++) {
      if ( cpt == VIDEO_mode_max()
          || VIDEO_mode_is_valid(cpt) != valid) {
          if (valid == 0)
              start = cpt;
            else {
              if (!firsttime)
                  printf (", ");
              firsttime = 0;
              printf ((start < cpt-2)
                        ? "0x%X..0x%X"
                        : (start == cpt-2)? "0x%X, 0x%X" : "0x%X",
                        start, cpt-1);
              }
          valid = !valid;
          }
      }
  if (firsttime)
      printf ("none.\r\n");
    else
      printf (".\r\n");
  }


static unsigned door_open_gs (void)
  {
  segment_door_key = 0;
  }

static void test_bound_stack (void (*fct) (void *))
  {bound_stack();{
  if (fct)
      (*(void (*)(void *)) fct) (fct);
  }}

static void test_bound_data (unsigned addr)
  {
                                                     ;
  }

static void putstr (const char *str)
  {
  UI.function.putstr (str);
  }

static void __attribute__ ((section (".cross_extra2text") ))
extraseg_puts (const char *str)
  {
  asm volatile (" \n " " movw	2+codeseg_adr,%%fs		\n" " popl	%%fs:1+1f			\n" " movw	%%cs,%%fs:3+1f			\n" " pushl	$1f				\n" " pushw %%fs				\n" " pushw	%0				\n" " lretw					\n" ".section .cross_text2extra,\"ax\"	\n" "1:					\n" " ljmpw $0,$0				\n" ".previous # .cross_extra2text		\n" : : "p" (putstr));
  }

static void __attribute__ ((section (".cross_extra2text")))
test_intersegment_call (const char *param)
  {
  extraseg_puts (param);
  }

static void __attribute__ ((section (".cross_text2extra")))
codeseg_test_intersegment_call (const char *param)
  {
  asm volatile (" \n " " movw	2+extraseg_adr,%%fs		\n" " popl	%%fs:1+1f			\n" " movw	%%cs,%%fs:3+1f			\n" " pushl	$1f				\n" " pushw	%%fs				\n" " pushw	%0				\n" " lretw					\n" ".section .cross_extra2text,\"ax\"	\n" "1:					\n" " ljmpw $0,$0				\n" ".previous # .cross_text2extra		\n" : : "p" (test_intersegment_call));
  }

static void testjump (void)
  {
  }

static void timertest (void)
  {
  }

static void recorder_test (unsigned param)
  {
  }

static unsigned gethexa (void)
  {
  return 0;
  }

static unsigned tester_probe_mode (unsigned first, unsigned last)
  {
  return 0;
  }


static unsigned menu (struct registers *regs)
  {
  unsigned start, stop, number, partition, currmode;
  unsigned char key;
  volatile int divide_per_0 = 0;

  for (;;) {
      key = UI.getkey() & 0x00FF;


      switch (key) {
        case '1':
          printf ("Found %u valid disks:\r\n\r\n", DI.nbdisk);
          for (number = 0; number < DI.nbdisk; number ++) {
              printf ("\r\nPress a key to continue...");
              UI.getkey();
              }
          continue;
        case '2':
          do {
              printf ("\r\nType the disk you want to boot from (0..%u),"
                        " or %u to \"fail\" this boot: ",
                        DI.nbdisk - 1, DI.nbdisk);
              number = gethexa();
              } while (number != (unsigned) -1 && number > DI.nbdisk);
          if (number == (unsigned) -1)
              continue;
          if (number == DI.nbdisk) {
              printf ("\r\nInvoking the possible \"failed\" boot handler...\r\n");
              _BIOS_failedboot();
              continue;
              }
          printf ("\r\n\r\nDisk description:\r\n");
          for (;;) {
              unsigned i;

              printf ("\r\nType the OS<number> you want to boot from, or 0 for MBR: ");
              if ((partition = gethexa()) == (unsigned) -1)
                  break;
              if (partition == 0) {
                  partition = DI.param[number].nbpartition;
                  break;
                  }
              for (i = 0; i < DI.param[number].nbpartition; i++)
                  if (partition == DI.param[number].partition[i].OSnumber) {
                      partition = i;
                      break;
                      }
              if (i != DI.param[number].nbpartition)
                  break;
              printf (" NOT FOUND!\r\n");
              }
          if (partition == (unsigned) -1)
              continue;
          if (partition != DI.param[number].nbpartition) {
              start = DI.param[number].partition[partition].start;
              printf ("\r\n\r\nPartition type 0x%X\r\n\r\n",
                        DI.param[number].partition[partition].type);
              }
            else {
              start = 0;
              printf ("\r\n\r\nBooting from MBR (sector 0)\r\n\r\n");
              }

          if (copy_boot1param_serialconf.port < 0)
              VGA_init();

          if ( DI.param[number].access == bios_chs
              || DI.param[number].access == ebios_lba) {
              printf ("setting edx to 0x%X.\r\n", DI.param[number].disknb);
              regs->edx = DI.param[number].disknb;
              }

          restore_vectors ();

          printf ("reading one sector at lba=%d on disk 0x%X and jumping...\r\n\r\n",
                        start, DI.param[number]);
          return codeseg_DISK_readsector (&DI.param[number], start, 1, 0x00007C00);
        case 'A': case 'a':
          divide_per_0 = 100 / divide_per_0;
          continue;
        case 'B': case 'b':
          asm volatile (" ud2 ");
          continue;
        case 'C': case 'c':
          test_bound_stack ((void*)&test_bound_stack);
          continue;
        case 'D': case 'd':
          test_bound_data (0);
          continue;
        case 'E': case 'e': {
          unsigned dummy = 0x10004;
          asm volatile (" movl %%ds:(%%eax),%%eax " : "+a" (dummy));
          }
          continue;
        case 'F': case 'f': {
          unsigned dummy = 0x10004;
          asm volatile (" movl %%ss:(%%eax),%%eax " : "+a" (dummy));
          }
          continue;
        case 'L': case 'l':
          codeseg_test_intersegment_call ("extraseg works\r\n");
          testjump ();
          continue;
        case 'T': case 't':
          timertest();
          break;
        case '.':
          if (door_open_gs()) {
              if (segment_door(0) != 0)
                  printf ("closing doors failed\r\n");
                else
                  printf ("closing doors OK\r\n");
              }
            else {
              if (segment_door(1) != 0)
                  printf ("opening doors failed\r\n");
                else
                  printf ("opening doors OK\r\n");
              }
          continue;
        case '/':

          restore_vectors ();

          return 1;
        case '*':

          restore_vectors ();

          return 0;
        case '-':
          printf ("\r\nPress a key to continue...");
          UI.getkey();
          continue;
        case '5' :
          if (copy_boot1param_serialconf.port < 0) {

              unsigned mode = 0, tmp;
              if (!((UI.parameter.nbcol != 0) && (UI.parameter.linelength == 0))) {
                  if (VGA_init() != 0) {
                      printf ("no VGA card found\r\n");
                      continue;
                      }
                  mode = UI.function.getmode () & 0x7FFF;
                  }
                else
                  printf ("Already in VGA, active mode 0x%X\r\n",
                          UI.function.getmode () & 0x7FFF);
              printf ("\r\nVGA card present, modes: ");
              listmode (&UI);
              printf ("switch to VGA mode (from previous list): 0x");
              number = gethexa();
              if (number != (unsigned) -1) {
                  if ((tmp = UI.function.setmode (number)) != 0)
                      printf ("\r\nError 0x%X switching to mode 0x%X\r\n\r\n",
                                tmp, number);
                  }
                else {
                  if (mode != 0)
                      if ((tmp = UI.function.setmode (mode)) != 0)
                   printf ("\r\nError 0x%X initialising to mode 0x%X\r\n\r\n",
                            tmp, number);
                  }



              }
            else {


              printf (" Terminal [");
              if (!(UI.parameter.nbcol != 0) && SERIAL_init() != 0) {
                  printf ("Switch to SERIAL failed!]\r\n");
                  continue;
                  }
              printf ("%s] ", UI.info.serial.terminalname);
              switch (UI.monitor) {
                case 0: printf ("Unknown"); break;
                case 1: printf ("B&W"); break;
                case 2: printf ("Monochrome"); break;
                case 3: printf ("Color"); break;
                }
              printf (" with valid modes: 0..%u", UI.info.serial.max_mode);
              printf ("\r\nswitch to SERIAL mode (from previous list): 0x");
              number = gethexa();
              if (number == (unsigned) -1)
                  printf ("\r\nStaying in current mode, at your own risks,\r\n"
                            "  Colors and attributes NOT initialised.\r\n\r\n");
                else
                  UI.function.setmode (number);



              }
          continue;

        case '6' : {
          if (copy_boot1param_serialconf.port >= 0) {
              printf ("VESA on a serial line?\r\n\r\n");
              continue;
              }
          if (!((UI.parameter.nbcol != 0) && (UI.parameter.linelength != 0))) {
              if (VESA_init() != 0) {
                  printf ("Switch to VESA failed!\r\n");
                  continue;
                  }
              UI.function.clearscreen();
              }
            else
              printf ("Already in VESA, active mode 0x%X\r\n",
                        UI.function.getmode () & 0x7FFF);

          printf ("%s card, VESA version %u.%u.",
                        UI.info.vesa.cardname,
                        UI.info.vesa.version >> 8,
                        UI.info.vesa.version & 0xFF);
          if (tester_probe_mode (0x100, 0x17F) == 0) {
              printf ("\r\n Argggg - none of the modes are valid...\r\n"
                    "\r\n\007Press a key to continue...");
              UI.getkey();
              UI_init (0);
              continue;
              }

          do {

              if ((UI.info.vesa.version >> 8) >= 2)
                  printf ("\r\n (add 0x4000 for linear frambuffer mode)");

              printf ("\r\nswitch to VESA mode (from previous list): 0x");
              number = gethexa();
              if (((UI.parameter.nbcol != 0) && (UI.parameter.linelength != 0)) && number == (unsigned) -1)
                  break;
              } while ( (number & ~0x4000) < 0x100
                        || (number & ~0x4000) > 0x17F);
          printf ("\r\n\r\n");
          if (number == (unsigned) -1)
              continue;
          if (UI.function.setmode (number) != 0)
              printf ("Setmode failed!\r\n");
          }
          continue;



        case '=': {
          char test[20] = { 0 };

          printf ("strlen (\"%s\") = %u.\r\n", test, strlen(test));

          printf ("strcpy (\"%s\", \"1234567XX\") = ", test);
          strcpy (test, "1234567XX");
          printf ("\"%s\".\r\n", test);

          printf ("strcpy (\"%s\", \"1234567\") = ", test);
          strcpy (test, "1234567");
          printf ("\"%s\".\r\n", test);

          printf ("strlen (\"%s\") = %u.\r\n", test, strlen(test));

          printf ("strncpy (\"%s\", \"123456789\", 6) = ", test);
          strncpy (test, "123456790", 6);
          printf ("\"%s\".\r\n", test);

          printf ("strncmp (\"%s\", \"123450\", 5) = %d.\r\n",
                        test, strncmp (test, "123450", 5));
          printf ("strncmp (\"%s\", \"123450\", 6) = %d.\r\n",
                        test, strncmp (test, "123450", 6));
          printf ("strncmp (\"%s\", \"123457\", 6) = %d.\r\n",
                        test, strncmp (test, "123457", 6));

          printf ("strcmp (\"1234\", \"1234\") = %d\r\n",
                        strcmp ("1234", "1234"));
          printf ("strcmp (\"1234\", \"123456\") = %d\r\n",
                        strcmp ("1234", "123456"));
          printf ("strcmp (\"123456\", \"1234\") = %d\r\n",
                        strcmp ("123456", "1234"));
          printf ("strcmp (\"aaaab\", \"aaaac\") = %d\r\n",
        strcmp ("aaaab", "aaaac"));
          printf ("stricmp (\"aAaab\", \"aaaab\") = %d\r\n",
        stricmp ("aAaab", "aaaab"));
          printf ("stricmp (\"aAaab\", \"aaaac\") = %d\r\n",
        stricmp ("aAaab", "aaaac"));

          printf ("strcat (\"%s\", \"CC\") = ", test);
          strcat (test, "CC");
          printf ("\"%s\".\r\n", test);


          strcpy (test, "-------");
          printf ("\r\nmemset (\"%s\" + 1, 'Y', 3) = ", test);
          memset (test + 1, 'Y', 3);
          printf ("\"%s\".\r\n", test);

          printf ("memcpy (\"%s\" + 1, \"XX\", 2) = ", test);
          memcpy (test + 1, "XX", 2);
          printf ("\"%s\".\r\n", test);

          printf ("\r\nPress a key to continue...");
          UI.getkey();
          }
          break;

        case '3': case '4': case '7':
        case '8': case '9': case ',': case '+':
        case 'G': case 'H': case 'I': case 'J': case 'K':
        case 'g': case 'h': case 'i': case 'j': case 'k':

          break;
        default:
          continue;
        }

      if (!(UI.parameter.nbcol != 0)) {
          printf (" Initialise the interface first!\r\n\r\n");
          continue;
          }


      switch (key) {
        case '3':

          if (copy_boot1param_serialconf.port < 0) {

              if (((UI.parameter.nbcol != 0) && (UI.parameter.linelength != 0)))
                  UI.function.putstr (


                        " It is safe to probe VESA modes,    \r\n"
                        "from 0x100 to 0x17F.                \r\n"
                        );
                else

                  UI.function.putstr (


                        " It is quite safe to probe video modes  \r\n"
                        "up to 0x13, but you can probe up to 7F. \r\n"
                        " You can turn OFF your monitor for these\r\n"
                        "tests, a beep will be emitted at end.   \r\n"
                        " This can take few minutes on slow PC,  \r\n"
                        "but if CAPS LOCK led is no more working,\r\n"
                        "your VIDEO BIOS is seriously buggy...   \r\n"
                        " Then, just reboot your PC, the faulty  \r\n"
                        "mode will never be tryed again.         \r\n"
                        "As usual, TRY AT YOUR OWN RISKS !\r\n"
                        "---------------------------------\r\n"
                        );
              }
            else {
              UI.function.putstr (
                        " If you have a really VT420 compatible  \r\n"
                        "display, you can probe up to 5, else    \r\n"
                        "limit the probe from 0 to 1. If you have\r\n"
                        "a non VT100 compatible terminal, I am   \r\n"
                        "really sorry!                           \r\n"
                        );
              }

          do {
              printf ("\r\nFirst mode to probe (ESC to abort, <= 17F): 0x");
              number = gethexa();
              if (number == (unsigned) -1)
                  break;
              } while (number > 0x17F);
          if (number == (unsigned) -1)
              break;
          start = number;
          do {
              printf ("\r\nLast mode to probe (ESC to abort, >= 0x%X): 0x",
                        start);
              number = gethexa();
              if (number == (unsigned) -1)
                  break;
              } while (number < start);
          if (number == (unsigned) -1)
              break;
          stop = number;
          number = tester_probe_mode (start, stop);
          if (((UI.parameter.nbcol != 0) && (UI.parameter.linelength == 0))) {
              void VGA_VESA_setup_color(void);
              unsigned cpt;


              VGA_VESA_setup_color ();
              for (cpt = number + 2; cpt < UI.parameter.nbrow; cpt++)
                   printf ("\r\n");
              UI.function.setcursor (number + 2, 0);
              }
          if (number == 0)
              printf ("\r\n No valid mode found!");
          printf ("\r\n\007Press a key to continue...");
          UI.getkey();
          break;
        case '4':
          UI.function.clearscreen();
          break;
        case '7': {
          unsigned y, yend;
          unsigned char row, col;
          signed x;

          if (!UI.parameter.isgraphic)
              break;
          UI.function.getcursor (&row, &col);
          yend = (row - 1) * (UI.parameter.charheigh? UI.parameter.charheigh : 8);
          for (y = 0; y < yend; y++) {
              for (x = (UI.parameter.nbcol - 1) * UI.parameter.charwidth - 1;
                   --x >= 0;) {
                  coord xy = {x: x, y: y}, xydest = xy;

                  xydest.x += UI.parameter.charwidth;
                  UI.function.setpixel (xydest, UI.function.getpixel (xy));
                  }
              for (x = 0; x < UI.parameter.charwidth; x++) {
                  coord xy = {x: x, y: y};
                  UI.function.setpixel (xy, UI.bgcolor);
                  }
              }
          }
          break;
        case '8': {
          unsigned short x, y, xstart, tmp;
          unsigned char saved_row, saved_col;
          unsigned long long rdtsc_start;
          unsigned total_rdtsc, nbtick, timeout;
          unsigned total_rdtsc_clearscreen, total_rdtsc_scrolling;
          unsigned calibrate_rdtsc;
          unsigned char ioval;

          setTFflagCounter (0);
          setTFflag();
          UI.function.clearscreen();
          clearTFflag();

          UI.function.putstr ("\r\n\r\n\r\n\r\n\r\n\r\n"
                " Will use assembly instruction 'rdtsc',\r\n"
                "   I hope you have it (i.e. at least Pentium) !\r\n");

          disable_interrupt();
          rdtsc_start = rdtsc();
          UI.function.clearscreen();
          total_rdtsc = rdtsc() - rdtsc_start;
          enable_interrupt();
          total_rdtsc_clearscreen = total_rdtsc;

          UI.function.putstr ("\r\n\r\n"
  "   Got clearscreen result, now measuring scrolling and shifting\r\n\r\n"
  "  Number of instruction is excluding time spend in interrupts,\r\n"
  "  so is only really valid in VESA2 (linear framebuffer) modes,\r\n"
  "  or VESA1 when the positionning _function_ is used (curently ");


          if (UI.parameter.winsize >= 0x100000)
              printf ("VESA2).\r\n\r\n");
            else if (UI.parameter.addrpositionfarfct != 0)
              printf ("true).\r\n\r\n");
            else

              printf ("false).\r\n\r\n");







          tmp = getTFflagCounter();
          printf ("  clear screen: %U instructions in %U cycles\r\n"
                  "     i.e. an average of %u cycles / instructions\r\n",
                  tmp, total_rdtsc, total_rdtsc / tmp);
          UI.function.getcursor (&saved_row, &saved_col);

          setTFflagCounter (0);
          UI.function.setcursor (UI.parameter.nbrow-1, 0);
          setTFflag();
          printf ("\r\n");
          clearTFflag();

          UI.function.setcursor (UI.parameter.nbrow-1, 0);
          disable_interrupt();
          rdtsc_start = rdtsc();
          printf ("\r\n");
          total_rdtsc_scrolling = rdtsc() - rdtsc_start;
          enable_interrupt();

          UI.function.setcursor (saved_row - 2, 0);
          tmp = getTFflagCounter();
          printf ("  scrolling: %U instructions in %U cycles\r\n"
                  "     i.e. an average of %u cycles / instructions\r\n",
          tmp, total_rdtsc_scrolling, total_rdtsc_scrolling / tmp);

          xstart = (UI.parameter.nbcol - 1) * UI.parameter.charwidth - 1;

          setTFflagCounter (0);
          setTFflag();
          for (y = 0; y < UI.parameter.charheigh; y++) {
              for (x = xstart; x > 0;) {
                  coord xy = {x: --x, y: y},
                        xydest = {x: x + UI.parameter.charwidth, y: y};
                  UI.function.setpixel (xydest, UI.function.getpixel (xy));
                  }
              }
          clearTFflag();

          disable_interrupt();
          rdtsc_start = rdtsc();
          for (y = 0; y < UI.parameter.charheigh; y++) {
              for (x = xstart; x > 0;) {
                  coord xy = {x: --x, y: y},
                        xydest = {x: x + UI.parameter.charwidth, y: y};
                  UI.function.setpixel (xydest, UI.function.getpixel (xy));
                  }
              }
          total_rdtsc = rdtsc() - rdtsc_start;
          enable_interrupt();

          tmp = getTFflagCounter();
          printf ("  shifting: %U instructions in %U cycles\r\n"
                  "     i.e. an average of %u cycles / instructions\r\n\r\n",
          tmp, total_rdtsc, total_rdtsc / tmp);

          nbtick = _BIOS_nbtick();
          printf ("Calibrating rtdsc: "




                 );
          while (_BIOS_nbtick() == nbtick) ;
          rdtsc_start = rdtsc();
          nbtick += 10;
          while (_BIOS_nbtick() <= nbtick) ;



          { unsigned long rem, div = 55;

          asm ("" : : : "eax", "edx" );

          calibrate_rdtsc = ull_div_ul ((rdtsc() - rdtsc_start) * (1000 / 10),
                                        div, &rem);
          }

          printf ("%U ticks/sec\r\n", calibrate_rdtsc);


          {
          unsigned size = (-1 + my_ffs (UI.parameter.nbcolor))
                          * UI.parameter.width
                          * UI.parameter.heigh / 8;

          printf ("Video memory: %U bytes, "
                  "bandwidth: write= %u Mb/s, read= %u Mb/s.\r\n",
                  size,
                  calibrate_rdtsc / total_rdtsc_clearscreen
                                  * size / 1024 / 1024,
                  calibrate_rdtsc / (total_rdtsc_scrolling
                                     - total_rdtsc_clearscreen)
                                  * size / 1024 / 1024
                  );
          }

          printf ("Checking vertical refresh bit: ");
          timeout = 100000;
          ioval = inb (0x3DA) & 0x08;
          while (--timeout && ioval == (inb (0x3DA) & 0x08)) ;
          if (!timeout) {
              printf ("Error\r\n");
              break;
              }
          ioval = inb (0x3DA) & 0x08;
          while (ioval == (inb (0x3DA) & 0x08)) ;
          rdtsc_start = rdtsc();
          while (ioval != (inb (0x3DA) & 0x08)) ;
          while (ioval == (inb (0x3DA) & 0x08)) ;
          total_rdtsc = rdtsc() - rdtsc_start;

          printf ("OK, done in %U cycles, refresh = %u Hz\r\n",
                total_rdtsc, (calibrate_rdtsc+total_rdtsc/2)/total_rdtsc);

          printf ("Checking horizontal refresh bit: ");
          timeout = 100000;
          ioval = inb (0x3DA) & 0x01;
          while (--timeout && ioval == (inb (0x3DA) & 0x01)) ;
          if (!timeout) {
              printf ("Error\r\n");
              break;
              }
          ioval = inb (0x3DA) & 0x01;
          while (ioval == (inb (0x3DA) & 0x01)) ;
          rdtsc_start = rdtsc();
          while (ioval != (inb (0x3DA) & 0x01)) ;
          while (ioval == (inb (0x3DA) & 0x01)) ;
          total_rdtsc = rdtsc() - rdtsc_start;

          printf ("OK, done in %U cycles, Hfreq = %u KHz\r\n\r\n",
                total_rdtsc, (calibrate_rdtsc+total_rdtsc/2)/total_rdtsc
                                 / 1000);
          printf ("\r\nPress a key to continue...");
          UI.getkey();
          }
          break;
        case '9': {
          unsigned size, cpt;

          for (cpt = 0; cpt < 16; cpt++)
              for (size = 0; size < 20; size++) {
                  coord xy = {x: 40 - size, y: 3 + size + cpt};
                  UI.function.plotHline (xy, 40 + size - 1, UI.stdcolor[cpt]);
                  }
          for (cpt = 0; cpt < 16; cpt++)
              for (size = 0; size < 20; size++) {
                  coord xy = {x: 82 - size + cpt, y: 3 + size + cpt};
                  UI.function.plotHline (xy, 82 + size + cpt - 1,
                                         UI.stdcolor[cpt]);
                  }
          for (size = 0; size < 40; size++) {
              coord xy = {x: 99 - size, y: 80 + size };
              UI.function.plotHline (xy, 99 + size - 1, UI.stdcolor[magenta]);
              }
          printf ("\r\nPress a key to continue...");
          UI.getkey();
          }
          break;
        case '+':
        case ',':
          printf ("Current mode: ");
          currmode = UI.function.getmode () & ~0x8000;
          if (currmode & 0x4000)
              printf ("0x%X (linear)\r\n", currmode & ~0x4000);
            else
              printf ("0x%X\r\n", currmode);
          if (!((UI.parameter.nbcol != 0) && (UI.parameter.linelength != 0))) {
              if (copy_boot1param_serialconf.port >= 0)
                  printf ("SERIAL");
                else
                  printf ("VGA");
              }
            else
              printf ("VESA");
          printf (" mode selected (ESC to abort");

          if ((UI.info.vesa.version >> 8) >= 2 && ((UI.parameter.nbcol != 0) && (UI.parameter.linelength != 0)))
              printf (", add 0x4000 for linear mode");

          printf ("): 0x");
          if ((number = gethexa()) != (unsigned) -1) {
              unsigned tmp;
              if ((tmp = UI.function.setmode (number)) != 0) {
                  if (tmp > 2 && tmp < 0x100)
                      UI.function.setmode (currmode);
                  printf ("\r\nError 0x%X: video mode switch failed\r\n\r\n",
                                 tmp);
                  }
                else {
                  printf ("\r\nPress return to keep that mode");
                  if ((UI.getkey() & 0x00FF) != '\r')
                      UI.function.setmode (currmode);
                  }
              }
          break;
        case 'G': case 'g': {
          unsigned short i;
          coord xy;
          unsigned start_tick, total_tick;
          unsigned char thekey;

          if (!UI.parameter.isgraphic) {
              printf ("\r 'G' is just displaying the full screen\r\n"
                      " with the 16 colors in graphic modes.\r\n\r\n");
              break;
              }

          for (i = 0; i < (sizeof (UI.stdcolor) / sizeof (UI.stdcolor[0])); i++) {
              start_tick = _BIOS_nbtick();
              for (xy.y = 0; xy.y < UI.parameter.heigh; xy.y++)
                  for (xy.x = 0; xy.x < UI.parameter.width; xy.x++)
                      UI.function.setpixel (xy, UI.stdcolor[i]);
              total_tick = _BIOS_nbtick() - start_tick;

              UI.function.setcursor (0, 0);
              printf ("It took %u ticks. "
                      "Press a key to continue, ESC to abort", total_tick);
              thekey = UI.getkey();
              if (thekey == '\033' || thekey == 0 || thekey == '\003')
                  break;
              }
          }
          break;
        case 'H':
        case 'h':
          recorder_test (0);
          break;
        case 'I':
        case 'i':
          recorder_test (1);
          break;
        case 'J':
        case 'j':
          recorder_test (2);
          break;
        case 'K':
        case 'k':
          recorder_test (3);
          break;
        }
      }
  }


-------------------
>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-prs mailing list