system.pas_(re)

Fri, 20 Jun 1997 15:38:00 +0200



Peter Gerwinski wrote:

> What about `__BORLAND_PASCAL__' and `__DELPHI__' (and `__EXTENDED_PASCAL__'
> and `__STANDARD_PASCAL__' etc. which are of course useless because these
> dialects don't allow conditional defines anyway;-)?

Sounds good! :-)

> Everybody, PLEASE check what GPC can already do and what it cannot BEFORE
> you post to this list.  You are confusing possible GPC newcomers!  ;-)

Sorry for that! (When I wrote the mail, I was at university, and of course,
they haven't installed gpc there...)-:

> > Perhaps (additionally) a separate switch for those who want to use
> > functions as procedures, but without the "risks" implied by "{$X+}"
> > in other aspects? I guess, most of my units would use such a switch.
>
> Ignoring a function's return value *is* a risky thing, because it
> switches off an error-checking rule which is important for teaching.
> Programmers who want to use this feature usually (should;-) know what
> they are doing, and won't be hit by the other "risky" things.  For
> instance:  A beginner might unintentionally increment a pointer instead
> of the value pointed to.  An expert probably won't - he produces much
> uglier bugs.

No, when I want to produce ugly bugs, I write in C or Asm -- it's so much
easier there... ;-)

I'd still feel better with a separate switch because I try to avoid pointer
arithmetic and such things in all but low level or very time critical code,
but I usually have to ignore some function results. (Perhaps with function
overloading, this can be solved cleanly -- could it be possible then to have
a function and a procedure with the same parameters???)

> > - Is calling the Dos interrupt like I did it ok, or is there a better way
> >   (perhaps some DPMI calls
>
> Praxis has shown for me that interrupts which don't pass pointers work
> without any DPMI magic.  But take care of clobbered registers!

I declared all eax, ebx, ecx, edx, esi and edi as clobbered. Do I need more?
(ebp? What about segment registers, anyway?)

> >   -- perhaps even without any asm, that would be better).
>
> No.  This would be *very* system-dependent, so it should not be a GPC
> built-in.

No, not built-in of course! I thought of the __dpmi* functions declared in
dpmi.h (at least with DJGPP). I had hoped someone had already figured out
how to use them in gpc... -- So I tried it myself, it seems to work on my
DJGPP (code below). Could someone please check if the code "looks" ok, and
if it works on an EMX system?

BTW: Chief, I think your version of __dpmi_regs in dpmi.pas (v1.00) has a
little mistake, because a "union" in C is a variant record in Pascal.

I think I found a bug with variant records, namely that gpc allows
duplicate identifiers in different "cases". I think the following program
should either fail to compile (what I'd expect), or write "MaxCard"-1 (but
that would be quite difficult to do in general). It does write -1.

var
  x:record
    case d:integer of
      1:(a:cardinal);
      2:(a:integer)
    end;

begin
  x.d:=2;
  x.a:=-1;
  x.d:=1;
  writeln(x.a)
end.

> > Would it seem reasonable (and feasible) to propagate defines
> > (either all of them, or only those that are specially marked) through
> > .gpi files?
>
> No.  Defines are C.  We do Pascal.

True. Ok, for now we can help with "-Drandom=RandReal" on the command line,
and later we'll make an overloaded function out of it... :-)

UNIT Rand;

INTERFACE

TYPE
  Card8=Byte;
  Card16=ShortWord;
  Card32=Cardinal;
  Card64=LongWord;
  Int32=Integer;

VAR RandSeed:Int32 VALUE 0;

FUNCTION Random(Range:Card16):Card16;
FUNCTION RandReal:Real;
PROCEDURE Randomize;

IMPLEMENTATION

{$W-,R-,W+}
PROCEDURE NextRand;
BEGIN
  RandSeed:=$8088405*RandSeed+1
END;

FUNCTION Random(Range:Card16):Card16;
BEGIN
  NextRand;
  Random:=(Card32(RandSeed)*Card64(Range)) DIV $100000000
END;

FUNCTION RandReal:Real;
BEGIN
  NextRand;
  RandReal:=RandSeed/4294967296.0+0.5
END;

{$IFDEF __DJGPP__}{$DEFINE DOS}{$ENDIF}
{$IFDEF __EMX__}{$DEFINE DOS}{$ENDIF}

{$IFDEF DOS}
TYPE
  PDPMIRegs=^TDPMIRegs;
  TDPMIRegs=RECORD
    CASE (d,x,h) OF
      d:(edi,esi,ebp,res,ebx,edx,ecx,eax:Card32);
      x:(di,di_hi,si,si_hi,bp,bp_hi,res_lo,res_hi,bx,bx_hi,dx,dx_hi,
         cx,cx_hi,ax,ax_hi,flags,es,ds,fs,gs,ip,cs,sp,ss:Card16);
      h:(edi_b,esi_b,ebp_b,res_b:ARRAY[0..3] OF Card8;
         bl,bh,ebx_b2,ebx_b3,
         dl,dh,edx_b2,edx_b3,
         cl,ch,ecx_b2,ecx_b3,
         al,ah,eax_b2,eax_b3:Card8)
    END;

{$W-}
FUNCTION __DPMI_Simulate_Real_Mode_Interrupt(Vector:Integer;VAR Regs:TDPMIRegs):Integer; C;
{$W+}

PROCEDURE Randomize;
VAR
  RandSeedLoHi:PACKED RECORD Lo,Hi:Card16 END ABSOLUTE RandSeed;
  DPMIRegs:TDPMIRegs;
BEGIN
  DPMIRegs.ah:=$2C;
  {$X+}
  __DPMI_Simulate_Real_Mode_Interrupt($21,DPMIRegs);
  {$X-}
  RandSeedLoHi.Lo:=DPMIRegs.cx;
  RandSeedLoHi.Hi:=DPMIRegs.dx
END;

{$ELSE}
FUNCTION Rand:Integer; C;
PROCEDURE SRand(Seed:Cardinal); C;
FUNCTION GetPID:Integer; C;

PROCEDURE Randomize;
BEGIN
  SRand(GetPID);
  RandSeed:=Rand
END;
{$ENDIF}
END.
-- 
Frank Heckenbach, Erlangen, Germany
heckenb@mi.uni-erlangen.de
Turbo Pascal:   http://www.mi.uni-erlangen.de/~heckenb/programs.htm
Internet links: http://www.mi.uni-erlangen.de/~heckenb/links.htm


Frank Heckenbach (heckenb@mi.uni-erlangen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es