&2Syntax10.Scn.FntSyntax10i.Scn.Fnt/ IStampElemsAlloc23 Jul 973Syntax10b.Scn.Fnt =pVersionElemsAllocBeg#Syntax10.Scn.FntPowerMac Windows Windows95NTWindows95NTPowerMac#Syntax16.Scn.FntPowerMacWindows#Syntax16.Scn.FntWindowsWindows95NT Syntax16.Scn.FntpVersionElemsAllocEnd)Cp#Syntax10.Scn.FntPowerMac Windows Windows95NTWindows95NTPowerMac#Syntax10.Scn.FntSysWindows#Syntax10.Scn.FntKernelWindows95NT pp#Syntax10.Scn.FntPowerMac Windows Windows95NTWindows95NTPowerMac#Syntax10.Scn.Fnt((Time = RECORD high, low: LONGINT END;Windows#Syntax10.Scn.FntTime = LONGINT;Windows95NT (pd  p#Syntax10.Scn.FntPowerMac Windows Windows95NTWindows95NTPowerMaclSyntax10.Scn.Fnt8FoldElemsNew#Syntax10.Scn.FntZZ (* returns micro sec *) BEGIN MSecs (time); (* implementation dependent *) END GetTime; 8ParcElemsAlloc  ௶8#Syntax10.Scn.Fnt VAR i: INTEGER; BEGIN i := -1; INC(i); add[i] := 0BF21FFE4H; (* stmw R25, -28(R1) *) INC(i); add[i] := 09421FFA8H; (* stwu R1, -88(R1) *) INC(i); add[i] := 03BE10038H; (* addi R31, 56(R1) *) INC(i); add[i] := 03BA30000H; (* lr R29, R3 *) INC(i); add[i] := 03B650000H; (* lr R27, R5 *) INC(i); add[i] := 03B270000H; (* lr R25, R7 *) INC(i); add[i] := 0807D0004H; (* lwz R3, 4(R29) *) INC(i); add[i] := 0809B0004H; (* lwz R4, 4(R27) *) INC(i); add[i] := 080DD0000H; (* lwz R6, 0(R29) *) INC(i); add[i] := 080FB0000H; (* lwz R7, 0(R27) *) INC(i); add[i] := 07CA32215H; (* add. R5, R3, R4 *) INC(i); add[i] := 07D063814H; (* addc R8, R6, R7 *) INC(i); add[i] := 090B90004H; (* stw R5, 4(R25) *) INC(i); add[i] := 091190000H; (* stw R8, 0(R25) *) INC(i); add[i] := 080210000H; (* lwz R1, 0(R1) *) INC(i); add[i] := 0BB21FFE4H; (* lmw R25, -28(R1) *) INC(i); add[i] := 04FE00020H; (* bclr ALWAYS, CF0.LT *) adrProc := SYSTEM.ADR(Add); adrArr := SYSTEM.ADR(add[0]); SYSTEM.PUT(adrProc, adrArr); i := -1; INC(i); sub[i] := 0BF21FFE4H; (* stmw R25, -28(R1) *) INC(i); sub[i] := 09421FFA8H; (* stwu R1, -88(R1) *) INC(i); sub[i] := 03BE10038H; (* addi R31, 56(R1) *) INC(i); sub[i] := 03BA30000H; (* lr R29, R3 *) INC(i); sub[i] := 03B650000H; (* lr R27, R5 *) INC(i); sub[i] := 03B270000H; (* lr R25, R7 *) INC(i); sub[i] := 0807D0004H; (* lwz R3, 4(R29) *) INC(i); sub[i] := 0809B0004H; (* lwz R4, 4(R27) *) INC(i); sub[i] := 080DD0000H; (* lwz R6, 0(R29) *) INC(i); sub[i] := 080FB0000H; (* lwz R7, 0(R27) *) INC(i); sub[i] := 07CA41851H; (* sub. R5, R4, R3 *) INC(i); sub[i] := 07D073010H; (* subc R8, R7, R6 *) INC(i); sub[i] := 090B90004H; (* stw R5, 4(R25) *) INC(i); sub[i] := 091190000H; (* stw R8, 0(R25) *) INC(i); sub[i] := 080210000H; (* lwz R1, 0(R1) *) INC(i); sub[i] := 0BB21FFE4H; (* lmw R25, -28(R1) *) INC(i); sub[i] := 04FE00020H; (* bclr ALWAYS, CF0.LT *) adrProc := SYSTEM.ADR(Sub); adrArr := SYSTEM.ADR(sub[0]); SYSTEM.PUT(adrProc, adrArr); i := -1; INC(i); mul[i] := 0BF41FFE8H; (* stmw R26, -24(R1) *) INC(i); mul[i] := 09421FFB0H; (* stwu R1, -80(R1) *) INC(i); mul[i] := 03BE10038H; (* addi R31, 56(R1) *) INC(i); mul[i] := 03BA30000H; (* lr R29, R3 *) INC(i); mul[i] := 03B850000H; (* lr R28, R5 *) INC(i); mul[i] := 03B460000H; (* lr R26, R6 *) INC(i); mul[i] := 080BD0004H; (* lwz R5, 4(R29) *) INC(i); mul[i] := 07CC5E1D6H; (* mullw R6, R5, R28 *) INC(i); mul[i] := 090DA0004H; (* stw R6, 4(R26) *) INC(i); mul[i] := 07CC5E016H; (* mulhwu R6, R5, R28 *) INC(i); mul[i] := 080FD0000H; (* lwz R7, 0(R29) *) INC(i); mul[i] := 07D07E1D6H; (* mullw R8, R7, R28 *) INC(i); mul[i] := 07D083214H; (* add R8, R8, R6 *) INC(i); mul[i] := 0911A0000H; (* stw R8, 0(R26) *) INC(i); mul[i] := 080210000H; (* lwz R1, 0(R1) *) INC(i); mul[i] := 0BB41FFE8H; (* lmw R25, -24(R1) *) INC(i); mul[i] := 04FE00020H; (* bclr ALWAYS, CF0.LT *) adrProc := SYSTEM.ADR(Mul); adrArr := SYSTEM.ADR(mul[0]); SYSTEM.PUT(adrProc, adrArr); i := -1; INC(i); div[i] := 0BF81FFF0H; (* stmw R28, -16(R1) *) INC(i); div[i] := 09421FFB8H; (* stwu R1, -72(R1) *) INC(i); div[i] := 03BE10038H; (* addi R31, 56(R1) *) INC(i); div[i] := 03BA30000H; (* lr R29, R3 *) INC(i); div[i] := 03B850000H; (* lr R28, R5 *) INC(i); div[i] := 0813D0004H; (* lwz R9, 4(R29) *) INC(i); div[i] := 0815D0000H; (* lwz R10, 0(R29) *) INC(i); div[i] := 07D2003A6H; (* mtspr MQ, R9 *) INC(i); div[i] := 07C6AE296H; (* div R3, R10, R28 *) INC(i); div[i] := 080210000H; (* lwz R1, 0(R1) *) INC(i); div[i] := 0BB81FFF0H; (* lmw R28, -16(R1) *) INC(i); div[i] := 04FE00020H; (* bclr ALWAYS, CF0.LT *) adrProc := SYSTEM.ADR(Div); adrArr := SYSTEM.ADR(div[0]); SYSTEM.PUT(adrProc, adrArr); END InitProc; 8 adrProc, adrArr: LONGINT; add: ARRAY 17 OF LONGINT; sub: ARRAY 17 OF LONGINT; mul: ARRAY 17 OF LONGINT; div: ARRAY 12 OF LONGINT; MSecs: PROCEDURE (msec: Time); Add: PROCEDURE (VAR a , b, c: Time); Sub: PROCEDURE (VAR a , b, c: Time); Mul: PROCEDURE (VAR a : Time; b: LONGINT; VAR c: Time); Div: PROCEDURE (VAR a: Time; b: LONGINT): LONGINT; PROCEDURE GetTime(VAR time: Time); (* returns micro sec *)  PROCEDURE InitProc;WindowsmSyntax10.Scn.FntSyntax10i.Scn.FntBUN  mod: LONGINT; timeGetTime: PROCEDURE (): LONGINT; (* returns 1 msec *) PROCEDURE GetTime (VAR time: Time); BEGIN time := timeGetTime()*10 END GetTime; PROCEDURE Add (VAR a , b, c: Time); (* c := a + b *) BEGIN c := a + b END Add; PROCEDURE Sub (VAR a , b, c: Time); (* c := a - b *) BEGIN c := a - b END Sub; PROCEDURE Mul (VAR a : Time; b: LONGINT; VAR c: Time); (* c := a * b *) BEGIN c := a*b END Mul; PROCEDURE Div (VAR a: Time; b: LONGINT): LONGINT; (* c := a div b *) BEGIN RETURN a DIV b END Div; Windows95NT  ZParcElemsAlloc p Z &=PKp/8FoldElemsNew#Syntax10.Scn.Fnt VAR i : INTEGER; BEGIN NEW(m.refCounters, nOfCounters); FOR i := 0 TO (nOfCounters - 1) DO m.refCounters[i].beg := 0; m.refCounters[i].end := 0; m.refCounters[i].amount := 0 END; COPY(name,m.name) END Init; 8 8#Syntax10.Scn.Fnt88 BEGIN INC(m.refCounters[counter].amount) END Process; 8 '8#Syntax10.Scn.Fnt]] BEGIN m.refCounters[counter].beg := beg; m.refCounters[counter].end := end END InitScope; 8 /8#Syntax10.Scn.Fnt   VAR i, max: INTEGER; end: LONGINT; BEGIN max := SHORT(LEN(m.refCounters^)); counter := -1; i := 0; WHILE (i < max) & ((pos < m.refCounters[i].beg) OR (m.refCounters[i].end < pos)) DO INC(i) END; IF i < max THEN end := m.refCounters[i].end; counter := i; INC(i); WHILE (i < max) & (m.refCounters[i].end <= end) DO IF (m.refCounters[i].beg <= pos) & (pos <= m.refCounters[i].end) THEN end := m.refCounters[i].end; counter := i END; INC(i) END; RETURN TRUE END; RETURN FALSE END FindCounter; 8 8#Syntax10.Scn.Fnt== BEGIN RETURN m.refCounters[counter].amount; END GetDataOf; 8 ,8#Syntax10.Scn.Fnt^^ BEGIN beg := m.refCounters[counter].beg; end := m.refCounters[counter].end END GetScopeOf; 8  8#Syntax10.Scn.Fnt;; BEGIN RETURN SHORT(LEN(m.refCounters^)) END NOfCounters; 8g8#Syntax10.Scn.Fntww VAR i: INTEGER; BEGIN FOR i := 0 TO SHORT(LEN(m.refCounters^)) - 1 DO m.refCounters[i].amount := 0 END END Reset; 8/8#Syntax10.Scn.Fnt VAR i : INTEGER; BEGIN m.Init^(name, nOfCounters); NEW(m.nameScopes, nOfCounters); NEW(m.elapsedTimes, nOfCounters); FOR i := 0 TO (nOfCounters - 1) DO Sub (m.elapsedTimes[i], m.elapsedTimes[i], m.elapsedTimes[i]) END END Init; 8 08#Syntax10.Scn.Fnt VAR end: INTEGER; BEGIN end := SHORT(LEN(m.refCounters^)); counter := 0; WHILE (counter < end) & ~((m.refCounters[counter].beg <= pos) & (pos <= m.refCounters[counter].end)) DO INC(counter) END; RETURN (counter < end) END FindCounter; 8 +8#Syntax10.Scn.Fnt^^ BEGIN beg := m.nameScopes[counter].beg; end := m.nameScopes[counter].end END GetNameScope; 8 '8#Syntax10.Scn.Fnt^^ BEGIN m.nameScopes[counter].beg := beg; m.nameScopes[counter].end := end END SetNameScope; 8 88:8#Syntax10.Scn.Fnt VAR i: INTEGER; BEGIN m.Reset^; FOR i := 0 TO SHORT(LEN(m.elapsedTimes^)) - 1 DO Sub (m.elapsedTimes[i], m.elapsedTimes[i], m.elapsedTimes[i]) END END Reset; 8 8#Syntax10.Scn.Fnt   VAR count, amount: LONGINT; time: Time; BEGIN count := m.refCounters[counter].amount; Mul(correctionTime, count DIV N, time); Sub(m.elapsedTimes[counter], time, time); amount := Div(time, unit); IF amount < 0 THEN RETURN 0 END; RETURN amount END GetDataOf; 88#Syntax10.Scn.FntBB BEGIN RETURN m.refCounters[counter].amount; END GetFrequencyOf; 8 88  !8#Syntax10.Scn.Fnt VAR prev, curr : Module; BEGIN prev := firstModule; curr := prev.next; WHILE (curr # NIL) & (curr.name # name) DO prev := curr; curr := curr.next END; IF curr # NIL THEN prev.next := curr.next; RETURN TRUE END; RETURN FALSE END DelModule; 8  !F8#Syntax10.Scn.Fnt VAR curr : Module; BEGIN curr := firstModule.next; WHILE (curr # NIL) & (curr.name # name) DO curr := curr.next END; RETURN curr; END GetModule; 8  6$8#Syntax10.Scn.Fnt VAR new : Module; b:BOOLEAN; BEGIN b := DelModule(name); NEW(new); new.next := firstModule.next; firstModule.next := new; new.Init(name, nOfCounters); RETURN new END NewModule; 8 78#Syntax10.Scn.Fnt VAR new: ModuleTime; b: BOOLEAN; BEGIN b := DelModule(name); NEW(new); new.next := firstModule.next; firstModule.next := new; new.Init(name, nOfTimers); RETURN new END NewModuleTime; 8  %-8CSyntax10.Scn.FntSyntax10b.Scn.Fnt  BEGIN IF i.nextMod # NIL THEN COPY(i.nextMod.name, name); i.nextMod := i.nextMod.next; RETURN TRUE END; RETURN FALSE END NextModName; 8Syntax12.Scn.Fnt  y8#Syntax10.Scn.Fntee VAR new : Iterator; BEGIN NEW(new); new.nextMod := firstModule.next; RETURN new END NewIterator; 858#Syntax10.Scn.Fnt VAR firstTime, lastTime: Time; i: INTEGER; BEGIN GetTime(firstTime); FOR i := 0 TO N DO GetTime(lastTime) END; Sub (lastTime, firstTime, correctionTime) END Init; 8Shp#Syntax10.Scn.FntPowerMac Windows Windows95NTWindows95NTPowerMac#Syntax10.Scn.FntmmSys.Assign ("Microseconds", SYSTEM.ADR (MSecs)); (* "implementation dependent" *) unit := 100; InitProc; Windows#Syntax10.Scn.Fntwwmod := Kernel.LoadLibrary("WINMM"); Kernel.GetAdr(mod, "timeGetTime", SYSTEM.VAL(LONGINT, timeGetTime)); unit := 1; Windows95NT HpMODULE PFBasic; (* Christian Mayrhofer, Friedrich Traunmueller  *) (* This module contains two versions. Versions: - PowerMac - Windows 3.11 - Windows 95, NT To switch versions click on Windows 95, NT with the middle mouse button. *) IMPORT Kernel, SYSTEM, Directories; CONST SeparationMark* = Directories.delimiter; maxStackSize = 256; N = 128; (* number of GetTime calls needed for time correction *) TYPE Name = ARRAY 32 OF CHAR; Time = RECORD low, high: LONGINT END; CounterDesc = RECORD amount: LONGINT; beg, end: LONGINT; begName, endName: LONGINT END; Module* = POINTER TO ModuleDesc; ModuleDesc = RECORD name: Name; refCounters: POINTER TO ARRAY OF CounterDesc; next: Module END; NameScope = RECORD beg, end: LONGINT END; ModuleTime* = POINTER TO ModuleTimeDesc; ModuleTimeDesc = RECORD (ModuleDesc) elapsedTimes: POINTER TO ARRAY OF Time; nameScopes: POINTER TO ARRAY OF NameScope END; Iterator* = POINTER TO IteratorDesc; IteratorDesc = RECORD nextMod : Module END; Stack= ARRAY maxStackSize OF RECORD module: ModuleTime; timer: INTEGER END; VAR firstModule: Module; lastTime: Time; correctionTime: Time; stack: Stack; sp: INTEGER; unit: LONGINT;  done: BOOLEAN; mod: LONGINT; QueryCounter: PROCEDURE (adr: LONGINT): BOOLEAN; QueryFrequency: PROCEDURE (adr: LONGINT): BOOLEAN; PROCEDURE GetTime (VAR time: Time); VAR done: BOOLEAN; BEGIN done := QueryCounter(SYSTEM.ADR(time)) END GetTime; PROCEDURE- add64 8BH, 5DH, 18H, (* mov ebx, 24[ebp] -- adr of c *) 8BH, 55H, 08H, (* mov edx, 8[ebp] -- adr of a *) 8BH, 4DH, 10H, (* mov ecx, 16[ebp] -- adr of b *) 8BH, 42H, 00H, (* mov eax, 0[edx] *) 8BH, 52H, 04H, (* mov edx, 4[edx] *) 03H, 41H, 00H, (* mov add, 0[ecx] *) 13H, 51H, 04H, (* mov adc, 4[ecx] *) 89H, 43H, 00H, (* mov 0[ebx], eax *) 89H, 53H, 04H; (* mov 4[ebx], edx *) PROCEDURE- sub64 8BH, 5DH, 18H, (* mov ebx, 24[ebp] -- adr of c *) 8BH, 55H, 08H, (* mov edx, 8[ebp] -- adr of a *) 8BH, 4DH, 10H, (* mov ecx, 16[ebp] -- adr of b *) 8BH, 42H, 00H, (* mov eax, 0[edx] *) 8BH, 52H, 04H, (* mov edx, 4[edx] *) 2BH, 41H, 00H, (* mov sub, 0[ecx] *) 1BH, 51H, 04H, (* mov sbb, 4[ecx] *) 89H, 43H, 00H, (* mov 0[ebx], eax *) 89H, 53H, 04H; (* mov 4[ebx], edx *) PROCEDURE- mul64 8BH, 5DH, 14H, (* mov ebx, 20[ebp] *) 8BH, 4DH, 08H, (* mov ecx, 8[ebp] *) 8BH, 41H, 00H, (* mov eax, 0[ecx] *) 0F7H, 65H, 10H, (* mul 16[ebp] *) 89H, 43H, 00H, (* mov 0[ebx], eax *) 8BH, 41H, 04H, (* mov eax, 4[ecx] *) 8BH, 0CAH, (* mov ecx, edx *) 0F7H, 65H, 10H, (* mul 16[ebp] *) 03H, 0C1H, (* add eax, ecx *) 89H, 43H, 04H; (* mov 4[ebx], eax *) PROCEDURE- div64 8BH, 4DH, 08H, (* mov ecx, 8[ebp] *) 8BH, 41H, 00H, (* mov eax, 0[ecx] *) 8BH, 51H, 04H, (* mov edx, 4[ecx] *) 0F7H, 75H, 10H, (* div 16[ebp] *) 8BH, 0E5H, (* mov esp, ebp *) 5DH, (* pop ebp *) 0C2H, 0CH, 00H; (* ret 12 *)  PROCEDURE Add (VAR a , b, c: Time); (* c := a + b *) BEGIN add64 END Add; PROCEDURE Sub (VAR a , b, c: Time); (* c := a - b *) BEGIN sub64 END Sub; PROCEDURE Mul (VAR a : Time; b: LONGINT; VAR c: Time); (* c := a * b *) BEGIN mul64 END Mul; PROCEDURE Div (VAR a: Time; b: LONGINT): LONGINT; (* c := a div b *) BEGIN div64 END Div;  PROCEDURE (m: Module) Init* (name : ARRAY OF CHAR; nOfCounters : INTEGER); PROCEDURE (m: Module) Process* (counter: INTEGER); PROCEDURE (m: Module) InitScope* (counter: INTEGER; beg,end : LONGINT); PROCEDURE (m: Module) FindCounter* (pos: LONGINT; VAR counter: INTEGER): BOOLEAN; PROCEDURE (m: Module) GetDataOf* (counter : INTEGER): LONGINT; PROCEDURE (m: Module) GetScopeOf* (counter: INTEGER; VAR beg, end : LONGINT); PROCEDURE (m: Module) NOfCounters* (): INTEGER; PROCEDURE (m: Module) Reset*; PROCEDURE (m: ModuleTime) Init* (name : ARRAY OF CHAR; nOfCounters : INTEGER); PROCEDURE (m: ModuleTime) FindCounter* (pos : LONGINT; VAR counter: INTEGER): BOOLEAN; PROCEDURE (m: ModuleTime) GetNameScope* (counter: INTEGER; VAR beg, end: LONGINT); PROCEDURE (m: ModuleTime) SetNameScope* (counter: INTEGER; beg, end: LONGINT); PROCEDURE (m: ModuleTime) Process* (counter: INTEGER); VAR t, delta: Time; mod: ModuleTime; i: INTEGER; BEGIN GetTime(t); m.Process^(counter); IF (sp >= 0) & (sp < maxStackSize) THEN mod := stack[sp].module(ModuleTime); i := stack[sp].timer; Sub(t, lastTime, delta); Add(mod.elapsedTimes[i], delta, mod.elapsedTimes[i]) END; INC(sp); IF sp < maxStackSize THEN stack[sp].timer := counter; stack[sp].module := m END; GetTime(lastTime) END Process;  PROCEDURE (m: ModuleTime) Reset*; PROCEDURE (m: ModuleTime) GetDataOf*(counter : INTEGER): LONGINT;  returns 0.1 msec  PROCEDURE (m: ModuleTime) GetFrequencyOf* (counter: INTEGER): LONGINT; PROCEDURE (m: ModuleTime) EndProcess*; VAR t, delta: Time; i: INTEGER; BEGIN GetTime(t); i := stack[sp].timer; Sub(t, lastTime, delta); Add(m.elapsedTimes[i], delta, m.elapsedTimes[i]); DEC(sp); GetTime(lastTime) END EndProcess;  PROCEDURE DelModule* (name : ARRAY OF CHAR): BOOLEAN; PROCEDURE GetModule* (name : ARRAY OF CHAR) : Module; PROCEDURE NewModule* (name: ARRAY OF CHAR; nOfCounters: INTEGER) : Module; PROCEDURE NewModuleTime* (name: ARRAY OF CHAR; nOfTimers: INTEGER): ModuleTime; PROCEDURE (i : Iterator) NextModName*(VAR name : ARRAY OF CHAR): BOOLEAN; PROCEDURE NewIterator*() : Iterator; PROCEDURE Init; BEGIN NEW(firstModule); firstModule.next := NIL; (* dummy module *) sp := -1; mod := Kernel.LoadLibrary("Kernel32"); Kernel.GetAdr(mod, "QueryPerformanceCounter", SYSTEM.VAL(LONGINT, QueryCounter)); Kernel.GetAdr(mod, "QueryPerformanceFrequency", SYSTEM.VAL(LONGINT, QueryFrequency)); done := QueryFrequency(SYSTEM.ADR(lastTime)); ASSERT (done & (lastTime.high = 0)); unit := lastTime.low DIV 10000;  Init END PFBasic.