delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/01/31/13:32:45

Message-ID: <32F238AF.474F@rangenet.com>
Date: Fri, 31 Jan 1997 12:23:43 -0600
From: Dan Hedlund <markiv AT rangenet DOT com>
Reply-To: markiv AT rangenet DOT com
Organization: Range Net
MIME-Version: 1.0
To: Thomas Demmer <demmer AT LSTM DOT Ruhr-UNI-Bochum DOT De>, djgpp AT delorie DOT com
Subject: Re: Possible bug/misfeature in GCC
References: <32F1A438 DOT 5509 AT rangenet DOT com> <32F1DBDD DOT 2F1C AT LSTM DOT Ruhr-UNI-Bochum DOT De>

Thomas Demmer wrote:
> 
> Dan Hedlund wrote:
> >
> > The following lines compile wrong with the -O3 option.
> >
> > unsigned char inportb (int port)
> > {
> >   unsigned char c;
> >   asm ("inb     %%dx, %%al"
> >       : "=a" (c)
> >       : "d" (port));
> >   return c;
> > }
> >
> > void main (void)
> > {
> >   while (inportb (0));
> > }
> >
> 
> Try
> volatile unsigned inportb() or something like that...
> 
> > I've also had a few problems with the -O2 option, but they are more
> > difficult to reproduce.  The problem goes away if I use the -O0 option
> > or comment the portion of the code that uses inportb.  GCC also seems to
> > produce incorrect code when accessing the control registers (cr0 and
> > cr3).
> >
> 
> Hmm, that'll require a guru ;-)
> 
> --
> Ciao
> Tom
> 

I tried volatile, and static.  If I make inportb a inline function, it
also doesn't work with -O1 and -O2.

Here's the code that was cauding problems with -O2

void iodelay (void)
{
  asm ("jmp 1f
        1:");
}

void _8042_empty (void)
{
  iodelay ();

  char c;
  while ((c = inportb (0x64)) & 0x03)
  {
    iodelay ();
    if (c & 0x01)
    {
      inportb (0x60);
      iodelay ();
    }
  }

  iodelay ();
}

int checkA20 (void)
{
  int a, r;
  volatile int *l, *h;

  l = (int *) (0 - AbsoluteAddr);               // pointer to 0 mb
  h = (int *) (0x100000 - AbsoluteAddr);        // pointer to 1 mb

  a = *l;                                       // save old value

  *h = a ^ 0xffffffff;                          // change value at 1mb

  r = ((*l) != (*h));                           // compare

  *l = a;                                       // restore old value

  return r;
}

void enableA20 (void)
{
  _8042_empty ();
  outportb (0x64, 0xd1);
  _8042_empty ();
  outportb (0x60, 0xdf);
  _8042_empty ();

  while (!checkA20 ());
}

void _8042_disableA20 (void)
{
  _8042_empty ();
  outportb (0x64, 0xd1);
  _8042_empty ();
  outportb (0x60, 0xdd);
  _8042_empty ();

//while (checkA20 ());
// this doesn't work anytime.
}


-- 

*****      ***   **    **       Dan M. Hedlund
 ** **    *****  ***   **       <markiv AT rangenet DOT com>
 **  **  **   ** ****  **       http://www.rangenet.com/markiv
 **   ** **   ** ** ** **
 **   ** ******* **  ****
 **  **  **   ** **   ***
 ** **   **   ** **    **
*****    **   ** **    **

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019