Turo51 Inline Procedures
Pascal Compiler for 8051 Microcontrollers
Procedures (and functions) that are declared with the Inline directive are copied to the places where they are called. This has the effect that there is no actual procedure (or function) call, the code of the procedure is just copied to where the procedure is needed, this results in faster execution speed if the procedure or function is used a lot but but usually means also larger code size. You can override this behaviour with the $InlineCode directive. When set to Off (default is On) the compiler will generate normal calls to inline procedures.
Example:
{
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.
InlineChar.inc:
begin Result := Char (Byte (Ch) and $DF); end;
Compiled program above looks like this:
; Turbo51 version 0.1.3.10, Copyright 2000 - 2011 Igor Funa
$REGISTERBANK (0)
_CODE SEGMENT CODE
_DATA SEGMENT DATA
EXTRN IDATA (StackStart)
EXTRN CODE (sysRandomWord)
; {
; 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
RSEG _CONST
; InitialFlags = [fl0, fl4, fl5];
; TempFlags = [fl0, fl1, fl3];
;
; Var
; WatchdogClock: Boolean absolute P0.4;
WatchdogClock BIT P0.4
;
; GlobalFlags: TFlagsSet;
RSEG _DATA
GlobalFlags: DS 1
; DataRecord1,
; DataRecord2: TVariantRecord;
DataRecord1: DS 4
DataRecord2: DS 4
; Character: Char;
Character: DS 1
; B1, B2: Byte;
;
; Function UpcaseChar (Ch: Char): Char;
Ch: DS 1
RSEG _CODE
USING 0
UpcaseChar:
; {$I InlineChar.inc }
; begin
; Result := Char (Byte (Ch) and $DF);
MOV A, Ch
ANL A, #$DF
; end;
RET
;
; Function InlineUpcaseChar (Ch: Char): Char; Inline;
RSEG _DATA
Ch: DS 1
RSEG _CODE
InlineUpcaseChar:
; {$I InlineChar.inc }
; begin
; Result := Char (Byte (Ch) and $DF);
MOV A, Ch
ANL A, #$DF
; end;
RET
;
; Procedure RestartWatchdog; Inline; Assembler;
; Asm
; CPL WatchdogClock;
; end;
;
; Procedure Multiply (Var Factor: Byte);
RSEG _DATA
Factor: DS 1
RSEG _CODE
Multiply:
; begin
; Factor := Factor * 10;
MOV R0, Factor
MOV A, @R0
MOV B, #$0A
MUL AB
MOV @R0, A
; If Factor >= 100 then Factor := 0;
ADD A, #-100
JNC L_00C7
MOV @R0, #0
L_00C7:
; end;
RET
;
; Procedure InlineMultiply (Var Factor: Byte); Inline;
RSEG _DATA
Factor: DS 1
RSEG _CODE
InlineMultiply:
; begin
; Factor := Factor * 10;
MOV R0, Factor
MOV A, @R0
MOV B, #$0A
MUL AB
MOV @R0, A
; If Factor >= 100 then Factor := 0;
ADD A, #-100
JNC L_00D6
MOV @R0, #0
L_00D6:
; end;
RET
CSEG AT $0000
Example4:
;
; begin
MOV SP, #StackStart-1
; GlobalFlags := InitialFlags;
MOV GlobalFlags, #$31
;
; Include (GlobalFlags, fl4);
ORL GlobalFlags, #$10
; Exclude (GlobalFlags, fl5);
ANL GlobalFlags, #$DF
; Change (GlobalFlags, fl6);
XRL GlobalFlags, #$40
;
; RestartWatchdog;
; CPL WatchdogClock;
CPL P0.4
;
; DataRecord1.L := $12345678;
MOV DataRecord1, #$78
MOV DataRecord1+1, #$56
MOV DataRecord1+2, #$34
MOV DataRecord1+3, #$12
; With DataRecord2 do
; begin
; DataWord := DataRecord1.W0 + DataRecord1.W1;
MOV A, DataRecord1
ADD A, DataRecord1+2
MOV DataRecord2, A
MOV A, DataRecord1+1
ADDC A, DataRecord1+3
MOV DataRecord2+1, A
; LocalFlags := [3, 5, 6];
MOV DataRecord2+2, #$68
; Flags := GlobalFlags;
MOV DataRecord2+3, GlobalFlags
; end;
;
; RestartWatchdog;
; CPL WatchdogClock;
CPL P0.4
;
; Case fl6 in DataRecord2.Flags of
MOV A, DataRecord2+3
; True: DataRecord2.Flags := DataRecord2.Flags * TempFlags + [fl2, fl3];
JNB ACC.6, L_0040
MOV A, DataRecord2+3
ANL A, #$0B
ORL A, #$0C
MOV DataRecord2+3, A
SJMP L_0043
L_0040:
; else DataRecord2.Flags := TempFlags;
MOV DataRecord2+3, #$0B
L_0043:
; end;
;
; RestartWatchdog;
; CPL WatchdogClock;
CPL P0.4
;
; If 0 in DataRecord2.IndividualBits then With DataRecord2 do
MOV A, DataRecord2
JNB ACC.0, L_0053
; begin
; Include (IndividualBits, 4);
ORL DataRecord2, #$10
; Exclude (IndividualBits, 15);
ANL DataRecord2+1, #$7F
; Change (IndividualBits, 31);
XRL DataRecord2+3, #$80
; end;
L_0053:
;
; { Call to function UpcaseChar }
;
; Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
MOV R2, #LOW ($001A)
MOV R3, #HIGH ($001A)
LCALL sysRandomWord
MOV A, R2
ADD A, #LOW ($0061)
MOV Character, A
; DataRecord1.Ch0 := UpcaseChar (Character);
MOV Ch, Character
LCALL UpcaseChar
MOV DataRecord1, A
;
; { Inline function InlineUpcaseChar }
;
; Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
MOV R2, #LOW ($001A)
MOV R3, #HIGH ($001A)
LCALL sysRandomWord
MOV A, R2
ADD A, #LOW ($0061)
MOV Character, A
; DataRecord1.Ch1 := InlineUpcaseChar (Character);
MOV Ch, Character
; Result := Char (Byte (Ch) and $DF);
MOV A, Ch
ANL A, #$DF
MOV DataRecord1+1, A
;
; { Call to procedure Multiply }
;
; Multiply (DataRecord1.B1);
MOV Factor, #DataRecord1+1
LCALL Multiply
;
; { Inline procedure InlineMultiply }
;
; InlineMultiply (DataRecord1.B1);
MOV Factor, #DataRecord1+1
; Factor := Factor * 10;
MOV R0, Factor
MOV A, @R0
MOV B, #$0A
MUL AB
MOV @R0, A
; If Factor >= 100 then Factor := 0;
ADD A, #-100
JNC L_0093
MOV @R0, #0
L_0093:
;
; {$InlineCode Off }
;
; { Normal call to Inline function InlineUpcaseChar }
;
; Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
MOV R2, #LOW ($001A)
MOV R3, #HIGH ($001A)
LCALL sysRandomWord
MOV A, R2
ADD A, #LOW ($0061)
MOV Character, A
; DataRecord1.Ch1 := InlineUpcaseChar (Character);
MOV Ch, Character
LCALL InlineUpcaseChar
MOV DataRecord1+1, A
;
; { Normal call to Inline procedure InlineMultiply }
;
; InlineMultiply (DataRecord1.B1);
MOV Factor, #DataRecord1+1
LCALL InlineMultiply
; end.
L_00AD:
SJMP L_00AD
RSEG _CONST
END
