{
    This file is part of the Turbo51 code examples.
    Copyright (C) 2008 by Igor Funa

    http://turbo51.com/

    This file is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
}

Program Example4;

{ Usless program just to demonstrate sets and inline procedures/functions }

Type
  TFlag = (fl0, fl1, fl2, fl3, fl4, fl5, fl6);
  TFlagsSet = Set of TFlag;

  TVariantRecord = Record
                     Case Byte of
                       0: (L: LongInt);
                       1: (W0, W1: Word);
                       2: (B0, B1, B2, B3: Byte);
                       3: (DataWord: Word; LocalFlags: Set of 0..7; Flags: TFlagsSet);
                       4: (IndividualBits: Set of 0..31);
                       5: (Ch0, Ch1, Ch2, Ch3: Char);
                   end;

Const
   InitialFlags = [fl0, fl4, fl5];
   TempFlags    = [fl0, fl1, fl3];

Var
  WatchdogClock: Boolean absolute P0.4;

  GlobalFlags: TFlagsSet;
  DataRecord1,
  DataRecord2: TVariantRecord;
  Character: Char;
  B1, B2: Byte;

Function UpcaseChar (Ch: Char): Char;
{$I InlineChar.inc }

Function InlineUpcaseChar (Ch: Char): Char; Inline;
{$I InlineChar.inc }

Procedure RestartWatchdog; Inline; Assembler;
Asm
  CPL  WatchdogClock;
end;

Procedure Multiply (Var Factor: Byte);
begin
  Factor := Factor * 10;
  If Factor >= 100 then Factor := 0;
end;

Procedure InlineMultiply (Var Factor: Byte); Inline;
begin
  Factor := Factor * 10;
  If Factor >= 100 then Factor := 0;
end;

begin
  GlobalFlags := InitialFlags;

  Include (GlobalFlags, fl4);
  Exclude (GlobalFlags, fl5);
  Change  (GlobalFlags, fl6);

  RestartWatchdog;

  DataRecord1.L := $12345678;
  With DataRecord2 do
    begin
      DataWord   := DataRecord1.W0 + DataRecord1.W1;
      LocalFlags := [3, 5, 6];
      Flags      := GlobalFlags;
    end;

  RestartWatchdog;

  Case fl6 in DataRecord2.Flags of
    True: DataRecord2.Flags := DataRecord2.Flags * TempFlags + [fl2, fl3];
    else  DataRecord2.Flags := TempFlags;
  end;

  RestartWatchdog;

  If 0 in DataRecord2.IndividualBits then With DataRecord2 do
    begin
      Include (IndividualBits, 4);
      Exclude (IndividualBits, 15);
      Change  (IndividualBits, 31);
    end;

{ Call to function UpcaseChar }

  Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
  DataRecord1.Ch0 := UpcaseChar (Character);

{ Inline function InlineUpcaseChar }

  Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
  DataRecord1.Ch1 := InlineUpcaseChar (Character);

{ Call to procedure Multiply }

  Multiply (DataRecord1.B1);

{ Inline procedure InlineMultiply }

  InlineMultiply (DataRecord1.B1);

{$InlineCode Off }

{ Normal call to Inline function InlineUpcaseChar }

  Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
  DataRecord1.Ch1 := InlineUpcaseChar (Character);

{ Normal call to Inline procedure InlineMultiply }

  InlineMultiply (DataRecord1.B1);
end.