[fpc-pascal]BIOS PnP function far call (go32v2)

Thomas Schatzl tom_at_work at gmx.at
Wed Sep 10 02:55:14 CEST 2003


[Note that I did a copy&paste from the list archives because the mail
address I am subscribed to this list isn't working properly atm. I switched
to another, but this means I couldn't reply to the original posting and so
message threading is broken. Sorry.]

Hi,

>under GO32V2 i want to call BIOS PnP function with entry point
>
>        db $FF,$1E; dw PnP_EntryPoint
>or
>        call DWord ptr [PnP_EntryPoint]
>
>but always i got error "SIGSEGV - segmentation violation".
>PnP_EntryPoint (type pointer) is normally somewhere in BIOS area at
>F000:xxxxh.
>
>In PnP specification i found this:
>
>  "If this function is called from protected mode the caller must
>  create a data segment descriptor using the 16-bit Protected Mode data
>  segment base address specified in the Plug and Play Installation Check
>  data structure, a limit of 64k, and the descriptor must be readable and
>  writable."
>
>But i don't know how can i do that
>-> "make a readable and writable data segment descriptor".

Probably the easiest way to accomplish that (at least worth a try) is using
a method provided by the DPMI server which allows you to call a real mode
procedure directly. The only problem is that the GO32 function does not
include this call, so you have to use a more complete DPMI interface I did
long ago (uploaded at http://members.yline.com/~tom_at_work/dpmidist.zip ,
for the example programs you may need another one of my units, called
MEMORY, grab a copy at
http://members.yline.com/~tom_at_work/memorydist.zip).
See the included documentation for dpmi_call_rm_procedure_with_retf_frame
and the dcall16.pas and call16.pas example programs which are included. They
show how to call a real mode procedure and pass real mode parameters (e.g.
buffer addresses) to those.

Btw, the DPMI zip also includes a good DPMI specification =) if you're
interested and/or have more detailed questions about it.

If you want to try the way described in the PnP description, have a look at
the dpmi_segment_to_descriptor() method which is exactly suited for this
purpose (again, see the docs for details). You simply have to provide a base
address and it returns you a selector to real mode memory with a limit of
64k. The short example program for this method is called vgasel.pas. (Note
that the go32 provides this call too, and there *should* be a similar
example program around*).

Then you probably have to pass this selector somehow to the PnP subsystem,
but don't ask me how...

* Eg. somewhere lost in the examples directory of the fpc distro. At least
there were in some 0.99.x distro... ;-)

>And the second problem is how can i make a pointer
>"PnP_EntryPoint" to this real memory area.

You can read/write this real mode data by first creating a
selector/descriptor to this memory area and use the seg_* methods.

Descriptor creation process:
- use dpmi_allocate_ldt_descriptors
- then set the base address/length of the descriptor
(dpmi_set_segment_base_address, dpmi_set_segment_limit)

The other mail already mentioned the names of the corresponding GO32
functions.

As usual there should be an example program around (both for the GO32 unit
and the DPMI units)

>Under real DOS with BP7 it is O.K.

As another reader already pointed out, FPC programs always runs in protected
mode, so it's quite common that such programs won't work (actually it'd be
quite surprising if they worked right away).

>Sorry, i know this is not really question to FPC, but maybe somebody
>could help me. The same problem i got with calling ASPI entry point.

I believe that the reasons/solutions are the same for both problems.

Note that as you may notice these units are older (never thought they'd be
of much use again), e.g. ~3 years, so there might be small problems when
compiling.

Hope this helps.

Regards,
  Thomas





More information about the fpc-pascal mailing list