Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2002-05

Re: FPC & DJGPP & GraphiX

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jonas Maebe
to Peter Beisel: can anyone help? compiler: FPC 1.0.4 target: DOS / Go32V2 graphix: 4.00 In my pascal main…
Peter Beisel wrote 7 lines
In my pascal main module (written with FPC) I want to call functions from c-librarys (written with DJGPP). In Textmode all works fine. Also the usage of the graph unit is no problem. BUT: using GraphiX doesn't work. The program crashes with runtime error 216.

The reason is probably this: GraphiX changes the limit of the ds selector so that instead of just including the memory that has been allocated to the program, it also includes the linear frame buffer (which lies somewhere above 3.8GB most of the time). However, this limit is reset by the Dos extender every time the heap has to grow. Therefore, GraphiX hooks itself into the FPC heap manager so that it can adjust the limit of the ds selector everytime getmem is called. You can't do this for malloc etc from the C library, so you get a crash if malloc had to grow the heap.

The only solution I see is to manually add calls to the function that adjusts the ds selectors limit. You should be able to find this function in the GraphiX sources by searching for "SetMemoryManager".

Jonas

Reply by email

Peter Beisel

Hi all,
can anyone help?

compiler: FPC 1.0.4
target: DOS / Go32V2
graphix: 4.00

In my pascal main module (written with FPC) I want to call functions from c-librarys (written
with DJGPP). In Textmode all works fine. Also the usage of the graph unit is no problem.

BUT: using GraphiX doesn't work. The program crashes with runtime error 216.

After reducing the code now it seems clear that malloc/free called in a c-librarys function
and the usage of grahpix doesn't work together - but why??

Any hint will help, regards Peter.

The c-library looks like that:

  File Lib1.c:
    /* lib1.c */
    #include <lib1.h>
    #include <stdlib.h>
    void fmallfree( long int i)   /* we test malloc & free */
    {
      void *mp;
      mp = malloc( i);
      free( mp);
    }
  file lib1.h:
    /* lib1.h */
    void fmallfree( long int i);

Here are 2 variations of code of the main program (both do crash): A) calling fmallfree before opening graphix:
--------------------------------------------

    uses
      gxtext, gxType, graphix, crt;
    {$l lib1.o}
    {$linklib c}
    procedure fmallfree( i: longint); cdecl; external;
    var
      vgaFont : TFontVGA;
    begin
    // call external c-library function:
    fmallfree( 1000000);
    writeln( 'lib1 - fmallfree( 1000000) successfull called. Hit a key
to enter graphix.');
    readkey;
    // now entering graphix
    if InitGraphiX( ig_vesa, ig_lfb + ig_hwa) then
      begin
      if SetModeGraphiX( 800, 600, ig_col24) then
        begin
        vgaFont.loadFont;
        bar( 0,0,getMaxx,getmaxy, $FFFFFF);
        vgaFont.outText( 20,20, 'Testing GRAPHIX. Hit a key to
terminate',0);
        readkey;
        vgaFont.removeFont;
        graphix.initText;
        end;
      end;
    end.

This version crashes when calling the bar-function of graphix: Runtime Error 216
barlm24, line 703 of graphixm.ppi

B) calling fmallfree within graphix running
--------------------------------------------

    uses
      gxtext, gxType, graphix, crt;
    {$l lib1.o}
    {$linklib c}
    procedure fmallfree( i: longint); cdecl; external;
    var
      vgaFont : TFontVGA;
    begin
    // first entering graphix
    if InitGraphiX( ig_vesa, ig_lfb + ig_hwa) then
      begin
      if SetModeGraphiX( 800, 600, ig_col24) then
        begin
        vgaFont.loadFont;
        bar( 0,0,getMaxx,getmaxy, $FFFFFF);
        vgaFont.outText( 20,20, 'Testing GRAPHIX. Hit a key to call
fmallfree',0);
        readkey;
        // call external c-library function:
        fmallfree( 1000000);
        vgaFont.outText( 20,60, 'lib1 - fmallfree( 1000000) successfull
called. Hit a key to terminate.',0);
        readkey;
        vgaFont.removeFont;
        graphix.initText;
        end;
      end;
    end.

This version crashes when calling the outText-function of graphix after the call of fmallfree( 1000000):
Runtime Error 216
putpixel24, line 208 of .\lib\graphixl.ppi

Reply by email

Peter Beisel
to Jonas Maebe: The reason is probably this: GraphiX changes the limit of the ds selector so that instead…

Hi Jonas, Hi Michael,
thank you very much, this was the right hint.

I could change my program with a little wrapper around the library function call like this:

  procedure callFMallFree( i: longint);
  var
    old_ds_base, new_ds_base : dword;
  begin
  old_ds_base := get_segment_base_address( get_ds);   // go32
  set_segment_limit( get_ds, getDSlimit);             // go32
  fMallFree( i);                                      // that's the library
function
  new_ds_base := get_segment_base_address( get_ds);   // go32
  set_segment_limit( get_ds,-1);                      // just like Michael
does it in gxmem.pp
  adjustaddresses( old_ds_base, new_ds_base);         // function from
gxmem.pp
  end;

Now it works.

BUT:
1) it's a little different if the program starts in text mode and calls the library function before it changes to graphics mode. But I think I can handle this.

2) I found a bug in graphiX:
Try this little program:
  uses  graphix;
  var  p : pointer;
  begin
  // first we force the heap to grow
  getMem( p, 30000000);
  freemem(p, 30000000);
  // now we enter graphiX
  if InitGraphiX(ig_vesa,ig_lfb + ig_hwa) then
    begin
    if SetModeGraphiX( 800, 600, ig_col24) then
      begin
      // do some graphics
      graphix.initText;
      end;
    end;
  end.

This program crashes with runtime error 216 in line 6 when calling getmem! Explanation:
When using the unit GraphiX the usage of gxmem is included. In the initialisation part of the unit gxmem the heapError procedure is hooked by NewHeapError.
In NewHeapError adjustAddresses is called. AdjustAddresses points to AdjustAllAddresses (unit gxGo32v2). AdjustAllAddresses calls CurGraphix.adjustAddresses.

BUT at this time curGraphix isn't initialized! Because curGraphix will get initialized when entering GraphiX by calling initGraphix.

Regards Peter

Show quoted text 19 lines
The reason is probably this: GraphiX changes the limit of the ds selector so that instead of just including the memory that has been allocated to the program, it also includes the linear frame buffer (which lies somewhere above 3.8GB most of the time). However, this limit is reset by the Dos extender every time the heap has to grow. Therefore, GraphiX hooks itself into the FPC heap manager so that it can adjust the limit of the ds selector everytime getmem is called. You can't do this for malloc etc from the C library, so you get a crash if malloc had to grow the heap. The only solution I see is to manually add calls to the function that adjusts the ds selectors limit. You should be able to find this function in the GraphiX sources by searching for "SetMemoryManager". Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email