Mail Archives: djgpp/1999/10/19/06:39:41
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 -