Contributor: ALFONS HOOGERVORST
(*> I have now added the {$IFOPT G+} to most of my current sources, but I> would like default detection code in my libraries (often used TPUs)> Even if my TPUs are compiled in G- (which they always are, because> I update them with TPC from a batch file), but if my 'main' source> files are accidentally G+ I would like that detected by my library> code.
*)
{$X+}{<<< Need this and strings unit }
{===========================================================================
 Copyrighted by Alfons Hoogervorst 1994 AD.
 Well. Ok. It's dumped in the public domain.
 ==========================================================================}
program Test8086;
uses
 WinCrt, Strings;
const
 { My firstname expressed in bytes, I guess. Use same bytes if possible
 to overcome the byte ordering on PC's }
 SEARCHID = $A2A2A2A2;
 SEARCHBYTE = Byte(SEARCHID); { LoByte }
 PUSHINT = 2;
procedure CallInOne(int: Integer);
begin
 { So I return }
end;
procedure CheckThisOut;
begin
 asm
 jmp @Continue
 dd SEARCHID { Bytes we're looking for }
 @continue:
 end;
 { if G+: push 0x02
 else mov ax,02; push ax
 }
 CallInOne(PUSHINT)
end;
type
 TGOption = (Error, Goff, Gon);
function IsOptionGOn: TGOption;
type
 PDword = ^Longint;
var
 Opcodes: PChar;
 i: Integer; { Say 50 bytes }
begin
 IsOptionGOn := Error;
 OpCodes := PChar(@CheckThisOut);
 { Find our ID }
 for i := 0 to 49 do { search some 50 bytes, must be enough }
 begin
 if PDword(OpCodes)^ = SEARCHID then
 begin { Found our bytes }
 OpCodes := OpCodes + sizeof(Longint); { Next instruction }
 { Check if it's PUSH PUSHINT instruction }
 if (OpCodes^ = #6ドルA) and ((OpCodes+1)^ = Char(PUSHINT)) then
 IsOptionGOn := Gon
 else IsOptionGOn := Goff;
 exit
 end;
 OpCodes := OpCodes + 1 { Try next }
 end;
end;
begin
 WriteLn('I Call You Call Me? Ok!');
 case IsOptionGOn of
 Error:
 begin
 WriteLn('Error... Borland Pascal code generation changed dramatically');
 WriteLn('The world is collapsing, all programs have become
incompatible'); WriteLn('The Horror of It! Get me some assembler and I''ll
fix it!') end;
 Gon:
 begin
 WriteLn('''t Was On');
 end;
 Goff:
 begin
 WriteLn('''t Was Off');
 end;
 end;
end.
(*
What am I doing here? Just looking for a push instruction. If {$G} on
constants are pushed with an immediate push instruction. Sounds
dificult? Well, just forget it, implement these functions in a unit
and you have your long-awaited test function.
I have some notes on my own code. If you're using my check-80X86 function
NEVER do the following things:
*)
if (OptionGOn = Goff) then
begin
 WriteLn('This code is compiled with $G+');
 Halt(2) {<<<<< PROBLEMS!!! }
end;
(*
Why?
If $G has been enabled you'll get:
push 2
call far HALT
And (as you noted) an 808X does not accept this.
Instead use this:
*)
if (OptionGOn = GOn) then
begin
 WriteLn('Option $G enabled message');
 Halt(Integer(OptionGOn)) { Or pass a variable }
end;
(*
In plain words: after checking the G-state with my function, don't call a
function with constant parameters. Always pass variables/function-results as
parameters.
This is not "portable":
*)
const
 ERROR_GERROR = 2;
 ANOTHER_CONST = 3;
if { my test } then
begin
 IWantToExitRightNow(ERROR_GERROR, ANOTHER_CONST, 4, 6, 7);
end;
{ Instead try this: }
if { my test } then
begin
 IWantToExitRightNow(VarIndicatingError, VarForAnotherConst,
 FunctionCall4, FunctionCall6, VarContaining7)
end;
{
This is _only_ necessary in the "code" block immediately following my
function, not in your other code. By the way: I have written a unit for
detecting this $G-state. It's partly written in asm. This unit does not
require the "use" of other units.
}


AltStyle によって変換されたページ (->オリジナル) /