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.