//This file was generated by the LASAL2 CodeGenerator  -- 
//Please, do not edit this file (it might be overwritten by the next generator run)
//{{LSL_DECLARATION
#include "..\..\Class\DiasMasterMain\DiasMasterMain.h"
#include "..\..\Class\HwControl\HwControl.h"
#include "..\..\Source\interfaces\lsl_st_pci.h"
#include "..\..\Source\interfaces\lsl_st_kernel.h"

(*!
<Class
	Name               = "DiasMasterMain"
	Revision           = "2.25"
	GUID               = "{8DDB958C-8E8E-4446-A332-88C51D93511B}"
	RealtimeTask       = "true"
	DefRealtime        = "1 ms"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\Tool.ico"
	SharedCommandTable = "true"
	Objectsize         = "(284,120)">
	<Channels>
		<Server Name="Chipstate" GUID="{56D24317-A311-4FCB-9E29-02FDB185D365}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="the state of the chip"/>
		<Server Name="Control">
		</Server>
		<Server Name="CyTimeIM_us" GUID="{F433EC8E-B6DA-4726-923A-BD2251220D75}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Estimated runtime of intelligent master cyclic program in µs"/>
		<Server Name="DIASRetryCounter" GUID="{88C4DE7C-7239-4266-8273-2EC64C914F07}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Server Name="HwControl" GUID="{B4DB4391-E345-4158-85A6-77D816C2C282}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="0=Not controlled by VaranMaster, 1=controlled by VaranMaster"/>
		<Server Name="MasterON" GUID="{08360379-B5D1-4885-BA3D-40B361B20CB4}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="1 = Master is running | 0 = Master is off"/>
		<Server Name="Release" GUID="{92E23854-5E9D-4F71-8519-2F7F0A137E2E}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Hardware + Software release"/>
		<Server Name="RiscState" GUID="{2076E2C4-C858-4E95-B06A-AB9A799B4952}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Server Name="Rt_Load" GUID="{FC1A2FCC-1551-4D00-850F-9A09C9C3FE2F}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="measured usage rate of IM Rt-Programm in µs (in 25µs steps)"/>
		<Server Name="RtTimeIM_us" GUID="{666EF25E-0094-47E6-9D47-BF816DC65069}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Estimated runtime of intelligent master realtime program in µs"/>
		<Server Name="TimeAtRtPreEnd" GUID="{F4A32A20-3FEA-4EEE-907B-D183CF24F9E9}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Client Name="RtDebug" Required="false" Internal="false" Comment="ATTENTION!! If client is activated hardware will be continue to work if a Realtime task is debugged. No Watchdog of hardware occures. (as Initvalue, default is off)"/>
		<Client Name="SyncCall" Required="true" Internal="false"/>
		<Client Name="To_HwControl" Required="false" Internal="false" Comment="connect to Server &apos;DiasMaster&apos; of &apos;HwControl&apos; class if VaranMaster is also used&#13;&#10;This connection is needed for synchonization between DiasMaster and VaranManager"/>
		<Client Name="To_Multitask" Required="false" Internal="false"/>
		<Client Name="To_OSKernel" Required="false" Internal="false"/>
		<Client Name="To_StdLib" Required="false" Internal="false"/>
		<Client Name="To_TaskObjectControl" Required="false" Internal="false" Comment="is connected automatically to OS channel"/>
		<Client Name="WaitSync" Required="false" Internal="false" Comment="0 = only wait for IM synchron | 1 = Wait for synchronizing all DiasModules (as initvalue)"/>
	</Channels>
	<Dependencies>
		<Files>
			<File Path=".\LSL_STITask.h" Include="false"/>
			<File Path=".\Class\DiasMasterMain\DiasMasterMain.h" Include="true"/>
			<File Path=".\Class\DiasMasterC\MasterSettings.h" Include="false"/>
			<File Path=".\Class\HwControl\HwControl.h" Include="true"/>
			<File Path=".\Source\interfaces\lsl_st_cdias.h" Include="false"/>
			<File Path=".\Source\interfaces\lsl_st_pci.h" Include="true"/>
			<File Path=".\Source\interfaces\lsl_st_kernel.h" Include="true"/>
		</Files>
	</Dependencies>
	<RevDoku>
		<Owner Company="Sigmatek" Author="AscFra"/>
		<Dokumentation Revision="2.25" Date="21.12.2020" Author="RamAnd" Company="Sigmatek" Description="On linux platforms there is no local DIAS/CDIAS therefore the class now doesn&apos;t try to initialize the local busses there anymore."/>
		<Dokumentation Revision="2.24" Date="05.08.2020" Author="FurDom" Company="Sigmatek" Description="Tracelogging changed. Trace messages for timeslice errors and watchdog errors are set in the function WriteRTLogs() /CyWork."/>
		<Dokumentation Revision="2.23" Date="24.07.2018" Author="RamAnd" Company="Sigmatek" Description="Prevent required error crash when current target platform is LARS."/>
		<Dokumentation Revision="2.22" Date="19.07.2018" Author="EisMic" Company="Sigmatek" Description="Corrected duplicate realtimecall if class was used with HwControl and a realtime task time &gt;= 2ms was used. Concerns only CIPC and CCL9xx."/>
		<Dokumentation Revision="2.21" Date="06.03.2018" Author="EisMic" Company="Sigmatek" Description="Attached header files no longer point to the installation directory of LASAL but instead now point to the the source/interfaces folder."/>
		<Dokumentation Revision="2.20" Date="23.01.2018" Author="RamAnd" Company="Sigmatek" Description="Log messages have been standardized for easier maintenance, easier use in any class and to allow spam filtering. Code for the logging functions is now only located in HwControl."/>
		<Dokumentation Revision="2.19" Date="18.09.2017" Author="LanSte" Company="Sigmatek" Description="Added NewInst Commands to check if the Post-Init is done."/>
		<Dokumentation Revision="2.18" Date="13.07.2017" Author="ZoePat" Company="Sigmatek" Description="Added WhoAmI=16#35 (ETV_Edge) to list of modules that trigger the CCLWatchdog."/>
		<Dokumentation Revision="2.17" Date="20.06.2016" Author="ZoePat" Company="Sigmatek" Description="Moved realtime logmessages to cyclic task to prevent possible rtruntime error."/>
		<Dokumentation Revision="2.16" Date="10.05.2016" Author="RamAnd" Company="Sigmatek" Description="Suppressed warning that would occur with target ARM on compiler version 30 or higher."/>
		<Dokumentation Revision="2.15" Date="09.07.2015" Author="PieSte" Company="Sigmatek" Description="Corrected cast for pointer in methode UpdateRtPostScan_IM()."/>
		<Dokumentation Revision="2.14" Date="28.10.2014" Author="RamAnd" Company="Sigmatek" Description="Stopped cyclic hardware class calls if an error has been reported by HwControl."/>
		<Dokumentation Revision="2.13" Date="02.10.2014" Author="LanSte" Company="Sigmatek" Description="Fixed compiler error when importing DiasMasterC without a HWControl in Project. The compiler error was caused by a missing type."/>
		<Dokumentation Revision="2.12" Date="28.07.2014" Author="RamAnd" Company="Sigmatek" Description="DiasError is now also triggered for asynchron methods (direct accesses). Can be disabled with #define DIASMASTER_DISABLE_DIAS_ERROR_ON_DIRECT_ACCESS in DiasMasterMain.h.&#13;&#10;Improved readability of code."/>
		<Dokumentation Revision="2.11" Date="24.06.2014" Author="LanSte" Company="Sigmatek" Description="Added support for reading hardware diagnosis."/>
		<Dokumentation Revision="2.10" Date="04.12.2013" Author="LanSte&#13;&#10;RamAnd" Company="Sigmatek" Description="AWL deactivated for ARM.&#13;&#10;Prevented crash if DiasmasterC is placed and there is no CDIAS/DIAS bus on the CPU. Server Release will be set to 16#FFFFFFFF in this case.&#13;&#10;Arraysize of OldRetryCounters was limited to 64, which is a problem if more than 64 modules are placed on DIAS (if place number is given at runtime)."/>
		<Dokumentation Revision="2.0" Date="18.07.2013" Author="ZoePat" Company="Sigmatek" Description="Added possibility to move data on CDIAS behind DataMover."/>
		<Dokumentation Revision="1.90" Date="07.03.2013" Author="BeiWol&#13;&#10;RamAnd" Company="Sigmatek" Description="(SA22489) Add cli error message if a module has a required error&#13;&#10;(SA23978) The safety modules on local CDIAS didn&apos;t work, if a PLC without intelligent master and without a VARAN interface (e.g. CCP531) has been used."/>
		<Dokumentation Revision="1.80" Date="23.12.2011" Author="RamAnd" Company="Sigmatek" Description="Added support for the SafetyManager"/>
		<Dokumentation Revision="1.79" Date="09.12.2011" Author="RamAnd" Company="Sigmatek" Description="The actual domain number is now added to the hardware path."/>
		<Dokumentation Revision="1.78" Date="19.01.2012" Author="ZoePat" Company="Sigmatek" Description="Corrected handling of RequiredError (In some cases it could have happened, that an error has been generated even if the module has been connected)"/>
		<Dokumentation Revision="1.77" Date="06.09.2011" Author="RamAnd" Company="Sigmatek" Description="Now the constructor detects, if it&apos;s a dummy object for derivation."/>
		<Dokumentation Revision="1.76" Date="22.09.2011" Author="RamAnd" Company="Sigmatek" Description="Parameter of Server Read/Write-Methods have been changed to the type of the server."/>
		<Dokumentation Revision="1.75" Date="04.07.2011" Author="RamAnd" Company="Sigmatek" Description="Changed order of initialisation in constructor to prevent a crash if there is no module connected to a VARAN-To-DIAS bridge."/>
		<Dokumentation Revision="1.74" Date="24.02.2011" Author="BleErn" Company="Sigmatek" Description="Constructor of DiasMasterMain is no longer called if it is derived for a non-local DiasMaster"/>
		<Dokumentation Revision="1.73" Date="19.01.2011" Author="BleErn" Company="Sigmatek" Description="Fixed incorrect handling of RtPostScan if no HwControl-Connection was available"/>
		<Dokumentation Revision="1.72" Date="12.01.2011" Author="RamAnd" Company="Sigmatek" Description="Added the time estimation for the DIAS access to the AddRd32Bit method."/>
		<Dokumentation Revision="1.71" Date="17.11.2010" Author="WocPet" Company="Sigmatek" Description="Initialisation has been adapted for CDIAS and DIAS modules, which can now cause a required error."/>
		<Dokumentation Revision="1.70" Date="15.11.2010" Author="BleErn" Company="Sigmatek" Description="Moved headerfile MasterSettings.h from DiasMasterMain back to DiasMasterC"/>
		<Dokumentation Revision="1.69" Date="21.10.2010" Author="BleErn" Company="Sigmatek" Description="Removed client &quot;PreventMasterError&quot; which was a relict from development"/>
		<Dokumentation Revision="1.68" Date="15.10.2010" Author="RamAnd" Company="Sigmatek" Description="Added method AddMovDO for the move command in the VM."/>
		<Dokumentation Revision="1.67" Date="24.08.2010" Author="BleErn / RamAnd" Company="Sigmatek" Description="Version check of OS-Methods for CDIAS access was wrong.&#13;&#10;Corrected comment of Server Rt_Load"/>
		<Dokumentation Revision="1.66" Date="23.06.2010" Author="WocPet" Company="Sigmatek" Description="Added functionality to write retry-counter values to classes if we are intelligent master,&#13;&#10;also set class state server to 16#ffff if MasterOn ist zero&#13;&#10;New client &quot;PreventMasterError&quot; added"/>
		<Dokumentation Revision="1.65" Date="03.03.2010" Author="BleErn" Company="Sigmatek" Description="Added RtPostScan functionality&#13;&#10;New global profiler for time measurement integreated"/>
		<Dokumentation Revision="1.64" Date="01.03.2010" Author="RamAnd" Company="Sigmatek" Description="Support for Edge CPUs added"/>
		<Dokumentation Revision="1.63" Date="12.08.2009" Author="RamAnd" Company="Sigmatek" Description="Added 2 new servers (RtTimeIM_us and CyTimeIM_us) to show estimated runtime of IM program.&#13;&#10;Added new trace messages if the estimated runtime is higher than the task time of the diasmaster."/>
		<Dokumentation Revision="1.62" Date="15.07.2009" Author="RamAnd" Company="Sigmatek" Description="Added functions for safety and hardwaretree.&#13;&#10;Changed mapping in intelligent master for better flexibility (code of realtime and cyclic share the same memory now)"/>
		<Dokumentation Revision="1.61" Date="17.02.2009" Author="RamAnd" Company="Sigmatek" Description="Bit in PLL is now requested to ensure synchronity of HW-Classes and intelligent master.&#13;&#10;Watchdog of x386 CPUs is now triggered in Realtime by default (was cyclic before). If constant TRIGGER_WD_386_IN_CYCLIC is defined it&apos;s done in cyclic again."/>
	</RevDoku>
	<Network Name="DiasMasterMain">
		<!-- List of Components in this network -->
		<Components>
			<Object
				Name       = "_base"
				GUID       = "{BB081F3E-9A4E-4E4F-91A9-AE8342826415}"
				Class      = "DiasMaster"
				Position   = "(270,330)"
				Visualized = "true"
				RealTime   = "1 ms">
				<Channels>
					<Server Name="Control"/>
				</Channels>
			</Object>
		</Components>
		<Comments>
		</Comments>
		<!-- List of Connections in this network -->
		<Connections>
			<Connection Source="this.Control" Destination="_base.Control" Vertices="(742,210),(570,420),"/>
		</Connections>
		<!-- Headerfiles -->
		<Options>
		</Options>
	</Network>
</Class>
*)
#pragma using DiasMaster

DiasMasterMain : CLASS
: DiasMaster
	TYPE
	  WaitSyncCall : STRUCT
	    thisp : pHwBase;  //! <Type Comment="thispointer to Object" Name="WaitSyncCall.thisp"/>
	    SyncState : USINT;  //! <Type Comment="0 = not Synchron | 1 = Synchron" Name="WaitSyncCall.SyncState"/>
	    WaitTime : UDINT;
	  END_STRUCT;
	  _T_DiasSync : STRUCT
	    Modules : ARRAY [0..(MaxSyncModules-1)] OF WaitSyncCall;
	    NumberCalls : UDINT;
	    ActMaxTime : UDINT;
	  END_STRUCT;
#pragma pack(push, 1)
	  a_RetryStruct : STRUCT
	    Place : UDINT;
	    p_State : ^IO_State;
	    p_RetryCounter : ^DINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  CallStruct : STRUCT
	    Opc : HSINT;
	    addr : HINT;
	    Mode : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  CntrlStruct : STRUCT
	    OPC : HSINT;
	    chAdr : HSINT;
	    ModAdr : HSINT;
	    Data : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  DelayStruct : STRUCT
	    OPC : HSINT;
	    TIME_uSec : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  DelStruct : STRUCT
	    Opc : HSINT;
	    Tim : USINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  EndStruct : STRUCT
	    Opc : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  EventStruct : STRUCT
	    Opc : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Inc8Struct : STRUCT
	    Opc : HSINT;
	    Adress : UINT;
	  END_STRUCT;
#pragma pack(pop)
	  IRQScanStruct : STRUCT
	    OPC : HSINT;
	    ModAdr : HSINT;
	    Data : HSINT;
	  END_STRUCT;
	  oneIRQ : STRUCT
	    ActionPtr : pVoid;
	    ThisPtr : pVoid;
	  END_STRUCT;
	  IRQStruct : STRUCT
	    anz : UDINT;
	    data : ARRAY [0..7] OF oneIRQ;
	  END_STRUCT;
#pragma pack(push, 1)
	  JmpStruct : STRUCT
	    Opc : HSINT;
	    Adress : UINT;
	  END_STRUCT;
#pragma pack(pop)
	  ModuleRetryCnt : ARRAY [0..63] OF USINT;
#pragma pack(push, 1)
	  MoveStruct : STRUCT
	    Opc : USINT;
	    Source : HINT;
	    Destination : HINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  MovStruct : STRUCT
	    Opc : HSINT;
	    Srce : UINT;
	    Dest : UINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  OneHandle : STRUCT
	    Address : UINT;  //! <Type Comment="to access later in the controller " Name="OneHandle.Address"/>
	    Typ : UINT;  //! <Type Comment="to know how it works (RTor Cyclic)" Name="OneHandle.Typ"/>
	    thisp : pHwBase;
	    Value : DINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Rd16Struct : STRUCT
	    Opc : HSINT;
	    ChAdr : HSINT;
	    ModAdr : HSINT;
	    Data : UINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Rd32Struct : STRUCT
	    opc : HSINT;
	    chAdr : HSINT;
	    ModAdr : HSINT;
	    Data : UDINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Rd8Struct : STRUCT
	    Opc : HSINT;
	    ChAdr : HSINT;
	    ModAdr : HSINT;
	    Data : USINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  RdKennStruct : STRUCT
	    OPC : HSINT;
	    ModAdr : HSINT;
	    Data : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Retrystruct : STRUCT
	    Quantity : DINT;
	    RetryCounter : ARRAY [0..499] OF a_RetryStruct;  //! <Type Comment="for 500 Entrys maximum (because its possible to place more then 64 moduls - and 500 calls are max for diasmaster)" Name="Retrystruct.RetryCounter"/>
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  RetStruct : STRUCT
	    Opc : HSINT;
	  END_STRUCT;
#pragma pack(pop)
	  s_DiasInfoType : STRUCT
	    DiasType : UDINT;
	    DiasHWPointer : UDINT;
	    CDIASType : UDINT;
	    CDIASHWPointer : UDINT;
	    CfgRegsType : UDINT;
	    CfgRegsHWPointer : UDINT;
	    XregsType : UDINT;
	    XregsHWPointer : UDINT;
	    PLLType : UDINT;
	    PLLHWPointer : UDINT;
	    EERType : UDINT;
	    EERPointer : UDINT;
	  END_STRUCT;
	  t_DMFunctions : STRUCT
	    p_RtFunction : pVoid;
	    p_SendSync : pVoid;
	    p_FinishIMProg : pVoid;
	    p_LastInit : pVoid;
	    p_This : pVoid;
	    sd_PllTime : DINT;
	    sd_DiasTime : DINT;
	    sd_RtDebug : DINT;
	    p_RtPostScanFunction : pVoid;
	    SafetyManagerThisPointer : ^pVirtualBase;
	  END_STRUCT;
#pragma pack(push, 1)
	  t_ModuleList : STRUCT
	    ui_Index : UINT;
	    ap_ModuleList : ARRAY [0..DIASMASTERC_MAX_MODULE_NO] OF pVirtualBase;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  t_OneSyncOut : STRUCT
	    ui_OffsetLow : UINT;
	    us_OffsetHigh : USINT;
	    us_Reserved : USINT;
	    us_PeriodMultiplier : USINT;
	    us_FrameCountTreshold : USINT;
	    us_SyncOutID : USINT;
	    us_Control : BSINT
	    [
	      1 SyncOut,
	      2 FrameCountEnable,
	    ];
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  t_PllStruct : STRUCT
	    sd_SystemPeriod : DINT;
	    sd_Reserved : DINT;
	    us_syncTimeFrameCounter : USINT;
	    us_IRQRegister : USINT;
	    us_PllState : BSINT
	    [
	      1 PllLocked,
	      2 PllUnlock,
	      6 IRQWatchdogEnable,
	      7 PllEnable,
	      8 SystemPeriodeOverwrite,
	    ];
	    us_MaxSyncMiss : USINT;
	    sd_DeviceDelayTime : DINT;
	    a_SyncOut : ARRAY [0..DmMaxSyncs-1] OF t_OneSyncOut;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  TmrStruct : STRUCT
	    OPC : HSINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Wr16Struct : STRUCT
	    Opc : HSINT;
	    ChAdr : HSINT;
	    ModAdr : HSINT;
	    Data : UINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Wr32Struct : STRUCT
	    opc : HSINT;
	    ChAdr : HSINT;
	    ModAdr : HSINT;
	    Data : UDINT;
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  Wr8Struct : STRUCT
	    Opc : HSINT;
	    ChAdr : HSINT;
	    ModAdr : HSINT;
	    Data : USINT;
	  END_STRUCT;
#pragma pack(pop)
	END_TYPE
  //Servers:
	Release 	: SvrCh_HDINT;
	Chipstate 	: SvrCh_DINT;
	RiscState 	: SvrCh_DINT;
	TimeAtRtPreEnd 	: SvrCh_DINT;
	DIASRetryCounter 	: SvrCh_DINT;
	MasterON 	: SvrCh_DINT;
	Rt_Load 	: SvrCh_DINT;
	RtTimeIM_us 	: SvrCh_UDINT;
	CyTimeIM_us 	: SvrCh_UDINT;
	HwControl 	: SvrCh_DINT;
  //Clients:
	To_TaskObjectControl 	: CltChCmd__TaskObjectControl;
	WaitSync 	: CltCh_DINT;
	SyncCall 	: CltCh_IO_State;
	RtDebug 	: CltCh_DINT;
	To_HwControl 	: CltCh_DINT;
	To_Multitask 	: CltChCmd__MultiTask;
	To_StdLib 	: CltChCmd__StdLib;
	To_OSKernel 	: CltChCmd__OSKernel;
  //Variables:
		FirstScan 	: USINT;
		TimeAtRealtimeTask 	: DINT;
		CallsRT : ARRAY [0..2047] OF HSINT;

		CallsCY : ARRAY [0..2047] OF HSINT;

		CodeRtCy : ARRAY [0..4095] OF HSINT;

		PtrRT 	: ^USINT;
		PtrCY 	: ^USINT;
		PtrCode 	: ^USINT;
		IPMainCY 	: DINT;
		IPMainRT 	: DINT;
		IPSub 	: DINT;
		TotalSizeCY 	: DINT;
		TotalSizeRT 	: DINT;
		StartOfRt 	: DINT;
		StartOfCy 	: DINT;
		StartOfCode 	: DINT;
		RtSSW 	: USINT;			//! <Variable Comment="steps into the realtime" Name="RtSSW"/>
		HandleNrCY 	: UINT;
		HandlesCY : ARRAY [0..499] OF OneHandle;

		HandleNrRT 	: UINT;
		HandlesRT : ARRAY [0..499] OF OneHandle;

		RtInterval 	: DINT;			//! <Variable Comment="in 25 usek periods" Name="RtInterval"/>
		TimeBeforeNextSync 	: UINT;			//! <Variable Comment="time to next sync 37-38 (925-950 usec)" Name="TimeBeforeNextSync"/>
		oldErrorCounter 	: DINT;
		FirstModulFound 	: USINT;
		CDiasType 	: USINT;
		DiasType 	: USINT;
		DiasHwPointer 	: ^USINT;
		CDiasHwPointer 	: ^USINT;
		RTBSyncAdr 	: ^USINT;
		OldTime 	: UDINT;
		CDiasI2CWatchdog 	: ^USINT;
		timestamp 	: DINT;
		timestampCDIAS 	: DINT;			//! <Variable Comment="//#SR007" Name="timestampCDIAS"/>
		IRQDias 	: IRQStruct;
		lsl_cdias_irq 	: ^LSL_CDIAS_IRQ;
		CDiasIRQpossible 	: BOOL;
		CDIASSync 	: ^USINT;			//! <Variable Comment="ptr on sync" Name="CDIASSync"/>
		StateCDiasSync : BSINT
		[
		  1 PllLocked,
		  2 Online,
		];

		PllTimeGlob 	: DINT;
		NumberSyncs 	: USINT;
		RtbLocalSyncAdr : ARRAY [0..NumberLocalSyncs-1] OF HINT;

		ImOff 	: BOOL;			//! <Variable Comment="1 = Master is Off" Name="ImOff"/>
		pSPCIInfo 	: ^LSL_SPCIINFO;			//! <Variable Comment="PCI info functions" Name="pSPCIInfo"/>
		CyclicReady 	: BOOL;			//! <Variable Comment="1= cyclic ready" Name="CyclicReady"/>
		RealtimeReady 	: BOOL;			//! <Variable Comment="1= realtime ready" Name="RealtimeReady"/>
		DiasSync 	: _T_DiasSync;
		ud_DelayRealtime 	: UDINT;
		ud_DelayCyclic 	: UDINT;
		SyncProgPtr 	: ^USINT;			//! <Variable Comment="//#SR003 Pointer to Sync Call" Name="SyncProgPtr"/>
		ud_IMMemory 	: UDINT;
		p_ModuleRetryCnt 	: ^ModuleRetryCnt;
		us_SyncModule 	: USINT;
		p_KernelLog 	: ^DINT;
		pDIAS 	: ^void;
		ui_RtStartPoint 	: UINT;
		sd_PllTimeGlob_us 	: DINT;
		ud_ErrorCountTimeSliceStart 	: UDINT;
		ud_ErrorCountTimeSliceEnd 	: UDINT;
		us_FirstTimeSliceStart 	: USINT;
		us_FirstTimeSliceEnd 	: USINT;
		p_DebugAPI 	: ^DEBUGAPI;
		us_ModuleUpdate1ms 	: USINT;
		us_RtPasses 	: USINT;
		us_MuSecMode 	: USINT;
		ui_ClockTicks 	: UINT;
		us_Counter_us 	: USINT;
		s_FunctionList 	: t_DMFunctions;
		p_SemaHandle 	: ^void;			//! <Variable Comment="//Handle for the semaphore to async calls" Name="p_SemaHandle"/>
		p_NewPll 	: ^t_PllStruct;
		ui_RtDIASAccesses 	: UINT;
		ui_CyDIASAccesses 	: UINT;
		ui_AddTime 	: UINT;
		p_CDIAS 	: ^t_OneSyncOut;
		p_DIAS 	: ^t_OneSyncOut;
		b_PllInit 	: BOOL;
		b_TaskTimeCorrected 	: BOOL;
		ud_TaskTime 	: UDINT;
		b_ObjectPathInit 	: BOOL;
		pHardwareTree 	: ^LSL_HARDWARETREE;
		HandleNrRTPostScan 	: UINT;
		HandlesRTPostScan : ARRAY [0..499] OF OneHandle;

		s_RetryCounter 	: Retrystruct;
		OldRetryCounters : ARRAY [0..499] OF USINT;

		p_port 	: ^UDINT;
		p_State 	: ^UDINT;
		p_RetryCounter 	: ^UDINT;
		p_OldRetryCounter 	: ^USINT;
		SafetyManagerThis 	: pVirtualBase;
		ARM_EAX 	: UDINT;
		ARM_EDI 	: UDINT;
		ud_DiasMasterPosition 	: UDINT;
		s_HWTModuleList 	: t_ModuleList;			//! <Variable Comment="List of this pointer of all modules. Pointers are set in the &quot;SetObjectThisp&quot; Method. Needed to suppport Hardwaretree diagnsis." Name="s_HWTModuleList"/>
		SkipCy 	: BOOL;
		bdRTLogs : BDINT
		[
		  1 Bit1,
		  2 Bit2,
		  3 Bit3,
		  4 Bit4,
		  5 Bit5,
		  6 Bit6,
		  7 Bit7,
		  8 Bit8,
		  9 Bit9,
		  10 Bit10,
		  11 Bit11,
		  12 Bit12,
		  13 Bit13,
		  14 Bit14,
		  15 Bit15,
		  16 Bit16,
		  17 Bit17,
		  18 Bit18,
		  19 Bit19,
		  20 Bit20,
		  21 Bit21,
		  22 Bit22,
		  23 Bit23,
		  24 Bit24,
		  25 Bit25,
		  26 Bit26,
		  27 Bit27,
		  28 Bit28,
		  29 Bit29,
		  30 Bit30,
		  31 Bit31,
		  32 Bit32,
		];

		b_IsPostInitDone 	: BOOL;
  //Functions:
				//! <Function Comment="#SR007 end&#13;&#10;" Name="Init"/>
	FUNCTION VIRTUAL GLOBAL Init;
				//! <Function Comment="[#ENGLISH]&#13;&#10; ***************************************************************&#13;&#10;   This Function is Called by PostScan from DiasMasterPostScan&#13;&#10; ***************************************************************&#13;&#10;" Name="CyWork"/>
	FUNCTION AWL VIRTUAL GLOBAL CyWork
		VAR_INPUT
			EAX 	: UDINT := EAX;
		END_VAR
		VAR_OUTPUT
			state (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL RtWork
		VAR_INPUT
			EAX 	: UDINT := EAX;
		END_VAR
		VAR_OUTPUT
			state (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION DiasMasterMain
		VAR_OUTPUT
			ret_code 	: ConfStates;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL UpdateRtPostScan;
	
	FUNCTION VIRTUAL GLOBAL GetPllTime
		VAR_OUTPUT
			PllTime 	: DINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;" Name="AddWait"/>
	FUNCTION AWL VIRTUAL GLOBAL AddWait
		VAR_INPUT
			RTCY 	: DINT;
			Time_uSec 	: DINT;			//! <Variable Comment="Time in uSec (valid from 0-255)" Name="AddWait.Time_uSec"/>
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Function is writing into controlarea of a diasmodul&#13;&#10;[Globals]  _RTOSVersion  : OS version&#13;&#10;    _lsl_pos   : OS interface structure&#13;&#10;[Members]  &#13;&#10;[Locals]  &#13;&#10;" Name="WrCntr"/>
	FUNCTION VIRTUAL GLOBAL WrCntr
		VAR_INPUT
			adress 	: DINT;
			Data 	: USINT;
		END_VAR
		VAR_OUTPUT
			state 	: DINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL AddWr8Bit
		VAR_INPUT
			adress 	: HINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			Data 	: USINT;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
				//! <Function Comment=" ***************************************&#13;&#10;   put programm into the buffer&#13;&#10; ***************************************&#13;&#10;  this is a 16 bit read&#13;&#10;  the thispointer we need to call the update method&#13;&#10;&#13;&#10;" Name="AddWR16Bit"/>
	FUNCTION AWL VIRTUAL GLOBAL AddWR16Bit
		VAR_INPUT
			adress 	: HINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			data 	: UINT;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			handle 	: DINT;
		END_VAR;
				//! <Function Comment=" *************************************************&#13;&#10;   RTB is fixed reserved for one MODUL&#13;&#10; *************************************************&#13;&#10;&#13;&#10;  if FirstRTB &lt;&gt; 0 then this modul is the first with RTB&#13;&#10;  and has to do perhaps something special&#13;&#10;  if FirstRTB = 0 then it already exists a modul with RTBSYNC&#13;&#10;&#13;&#10;" Name="AddRTBSync"/>
	FUNCTION AWL VIRTUAL GLOBAL AddRTBSync
		VAR_INPUT
			Adress 	: HINT;
		END_VAR
		VAR_OUTPUT
			FirstRTB 	: DINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL AddRet
		VAR_INPUT
			RTCY 	: DINT;
		END_VAR;
				//! <Function Comment=" ***************************************&#13;&#10;   put programm into the buffer&#13;&#10; ***************************************&#13;&#10;  this is a 16 bit read&#13;&#10;  the thispointer we need to call the update method&#13;&#10;&#13;&#10;" Name="AddRd32Bit"/>
	FUNCTION AWL VIRTUAL GLOBAL AddRd32Bit
		VAR_INPUT
			Adress 	: HINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
				//! <Function Comment=" ***************************************&#13;&#10;   put programm into the buffer&#13;&#10; ***************************************&#13;&#10;  this is a 16 bit read&#13;&#10;  the thispointer we need to call the update method&#13;&#10;&#13;&#10;" Name="AddRd16Bit"/>
	FUNCTION AWL VIRTUAL GLOBAL AddRd16Bit
		VAR_INPUT
			Adress 	: HINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetKennung
		VAR_INPUT
			Place 	: UDINT;			//! <Variable Comment="  DIAS module" Name="GetKennung.Place"/>
		END_VAR
		VAR_OUTPUT
			Kennung 	: UDINT;
		END_VAR;
				//! <Function Comment=" ***************************************&#13;&#10;     add a call to the main Programm&#13;&#10; ***************************************&#13;&#10;&#13;&#10; RTCY = 0 cyclic programm&#13;&#10; RTCY = constant realtime  --&gt; realtime programm&#13;&#10;&#13;&#10; MODE Bit 0 = continue&#13;&#10;   Bit 1 = single&#13;&#10;  Bit 4 = block execution   !!!  (important for Analogcards 3 opcodes must be together)&#13;&#10;&#13;&#10;&#13;&#10;" Name="AddCall2Main"/>
	FUNCTION AWL VIRTUAL GLOBAL AddCall2Main
		VAR_INPUT
			Mode 	: UINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 16 Bit read access&#13;&#10;[Globals]  _RTOSVersion   : OS version&#13;&#10;    _lsl_pos    : OS interface structure&#13;&#10;[Members]  &#13;&#10;[Locals]  ui_data   :R/W :intermediate storeage of data&#13;&#10;    di_ret   :R/W :returnvalue of OS&#13;&#10;" Name="Rd16Bit"/>
	FUNCTION VIRTUAL GLOBAL Rd16Bit
		VAR_INPUT
			Adress 	: UDINT;
		END_VAR
		VAR_OUTPUT
			Data 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 8 Bit read access&#13;&#10;[Globals]  _RTOSVersion   : OS version&#13;&#10;    _lsl_pos    : OS interface structure&#13;&#10;[Members]  &#13;&#10;[Locals]  us_data   :R/W :intermediate storage of data&#13;&#10;    di_ret   :R/W :return value of OS function&#13;&#10;" Name="Rd8Bit"/>
	FUNCTION VIRTUAL GLOBAL Rd8Bit
		VAR_INPUT
			Adress 	: UDINT;
		END_VAR
		VAR_OUTPUT
			Data 	: DINT;			//! <Variable Comment="  Data read" Name="Rd8Bit.Data"/>
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 8 Bit write access&#13;&#10;[Globals]  _RTOSVersion  : OS version&#13;&#10;    _lsl_pos   : OS interface structure&#13;&#10;[Members]  &#13;&#10;[Locals]  &#13;&#10;" Name="Wr8Bit"/>
	FUNCTION VIRTUAL GLOBAL Wr8Bit
		VAR_INPUT
			Adress 	: UDINT;			//! <Variable Comment="  Module address and offset" Name="Wr8Bit.Adress"/>
			Data 	: USINT;			//! <Variable Comment="  Data to write" Name="Wr8Bit.Data"/>
		END_VAR
		VAR_OUTPUT
			State 	: DINT;			//! <Variable Comment="  " Name="Wr8Bit.State"/>
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 16 Bit write access&#13;&#10;[Globals]  _RTOSVersion  : OS version&#13;&#10;    _lsl_pos   : OS interface structure&#13;&#10;[Members]  &#13;&#10;[Locals]  &#13;&#10;" Name="Wr16Bit"/>
	FUNCTION VIRTUAL GLOBAL Wr16Bit
		VAR_INPUT
			Adress 	: UDINT;
			Data 	: UINT;
		END_VAR
		VAR_OUTPUT
			State 	: DINT;
		END_VAR;
				//! <Function Comment=" ***************************************&#13;&#10;   put programm into the buffer&#13;&#10; ***************************************&#13;&#10;  this is a 8 bit read&#13;&#10;  the thispointer we need to call the update method&#13;&#10;&#13;&#10;" Name="AddRd8Bit"/>
	FUNCTION AWL VIRTUAL GLOBAL AddRd8Bit
		VAR_INPUT
			Adress 	: HINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetEEState
		VAR_OUTPUT
			State 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL ReadEEData
		VAR_INPUT
			Adress 	: UDINT;
			pData 	: ^USINT;
		END_VAR
		VAR_OUTPUT
			retval 	: DINT;			//! <Variable Comment="  Module ID" Name="ReadEEData.retval"/>
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;0= connected direct to master&#13;&#10;1= connected via CIC&#13;&#10;&#13;&#10;&#13;&#10;-1 = fault&#13;&#10;" Name="GetConnection"/>
	FUNCTION VIRTUAL GLOBAL GetConnection
		VAR_OUTPUT
			CType 	: DINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;read one Byte from C-DIAS bus on Board&#13;&#10;" Name="I2CReadOneByte"/>
	FUNCTION VIRTUAL GLOBAL I2CReadOneByte
		VAR_INPUT
			AdressCDIAS 	: UINT;
			pData 	: ^USINT;
		END_VAR
		VAR_OUTPUT
			result 	: DINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL AddCall2List
		VAR_INPUT
			Mode 	: UINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetMasterType
		VAR_OUTPUT
			MasterType 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetCDiasIosegment
		VAR_OUTPUT
			CIOSegment 	: ^USINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL AddDiasIRQ
		VAR_INPUT
			Place 	: USINT;
			ActionPtr 	: pVoid;
			thisptr 	: pVoid;
		END_VAR
		VAR_OUTPUT
			ok 	: USINT;
		END_VAR;
				//! <Function Comment="[#DEUTSCH]&#13;&#10;" Name="AddCDiasIRQ"/>
	FUNCTION VIRTUAL GLOBAL AddCDiasIRQ
		VAR_INPUT
			irqnr 	: USINT;			//! <Variable Comment="0..IRQ I/O (IRQ PIN C3) | 1..IRQ Comunication (GP2 PIN A10)" Name="AddCDiasIRQ.irqnr"/>
			ActionPtr 	: pVoid;
			thisp 	: pVoid;
		END_VAR
		VAR_OUTPUT
			ok 	: USINT;
		END_VAR;
				//! <Function Comment="&#13;&#10; THR Aug. 21, 2003&#13;&#10;  Added function to add NOPs to the RISC program.  Unlike the&#13;&#10;  WAIT command, a NOP command CANNOT be interrupted by the&#13;&#10;  Cyclic Program.&#13;&#10;  Only for old DiasModuls&#13;&#10;" Name="AddNOP"/>
	FUNCTION AWL VIRTUAL GLOBAL AddNOP
		VAR_INPUT
			RTCY 	: DINT;
			nCount 	: DINT;
		END_VAR;
				//! <Function Comment=" to read the identifier of a modul&#13;&#10;" Name="AddRdKenn"/>
	FUNCTION AWL VIRTUAL GLOBAL AddRdKenn
		VAR_INPUT
			Adress 	: HSINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
				//! <Function Comment=" BS 14.11.2001&#13;&#10; This command is to switch for example a bank back in im routine.&#13;&#10; &#13;&#10;[#ENGLISH]&#13;&#10;" Name="AddMove"/>
	FUNCTION AWL VIRTUAL GLOBAL AddMove
		VAR_INPUT
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
			SourceAddr 	: HDINT := 0;			//! <Variable Comment="only used for move with datamover" Name="AddMove.SourceAddr"/>
			DestAddr 	: HDINT := 0;			//! <Variable Comment="only used for move with datamover" Name="AddMove.DestAddr"/>
			MoveLen 	: UDINT := 0;			//! <Variable Comment="only used for move with datamover" Name="AddMove.MoveLen"/>
			pEnable 	: ^USINT := NIL;			//! <Variable Comment="only used for move with datamover" Name="AddMove.pEnable"/>
			Settings 	: HDINT := 0;			//! <Variable Comment="only used for move with datamover&#13;&#10;&#13;&#10;settings:&#13;&#10; priority         -&gt; VM_PRIORITY_FILTER (VM_PRIORITY_1; VM_PRIORITY_2; VM_PRIORITY_3;)&#13;&#10; add CDIAS-addr   -&gt; 0x01: add to source; 0x02: add to dest; 0x03: add to both;" Name="AddMove.Settings"/>
		END_VAR
		VAR_OUTPUT
			HandleMove 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetCDiasPlaceIoSegment
		VAR_INPUT
			place 	: UDINT;
		END_VAR
		VAR_OUTPUT
			IOSegment 	: ^USINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL AddWaitSync
		VAR_INPUT
			thisp 	: pVoid;
			MaxWaitTime 	: UDINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;" Name="AddIRQScan"/>
	FUNCTION AWL VIRTUAL GLOBAL AddIRQScan
		VAR_INPUT
			Place 	: USINT;
			RTCY 	: DINT;
			thisp 	: ^void;
			callOptions 	: USINT := CALL_OPTION_RT_PRESCAN;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL IRQScan
		VAR_INPUT
			Place 	: UDINT;
		END_VAR
		VAR_OUTPUT
			Data 	: DINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;" Name="GetRtPasses"/>
	FUNCTION VIRTUAL GLOBAL GetRtPasses
		VAR_OUTPUT
			us_rt_passes 	: USINT;			//! <Variable Comment="number of realtime passes before update" Name="GetRtPasses.us_rt_passes"/>
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;For modules with old Pll (update only every ms in µs - Mode)&#13;&#10;" Name="GetUpdateState"/>
	FUNCTION VIRTUAL GLOBAL GetUpdateState
		VAR_OUTPUT
			us_update 	: USINT;			//! <Variable Comment="0=no update, 1=update" Name="GetUpdateState.us_update"/>
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL I2CWriteOneByte
		VAR_INPUT
			AdressCDIAS 	: UINT;
			pData 	: ^USINT;
		END_VAR
		VAR_OUTPUT
			result 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL WriteEEData
		VAR_INPUT
			Adress 	: UDINT;
			pData 	: ^USINT;
			ui_length 	: UINT;
			ui_offset 	: UINT;
		END_VAR
		VAR_OUTPUT
			retval 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetObjectPath
		VAR_INPUT
			p_us_ObjectPath 	: ^USINT;
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SetObjectThisp
		VAR_INPUT
			p_us_ObjectPath 	: ^USINT;
			ud_thisp 	: UDINT;
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetObjectThisp
		VAR_INPUT
			p_us_ObjectPath 	: ^USINT;
		END_VAR
		VAR_OUTPUT
			ud_Thisp 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SetRetryCounterAvailability
		VAR_INPUT
			Port 	: USINT;
			p_State 	: ^IO_State;
			p_RetryCounter 	: ^DINT;
		END_VAR;
	
	FUNCTION VIRTUAL UpdateDIASRetryCounter;
	
	FUNCTION VIRTUAL GLOBAL AddRequiredObject
		VAR_INPUT
			thisp 	: ^void;
		END_VAR;
	
	FUNCTION VIRTUAL CheckforRequiredError;
	
	FUNCTION VIRTUAL GLOBAL SetRequiredError
		VAR_INPUT
			p_this 	: ^HwBase;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL UpdateRtPostScan_IM;
	
	FUNCTION AWL VIRTUAL GLOBAL RtWorkIMCIPC
		VAR_INPUT
			EAX 	: UDINT;
		END_VAR
		VAR_OUTPUT
			state 	: UDINT;			//! <Variable Comment="  0..success" Name="RtWorkIMCIPC.state"/>
		END_VAR;
	
	FUNCTION FinishIMProg;
	
	FUNCTION LastInit;
	
	FUNCTION AWL SendSync;
	
	FUNCTION AWL InitChip;
				//! <Function Comment="[English]&#13;&#10; reads all identification codes &#13;&#10;[Globals]  _RTOSVersion  :R  :OS version&#13;&#10;    _DiasConfig   :R/W :configuration array (filled by OS)&#13;&#10;    _WhoAmI    :R  :CPU identification&#13;&#10;    OPS     :R  :OS variable&#13;&#10;[Members]  FirstModuleFound :W  :determine a place on the bus where a modules is connected&#13;&#10;   (s) Release    :R  :Hardware + Software release&#13;&#10;[Locals]  MyTAbsolute   :R/W :for a fixed time delay&#13;&#10;" Name="ReadAllKenn"/>
	FUNCTION ReadAllKenn;
				//! <Function Comment="[English]&#13;&#10; reads the identification code of one module&#13;&#10;[Globals]  _RTOSVersion  :R  :OS version&#13;&#10;    _lsl_pos   :R  :OS interface structure&#13;&#10;[Members]&#13;&#10;[Locals]&#13;&#10;" Name="ReadKenn"/>
	FUNCTION ReadKenn
		VAR_INPUT
			Place 	: DINT;
		END_VAR
		VAR_OUTPUT
			Kenn 	: DINT;			//! <Variable Comment="  ID code" Name="ReadKenn.Kenn"/>
		END_VAR;
				//! <Function Comment=" /ws004&#13;&#10;[#ENGLISH]&#13;&#10;Diese Funktion prüft ob der Master vorhanden ist und wenn ja trägt Sie&#13;&#10;die HW und Software Kennung in Release ein&#13;&#10;&#13;&#10;IPC: (Hardware and software release)&#13;&#10;Bit 0-15   in Release ist Software Version // #BS016&#13;&#10;Bit 16-31  in Release ist Hardware Version&#13;&#10;&#13;&#10;C-IPC: (only one vlaue for hardware and software release)&#13;&#10;Bit 0-7 &#13;&#10;&#13;&#10;Release = 16#FFFFFFFF ( Fehler Master nicht vorhanden)&#13;&#10;&#13;&#10;&#13;&#10;" Name="TestMasterIM"/>
	FUNCTION AWL TestMasterIM
		VAR_OUTPUT
			MasterOK 	: UINT;
		END_VAR;
				//! <Function Comment="&#13;&#10; --&gt; ebx is this pointer &#13;&#10;     edx is IPSUB&#13;&#10;     ecx is IPMAIN&#13;&#10; --&gt; ax mode reg  bit 0  = RT or Cyclic&#13;&#10;           bit 14 =&#13;&#10;      bit 15 = Main or Sub     &#13;&#10;     edi thispointer&#13;&#10;&#13;&#10; &lt;-- EAX is handle it is a direct pointer to the programm in the master&#13;&#10;&#13;&#10;" Name="GetHandle"/>
	FUNCTION AWL GetHandle
		VAR_INPUT
			Offset 	: UDINT;
			callOptions 	: USINT;
		END_VAR;
	
	FUNCTION AWL GetProgPointer;
				//! <Function Comment="&#13;&#10;&#13;&#10;  --&gt; ax is mode byte (realtime or cyclic)&#13;&#10;  ECX = IP of the Mainprog&#13;&#10;  EDX = IP of the subprog &#13;&#10;" Name="StoreNewPointers"/>
	FUNCTION AWL StoreNewPointers;
				//! <Function Comment=" ****************************************&#13;&#10;   einmal das programm linken &#13;&#10; ****************************************&#13;&#10; the main and the subprogramms are linked together&#13;&#10; also the calls are linked with the absolute adresse  &#13;&#10;" Name="LinkMaster"/>
	FUNCTION AWL LinkMaster;
				//! <Function Comment=" ********************************************************&#13;&#10;  .. load the cyclic programm in to the master&#13;&#10; ********************************************************&#13;&#10;" Name="LoadCyclicProg"/>
	FUNCTION AWL LoadCyclicProg;
	
	FUNCTION AWL StartCyclicProg;
				//! <Function Comment=" ********************************************************&#13;&#10;  .. load the cyclic programm into the master&#13;&#10; ********************************************************&#13;&#10;" Name="LoadRealtimeProg"/>
	FUNCTION LoadRealtimeProg;
	
	FUNCTION AWL StartRealtimeProg;
	
	FUNCTION AWL LoadRtCyCode;
	
	FUNCTION CallUpdata
		VAR_INPUT
			Thisp 	: pHwBase;
			Handle 	: UDINT;
		END_VAR;
	
	FUNCTION CallUpdataRT
		VAR_INPUT
			Thisp 	: pHwBase;
			Handle 	: UDINT;
		END_VAR;
	
	FUNCTION CallUpdataRtPostScan
		VAR_INPUT
			Thisp 	: pHwBase;
			Handle 	: UDINT;
		END_VAR;
	
	FUNCTION AWL VIRTUAL GLOBAL RtWorkStdMas;
	
	FUNCTION AWL VIRTUAL GLOBAL CyWorkStdMas;
	
	FUNCTION AWL VIRTUAL GLOBAL RtWorkStdMasIPC;
	
	FUNCTION WdCDIAS;
	
	FUNCTION WDDIAS;
	
	FUNCTION ErrorLocalSyncTrace;
	
	FUNCTION TraceAsyncError
		VAR_INPUT
			Place 	: UDINT := 255;
		END_VAR;
	
	FUNCTION GetVerIMCIPC
		VAR_OUTPUT
			Ver (EAX) 	: HDINT;
		END_VAR;
	
	FUNCTION GetMuSec
		VAR_OUTPUT
			value (EAX) 	: UDINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;" Name="CheckSyncModules"/>
	FUNCTION AWL CheckSyncModules
		VAR_INPUT
			TimeStampStart 	: UDINT;
		END_VAR
		VAR_OUTPUT
			StateSync 	: UDINT;			//! <Variable Comment="0 = Busy | 1 = Sync | 2 = TimeOut" Name="CheckSyncModules.StateSync"/>
		END_VAR;
	
	FUNCTION CallGetSync
		VAR_INPUT
			thisp (EDI) 	: pHwBase;
		END_VAR
		VAR_OUTPUT
			syncchron (AL) 	: USINT;
		END_VAR;
				//! <Function Comment=" /ws001&#13;&#10;" Name="Risc_Off"/>
	FUNCTION Risc_Off;
				//! <Function Comment="ws004&#13;&#10;[#ENGLISH]&#13;&#10; This function updates the DIAS retry counter (using a function provided by the OS)&#13;&#10; [Globals] _LSL_POS   :R  :OS interface structure&#13;&#10; [Members] oldErrorCounter  :R/W :calculate change&#13;&#10;   (S) DiasRetryCounter :W  :update retry counter&#13;&#10; [Locals]  us_actcount   :R/W :currently read value&#13;&#10;    di_oldcount   :R/W :temporary storeage of the previous value&#13;&#10;" Name="UpdateRetryCounter"/>
	FUNCTION UpdateRetryCounter;
				//! <Function Comment="[#ENGLISH]&#13;&#10;Function for logging Realtime steps at startup&#13;&#10;" Name="LogRtSSW"/>
	FUNCTION LogRtSSW;
				//! <Function Comment="**************************************************************************&#13;&#10;** below this comment block are all hardware access routines which were **&#13;&#10;** replaced by OS calls (from version 5.44 upwards)                     **&#13;&#10;**    ||                                                          ||    **&#13;&#10;**    ||                                                          ||    **&#13;&#10;**   ----                                                        ----   **&#13;&#10;**   \  /                                                        \  /   **&#13;&#10;**    \/                                                          \/    **&#13;&#10;**************************************************************************&#13;&#10; /ws004&#13;&#10;[#ENGLISH]&#13;&#10; This function reads the DIAS ID of a module&#13;&#10; [Globals] _IOSegment   :R  &#13;&#10; [Members] ImOff    :R  :master is off&#13;&#10;    DIAS type   :R  :intelligent &lt;-&gt; standard master&#13;&#10; [Locals]  &#13;&#10;" Name="DM_DIAS_ReadKenn_x"/>
	FUNCTION AWL DM_DIAS_ReadKenn_x
		VAR_INPUT
			Place 	: DINT;
		END_VAR
		VAR_OUTPUT
			retval 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 16 Bit write access&#13;&#10; see Wr16Bit&#13;&#10;" Name="DM_DIAS_WriteWord_x"/>
	FUNCTION AWL DM_DIAS_WriteWord_x
		VAR_INPUT
			Adress 	: UDINT;
			Data 	: UINT;
		END_VAR
		VAR_OUTPUT
			state 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 8 Bit read access&#13;&#10; see Rd8Bit&#13;&#10;" Name="DM_DIAS_ReadByte_x"/>
	FUNCTION AWL DM_DIAS_ReadByte_x
		VAR_INPUT
			Adress 	: UDINT;
		END_VAR
		VAR_OUTPUT
			Data 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 16 Bit read access&#13;&#10; see Rd16Bit&#13;&#10;" Name="DM_DIAS_ReadWord_x"/>
	FUNCTION AWL DM_DIAS_ReadWord_x
		VAR_INPUT
			Adress 	: UDINT;
		END_VAR
		VAR_OUTPUT
			Data 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 8 Bit write access (control area)&#13;&#10; see WrCntr&#13;&#10;" Name="DM_DIAS_WriteCtrl_x"/>
	FUNCTION AWL DM_DIAS_WriteCtrl_x
		VAR_INPUT
			adress 	: DINT;
			Data 	: USINT;
		END_VAR
		VAR_OUTPUT
			state 	: DINT;
		END_VAR;
				//! <Function Comment="[English]&#13;&#10; Does a 8 Bit write access &#13;&#10; see Wr8Bit&#13;&#10;" Name="DM_DIAS_WriteByte_x"/>
	FUNCTION AWL DM_DIAS_WriteByte_x
		VAR_INPUT
			Adress 	: UDINT;
			Data 	: USINT;
		END_VAR
		VAR_OUTPUT
			State 	: DINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;Function gives back the Dias Adress, of the module which&#13;&#10;answer to the global sync.&#13;&#10;" Name="GetSyncModuleNumber"/>
	FUNCTION VIRTUAL GLOBAL GetSyncModuleNumber
		VAR_OUTPUT
			us_ModuleNr 	: USINT;
		END_VAR;
	
	FUNCTION CCLWatchdog_Trigger;
	
	FUNCTION AWL VIRTUAL GLOBAL RtWorkETV
		VAR_INPUT
			EAX 	: UDINT;
		END_VAR
		VAR_OUTPUT
			state 	: UDINT;
		END_VAR;
				//! <Function Comment="[#ENGLISH]&#13;&#10;" Name="IncreaseHwAccessTime"/>
	FUNCTION VIRTUAL GLOBAL IncreaseHwAccessTime
		VAR_INPUT
			ui_value 	: UINT;			//! <Variable Comment="value wich increases access time for ardware access" Name="IncreaseHwAccessTime.ui_value"/>
		END_VAR;
	
	FUNCTION StartPll;
	
	FUNCTION CorrectMyTaskTime;
	
	FUNCTION CallSafetyManager;
	
	FUNCTION AWL DiasIRQCall
		VAR_INPUT
			Station 	: UINT;
			ThisIn 	: ^USINT;
		END_VAR;
	
	FUNCTION WriteRTLogs;
	
	FUNCTION VIRTUAL GLOBAL Control::NewInst
		VAR_INPUT
			pPara 	: ^CmdStruct;
			pResult 	: ^results;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
				//! <Function Comment="ws001&#13;&#10;" Name="Release.Read"/>
	FUNCTION VIRTUAL GLOBAL Release::Read
		VAR_OUTPUT
			output (EAX) 	: HDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL Chipstate::Read
		VAR_OUTPUT
			output (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL RiscState::Read
		VAR_OUTPUT
			output (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL TimeAtRtPreEnd::Read
		VAR_OUTPUT
			output (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL DIASRetryCounter::Read
		VAR_OUTPUT
			output (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL MasterON::Read
		VAR_OUTPUT
			output (EAX) 	: DINT;
		END_VAR;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

#pragma usingLtd _MultiTask
#pragma usingLtd _OSKernel
#pragma usingLtd _StdLib
#pragma usingLtd _TaskObjectControl


//}}LSL_DECLARATION


FUNCTION GLOBAL TAB DiasMasterMain::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_DIASMASTERMAIN
2$UINT, 25$UINT, (SIZEOF(::DiasMasterMain))$UINT, 
10$UINT, 8$UINT, 0$UINT, 
TO_UDINT(3792535737), "DiasMasterMain", //Class
TO_UDINT(2647887450), "DiasMaster", 2$UINT, 33$UINT, //Baseclass
//Servers:
(::DiasMasterMain.Release.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2701327623), "Release", 
(::DiasMasterMain.Chipstate.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3029740863), "Chipstate", 
(::DiasMasterMain.RiscState.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2238433318), "RiscState", 
(::DiasMasterMain.TimeAtRtPreEnd.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3372577840), "TimeAtRtPreEnd", 
(::DiasMasterMain.DIASRetryCounter.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1894626063), "DIASRetryCounter", 
(::DiasMasterMain.MasterON.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1463289926), "MasterON", 
(::DiasMasterMain.Rt_Load.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(917365678), "Rt_Load", 
(::DiasMasterMain.RtTimeIM_us.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(4133277675), "RtTimeIM_us", 
(::DiasMasterMain.CyTimeIM_us.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1826250576), "CyTimeIM_us", 
(::DiasMasterMain.HwControl.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2471641665), "HwControl", 
//Clients:
(::DiasMasterMain.To_TaskObjectControl.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2751224004), "To_TaskObjectControl", TO_UDINT(1584830088), "_TaskObjectControl", 1$UINT, 1$UINT, 
(::DiasMasterMain.WaitSync.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(109293062), "WaitSync", 
(::DiasMasterMain.SyncCall.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(4187542331), "SyncCall", 
(::DiasMasterMain.RtDebug.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(3823771403), "RtDebug", 
(::DiasMasterMain.To_HwControl.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(1012711711), "To_HwControl", 
(::DiasMasterMain.To_Multitask.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2145650779), "To_Multitask", TO_UDINT(2641766936), "_MultiTask", 1$UINT, 1$UINT, 
(::DiasMasterMain.To_StdLib.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2139173287), "To_StdLib", TO_UDINT(3689364044), "_StdLib", 2$UINT, 0$UINT, 
(::DiasMasterMain.To_OSKernel.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2681344549), "To_OSKernel", TO_UDINT(3045737964), "_OSKernel", 0$UINT, 5$UINT, 
END_FUNCTION


#define USER_CNT_DiasMasterMain 71

TYPE
	_LSL_STD_VMETH	: STRUCT
			CmdTable	: CMDMETH;
			UserFcts	: ARRAY[0..USER_CNT_DiasMasterMain] OF ^Void;
	END_STRUCT;
END_TYPE

FUNCTION DiasMasterMain::@STD
	VAR_OUTPUT
		ret_code	: CONFSTATES;
	END_VAR
	VAR
		vmt	: _LSL_STD_VMETH;
		nCmdSize	: UINT;
	END_VAR

	ret_code	:= DiasMaster::@STD();
	IF ret_code <> C_OK THEN
		RETURN;
	END_IF;
	nCmdSize		:= DiasMaster::Control.pMeth^.nCmds$UINT*SIZEOF(pVoid) + CMDMETH.Init;

	_memcpy((#vmt.CmdTable)$^USINT, DiasMaster::Control.pMeth, nCmdSize);
	vmt.CmdTable.nCmds		:= nSTDCMD + USER_CNT_DiasMasterMain;
	vmt.CmdTable.NewInstr		:= #Control::NewInst();
	vmt.CmdTable.Init		:= #Init();
	vmt.CmdTable.CyWork		:= #CyWork();
	vmt.CmdTable.RtWork		:= #RtWork();
#pragma warning (disable : 74)
	vmt.UserFcts[0]		:= #UpdateRtPostScan();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[1]		:= #GetPllTime();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[2]		:= #AddWait();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[3]		:= #WrCntr();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[4]		:= #AddWr8Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[5]		:= #AddWR16Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[6]		:= #AddRTBSync();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[7]		:= #AddRet();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[8]		:= #AddRd32Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[9]		:= #AddRd16Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[10]		:= #GetKennung();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[11]		:= #AddCall2Main();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[12]		:= #Rd16Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[13]		:= #Rd8Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[14]		:= #Wr8Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[15]		:= #Wr16Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[16]		:= #AddRd8Bit();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[17]		:= #GetEEState();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[18]		:= #ReadEEData();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[19]		:= #GetConnection();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[20]		:= #I2CReadOneByte();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[21]		:= #AddCall2List();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[22]		:= #GetMasterType();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[23]		:= #GetCDiasIosegment();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[25]		:= #AddDiasIRQ();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[26]		:= #AddCDiasIRQ();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[27]		:= #AddNOP();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[28]		:= #AddRdKenn();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[29]		:= #AddMove();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[30]		:= #GetCDiasPlaceIoSegment();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[31]		:= #AddWaitSync();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[32]		:= #AddIRQScan();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[33]		:= #IRQScan();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[34]		:= #GetRtPasses();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[35]		:= #GetUpdateState();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[49]		:= #I2CWriteOneByte();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[50]		:= #WriteEEData();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[53]		:= #GetObjectPath();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[54]		:= #SetObjectThisp();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[56]		:= #GetObjectThisp();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[57]		:= #SetRetryCounterAvailability();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[58]		:= #UpdateDIASRetryCounter();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[59]		:= #AddRequiredObject();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[60]		:= #CheckforRequiredError();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[61]		:= #SetRequiredError();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[63]		:= #UpdateRtPostScan_IM();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[64]		:= #RtWorkIMCIPC();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[65]		:= #RtWorkStdMas();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[66]		:= #CyWorkStdMas();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[67]		:= #RtWorkStdMasIPC();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[68]		:= #GetSyncModuleNumber();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[69]		:= #RtWorkETV();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[70]		:= #IncreaseHwAccessTime();

#pragma warning (default : 74)
	DiasMaster::Control.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF DiasMaster::Control.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	Release.pMeth			:= StoreMethod( #Release::Read(), #M_NO_F() );
	IF Release.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	Chipstate.pMeth			:= StoreMethod( #Chipstate::Read(), #M_NO_F() );
	IF Chipstate.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	RiscState.pMeth			:= StoreMethod( #RiscState::Read(), #M_NO_F() );
	IF RiscState.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	TimeAtRtPreEnd.pMeth			:= StoreMethod( #TimeAtRtPreEnd::Read(), #M_NO_F() );
	IF TimeAtRtPreEnd.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	DIASRetryCounter.pMeth			:= StoreMethod( #DIASRetryCounter::Read(), #M_NO_F() );
	IF DIASRetryCounter.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	MasterON.pMeth			:= StoreMethod( #MasterON::Read(), #M_WR_DIRECT() );
	IF MasterON.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ret_code	:= DiasMasterMain();

END_FUNCTION

#pragma usingLtd HwBase

//{{LSL_IMPLEMENTATION
#pragma using HwBase


(************************************************************************************************
*	MasterController
*	Created	: Sigmatek / 2003
*	Changes :
*
*
*   FOR NEWER CHANGES SEE REVISION DOCUMENTATION IN CLASS PROPERTIES
*
*
*		1.59 => 1.60    /   21.03.2008  /   Mark:   //#UL001
*			- [DB 817]: take over RtDebug-flag from HW-Control
*		1.58 => 1.59	/	20.08.2007	/	Mark:	//#SR022
*			- [DB 718]: Pll now starts correct with Rt-Time > 2 with ETV
*		1.57 => 1.58	/	20.08.2007	/	Mark:	//#SR021
*			- [DB 586]: add Rt - IM time if CIC with repeater is used
*		1.56 => 1.57	/	16.05.2007	/	Mark:	//#SR020
*			- [DB 640]: only update connected cyclic classes if realtime is ready
*		1.55 => 1.56	/	16.05.2007	/	Mark:	//#SR019
*			- [DB 568]: interrogation if _IOSegment is 0 in RtWorkStdMeth (for CCL081)
*		1.54 => 1.55	/	16.03.2007	/	Mark:	//#SR018
*			- [DB 528]: insert functions to write to cdias eeprom
*		1.53 => 1.54	/	15.02.2007	/	Mark:	//#SR017
*			Bug in Sync - Methode, only necessary for us - Mode
*			Error messages for TimSlice overrun are not indicated 
*			Bug in IRQScan - function and Async Channels are now initialized with Ready and Error Bit
*		1.52 => 1.53	/	14.11.2006	/ 	Mark:	//#SR016
*			make compatible to ETV
*		1.51 => 1.52	/	14.11.2006	/ 	Mark:	//ws008
*			ops.tAbsolute calculations corrected
*		1.50 => 1.51	/	04.10.2006	/	Mark:	//#SR015
*			set realtime startpoint before sending syncs
*		1.49 => 1.50	/	09.08.2006	/	Mark: 	//ws007
*			No semaphor-protected async. Dias access for standard master
*		1.48 => 1.49	/	14.06.2006	/	no Mark	//SR
*			insert headerfile "lsl_STITask.h" to have no redefinition
*		1.47 => 1.48	/	30.05.2006	/	Mark: 	//ws006
*			protect async acces with a semaphore
*		1.46 => 1.47	/	23.02.2006	/	Mark:	//#SR014
*			make compatible to HwControl class
*		1.45 => 1.46	/	10.02.2006	/	Mark:	//#SR013
*			delete #define DiasMaster200us and make compatible to Xilinx 2.1 (µs-Version in Lasal2)
*		1.44 => 1.45	/	16.01.2006	/	Mark:	//#SR012
*			Function to identify sync - module does not work when DiasMaster is placed after hardwareclass in ONE
*		1.43 => 1.44	/	12.01.2006	/	Mark:	//#SR011
*			Insert function to debug in Rt-task but hardware is still running (Rt-Task of DiasMaster sill runs)
*		1.42 => 1.43	/	22.12.2005	/	Mark:	//#SR010
*			Interrogation if realtime program of intelligent master overlap realtime of DiasMaster -> not allowed
*		1.41 => 1.42	/	22.11.2005	/	Mark:	//#SR009
*			Bug in Function AddNop (eax register was false before call GetProgPointer)
*			Replace Objectchannel to old System class to _TaskObjectControl class
*			Insert server which shows the usage rate of Intelligent master Rt - program
*			Start Cyclic program of intelligent master only if we have one (save time)
*		1.40 => 1.41 / 04.11.2005 / Mark: //ws006
*			object names of trace messages are now ascertained by the loader
*		1.39 => 1.40	/	24.10.2005	/	Mark:	//#SR008
*			Add Function to find out which module answer to the global sync
*			Insert Logging function (Log in event00.log)
*		1.38 => 1.39	/ 	24.10.2005	/	Mark:	//ws005
*			use OS functions wherever possible
*		1.37 => 1.38	/	30.09.2005	/	Mark:	//ws004
*			Support ETT321 and ET261
*		1.36 => 1.37	/	30.08.2005	/	Mark:	//#SR007
*			Add some time measurements ( activate with define DMC_Profiler) 
*		1.35 => 1.36	/ 	07.06.2005	/	Mark:	//ws003
*			replacement of pointer offsets with data structures
*		1.34 => 1.35	/	31.05.2005	/	Mark:	//#SR006
*			add Methods IRQScan and AddIRQScan for intelligent master
*		1.33 => 1.34 / 21.04.2005 / Mark: //ws002	//#SR005
*			added read() methods to server channels which are connected to base classes.
*			Reason: LSE cannot read the value of these servers without this method (SA5320)
*			Control state of Risc in cyclic and give out a Trace if Risc is off				//#SR005
*			insert a Pointer for specific module retry counters								//#SR005
*		1.32 => 1.33	/	31.03.2005	/	Mark:	//#SR004
*			added some Error questioning for intelligent Master program
*			splitt IM - Memory half for realtime and half for cyclic (old was: cyclic 1/4 and realtime 3/4) 
*		1.31 => 1.32	/	22.03.2005	/	Mark:	//#SR003
*			make compatible to 200us CIPC (have to activate #define DiasMaster200us in MasterSettings.h)
*		1.30 => 1.31	/	08.05.2005	/	Mark:	//#SR002
*			make compatible with CCL081
*		1.29 => 1.30	/ 	21.01.2005	/	Mark:	// ws001
*			Do not use #define TEMPMAX anymore, use the respective clients at the modules instead!
*		1.28 => 1.29	/	11.01.2005	/	Mark:	//#SR001
*			Change Time calculation and starttime of Intelligent Master Programm
*		0.28 => 1.28 / 23.12.2004 / no Mark / ws
*			compatibility with Lasal Class 2
*			removed visible flags from internal servers
*		0.27 => 0.28	/	26.11.2004	/	Mark:	//#SR000
*			Make correction because ecx register wasn't set rigth in Function AddCall2List
*		0.26 => 0.27 / 18.10.2004 / Mark: // #BS016
*			Now there is a define to set the watchdogtime to max (DiasMasterC\MasterSettings.h "define MaxWatchdog")
*			The retrycounter didn't work correct
*			There is no hardwarerelease it's an ID
*			Now the DiasMaster also works with Lasal 57f
*		0.25 => 0.26 / 22.09.2004 / Mark: // #BS015
*			Bug in synchronizing the Modules with there own Maxtime
*		0.24 => 0.25 / 22.09.2004 / Mark: // #BS014
*			Now for synchronizing the Modules the Moduls own Maxtime is checked and not the Maximumtime from every Modul
*		0.23 => 0.24 / 12.08.2004 / Mark: // #BS013
*			Made a longer timeout on asynchron methods
*		0.22 => 0.23 / 26.07.2004 / Mark: // #BS012
*			First have to be asked if ready and then the timeout (could be a problem with CIPC and BIOS setting USB legacy = Enabled)
*			Changes in function ReadKenn,Wr8Bit,Wr16Bit,Rd8Bit,Rd16Bit and WrCntr
*			Also optimized the code
*			There was a com error with a CCL081
*		0.21 => 0.22 / 01.06.2004 / Mark: // #BS011
*			Now you can select with client "WaitSync" = 1 (as initvalue) to wait for all modules for synchron mode
*		0.20 => 0.21 / 28.04.2004 / Mark: // #BS010
*			Now there is a trace message if the interrupt list of dias is full
*		0.19 => 0.20 / 01.04.2004 / Mark: // #BS009
*			Added a timeout in ReadKenn() (Hang up if no DiasModul is connected)
*		0.18 => 0.19 / 23.03.2004 / Mark: // #BS008
*			Synctime an CDIAS of CIPC bus was written wrong
*		0.17 => 0.18 / 05.02.2004 / Mark: // #BS007
*			1. Added a delay time of 150ms to skip dias error 63
*			2. corrected dias retry counter
*		0.16 => 0.17
*			Added function GetPlaceIOSegment()
*		0.15 => 0.16 / 02.12.2003 / Mark: // #BS006
*			The Plltime on IM was written wrong
*		0.14 => 0.15 / 13.11.2003
*			Mark: #BS003
*			Now correct triggering of watchdog for CCL721 and retrycounter for all non intelligent masters
*			Mark: #BS004
*			Added function AddMove
*			Mark: #BS005
*			Added a waittime of 5ms => DiasError 16#3F on first ReadKenn
*		0.13 => 0.14 / 06.11.2003 / Mark: #BS002
*			Changes in triggering watchdog on CIPC
*		0.12 => 0.13 / 30.10.2003 / Mark: #BS001
*			A trace message is given out if a dias irq is installed with IM
*			=> no IRQs on IM
*
*		0.11 => 0.12 / 27.10.2003 / Mark: #BS000
*			If a Watchdog on CDIASBus occurs a tracemessage is given out (only CIPC).
*
*  			14.10.2003 Franz Aschl
*			Ab OS version 5.42 wird unser Task egal wo er plaziert ist ganz nach oben geschoben
*			und dieser Bereits im letzen Schritt vom Init gestartet. Wenn der Master mit dem
*			Code geladen ist.
*
*			1. Es wird solange im Init gewartet bis der I-Master synchron ist 
*			2. Es wird das PA für die Echzeit bzw. für die Cyclic einmal aufgerufen
*			   um sicher zu stellen, das beim start der RT und CY alle I/O bereits eingetragen 
*			   sind.
*	 
*			Damit Lasal das alte bleiben kann weil sonst der Master nicht mehr geht
*			ohne neu Lasal Install (und das wollen wir den Kuden nicht antun)
*			machen wir die pointer in die LasalOS Structur selber (steht später auch in der
*			Rtos_interfaces.h aber erst später)
*
* 			pr: V5.43
*************************************************************************************************)

//**********************************************
//** Global variables                         **
//**********************************************

//#WP001 start - defined MasterSettings.h - may2010
#ifdef DiasMasterC_Profiler
  #pragma message ("Time measurement in Diasmaster is active")
  VAR_GLOBAL
    DMC_Time_CY	      	: s_PROFILER_Time;
    DMC_Time_RT		      : s_PROFILER_Time;
  END_VAR
#endif
//#WP001 end


FUNCTION __cdecl ops_cpuequipment_get
  VAR_OUTPUT 
    retcode : UDINT;
  END_VAR
  VAR
    ptr : ^UDINT;
  END_VAR
  
  // we take the offset from _RealMaximumTime because an define for the right address would make troubles
  ptr := #_RealMaximumTime;
  ptr += 16#F44;
  retcode := ptr^;
  
END_FUNCTION

FUNCTION __cdecl ops_platform_get
  VAR_OUTPUT
    retcode : UDINT;
  END_VAR
  
  retcode := ops_cpuequipment_get() AND DIASMASTERC_PLATFORMMASK;
  
END_FUNCTION

FUNCTION __cdecl ops_is_linux
  VAR_OUTPUT
    retcode : UDINT;
  END_VAR
  
  retcode := (ops_cpuequipment_get() AND (DIASMASTERC_OS_LINUX OR DIASMASTERC_EQUIPMENT_VALID)) = (DIASMASTERC_OS_LINUX OR DIASMASTERC_EQUIPMENT_VALID);

END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::Init
  VAR
    ptr		            : ^USINT;
    i		              : UDINT;				//#SR014
    sd_system_period	: DINT;			//#SR016
    sd_dias_time		  : DINT;			//#SR016
  END_VAR

//#wp001
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
    DMC_Time_CY.sum 	:= 0;
    DMC_Time_CY.run 	:= 0;
    DMC_Time_CY._max 	:= 0;
    DMC_Time_CY._min 	:= 16#ffffffff;
    DMC_Time_CY.init  := OS_readmicrosec();
    DMC_Time_RT.sum 	:= 0;
    DMC_Time_RT.run 	:= 0;
    DMC_Time_RT._max 	:= 0;
    DMC_Time_RT._min 	:= 16#ffffffff;
    DMC_Time_RT.init  := OS_readmicrosec();
#endif
//-------------------------------------Profiler End------------------------------------------------
  

  //init pointers
  p_port           := #s_RetryCounter.RetryCounter[0].Place;
  p_State          := (#s_RetryCounter.RetryCounter[0].p_State)$^UDINT;
  p_RetryCounter   := (#s_RetryCounter.RetryCounter[0].p_RetryCounter)$^UDINT;
  p_OldRetryCounter:= #OldRetryCounters[0];


  WaitSync := WaitSync.Read(); // #BS011

  if ( FirstScan = 0 ) then
    b_IsPostInitDone := TRUE; // Default no Postinit => auto done
    
    RtSSW :=0;				// start with wait for sync

    // if we have no pll, we don't need to initialize it
    if ( p_NewPll = NIL ) then
      b_PllInit := true; // we pretend, that we already initialized it
    end_if; 
    
    //#SR014 start
    if ( IsClientConnected( #To_HwControl ) ) then
      
      //look which rt methode do we have
      if ( DiasType = 2 ) then

        //Semaphore for async calls	//ws006
        p_SemaHandle := To_Multitask.CreateSemaphore( MTSEMATYPE_RESOURCE, 1, 0, "DM_ASYNC_SEMA" );
        if( p_SemaHandle = NIL )then
          MasterOn := 0;
          ImOff := 1;
#ifdef HWC_LogError
          HWC_LogError(this, "@0550 (DiasMasterMain::Init) Unable to create semaphore for async access!");
#else
					if p_KernelLog <> NIL then
						OS_KernelLog0( "DiasMaster: Unable to create semaphore for async access!" );
					end_if;
					TRACE( "DiasMaster: Unable to create semaphore for async access!");
#endif
        end_if;

        if ( CDiasType = 2 ) then		  			
          s_FunctionList.p_RtFunction := #RtWorkIMCIPC();		//CIPC,CCL911
          CorrectMyTaskTime();
        else
          s_FunctionList.p_RtFunction := #RtWork();			//IPC with IM
        end_if;

        //#SR016 start
        if ( p_NewPll <> NIL ) then
          s_FunctionList.p_RtFunction := #RtWorkETV();
        end_if;
        //#SR016 end
        
        s_FunctionList.p_RtPostScanFunction := #UpdateRtPostScan_IM(); //BLEERN 002
           
      else

        //No intelligent Master

        if ( _IOSegment <> 16#d0000 ) then	
          s_FunctionList.p_RtFunction :=#RtWorkStdMas();		//CCL721,CCL081,DCL....
        else		  		
          s_FunctionList.p_RtFunction :=#RtWorkStdMasIPC();	//IPC
        end_if;

        s_FunctionList.p_RtPostScanFunction := #UpdateRtPostScan(); //BLEERN 002

      end_if;
    
      s_FunctionList.p_SendSync 		:= #SendSync();
      s_FunctionList.p_FinishIMProg 	:= #FinishIMProg();
      s_FunctionList.p_LastInit 		:= #LastInit();
      s_FunctionList.p_This	 		:= this;
      s_FunctionList.sd_Plltime	 	:= GetPllTime(); 
      
      if ( ui_ClockTicks >= 1000 ) then
        s_FunctionList.sd_DiasTime		:= sd_PllTimeGlob_us;
      else
        s_FunctionList.sd_DiasTime		:= ui_ClockTicks;
      end_if;

      SafetyManagerThis := NIL;
      s_FunctionList.SafetyManagerThisPointer := #SafetyManagerThis;

      if ( To_HwControl.write( ( #s_FunctionList )$DINT ) <> 0 ) then
        MasterOn := 0;
        ImOff := 1;
        
#ifdef HWC_LogError
        HWC_LogError(this, "@0001 (DiasMasterMain::Init) Client 'To_HwControl' has to be connected to Server 'DiasMaster' of class HwControl");
#else
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Client 'To_HwControl' has to be connected to Server 'DiasMaster' of class HwControl" );
				end_if;
				TRACE( "DiasMaster: Client 'To_HwControl' has to be connected to Server 'DiasMaster' of class HwControl");
#endif

      else
        HwControl := 1;
        
        b_IsPostInitDone := FALSE;  // Postinit done ist set by HW-Control
      end_if;
    end_if;
    //#SR014 end

    IF DiasType = 2 THEN // #BS006

      //Semaphore for async calls	//ws006
      if( p_SemaHandle = NIL )then
        p_SemaHandle := To_Multitask.CreateSemaphore( MTSEMATYPE_RESOURCE, 1, 0, "DM_ASYNC_SEMA" );
      end_if;
      
      if( p_SemaHandle = NIL )then
        MasterOn := 0;
        ImOff := 1;
#ifdef HWC_LogError
        HWC_LogError(this, "@0550 (DiasMasterMain::Init) Unable to create semaphore for async access!");
#else
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Unable to create semaphore for async access!" );
				end_if;
				TRACE( "DiasMaster: Unable to create semaphore for async access!");
#endif
      end_if;

      ptr$UDINT := _IOsegment$UDINT + DmPllPeriode;
      ptr^ := GetPllTime()$USINT;
      //Set Realtime Intervall in 25µs units
    
      //#SR003 Start
      RtInterval := GetPllTime() * 1000 / ( DmTmrResso * us_RtPasses );	//#SR001 	//#SR013

    END_IF; // #BS006

#ifdef HWC_LogValue2
    HWC_LogValue2(this, "@050A (DiasMasterMain::Init) DiasType = {0}, CdiasType = {1}", DiasType, CDiasType);
#else
		//#SR008 start
		if p_KernelLog <> NIL then
			OS_KernelLog2( "DiasMaster: DiasType = %d, CdiasType = %d", DiasType$DINT, CDiasType );
		end_if;
		//#SR008 end
#endif

    IF CDiasType = 2 THEN // #BS008			
      if ( CDIASSync <> NIL ) then				//#SR016
        (CDIASSync+1)^ := GetPllTime()$USINT;
      end_if;										//#SR016
    ELSIF CDiasType = 1 & GetPllTime() <> 2 THEN
      TRACE("RtWork of Class 'DiasMasterC' has to be set to 2 ms to ensure a correct functionality of CDIAS modules and CDIAS bus !!");
      // The cdias sync on ccl runs with the time of rttask => depending on hardware
    END_IF; // #BS008

    //#SR016 start
    //look if we have a new pll
    if ( p_NewPll <> NIL ) then

      //get system time
      sd_system_period := p_NewPll^.sd_SystemPeriod;

      if ( ui_ClockTicks < 1000 ) then
        sd_dias_time := ui_ClockTicks;
      else	
        sd_dias_time := sd_PllTimeGlob_us;
      end_if;
      
      //look if we have a multiple
      if ( ( sd_dias_time mod ( sd_system_period / 100 ) ) = 0 ) then

        //get right sync pointer for cdias and dias
        for i := 0 to DmMaxSyncs - 1 do
      
          //look for right cdias pointer
          if ( p_NewPll^.a_SyncOut[ i ].us_SyncOutID = 16#80 ) then
        
            //enable sync out
            p_NewPll^.a_SyncOut[ i ].us_PeriodMultiplier := TO_USINT( sd_PllTimeGlob_us / ( sd_system_period / 100 ) );
//#SR022    p_NewPll^.a_SyncOut[ i ].us_Control.SyncOut	:= TRUE;
            p_CDIAS := #p_NewPll^.a_SyncOut[ i ];					//#SR022
          end_if;

          //look for right dias pointer
          if ( p_NewPll^.a_SyncOut[ i ].us_SyncOutID = 16#81 ) then

            //enable sync out
            p_NewPll^.a_SyncOut[ i ].us_PeriodMultiplier := TO_USINT( sd_PllTimeGlob_us / ( sd_system_period / 100 ) );
//#SR022    p_NewPll^.a_SyncOut[ i ].us_Control.SyncOut := TRUE;
            p_DIAS := #p_NewPll^.a_SyncOut[ i ];				//#SR022
          end_if;
        end_for;

      else
        MasterOn := 0;
        ImOff := 1;
#ifdef HWC_LogValue2
        HWC_LogValue2(this, "@055A (DiasMasterMain::Init) Wrong DiasMaster Time for new Pll! SystemPeriod: {0}, DiasMasterTime: {1}", sd_system_period$UDINT, sd_dias_time$UDINT);
#else
				if p_KernelLog <> NIL then
					OS_KernelLog2( "DiasMaster: Wrong DiasMaster Time for new Pll! SystemPeriod: %d, DiasMasterTime: %d", sd_system_period, sd_dias_time );
				end_if;
				TRACE( "DiasMaster: Wrong DiasMaster Time for new Pll!");
#endif
      end_if;
    
    end_if;
    //#SR016 end
      
  //#SR014 start
  elsif Firstscan = 1 then

    if ( HwControl ) then
      
      //set off task time of DiasMaster
      To_TaskObjectControl.ChangeObjectState( thispointer := this, actioncmd := 2, tasktype := OBJ_RT, debugobj := 0, newtime := 0 );
      //#UL001 start 
      //RtDebug := 0;
      //take over RtDebug-flag from HwControl
      RtDebug := s_FunctionList.sd_RtDebug;
      //#UL001 end
    else
    
      //#SR011 start
      if OS_CILGet( "DEBUGAPI", #p_DebugAPI ) = SYS_ERR_NONE then
        RtDebug := RtDebug.read();
        if RtDebug then
          SaveThisPointer( this, 0 );
        else
          SaveThisPointer( NIL, 0 );
        end_if;
      end_if;
      //#SR011 end
    end_if;
  end_if;
  //#SR014 end

// *********************************************************************
// test if this is the last call of the INIT 
// then firstscan is for one cycle TRUE (for the rest it is false)
// *********************************************************************

//	( ( _IOSegment + DmCmdBuf1 )$^USINT )^ := 0;
   
  //#SR014 start
  IF 	( _FirstScan 	= TRUE 
    & HwControl 	= 0 
    )
  then
   
    FinishIMProg();
    LastInit();				
  END_IF;
  //#SR014 end

  timestamp$UDINT := ops.tAbsolute - 200;
  FirstScan += 1;			//#SR014

  //in 11th init run check for required error
  if FirstScan = 11 then
    CheckforRequiredError();
  end_if;


END_FUNCTION //VIRTUAL GLOBAL DiasMasterMain::Init
//[#ENGLISH]
// ***************************************************************
//   This Function is Called by PostScan from DiasMasterPostScan
// ***************************************************************
#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::CyWork
VAR_INPUT
	EAX		  : UDINT;
END_VAR
VAR_OUTPUT
	state		: UDINT;
END_VAR
VAR
  ActErrorCount : USINT;
  pHandle       : ^OneHandle;
  TempState     : USINT;
  i             : UDINT;
//#wp001
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  MuSecTime : UDINT;
END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_CY.init > DM_ProfilerDelay then
    DMC_Time_CY.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_CY.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_CY.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
END_VAR
#endif

  WriteRTLogs();
  
  if (ImOff = FALSE) & (Release <> 16#FFFFFFFF) then
    // refresh dias retry counter
    UpdateDIASRetryCounter();

    ActErrorCount := (_IOSEGMENT$^USINT + DmErrorCnt)^;
    DIASRetryCounter += to_dint(ActErrorCount) - oldErrorCounter;
    oldErrorCounter  := to_dint(ActErrorCount);

    Chipstate := to_dint((_IOSEGMENT$^USINT + DmError)^);   //DmError
    RiscState := to_dint((_IOSEGMENT$^USINT + DmState)^);
  
// **************************************************
//   first wait if RTssw >= 4
// **************************************************
    if RtSSW >= 4 then
// **************************************************
//  first test if the master is ready with the main
// **************************************************
      if ((_IOSEGMENT$^USINT + DmControl)^ AND 2#11) = 2#11 then
        // check if cyclic ready
        if (RiscState AND 16#10) = 0 then
          CyclicReady := TRUE;
          
        	//#SR020 start
          // now take data and call update function with thisp 
        	// only if realtime is ready and
          // //#SR009 we must not start cyclic IM if we have none
          if RealtimeReady & HandleNrCy then
            pHandle := #HandlesCY[0];
            for i := 0 to HandleNrCy-1 do
              if pHandle^.Typ AND DmCallProg then
                pHandle^.thisp^.UpdateCy(pHandle^.Address);
              end_if;
              
              pHandle += sizeof(OneHandle);
            end_for;

            // if we have something in IM, try 100 times to start it
            if IPMainCY <> 1 then
              i := 100;
              TempState := (_IOSegment$^USINT + DmState)^ OR 16#10;
              while i & ((_IOSegment$^USINT + DmState)^ <> TempState) do
              
                (_IOSegment$^USINT + DmState)^ := TempState;
              
                i -= 1;
              end_while;
            end_if;
          end_if;
        end_if;
      else
        Risc_Off();
      end_if;
    end_if;
  end_if;

  // look if we got the pointer to the safety manager
  if SafetyManagerThis then
    // call safety manager  
    SafetyManagerThis^.CyWork(0);
  end_if;

  state := READY;
  
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_CY.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_CY.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_CY.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_CY.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_CY.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_CY.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_CY._min then
      DMC_Time_CY._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_CY._max then
      DMC_Time_CY._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_CY.avg := DMC_Time_CY.sum * 100 / DMC_Time_CY.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
END_FUNCTION //VIRTUAL GLOBAL DiasMasterMain::CyWork

#else
 //VIRTUAL GLOBAL DiasMasterMain::CyWork


FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::CyWork
	VAR_INPUT
		EAX 	      : UDINT;
	END_VAR
	VAR_OUTPUT
		state (EAX) : UDINT;
	END_VAR

//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_CY.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_CY.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_CY.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_CY.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	
//============================ Profiler end========================================================

  call      WriteRTLogs

	CMP.B		  ImOff,1
	JE			  CyNotReady	

	cmp.d		  release,16#FFFFFFFF
	je			  CyNotReady				// #fa 080103

  call      UpdateDIASRetryCounter

	L.EDI		  _IOSEGMENT

	Lzxb.eax	(EDI+DmErrorCnt)
	l.ebx		  oldErrorCounter
	s.eax		  oldErrorCounter
	sub.al		bl
	lzxb.eax	al

	add.d		  DIASRetryCounter,eax	

	LZXB.EBX	(EDI+DmError) //DmError
	s.EBX		  chipState

	Lzxb.ebx	(EDI+DmState)
	s.ebx		  riscstate	
			
// **************************************************
//   first wait if RTssw >= 4
// **************************************************

	cmp.b		  rtssw,4			//ws005
	jb			  CyNotReady
	
// **************************************************
//  first test if the master is ready with the main
// **************************************************

	//#SR005 Start
	l.al		  (EDI+DmControl)
	and.al		16#3
	cmp.al		16#3
	je			  LABEL_RISC_ON
	call		  Risc_Off
	jmp			  CyNotReady
	
LABEL_RISC_ON
 	test.bl   16#10
	jnz			  CyNotReady  // --> no we have to wait

	l.b			  CyclicReady,1	//ws005

// **************************************************
//  now take data and call update function with thisp 
// **************************************************

	//#SR020 start
	//only update cyclic calls if realtime is ready
	cmp.b		  RealtimeReady, 1
	jne			  CyNotReady
	//#SR020 end	

	lzxw.ecx	HandleNrCy
	jecxz		  CyNotReady					//NoCyclProg	//#SR009 we must not start cyclic IM if we have none
	l.ebx		  #HandlesCY

HandleLoop
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandle

	push		  ecx
	push		  ebx

	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax
	call		  CallUpdata
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandle	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoop
	l.edi		  _IOSegment  //ws005

	//#SR009 start				we must not start it if we have no cyclic prog of IM
	cmp.d		  IPMainCY,1
	je			  CyNotReady
	//#SR009 end

	l.ecx		  100					// we try 100 times
	L.al		  (EDI+DmState)		// start again 
	o.al		  16#10
  
WriteDmState
	s.al		  (EDI+DmState)
	cmp.al		(EDI+DmState)
	loopne		WriteDmState		//ws005: replaced a dec and a jnz
	//-
CyNotReady
	l.d			  state,READY
  
  // look if we got the pointer to the safety manager
  cmp.d     SafetyManagerThis, 0
  je        NoLocalSafety

  // call safety manager  
  CALL      CallSafetyManager
  
NoLocalSafety

//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_CY.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_CY.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_CY.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_CY.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_CY.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_CY.sum					//Summe speichern
	l.ecx		  DMC_Time_CY.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_CY.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_CY._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_CY._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_CY._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_CY._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_CY.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION //VIRTUAL GLOBAL DiasMasterMain::CyWork
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::RtWork
	VAR_INPUT
		EAX 	: UDINT;
	END_VAR
	VAR_OUTPUT
		state : UDINT;
	END_VAR
  VAR
    Temp      : DINT;
    pHandle   : ^OneHandle;
    i         : UDINT;
  //-------------------------------------Profiler Start----------------------------------------------
  #ifdef DiasMasterC_Profiler
    MuSecTime : UDINT;
  END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_RT.init > DM_ProfilerDelay then
    DMC_Time_RT.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_RT.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_RT.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
  END_VAR
#endif

  if (ImOff = FALSE) then
    if HwControl = 0 then
      SendSync();
    end_if;
    
    if ops.SysState = C_RUNRAM then
      //look if Rt program of IM is finished
      if (_IOSegment$^USINT + DmUserData + 3)^ then
        ud_ErrorCountTimeSliceEnd += 1;
        if us_FirstTimeSliceEnd = 0 then
          us_FirstTimeSliceEnd := 1;
        end_if;
      end_if;
      
      //Reset Byte to find out if Rt of IM starts while Rt of DM is running
      (_IOSegment$^USINT + DmUserData + 4)^ := 0;
      
      case RtSSW of
      
          // ***********************************************************
          //   we have to wait that the PLL is locked before we start
          // ***********************************************************
        0:

          if Release <> 16#FFFFFFFF then
            if ((_IOSegment$^USINT + DmPllSyncState)^ AND DmPLLisLock) = DmPLLisLock then
              StartRealtimeProg();
              RtSSW += 1;
              LogRtSSW();
            end_if;
            
            // Start it always to keep the moduls alive 
            (_IOSegment$^USINT + DmState)^ := (_IOSegment$^USINT + DmState)^ OR 16#10;
            
            (_IOSegment$^USINT + DMWDRegister)^ := 1;
            (_IOSegment$^USINT + DMWDTriggerMode)^ := 1;
            (_IOSegment$^USINT + DMWDRegister)^ := 0;
          end_if;


          // **********************************************************
          //  now we are starting the RTProg 
          // **********************************************************
        1:

          StartRealtimeProg();
          RtSSW += 1;
          LogRtSSW();


          // ****************************************************************
          //  now we have to move the startpoint till we are 50usec before
          // ****************************************************************
        2:

          Temp := RtInterval - (ud_DelayRealtime / (DmTmrResso * 1000))$DINT - (_IOSegment$^USINT + DmPllSyncDel)^ - DmTimeReserveIM;
          (_IOSegment$^USINT + DmPllSyncDel)^ := Temp$USINT;
          ui_RtStartPoint := Temp$UINT * DmTmrResso;
          RtSSW += 1;
          LogRtSSW();
          
          
          // ***********************************************************
          //   read the calculated time 
          // ***********************************************************
        3:

          TimeBeforeNextSync := to_uint((_IOSegment$^USINT + DmUserData)^);
          RtSSW += 1;
          LogRtSSW();


          // ***************************************************************
          //   do the refresh of I/O 
          // ***************************************************************
        4:
          
          // get rtload of im
          TimeAtRtPreEnd := (_IOSegment$^USINT + DmUserData)^ * DmTmrResso;          
          Rt_Load := ((TimeAtRtPreEnd - ui_RtStartPoint) * 1000) / sd_PllTimeGlob_us;

          RealtimeReady := TRUE;
          
          // call update methods with thispointer
          if HandleNrRT then
            pHandle := #HandlesRT[0];
            for i := 0 to HandleNrRT-1 do
              if pHandle^.Typ AND DmCallProg then
                pHandle^.thisp^.UpdateRt(pHandle^.Address);
              end_if;
              
              pHandle += sizeof(OneHandle);
            end_for;

            if HwControl = 0 then
              UpdateRtPostScan_IM();
            end_if;
          end_if;
      end_case;
    end_if;
    
    WDDIAS();
  end_if;

  state := READY;
  
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_RT.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_RT.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_RT.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_RT.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_RT.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_RT.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_RT._min then
      DMC_Time_RT._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_RT._max then
      DMC_Time_RT._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_RT.avg := DMC_Time_RT.sum * 100 / DMC_Time_RT.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
END_FUNCTION
#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::RtWork
  VAR_INPUT
    EAX		: UDINT;
  END_VAR
  VAR_OUTPUT
    state	: UDINT;
  END_VAR

//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		edi
	push 		eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		eax
	sub.ebx		DMC_Time_RT.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			LABEL_DMCPREEND
	s.eax 		DMC_Time_RT.start					//Startzeit nehmen
	x.cl		cl							
	s.cl		DMC_Time_RT.initfl				//Initflag löschen
	jmp 		LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		DMC_Time_RT.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		eax
	pop 		edi
#endif	
//============================ Profiler end========================================================

	CMP.B		  ImOff,1
	JE			  RT_End1

	//#SR014 start
	cmp.d			HwControl, 1
	je				LABEL_EndPllSync

	call			SendSync

LABEL_EndPllSync
	l.edi			_IOSegment
	//#SR014 end

	//#SR010 start
	cmp.w			ops.SysState,1					//look if CPU is in RunRam
	jne				LABEL_Continue

	l.bl			( edi + DmUserData + 3 )		//look if Rt program of IM is finished
	o.bl			bl
	jz				LABEL_Continue
	inc.d			ud_ErrorCountTimeSliceEnd
	cmp.b			us_FirstTimeSliceEnd,0
	jne				LABEL_Continue

	l.b				us_FirstTimeSliceEnd,1

LABEL_Continue
	l.b				( edi + DmUserData + 4 ), 0		//Reset Byte to find out if Rt of IM starts while Rt of DM is running
	//#SR010 end

	lzxb.eax	RtSSW		//ws005
 	shl.eax		3             //ws005: save some time here
	add.eax		#RtSel
	jmp			  eax

RtSel
	jmp			WaitForSync			// 0 : wait till PLL in locked
	rcl.eax 	0               	//ws005: simple placeholder (does really nothing)
	jmp			weAreSync			// 1 : wait one period to get a right time 
	rcl.eax		0               	//ws005: simple placeholder (does really nothing)
	jmp			MovStartPoint		// 2 : mov start point to the right pos
	rcl.eax 	0               	//ws005: simple placeholder (does really nothing)
	jmp			readpoint           // 3 : read one time the point 
	rcl.eax 	0               	//ws005: simple placeholder (does really nothing)
	jmp			RtRefresh			// 4 : do the realtime refresh


// ***************************************************************
//   do the refresh of I/O 
// ***************************************************************

RtRefresh

// *************************************************
//  read the time point
// *************************************************
	lzxb.eax	(edi+DmUserData)
	imul.ax		ax,DmTmrResso
	s.eax 		TimeAtRtPreEnd 

	//#SR009
	//***********calculate Rt - usage rate***********************
	lzxw.ebx	ui_RtStartPoint
	sub.eax		ebx
	imul.eax	eax,1000
	x.edx		  edx
	l.ebx		  sd_PllTimeGlob_us
	div			  ebx
	s.eax		  Rt_Load
	//#SR009 

// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b			  RealtimeReady,1		//ws005

	l.ebx		  #HandlesRt
	lzxw.ecx	HandleNrRt
	jecxz		  LABEL_RtPostScan	//#SR010 	RT_end    //NoRtProg  //ws005

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRT
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt


LABEL_RtPostScan
//BLEERN START
  cmp.d     HwControl, 0
  jne       RT_end
  
  call      UpdateRtPostScan_IM
//BLEERN ENDE

	jmp			  RT_end	


// ****************************************************************
//  now we have to move the startpoint till we are 50usec before
// ****************************************************************

MovStartPoint

	//#SR001 Start
	L.EAX		  ud_DelayRealtime	//Time of Rt - Programm of IM in ns
	CLR			  EDX
	L.ECX		  DmTmrResso*1000		// we have nanoseconds and we have to put in 25µs units
	DIV 		  ECX
	l.ebx		  eax
	//#SR001 End

	l.eax		  RtInterval

	sub.eax		ebx

	lzxb.ebx	(EDI+DmPllSyncDel)	// time delay			
	sub.eax		ebx											

 	sub.eax 	3             			//ws005: just subtract 3 instead of ... (see above)
   s.al		  (EDI+DmPllSyncDel)
	imul.ax		ax,DmTmrResso			//#SR009
	s.ax		  ui_RtStartPoint			//#SR009
	inc.b		  RtSSW					//ws005
	call		  LogRtSSW				//#SR008
	jmp			  RT_end	
	

// ***********************************************************
//   read the calculated time 
// ***********************************************************

ReadPoint
	clr			  eax
	l.al		  (edi+DmUserData)
	s.ax		  TimeBeforeNextSync
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	jmp			  RT_end	



// **********************************************************
//  now we are starting the RTProg 
// **********************************************************

weAreSync
	call		  StartRealtimeProg	
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	jmp			  RT_end	



// ***********************************************************
//   we have to wait that the PLL is locked before we start
// ***********************************************************
WaitForSync
	cmp.d		  release,16#FFFFFFFF
	je			  RT_end					// #fa 080103

	l			    (edi+DmPLLSyncState)
	test.al		DmPLLisLock
	jz			  WaitForSyncRet
	call		  StartRealtimeProg	
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	l.edi		  _IOSEGMENT			//#SR008
WaitForSyncRet
	L.AL		  (EDI+DmState)           // Start it always to keep the moduls alive 
	OR.AL		  16#10
	S.AL		  (EDI+DmState)  
	// #BS 240903
	L.B			  (EDI+DMWDRegister),1 // set WDTrigger
	L.B			  (EDI+DMWDTriggerMode),1 // set WDTrigger to watchdogregister
	L.B			  (EDI+DMWDRegister),0 // set WDTrigger
	

RT_end

	FC			  WDDIAS
RT_End1
	L.EAX	    READY$UDINT

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_RT.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			  LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_RT.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_RT.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_RT.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_RT.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_RT.sum					//Summe speichern
	l.ecx		  DMC_Time_RT.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_RT.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_RT._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_RT._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_RT._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_RT._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_RT.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

//[English]
// Does a 16 Bit write access
//[Globals]		_RTOSVersion		: OS version
//				_lsl_pos			: OS interface structure
//[Members]		
//[Locals]		
//[>Adress]		Module address and offset
//[>Data]		Data to write
//[<State]		
FUNCTION VIRTUAL GLOBAL DiasMasterMain::Wr16Bit
  VAR_INPUT
    Adress	: UDINT;
    Data		: UINT;
  END_VAR
  VAR_OUTPUT
    State		: DINT;
  END_VAR

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then
		if( p_SemaHandle <> NIL )then			//ws007
			To_Multitask.Wait( p_SemaHandle );	//ws006	
		end_if;
		State := OS_DIAS_WriteWord( pDIAS   := pDIAS, 
                                us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
                                ui_off  := ( Adress and 16#ff )$uint, 
                                ui_data := Data ); 

		if( p_SemaHandle <> NIL )then				//ws007
			To_Multitask.Signal( p_SemaHandle );	//ws006
		end_if;
		if( State <> 0 )then 
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		end_if;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
  	TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
	end_if;

END_FUNCTION
//[English]
// Does a 8 Bit read access
//[Globals]		_RTOSVersion			: OS version
//				_lsl_pos				: OS interface structure
//[Members]		
//[Locals]		us_data			:R/W	:intermediate storage of data
//				di_ret			:R/W	:return value of OS function
//[>Adress]		Module address and offset
//[<Data]		Data read
FUNCTION VIRTUAL GLOBAL DiasMasterMain::Rd8Bit
  VAR_INPUT
    Adress	: UDINT;
  END_VAR
  VAR_OUTPUT
    Data		: DINT;
  END_VAR
  VAR
    us_data : usint;
    di_ret	: dint;
  END_VAR

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then
		if( p_SemaHandle <> NIL )then			//ws007
			To_Multitask.Wait( p_SemaHandle );	//ws006
		end_if;
		di_ret := OS_DIAS_ReadByte( pDIAS   := pDIAS, 
                                us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
                                ui_off  := ( Adress and 16#ff )$uint, 
                                us_data := #us_data );
		if( p_SemaHandle <> NIL )then				//ws007
			To_Multitask.Signal( p_SemaHandle );	//ws006
		end_if;
		if( di_ret <> 0 )then
			Data := 0;
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		else
			Data := us_data;
		end_if;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
  	TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
	end_if;

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddCall2Main
  VAR_INPUT
    Mode		    : UINT;
    RTCY		    : DINT;
    thisp		    : ^void;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    Handle		  : DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeCall;
  
    (IPMainRT + PtrRT + CallStruct.Opc)^        := DbCall;                    // opcode 
    (IPMainRT + PtrRT$^INT + CallStruct.Addr)^  := StartOfCode$INT + IPSub$INT;           // IP on the SUB
    (IPMainRT + PtrRT + CallStruct.Mode)^       := Mode$HSINT AND 2#00010011; // write mode byte
    
    ARM_EAX := RTCY$UDINT OR DmCallProg;
    ARM_EDI := thisp$UDINT;
    GetHandle(CallStruct.mode, callOptions);
    Handle := ARM_EAX$DINT;
    IPMainRT += sizeof(CallStruct);
  else
    ud_DelayCyclic += C_TimeCall;

    (IPMainCY + PtrCY + CallStruct.Opc)^        := DbCall;                    // opcode 
    (IPMainCY + PtrCY$^INT + CallStruct.Addr)^  := StartOfCode$INT + IPSub$INT;           // IP on the SUB
    (IPMainCY + PtrCY + CallStruct.Mode)^       := Mode$HSINT AND 2#00010011; // write mode byte
    
    ARM_EAX := RTCY$UDINT OR DmCallProg;
    ARM_EDI := thisp$UDINT;
    GetHandle(CallStruct.mode, callOptions);
    Handle := ARM_EAX$DINT;
    IPMainCY += sizeof(CallStruct);
  end_if;
  
END_FUNCTION
#else

// ***************************************
//     add a call to the main Programm
// ***************************************
//
// RTCY = 0 cyclic programm
// RTCY = constant realtime  --> realtime programm
//
// MODE Bit 0 = continue
// 		Bit 1 = single
//		Bit 4 = block execution   !!!  (important for Analogcards 3 opcodes must be together)
//
//

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddCall2Main	VAR_INPUT
		Mode 	      : UINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime   				// mask the rest 
	
//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AC2M_NORT
	ADD.D		  ud_DelayRealtime, C_TimeCall
  JMP       LABEL_AC2M_TIMETAKEN
  
LABEL_AC2M_NORT
	ADD.D		  ud_DelayCyclic, C_TimeCall 

LABEL_AC2M_TIMETAKEN
//#SR001 End

	call		  GetProgPointer

	l.b			  (ecx+ebx+CallStruct.Opc), DbCall			// opcode Call
	push		  edx

  add.edx		StartOfCode

	s.dx		  (ecx+ebx+CallStruct.Addr)					// IP on the SUB   
	pop			  edx	

	l.ax		  Mode					// write mode byte
	and.al		2#00010011
	s.al		  (ecx+ebx+CallStruct.Mode)

	l.ax		  RTCY+0
	or.ax		  DmCallProg				// this is in the Main	
	l.edi		  thisp					

  push.b    callOptions

	push.d		CallStruct.mode         // direct pointer on the mode byte
	call		  GetHandle

  add.esp   5
	s.eax		  handle

	add.ecx		sizeof (CallStruct)
	l.eax		  RTCY
	and.eax		Dmrealtime	
	call		  StoreNewPointers

END_FUNCTION
#endif

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetKennung
  VAR_INPUT
    Place		  : UDINT;
  END_VAR
  VAR_OUTPUT
    Kennung		: UDINT;
  END_VAR
  
	Kennung := TO_UDINT (_diasconfig[Place]);
  
END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRd16Bit
  VAR_INPUT
    Adress		  : HINT;
    RTCY		    : DINT;
    thisp		    : ^void;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    Handle		  : DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeRd16Bit;
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeRd16Bit;
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + Rd16Struct.Opc)^         := DbRd16;
  (PtrCode$^HINT + IPSub + Rd16Struct.ChAdr)^ := Adress;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(Rd16Struct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(Rd16Struct);
  
END_FUNCTION
#else

// ***************************************
//   put programm into the buffer
// ***************************************
//  this is a 16 bit read
//  the thispointer we need to call the update method
//

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRd16Bit
	VAR_INPUT
		Adress 	    : HINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AR16B_NORT
	ADD.D		  ud_DelayRealtime,C_TimeRd16Bit
	inc.w		  ui_RtDIASAccesses				//#SR021
  JMP       LABEL_AR16B_TIMETAKEN
  
LABEL_AR16B_NORT
	ADD.D		  ud_DelayCyclic,C_TimeRd16Bit
	inc.w		  ui_CyDIASAccesses
  
//#SR001 End

LABEL_AR16B_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+Rd16Struct.Opc),DbRd16	   			// opcode Read 8
	l.ax		  Adress					// adress lo+high
	s.ax		  (edx+ebx+Rd16Struct.ChAdr+0)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	

  push.b    callOptions

	push.d		Rd16Struct.Data			// direct pointer on the data 
	call		  GetHandle

  add.esp   5

	s.eax		  Handle
	add.edx		sizeof (Rd16Struct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRet
  VAR_INPUT
    RTCY		: DINT;
  END_VAR

  if (RTCY AND DMREALTIME) = DMREALTIME then
    ud_DelayRealtime += C_TimeRet;
  else
    ud_DelayCyclic += C_TimeRet;
  end_if;

  (PtrCode + IPSub + RetStruct.Opc)^ := DbRet;
  
  IPSub += sizeof(RetStruct);
  
END_FUNCTION

#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRet
  VAR_INPUT
    RTCY		: DINT;
  END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AR_NORT
	ADD.D		  ud_DelayRealtime,C_TimeRet
  JMP       LABEL_AR_TIMETAKEN
  
LABEL_AR_NORT
//#SR001 End
	ADD.D		  ud_DelayCyclic,C_TimeRet

LABEL_AR_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+RetStruct.Opc),DbRet			     // opcode Ret
	add.edx		sizeof (RetStruct)

	l.eax		  RTCY
	and.eax		Dmrealtime	
	call		  StoreNewPointers

END_FUNCTION
#endif

//[English]
// Does a 16 Bit read access
//[Globals]		_RTOSVersion			: OS version
//				_lsl_pos				: OS interface structure
//[Members]		
//[Locals]		ui_data			:R/W	:intermediate storeage of data
//				di_ret			:R/W	:returnvalue of OS
//[>Adress]		Module address and offset
//[<Data]		Data read
FUNCTION VIRTUAL GLOBAL DiasMasterMain::Rd16Bit
  VAR_INPUT
    Adress	: UDINT;
  END_VAR
  VAR_OUTPUT
    Data		: DINT;
  END_VAR
  VAR
    ui_data : uint;
    di_ret	: dint;
  END_VAR


	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then
		if( p_SemaHandle <> NIL )then			//ws007
			To_Multitask.Wait( p_SemaHandle );	//ws006
		end_if;
		di_ret := OS_DIAS_ReadWord( pDIAS  := pDIAS, 
								   us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
								   ui_off  := ( Adress and 16#ff )$uint, 
								   ui_data := #ui_data );
		if( p_SemaHandle <> NIL )then				//ws007
			To_Multitask.Signal( p_SemaHandle );	//ws006
		end_if;
		if( di_ret <> 0 )then
			Data := 0;
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		else
			Data := ui_data;
		end_if;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
		TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
	end_if;

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRd32Bit
  VAR_INPUT
    Adress		  : HINT;
    RTCY		    : DINT;
    thisp		    : ^void;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    Handle		  : DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeRd8Bit + 3*(C_TimeRd16Bit - C_TimeRd8Bit); // appraised value: 1*basetime + 4*time for 1 byte (instead of C_TimeRd32Bit)
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeRd8Bit + 3*(C_TimeRd16Bit - C_TimeRd8Bit); // appraised value: 1*basetime + 4*time for 1 byte (instead of C_TimeRd32Bit)
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + Rd32Struct.Opc)^         := DbRd32;
  (PtrCode$^HINT + IPSub + Rd32Struct.ChAdr)^ := Adress;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(Rd32Struct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(Rd32Struct);

END_FUNCTION

#else
// ***************************************
//   put programm into the buffer
// ***************************************
//  this is a 16 bit read
//  the thispointer we need to call the update method
//

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRd32Bit
	VAR_INPUT
		Adress 	    : HINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

  
	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AR32B_NORT
	ADD.D		  ud_DelayRealtime,C_TimeRd32Bit
	inc.w		  ui_RtDIASAccesses			
  JMP       LABEL_AR32B_TIMETAKEN
  
LABEL_AR32B_NORT
	ADD.D		  ud_DelayCyclic,C_TimeRd32Bit
	inc.w		  ui_CyDIASAccesses
//#SR001 End

LABEL_AR32B_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+Rd32Struct.Opc),DbRd32	   			// opcode Read 8
	l.ax		  Adress					// adress lo+high
	s.ax		  (edx+ebx+Rd32Struct.ChAdr+0)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	
  
  push.b    callOptions
  
	push.d		Rd16Struct.Data			// direct pointer on the data 
	call		  GetHandle

  add.esp 5

	s.eax		  Handle

	add.edx		sizeof (Rd32Struct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRd8Bit
  VAR_INPUT
    Adress		  : HINT;
    RTCY		    : DINT;
    thisp		    : ^void;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    Handle		  : DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeRd8Bit;
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeRd8Bit;
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + Rd8Struct.Opc)^         := DbRd8;
  (PtrCode$^HINT + IPSub + Rd8Struct.ChAdr)^ := Adress;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(Rd8Struct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(Rd8Struct);

END_FUNCTION

#else
// ***************************************
//   put programm into the buffer
// ***************************************
//  this is a 8 bit read
//  the thispointer we need to call the update method
//

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRd8Bit
	VAR_INPUT
		Adress 	    : HINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR


	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AR8B_NORT
	ADD.D		  ud_DelayRealtime,C_TimeRd8Bit
	inc.w		  ui_RtDIASAccesses			//#SR021
  JMP       LABEL_AR8B_TIMETAKEN
  
LABEL_AR8B_NORT
	ADD.D		  ud_DelayCyclic,C_TimeRd8Bit
	inc.w		  ui_CyDIASAccesses
//#SR001 End

LABEL_AR8B_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+Rd8Struct.Opc),DbRd8	   			// opcode Read 8
	l.ax		  Adress					// adress lo+high
	s.ax		  (edx+ebx+Rd8Struct.ChAdr+0)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	
  
  push.b    callOptions

	push.d		Rd8Struct.Data			// direct pointer on the data 
	call		  GetHandle

  add.esp   5

	s.eax		  Handle
	add.edx		sizeof (Rd8Struct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRTBSync
  VAR_INPUT
    Adress		: HINT;
  END_VAR
  VAR_OUTPUT
    FirstRTB	: DINT;
  END_VAR
  #ifdef OldDiasXilinx
  VAR
    pUSINT : ^USINT;
  END_VAR
#endif


  FirstRTB := 0;
  
  if DiasType <> 2 then

#IFNDEF OldDiasXilinx
    if RTBSyncAdr = NIL then
      RTBSyncAdr := (16#100*63+16#8002)$^USINT;// global sync
      
      FirstRTB := 1;
    end_if;
#ELSE
    if NumberSyncs >= NumberLocalSyncs then
      ErrorLocalSyncTrace();
    else
      ((#RtbLocalSyncAdr)$^DINT + NumberSyncs * (SIZEOF(RtbLocalSyncAdr)/NumberLocalSyncs))^ := Adress + 16#8000;
    end_if;
#ENDIF
  else
    // DiasType = 2 --> it is a new Master
#IFNDEF OldDiasXilinx
    if (SyncProgPtr + CntrlStruct.OPC)^ <> DbCntrl then
      (SyncProgPtr + CntrlStruct.OPC)^          := DbCntrl;
      (SyncProgPtr$^UINT + CntrlStruct.chAdr)^  := 16#100*63+2;
      (SyncProgPtr + CntrlStruct.Data)^         := 0;
      FirstRTB := 1;
      
      ud_DelayRealtime := ud_DelayRealtime + C_TimeControlWrite - C_TimeNop * 4; //because the 4 Nops were overwritten
    end_if;
#ELSE    
    if NumberSyncs >= NumberLocalSyncs then
      ErrorLocalSyncTrace();
    else
      pUSINT := #CallsRt[0] + sizeof(TmrStruct) + NumberSyncs * SIZEOF(CntrlStruct);
  
      if (pUSINT + CntrlStruct.OPC)^ <> DbCntrl then
        (pUSINT + CntrlStruct.OPC)^         := DbCntrl;
        (pUSINT$^UINT + CntrlStruct.chAdr)^ := Adress;
        (pUSINT + CntrlStruct.Data)^        := 0;

        ud_DelayRealtime := ud_DelayRealtime + C_TimeControlWrite - C_TimeNop * 4; //because the 4 Nops were overwritten  
      end_if;
    end_if;
#ENDIF
  end_if;

  NumberSyncs += 1;
  
  if FirstRTB = 1 then
    us_SyncModule := (Adress SHR 8)$USINT;
  end_if;
  
END_FUNCTION

#else

// *************************************************
//   RTB is fixed reserved for one MODUL
// *************************************************
//
//  if FirstRTB <> 0 then this modul is the first with RTB
//  and has to do perhaps something special
//  if FirstRTB = 0 then it already exists a modul with RTBSYNC
//

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRTBSync
  VAR_INPUT
    Adress		: HINT;
  END_VAR
  VAR_OUTPUT
    FirstRTB	: DINT;
  END_VAR

	l.d			FirstRTB,0

	cmp.b		DiasType,2			//ws005
	je			AddRTBIMaster		// --> it is a new Master

#IFNDEF OldDiasXilinx
	cmp.d		RTBSyncAdr,0
	jne			AddRTBSyncRet


	L.EDI		16#100*63+16#8002 		// global sync  //ws005: faster

	s.edi		RTBSyncAdr

	l.d			FirstRTB,1						// first RTB
#ELSE
	LZXW.EDI	Adress
	ADD.EDI		16#8000

	LZXB.EAX	NumberSyncs
	CMP.AL		NumberLocalSyncs
	JAE			  ErrorSync
	L.AH		  SIZEOF(RtbLocalSyncAdr)/NumberLocalSyncs
	MUL			  AH
	ADD.EAX		#RtbLocalSyncAdr

	S.EDI		  (EAX)
#ENDIF
	jmp			  AddRTBSyncRet



AddRTBIMaster
#IFNDEF OldDiasXilinx

	//#SR003 Start
	l.edi	    SyncProgPtr
	//#SR003 End

	cmp.b		  (edi+CntrlStruct.OPC),DbCntrl
	je			  AddRTBSyncRet

	l.b			  (edi+CntrlStruct.OPC),DbCntrl

	l.ax		  16#100*63+2 		// global sync
	
	s.ax		  (edi+CntrlStruct.chAdr+0)		// the modul normal = 63 (global SYNC)

	l.b			  (edi+CntrlStruct.Data),0		// we always write data 0 
	l.d			  FirstRTB,1						// first RTB

//#SR001 Start
	SUB.D		  ud_DelayRealtime,C_TimeNop * 4			//because the 4 Nops were write over
	ADD.D		  ud_DelayRealtime,C_TimeControlWrite
//#SR001 End

#ELSE
	l.edi		  #CallsRt
	add.edi		sizeof (TmrStruct)  // the first INSTR is tmr 

	LZXB.EAX	NumberSyncs
	CMP.AL		NumberLocalSyncs
	JAE			  ErrorSync
	L.AH		  SIZEOF(CntrlStruct)
	MUL			  AH
	ADD.EDI		EAX

	cmp.b		  (edi+CntrlStruct.OPC),DbCntrl
	je			  AddRTBSyncRet

	l.b			  (edi+CntrlStruct.OPC),DbCntrl
	l.ax		  Adress
	s.ax		  (edi+CntrlStruct.chAdr+0)		// the modul normal = 63 (global SYNC)

	l.b			  (edi+CntrlStruct.Data),0		// we always write data 0 

//#SR001 Start
	SUB.D		  ud_DelayRealtime,C_TimeNop * 4			//because the 4 Nops were write over
	ADD.D		  ud_DelayRealtime,C_TimeControlWrite	
//#SR001 End

	JMP			  AddRTBSyncRet

ErrorSync
	FC			  ErrorLocalSyncTrace
#ENDIF

AddRTBSyncRet

	INC.B		  NumberSyncs

	//#SR008 start
	cmp.d		  FirstRTB,1
	jne			  LABEL_End

	l.ax		  Adress
	shr.ax		8
	s.al		  us_SyncModule

LABEL_End
	//#SR008 end

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddWR16Bit
  VAR_INPUT
    adress	    : Hint;
    RTCY		    : DINT;
    thisp		    : ^void;
    data		    : UINT;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    handle		  : DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeWr16Bit;
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeWr16Bit;
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + Wr16Struct.Opc)^         := DbWr16;
  (PtrCode$^HINT + IPSub + Wr16Struct.ChAdr)^ := Adress;
  (PtrCode$^HINT + IPSub + Wr16Struct.Data)^  := data;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(Wr16Struct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(Wr16Struct);
  
END_FUNCTION


// ***************************************
//   put programm into the buffer
// ***************************************
//  this is a 16 bit read
//  the thispointer we need to call the update method
//
#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddWR16Bit
	VAR_INPUT
		adress 	      : HINT;
		RTCY 	        : DINT;
		thisp 	      : ^void;
		data 	        : UINT;
		callOptions 	: USINT;
	END_VAR
	VAR_OUTPUT
		handle 	      : DINT;
	END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AW16B_NORT
	ADD.D		  ud_DelayRealtime,C_TimeWr16Bit
	inc.w		  ui_RtDIASAccesses			//#SR021
  JMP       LABEL_AW16B_TIMETAKEN
  
LABEL_AW16B_NORT
	ADD.D		  ud_DelayCyclic,C_TimeWr16Bit
	inc.w		  ui_CyDIASAccesses
//#SR001 End

LABEL_AW16B_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+Wr16Struct.Opc),DbWr16	   			// opcode Read 8
	l.ax		  Adress					// adress lo+high
	s.ax		  (edx+ebx+Wr16Struct.ChAdr+0)

	l.ax		  data
	s.ax		  (edx+ebx+Wr16Struct.Data)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	

  push.b    callOptions

	push.d		Wr16Struct.Data			// direct pointer on the data 
	call		  GetHandle

  add.esp   5

	s.eax		  Handle

	add.edx		sizeof (Wr16Struct)
	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddWr8Bit
	VAR_INPUT
		adress 	    : HINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		Data 	      : USINT;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += C_TimeWr8Bit;
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeWr8Bit;
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + Wr8Struct.Opc)^         := DbWr8;
  (PtrCode$^HINT + IPSub + Wr8Struct.ChAdr)^ := Adress;
  (PtrCode$^HINT + IPSub + Wr8Struct.Data)^  := data;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(Wr8Struct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(Wr8Struct);
  
END_FUNCTION

#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddWr8Bit
	VAR_INPUT
		adress 	    : HINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		Data 	      : USINT;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AW8B_NORT
	ADD.D		  ud_DelayRealtime,C_TimeWr8Bit
	inc.w		  ui_RtDIASAccesses			//#SR021
  JMP       LABEL_AW8B_TIMETAKEN
  
LABEL_AW8B_NORT
	ADD.D		  ud_DelayCyclic,C_TimeWr8Bit
	inc.w		  ui_CyDIASAccesses
//#SR001 End

LABEL_AW8B_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+Wr8Struct.Opc),DbWr8	   			// opcode Read 8
	l.ax		  Adress					// adress lo+high
	s.ax		  (edx+ebx+Wr8Struct.ChAdr+0)
	l.al		  data
	s.al		  (edx+ebx+Wr8Struct.Data)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	

  push.b    callOptions

	push.d	  Wr8Struct.Data			// direct pointer on the data 
	call		  GetHandle

  add.esp   5
	s.eax		  Handle

	add.edx		sizeof (Wr8Struct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

//[English]
// Function is writing into controlarea of a diasmodul
//[Globals]		_RTOSVersion		: OS version
//				_lsl_pos			: OS interface structure
//[Members]		
//[Locals]		
//[>Adress]		High Byte Modulnumber, Low Byte offset in Controlarea
//[>Data]		Data to write
//[<state]		0..success
FUNCTION VIRTUAL GLOBAL DiasMasterMain::WrCntr
  VAR_INPUT
    adress		: DINT;
    Data		  : Usint;
  END_VAR
  VAR_OUTPUT
    state		: DINT;
  END_VAR


	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then
		if( p_SemaHandle <> NIL )then			//ws007
			To_Multitask.Wait( p_SemaHandle );	//ws006
		end_if;
		state := OS_DIAS_WriteCtrl_( pDIAS  := pDIAS, 
									us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
									ui_off  := ( Adress and 16#ff )$uint, 
									us_data := Data );
		if( p_SemaHandle <> NIL )then				//ws007
			To_Multitask.Signal( p_SemaHandle );	//ws006
		end_if;
		if( state <> 0 )then
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		end_if;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
		if( ( _WhoAmI = 16#19 ) | ( _WhoAmI = 16#17 ) )then //ET261 and ETT321
			state := OS_DIAS_WriteCtrl_( pDIAS  := pDIAS, 
										us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
										ui_off  := ( Adress and 16#ff )$uint, 
										us_data := Data );
			if( state <> 0 )then
				TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
			end_if;
		else

	// /ws005
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		end_if;
	end_if;

END_FUNCTION
//[#ENGLISH]
//[>Time_uSec]Time in uSec (valid from 0-255)

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddWait
  VAR_INPUT
    RTCY		  : DINT;
    Time_uSec	: DINT;
  END_VAR

  if (RTCY AND Dmrealtime) = Dmrealtime then
    ud_DelayRealtime += Time_uSec$UDINT * 1000;
  else
    ud_DelayCyclic += Time_uSec$UDINT * 1000;
  end_if;

  (PtrCode + IPSub + DelayStruct.Opc)^       := DbDelay;
  (PtrCode + IPSub + DelayStruct.TIME_uSec)^ := Time_uSec$HSINT;
  
  IPSub += sizeof(DelayStruct);
  
END_FUNCTION
#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddWait
  VAR_INPUT
    RTCY		  : DINT;
    Time_uSec	: DINT;
  END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	l.ecx		  Time_usec
	imul.ecx	ecx,1000
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AW_NORT
	ADD.D		  ud_DelayRealtime,ecx
  JMP       LABEL_AW_TIMETAKEN
  
LABEL_AW_NORT
  ADD.D		  ud_DelayCyclic,ecx
//#SR001 End

LABEL_AW_TIMETAKEN
  

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+DelayStruct.OPC),DbDelay	   			// opcode delay uSec
	l.eax		  Time_uSec					
	s.al		  (edx+ebx+DelayStruct.TIME_uSec)
	add.edx		sizeof (DelayStruct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetPllTime
  VAR_OUTPUT
    PllTime		: DINT;
  END_VAR
  VAR
    objinfo : LSLOBJ_INFO;
    Val		: DINT;
  END_VAR
	
	IF PllTimeGlob = 0 THEN
		
		To_TaskObjectControl.GetObjectInfo(this,OBJ_RT,#objinfo);			//#SR009

		// the set value of object
		PllTimeGlob := objinfo.period$DINT; 
		IF PllTimeGlob = 0 THEN
#ifdef HWC_LogError
      HWC_LogError(this, "@0002 (DiasMasterMain::GetPllTime) A realtime of object 'DiasMasterC' is required !! ( 1ms is the default value ) !!");
#else
      TRACE("A realtime of object 'DiasMasterC' is required !! ( 1ms is the default value ) !!");
#endif
		END_IF;

    //look if we have µs or ms (µs msb is set)
    if ( ( objinfo.period and 16#8000_0000 ) = 0 ) then
      
      //we need our task time in µs
      ud_TaskTime := objinfo.period * 1000;
    else

      //we have already µs seconds
      ud_TaskTime := objinfo.period and 16#7FFF_FFFF;
    end_if;

		//#SR013 start
		us_RtPasses := 1;
		us_ModuleUpdate1ms := 1;
		us_MuSecMode := 0;
		
		//look if we have no old OS ( from 1.1.50 upwards)
		if _RtOSversion >= 16#1132 then
			//RTOS variable _ClockTicks ( with pointer because of linker error with old loaders without this variable)
			//_Firstscan has Offset 0EB8 and _ClockTicks has offset 0EAB, therefore -13
			ui_ClockTicks := ( ( #_Firstscan - 13 )$^UINT )^;

      if ui_ClockTicks < 1000 then
        //is DiasMaster rt time same as OS-Time (maintimer)
        if ( PllTimeGlob and 16#7FFF_FFFF ) = ui_ClockTicks then
          // check if maintimer has a valid value
          if ( 1000 mod ui_ClockTicks ) | ui_ClockTicks < 50 then					
#ifdef HWC_LogError
            HWC_LogError(this, "@0003 (DiasMasterMain::GetPllTime) No valid maintimer value in OS (valid: 50,100,125,200,250,500,1000)! Master is set off!");
#else
            TRACE( "No valid maintimer value in OS (valid: 50,100,125,200,250,500,1000)! Master is set off!" );
#endif
            MasterOn := 0;
            ImOff := 1;
          else
            us_RtPasses := ( 1000 / ui_ClockTicks )$USINT;
            us_MuSecMode := 1;
            us_ModuleUpdate1ms := 0;
          end_if;
        else
          // there is only one FPGA SyncOut for OS-RT and DiasMaster, so they have to be at the same cycle
#ifdef HWC_LogError
          HWC_LogError(this, "@0004 (DiasMasterMain::GetPllTime) Rt-Time of DiasMasterC not the same as Base Rt-Time of OS (Maintimer). Master is set off!");
#else
          TRACE( "Rt-Time of DiasMasterC not the same as Base Rt-Time of OS (Maintimer). Master is set off!" );
#endif
          MasterOn := 0;
          ImOff := 1;
        end_if;
      end_if;
		end_if;
		//#SR013 End	

		// but it could be a CPU with 3ms
		Val := PllTimeGlob MOD Ops.RtInterv_mSec$DINT;
		IF Val THEN
			PllTimeGlob += Ops.RtInterv_mSec$DINT - Val ;
		END_IF;

		// there could be a error
		IF PllTimeGlob < Ops.RtInterv_mSec$DINT THEN
			PllTimeGlob := Ops.RtInterv_mSec$DINT;
		END_IF;

#ifdef HWC_LogValue1
    HWC_LogValue1(this, "@0500 (DiasMasterMain::GetPllTime) PllTime = {0}", PllTimeGlob$UDINT);
#else
		//#SR008 start
		if p_KernelLog <> NIL then
			OS_KernelLog1( "DiasMaster: PllTime = %d", PllTimeGlob );
		end_if;
		//#SR008 end
#endif

		sd_PllTimeGlob_us := PllTimeGlob * 1000;		//#SR009	
	END_IF;

	// aber eigentlich hängt er ja am TASK0 => #FA fragen !! => Ops.RtInterv_mSec

	PllTime := PllTimeGlob;

END_FUNCTION
//[English]
// Does a 8 Bit write access
//[Globals]		_RTOSVersion		: OS version
//				_lsl_pos			: OS interface structure
//[Members]		
//[Locals]		
//[>Adress]		Module address and offset
//[>Data]		Data to write
//[<State]		
FUNCTION VIRTUAL GLOBAL DiasMasterMain::Wr8Bit
  VAR_INPUT
    Adress	: UDINT;
    Data		: Usint;
  END_VAR
  VAR_OUTPUT
    State		: DINT;
  END_VAR

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then
		if( p_SemaHandle <> NIL )then			//ws007
			To_Multitask.Wait( p_SemaHandle );	//ws006
		end_if;
		State := OS_DIAS_WriteByte(pDIAS   := pDIAS, 
                               us_mod  := ( ( Adress shr 8 ) and 16#ff )$usint, 
                               ui_off  := ( Adress and 16#ff )$uint, 
                               us_data := Data ); 
		if( p_SemaHandle <> NIL )then				//ws007
			To_Multitask.Signal( p_SemaHandle );	//ws006
		end_if;
		if( State <> 0 )then
			TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
		end_if;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
		TraceAsyncError(( ( Adress shr 8 ) and 16#ff )$usint);
	end_if;

END_FUNCTION


FUNCTION  DiasMasterMain::DiasMasterMain
  VAR_OUTPUT
    ret_code		: CONFSTATES;
  END_VAR
  VAR
    MyProgPtr       : ^USINT;
    P2Cil		        : ^s_DiasInfoType;	//ws003
    i		            : USINT;
    PTRWDDIAS	      : ^USINT;
    SigmaTekDevInfo : ^PCICONFDATA;
    timex		        : UDINT;
#ifndef HWC_LogInit
    P2SSR		        : ^LSL_SSR;				//#SR008
#endif
    p_Obj           : ^Obj;
    p_ClsHdr        : ^ClsHdr;
    b_IsLocalMaster : BOOL;
  END_VAR

  // check if we are any kind of derivation that makes us no local master!
  b_IsLocalMaster := TRUE;
  p_Obj		:= LSL_GetHdr(this);
  p_ClsHdr := p_Obj^.pClsHdr;
  WHILE p_clsHdr^.pBaseCls <> NIL DO // go down until there is no base - we might be derived by the user....
    #pragma warning(disable: 137 )
    IF  _strcmp(str1:=#p_ClsHdr^.pDsc^.Name.Text$CHAR, str2:="Dias2DataMover") = 0 
      | _strcmp(str1:=#p_ClsHdr^.pDsc^.Name.Text$CHAR, str2:="DiasMasterSplitter") = 0
      | _strcmp(str1:=#p_ClsHdr^.pDsc^.Name.Text$CHAR, str2:="DiasMasterC_Dummy") = 0 THEN
      //if we find a derivation during going down that is called Dias2DataMover or DiasMasterSplitter
      //this is no local DiasMaster and we do not need to initialize it
      b_IsLocalMaster := FALSE;
      EXIT;
    END_IF;
    #pragma warning(default: 137 )
    p_ClsHdr := p_ClsHdr^.pBaseCls;
  END_WHILE;

  MasterON := 1;
  RTBSyncAdr :=NIL;
  CDiasType:=0;
  DiasType := 16#ff;
  ud_DelayRealtime := 0;	//#SR001	
  us_SyncModule := 255;	//#SR012	

  //#SR013 start
  us_RtPasses := 1;
  us_ModuleUpdate1ms := 1;
  us_MuSecMode := 0;
  //#SR013 end

  PtrCY 	 := #CallsCY[0];
  IPMainCY := 0;   // stops with a end programm
  IPSub  := 0;//(DmCallRes* sizeof (CallStruct)) + sizeof (EndStruct);


  PtrRT 	 := #CallsRT[0];

  PtrCode  := #CodeRtCy[0];

  IF b_IsLocalMaster THEN

    pDIAS := _lsl_pos^.piDias;  //ws005: prepare the DIAS pointer (faster)

#ifdef HWC_LogInit
    HWC_LogInit();
#else
    //#SR008 start
    if OS_CILGET( "SSR", #P2SSR ) then
      p_KernelLog := NIL;
    else
      p_KernelLog := ( P2SSR^.KernelLog )$^DINT;		
    end_if;
    //#SR008
#endif

    // test if interface already exist	
    if OS_CILGET("DiasInfo", #P2Cil) then
      if ((_IOsegment$DINT <> 0) & (_IOsegment$DINT <> 16#D0000)) then
        release :=0;
        DiasType:=1;
      end_if;
    else
      DiasType := P2Cil^.DiasType$usint;
      _IOSegment$^USINT := DiasHwPointer  := P2Cil^.DiasHWPointer$^usint; //ws003
      CDiasHwPointer := P2Cil^.CDiasHWPointer$^usint;	//ws003
      CDiasType := ( P2Cil^.CDiasType )$USINT;	//ws003

      IF CDiasType = 1 THEN

        //--- CCL -----------------------------------------------------
        IF OS_CILGET("CDIAS_IRQ",#lsl_cdias_irq) = SYS_ERR_NONE THEN
          CDiasIRQpossible := 1;
        END_IF;

      ELSIF CDiasType = 2 THEN

        //--- CIPC ----------------------------------------------------
        IF OS_CILGET("CDIAS_IRQ",#lsl_cdias_irq) = SYS_ERR_NONE THEN
          CDiasIRQpossible := 1;
        END_IF;

        IF OS_CILGET("PCICONFIG", #pSPCIInfo) =  SYS_ERR_NONE THEN
          // watchdog C-DIAS Bus
          // Trigger: write on offset 13 value 0
          SigmaTekDevInfo := SPCIINFO_FINDDEVICEBYNAME( "CDIASWATCHDOG" ,0 );
          CDiasI2CWatchdog$pVoid := SPCIINFO_GETADDRESS(SigmaTekDevInfo);
          CDiasI2CWatchdog$UDINT += 13;
          CDiasI2CWatchdog^ := 0;
          // #BS000
          i := (CDiasI2CWatchdog+2)^; // quit overrun (for Watchdog tracemessage)
        ELSE
#ifdef HWC_LogError
          HWC_LogError(this, "@0005 (DiasMasterMain::DiasMasterMain) A newer OS is required to insure a correct functionality of the CDIAS-Bus of the CPU !!");
#else
          Trace("A newer OS is required to insure a correct functionality of the CDIAS-Bus of the CPU !!");
#endif
        END_IF;
        
        //#SR016 start
        if ( P2Cil^.PLLType = 2 ) then

          //get pointer to new pll
          p_NewPll$^UDINT := ( P2Cil^.PLLHWPointer )$^UDINT;
        else
        //#SR016 end
        
          // sync on cdias bus
          CDIASSync$UDINT := P2Cil^.PLLHWPointer;		//ws003
          (CDIASSync+1)^ := ops.RtInterv_mSec$USINT; // Set Sync Time on CDIAS-Bus
        end_if;			//#SR016

      END_IF;	 	
    end_if;

    // on linux platforms there is no local DIAS/CDIAS
    if ops_is_linux() = 0 then
      if _WHOAMI <= 16#35 then  //LanSte 09.12.2013 Only check for relativly old CPU's, newer CPU's may have no DIAS Bus at all.
        if (DiasType = 16#2) | (DiasType = 16#ff) then 
          if TestMasterIM() = TRUE then
            // #BS 240903
            PTRWDDIAS$UDINT := _IOSegment$UDINT + DMWDTriggerMode;
            PTRWDDIAS^ := 0; // set to Trigger on async too
            PTRWDDIAS$UDINT := _IOSegment$UDINT + DMWDTimeBase;
            PTRWDDIAS^ := 8; // set timebase of watchdog to 8*16=128ms

            DiasType:=2;		// we are a IMaster
            InitChip();

            // to skip DiasError 63 on old intellgent master
            // #BS007
            timex := ops.tAbsolute;
            WHILE ops.tAbsolute - timex <= 150ms DO END_WHILE; 
          else
              // if IOsegment <> 0 then it must be a old standard master
            if _IOsegment <> 0 then
              release :=0;
              DiasType:=1;
            end_if;
            
          END_IF;
        end_if;
      else
        Release   := 16#FFFFFFFF;   // Fehler Master nicht vorhanden
        MasterON  := 0;
      end_if;
    else
      Release   := 16#FFFFFFFF;   // Fehler Master nicht vorhanden
      MasterON  := 0;
    end_if;
  // pointer to top of programm and we keep space for 100 calls + END

  // 1. in the RT Prog at the begin is fix wait timer event

    #IFNDEF OldDiasXilinx
    
    //#SR013 start
    IPMainRT := sizeof( EventStruct );				
  #ELSE
    i := NumberLocalSyncs;
    IF i THEN
      IPMainRT := sizeof (CntrlStruct) * NumberLocalSyncs + sizeof (EventStruct);  
    ELSE
      IPMainRT := sizeof (CntrlStruct) + sizeof (EventStruct);  
    END_IF;

  #ifdef HWK_SHOW_PRAGMA_MESSAGES
      #pragma message("Hier wurde Code temporär von FucHer am 05.06.2013 16:38 geändert! Zurückbauen nicht vergessen!")   
  #endif 
  #ENDIF


    // always begins with a timer event and fixed NOP for SYNC

    MyProgPtr :=PtrRT;

    #pragma warning( disable: 74 )				//#SR007
    // timer event 
    MyProgPtr^   := DbTmrEve;     // always at the begin is a timer event 
    MyProgPtr    += 1;
    #pragma warning( default: 74 )				//#SR007

    ud_DelayRealtime += C_TimeTimerEvent;		//#SR001

    #IFNDEF OldDiasXilinx
    // control write = 4 Byte filled with nop's 
    // only one global sync

    //#SR013 start
    if DiasType =  2 then
      AddCall2Main( Mode := DmSingle, RTCY := DMRealtime, thisp := NIL ); 	// pointer is set later
      SyncProgPtr$UDINT := IPSub$UDINT + ( #CodeRtCy )$UDINT;
      AddNOP( RTCY := DMRealtime, nCount := 4 );
      AddRet( RTCY := DMRealtime );

      HandleNrRt := 1;		
    else
      HandleNrRt := 0;		
    end_if;

    IPMainRT += 2 * sizeof( MoveStruct );
    MyProgPtr += sizeof( CallStruct );
    //#SR013

    //#SR010 start	
    //Mark realtime task of intelligent master as active to find out if realtime is already running when 
    //Rt of DiasMasterC starts (Byte is only read in DiasMasterC Rt - Program)
    MyProgPtr^	:= DbMov;
    MyProgPtr   += 1;
    ( MyProgPtr$^UINT )^	:= DmUserData + 1;
    MyProgPtr   += 2;
    ( MyProgPtr$^UINT )^	:= DmUserData + 3;
    MyProgPtr	+= 2;
    
    ud_DelayRealtime += C_TimeMove;

    //Set Bit to recognize that realtime of IM doesn't start when Rt of DiasMaster runs
    //(Byte is reseted at the beginning of DiasMasterC Rt - Program)
    MyProgPtr^	:= DbMov;
    MyProgPtr	+= 1;
    ( MyProgPtr$^UINT )^	:= DmUserData + 1;
    MyProgPtr	+= 2;
    ( MyProgPtr$^UINT )^	:= DmUserData + 4;

    ud_DelayRealtime += C_TimeMove;

    //save copy values in UserData Area
    if( DiasType = 2 )then			
      MyProgPtr 	:= ( _IOSegment + DmUserData + 1 )$^USINT;
      MyProgPtr^	:= 1;
      MyProgPtr	+= 1;
      MyProgPtr^	:= 0;
    end_if;
    //#SR010 end


  #ELSE
    // many local syncs
    i := NumberLocalSyncs;
    IF i THEN
      FOR i := 0 TO NumberLocalSyncs-1 DO
        MyProgPtr^   := DbNOP;     
        MyProgPtr    += 1;
        MyProgPtr^   := DbNOP;     
        MyProgPtr    += 1;
        MyProgPtr^   := DbNOP;     
        MyProgPtr    += 1;
        MyProgPtr^   := DbNOP;
        MyProgPtr    += 1;
      END_FOR;

      ud_DelayRealtime += ( C_TimeNop	* 4 * NumberLocalSyncs );	//#SR001

    ELSE
      // we say 1 sync is required
      MyProgPtr^   := DbNOP;     
      MyProgPtr    += 1;
      MyProgPtr^   := DbNOP;     
      MyProgPtr    += 1;
      MyProgPtr^   := DbNOP;     
      MyProgPtr    += 1;
      MyProgPtr^   := DbNOP;
      MyProgPtr    += 1;

      ud_DelayRealtime += ( C_TimeNop	* 4 );	//#SR001

    END_IF;
    HandleNrRt := 0;		//#SR013
  #ENDIF

    //get interface for hardwaretree functions
    if ( OS_CILGET(INTERFACE_HARDWARETREE, #pHardwareTree)) then
      pHardwareTree := NIL;

#ifdef HWC_LogError
      HWC_LogError(this, "@0006 (DiasMasterMain::DiasMasterMain) Hardwaretree-Interface not found. A newer OS is required for Safety-Modules");
#else
      TRACE("Hardwaretree-Interface not found. A newer OS is required for Safety-Modules");
      if p_KernelLog <> NIL then
        OS_KernelLog0("Hardwaretree-Interface not found. A newer OS is required for Safety-Modules");
      end_if;
#endif
    end_if;

    HandleNrCy := 0;

    ReadAllKenn();  // must be done in the constructor

  END_IF;

  ret_code	:= C_OK;

END_FUNCTION


#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::InitChip
  VAR
    Temp : DINT;
  END_VAR

// *****************************************
//  all programms off and chip on risk off
// *****************************************

  (_IOSegment$^USINT + DmControl)^  :=  1;  // Chip On, Risc Off
  (_IOSegment$^USINT + DmState)^    :=  0;  // All Programms OFF


// **********************************************
//  set period time of PLL
// **********************************************

// Pll Periode is overwritten later by realtime time of object
  (_IOSegment$^USINT + DmPllSyncDel)^  :=  (1000/DmTmrResso - 975/DmTmrResso);
  (_IOSegment$^USINT + DmPllPeriode)^  :=  ops.RtInterv_mSec$USINT;
  

// ****************************************************
//  we divide the complete memory into 3 fixed parts (1/4 for Cy Calls, 1/4 for Rt Calls and 1/2 for RtCy Code)
// ****************************************************

  (_IOSegment$^UINT + DmCyStartAdrM0)^   := 0; // Cyclic Start at Adr 00

  ud_IMMemory := (((_IOSegment$^USINT + DmCR_ProgMem)^ SHR 1) SHL 10);  // wieviel programm speicher haben wir
  (_IOSegment$^UINT + DmRtStartAdrM0)^ := (ud_IMMemory SHR 2)$UINT;


// *********************************
//  mov the IP to start destination
// *********************************

  StartOfCode := ud_IMMemory$DINT SHR 1;  // we use 2nd half of memory for the code => divide memory by 2

  Temp := (_IOSegment$^UINT + DmCyStartAdrM0)^;
  (_IOSegment$^UINT + DmCyProgCntrM0)^ := Temp$UINT; // CycPrgCntr = CycStart
  StartOfCy := Temp;


  Temp := (_IOSegment$^UINT + DmRtStartAdrM0)^;
  (_IOSegment$^UINT + DmRtProgCntrM0)^ := Temp$UINT; // RtPrgCntr = RtStart
  StartOfRt := Temp;

  (_IOSegment$^USINT + DmControl)^     := 2#11;   // Chip On, Risc On

END_FUNCTION
#else
FUNCTION  AWL DiasMasterMain::InitChip

  L.EDI      _IOSegment

// *****************************************
//  all programms off and chip on risk off
// *****************************************

	L.B		    (EDI+DmControl),1		// Chip On, Risc Off
	L.B		    (EDI+DmState)  ,0	    // All Programms OFF
  
// **********************************************
//  set period time of PLL
// **********************************************

	L.B		    (EDI+DmPllSyncDel),(1000/DmTmrResso  - 975/DmTmrResso)


// is overwritten later by realtime time of object
	L		      Ops.RtInterv_mSec+0		// Set Pll Periode 
	S		      (EDI+DmPllPeriode)

// ****************************************************
//  we divide the complete memory into 3 fixed parts (1/4 for Cy Calls, 1/4 for Rt Calls and 1/2 for RtCy Code)
// ****************************************************

	L.W			  (EDI+DmCyStartAdrM0), 0   // Cyclic Start at Adr 00

	LZXB.eAX	(EDI+DmCR_ProgMem)		// wieviel programm speicher haben wir	
	shr.eax		1									//#SR004
  shl.eax		8
	s.ax		  (EDI+DmRtStartAdrM0)
  shl.eax		2									//#SR004
	s.eax		  ud_IMMemory							//#SR004


// *********************************
//  mov the IP to start destination
// *********************************

  shr.eax   1  // we use 2nd half of memory for the code => divide memory by 2
  s.eax     StartOfCode


	LZXW.EAX	(EDI+DmCyStartAdrM0)
	S.AX		  (EDI+DmCyProgCntrM0)     // CycPrgCntr = CycStart
	s.eax		  StartOfCy

	LZXW.EAX	(EDI+DmRtStartAdrM0)
	S.AX		  (EDI+DmRtProgCntrM0)     // RtPrgCntr = RtStart
	s.eax		  StartOfRt

	L.B			  (EDI+DmControl),3	   // Chip On, Risc On


END_FUNCTION
#endif

//[English]
// reads all identification codes 
//[Globals]		_RTOSVersion		:R		:OS version
//				_DiasConfig			:R/W	:configuration array (filled by OS)
//				_WhoAmI				:R		:CPU identification
//				OPS					:R		:OS variable
//[Members]		FirstModuleFound	:W		:determine a place on the bus where a modules is connected
//			(s) Release				:R		:Hardware + Software release
//[Locals]		MyTAbsolute			:R/W	:for a fixed time delay
FUNCTION  DiasMasterMain::ReadAllKenn
  VAR
    i           : usint;		//ws005
    MyTabsolute : DINT;
  END_VAR

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then	
		FirstModulFound := 16#ff;				//ws005
		for i := 0 to 62 do 
			if( _DiasConfig[ i ] <> 255 )then 	// read directly from the DiasConfig 
				FirstModulFound := i;           // which is provided by the OS
			end_if;								// this is in fact the last module in the array => does not matter
		end_for;
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
		if Release <> 16#ffffffff then 
			//ws004
			if( ( _WhoAmI = 16#19 ) | ( _WhoAmI = 16#17 ) )then //ET261 and ETT321

				FirstModulFound := 16#ff;	//ws005
				for i := 0 to 62 do 
					if( _DiasConfig[ i ] <> 255 )then 	// read directly from the DiasConfig 
						FirstModulFound := i;           // which is provided by the OS
					end_if;								// this is in fact the last module in the array => does not matter
				end_for;

			else
			// /ws004
				// dummy weil bus noch nicht laufen könnte 
				ReadKenn(0); 	
				MyTabsolute := OPS.tAbsolute$DINT;
				while ((OPS.tabsolute - MyTabsolute$udint) < 50) do	//ws008
				end_while;; 
				ReadKenn(0);    

				// ************************************************ 
				// jetzt laufen alle Karten sicher 
				// und darum können wir jetzt die Kennung lesen
				// ************************************************ 

				FirstModulFound := 16#ff;	//ws005

				For i:=0 to 62 do  
					_Diasconfig[i] := to_USINT(ReadKenn(i));
					if _Diasconfig[i] <> 255 then
						FirstModulFound :=i;
					end_if;	
				end_for;

				_Diasconfig[63]:=16#FF;  // sicher nicht da 
				Return;

			end_if;
  
		else
		// otherwise you get problem on old DiasMasterMain + disable master = offline 
			FirstModulFound :=16#FF;
			For i:=0 to 62 do  
				_Diasconfig[i] := 16#FF;
			end_for; 
		end_if;
	end_if;

END_FUNCTION
//[English]
// reads the identification code of one module
//[Globals]		_RTOSVersion		:R		:OS version
//				_lsl_pos			:R		:OS interface structure
//[Members]
//[Locals]
//[>Place]		Place on bus
//[<Kenn]		ID code
#pragma warning (disable:73) 
#pragma warning (disable:76) 
FUNCTION DiasMasterMain::ReadKenn
  VAR_INPUT
    Place		: DINT;
  END_VAR
  VAR_OUTPUT
    Kenn		: DINT;
  END_VAR
#ifdef _LSL_TARGETARCH_X86

	if( ImOff = 1 )then // Master is off
		Kenn := 16#ff;
		return;
  	end_if;

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	if( _RTOSVersion >= OSVersionDIASIO )then	
		if( pDIAS = NIL )then // OS has no Dias Interface (for now only CCL081)
			Kenn := 16#ff;
			return;
		end_if;
		Kenn := OS_DIAS_ReadKenn( pDIAS, Place$usint ); // OS function suits best
	else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
		if( ( _WhoAmI = 16#19 ) | ( _WhoAmI = 16#17 ) )then //ET261 and ETT221
			Kenn := OS_DIAS_ReadKenn( pDias, Place$usint ); // OS function suits best
		else	//compatible mode
			TraceAsyncError(Place$usint);
		end_if;
  end_if;
#endif

END_FUNCTION
#pragma warning (default:73)
#pragma warning (default:76)
// /ws004

//[#ENGLISH]
//Diese Funktion prüft ob der Master vorhanden ist und wenn ja trägt Sie
//die HW und Software Kennung in Release ein
//
//IPC: (Hardware and software release)
//Bit 0-15   in Release ist Software Version // #BS016
//Bit 16-31  in Release ist Hardware Version
//
//C-IPC: (only one vlaue for hardware and software release)
//Bit 0-7 
//
//Release = 16#FFFFFFFF ( Fehler Master nicht vorhanden)
//
//
#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::TestMasterIM
  VAR_OUTPUT
    MasterOK		: UINT;
  END_VAR

#ifndef DIAS_MASTER_PCI

  MasterOK := FALSE;
  Release := 16#FFFFFFFF;
  
  if DiasType <> 2 then                     // --> bereits erkannt über schnittstelle
    //---- Das Macht Später das BetrSyst !!---
    To_OSKernel.OutWord(Portnumber:=16#210, value:=(_IOSegment SHR 4)$UINT);  // Den CHIP In Den I/O Bereich legen
    To_OSKernel.OutByte(Portnumber:=16#212, value:=1);                        // Turn Chip
    if To_OSKernel.InWord(Portnumber:=16#21E) <> 16#494D then                 // "IM"
      return;
    end_if;
  end_if;

#endif

  if (_IOSegment$^UINT + DMID)^ <> 16#494d then // "IM"
    return;
  end_if;
  
  if CDiasType = 2 then
    Release := GetVerIMCIPC();
  else
    Release := (_IOSegment$^USINT + DMXVER)^;
  end_if;
  
  (_IOSegment$^USINT + DMCMDBUF1)^ := 3;  // Command Buffer Init mit Error
  (_IOSegment$^USINT + DMCMDBUF2)^ := 3;  // Command Buffer Init mit Error
  MasterOK := TRUE;

END_FUNCTION
#else
FUNCTION AWL  DiasMasterMain::TestMasterIM
  VAR_OUTPUT
    MasterOK		: UINT;
  END_VAR


#ifdef DIAS_MASTER_PCI
//
//	THR Aug. 21, 2003
//	To get a plug-in PCI card to work at D0000, bypass the "port"
//	test!!!
//	only on PC's with PCI412 and PCI402

	jmp				TestMasterGo
//
#endif	// DIAS_MASTER_PCI

	l.w			  MasterOK,FALSE
	l.d			  Release,16#ffffffff  	// Error 

	cmp.b		  DiasType,2				//ws005	
	je			  TestMasterGo			// --> bereits erkannt über schnittstelle 

//---- Das Macht Später das BetrSyst !!---

	L.DX		  16#210					// Den CHIP In Den I/O Bereich Legen
	L.EAX		  _IOSegment
	SHR.EAX		4
	OUTW

	L.DX		  16#212					// Turn Chip
	L			    16#01
	OUTB

	l.dx		  16#21E
	inw
	cmp.ax 		16#494d					// "IM"
	jne			  TestMasterIMError		// --> no intelligent Master


//----------------------

TestMasterGo
	l.EDI		  _IOSegment
	l.ax 		  (EDI+DmID)
	cmp.ax 		16#494d					// "IM"
	jne			  TestMasterIMError
	CMP.b		  CDiasType,2 // #BS 100903	//ws005
	JE			  CIPCRelease

	// 	IPC
	clr			  eax
	l			    (EDI+DmXver)			// Xilinx  Version
	JMP			  CMDInitError

CIPCRelease
// #BS 100903 for C-IPC
	FC			  GetVerIMCIPC
			
CMDInitError
	s.eax		  Release 

	l.b			  (EDI+DmCmdBuf1),3			// Command Buffer Init mit Error		//#SR017
	l.b			  (EDI+DmCmdBuf2),3			// Command Buffer Init mit Error 		//#SR017
	l.w			  MasterOK,TRUE

TestMasterIMError

END_FUNCTION
#endif
//
// --> ebx is this pointer 
//     edx is IPSUB
//     ecx is IPMAIN
// --> ax mode reg  bit 0  = RT or Cyclic
//        			bit 14 =
// 					bit 15 = Main or Sub     
//     edi thispointer
//
// <-- EAX is handle it is a direct pointer to the programm in the master
//

#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::GetHandle
  VAR_INPUT
    Offset        : UDINT;
    callOptions 	: USINT;
  END_VAR
  VAR
    pHandle       : ^OneHandle;
    SizeRtPostScan: DINT;
    SizeRt        : DINT;
    SizeCy        : DINT;
  END_VAR

  if ARM_EAX AND DmRealtime then
    // ** we put it into the realtime handlers **
    if callOptions AND CALL_OPTION_RT_POSTSCAN then
      SizeRtPostScan := HandleNrRtPostScan * sizeof(OneHandle);
      
      if SizeRtPostScan >= sizeof(HandlesRTPostScan) then
        //BLEERN - let the system crash if we try to allocate too many handles!
        pHandle$UDINT :=  0;
        pHandle$^UDINT^ := 0;
      end_if;
      
      pHandle := #HandlesRTPostScan[0] + SizeRtPostScan;
      pHandle^.Typ   := ARM_EAX$UINT;
      pHandle^.thisp := ARM_EDI$^HwBase;
      
      if ARM_EAX AND DmCallProg then    // test if it is Main Prog
        pHandle^.Address := (IPMainRT + StartOfRt + Offset$DINT)$UINT;
        ARM_EAX := pHandle^.Address;
      else
        pHandle^.Address := (IPSub + StartOfCode + Offset$DINT)$UINT;
        ARM_EAX := pHandle^.Address;
      end_if;

      HandleNrRtPostScan += 1;  
    end_if;

    if callOptions AND CALL_OPTION_RT_PRESCAN then
      SizeRt := HandleNrRt * sizeof(OneHandle);
      
      if SizeRt >= sizeof(HandlesRT) then
        //BLEERN - let the system crash if we try to allocate too many handles!
        pHandle$UDINT :=  0;
        pHandle$^UDINT^ := 0;
      end_if;
      
      pHandle := #HandlesRT[0] + SizeRt;
      pHandle^.Typ   := ARM_EAX$UINT;
      pHandle^.thisp := ARM_EDI$^HwBase;
    
      if ARM_EAX AND DmCallProg then  // test if it is Main Prog
        pHandle^.Address := (IPMainRT + StartOfRt + Offset$DINT)$UINT;
        ARM_EAX := pHandle^.Address;
      else
        pHandle^.Address := (IPSub + StartOfCode + Offset$DINT)$UINT;
        ARM_EAX := pHandle^.Address;
      end_if;
    
      HandleNrRT += 1;  
    end_if;

  else
    // ** we put it into the Cyclic handlers **
    SizeCy := HandleNrCY * sizeof(OneHandle);
      
    if SizeCy >= sizeof(HandlesCY) then
      //BLEERN - let the system crash if we try to allocate too many handles!
      pHandle$UDINT :=  0;
      pHandle$^UDINT^ := 0;
    end_if;

    pHandle := #HandlesCY[0] + SizeCy;
    pHandle^.Typ   := ARM_EAX$UINT;
    pHandle^.thisp := ARM_EDI$^HwBase;
    
    if ARM_EAX AND DmCallProg then  // test if it is Main Prog
      pHandle^.Address := (IPMainCY + StartOfCy + Offset$DINT)$UINT;
      ARM_EAX := pHandle^.Address;
    else
      pHandle^.Address := (IPSub + StartOfCode + Offset$DINT)$UINT;
      ARM_EAX := pHandle^.Address;
    end_if;
    
    HandleNrCY += 1;  
  end_if;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::GetHandle
	VAR_INPUT
		Offset 	    : UDINT;
		callOptions : USINT;
	END_VAR
  VAR
  	mode        : UDINT;
    old_ecx     : UDINT;
  END_VAR

	push		  edx
	push		  ecx

	clr			  ebx	

  s.ecx     old_ecx

  s.eax     mode

	test.ax		Dmrealtime						// test if it is a realtime handle or not
	jnz			  GetHandleRTPostScan						// --> it is a realtime handle				
	
// ** we put it into the Cyclic handlers **

	lzxw.ebx	HandleNrCY

//BLEERN - let the system crash if we try to allocate too many handles!
  cmp.ebx   (SIZEOF(HandlesCY) / SIZEOF(OneHandle))
  jne       HandleCyOK
  xor.edi   edi
  l.w       (edi), 0
HandleCyOK
//END BLEERN - let the system crash if we try to allocate too many handles!
    
  imul.ebx	ebx, sizeof (OneHandle)			
	push		  edi
	l.edi		  #handlescy					   // there is an compiler error 				
	add.ebx	  edi							   // this is the reason wy we do this different
	pop			  edi

	s.ax		  (ebx+OneHandle.Typ)
	s.edi		  (ebx+OneHandle.thisp)	  

	test.ax		DmCallProg	    				// test if it is Main Prog
	jz			  getHandleCySB
	add.ecx		StartOfCy
	add.ecx		offset
	s.cx		  (ebx+OneHandle.Address)
	l.eax		  ecx  
	jmp			  getHandleCyMain

getHandleCySB
	add.edx		StartOfCode
	add.edx		offset
	s.dx		  (ebx+OneHandle.Address)  
	l.eax		  edx
getHandleCyMain

	inc.w		  HandleNrCY
  
	jmp			  GetHandleRet

// ** we put it into the realtime handlers **


GetHandleRTPostScan

  test.     b callOptions, CALL_OPTION_RT_POSTSCAN
  jz        GetHandleRT

  lzxw.ebx	HandleNrRtPostScan
  
//BLEERN - let the system crash if we try to allocate too many handles!
  cmp.ebx   (SIZEOF(HandlesRTPostScan) / SIZEOF(OneHandle))
  jne       HandleRTPostScanOk
  xor.edi   edi
  l.w       (edi), 0
HandleRTPostScanOK
//END BLEERN - let the system crash if we try to allocate too many handles! 
  
	imul.ebx	ebx, sizeof (OneHandle)			
	push		  edi
	l.edi		  #HandlesRTPostScan					   // there is an compiler error 				
	add.ebx		edi							   // this is the reason wy we do this different
	pop			  edi

	s.ax		  (ebx+OneHandle.Typ)
	s.edi		  (ebx+OneHandle.thisp)	  

	test.ax		DmCallProg						// test if it is Main Prog
	jz			  getHandleRtPostScanSB
	add.ecx		StartOfRt
	add.ecx		offset
	s.cx		  (ebx+OneHandle.Address)  
	l.eax		  ecx								// handle		
	jmp			  getHandleRtPostScanMain

getHandleRTPostScanSB
	add.edx		StartOfCode
	add.edx		offset
	s.dx		  (ebx+OneHandle.Address) 
	l.eax		  edx 

getHandleRtPostScanMain
	inc.w		  HandleNrRTPostScan

GetHandleRT

  test.b    callOptions, CALL_OPTION_RT_PRESCAN
  jz        GetHandleRet
  
  l.eax     mode
  l.ecx     old_ecx
	
  lzxw.ebx	HandleNrRt
  
//BLEERN - let the system crash if we try to allocate too many handles!
  cmp.ebx   (SIZEOF(HandlesRT) / SIZEOF(OneHandle))
  jne       HandleRTOk
  xor.edi   edi
  l.w       (edi), 0
HandleRTOK
//END BLEERN - let the system crash if we try to allocate too many handles!  
  
	imul.ebx	ebx, sizeof (OneHandle)			
	push		  edi
	l.edi		  #handlesrt					   // there is an compiler error 				
	add.ebx		edi							   // this is the reason wy we do this different
	pop			  edi

	s.ax		  (ebx+OneHandle.Typ)
	s.edi		  (ebx+OneHandle.thisp)	  

	test.ax		DmCallProg						// test if it is Main Prog
	jz			  getHandleRtSB
	add.ecx		StartOfRt
	add.ecx		offset
	s.cx		  (ebx+OneHandle.Address)  
	l.eax		  ecx								// handle		
	jmp			  getHandleRtMain

getHandleRTSB
	add.edx		StartOfCode
	add.edx		offset
	s.dx		  (ebx+OneHandle.Address) 
	l.eax		  edx 

getHandleRtMain
  
	inc.w		  HandleNrRT  
  
GetHandleRet
	pop			  ecx
	pop			  edx

END_FUNCTION
#endif

FUNCTION AWL DiasMasterMain::GetProgPointer
#ifdef _LSL_TARGETARCH_X86

// it is in the cyclic
	
	l.ebx		PtrCY
	l.edx   IPSub
	l.ecx		IPMainCy
	test.AX		Dmrealtime
	jz			GetProgP_Cy

// it is in the Realtime			
	l.ebx		PtrRT
	l.ecx		IPMainRT
GetProgP_Cy
#endif
END_FUNCTION
//
//
//  --> ax is mode byte (realtime or cyclic)
//		ECX = IP of the Mainprog
//		EDX = IP of the subprog 
FUNCTION AWL DiasMasterMain::StoreNewPointers
#ifdef _LSL_TARGETARCH_X86
	s.edx		  IPSub
	and.ax		DmRealtime
	jnz			  StoreNewPRT		// --> realtime
	s.ecx		  IPMainCY
	jmp			  StoreNewRet

StoreNewPRT					
	s.ecx		  IPMainRT
StoreNewRet
#endif
END_FUNCTION
// ****************************************
//   einmal das programm linken 
// ****************************************
// the main and the subprogramms are linked together
// also the calls are linked with the absolute adresse  
#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::LinkMaster
  VAR
  	pSINT : ^SINT;
  END_VAR


// ****************************************
//   add the "END" to the cyclic programm 
// ****************************************

  (#CallsCY[0] + IPMainCY)^ := dbEnd;
  IPMainCY += 1;

// *******************************************************
//   add the "JMP to Begin" to the RT Programm 
//   + mov timer to RAMCELL to calculate the right timing 
// *******************************************************

  pSINT := #CallsRT[0] + IPMainRT;
  (pSINT + MovStruct.Opc)^        := dbMov;
  (pSINT$^UINT + MovStruct.Srce)^  := DmPllTmrAct;
  (pSINT$^UINT + MovStruct.Dest)^  := DmUserData;

  pSINT    += sizeof(MovStruct);
  IPMainRt += sizeof(MovStruct);
  
  ud_DelayRealtime += C_TimeMove;
  
  // Mark realtime task of intelligent master as inactive
  (pSINT + MovStruct.Opc)^        := dbMov;
  (pSINT$^UINT + MovStruct.Srce)^  := DmUserData + 2;
  (pSINT$^UINT + MovStruct.Dest)^  := DmUserData + 3;
  
  pSINT    += sizeof(MovStruct);
  IPMainRt += sizeof(MovStruct);

  ud_DelayRealtime += C_TimeMove;


  (pSINT + JmpStruct.Opc)^          := dbJmp;
  (pSINT$^UINT + JmpStruct.Adress)^  := StartOfRt$UINT;

  IPMainRT += sizeof(JmpStruct);

  ud_DelayRealtime += C_TimeJump;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::LinkMaster
  VAR
    SizeofMainCY : DINT;
    SizeofMainRT : DINT;
  END_VAR



// ****************************************
//   add the "END" to the cyclic programm 
// ****************************************

	l.ebx		  IPMainCy
	l.edi		  #CallsCY
	l.b			  (ebx+edi),dbend
	inc.d		  IPMainCy

// *******************************************************
//   add the "JMP to Begin" to the RT Programm 
//   + mov timer to RAMCELL to calculate the right timing 
// *******************************************************

	l.ebx		  IPMainRt
	l.edi		  #CallsRt

	l.b			  (ebx+edi+MovStruct.Opc),dbMov
	l.w			  (ebx+edi+MovStruct.Srce),DmPllTmrAct
	l.w			  (ebx+edi+MovStruct.Dest),DmUserData

	add.ebx		sizeof (MovStruct)
	add.d		  IPMainRT, sizeof (MovStruct)

	ADD.D		  ud_DelayRealtime,C_TimeMove		//#SR001

	//#SR010 start Mark realtime task of intelligent master as inactive
	l.b			  ( ebx + edi + MovStruct.Opc ), dbMov
	l.w			  ( ebx + edi + MovStruct.Srce ), DmUserData + 2
	l.w			  ( ebx + edi + MovStruct.Dest ), DmUserData + 3
  
	add.ebx		sizeof (MovStruct)
	add.d		  IPMainRT, sizeof (MovStruct)

	ADD.D		  ud_DelayRealtime,C_TimeMove
	//#SR010 end

	l.b			  (ebx+edi+JmpStruct.Opc),dbJmp
	l.eax		  startofrt
	s.ax		  (ebx+edi+JmpStruct.Adress)

	add.d		  IPMainRT, sizeof (JmpStruct)

	ADD.D		  ud_DelayRealtime,C_TimeJump		//#SR001

END_FUNCTION
#endif

// ********************************************************
//  .. load the cyclic programm in to the master
// ********************************************************
#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::LoadCyclicProg
  VAR
    Counter : DINT;
    pCalls  : ^USINT;
    pProg   : ^USINT;
    pUSINT  : ^USINT;
  END_VAR

  // with help variable we get only half of the ARM assembler code for the assignment
  pUSINT := _IOSEGMENT$^USINT + DmState;
  pUSINT^ := pUSINT^ AND 16#0F;   // all cyclic programs OFF
  
  pProg := _IOSEGMENT$^USINT + (_IOSEGMENT$^UINT + DmCyStartAdrM0)^;  // load start of program
  
  pCalls  := #CallsCY[0];
  Counter := IPMainCY + 1;
  
  while Counter do
    pProg^ := pCalls^;
    
    pCalls += 1;
    pProg += 1;
    Counter -= 1;
  end_while;
  
END_FUNCTION

#else
FUNCTION AWL DiasMasterMain::LoadCyclicProg


	L.EDI		  _IOSEGMENT
	L.AL		  (EDI+DmState)           // All Cyclic Programms OFF
	and.al		16#0f
	S.AL		  (EDI+DmState)    

	clr			  ebx
	L.BX		  (EDI+DmCyStartAdrM0)      // load start of programm
	
	l.edx		  #CallsCY
	l.ecx		  IPMainCY
	inc			  ecx
	
LoadCyLoop
	l.al		  (edx)
	s.al		  (ebx+edi)
	inc			  ebx
	inc			  edx
	loop		  LoadCyLoop

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::StartCyclicProg
  VAR
  	pUSINT  : ^USINT;
  END_VAR

  // with help variable we get only half of the ARM assembler code
  pUSINT := _IOSEGMENT$^USINT + DmState;

  // Cyclic Programms ON Master 1
  pUSINT^ := pUSINT^ OR 16#10;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::StartCyclicProg

	L.EDI		_IOSEGMENT
	L.AL		(EDI+DmState)           // Cyclic Programms ON Master 1
	OR.AL		16#10
	S.AL		(EDI+DmState)    

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::StartRealtimeProg
  VAR
  	pUSINT  : ^USINT;
  END_VAR

  // with help variable we get only half of the ARM assembler code
  pUSINT := _IOSEGMENT$^USINT + DmState;

  // Realtime Programms ON Master 1
  pUSINT^ := pUSINT^ OR 16#01;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::StartRealtimeProg

	L.EDI		_IOSEGMENT
	L.AL		(EDI+DmState)           // Cyclic Programms ON Master 1
	OR.AL		16#01
	S.AL		(EDI+DmState)    

END_FUNCTION
#endif

// ********************************************************
//  .. load the cyclic programm into the master
// ********************************************************
FUNCTION DiasMasterMain::LoadRealtimeProg
  VAR
    Counter : DINT;
    pCalls  : ^USINT;
    pProg   : ^USINT;
    pUSINT  : ^USINT;
  END_VAR

  // with help variable we get only half of the ARM assembler code for the assignment
  pUSINT := _IOSEGMENT$^USINT + DmState;
  pUSINT^ := pUSINT^ AND 16#F0;   // all realtime programs OFF
  
  pProg := _IOSEGMENT$^USINT + (_IOSEGMENT$^UINT + DmRtStartAdrM0)^;  // load start of program
  
  pCalls  := #CallsRT[0];
  Counter := IPMainRT + 1;
  
  while Counter do
    pProg^ := pCalls^;
    
    pCalls += 1;
    pProg += 1;
    Counter -= 1;
  end_while;

END_FUNCTION


FUNCTION  DiasMasterMain::CallUpdata
  VAR_INPUT
    Thisp		  : pHwBase;
    Handle		: UDINT;
  END_VAR

	thisp^.updatecy(handle);

END_FUNCTION
FUNCTION  DiasMasterMain::CallUpdataRT
  VAR_INPUT
    Thisp		  : pHwBase;
    Handle		: UDINT;
  END_VAR

	thisp^.updatert(handle);
  
END_FUNCTION

//[#ENGLISH]
//0= connected direct to master
//1= connected via CIC
//
//
//-1 = fault
FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetConnection
  VAR_OUTPUT
    CType		: DINT;
  END_VAR
  
	CType :=0;		// we are the main controller
  
END_FUNCTION

//[#ENGLISH]
//read one Byte from C-DIAS bus on Board
#pragma warning (disable:73) 
FUNCTION VIRTUAL GLOBAL DiasMasterMain::I2CReadOneByte
  VAR_INPUT
    AdressCDIAS	: UINT;
    pData		    : ^USINT;
  END_VAR
  VAR_OUTPUT
    result		  : DINT;
  END_VAR
  
	result:=-1;

END_FUNCTION
#pragma warning (default:73) 

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetEEState
  VAR_OUTPUT
    State		: DINT;
  END_VAR

	State := CDiasType;

END_FUNCTION 

#pragma warning (disable:73) 
FUNCTION VIRTUAL GLOBAL DiasMasterMain::ReadEEData
  VAR_INPUT
    Adress		: UDINT;
    pData		  : ^USINT;
  END_VAR
  VAR_OUTPUT
    retval		: DINT;
  END_VAR

	retval := -1;

END_FUNCTION
#pragma warning (default:73) 

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddCall2List
  VAR_INPUT
    Mode		    : UINT;
    RTCY		    : DINT;
    thisp		    : ^void;
    callOptions : USINT;
  END_VAR
  VAR_OUTPUT
    Handle		  : DINT;
  END_VAR

  if (RTCY AND DmRealtime) = DmRealtime then 
    ARM_EAX := RTCY$UDINT OR DmCallProg;
    ARM_EDI := thisp$UDINT;
    GetHandle(HandleNrRT, callOptions);
    Handle := ARM_EAX$DINT;
  else    
    ARM_EAX := RTCY$UDINT OR DmCallProg;
    ARM_EDI := thisp$UDINT;
    GetHandle(HandleNrCY, callOptions);
    Handle := ARM_EAX$DINT;
  end_if;
  
END_FUNCTION

#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddCall2List
	VAR_INPUT
		Mode 	      : UINT;
		RTCY 	      : DINT;
		thisp 	    : ^void;
		callOptions : USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	    : DINT;
	END_VAR

	l.ecx		  16#8000					//Because we got equal handles and ecx register wasn't set //#SR000
	
	l.ax		  RTCY+0
	or.ax		  DmCallProg				// this is in the Main	
	l.edi		  thisp					

    // changed not CallStruct.Mode because we need for each add call a different number
    // and therefore we take IP off programm 
	
	test.ax		Dmrealtime
	jnz			  AddCall2ListRT
	lzxw.ebx	HandleNrCY
	jmp			  AddCall2ListCy
AddCall2ListRT
	lzxw.ebx	HandleNrRT
AddCall2ListCy

  push.b    callOptions

	push		  ebx		
	call		  GetHandle
  add.esp   5
	s.eax		  handle

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::CyWorkStdMas
  VAR
#ifdef TRIGGER_WD_386_IN_CYCLIC
    TempAL    : SINT;
#endif
    TempEBX   : DINT;
    i         : UDINT;
    pHandle   : ^OneHandle;
  //-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
    MuSecTime : UDINT;
  END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_CY.init > DM_ProfilerDelay then
    DMC_Time_CY.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_CY.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_CY.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
  END_VAR
#endif

  WriteRTLogs();

  if ops.tAbsolute <> OldTime then
  
#ifdef TRIGGER_WD_386_IN_CYCLIC
// ** hier mal den watchdog triggern ** #FA  (Watchdog der CCL)	
//ist interner CPU Watchdog --> kein Abfall der Hardware wenn nicht getriggert wird

    if (_WhoAmI = 16#23) |  (_WhoAmI = 16#27) | (_WhoAmI = 16#28) | (_WhoAmI = 16#29) then
      if _RTOSVersion >= OSVersionDIASIO then
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
        CCLWatchdog_Trigger();
      else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
        TraceAsyncError();
      end_if;
    end_if;
#endif


// **************************************************
//  now take data and call update function with thisp 
// **************************************************
    CyclicReady := TRUE;
    
    if HandleNrCy then
      pHandle := #HandlesCY[0];  
      
      for i := 0 to HandleNrCy-1 do
        if pHandle^.Typ AND DmCallProg then
          pHandle^.thisp^.UpdateCy(pHandle^.Address);
        end_if;
        
        pHandle += sizeof(OneHandle);
      end_for;
    end_if;
      
    if _RTOSVersion >= OSVersionDIASIO then
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
      UpdateRetryCounter();
    else
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
      if (_WhoAmI = 16#17) | (_WhoAmI = 16#19) then
        UpdateRetryCounter();
      else
        if _IOSegment then
          if _IOSegment = 16#D0000 then
            TraceAsyncError();
          else
            TempEBX := to_DINT((_IOSegment$^SINT + 16#C008)^);
          end_if;

          DIASRetryCounter += TempEBX$USINT - oldErrorCounter$USINT;
          oldErrorCounter := TempEBX;
        end_if;
      end_if;
    end_if;
  end_if;
  OldTime := ops.tAbsolute;

  // look if we got the pointer to the safety manager
  if SafetyManagerThis then
    // call safety manager  
    SafetyManagerThis^.CyWork(0);
  end_if;

//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_CY.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_CY.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_CY.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_CY.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_CY.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_CY.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_CY._min then
      DMC_Time_CY._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_CY._max then
      DMC_Time_CY._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_CY.avg := DMC_Time_CY.sum * 100 / DMC_Time_CY.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
  
END_FUNCTION

#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::CyWorkStdMas


//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_CY.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_CY.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_CY.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_CY.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	
//============================ Profiler end========================================================

  cmp.b     SkipCy,1
  je        NoLocalSafety2

	l.eax		  OPS.Tabsolute
	cmp.eax		oldtime
	je			  NoCyclProgEnd // #BS003
	s.eax		  oldtime

#ifdef TRIGGER_WD_386_IN_CYCLIC

// ** hier mal den watchdog triggern ** #FA  (Watchdog der CCL)	
//ist interner CPU Watchdog --> kein Abfall der Hardware wenn nicht getriggert wird


 	CMP.D		  _WhoAmI,16#23 // #BS003
	
	//#SR002 Start	
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#27
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#28
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#29
	jne			  NoCCLWatchdog

CCLWatchdog
	//#SR002 End
				
	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	cmp.d		  _RTOSVersion, OSVersionDIASIO
	jl			  LABEL_OLDWD
  call    	CCLWatchdog_Trigger	
	jmp			  NoCCLWatchdog

LABEL_OLDWD
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
							
	l.dx		  16#f862
	inb
	or			  16#40
	outb
	and			  2#10111111
	outb
	// /ws005

NoCCLWatchdog
#endif


// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b 		  CyclicReady,1	//ws005

	l.ebx		  #HandlesCY
	lzxw.ecx	HandleNrCy
	jecxz		  NoCyclProg

HandleLoop
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandle

	push		  ecx
	push		  ebx

	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax
	call		  CallUpdata
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandle	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoop
NoCyclProg


//ws004

	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	cmp.d		  _RTOSVersion, OSVersionDIASIO
	jl			  LABEL_OLDUPDATE
  call      UpdateRetryCounter	// this function will also run with ETT321 and ET261
	jmp			  NoCyclProgEND

LABEL_OLDUPDATE
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	cmp.d		  _WHOAMI, 16#19
	je			  LABEL_ET2XX
	cmp.d		  _WHOAMI, 16#17
	je			  LABEL_ET2XX
	jmp			  LABEL_CONT

LABEL_ET2XX
	call      UpdateRetryCounter	// this function will also run with ETT321 and ET261
	jmp		    NoCyclProgEND

LABEL_CONT
	// /ws005

// #BS003 Start
// #BS007 Start
	L.EDI		  _IOSegment
	//#SR019 start				//if _IOSegment = 0 we do not update retry counter
	o.edi		  edi
	jz			  NoCyclProgEND
	//#SR019 end

	CMP.EDI		16#D0000
	JNE			  Retry386
	PUSHF
	CLI

	l.dx		  16#335
	l			    1 // switch to control
	outb

	LZXB.EBX	(edi+16#4008)

	l.dx		  16#335
	clr			  al
	outb

	POPF
	JMP			  UpdateCount
Retry386
	Lzxb.ebx	(EDI+16#C008)

UpdateCount
// #BS007 End
	l.eax		  oldErrorCounter
	s.ebx		  oldErrorCounter
// #BS016 Start
	sub.bl		al
	lzxb.ebx	bl
	add.d		  DIASRetryCounter,eBx
NoCyclProgEND
// #BS003 End
  
  // look if we got the pointer to the safety manager
  cmp.d     SafetyManagerThis, 0
  je        NoLocalSafety2

  // call safety manager  
  CALL      CallSafetyManager
  
NoLocalSafety2

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_CY.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			  LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_CY.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_CY.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_CY.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_CY.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_CY.sum					//Summe speichern
	l.ecx		  DMC_Time_CY.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_CY.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_CY._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_CY._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_CY._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_CY._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_CY.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::RtWorkStdMas
#ifdef DM_DEBUG_ARM
  // This method is not supported with ARM
  ((0)$^USINT)^ := 0;
#endif
END_FUNCTION
#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::RtWorkStdMas

//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_RT.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_RT.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_RT.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_RT.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	
//============================ Profiler end========================================================
  cmp.b			b_PllInit, TRUE
	je				LABEL_NoStart

	//in first run we start pll
	call			StartPll
	l.b				b_PllInit, TRUE
LABEL_NoStart

#ifndef TRIGGER_WD_386_IN_CYCLIC

// ** hier mal den watchdog triggern ** #FA  (Watchdog der CCL)	
//ist interner CPU Watchdog --> kein Abfall der Hardware wenn nicht getriggert wird


 	CMP.D		  _WhoAmI,16#23 // #BS003
	
	//#SR002 Start	
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#27
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#28
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#29
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#35
	je			  CCLWatchdog
	cmp.d		  _WhoAmI,16#34
	jne			  NoCCLWatchdog

CCLWatchdog
	//#SR002 End
				
	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	cmp.d		  _RTOSVersion, OSVersionDIASIO
	jl			  LABEL_OLDWD
  	call   	CCLWatchdog_Trigger	
	jmp			  NoCCLWatchdog

LABEL_OLDWD
	//*****************************************************
	//*** use own functions (should be obsolete by now) ***
	//*****************************************************
	// /ws005
							
	l.dx		  16#f862
	inb
	or			  16#40
	outb
	and			  2#10111111
	outb
	// /ws005

NoCCLWatchdog
#endif

#IFNDEF OldDiasXilinx // global sync
	l.ebx		  RTBSyncAdr
	o.ebx		  ebx
	jz			  RtNoRTB
	//ws005
	//*****************************************************
	//***** use OS functions instead of own functions *****
	//*****************************************************
	cmp.d		  _RTOSVersion, OSVersionDIASIO
	jl			  LABEL_MAYBEOLDUPDATE
	push.d		0     //data to write
	push.d		2     //offset
	push.d		63    //DIAS place
	l.eax		  pDIAS
	push		  eax   //DIAS structure
	call		  ( eax + 27 )  //call to OS function OS_DIAS_WriteCtrl_
	add.esp		16
	jmp			  RtNoRTB	

LABEL_MAYBEOLDUPDATE
	cmp.d		  _WHOAMI, 16#19
	je			  LABEL_ISETXX
	cmp.d		  _WHOAMI, 16#17
	jne			  LABEL_OLDUPDATE

LABEL_ISETXX
	push.d		0     //data to write
	push.d		2     //offset
	push.d		63    //DIAS place
	l.eax		  pDIAS
	push		  eax   //DIAS structure
	call		  ( eax + 27 )  //call to OS function OS_DIAS_WriteCtrl_
	add.esp		16
	jmp			  RtNoRTB	

LABEL_OLDUPDATE
  l.edi		  _ioSegment  //ws005
	s			    ( ebx + edi )

	// /ws005	

#ELSE // local sync
	LZXB.ECX	NumberSyncs
	JECXZ		  RtNoRTB

	L.EDX		  #RtbLocalSyncAdr[0]
SyncJMP
	l.edi		  _ioSegment  //ws005
	LZXW.EBX	(EDX)
	L.B			  (ebx+edi),1
	ADD.EDX		SIZEOF(HINT)
	LOOP		  SyncJMP
#ENDIF


RtNoRTB
// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b			  RealtimeReady,1		//ws005

	l.ebx		  #HandlesRt
	lzxw.ecx	HandleNrRt
	jecxz		  LABEL_RtPostScan

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRT
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

LABEL_RtPostScan

//BLEERN START
  cmp.d     HwControl, 0
  jne       NoRtProg
  
  call      UpdateRtPostScan
//BLEERN ENDE

NoRtProg

	FC			WDDIAS

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_RT.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			  LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_RT.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_RT.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_RT.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_RT.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_RT.sum					//Summe speichern
	l.ecx		  DMC_Time_RT.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_RT.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_RT._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_RT._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_RT._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_RT._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_RT.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetMasterType
  VAR_OUTPUT
    MasterType		: UDINT;
  END_VAR
  
  MasterType:=DiasType;
  
END_FUNCTION

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetCDiasIosegment
  VAR_OUTPUT
    CIOSegment		: ^USINT;
  END_VAR
  
  CIOSegment := CDiasHwPointer;
    
END_FUNCTION


#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::RtWorkStdMasIPC
#ifdef _LSL_TARGETARCH_X86
  VAR
    i         : DINT;
    pHandle   : ^OneHandle;
  #ifdef OldDiasXilinx
    pHINT     : ^HINT;
  #endif
  //-------------------------------------Profiler Start----------------------------------------------
  #ifdef DiasMasterC_Profiler
    MuSecTime : UDINT;
  END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_RT.init > DM_ProfilerDelay then
    DMC_Time_RT.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_RT.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_RT.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
  END_VAR
#endif

#IFNDEF OldDiasXilinx // global sync
  if RTBSyncAdr then
    CLI();
    
    To_OSKernel.OutByte(Portnumber:=16#335, value:=1);
    
    (_IOSegment$^USINT + RTBSyncAdr$UDINT - 16#8000)^ := 1;
    
    To_OSKernel.OutByte(Portnumber:=16#335, value:=0);
    
    STI();
  end_if;
#ELSE // local sync
  if NumberSyncs then
    CLI();

    To_OSKernel.OutByte(Portnumber:=16#335, value:=1);

    pHINT := #RtbLocalSyncAdr[0];
    for i := 0 to NumberSyncs-1 do
      (_IOSegment$^SINT + pHINT^ - 16#8000)^ := 1;
      
      pHINT += sizeof(HINT);
    end_for;

    To_OSKernel.OutByte(Portnumber:=16#335, value:=0);

    STI();
  end_if;
#ENDIF

// **************************************************
//  now take data and call update function with thisp 
// **************************************************
  RealtimeReady := 1;
  
  // call update methods with thispointer
  if HandleNrRt then
    pHandle := #HandlesRT[0];
    for i := 0 to HandleNrRT-1 do
      if pHandle^.Typ AND DmCallProg then
        pHandle^.thisp^.UpdateRt(pHandle^.Address);
      end_if;
      
      pHandle += sizeof(OneHandle);
    end_for;
  end_if;

  if HwControl = 0 then
    UpdateRtPostScan();
  end_if;

  WDDIAS();

//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_RT.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_RT.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_RT.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_RT.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_RT.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_RT.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_RT._min then
      DMC_Time_RT._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_RT._max then
      DMC_Time_RT._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_RT.avg := DMC_Time_RT.sum * 100 / DMC_Time_RT.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
#endif
END_FUNCTION
#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::RtWorkStdMasIPC


//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_RT.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_RT.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_RT.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_RT.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	
//============================ Profiler end========================================================

	l.edi		  _ioSegment

#IFNDEF OldDiasXilinx // global sync
	l.ebx		  RTBSyncAdr
	o.ebx		  ebx
	jz			  RtNoRTB

	cli
	l.dx		  16#335
	l			    1
	outb
	sub.ebx		16#8000
	s			    (ebx+edi)
	clr			  al
	outb
	sti

#ELSE // local sync
	LZXB.ECX	NumberSyncs
	JECXZ		  RtNoRTB

	cli
	l.dx		  16#335
	l			    1 // switch to control
	outb

	L.EDX		  #RtbLocalSyncAdr[0]
SyncJMP
	LZXW.EBX	(EDX)

	sub.ebx		16#8000
	L.B			  (ebx+edi),1

	ADD.EDX		SIZEOF(HINT)
	LOOP		  SyncJMP

	l.dx		  16#335
	clr			  al
	outb
	sti

#ENDIF

RtNoRTB
// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b			  RealtimeReady,1		//ws005

	l.ebx		  #HandlesRt
	lzxw.ecx	HandleNrRt
	jecxz		  LABEL_RtPostScan

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRT
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

LABEL_RtPostScan
//BLEERN START
  cmp.d     HwControl, 0
  jne       NoRtProg
  
  call      UpdateRtPostScan
//BLEERN ENDE

NoRtProg

	FC			  WDDIAS

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_RT.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			  LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_RT.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_RT.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_RT.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_RT.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_RT.sum					//Summe speichern
	l.ecx		  DMC_Time_RT.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_RT.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_RT._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_RT._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_RT._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_RT._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_RT.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

FUNCTION  DiasMasterMain::WdCDIAS

  IF RTSSW <> 4 THEN
	  	//--- do watchdog while synchronizing -------------------
		#IFNDEF MaxWatchdog	// #BS016
		IF ops.tAbsolute - timestampCDIAS$UDINT > 100ms | RtDebug = 1 THEN			//#SR011
			timestampCDIAS$UDINT := ops.tAbsolute;
		#ENDIF 

		//**** C - Dias Watchdog ****************************
			// #BS000
			IF (CDiasI2CWatchdog+2)^ AND 1 & MasterOn = 1 THEN // watchdogstatus (Bit0 = 1 => watchdog)
        bdRTLogs.Bit5 := 1;   //set Flag for Error Log
				MasterOn := 0;
				IMOFF := 1;
			ELSE
				IF MasterOn THEN
					CDiasI2CWatchdog^ := 0; // trigger watchdog
					// #BS002 only one watchdogregister for CDIAS and DIAS (IM)
				END_IF;
			END_IF;

			//**** Dias - Watchdog ******************************
			IF FirstModulFound <> 16#ff THEN		//ws005
				ReadKenn(FirstModulFound);
			END_IF;

		#IFNDEF MaxWatchdog	// #BS016
		END_IF;
		#ENDIF 
  ELSE        //ws005: there is no point in triggering the WD twice while synchronizing

	#IFNDEF MaxWatchdog	// #BS016
    IF ops.tAbsolute - timestampCDIAS$UDINT > 100ms | RtDebug = 1 THEN			//#SR011
      timestampCDIAS$UDINT := ops.tAbsolute;
    #ENDIF 
      //----- Always do CDIAS watchdog --------------------
      //**** C - Dias Watchdog *********************************************
      // #BS000
      IF (CDiasI2CWatchdog+2)^ AND 1 & MasterOn = 1 THEN // watchdogstatus (Bit0 = 1 => watchdog)
        bdRTLogs.Bit5 := 1;   //set Flag for Error Log
        MasterOn := 0;
        IMOFF := 1;
      ELSE
        IF MasterOn THEN
          CDiasI2CWatchdog^ := 0; // trigger watchdog
          // #BS002 only one watchdogregister for CDIAS and DIAS (IM)
        END_IF;
      END_IF;

    #IFNDEF MaxWatchdog	// #BS016
    END_IF;
	#ENDIF
  END_IF; //ws005

END_FUNCTION // DiasMasterMain::WdCDIAS
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddDiasIRQ
  VAR_INPUT
    Place		  : USINT;
    ActionPtr	: pVoid;
    thisptr		: pVoid;
  END_VAR
  VAR_OUTPUT
    ok		    : USINT;
  END_VAR

	ok := 0;
	IF IRQDias.anz <= 7 THEN // only 8 Irqs are possible
		IRQDias.data[IRQDias.anz$SINT].ActionPtr	:= ActionPtr;// #BS016
		IRQDias.data[IRQDias.anz$SINT].ThisPtr	:= thisptr;// #BS016
		IF OS_DiasIRQ(TO_USINT(place), #DiasIRQCall() , #IRQDias.data[IRQDias.anz$SINT]) = 0 THEN// #BS016
			ok := 1;
			IRQDias.anz += 1;
		END_IF;
		IF DiasType = 2 THEN
			// #BS001
#ifdef HWC_LogError
      HWC_LogError(thisptr$pVirtualBase, "@0007 (DiasMasterMain::AddDiasIRQ) Interupts on DiasBus with intelligent master are not supported !!! Configurationerror in this object");
#else
			Trace("Interupts on DiasBus with intelligent master are not supported !!! Configurationerror in object:");
#endif
			ok := 0; // only till os gives right value back
		END_IF;
	ELSE // #BS010
#ifdef HWC_LogError
      HWC_LogError(thisptr$pVirtualBase, "@0008 (DiasMasterMain::AddDiasIRQ) Diasinterruptlist is full !! No IRQ for this object");
#else
		Trace("Diasinterruptlist is full !! No IRQ for object:"); // #BS010
#endif
	END_IF;

END_FUNCTION
//[#DEUTSCH]
//[>irqnr]0..IRQ I/O (IRQ PIN C3) | 1..IRQ Comunication (GP2 PIN A10)
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddCDiasIRQ
  VAR_INPUT
    irqnr		: USINT;
    ActionPtr	: pVoid;
    thisp		: pVoid;
  END_VAR
  VAR_OUTPUT
    ok		: USINT;
  END_VAR

	ok := 0;
	IF CDiasIRQpossible THEN // if possible
		IF OS_INSTALL_CDIAS_IRQ(irqnr, ActionPtr, thisp) = 0 THEN
			ok := 1;
		END_IF;
	END_IF;

END_FUNCTION

#ifdef _LSL_TARGETARCH_X86
FUNCTION AWL DiasMasterMain::DiasIRQCall
	VAR_INPUT
    Station		: UINT;
    ThisIn		: ^USINT;
	END_VAR
  
//hier die Bedeutung des Registers EBP in Bezug auf den Stack:
//
//+-----------+
//|   param1  |
//+-----------+
//|   param0  | <--- this is [ebp + 8] ( assuming mov ebp, esp )
//+-----------+
//|ret_address|
//+-----------+
//|    ebp    |
//+-----------+ <--- esp
//
//Also, auf EBP + 8 beginnt der 1. Übergabeparameter. In deinem Fall die
//Stationsnummer. Diese wird nur mit 16 Bit Länge auf den Stack gepusht. D.h.,
//der nächste Übergabeparameter beginnt auf EBP + 10. Hier handelt es sich
//dann um ThisIn.
//
//Auf einer 32-Bit-Maschine sollten Übergabeparameter eigentlich immer mit
//32-Bit auf dem Stack landen, da es ansonsten zu einem Misaligned
//Stack-Pointer kommen kann.

// to get a standard interface

	L.EDI		(EBP+10) 
	L.ESI		(EDI+oneIRQ.ThisPtr)
	CALL		(EDI+oneIRQ.ActionPtr)

END_FUNCTION
#else
#pragma warning(disable:73 )
FUNCTION DiasMasterMain::DiasIRQCall
	VAR_INPUT
		Station 	: UINT;
		ThisIn 	  : ^USINT;
	END_VAR
  #pragma warning(Default:73)

#ifdef DM_DEBUG_ARM
  // This method is not supported with ARM
  ((0)$^USINT)^ := 0;
#endif

  //LanSte Method is not needed for ARM CPU
  
END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::RtWorkIMCIPC
  VAR_INPUT
    EAX		: UDINT;
  END_VAR
  VAR_OUTPUT
    state		: UDINT;
  END_VAR
  VAR
    Temp      : DINT;
    pHandle   : ^OneHandle;
    i     :    UDINT;
  //-------------------------------------Profiler Start----------------------------------------------
  #ifdef DiasMasterC_Profiler
    MuSecTime : UDINT;
  END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_RT.init > DM_ProfilerDelay then
    DMC_Time_RT.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_RT.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_RT.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
  END_VAR
#endif

  if (ImOff = FALSE) then
    if (b_TaskTimeCorrected = 0) | (CDIASSync + 3)^ then
      if HwControl = 0 then
        SendSync();
      end_if;
      
      //look if Rt program of IM is finished
      if (ops.SysState = C_RUNRAM) & (_IOSegment$^USINT + DmUserData + 3)^ then
        ud_ErrorCountTimeSliceEnd += 1;
        if us_FirstTimeSliceEnd = 0 then
          us_FirstTimeSliceEnd := 1;
        end_if;
      end_if;
      
      //Reset Byte to find out if Rt of IM starts while Rt of DM is running
      (_IOSegment$^USINT + DmUserData + 4)^ := 0;
      
      case RtSSW of
      
          // ***********************************************************
          //   we have to wait that the PLL is locked before we start
          // ***********************************************************
        0:

          if Release <> 16#FFFFFFFF then
            if ((_IOSegment$^USINT + DmPllSyncState)^ AND DmPLLisLock) = DmPLLisLock then
              StartRealtimeProg();
              RtSSW += 1;
              LogRtSSW();
            end_if;
            
            // Start it always to keep the moduls alive 
            (_IOSegment$^USINT + DmState)^ := (_IOSegment$^USINT + DmState)^ OR 16#10;
          end_if;


          // **********************************************************
          //  now we are starting the RTProg 
          // **********************************************************
        1:

          StartRealtimeProg();
          RtSSW += 1;
          LogRtSSW();


          // ****************************************************************
          //  now we have to move the startpoint till we are 50usec before
          // ****************************************************************
        2:

          if us_MuSecMode then
            Temp := RtInterval - (ud_DelayRealtime / (DmTmrResso * 1000))$DINT - DmTimeReserveIM;
          else
            Temp := RtInterval - (ud_DelayRealtime / (DmTmrResso * 1000))$DINT - (DmTimeReserveIM + 1);
          end_if;

          (_IOSegment$^USINT + DmPllSyncDel)^ := Temp$USINT;
          ui_RtStartPoint := Temp$UINT * DmTmrResso;
          RtSSW += 1;
          LogRtSSW();
          
          
          // ***********************************************************
          //   read the calculated time 
          // ***********************************************************
        3:

          TimeBeforeNextSync := to_uint((_IOSegment$^USINT + DmUserData)^);
          RtSSW += 1;
          LogRtSSW();


          // ***************************************************************
          //   do the refresh of I/O 
          // ***************************************************************
        4:

          // get rtload of im
          TimeAtRtPreEnd := to_dint((_IOSegment$^USINT + DmUserData)^) * DmTmrResso;          
          Rt_Load := ((TimeAtRtPreEnd - ui_RtStartPoint) * 1000) / sd_PllTimeGlob_us;

          RealtimeReady := TRUE;
          
          // now take data and call update methods with thispointer
          if HandleNrRT then
            pHandle := #HandlesRT[0];
            for i := 0 to HandleNrRT-1 do
              if pHandle^.Typ AND DmCallProg then
                pHandle^.thisp^.UpdateRt(pHandle^.Address);
              end_if;
              
              pHandle += sizeof(OneHandle);
            end_for;
          end_if;
          
          if HwControl = 0 then
            UpdateRtPostScan_IM();
          end_if;

      end_case;
      
      if (StateCDiasSync AND 1) = 0 then
        StateCDiasSync := (CDIASSync + 2)^;
      end_if;

      WdCDIAS();
    end_if;
  end_if;

  state := READY;
  
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_RT.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_RT.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_RT.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_RT.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_RT.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_RT.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_RT._min then
      DMC_Time_RT._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_RT._max then
      DMC_Time_RT._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_RT.avg := DMC_Time_RT.sum * 100 / DMC_Time_RT.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
END_FUNCTION

#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::RtWorkIMCIPC
  VAR_INPUT
    EAX		: UDINT;
  END_VAR
  VAR_OUTPUT
    state		: UDINT;
  END_VAR

//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_RT.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_RT.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_RT.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_RT.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	  
//============================ Profiler end========================================================

	CMP.B			ImOff,1
	JE				RT_End1

  cmp.b     b_TaskTimeCorrected, 1
  jne       LABEL_AfterTaskCheck
  
  // task selector over fpga bit => to ensure synchronity
  l.edi     CDIASSync
  l         (edi + 3)
  cmp.al    0
  jz        RT_End1
  
LABEL_AfterTaskCheck

	//#SR014 start
	cmp.d			HwControl, 1
	je				LABEL_EndPllSync

	call			SendSync
	//#SR014 end

LABEL_EndPllSync	//#SR013

	//#SR010 start
	cmp.w			ops.SysState,1					//look if CPU is in RunRam
	jne				LABEL_Continue

 	l.edi			_IOSegment						//#SR014
	l.bl			( edi + DmUserData + 3 )		//look if Rt program of IM is finished
	o.bl			bl
	jz				LABEL_Continue
	inc.d			ud_ErrorCountTimeSliceEnd
	cmp.b			us_FirstTimeSliceEnd,0
	jne				LABEL_Continue

	l.b				us_FirstTimeSliceEnd,1
LABEL_Continue
  l.edi			_IOSegment						//#SR014
	l.b				( edi + DmUserData + 4 ), 0		//Reset Byte to find out if Rt of IM starts while Rt of DM is running
	//#SR010 end

	lzxb.eax	RtSSW		//ws005
	shl.eax		3             //ws005: save some time here
	add.eax		#RtSel
	jmp			  eax

RtSel
	jmp			WaitForSync			// 0 : wait till PLL in locked
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			weAreSync			// 1 : wait one period to get a right time 
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			MovStartPoint		// 2 : mov start point to the right pos
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			readpoint           // 3 : read one time the point 
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			RtRefresh			// 4 : do the realtime refresh


// ***************************************************************
//   do the refresh of I/O 
// ***************************************************************

RtRefresh

// *************************************************
//  read the time point
// *************************************************
	lzxb.eax	(edi+DmUserData)
	imul.ax		ax,DmTmrResso
	s.eax 		TimeAtRtPreEnd 

	//#SR009
	//***********calculate Rt - usage rate***********************
	lzxw.ebx	ui_RtStartPoint
	sub.eax		ebx
	imul.eax	eax,1000
	x.edx		  edx
	l.ebx		  sd_PllTimeGlob_us
	div			  ebx
	s.eax		  Rt_Load
	//#SR009 

// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b			  RealtimeReady,1		//ws005

	l.ebx		  #HandlesRt
	lzxw.ecx	HandleNrRt
	jecxz		  LABEL_RtPostScan		//#SR010 RT_end    //NoRtProg  //ws005

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRT
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

LABEL_RtPostScan
//BLEERN START
  cmp.d     HwControl, 0
  jne       Rt_end
  
  call      UpdateRtPostScan_IM
//BLEERN ENDE

	jmp			  RT_end	


// ****************************************************************
//  now we have to move the startpoint till we are 50usec before
// ****************************************************************

MovStartPoint
	
	//#SR001 Start
	L.EAX		  ud_DelayRealtime	//Time of Rt - Programm of IM				
	CLR			  EDX
	L.ECX		  DmTmrResso*1000		// we have nanoseconds and we have to put in 25µs units
	DIV 		  ECX
	l.ebx		  eax
	//#SR001 End

	l.eax		  RtInterval
				
	sub.eax		ebx

	//#SR013 start
	cmp.b		  us_MuSecMode,1			//have we µs - Mode
	jne			  LABEL_Reserve_Std
	sub.eax		DmTimeReserveIM			//not so much reserve tim in µs - Mode
	jmp			  LABEL_EndReserve
LABEL_Reserve_Std
	//#SR013 end
	sub.eax		DmTimeReserveIM + 1		//ws005: just subtract 3 instead of ... (see above)			//#SR010 (make variable with define [instead of 3])
LABEL_EndReserve						//#SR013
  s.al		  (EDI+DmPllSyncDel)
	imul.ax		ax,DmTmrResso			//#SR009
	s.ax		  ui_RtStartPoint			//#SR009
	inc.b		  RtSSW					//ws005
	call		  LogRtSSW				//#SR008
	jmp			  RT_end	

// ***********************************************************
//   read the calculated time 
// ***********************************************************

ReadPoint
	clr			  eax
	l.al		  (edi+DmUserData)
	s.ax		  TimeBeforeNextSync
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	jmp			  RT_end	



// **********************************************************
//  now we are starting the RTProg 
// **********************************************************

weAreSync
	call		  StartRealtimeProg	
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	jmp			  RT_end	



// ***********************************************************
//   we have to wait that the PLL is locked before we start
// ***********************************************************
WaitForSync
	cmp.d		  release,16#FFFFFFFF
	je			  RT_end					// #fa 080103

	l			    (edi+DmPLLSyncState)
	test.al		DmPLLisLock
	jz			  WaitForSyncRet
	call		  StartRealtimeProg	
	inc.b		  RtSSW				//ws005
	call		  LogRtSSW			//#SR008
	l.edi		  _IOSEGMENT			//#SR008
WaitForSyncRet
	L.AL		  (EDI+DmState)           // Start it always to keep the moduls alive 
	OR.AL		  16#10
	S.AL		  (EDI+DmState)  
	// #BS002

RT_end

	BT.W			StateCDiasSync+0,0
	JC				CDIASSyncOK
	L.EDI			CDIASSync // sync of CDIASBus
	L				  (EDI+2)
	S				  StateCDiasSync
CDIASSyncOK

	FC				WDCDIAS
RT_End1
	L.EAX	 		READY$UDINT

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_RT.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			  LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_RT.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_RT.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_RT.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_RT.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_RT.sum					//Summe speichern
	l.ecx		  DMC_Time_RT.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_RT.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_RT._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_RT._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_RT._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_RT._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_RT.avg					//Durchschnitt speichern
	popad 

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

FUNCTION  DiasMasterMain::WDDIAS

	IF FirstModulFound <> 16#ff THEN	//ws005
	  IF DiasType <> 2 | RtSSw <> 4 THEN
 #IFNDEF MaxWatchdog	// #BS016
		IF ops.tAbsolute - timestamp$UDINT > 100ms | RtDebug = 1 THEN				//#SR011
			timestamp$UDINT := ops.tAbsolute;
 #ENDIF

			//**** Watchdog *************************************
			ReadKenn(FirstModulFound);
		
 #IFNDEF MaxWatchdog	// #BS016
		END_IF;
 #ENDIF
	  END_IF;
	END_IF;

	IF DiasType = 2 THEN
 #IFNDEF MaxWatchdog	// #BS016
		IF ops.tAbsolute - timestamp$UDINT > 100ms | RtDebug = 1 THEN				//#SR011
			timestamp$UDINT := ops.tAbsolute;
 #ENDIF

			IF (((_IOSegment$UDINT + DmControl)$^USINT)^ AND 2#10) = 0 & MasterON = 1 THEN
				MasterON := 0; // Risk is stopped => would be a watchdog
				IF Firstmodulfound <> 16#ff THEN		//ws005
          bdRTLogs.Bit6 := 1;
				END_IF;
				ImOff := 1;
			END_IF;

			//**** Watchdog for Risk (Xlinixversion 2.1) ****
			((_IOSegment$UDINT + DMWDRegister)$^USINT)^ := 1;

 #IFNDEF MaxWatchdog	// #BS016
		END_IF;
 #ENDIF
	END_IF;


END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddNOP
  VAR_INPUT
    RTCY		  : DINT;
    nCount		: DINT;
  END_VAR
  VAR
    i : DINT;
  END_VAR

  if (RTCY AND DmRealtime) = DmRealtime then
    ud_DelayRealtime += C_TimeNop;
  else
    ud_DelayCyclic += C_TimeNop;
  end_if;

  for i := 0 to (nCount-1) do
    (PtrCode + IPSub)^ := DbNop;
    
    IPSub += sizeof(RetStruct);
  end_for;

END_FUNCTION

#else
//
//	THR Aug. 21, 2003
//		Added function to add NOPs to the RISC program.  Unlike the
//		WAIT command, a NOP command CANNOT be interrupted by the
//		Cyclic Program.
//		Only for old DiasModuls
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddNOP
  VAR_INPUT
    RTCY		  : DINT;
    nCount		: DINT;
  END_VAR


	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	x.edx		  edx						//#SR003		
	l.ebx		  nCount					//#SR003		//#SR009 (use ebx instead of eax register)
	imul.ebx	ebx,C_TimeNop			//#SR003		//#SR009
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AN_NORT
	ADD.D		  ud_DelayRealtime,ebx	//#SR003		//#SR009
  JMP       LABEL_AN_TIMETAKEN
LABEL_AN_NORT
	ADD.D		  ud_DelayCyclic,ebx
//#SR001 End

LABEL_AN_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	push		  ecx
	l.ecx		  nCount+0
an_loop
	l.b			  (edx+ebx),DbNop	   			// opcode NOP
	inc			  edx
	loop		  an_loop						//ws005: replaced dec,jnz with loop
	pop			  ecx

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

FUNCTION  DiasMasterMain::ErrorLocalSyncTrace

#ifdef HWC_LogError
  HWC_LogError(this, "@000A (DiasMasterMain::ErrorLocalSyncTrace) The constant 'NumberLocalSyncs' is defined too small !!! Remember: This is the number of maximum local Syncs !!!");
#else
	TRACE("The constant 'NumberLocalSyncs' is defined too small !!! Remember: This is the number of maximum local Syncs !!!");
#endif

END_FUNCTION

FUNCTION  DiasMasterMain::GetVerIMCIPC
  VAR_OUTPUT
    Ver(EAX)		: HDINT; // #BS016
  END_VAR
  VAR
    SigmaTekDevInfo : ^PCICONFDATA;
  END_VAR

#ifdef _LSL_TARGETARCH_X86
	SAVE_REG();
#endif

	IF pSPCIInfo <> NIL THEN
		SigmaTekDevInfo := SPCIINFO_FINDDEVICEBYNAME( "DIASIM" , 0 );
		Ver := 0;
		IF SigmaTekDevInfo <> NIL THEN
			Ver$USINT := SigmaTekDevInfo^.Version;		
		END_IF;
	ELSE
		Ver := 0; // Error in OS - Interface (shouldn't be)
	END_IF;

#ifdef _LSL_TARGETARCH_X86
	RESTORE_REG();
#endif

(*
other funktions:

VAR
	pSPCIInfo     	: ^LSL_SPCIINFO;
	SigmatTekDevs	: DINT;
	SigmaTekDevInfo : ^PCICONFDATA;
	Version : USINT;
	Index : DINT;
	BaseAddress : ^VOID;
	BaseAddressLEN : UDINT;
END_VAR	



	if OS_CILGET("PCICONFIG", #pSPCIInfo) then
		state:= 1;
	else
		state:= 0;
	end_if;

	// Anzahl der Einträge im InfoBlock 
	SigmatTekDevs := SPCIINFO_GETDEVICECOUNT();

	for Index := 0 to SigmatTekDevs-1 do
		SigmaTekDevInfo := SPCIINFO_GETDEVICEBYINDEX( Index );
		Version := SigmaTekDevInfo^.Version;
	end_for;

	// z.B. PLL
	SigmaTekDevInfo := SPCIINFO_FINDDEVICEBYNAME( "PLL", 0 );
	SigmaTekDevInfo := SPCIINFO_FINDDEVICE( 16#0E08, 0 );
	BaseAddress := SPCIINFO_GETADDRESS( SigmaTekDevInfo );
	BaseAddressLen := SPCIINFO_GETADDRESSLEN( SigmaTekDevInfo );

	// z.B. CDIAS
	SigmaTekDevInfo := SPCIINFO_FINDDEVICEBYNAME( "CDiasBus", 0 );
	SigmaTekDevInfo := SPCIINFO_FINDDEVICE( 16#0500, 0 );
	BaseAddress := SPCIINFO_GETADDRESS( SigmaTekDevInfo );
	BaseAddressLen := SPCIINFO_GETADDRESSLEN( SigmaTekDevInfo );



*)

END_FUNCTION


FUNCTION DiasMasterMain::TraceAsyncError
	VAR_INPUT
		Place 	: UDINT;(* := 255 *)
	END_VAR
  VAR
    ptr		  : ^USINT;
    tracewd	: USINT;		// #BS012
    LogStr  : ARRAY [0..255] OF CHAR;
    NumStr  : ARRAY [0..9] OF CHAR;
  END_VAR

	if ( MasterOn <> 0 ) then		//#SR016	( because otherwise we have a lot of event messages

#ifdef _LSL_TARGETARCH_X86
		SAVE_REG();
#endif
		// #BS012 Start
		tracewd := 0;
		IF CDIASType = 2 THEN // CIPC
			IF ((CDiasI2CWatchdog+2)^ AND 1) = 1 THEN // watchdogstatus (Bit0 = 1 => watchdog)
#ifdef HWC_LogError
        HWC_LogError(this, "@0578 (DiasMasterMain::TraceAsyncError) Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)");
#else
				// Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)
				Trace("DiasMaster: Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)");
				//#SR008 start
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)" );
				end_if;
				//#SR008 end
#endif
			ELSE
				tracewd := 1;
			END_IF;
		END_IF;
		// #BS012 End
		ptr$UDINT := _IOSegment$UDINT + DMControl;
		ptr^ := 1; // Chip on risk off
		ImOff := 1;
		MasterOn := 0;
#ifdef HWC_LogError
    HWC_LogError(this, "@0582 (DiasMasterMain::TraceAsyncError) Timeout on asynchron methods !! => DiasBus is set off!!");
#else
		TRACE("DiasMaster: Timeout on asynchron methods !! => DiasBus is set off!!");
		//#SR008 start
		if p_KernelLog <> NIL then
			OS_KernelLog0( "DiasMaster: Timeout on asynchron methods !! => DiasBus is set off!!" );
		end_if;
#endif

#ifndef DIASMASTER_DISABLE_DIAS_ERROR_ON_DIRECT_ACCESS
    // if we got a place => create a dias error
    if Place <> 255 then

#ifdef HWC_LogValue1
      HWC_LogValue1(this, "@05F0 (DiasMasterMain::TraceAsyncError) Dias Error occured at place 0x{0}", Place);
#else
      _strcpy(dest:=#LogStr[0], src:="(DiasMasterMain::TraceAsyncError) Dias Error occured at place 0x");
      _itoa(udNumber:=Place, pString:=#NumStr[0]);
      _strcat(dest:=#LogStr[0], src:=#NumStr[0]);
      TRACE(#LogStr[0]);
      if p_KernelLog <> NIL then
        OS_KernelLog0(#LogStr[0]);
      end_if;
#endif

      _strcpy(dest:=#LogStr[0], src:="exec climsg 25 Dias Error occured at place 0x");
      _itoa(udNumber:=Place, pString:=#NumStr[0]);
      _strcat(dest:=#LogStr[0], src:=#NumStr[0]);
      
      To_OSKernel.AddToServiceProvider(command:=#LogStr[0], immediatly:=1);
    end_if;
#endif
    
		//#SR008 end
		// #BS012 Start
		IF tracewd THEN
#ifdef HWC_LogError
      HWC_LogError(this, "@058C (DiasMasterMain::TraceAsyncError) But no Watchdog on CDIAS and DIAS - Bus");
#else
			Trace("DiasMaster: But no Watchdog on CDIAS and DIAS - Bus");
			//#SR008 start
			if p_KernelLog <> NIL then
				OS_KernelLog0( "DiasMaster: But no Watchdog on CDIAS and DIAS - Bus" );
			end_if;
			//#SR008 end
#endif
		END_IF;
		// #BS012 End
#ifdef _LSL_TARGETARCH_X86
		RESTORE_REG();
#endif
	end_if;						//#SR016

END_FUNCTION


FUNCTION  DiasMasterMain::GetMuSec
  VAR_OUTPUT
    value(EAX)		: UDINT;
  END_VAR

#ifdef _LSL_TARGETARCH_X86
	SAVE_REG();
#endif
	value := OS_ReadMicroSec();

#ifdef _LSL_TARGETARCH_X86
	RESTORE_REG();
#endif

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRdKenn
  VAR_INPUT
    Adress		: HSINT;
    RTCY		: DINT;
    thisp		: ^void;
    callOptions 	: USINT;
  END_VAR
  VAR_OUTPUT
    Handle		: DINT;
  END_VAR

  if (RTCY AND DmRealtime) = DmRealtime then
    ud_DelayRealtime += C_TimeReadKennung;
    ui_RtDIASAccesses += 1;
  else
    ud_DelayCyclic += C_TimeReadKennung;
    ui_CyDIASAccesses += 1;
  end_if;

  (PtrCode + IPSub + RdKennStruct.Opc)^   := DbRdKenn;
  (PtrCode + IPSub + RdKennStruct.ModAdr)^ := Adress;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(RdKennStruct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(RdKennStruct);
  
END_FUNCTION

#else
// to read the identifier of a modul

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddRdKenn
	VAR_INPUT
		Adress 	: HSINT;
		RTCY 	: DINT;
		thisp 	: ^void;
		callOptions 	: USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	: DINT;
	END_VAR

  
	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_ARK_NORT
	ADD.D		  ud_DelayRealtime,C_TimeReadKennung
	inc.w		  ui_RtDIASAccesses			//#SR021
  JMP       LABEL_ARK_TIMETAKEN
  
LABEL_ARK_NORT
	ADD.D		  ud_DelayCyclic,C_TimeReadKennung
	inc.w		  ui_CyDIASAccesses
//#SR001 End

LABEL_ARK_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+RdKennStruct.Opc),DbRdKenn	   			// opcode read identifier
	l			    Adress					// adress of dias modul
	s			    (edx+ebx+RdKennStruct.ModAdr)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	

  push.b    callOptions

	push.d		RdKennStruct.Data			// direct pointer on the data 
	call		  GetHandle
  add.esp   5

	s.eax		  Handle
	add.edx		sizeof (RdKennStruct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddMove
  VAR_INPUT
    RTCY		: DINT;
    thisp		: ^void;
    callOptions 	: USINT;
    SourceAddr 	: HDINT;
    DestAddr 	: HDINT;
    MoveLen 	: UDINT;
    pEnable 	: ^USINT;
    Settings 	: HDINT;
  END_VAR
  VAR_OUTPUT
    HandleMove		: DINT;
  END_VAR

  if (RTCY AND DmRealtime) = DmRealtime then
    ud_DelayRealtime += C_TimeMove;
  else
    ud_DelayCyclic += C_TimeMove;
  end_if;

  (PtrCode + IPSub + MoveStruct.Opc)^               := DbMov;
  (PtrCode$^HINT + IPSub + MoveStruct.Source)^      := (IPSub + MoveStruct.Destination)$HINT;
  (PtrCode$^HINT + IPSub + MoveStruct.Destination)^ := (IPSub + MoveStruct.Destination)$HINT;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(MoveStruct.Source, callOptions);
  HandleMove := ARM_EAX$DINT;
  IPSub += sizeof(MoveStruct);
  
END_FUNCTION

#else
// BS 14.11.2001
// This command is to switch for example a bank back in im routine.
// 
//[#ENGLISH]
//[<HandleMove]pointer on source (2 Byte further is destination)

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddMove
	VAR_INPUT
		RTCY 	: DINT;
		thisp 	: ^void;
		callOptions 	: USINT;
		SourceAddr 	: HDINT;
		DestAddr 	: HDINT;
		MoveLen 	: UDINT;
		pEnable 	: ^USINT;
		Settings 	: HDINT;
	END_VAR
	VAR_OUTPUT
		HandleMove 	: DINT;
	END_VAR

  
	l.eax		  RTCY
	and.eax		Dmrealtime

//#SR001 Start
	CMP.EAX		Dmrealtime
	JNE			  LABEL_AM_NORT
	ADD.D		  ud_DelayRealtime,C_TimeMove
  JMP       LABEL_AM_TIMETAKEN
  
LABEL_AM_NORT
  ADD.D		  ud_DelayCyclic,C_TimeMove
//#SR001 End

LABEL_AM_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+MoveStruct.Opc),DbMov	   			// opcode read identifier

	L.EAX		  EDX
	ADD.EAX		MoveStruct.Destination
	S.AX		  (edx+ebx+MoveStruct.Source) // read destination
	S.AX		  (edx+ebx+MoveStruct.Destination) // save on destination

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	
  
  push.b    callOptions

	push.d		MoveStruct.Source			// direct pointer on the data 
	call		  GetHandle
  add.esp 5

	s.eax		  HandleMove
	add.edx		sizeof (MoveStruct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetCDiasPlaceIoSegment
  VAR_INPUT
    place		: UDINT;
  END_VAR
  VAR_OUTPUT
    IOSegment		: ^USINT;
  END_VAR

	IOSegment$UDINT :=  CDiasHwPointer$UDINT + (place*16#100)$UDINT;

END_FUNCTION

//[#ENGLISH]
//[<StateSync]0 = Busy | 1 = Sync | 2 = TimeOut
#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::CheckSyncModules
  VAR_INPUT
    TimeStampStart		: UDINT;
  END_VAR
  VAR_OUTPUT
    StateSync		: UDINT;
  END_VAR
  VAR
    pModule : ^WaitSyncCall;
    i : UDINT;
    MaxTime : UDINT;
  END_VAR

  // init with synchron
  StateSync := 1;
  
  // check if there are any sync calls
  if DiasSync.NumberCalls then
    pModule := #DiasSync.Modules[0];
    MaxTime := 0;

    // search for the max possible sync time
    for i := 0 to (DiasSync.NumberCalls - 1) do
      if (pModule^.SyncState = 0) & (pModule^.WaitTime > MaxTime) then
        MaxTime := pModule^.WaitTime;   // save the maxtime
      end_if;
      
      pModule += sizeof(WaitSyncCall);
    end_for;
    DiasSync.ActMaxTime := MaxTime;
    
    pModule := #DiasSync.Modules[0];

    // search if modules are ready
    for i := 0 to (DiasSync.NumberCalls - 1) do
      if (pModule^.SyncState = 0) then
        pModule^.SyncState := CallGetSync(thisp:=pModule^.thisp);
        if pModule^.SyncState = 0 then
          StateSync := 0;   // busy
        end_if;
      end_if;
      
      pModule += sizeof(WaitSyncCall);
    end_for;
    
    if (StateSync = 0) & ((ops.tAbsolute - TimeStampStart) > DiasSync.ActMaxTime) then
      StateSync := 2;   // timeout
    end_if;
  end_if;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::CheckSyncModules
  VAR_INPUT
    TimeStampStart		: UDINT;
  END_VAR
  VAR_OUTPUT
    StateSync		: UDINT;
  END_VAR


// #BS014 Start
// init with synchron
	L.D			  StateSync,1 

// check if there are any sync calls
	L.ECX		  DiasSync.NumberCalls
	JECXZ		  SyncReady

// search for the max possible sync time
	L.EDI		  #DiasSync.Modules[0]
	X.EAX		  EAX
SearchTime
	CMP.B		  (EDI+WaitSyncCall.SyncState),1	// if the modul is sync we cancel it
	JE			  NextObjectTime
	CMP.EAX		(EDI+WaitSyncCall.WaitTime)
	JAE			  NextObjectTime
	L.EAX		  (EDI+WaitSyncCall.WaitTime)		// save the maxtime
NextObjectTime
	ADD.EDI		SIZEOF(WaitSyncCall)
	LOOP		  SearchTime

	S.EAX		  DiasSync.ActMaxTime

// search if modules are ready
	L.EDI		  #DiasSync.Modules[0]
	L.ECX		  DiasSync.NumberCalls

SyncSearch

	CMP.B		  (EDI+WaitSyncCall.SyncState),1
	JE			  NextObject
		
	PUSH		  EDI
	PUSH		  ESI
	PUSH		  ECX

	X.AL		  AL
	
	L.EDI		  (EDI+WaitSyncCall.thisp)
	CALL		  CallGetSync

	POP			  ECX
	POP			  ESI
	POP			  EDI
	
	S.AL		  (EDI+WaitSyncCall.SyncState)
	CMP.AL	  1	// if sync then next obj
	JE			  NextObject
	L.D			  StateSync,0 // busy
NextObject
	ADD.EDI		SIZEOF(WaitSyncCall)
	LOOP		  SyncSearch

	CMP.D		  StateSync,1
	JE			  SyncReady

	L.EAX		  ops.tAbsolute
	SUB.EAX		TimeStampStart
	CMP.EAX		DiasSync.ActMaxTime
	JBE			  EndSyncCheck	

	L.D			  StateSync,2 // timeout
	JMP			  EndSyncCheck

SyncReady

EndSyncCheck
// #BS014 End 

END_FUNCTION
#endif

FUNCTION  DiasMasterMain::CallGetSync
  VAR_INPUT
    thisp(EDI)		: pHwBase;
  END_VAR
  VAR_OUTPUT
    syncchron(AL)		: USINT;
  END_VAR

	syncchron := thisp^.CheckSync();

END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddWaitSync
  VAR_INPUT
    thisp		: pVoid;
    MaxWaitTime		: UDINT;
  END_VAR

	IF DiasSync.NumberCalls * SIZEOF(WaitSyncCall) < SIZEOF(DiasSync.Modules) THEN
		DiasSync.Modules[DiasSync.NumberCalls$SINT].thisp$pVoid 	:= thisp;// #BS016
		DiasSync.Modules[DiasSync.NumberCalls$SINT].WaitTime := MaxWaitTime;// #BS016
		DiasSync.NumberCalls += 1;

		IF MaxWaitTime > DiasSync.ActMaxTime THEN
			DiasSync.ActMaxTime	:= MaxWaitTime;
		END_IF;
	ELSE
  
#ifdef HWC_LogError
    HWC_LogError(this, "@000B (DiasMasterMain::AddWaitSync) The constant 'MaxSyncModules' is defined too small !!!");
#else
		TRACE("The constant 'MaxSyncModules' is defined too small !!!");
#endif
	END_IF;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::Release::Read
	VAR_OUTPUT
		output (EAX) 	: HDINT;
	END_VAR

	output := Release;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::Chipstate::Read
  VAR_OUTPUT
    output		: DINT;
  END_VAR

	output := Chipstate;
  
END_FUNCTION 


FUNCTION VIRTUAL GLOBAL DiasMasterMain::RiscState::Read
  VAR_OUTPUT
    output		: DINT;
  END_VAR

	output := RiscState;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::TimeAtRtPreEnd::Read
  VAR_OUTPUT
    output		: DINT;
  END_VAR

	output := TimeAtRtPreEnd;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::DIASRetryCounter::Read
  VAR_OUTPUT
    output		: DINT;
  END_VAR

	output := DIASRetryCounter;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::MasterON::Read
  VAR_OUTPUT
    output		: DINT;
  END_VAR

	output := MasterON;

END_FUNCTION


FUNCTION  DiasMasterMain::Risc_Off

#ifdef HWC_LogError
  HWC_LogError(this, "@0596 (DiasMasterMain::Risc_Off) RISC is set of -> DiasMasterOn = 0 and ImOff = 1");
#else
	TRACE("DiasMaster: RISC is set of -> DiasMasterOn = 0 and ImOff = 1");
	//#SR008 start
	if p_KernelLog <> NIL then
		OS_KernelLog0( "DiasMaster: RISC is set of -> DiasMasterOn = 0 and ImOff = 1" );
	end_if;
	//#SR008 end
#endif
	ImOff := 1;
	MasterOn := 0;

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddIRQScan
  VAR_INPUT
    Place		: USINT;
    RTCY		: DINT;
    thisp		: ^void;
    callOptions 	: USINT;
  END_VAR
  VAR_OUTPUT
    Handle		: DINT;
  END_VAR

  if (RTCY AND DmRealtime) = DmRealtime then
    ud_DelayRealtime += C_TimeIRQScan;
  else
    ud_DelayCyclic += C_TimeIRQScan;
  end_if;

  (PtrCode + IPSub + IRQScanStruct.Opc)^    := DbIRQScan;
  (PtrCode + IPSub + IRQScanStruct.ModAdr)^ := Place;
  
  ARM_EAX := RTCY$UDINT;
  ARM_EDI := thisp$UDINT;
  GetHandle(IRQScanStruct.Data, callOptions);
  Handle := ARM_EAX$DINT;
  IPSub += sizeof(IRQScanStruct);
  
END_FUNCTION

#else
//[#ENGLISH]
//[>Place]modul number
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::AddIRQScan
	VAR_INPUT
		Place 	: USINT;
		RTCY 	: DINT;
		thisp 	: ^void;
		callOptions 	: USINT;
	END_VAR
	VAR_OUTPUT
		Handle 	: DINT;
	END_VAR

	l.eax		  RTCY
	and.eax		Dmrealtime

	CMP.EAX		Dmrealtime
	JNE			  LABEL_AIRQ_NORT
	ADD.D		  ud_DelayRealtime,C_TimeIRQScan
  JMP       LABEL_AIRQ_TIMETAKEN
  
LABEL_AIRQ_NORT
	ADD.D		  ud_DelayCyclic,C_TimeIRQScan

LABEL_AIRQ_TIMETAKEN

	call		  GetProgPointer

  l.ebx     PtrCode

	l.b			  (edx+ebx+IRQScanStruct.Opc),DbIRQScan	   			// opcode IRQ identifier
	l			    Place					// place of dias modul
	s			    (edx+ebx+IRQScanStruct.ModAdr)

	l.ax		  RTCY+0
	l.edi		  thisp				    // to put into then handle	
  
  push.b    callOptions

	push.d		IRQScanStruct.Data			// direct pointer on the data 
	call		  GetHandle
  add.esp   5

	s.eax		  Handle
	add.edx		sizeof (IRQScanStruct)

	l.eax		  RTCY	
	and.eax		Dmrealtime
	call		  StoreNewPointers

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::IRQScan
  VAR_INPUT
    Place		: udint;
  END_VAR
  VAR_OUTPUT
    Data		: DINT;
  END_VAR
  VAR
    Time1, Time2  : UDINT;
    TimeoutFlag   : DINT;
  END_VAR


  if (DiasType = 2) & (ImOff = FALSE) then
#ifdef _LSL_TARGETARCH_X86
    Save_Flg();
    CLI();          // needed for async read
#endif
    
    Time1 := Time2 := OS_ReadMicroSec();
    
    while ((Time2 - Time1) <= DmConstTimeOut) do
      Time2 := OS_ReadMicroSec()
      if (_IOSegment$^USINT + DmCmdBuf1)^ AND 1 then
        exit;
      end_if;
    end_while;

    (_IOSegment$^USINT+1+DmCmdBuf1+IRQScanStruct.ModAdr)^ := Place$USINT;
    (_IOSegment$^USINT + DmCmdBuf1)^ := 0; // kill ready
    (_IOSegment$^USINT+1+DmCmdBuf1+IRQScanStruct.Opc)^ := DbIRQScan;
    
    Time1 := Time2 := OS_ReadMicroSec();
    TimeoutFlag := 1;
    
    while ((Time2 - Time1) <= DmConstTimeOut) do
      Time2 := OS_ReadMicroSec()
      if (_IOSegment$^USINT + DmCmdBuf1)^ AND 1 then
        Data := to_dint((_IOSegment$^USINT+1+DmCmdBuf1+IRQScanStruct.Data)^);
        TimeoutFlag := 0;
        exit;
      end_if;
    end_while;

    if TimeoutFlag then
      // timeout
      TraceAsyncError();
      Data := 0;
    end_if;

#ifdef _LSL_TARGETARCH_X86
    Restore_Flg();
#endif
  end_if;

END_FUNCTION

#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::IRQScan
  VAR_INPUT
    Place		: udint;
  END_VAR
  VAR_OUTPUT
    Data		: DINT;
  END_VAR


  //ws005: moved to the start, since these cmp are critical
	cmp.b		  DiasType,2		//ws005
	jne			  LABEL_End		// --> it is a new Master

  CMP.B		  ImOff,1
	JE			  LABEL_End
  // /ws005

	push		  edi
	push		  ebx
	push		  eax

	L.EDI		  _IOSEGMENT

	CLR 		  EAX
 
 	L.ebx		  Place

	PUSHF
	CLI // needed for async read

	FC			  GetMuSec
	S.EAX		  EDX	
BSyIRQ
	FC			  GetMuSec
	SUB.EAX		EDX	
	TST.B		  (EDI+DmCmdBuf1),1
	JNZ			  BSyIRQConti		
	CMP.EAX		DmConstTimeOut
	JA			  TimeOutError	
	JMP			  BSyIRQ		
BSyIRQConti		

	S.Bl		  (EDI+1+DmCmdBuf1+IRQScanStruct.ModAdr)	
	L.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+IRQScanStruct.Opc),DbIRQScan

	FC			  GetMuSec
	S.EAX		  EDX	
NixDaIRQ
	FC			  GetMuSec
	SUB.EAX		EDX	
	TST.B		  (EDI+DmCmdBuf1),1
	JNZ			  IRQScanOkIM	
	CMP.EAX		DmConstTimeOut
	JA			  TimeOutError
	JMP			  NixDaIRQ

TimeOutError
	POPF
  L.EAX     Place
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	L.D			  Data,0
	JMP			  LABEL_End1  //ws005

IRQScanOkIM		
	LZXB.EAX	(EDI+1+DmCmdBuf1+IRQScanStruct.Data)
//	POPF				//#SR017
	S.EAX		  Data

LABEL_End1    //ws005
	POPF				//#SR017
	pop			  eax
	pop			  ebx
	pop			  edi

LABEL_End     //ws005

END_FUNCTION
#endif


//[#ENGLISH]
// This function updates the DIAS retry counter (using a function provided by the OS)
// [Globals]	_LSL_POS			:R		:OS interface structure
// [Members]	oldErrorCounter		:R/W	:calculate change
//			(S)	DiasRetryCounter	:W		:update retry counter
// [Locals]		us_actcount			:R/W	:currently read value
//				di_oldcount			:R/W	:temporary storeage of the previous value
FUNCTION DiasMasterMain::UpdateRetryCounter
  VAR
    us_actcount : usint;
    di_oldcount : dint;
    di_ret	    : dint;		//ws005
  END_VAR;
  
	if( pDIAS <> NIL )then	// CPU has a DIAS bus (for now only valid for CCL081)
		//ws005: consider the return value
		di_ret := OS_DIAS_ReadRegister( pDIAS, ( DIASRetryCounterOffset + 0 )$uint,  #us_actcount );
    di_oldcount := oldErrorCounter;
    oldErrorCounter := to_dint( us_actcount );
    DiasRetryCounter += oldErrorCounter - di_oldcount;
	end_if;    

END_FUNCTION

//[#ENGLISH]
//Function gives back the Dias Adress, of the module which
//answer to the global sync.
FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetSyncModuleNumber
  VAR_OUTPUT
    us_ModuleNr		: USINT;
  END_VAR

	us_ModuleNr := us_SyncModule;

END_FUNCTION


//[#ENGLISH]
//Function for logging Realtime steps at startup
FUNCTION  DiasMasterMain::LogRtSSW

  case RtSSW of

    1:		bdRTLogs.Bit1 := 1; //OS_KernelLog0( "DiasMaster: Pll is locked and Rt programm of intelligent master starts (1)"); 	//#SR021

    2:		bdRTLogs.Bit2 := 1; //OS_KernelLog1( "DiasMaster: We are Sync -> Rt programm of intelligent master starts again (Sync Module Place: %d) (2)", us_SyncModule ); 		//#SR021

    3:		bdRTLogs.Bit3 := 1; //OS_KernelLog2( "DiasMaster: MoveStartPointer -> Start moment of IM - programm is set (Rt - Startpoint: %dus, AddTime: %dns) (3)", ui_RtStartpoint, ui_AddTime );	//#SR021
  
    4:		bdRTLogs.Bit4 := 1; //OS_KernelLog1( "DiasMaster: One Time point was read -> start updating realtime tasks now (%d Rt - Dias accesses) (4)", ui_RtDIASAccesses );			//#SR021

  end_case;

END_FUNCTION


FUNCTION  DiasMasterMain::WriteRTLogs

  if bdRTLogs then
    if p_KernelLog <> NIL then
      if bdRTLogs.Bit1 then
        bdRTLogs.Bit1 := 0;
#ifdef HWC_LogError
        HWC_LogError(this, "@0514 (DiasMasterMain::WriteRTLogs) Pll is locked and Rt programm of intelligent master starts (1)");
#else
        if p_KernelLog <> NIL then
          OS_KernelLog0( "DiasMaster: Pll is locked and Rt programm of intelligent master starts (1)"); 	//#SR021
        end_if;
#endif
      end_if;
      if bdRTLogs.Bit2 then
        bdRTLogs.Bit2 := 0;
#ifdef HWC_LogValue1
        HWC_LogValue1(this, "@051E (DiasMasterMain::WriteRTLogs) We are Sync -> Rt programm of intelligent master starts again (Sync Module Place: {0}) (2)", us_SyncModule);
#else
        if p_KernelLog <> NIL then
          OS_KernelLog1( "DiasMaster: We are Sync -> Rt programm of intelligent master starts again (Sync Module Place: %d) (2)", us_SyncModule ); 		//#SR021
        end_if;
#endif
      end_if;
      if bdRTLogs.Bit3 then
        bdRTLogs.Bit3 := 0;
#ifdef HWC_LogValue2
        HWC_LogValue2(this, "@0528 (DiasMasterMain::WriteRTLogs) MoveStartPointer -> Start moment of IM - programm is set (Rt - Startpoint: {0}us, AddTime: {1}ns) (3)", ui_RtStartpoint, ui_AddTime);
#else
        if p_KernelLog <> NIL then
          OS_KernelLog2( "DiasMaster: MoveStartPointer -> Start moment of IM - programm is set (Rt - Startpoint: %dus, AddTime: %dns) (3)", ui_RtStartpoint, ui_AddTime );	//#SR021
        end_if;
#endif
      end_if;
      if bdRTLogs.Bit4 then
        bdRTLogs.Bit4 := 0;
#ifdef HWC_LogValue1
        HWC_LogValue1(this, "@0532 (DiasMasterMain::WriteRTLogs) One Time point was read -> start updating realtime tasks now (%d Rt - Dias accesses) (4)", ui_RtDIASAccesses);
#else
        if p_KernelLog <> NIL then
          OS_KernelLog1( "DiasMaster: One Time point was read -> start updating realtime tasks now (%d Rt - Dias accesses) (4)", ui_RtDIASAccesses );			//#SR021
        end_if;
#endif
      end_if;
    end_if;
  end_if;
  
  //Trace Message for Timesliceerror
	if us_FirstTimeSliceStart = 1 (* //#SR017 & ud_ErrorCountTimeSliceStart >= 10*) then
	
		us_FirstTimeSliceStart := 2;
#ifdef HWC_LogError
    HWC_LogError(this, "@05A0 (DiasMasterMain::Trace_JitterError) [SL] Rt of IM starts while Rt of DiasMaster is running!!");
#else
		trace("DiasMaster: Rt of IM starts while Rt of DiasMaster is running!!");
		if p_KernelLog <> NIL then
			OS_KernelLog0( "DiasMaster: Rt of IM starts while Rt of DiasMaster is running!!" ); 
		end_if;
#endif
	
	elsif us_FirstTimeSliceEnd = 1 (* //#SR017 & ud_ErrorCountTimeSliceEnd >= 10*) then
		
		us_FirstTimeSliceEnd := 2;
#ifdef HWC_LogError
    HWC_LogError(this, "@05AA (DiasMasterMain::Trace_JitterError) [SL] Timeslice overrun!!");
#else
		trace("DiasMaster: Timeslice overrun!!");
		if p_KernelLog <> NIL then
			OS_KernelLog0( "DiasMaster: Timeslice overrun!!" ); 
		end_if;
#endif
	end_if;

  //Watchdog Error CDIAS
  if bdRTLogs.Bit5 then
    if RTSSW <> 4 then
#ifdef HWC_LogError
      HWC_LogError(this, "@0564 (DiasMasterMain::WdCDIAS) Watchdog Error (RTSSW<>4) -> DiasMasterOn = 0 and ImOff = 1");
#else
      // Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)
      Trace("Watchdog Error (RTSSW<>4) -> DiasMasterOn = 0 and ImOff = 1");
      //#SR008 start
      if p_KernelLog <> NIL then
        OS_KernelLog0( "Watchdog Error (RTSSW<>4) -> DiasMasterOn = 0 and ImOff = 1" );
      end_if;
      //#SR008 end
#endif      
    else
#ifdef HWC_LogError
      HWC_LogError(this, "@056E (DiasMasterMain::WdCDIAS) Watchdog Error -> DiasMasterOn = 0 and ImOff = 1");
#else
      // Watchdog on CDIAS and DIAS - Bus occured !! (The RtTask of DiasMasterC - Class was set Off for more than 30ms => Hardwarereset on DIAS and CDIAS - Bus)
      Trace("Watchdog Error -> DiasMasterOn = 0 and ImOff = 1");
      //#SR008 start
      if p_KernelLog <> NIL then
        OS_KernelLog0( "Watchdog Error -> DiasMasterOn = 0 and ImOff = 1" );
      end_if;
      //#SR008 end
#endif    
    end_if;
    bdRTLogs.Bit5 := 0; 
  end_if;

  //Watchdog Error DIAS
  if bdRTLogs.Bit6 then
   
#ifdef HWC_LogError
      HWC_LogError(this, "@0009 (DiasMasterMain::WDDIAS) Watchdog on DIAS - Bus occured !! Make sure that this RtTask is called every set Real Time !! (No call for more than 130ms => Hardwarereset on DIAS - Bus)");
#else
      Trace("Watchdog on DIAS - Bus occured !! Make sure that this RtTask is called every set Real Time !! (The RtTask of DiasMasterC - Class was set Off for more than 130ms => Hardwarereset on DIAS - Bus) ");
#endif
    bdRTLogs.Bit6 := 0;
  end_if;


END_FUNCTION

//[#ENGLISH]
//For modules with old Pll (update only every ms in µs - Mode)
//[<us_update]0=no update, 1=update
FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetUpdateState
  VAR_OUTPUT
    us_update		: USINT;
  END_VAR

	us_update := us_ModuleUpdate1ms;

END_FUNCTION
//[#ENGLISH]
//[<us_rt_passes]number of realtime passes before update
FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetRtPasses
  VAR_OUTPUT
    us_rt_passes		: USINT;
  END_VAR

	us_rt_passes := us_RtPasses;

END_FUNCTION

//**************************************************************************
//** below this comment block are all hardware access routines which were **
//** replaced by OS calls (from version 5.44 upwards)                     **
//**    ||                                                          ||    **
//**    ||                                                          ||    **
//**   ----                                                        ----   **
//**   \  /                                                        \  /   **
//**    \/                                                          \/    **
//**************************************************************************


// /ws004
//[#ENGLISH]
// This function reads the DIAS ID of a module
// [Globals]	_IOSegment			:R		
// [Members]	ImOff				:R		:master is off
//				DIAS type			:R		:intelligent <-> standard master
// [Locals]		
//[>Place]		DIAS module
//[<retval]		Module ID
FUNCTION AWL DiasMasterMain::DM_DIAS_ReadKenn_x
	VAR_INPUT
    Place		: DINT;
	END_VAR
	VAR_OUTPUT
    retval		: DINT;
	END_VAR
#ifdef _LSL_TARGETARCH_X86

	L.EDI		  _IOSEGMENT

	l.al		  DiasType			//ws005
	cmp.al		2
	je			  ReadKennI			// --> intelligent
	cmp.al		1
	je			  ReadKennStd			// --> alter Master (64 k AdressRaum)

	l.eax		  16#ff				// no_kenn
	jmp			  EndReadKenn			
	
ReadKennStd
	cmp.edi		16#d0000			// test if master in PC
	jne			  MasterFull			// no high line requiered


	l.ebx		  place
	shl.ebx		8
	add.ebx		16#ff
	pushf
	cli
	l.dx		  16#335
	l			    1
	outb
	lzxb.eax	(ebx+edi)

	push		  ax
	clr			  al
	outb
	pop			  ax

	popf
	jmp			  EndReadKenn

MasterFull
	l.ebx		  place
	shl.ebx		8
	add.ebx		16#80ff				// read kennnung
	lzxb.eax	(ebx+edi)
	jmp			  EndReadKenn			


ReadKennI		

// there must be some colisions with the read kennung in the OPS
	PUSHF
	CLI
	
// Check if someone else is working with this buffer and is not ready 
	FC			  GetMuSec
	S.EAX		  EDX
BSyRdKenn
	FC			  GetMuSec				// #BS012
	TST.B		  (EDI+DmCmdBuf1),3		// #BS012
	JNZ			  RdyRdKenn
	SUB.EAX		EDX
	CMP.EAX		DmConstTimeOut
	JA			  TimeOutError
	JMP			  BSyRdKenn

RdyRdKenn

	L			    Place+0
	S  			  (EDI+1+DmCmdBuf1+Rd8Struct.ChAdr)	
	l.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+Rd8Struct.Opc),DBRdKenn
	CLR			  EAX

	FC			  GetMuSec
	S.EAX		  EDX
WaitRdKenn
	FC			  GetMuSec			// #BS012
	TST.B		  (EDI+DmCmdBuf1),3	// #BS012
	JNZ			  ReadKennRdy
	SUB.EAX		EDX
	CMP.EAX		DmConstTimeOut
	JA			  TimeOutError
	JMP			  WaitRdKenn

TimeOutError
	POPF							// #BS012
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	L.EAX		  16#FF				// #BS012
	JMP			  EndReadKenn			// #BS012

ReadKennRdy
	POPF
	LZXB.EAX	(EDI+1+DmCmdBuf1+Rd8Struct.ModAdr)

EndReadKenn	
	S.EAX		  retval
#endif
END_FUNCTION
//[English]
// Does a 16 Bit write access
// see Wr16Bit
FUNCTION AWL DiasMasterMain::DM_DIAS_WriteWord_x
	VAR_INPUT
		Adress 	: UDINT;
		Data 	: UINT;
	END_VAR
	VAR_OUTPUT
	state		: DINT;
	END_VAR
#ifdef _LSL_TARGETARCH_X86

  push		  edi
  push		  ebx
  push		  eax

  L.EDI		  _IOSEGMENT
  cmp.b		  DiasType,2		//ws005
  je			  Wr16IMaster		// --> it is a new Master

  // this is the old Master
  l.ebx		  Adress
  l.ax		  Data
  s.ax		  (ebx+edi+16#4000)
  jmp			  wr16ret


Wr16IMaster
  CMP.B		  ImOff,1
  JE			  Wr16Ret

  L.BX		  Adress+0

  PUSHF
  CLI	// needed for async write
  FC			  GetMuSec
  S.EAX		  EDX							// #BS012
BsyWr16
  FC			  GetMuSec
  SUB.EAX		EDX							// #BS012
  TST.B		  (EDI+DmCmdBuf1),1			// #BS012
  JNZ			  BsyWr16Conti				// #BS012
  CMP.EAX		DmConstTimeOut				// #BS012
  JA			  TimeOutError				
  JMP			  BsyWr16						// #BS012
BsyWr16Conti								// #BS012

  S.BX		  (EDI+1+DmCmdBuf1+Wr16Struct.ChAdr+0)	
  L.AX		  Data
  S.AX		  (EDI+1+DmCmdBuf1+Wr16Struct.Data)

  l.b			  (EDI+DmCmdBuf1),0		// Ready Töten
  L.B			  (EDI+1+DmCmdBuf1+Wr16Struct.Opc),DBWr16

  FC			  GetMuSec
  S.EAX		  EDX							// #BS012
NixDaWr16
  FC			  GetMuSec
  SUB.EAX		EDX							// #BS012
  TST.B		  (EDI+DmCmdBuf1),1			// #BS012
  JNZ			  W16OkIm						// #BS012
  CMP.EAX		DmConstTimeOut				// #BS012
  JA			  TimeOutError
  JMP			  NixDaWr16					// #BS012

TimeOutError
  POPF									// #BS012
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
  JMP			  wr16ret						// #BS012

W16OkIm
  POPF

wr16ret		
  CLR			  EAX
  S.EAX		  State

  pop			  eax
  pop			  ebx
  pop			  edi
#endif	
END_FUNCTION

//[English]
// Does a 8 Bit read access
// see Rd8Bit
FUNCTION AWL DiasMasterMain::DM_DIAS_ReadByte_x
	VAR_INPUT
		Adress 	: UDINT;
	END_VAR
	VAR_OUTPUT
    Data		: DINT;
	END_VAR
#ifdef _LSL_TARGETARCH_X86

	push		  edi
	push		  ebx
	push		  eax

	L.EDI		  _IOSEGMENT
	cmp.b		  DiasType,2		//ws005
	je			  Rd8IMaster		// --> it is a new Master

// this is the old Master
	l.ebx		  Adress
	lzxb.eax	(ebx+edi)
	s.eax		  Data
	jmp			  rd8ret

Rd8IMaster
	CLR 		  EAX
	CMP.B		  ImOff,1
	JE			  rd8Ret
 
 	L.BX		  Adress+0

	PUSHF
	CLI // needed for async read

	FC			  GetMuSec
	S.EAX		  EDX							// #BS012
BSyRd8
	FC			  GetMuSec
	SUB.EAX		EDX							// #BS012
	TST.B		  (EDI+DmCmdBuf1),1			// #BS012
	JNZ			  BSyRd8Conti					// #BS012
	CMP.EAX		DmConstTimeOut				// #BS012
	JA			  TimeOutError				// #BS012
	JMP			  BSyRd8						// #BS012
BSyRd8Conti									// #BS012

	S.BX		  (EDI+1+DmCmdBuf1+Rd8Struct.ChAdr+0)	
	L.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+Rd8Struct.Opc),DBRd8

	FC			  GetMuSec
	S.EAX		  EDX							// #BS012
NixDaRd8
	FC			  GetMuSec
	SUB.EAX		EDX							// #BS012
	TST.B		  (EDI+DmCmdBuf1),1			// #BS012
	JNZ			  Read8BitOkIM				// #BS012
	CMP.EAX		DmConstTimeOut				// #BS012
	JA			  TimeOutError
	JMP			  NixDaRd8					// #BS012

TimeOutError
	POPF		  							// #BS012
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	L.D			  Data,0
	JMP			  rd8ret						// #BS012

Read8BitOkIM		
	LZXB.EAX	(EDI+1+DmCmdBuf1+Rd8Struct.Data) // #BS012
	POPF
	S.EAX		  Data

rd8ret
	pop			  eax
	pop			  ebx
	pop			  edi
#endif
END_FUNCTION
//[English]
// Does a 16 Bit read access
// see Rd16Bit
FUNCTION AWL DiasMasterMain::DM_DIAS_ReadWord_x
	VAR_INPUT
		Adress 	: UDINT;
	END_VAR
	VAR_OUTPUT
    Data		: DINT;
  END_VAR
#ifdef _LSL_TARGETARCH_X86

	push		  edi
	push		  ebx
	push		  eax

	L.EDI		  _IOSEGMENT
	cmp.b		  DiasType,2		//ws005
	je			  Rd16IMaster		// --> it is a new Master

// this is the old Master
	l.ebx		  Adress
	lzxw.eax	(ebx+edi+16#4000)
	s.eax		  Data
	jmp			  rd16ret

Rd16IMaster
	CLR 		  EAX
	CMP.B		  ImOff,1
	JE			  rd16Ret

	L.BX		  Adress+0

	PUSHF
	CLI // needed for for async reads

	FC			  GetMuSec
	S.EAX		  EDX						// #BS012
BSyRd16
	FC			  GetMuSec
	SUB.EAX		EDX						// #BS012
	TST.B		  (EDI+DmCmdBuf1),1		// #BS012
	JNZ			  BSyRd16Conti			// #BS012
	CMP.EAX		DmConstTimeOut			// #BS012
	JA			  TimeOutError
	JMP			  BSyRd16					// #BS012
BSyRd16Conti							// #BS012

	S.BX		  (EDI+1+DmCmdBuf1+Rd8Struct.ChAdr+0)	
	l.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+Rd8Struct.Opc),DBRd16

	FC			  GetMuSec
	S.EAX		  EDX						// #BS012
NixDaRd16
	FC			  GetMuSec
	SUB.EAX		EDX						// #BS012
	TST.B		  (EDI+DmCmdBuf1),1		// #BS012
	JNZ			  Read16BitOKIM			// #BS012
	CMP.EAX		DmConstTimeOut			// #BS012
	JA			  TimeOutError
	JMP			  NixDaRd16				// #BS012

TimeOutError
	POPF								// #BS012
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	L.D			  Data,0
	JMP			  rd16ret

Read16BitOKIM		
	LZXW.EAX	(EDI+1+DmCmdBuf1+Rd8Struct.Data+0)	// #BS012
	POPF
	S.EAX		  Data

rd16ret
	pop			  eax
	pop			  ebx
	pop			  edi
#endif
END_FUNCTION
//[English]
// Does a 8 Bit write access (control area)
// see WrCntr
FUNCTION AWL DiasMasterMain::DM_DIAS_WriteCtrl_x
	VAR_INPUT
    adress		: DINT;
		Data 	: USINT;
	END_VAR
	VAR_OUTPUT
    state		: DINT;
	END_VAR
#ifdef _LSL_TARGETARCH_X86

	push		  edi
	push		  ebx
	push		  eax

	L.EDI		  _IOSEGMENT
	cmp.b		  DiasType,2			//ws005
	je			  WrCntrIMaster		// --> it is a new Master

	CMP.EDI		16#D0000
	JNE			  StdMasterCPU

	PUSH		  DX
	PUSHF
	CLI
	
	l.dx		  16#335
	l			    1   
	outb // switch controller

	l.ebx		  Adress
	l.al		  Data
	s.al		  (ebx+edi)

	clr			  al
	outb // switch controller back

	POPF
	POP			  DX
	jmp			  WrCntrRet

// this is the old Master
StdMasterCPU
	l.ebx		  Adress
	l.al		  Data
	s.al		  (ebx+edi+16#8000)
	jmp			  WrCntrRet

WrCntrIMaster
	L.BX		  Adress+0

	CMP.B		  ImOff,1
	JE			  WrCntrRet

	PUSHF
	CLI			// needed for async access

	FC			  GetMuSec
	S.EAX		  EDX							// #BS012
BsyCntw
	FC			  GetMuSec
	SUB.EAX		EDX							// #BS012
	TST.B		  (EDI+DmCmdBuf1),1			// #BS012
	JNZ			  BSyCntwConti				// #BS012
	CMP.EAX		DmConstTimeOut				// #BS012
	JA			  TimeOutError	
	JMP			  BsyCntw						// #BS012
BSyCntwConti								// #BS012

	S.BX		  (EDI+1+DmCmdBuf1+CntrlStruct.chAdr+0)	
	L		      Data
	S			    (EDI+1+DmCmdBuf1+CntrlStruct.Data)
	l.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+CntrlStruct.OPC),DbCntrl

	FC			  GetMuSec
	S.EAX		  EDX							// #BS012
NixDaCnt
	FC			  GetMuSec
	SUB.EAX		EDX							// #BS012
	TST.B		  (EDI+DmCmdBuf1),1			// #BS012
	JNZ			  WrCntrOK					// #BS012
	CMP.EAX		DmConstTimeOut				// #BS012
	JA			  TimeOutError
	JMP			  NixDaCnt					// #BS012

TimeOutError
	POPF
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	JMP			  WrCntrRet

WrCntrOK
	POPF

WrCntrRet
	clr			  eax
	S.EAX		  State

	pop 		  eax
	pop 		  ebx
	pop 		  edi
#endif  
END_FUNCTION
//[English]
// Does a 8 Bit write access 
// see Wr8Bit
FUNCTION AWL DiasMasterMain::DM_DIAS_WriteByte_x
	VAR_INPUT
		Adress 	: UDINT;
		Data 	: USINT;
	END_VAR
	VAR_OUTPUT
    State		: DINT;
	END_VAR
#ifdef _LSL_TARGETARCH_X86

	push		  edi
	push		  ebx
	push		  eax

	L.EDI		  _IOSEGMENT
	cmp.b		  DiasType,2		//ws005
	je			  Wr8IMaster		// --> it is a new Master

// this is the old Master
	l.ebx		  Adress
	l.al		  Data
	s.al		  (ebx+edi)
	jmp			  wr8ret

Wr8IMaster

	CMP.B		  ImOff,1
	JE			  Wr8Ret

	L.BX		  Adress+0
	

	PUSHF
	CLI // needed for async write
	FC			  GetMuSec
	S.EAX		  EDX					// #BS012
BsyWr8
	FC			  GetMuSec
	SUB.EAX		EDX					// #BS012
	TST.B		  (EDI+DmCmdBuf1),1	// #BS012
	JNZ			  BSyWr8Conti			// #BS012
	CMP.EAX		DmConstTimeOut		// #BS012
	JA			  TimeOutError
	JMP			  BsyWr8				// #BS012
BSyWr8Conti

	S.BX		  (EDI+1+DmCmdBuf1+Wr8Struct.ChAdr+0)	
	L		      Data
	S			    (EDI+1+DmCmdBuf1+Wr8Struct.Data+0)
  
	l.b			  (EDI+DmCmdBuf1),0		// Ready Töten
	L.B			  (EDI+1+DmCmdBuf1+Wr8Struct.Opc),DBWr8

	FC			  GetMuSec
	S.EAX		  EDX
NixDaWr8
	FC			  GetMuSec
	SUB.EAX		EDX					// #BS012
	TST.B		  (EDI+DmCmdBuf1),1	// #BS012
	JNZ			  W8OkIm				// #BS012
	CMP.EAX		DmConstTimeOut		// #BS012
	JA			  TimeOutError		// #BS012
	JMP			  NixDaWr8			// #BS012

TimeOutError
	POPF							// #BS012
  L.EAX     255
  PUSH      EAX
	FC			  TraceAsyncError	
  ADD.ESP   4
	JMP			  Wr8Ret				// #BS012

W8OkIm
	POPF


Wr8Ret
	CLR			  EAX
	S.EAX		  State
	pop			  eax
	pop			  ebx
	pop			  edi
#endif
END_FUNCTION

FUNCTION  DiasMasterMain::CCLWatchdog_Trigger

	OS_WATCHDOG_TRIGGER();

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::SendSync

  if p_NewPll = 0 then
    if CDIASSync then
      if us_MuSecMode then                //is µs Mode active ?
        us_ModuleUpdate1ms := (CDIASSync + 3)^ AND 1; //we need only Bit0
        
        if us_RtPasses = us_Counter_us then   //can we send sync signal (every ms in µs - Mode) ?
          us_Counter_us := 1;
          (CDIASSync)^ := 0;
          if DiasType = 2 then
            (_IOSegment$^USINT+DmPllSyncAdr)^ := 0;
          end_if;
        else
          us_Counter_us += 1;
        end_if;
      else
        us_Counter_us := 1;
        (CDIASSync)^ := 0;                // sync of CDIASBus
        if DiasType = 2 then
          (_IOSegment$^USINT+DmPllSyncAdr)^ := 0;
        end_if;
      end_if;
    else
      if DiasType = 2 then
        (_IOSegment$^USINT+DmPllSyncAdr)^ := 0;
      end_if;
    end_if;    
  end_if;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::SendSync			//#SR014

	cmp.d			  p_NewPll, 0					//#SR016
	jne				  LABEL_EndPllSync			//#SR016
	
	cmp.d     	CDIASSync,0					//#SR014
	je        	LABEL_SendDiasSync			//#SR014

	//#SR013 start
	cmp.b			  us_MuSecMode,1						//is µs Mode active
	jne				  LABEL_PllSync						

	l.b				  us_ModuleUpdate1ms,0				//do not update (for modules with old Pll)
	l.edi			  CDIASSync							
	l.al			  ( edi + 3 )							//check sync register (Bit0 = Sync Out)
	and.al			1									//we need only Bit0
	o.al			  al									//is bit set
	jz				  LABEL_NoSyncRead
	l.b				  us_ModuleUpdate1ms,1				//modules can update (for modules with old pll)

LABEL_NoSyncRead
 	l.edi			  _IOSegment
	l.al			  us_RtPasses
 	cmp.al			us_Counter_us						//can we send sync signal (every ms in µs - Mode)
	je				  LABEL_PllSync
	inc.b			  us_Counter_us						//increment counter
	jmp				  LABEL_EndPllSync

LABEL_PllSync
	l.b				  us_Counter_us,1
	//#SR013 end

  L.EDI			  CDIASSync // sync of CDIASBus
	S				    (EDI)

	//#SR014 start
LABEL_SendDiasSync
	cmp.b			  DiasType,2
	jne				  LABEL_EndPllSync
	//#SR014 end
	
	L.EDI			  _IOSEGMENT
//--- Sync To Master PLL --
	S				    (EDI+DmPllSyncAdr)
LABEL_EndPllSync

END_FUNCTION
#endif

FUNCTION DiasMasterMain::FinishIMProg
  VAR
    i		   : UDINT;
  END_VAR

	if DiasType = 2  then  // test if we have a IMaster
		if release <> 16#ffffffff then  // #fa 080103
  
			//#SR005 Start
			p_ModuleRetryCnt := ( _IOSegment$UDINT + 16#F200 )$^ModuleRetryCnt;			
			for i := 0 to 63 do
				( ( p_ModuleRetryCnt + i )$^USINT )^ := 0;
			end_for;
			//#SR005 End

			//#SR021 start
			//add Realtime Time offset for IM (actually for CIC012)
			ud_DelayRealtime += ( ui_AddTime * ui_RtDIASAccesses );
      ud_DelayCyclic += ( ui_AddTime * ui_CyDIASAccesses );
			//#SR021 end
			
			//#SR004 Start
			if IPMainCy > ( ud_IMMemory / 4 )$DINT then//DmCallRes * sizeof( CallStruct ) then
#ifdef HWC_LogError
        HWC_LogError(this, "@05B4 (DiasMasterMain::FinishIMProg) Too many cyclic calls");
#else
				TRACE("DiasMaster: Too many cyclic calls");
				//#SR008 start
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Too many cyclic calls");
				end_if;
				//#SR008 end
#endif
				MasterOn := 0;
				ImOff := 1;

			elsif IPMainRt >  ( ud_IMMemory / 4 )$DINT then//DmCallRes * sizeof( CallStruct ) then
#ifdef HWC_LogError
        HWC_LogError(this, "@05BE (DiasMasterMain::FinishIMProg) Too many realtime calls");
#else
        TRACE("DiasMaster: Too many realtime calls");
				//#SR008 start
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Too many realtime calls");
				end_if;
				//#SR008 end
#endif
				MasterOn := 0;
				ImOff := 1;

      elsif IPSub > ( ud_IMMemory / 2 )$DINT then
#ifdef HWC_LogError
        HWC_LogError(this, "@000C (DiasMasterMain::FinishIMProg) Program of intelligent master is too large");
#else
        TRACE("DiasMaster: Program of intelligent master is too large");
				//#SR008 start
				if p_KernelLog <> NIL then
					OS_KernelLog0( "DiasMaster: Program of intelligent master is too large");
				end_if;
				//#SR008 end
#endif
				MasterOn := 0;
				ImOff := 1;

      else
	  		//#SR004 End
				
				//#SR015 start
				//calculate Rt - Startpoint (detailed description see Methode "RtWorkCIPC" Label "MovestartPoint"
				if ( us_MusecMode ) then
					( ( _IOSegment$UDINT + DmPllSyncDel )$^USINT )^ := ( RtInterval$UDINT - ( ud_DelayRealtime / ( DmTmrResso * 1000 ) ) - DmTimeReserveIM )$USINT;
				else
					( ( _IOSegment$UDINT + DmPllSyncDel )$^USINT )^ := ( RtInterval$UDINT - ( ud_DelayRealtime / ( DmTmrResso * 1000 ) ) - DmTimeReserveIM - 1 )$USINT;
				end_if;
				//#SR015 end
				
				LinkMaster();
				LoadCyclicProg();
				LoadRealtimeProg();
        LoadRtCyCode();
				StartCyclicProg();
				DIASRetryCounter :=0;
			end_if;	//#SR004

			#ifndef OldDiasXilinx										//#SR013
				//we have to set the pointer for RTBSync Realtimeprog

      HandlesRT[0].thisp := ( SyncCall.Read() )$^HwBase;    //===HF
			#endif
	  	
      RtTimeIM_us := ud_DelayRealtime/1000;
      CyTimeIM_us := ud_DelayCyclic/1000;
      
			//#SR013 start
			if _RtOSversion >= 16#1132 & us_MuSecMode then
				if ud_DelayRealtime > ui_ClockTicks * 1000 / 2 then
#ifdef HWC_LogError
          HWC_LogError(this, "@05D2 (DiasMasterMain::FinishIMProg) Time of realtime - program of intelligent master is to long. Diasbus is set off");
#else
					TRACE("Time of realtime - program of intelligent master is to long. Diasbus is set off");
#endif
					MasterOn := 0;
					ImOff := 1;
				elsif (ud_DelayRealtime + ud_DelayCyclic) > ui_ClockTicks * 1000 / 2 then
#ifdef HWC_LogError
          HWC_LogError(this, "@05C8 (DiasMasterMain::FinishIMProg) Warning: Cyclic - program of intelligent master can't be done in 1 run");
#else
					TRACE("Warning: Cyclic - program of intelligent master can't be done in 1 run");
#endif
        end_if;
      else
				if ud_DelayRealtime > (sd_PllTimeGlob_us$UDINT * 1000) then
#ifdef HWC_LogError
          HWC_LogError(this, "@05D2 (DiasMasterMain::FinishIMProg) Time of realtime - program of intelligent master is to long. Diasbus is set off");
#else
					TRACE("Time of realtime - program of intelligent master is to long. Diasbus is set off");
#endif
					MasterOn := 0;
					ImOff := 1;
				elsif (ud_DelayRealtime + ud_DelayCyclic) > (sd_PllTimeGlob_us$UDINT * 1000) then
#ifdef HWC_LogError
          HWC_LogError(this, "@05C8 (DiasMasterMain::FinishIMProg) Warning: Cyclic - program of intelligent master can't be done in 1 run");
#else
					TRACE("Warning: Cyclic - program of intelligent master can't be done in 1 run");
#endif
        end_if;
			end_if;				
			//#SR013 end
		end_if;
 
 		IF CDiasType = 2 THEN
      this^.control.pmeth^.rtwork := #RtWorkIMCIPC();
      CorrectMyTaskTime();
 		END_IF;
	else

 		this^.control.pmeth^.cywork :=#CyWorkStdMas();

 		if _IOSegment <> 16#d0000 then	
      // we overload our rtwork and cywork funktion
      // because we have a standard master
      this^.control.pmeth^.rtwork :=#RtWorkStdMas();
      rtssw :=4;	// it is standard so no setup phase	
 		else
      this^.control.pmeth^.rtwork :=#RtWorkStdMasIPC();
      rtssw :=4;	// it is standard so no setup phase	
 		end_if;

	end_if;

	//#SR016 start
	if ( p_NewPll <> NIL ) & (DiasType = 2) then
		this^.control.pmeth^.rtwork :=#RtWorkETV();
	end_if;
	//#SR016 end

  if ImOff then
#ifdef HWC_LogError
    HWC_LogError(this, "@05DC (DiasMasterMain::FinishIMProg) Intelligent master has been switched off");
#else
    //#SR008 start
    if p_KernelLog <> NIL then
      OS_KernelLog0( "DiasMaster: Intelligent master has been switched off" );
    end_if;
    //#SR008 end
#endif
  end_if;

END_FUNCTION


FUNCTION DiasMasterMain::LastInit
  VAR
    ActualTime  : UDINT;
    ErrorSync   : USINT;	// #BS011
    StateSync   : UDINT; // #BS011
    i		        : UDINT;
    ptrS	      : ^WaitSyncCall;
    sz_name	    : ARRAY[ 0..255 ] OF CHAR;	//ws006
  END_VAR

	IF _LSL_POS^.piTask^$MYLSL_ITASK.SetNbrOfLdrPhaseObjects <> NIL 
 		& _LSL_POS^.piTask^$MYLSL_ITASK.MoveObject THEN// nur wenn funktionen verfügbar 


		// ****** first synchronize the IM ****************************************
 		// bring me to the first position
 		if ( HwControl = 0 ) then			//#SR014
			
			OS_MoveObject(this,2,1);
 			OS_SetNbrOfLdrPhaseObjects(1);				
		end_if;												//#SR014

 		// now wait max 1 sek to get sync otherwise start APL and give
 		// error message to develloper
 		ActualTime := ops.tAbsolute;
 		ErrorSync  := 0; // #BS011

	 	// now we wait till the Master is synchron
 		while ((ops.tAbsolute - ActualTime) < 5secs) do
      if rtssw = 4 then
        cywork();
      end_if;
      if (CyclicReady AND 1) & (RealtimeReady AND 1) then
#ifdef HWC_LogError
        HWC_LogError(this, "@053C (DiasMasterMain::LastInit) Init ends");
#else
        //#SR008 start
        if p_KernelLog <> NIL then
          OS_KernelLog0( "DiasMaster: Init ends" );
        end_if;
        //#SR008 end
#endif
        EXIT;	// --> READY start 
      end_if;
 		end_while;

 		if ((ops.tAbsolute - ActualTime) >= 5secs) then
#ifdef HWC_LogError
      HWC_LogError(this, "@05E6 (DiasMasterMain::LastInit) Timeout while synchronization. DIAS Master is not ready (startup fault)!");
#else
      TRACE("DiasMaster: Timeout while synchronization. DIAS Master is not ready (startup fault)!");
			//#SR008 start
			if p_KernelLog <> NIL then
				OS_KernelLog0( "DiasMaster: Timeout while synchronization. DIAS Master is not ready (startup fault)!");
			end_if;
			//#SR008 end
#endif
      ErrorSync := 1;
 		end_if;
	end_if;

		// ****** then synchronize all DiasModules if necessary ***********************
	// #BS011
	IF WaitSync & ErrorSync = 0 THEN
		ActualTime := ops.tAbsolute;
		StateSync := CheckSyncModules(ActualTime);
		WHILE StateSync = 0 DO
			cywork();
			StateSync := CheckSyncModules(ActualTime);
		END_WHILE;
		IF StateSync = 2 THEN
			// on timeout we trace the objectnames
			IF DiasSync.NumberCalls THEN
				ptrS := #DiasSync.Modules[0];
#ifdef HWC_LogError
        HWC_LogError(this, "@000D (DiasMasterMain::LastInit) Timeout on synchronizing modules on objects:");
#else
				Trace("Timeout on synchronizing modules on objects:");
#endif
				FOR i := 0 TO DiasSync.NumberCalls-1 DO
					IF PtrS^.SyncState = 0 THEN
						IF PtrS^.thisp <> NIL THEN
							//ws006
							_GetObjName( PtrS^.thisp$^VirtualBase, #sz_name[ 0 ] );
#ifdef HWC_LogError
              HWC_LogError(this, #sz_name[ 0 ]);
#else
							trace( #sz_name[ 0 ] );
#endif
						ELSE
#ifdef HWC_LogError
              HWC_LogError(this, "Object with NIL Pointer !!");
#else
							Trace("Object with NIL Pointer !!");
#endif
						END_IF;
					END_IF;
					PtrS += SIZEOF(WaitSyncCall);
				END_FOR;
			END_IF;
		END_IF;
	END_IF;
	// #BS011

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::RtWorkETV
  VAR_INPUT
    EAX		: UDINT;
  END_VAR
  VAR_OUTPUT
    state		: UDINT;
  END_VAR
  VAR
    Temp      : DINT;
    pHandle   : ^OneHandle;
    i         : UDINT;
  //-------------------------------------Profiler Start----------------------------------------------
  #ifdef DiasMasterC_Profiler
    MuSecTime : UDINT;
  END_VAR

  MuSecTime := OS_ReadMicroSec();
  //Anfangsdelay abwarten
	if MuSecTime - DMC_Time_RT.init > DM_ProfilerDelay then
    DMC_Time_RT.start  := MuSecTime;    //Startzeit nehmen
    DMC_Time_RT.initfl := FALSE;        //Initflag löschen
  else
    DMC_Time_RT.initfl := TRUE;         //Initflag setzen
  end_if;
//-------------------------------------Profiler End------------------------------------------------
#else
  END_VAR
#endif

  if b_PllInit = FALSE then
    StartPll();
    b_PllInit := TRUE;
  end_if;

  if (ImOff = FALSE) then      
    //look if Rt program of IM is finished
    if (ops.SysState = C_RUNRAM) & (_IOSegment$^USINT + DmUserData + 3)^ then
      ud_ErrorCountTimeSliceEnd += 1;
      if us_FirstTimeSliceEnd = 0 then
        us_FirstTimeSliceEnd := 1;
      end_if;
    end_if;
      
    //Reset Byte to find out if Rt of IM starts while Rt of DM is running
    (_IOSegment$^USINT + DmUserData + 4)^ := 0;


    case RtSSW of
      
        // ***********************************************************
        //   we have to wait that the PLL is locked before we start
        // ***********************************************************
      0:

        if Release <> 16#FFFFFFFF then
          StartRealtimeProg();
          RtSSW += 1;
          LogRtSSW();
        end_if;


        // **********************************************************
        //  now we are starting the RTProg 
        // **********************************************************
      1:

        StartRealtimeProg();
        RtSSW += 1;
        LogRtSSW();


        // ****************************************************************
        //  now we have to move the startpoint till we are 50usec before
        // ****************************************************************
      2:

        if us_MuSecMode then
          Temp := RtInterval - (ud_DelayRealtime / (DmTmrResso * 1000))$DINT - DmTimeReserveIM;
        else
          Temp := RtInterval - (ud_DelayRealtime / (DmTmrResso * 1000))$DINT - (DmTimeReserveIM + 1);
        end_if;
        (_IOSegment$^USINT + DmPllSyncDel)^ := Temp$USINT;
        ui_RtStartPoint := Temp$UINT * DmTmrResso;
        RtSSW += 1;
        LogRtSSW();
          
          
        // ***********************************************************
        //   read the calculated time 
        // ***********************************************************
      3:

        TimeBeforeNextSync := to_uint((_IOSegment$^USINT + DmUserData)^);
        RtSSW += 1;
        LogRtSSW();


        // ***************************************************************
        //   do the refresh of I/O 
        // ***************************************************************
      4:
          
        // get rtload of im
        TimeAtRtPreEnd := (_IOSegment$^USINT + DmUserData)^ * DmTmrResso;          
        Rt_Load := ((TimeAtRtPreEnd - ui_RtStartPoint) * 1000) / sd_PllTimeGlob_us;

        RealtimeReady := TRUE;
          
        // now take data and call update methods with thispointer
        if HandleNrRT then
          pHandle := #HandlesRT[0];
          for i := 0 to HandleNrRT-1 do
            if pHandle^.Typ AND DmCallProg then
              pHandle^.thisp^.UpdateRt(pHandle^.Address);
            end_if;
              
            pHandle += sizeof(OneHandle);
          end_for;

          if HwControl = 0 then
            UpdateRtPostScan_IM();
          end_if;
        end_if;
    end_case;

    if (StateCDiasSync AND 1) = 0 then
      StateCDiasSync := (CDIASSync + 2)^;
    end_if;

    WDDIAS();
  end_if;
    
  state := READY;
  
//-------------------------------------Profiler Start----------------------------------------------
#ifdef DiasMasterC_Profiler
  //schaun ob Delayzeit schon abgelaufen ist
  if DMC_Time_RT.initfl = FALSE then
    MuSecTime := OS_ReadMicroSec();

    DMC_Time_RT.stop := MuSecTime;        //Stopzeit speichern

    MuSecTime -= DMC_Time_RT.start;       //Differenz berechnen
    MuSecTime -= DM_CPUconstant;          //Zeit für OS_REadMicroSec - Funktion subtrahieren

    DMC_Time_RT.diff := MuSecTime;        //korr. Differenz speichern
    DMC_Time_RT.sum  += MuSecTime;        //Zur Summe addieren

    DMC_Time_RT.run  += 1;                //Durchlaufzähler erhöhen

    if MuSecTime < DMC_Time_RT._min then
      DMC_Time_RT._min := MuSecTime;      //Minimalzeit speichern
    end_if;

    if MuSecTime > DMC_Time_RT._max then
      DMC_Time_RT._max := MuSecTime;      //Maximalzeit speichern
    end_if;

    //Durchschnitt berechnen
    //*100 damit wir 2 Kommastellen haben
    DMC_Time_RT.avg := DMC_Time_RT.sum * 100 / DMC_Time_RT.run;
  end_if;

#endif
//-------------------------------------Profiler End------------------------------------------------
END_FUNCTION
#else
FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::RtWorkETV				//#SR016
  VAR_INPUT
    EAX		: UDINT;
  END_VAR
  VAR_OUTPUT
    state		: UDINT;
  END_VAR


//#wp001
//============================ Profiler start======================================================
#ifdef  DiasMasterC_Profiler
	CLI											//damit keine Interrupts die Messung stören
	push 		  edi
	push 		  eax
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_ReadMicroSec - Funktion aufrufen
	l.ebx		  eax
	sub.ebx		DMC_Time_RT.init					//Anfangsdelay abwarten
	cmp.ebx		DM_ProfilerDelay
	jle			  LABEL_DMCPREEND
	s.eax 		DMC_Time_RT.start					//Startzeit nehmen
	x.cl		  cl							
	s.cl		  DMC_Time_RT.initfl				//Initflag löschen
	jmp 		  LABEL_DMCstartfunc

LABEL_DMCPREEND
	l.b		    DMC_Time_RT.initfl,1					//Initflag setzen
	
LABEL_DMCstartfunc
	pop 		  eax
	pop 		  edi
#endif	
//============================ Profiler end========================================================

	//#SR022 start
	cmp.b			b_PllInit, TRUE
	je				LABEL_NoStart

	//in first run we start pll
	call			StartPll
	l.b				b_PllInit, TRUE
LABEL_NoStart
	//#SR022 end

	CMP.B			ImOff,1
	JE				RT_End1
	
	cmp.w			ops.SysState,1					//look if CPU is in RunRam
	jne				LABEL_Continue

  	l.edi			_IOSegment
	l.bl			( edi + DmUserData + 3 )		//look if Rt program of IM is finished
	o.bl			bl
	jz				LABEL_Continue
	inc.d			ud_ErrorCountTimeSliceEnd
	cmp.b			us_FirstTimeSliceEnd,0
	jne				LABEL_Continue

	l.b				us_FirstTimeSliceEnd,1
LABEL_Continue
  l.edi			_IOSegment
	l.b				( edi + DmUserData + 4 ), 0		//Reset Byte to find out if Rt of IM starts while Rt of DM is running

	lzxb.eax	RtSSW
	shl.eax		3           //save some time here
	add.eax		#RtSel
	jmp			  eax

RtSel
	jmp			WaitForSync			// 0 : wait till PLL in locked
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			weAreSync			// 1 : wait one period to get a right time 
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			MovStartPoint		// 2 : mov start point to the right pos
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			readpoint           // 3 : read one time the point 
	rcl.eax 	0					//ws005: simple placeholder (does really nothing)
	jmp			RtRefresh			// 4 : do the realtime refresh


// ***************************************************************
//   do the refresh of I/O 
// ***************************************************************

RtRefresh

// *************************************************
//  read the time point
// *************************************************
	lzxb.eax	(edi+DmUserData)
	imul.ax		ax,DmTmrResso
	s.eax 		TimeAtRtPreEnd 

	//***********calculate Rt - usage rate***********************
	lzxw.ebx	ui_RtStartPoint
	sub.eax		ebx
	imul.eax	eax,1000
	x.edx		  edx
	l.ebx		  sd_PllTimeGlob_us
	div			  ebx
	s.eax		  Rt_Load

// **************************************************
//  now take data and call update function with thisp 
// **************************************************
	l.b			  RealtimeReady,1

	l.ebx		  #HandlesRt
	lzxw.ecx	HandleNrRt
	jecxz		  LABEL_RtPostScan

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRT
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

LABEL_RtPostScan
//BLEERN START
  cmp.d     HwControl, 0
  jne       Rt_end
  
  call      UpdateRtPostScan_IM
//BLEERN ENDE

	jmp			  RT_end	

// ****************************************************************
//  now we have to move the startpoint till we are 50usec before
// ****************************************************************

MovStartPoint
	L.EAX		  ud_DelayRealtime	//Time of Rt - Programm of IM				
	CLR			  EDX
	L.ECX		  DmTmrResso*1000		// we have nanoseconds and we have to put in 25µs units
	DIV 		  ECX
	l.ebx		  eax

	l.eax		  RtInterval				
	sub.eax		ebx
	cmp.b		  us_MuSecMode,1			//have we µs - Mode
	jne			  LABEL_Reserve_Std
	sub.eax		DmTimeReserveIM			//not so much reserve tim in µs - Mode
	jmp			  LABEL_EndReserve
LABEL_Reserve_Std
	sub.eax		DmTimeReserveIM + 1
LABEL_EndReserve
	s.al		  (EDI+DmPllSyncDel)
	imul.ax		ax,DmTmrResso
	s.ax		  ui_RtStartPoint
	inc.b		  RtSSW
	call		  LogRtSSW
	jmp			  RT_end	


// ***********************************************************
//   read the calculated time 
// ***********************************************************

ReadPoint
	clr			  eax
	l.al		  (edi+DmUserData)
	s.ax		  TimeBeforeNextSync
	inc.b		  RtSSW
	call		  LogRtSSW
	jmp			  RT_end	



// **********************************************************
//  now we are starting the RTProg 
// **********************************************************

weAreSync
	call		  StartRealtimeProg	
	inc.b		  RtSSW
	call		  LogRtSSW
	jmp			  RT_end	



// ***********************************************************
//   we have to wait that the PLL is locked before we start
// ***********************************************************
WaitForSync
	cmp.d		  release,16#FFFFFFFF
	je			  RT_end

	call		  StartRealtimeProg	
	inc.b		  RtSSW
	call		  LogRtSSW
RT_end

	FC				WDCDIAS
RT_End1
	L.EAX	 		READY$UDINT

//#wp001
//============================ Profiler end======================================================
#ifdef  DiasMasterC_Profiler	
	cmp.b 		DMC_Time_RT.initfl, 1				//schaun ob Delayzeit schon abgelaufen ist
	je			LABEL_DMCEND
	pushad 	
	l.edi 		_LSL_POS
	l.edi 		( edi + DM_LSLPOS_SYSTIME )
	l.edi 		( edi + DM_LSLSYSTIME_MICROSEC )
	call		  edi								//OS_REadMicroSec - Funktion aufrufen
	s.eax 		DMC_Time_RT.stop					//Stopzeit speichern
	l.ebx 		DMC_Time_RT.start
	sub.eax		ebx								//Differenz berechnen
	sub.eax		DM_CPUconstant					//Zeit für OS_REadMicroSec - Funktion subtrahieren
	s.eax 		DMC_Time_RT.diff					//Ergebnis speicern
	l.ebx 		DMC_Time_RT.sum
	add.ebx 	eax								//Zur Summe addieren
	s.ebx 		DMC_Time_RT.sum					//Summe speichern
	l.ecx		  DMC_Time_RT.run
	inc 		  ecx								//Durchlaufzähler erhöhen
	s.ecx 		DMC_Time_RT.run					//Durchlaufzähler speichern
	cmp.eax		DMC_Time_RT._min					//mit Minimalzeit vergleichen
	jae			  LABEL_DMCcont
	s.eax 		DMC_Time_RT._min					//Minimalzeit speichern

LABEL_DMCcont
	cmp.eax 	DMC_Time_RT._max					//Mit Maximalzeit vergleichen
	jbe 		  LABEL_DMCcont1
	s.eax 		DMC_Time_RT._max					//Maximalzeit speichern

LABEL_DMCcont1
	l.eax		  ebx								//Summe in al laden
	imul.eax	eax,100							//*100 damit wir 2 Kommastellen haben
	x.edx 		edx					
	idiv		  ecx								//durch Durchläufe dividieren
	s.eax		  DMC_Time_RT.avg					//Durchschnitt speichern
	popad

LABEL_DMCEND
	STI
#endif	
//============================ Profiler end========================================================

END_FUNCTION
#endif

#pragma warning (disable:73) 
FUNCTION VIRTUAL GLOBAL DiasMasterMain::I2CWriteOneByte
  VAR_INPUT
    AdressCDIAS		: UINT;
    pData		: ^USINT;
  END_VAR
  VAR_OUTPUT
    result		: DINT;
  END_VAR
  
	result:=-1;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::WriteEEData
  VAR_INPUT
    Adress		: UDINT;
    pData		: ^USINT;
    ui_length		: UINT;
    ui_offset		: UINT;
  END_VAR
  VAR_OUTPUT
    retval		: DINT;
  END_VAR
  
	retval:=-1;
  
END_FUNCTION
#pragma warning (default:73)
//[#ENGLISH]
//[>ui_value]value wich increases access time for ardware access
FUNCTION VIRTUAL GLOBAL DiasMasterMain::IncreaseHwAccessTime
  VAR_INPUT
    ui_value		: UINT;
  END_VAR

	ui_AddTime += ui_value;

END_FUNCTION


FUNCTION  DiasMasterMain::StartPll

	//start CDIAS Pll if available
	if ( p_CDIAS <> NIL ) then
		p_CDIAS^.us_Control.SyncOut	:= TRUE;
	end_if;

	//start DIAS Pll if available
	if ( p_DIAS <> NIL ) then
		p_DIAS^.us_Control.SyncOut	:= TRUE;
	end_if;

END_FUNCTION


FUNCTION DiasMasterMain::CorrectMyTaskTime

  //Only correct tasktime if we are Not connected with HwControl, we have a tasktime >1ms and PLL Trigger mode is correct
  if (ud_TaskTime > 1000) & ( CDIASSync <> NIL ) & ((CDIASSync + 2)^ AND 16#80) & HwControl = 0 then

    //set task time of DiasMaster to 1ms and select the right ms in RtWork
    if To_TaskObjectControl.ChangeObjectState( thispointer := this, actioncmd := 1, tasktype := OBJ_RT, debugobj := 0, newtime := 1 ) = 0 then
      b_TaskTimeCorrected := TRUE;
    else
      // failed to correct task time
    end_if;
  end_if;

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
FUNCTION DiasMasterMain::LoadRtCyCode
  VAR
  	pIM   : ^USINT; // pointer to IM, where code should be stored
    pCode : ^USINT; // pointer on local memory, where code is stored
    i     : DINT;
  END_VAR

	// _IOSEGMENT    pointer to IM
	//	StartOfCode  load startoffset of programm in IM
	// #CodeRtCy     pointer on local memory, where code is stored
	// IPSub         maximum offset in local memory

  pIM := _IOSegment$^USINT + StartOfCode;
  pCode := #CodeRtCy[0];

  for i := 0 to (IPSub-1) do
    pIM^ := pCode^;
    
    pIM   += sizeof(USINT);
    pCode += sizeof(USINT);
  end_for;

END_FUNCTION
#else
FUNCTION AWL DiasMasterMain::LoadRtCyCode

	L.EDI		_IOSEGMENT   // pointer to IM
	L.EBX		StartOfCode  // load startoffset of programm in IM
	l.edx		#CodeRtCy    // pointer on local memory, where code is stored
	l.ecx		IPSub        // maximum offset in local memory
	inc			ecx          // increase by 1 to get length of used memory
	
LoadRtLoop
	l.al		(edx)
	s.al		(ebx+edi)
	inc			ebx
	inc			edx
	loop		LoadRtLoop

END_FUNCTION
#endif  

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetObjectPath
	VAR_INPUT
		p_us_ObjectPath 	: ^USINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	: DINT;
	END_VAR

  if ( p_us_ObjectPath <> NIL ) then
  
    //set length of path = 1
    p_us_ObjectPath^ := 1;

#ifdef HWT_ucGetMyDomain
    if pHardwareTree then
      // at least CIL version 01.00.003 needed
      if pHardwareTree^.udVersion >= 16#1003 then
        // domain info byte
        ( p_us_ObjectPath + 1 )^ := HWT_ucGetMyDomain();  
      else
        // domain info byte
        ( p_us_ObjectPath + 1 )^ := 0;
#ifdef HWC_LogError
        HWC_LogError(this, "@000E (DiasMasterMain::GetObjectPath) No domain info availbable: hardwaretree CIL version >= 01.00.003 needed");
#else
        TRACE("No domain info availbable: hardwaretree CIL version >= 01.00.003 needed");
#endif
      end_if;
    else
      // domain info byte
      ( p_us_ObjectPath + 1 )^ := 0;
    end_if;
#else
    // domain info byte
    ( p_us_ObjectPath + 1 )^ := 0;
#endif

    sd_retval := 0;
        
  else
  
    sd_retval := -1;
    
  end_if;
    
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::SetObjectThisp
	VAR_INPUT
		p_us_ObjectPath 	: ^USINT;
		ud_thisp 	: UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	: DINT;
	END_VAR
  VAR
  	i : UINT;
    b_ModuleFound : BOOL;
  END_VAR

  
  if ( pHardwareTree <> NIL ) then
    
    sd_retval := HWT_ISETOBJECTTHISP(0,p_us_ObjectPath,ud_thisp);
    
  else
    
    sd_retval := 0;
  
  end_if;
  
  // Check if this pointer is already in the list
  b_ModuleFound := FALSE;
  if s_HWTModuleList.ui_Index then
    
    i := 0;   
    repeat
    
      if (s_HWTModuleList.ap_ModuleList[i] = ud_thisp$pVirtualBase) then
        b_ModuleFound := TRUE;
      end_if;
    
      i += 1;
    until i >= s_HWTModuleList.ui_Index end_repeat;

  end_if;
  
  // Safe this pointer if it is not in the list
  if b_ModuleFound = FALSE &
     s_HWTModuleList.ui_Index < DIASMASTERC_MAX_MODULE_NO then
    s_HWTModuleList.ap_ModuleList[s_HWTModuleList.ui_Index] := ud_thisp$pVirtualBase;
    s_HWTModuleList.ui_Index += 1;
  end_if;
  
  
END_FUNCTION

FUNCTION VIRTUAL GLOBAL DiasMasterMain::GetObjectThisp
	VAR_INPUT
		p_us_ObjectPath 	: ^USINT;
	END_VAR
	VAR_OUTPUT
		ud_Thisp 	: UDINT;
	END_VAR
  
  if ( pHardwareTree <> NIL ) then
  
    ud_thisp := HWT_iGetObjectThisp(0,p_us_ObjectPath);

  else
  
    ud_thisp := 0;
  
  end_if;

END_FUNCTION

#ifdef _LSL_TARGETARCH_ARM
#pragma warning(disable:72 )
FUNCTION VIRTUAL GLOBAL DiasMasterMain::UpdateRtPostScan
  VAR
    pHandle  : ^OneHandle;
    i        : DINT;
  END_VAR
#pragma warning(default:72 )
#ifdef DM_DEBUG_ARM
  // This method is not supported with ARM
  ((0)$^USINT)^ := 0;
#endif

END_FUNCTION
#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::UpdateRtPostScan

  // Function is called by HW-Control!
    
	l.ebx		  #HandlesRTPostScan
	lzxw.ecx	HandleNrRTPostScan
	jecxz		  NoRtProg

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRtPostScan
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

NoRtProg

END_FUNCTION
#endif

#ifdef _LSL_TARGETARCH_ARM
FUNCTION VIRTUAL GLOBAL DiasMasterMain::UpdateRtPostScan_IM
  VAR
    pHandle  : ^OneHandle;
    i        : UDINT;
  END_VAR

  // Function is called by HW-Control!
  if MasterON then
    // call update methods with thispointer
    if HandleNrRTPostScan then
      pHandle := #HandlesRTPostScan[0];

      for i := 0 to HandleNrRTPostScan-1 do
        if pHandle^.Typ AND DmCallProg then
          pHandle^.thisp^.UpdateRtPostScan(pHandle^.Address);
        end_if;
              
        pHandle += sizeof(OneHandle);
      end_for;
    end_if;

//LABEL_TimeSlice
    if (_IOSegment$^USINT + DmUserData + 4)^ then
      ud_ErrorCountTimeSliceStart += 1;
      if us_FirstTimeSliceStart = 0 then
        us_FirstTimeSliceStart := 1;
      end_if;
    end_if;
  end_if;

END_FUNCTION
#else

FUNCTION AWL VIRTUAL GLOBAL DiasMasterMain::UpdateRtPostScan_IM

  // Function is called by HW-Control!
  
  cmp.d     MasterON, 1
  jne       RT_End
  
	l.ebx		  #HandlesRTPostScan
	lzxw.ecx	HandleNrRTPostScan
	jecxz		  LABEL_TimeSlice

HandleLoopRt
	test.w		(ebx+OneHandle.Typ),DmCallProg
	jz			  NextHandleRt

	push		  ecx
	push		  ebx


	L.eax		  (ebx+OneHandle.thisp)
	LZXW.ECX	(ebx+OneHandle.Address)
	push		  ecx
	push		  eax

	call		  CallUpdataRtPostScan
	add.esp		8

	pop			  ebx
	pop			  ecx

NextHandleRt	
	add.ebx		sizeof (OneHandle)
	loop		  HandleLoopRt

	//#SR010 start
LABEL_TimeSlice
  l.edi		  _IOSegment
	lzxb.eax	( edi + DmUserData + 4 )
	o.eax		  eax
	jz			  RT_end

	inc.d		  ud_ErrorCountTimeSliceStart
	cmp.b		  us_FirstTimeSliceStart,0
	jne			  RT_end
	l.b			  us_FirstTimeSliceStart,1
	//#SR010 end		
  
RT_End

END_FUNCTION
#endif

FUNCTION DiasMasterMain::CallUpdataRtPostScan
	VAR_INPUT
		Thisp 	: pHwBase;
		Handle 	: UDINT;
	END_VAR
  
  thisp^.UpdateRtPostScan(handle);
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::SetRetryCounterAvailability
	VAR_INPUT
		Port 	          : USINT;
		p_State 	      : ^IO_State;
		p_RetryCounter 	: ^DINT;
	END_VAR
  
  if s_RetryCounter.Quantity < 500 then
    s_RetryCounter.RetryCounter[s_RetryCounter.Quantity].Place          := Port;
    s_RetryCounter.RetryCounter[s_RetryCounter.Quantity].p_State        := p_State;
    s_RetryCounter.RetryCounter[s_RetryCounter.Quantity].p_RetryCounter := p_RetryCounter;
    s_RetryCounter.Quantity += 1;
  end_if;

END_FUNCTION


FUNCTION VIRTUAL DiasMasterMain::UpdateDIASRetryCounter
  VAR
    i                          : DINT;
    OldRetryCounter            : USINT;
    NewRetryCounter            : USINT;
    p_actualRetryCounterServer : ^UDINT;
    p_actualStateServer        : ^IO_State;
  END_VAR

  //get info how much DIAS moduls are connected
  i := s_RetryCounter.Quantity - 1 ;
  
  while i > - 1  do
  
    //load pointer to state server from counterstruct
    p_actualStateServer := (p_State + (i * sizeof(a_RetryStruct)))^$^IO_State;
    
    //check if pointer is valid
    if p_actualStateServer <> NIL then
    
      //check online state
      if MasterON then
    
        //compare if hw class state is ok
        if ((p_actualStateServer^$UINT) and 2#1100000000000011) = 0 then
        
          if DiasType = 2 then //check if we are intelligent master
      
            //load pointer to retrycounter server from counterstruct
            p_actualRetryCounterServer := (p_RetryCounter + (i * sizeof(a_RetryStruct)))^$^UDINT;
          
            //check if pointer is valid
            if p_actualRetryCounterServer <> NIL then
            
              //load retrycounter value from hardware
              NewRetryCounter := (p_ModuleRetryCnt$^USINT + (p_port + (i * sizeof(a_RetryStruct)))^)^;
              //get old value from counter
              OldRetryCounter := (p_OldRetryCounter + i)^;
              
              //check for differences
              if NewRetryCounter <> OldRetryCounter then
              
                //if new counter greater, no overflow ->
                if NewRetryCounter > OldRetryCounter then
                  p_actualRetryCounterServer^ += (NewRetryCounter - OldRetryCounter);
                else
                  //for overflow correction add 256
                  p_actualRetryCounterServer^ += (NewRetryCounter + 256 - OldRetryCounter);
                end_if;
                
                //set old counter to the value from new counter
                (p_OldRetryCounter + i)^ := NewRetryCounter;
              end_if;
              
            end_if;
            
          end_if;  
          
        else
          
          //class state not ok, so set state pointer to nil - no more checks needed
          (p_State + (i * sizeof(a_RetryStruct)))^ := NIL;
          
        end_if;
        
      else
        //online state is 0, so signal error on class state server
        p_actualStateServer^$UINT := 16#FFFF;
      end_if;
      
    end_if;
    
    //decrement struct counter
    i -= 1;
  
  end_while;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL DiasMasterMain::AddRequiredObject
	VAR_INPUT
		thisp 	: ^void;
	END_VAR
  
  if b_NotfirstCall = false then
    b_NotfirstCall := true;
    p_RequiredObjects := To_StdLib.Malloc(size:=(500*sizeof(^void)));
  end_if;
  
  
  if RequiredObjectCounter < 500 then
    (p_RequiredObjects + (RequiredObjectCounter * sizeof(^void)))^$^void := thisp;
    RequiredObjectCounter += 1;
  else
#ifdef HWC_LogError
    HWC_LogError(this, "@000F (DiasMasterMain::AddRequiredObject) Too many required object classes added");
#else
		TRACE( "DiasMaster: Too many required object classes added");
#endif
  end_if;  

END_FUNCTION

#pragma warning(disable:137 )
FUNCTION VIRTUAL DiasMasterMain::CheckforRequiredError
  VAR
    i         : UINT;
    thisp     : ^virtualbase;
#ifndef HWC_LogError
    sz_name	  : array[ 0..255 ] of char;
#endif
    MyPara    : CmdStruct;
    MyResult  : results;
    DiasError : BOOL;
    CdiasError: BOOL;
  END_VAR

  if RequiredObjectCounter > 0 then
    //--- init the newInst command
    MyPara.uiCmd := DM_CHECK_REQUIRED_ERROR;
    CdiasError  := false;
    DiasError   := false;
    for i := 0 to (RequiredObjectCounter -1) do 
      thisp := (p_RequiredObjects + (i * sizeof(^void)))^$^virtualbase;
      //--- init result for next call
      MyResult.aData[0] := 16#FF;
      MyResult.aData[1] := 16#FF;
      if (thisp^.NewInst(#MyPara, #MyResult) = ERROR) then
        //Required Error!
        
        if (MyResult.aData[1] = CDIAS_MODULE) then
          CdiasError := true;
        end_if;
        if (MyResult.aData[1] = DIAS_MODULE) then
          DiasError := true;
        end_if;

#ifdef HWC_LogError
        HWC_LogError(thisp, "@0010 (DiasMasterMain::CheckforRequiredError) Required Error triggerd by this object");
#else
        _GetObjName( thisp, #sz_name[ 0 ] );
        if RequiredErrors = 0 then
          Trace ("DiasMaster: Required Error triggerd by object(s):");
        end_if;
        Trace (#sz_name[ 0 ] );
#endif

        RequiredErrors +=1;
      end_if;     
    end_for;
    
    
    if RequiredErrors > 0 then
    
      if ( IsClientConnected( #To_HwControl ) ) then
        To_HwControl.Write(0);
      end_if; 
      
      case _WhoAmI of
        DESTPLC_WINPC_98,    // LARS, Standard PC, Win98/ME
        DESTPLC_WINPC_NT,    // LARS, Standard PC, WinNT/Win2000/WinXP
        DESTPLC_WINIPC_98,   // LARS, IPC, Win98/ME
        DESTPLC_WINIPC_NT:   // LARS, IPC, WinNT/Win2000/WinXP
        
          //LARS 
          //RamAnd: Don't execute a required error when target platform is lars due to SA 40955

      else
        //--- rtk-os
          if (_rtosversion >= 16#12DC) & (CdiasError = true)then   // _rtosversion >= 1.2.220
            To_OSKernel.AddToServiceProvider(command:="exec climsg 70 A CDIAS module is set required, but there is no CDIAS Module", immediatly:=1);  //stop application
          elsif (_rtosversion >= 16#12DC) & (DiasError = true) then // _rtosversion >= 1.2.220
            To_OSKernel.AddToServiceProvider(command:="exec climsg 25 A DIAS module is set required, but there is no DIAS Module", immediatly:=1);  //stop application
          else
            To_OSKernel.Reset();  //stop application, because this OS doesn't support the message and the CPU state
          end_if;
      end_case;
      
    end_if; 
    
    To_StdLib.Free(p_RequiredObjects);
    
  end_if;  
  
END_FUNCTION
#pragma warning(Default:137 ) 


FUNCTION VIRTUAL GLOBAL DiasMasterMain::SetRequiredError
	VAR_INPUT
		p_this 	: ^HWBase;
	END_VAR
#ifndef HWC_LogError
  VAR
 		sz_name	: array[ 0..255 ] of char;
  END_VAR
#endif
    
  //Required Error!
  
  //log the object responsable
#ifdef HWC_LogError
  HWC_LogError(p_this, "@0011 (DiasMasterMain::SetRequiredError) Required Error triggerd by this object");
#else
  _GetObjName( p_this, #sz_name[ 0 ] );
  if RequiredErrors = 0 then
    Trace ("Required Error triggerd by object(s):");
  end_if;
  Trace (#sz_name[ 0 ] );
#endif
  
  RequiredErrors +=1;
  
  if RequiredErrors > 0 then
  
    if ( IsClientConnected( #To_HwControl ) ) then
      To_HwControl.Write(0);
    end_if;  

    MasterON := 0;
    To_OSKernel.Reset();
    
  end_if;  

END_FUNCTION


FUNCTION DiasMasterMain::CallSafetyManager

  SafetyManagerThis^.CyWork(0);

END_FUNCTION

FUNCTION VIRTUAL GLOBAL DiasMasterMain::Control::NewInst
	VAR_INPUT
		pPara 	: ^CmdStruct;
		pResult 	: ^Results;
	END_VAR
	VAR_OUTPUT
		ret_code 	: IprStates;
	END_VAR
  VAR
  	ui_CurrentHandleNr : UINT;
    // local variables for the Requested HWTString
    pStr_HWTRequested     : ^CHAR;
    b_ModuleFound : BOOL;
  END_VAR
  
  ui_CurrentHandleNr  := 0;
  // local variables for the Requested HWTString
  pStr_HWTRequested   := NIL;
  b_ModuleFound       := FALSE;

  ret_code := ERROR;
  
  CASE pPara^.uiCmd OF  
    //**********************************************************************************************************************************************************
    CMD_GET_HARDWARE_TREE_ENTRY:

      //Set Errors
      pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_ERROR;
      ret_code := ERROR;     
        
      pStr_HWTRequested     := pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry;
      
      //First HWT Path
      if pStr_HWTRequested = nil then
        
        //DiasMaster always has the same object path, store it on the variable
        ud_DiasMasterPosition := DIASMASTERC_OBJECT_PATH_CDIAS;
        
        ret_code := READY;
        pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_HWTSTR_RETURNED;
        pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry := (#ud_DiasMasterPosition)$^CHAR;
                
      //Only possible for Diasmaster own HWT Path
      elsif (pStr_HWTRequested^$USINT = 2) & (pStr_HWTRequested^$UDINT = DIASMASTERC_OBJECT_PATH_CDIAS) then
                
        //DiasMaster always has the same object path, store it on the variable
        ud_DiasMasterPosition := DIASMASTERC_OBJECT_PATH_DIAS;
        
        ret_code := READY;
        pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_HWTSTR_RETURNED;
        pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry := (#ud_DiasMasterPosition)$^CHAR;
      
      elsif (pStr_HWTRequested^$USINT = 2) & (pStr_HWTRequested^$UDINT = DIASMASTERC_OBJECT_PATH_DIAS) then
        
        // Check i list is valid
        if s_HWTModuleList.ui_Index > 0 then
        
          // Call 1st entry in list
          if s_HWTModuleList.ap_ModuleList[0] then
            ret_code := s_HWTModuleList.ap_ModuleList[0]^.NewInst(pPara:=pPara, pResult:=pResult);
          end_if;
        else
          // Dias/CDIAS Master found, but no modules connected.
          ret_code := READY;
          pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_MODULE_FOUND;   
        end_if; 

      else

        // Only Error case is returned from the newInst      
        ret_code := READY;
        pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_MODULE_FOUND;  
        
        // Search for module with passed HWT string
        if s_HWTModuleList.ui_Index > 0 &
           s_HWTModuleList.ui_Index <= DIASMASTERC_MAX_MODULE_NO then
          
          ui_CurrentHandleNr := 0;
          b_ModuleFound := FALSE;
          
          repeat
          
            // Search for the passed HWT-Strubg
            if s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr] then
              ret_code := s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr]^.NewInst(pPara:=pPara, pResult:=pResult);
            end_if;
            
            ui_CurrentHandleNr += 1;            
            
            if ret_code = READY & pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode = _HWC_RETVAL_OK_MODULE_FOUND then
              // If Module was found 
              b_ModuleFound := TRUE;
              exit;
            
            end_if;            
            
          until ui_CurrentHandleNr >= s_HWTModuleList.ui_Index end_repeat;
          
          if b_ModuleFound &                                    // Module was found
             ui_CurrentHandleNr < s_HWTModuleList.ui_Index then // and the next entry is in the list
          
            repeat
              
              // Call next valid Module
              if s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr] then
                ret_code := s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr]^.NewInst(pPara:=pPara, pResult:=pResult);
                return;
              end_if;
            
            until ui_CurrentHandleNr >= s_HWTModuleList.ui_Index end_repeat;
          
            // Already set
//          else
//            // Dias/CDIAS Module found, but no further modules connected.
//            ret_code := READY;
//            pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_MODULE_FOUND;   
          end_if;

          // Already set
//        else
//          // Dias/CDIAS Master found, but no modules connected.
//          ret_code := READY;
//          pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_MODULE_FOUND;   
        end_if;
      end_if;      
        
    //**********************************************************************************************************************************************************
    CMD_GET_HARDWARE_DIAGNOSIS:
    
      //Set Errors
      pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_ERROR;
      ret_code := ERROR;   
      
      pStr_HWTRequested     := pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry;
      
      if pStr_HWTRequested$^UINT^ > 2 then      

        // Search for module with passed HWT string
        if s_HWTModuleList.ui_Index > 0 &
           s_HWTModuleList.ui_Index <= DIASMASTERC_MAX_MODULE_NO then
           
          // Change Command to CMD_GET_HARDWARE_TREE_ENTRY search for the module
          pPara^.uiCmd := CMD_GET_HARDWARE_TREE_ENTRY;          
          
          ui_CurrentHandleNr := 0;
          repeat
            
            ret_code := s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr]^.NewInst(pPara:=pPara, pResult:=pResult);
            
            if ret_code = READY & pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode = _HWC_RETVAL_OK_MODULE_FOUND then
              
              // Get Diagnosis of Module just found
              pPara^.uiCmd := CMD_GET_HARDWARE_DIAGNOSIS;
              
              ret_code := s_HWTModuleList.ap_ModuleList[ui_CurrentHandleNr]^.NewInst(pPara:=pPara, pResult:=pResult);              
              
              return;              
            end_if;
            
            ui_CurrentHandleNr += 1;
            
          until ui_CurrentHandleNr >= s_HWTModuleList.ui_Index end_repeat;
   
        end_if;      
      
      // Check for diasmaster       
      elsif (pStr_HWTRequested^$USINT = 2) & 
         (pStr_HWTRequested^$UDINT = DIASMASTERC_OBJECT_PATH_CDIAS | pStr_HWTRequested^$UDINT = DIASMASTERC_OBJECT_PATH_DIAS ) then
        
        pResult^.aData$t_HWCGetHardwareDiagnosisOut.retcode     := _HWC_RETVAL_OK;
        ret_code := READY;
      end_if;
//**********************************************************************************************************************************************************
    CMD_HWC_ERROR_TO_DIASM:
      // we need to stop the cyclic (rt is stopped, since it's no longer called by the hw control object)
      MasterOn := 0;
      ImOff := 1;
      SkipCy := true;
      
//**********************************************************************************************************************************************************
    CMD_SET_POSTINIT_DONE:
      ret_code := READY;
      b_IsPostInitDone := TRUE;
      
//**********************************************************************************************************************************************************    
    CMD_IS_POSTINIT_DONE:
    
      ret_code := READY;
      pResult^.uiLng    := sizeof(BOOL);
      pResult^.aData[0]$BOOL := b_IsPostInitDone;      
    
//**********************************************************************************************************************************************************    
    else
  
      ret_code := DiasMaster::Control.NewInst(pPara, pResult);
    
  END_CASE;
    
END_FUNCTION
