delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/10/19/06:39:41

Date: Tue, 19 Oct 1999 10:21:01 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Gisle Vanem <giva AT bryggen DOT bgnett DOT no>
cc: djgpp AT delorie DOT com
Subject: Re: far call
In-Reply-To: <Pine.UW2.3.95.991018230952.12654A-100000@bryggen.bgnett.no>
Message-ID: <Pine.SUN.3.91.991019102028.12301K-100000@is>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Mon, 18 Oct 1999, Gisle Vanem wrote:

> I've used the procedure described in the FAQ and used in Allegro
> (dpmi.c and vesa.c), but it crashes at the "lcall (%%edi)" line.

Please always post the *exact* crash message printed by the program,
complete with the registers' dump and call frame traceback, after
running SYMIFY on it.  Otherwise, helping you efficiently requires
much more work.

Please also describe what OS did you use (DOS? Windows?) and how is
your machine setup as far as memory manager and DPMI server are
concerned.

> union bios32 {
>       struct {
>         unsigned long  signature;    /* "_32_" */
>         unsigned long  entry;        /* 32 bit physical address */
>         unsigned char  revision;     /* Revision level, 0 */
>         unsigned char  length;       /* Length in paragraphs should be 01 */
>         unsigned char  checksum;     /* All bytes must add up to zero */
>         unsigned char  reserved[5];  /* Must be zero */
>       } fields;
>       char chars[16];
>     };

If this struct is defined by the PCI standard, it probably should be
declared with __attribute__((packed)).  Better be safe than sorry.

>   __asm__ __volatile__ (
>            "lcall (%%edi)"
>            : "=a" (return_code), "=b" (address), "=c" (length), "=d" (entry)
>            : "0" (service), "1" (0), "D" (&bios32_api) );

"lcall _bios32_api" is simpler, I think (and you don't need to load it
into EDI in that case).

>     __dpmi_set_segment_base_address (selector, addr);
>     __dpmi_set_segment_limit (selector, 4096-1);
> 
>     bios32_api.offset32 = check.fields.entry;
>     bios32_api.selector = selector;

You have defined a special selector for the memory region, but didn't
adjust the offset accordingly.  You need to subtract addr from
check.fields.entry, to make it a segment-relative offset suitable to
use with your selector.  Otherwise, bios32_api.offset32 is way above
the 4K limit you've set up for bios32_api.selector.

- Raw text -


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