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