ORGANIZATION_BLOCK OB 1
	VAR_TEMP
		TMPDUMMY	: INT;
		DTTEMP		: DATE_AND_TIME;
	END_VAR
BEGIN

	// Check forwarding of compound data type to FC
	// (This will create implicit DB pointers)
	AUF		DB 42
	LAR1		P##DTTEMP
	L		DW#16#12345678
	T		D [AR1, P#0.0]
	L		DW#16#87654321
	T		DBD 4
	L		DW#16#AABBCCDD
	T		D [AR1, P#4.0]
	L		DW#16#DDCCBBAA
	T		DBD 8
	CALL		FC 1 (
		DTTEMP	:= #DTTEMP,
		DTDB	:= DB42.DTVAR1,
	)

	// Check forwarding of compound data type from FB to FC
	CALL		FB 10, DB 10 (
		DUMMYIN	:= 42,
		DTVAR	:= DB42.DTVAR1,
	)


	// Check FB compound data type IN_OUT parameter semantics.
	L		42
	T		MW 0
	L		43
	T		MW 2
	L		44
	T		MW 4
	AUF		DB 42
	L		DW#16#11223344 // DB42.DTVAR4
	T		DBD 30
	L		DW#16#55667788 // DB42.DTVAR4
	T		DBD 34
	CALL		FB 20, DB 20 (
		DTIN		:= DB42.DTVAR2,
		INTIN		:= MW 0,
		DTOUT		:= DB42.DTVAR3,
		INTOUT		:= MW 2,
		DTINOUT		:= DB42.DTVAR4,
		INTINOUT	:= MW 4,
	)
	// Check modified DTINOUT (DB42.DTVAR4)
	AUF		DB 42
	L		DBD 30
	__ASSERT==	__ACCU 1,	DW#16#12131415
	L		DBD 34
	__ASSERT==	__ACCU 1,	DW#16#16171819



	// Check explicit DB-pointer parameters
	CALL		FC 50 (
		FCPTR1		:= P#DB50.DBX 10.0,
		FCPTR2		:= DB50.DBX 10.1,
		FCPTR3		:= P#M 99.7,
		FCPTR4		:= M 99.7,
		FCPTR5		:= P#7.1,
		FCPTR6		:= DB1.DBVAR2[2].V2,
		FCPTR7		:= #TMPDUMMY,
		FCOUTPTR1	:= M 98.7,
		RET_VAL		:= A 97.6,
	)
	CALL		FB 50, DB 50 (
		FBPTR1		:= P#DB50.DBX 10.0,
		FBPTR2		:= DB50.DBX 10.1,
		FBPTR3		:= P#M 99.7,
		FBPTR4		:= M 99.7,
		FBPTR5		:= P#7.1,
		FBPTR6		:= DB1.DBVAR2[2].V2,
		FBPTR7		:= #TMPDUMMY,
	)


	// Pass DATE_AND_TIME immediate passing to FC and FB parameters.
	// This is an awlsim extension.
	CALL		FC 60 (
		FC_DTIMM_0	:= DT#1998-02-03-16:17:20.211,
	)
	CALL		FB 60, DB 60 (
		FB_DTIMM_0	:= DT#1998-02-03-16:17:20.211,
	)


	// Check fully qualified DB variable pointer.
	// This is an awlsim extension.
	L		P#DB42.DTVAR1
	__ASSERT==	__ACCU 1,	P#DBX 4.0
	L		P#"Data".DTVAR1
	__ASSERT==	__ACCU 1,	P#DBX 4.0
	L		P#DB42.ARR1[1].V1
	__ASSERT==	__ACCU 1,	P#DBX 38.0
	L		P#DB42.ARR1[2].V2
	__ASSERT==	__ACCU 1,	P#DBX 44.0
	CALL		FC 70 (
		FCP1	:= P#DB42.ARR1[1].V1,
	)
	CALL		"FC70_sym" (
		FCP1	:= P#DB42.ARR1[1].V1,
	)
	CALL		FB 70, DB 70 (
		FBP1	:= P#DB42.ARR1[1].V1,
	)


	CALL SFC 46 // STOP CPU
END_ORGANIZATION_BLOCK


DATA_BLOCK DB 1
	STRUCT
		DBVAR1		: INT;
		DBVAR2		: ARRAY[1 .. 6] of STRUCT
			V1	: INT;
			V2	: INT;
		END_STRUCT;
		DBVAR3		: INT;
	END_STRUCT
BEGIN
END_DATA_BLOCK


FUNCTION_BLOCK FB 20
	VAR_INPUT
		DTIN		: DATE_AND_TIME;
		INTIN		: INT;
	END_VAR
	VAR_OUTPUT
		DTOUT		: DATE_AND_TIME;
		INTOUT		: INT;
	END_VAR
	VAR_IN_OUT
		DTINOUT		: DATE_AND_TIME;
		INTINOUT	: INT;
	END_VAR
	VAR
		DTSTAT		: DATE_AND_TIME;
		INTSTAT		: INT;
	END_VAR
	VAR_TEMP
		DBNR		: INT;
	END_VAR
BEGIN
	// Check all variable addresses
	L		P##DTIN
	__ASSERT==	__ACCU 1,	P#DIX 0.0
	L		P##INTIN
	__ASSERT==	__ACCU 1,	P#DIX 8.0
	L		P##DTOUT
	__ASSERT==	__ACCU 1,	P#DIX 10.0
	L		P##INTOUT
	__ASSERT==	__ACCU 1,	P#DIX 18.0
	L		P##DTINOUT	// 6 byte DB-ptr
	__ASSERT==	__ACCU 1,	P#DIX 20.0
	L		P##INTINOUT
	__ASSERT==	__ACCU 1,	P#DIX 26.0
	L		P##DTSTAT
	__ASSERT==	__ACCU 1,	P#DIX 28.0
	L		P##INTSTAT
	__ASSERT==	__ACCU 1,	P#DIX 36.0

	// Check DTINOUT data (via DB ptr)
	L		P##DTINOUT
	LAR1
	L		W [AR1, P#0.0]	// Get DB-nr from DB-ptr
	T		#DBNR
	__ASSERT==	__ACCU 1,	42
	AUF		DB [#DBNR]
	L		D [AR1, P#2.0]	// Get address from DB-ptr
	LAR1
	__ASSERT==	__ACCU 1,	P#DBX 30.0

	L		D [AR1, P#0.0]	// Get DTINOUT data
	__ASSERT==	__ACCU 1,	DW#16#11223344
	L		D [AR1, P#4.0]	// Get DTINOUT data
	__ASSERT==	__ACCU 1,	DW#16#55667788

	// Modify DTINOUT data (via DB ptr)
	L		DW#16#12131415
	T		D [AR1, P#0.0]	// Write DTINOUT data
	L		DW#16#16171819
	T		D [AR1, P#4.0]	// Write DTINOUT data
END_FUNCTION_BLOCK


DATA_BLOCK DB 20
	FB 20
BEGIN
END_DATA_BLOCK


FUNCTION FC 1 : VOID
	VAR_INPUT
		DTTEMP		: DATE_AND_TIME;
		DTDB		: DATE_AND_TIME;
	END_VAR
	VAR_TEMP
		DBNR		: INT;
	END_VAR
BEGIN
	// Load #DTTEMP into AR1
	L		P##DTTEMP
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	// Check the DB-pointer pointed to by #DTTEMP
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0 // DB-nr
	T		#DBNR
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	DW#16#87000010
	LAR2
	AUF		DB [#DBNR]
	// Check the actual values
	L		D [AR2, P#0.0]
	__ASSERT==	__ACCU 1,	DW#16#12345678
	L		D [AR2, P#4.0]
	__ASSERT==	__ACCU 1,	DW#16#AABBCCDD


	// Load #DTDB into AR1
	L		P##DTDB
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	// Check the DB-pointer pointed to by #DTDB
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	42 // DB-nr
	T		#DBNR
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	DW#16#84000020
	LAR2
	AUF		DB [#DBNR]
	// Check the actual values
	L		D [AR2, P#0.0]
	__ASSERT==	__ACCU 1,	DW#16#87654321
	L		D [AR2, P#4.0]
	__ASSERT==	__ACCU 1,	DW#16#DDCCBBAA
END_FUNCTION


FUNCTION_BLOCK FB 10
	VAR_INPUT
		DUMMYIN		: INT;
		DTVAR		: DATE_AND_TIME;
	END_VAR
BEGIN
	CALL FC 11 (
		DTIN	:= #DTVAR,
	)
END_FUNCTION_BLOCK


FUNCTION FC 11 : VOID
	VAR_INPUT
		DTIN		: DATE_AND_TIME;
	END_VAR
	VAR_TEMP
		DBNR		: INT;
	END_VAR
BEGIN
	// Load #DTDB into AR1
	L		P##DTIN
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	// Check the DB-pointer pointed to by #DTIN
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	10 // DB-nr
	T		#DBNR
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	DW#16#84000010
	LAR2
	AUF		DB [#DBNR]
	// Check the actual values
	L		D [AR2, P#0.0]
	__ASSERT==	__ACCU 1,	DW#16#87654321
	L		D [AR2, P#4.0]
	__ASSERT==	__ACCU 1,	DW#16#DDCCBBAA
END_FUNCTION


DATA_BLOCK DB 10
	FB 10
BEGIN
END_DATA_BLOCK


DATA_BLOCK DB 42
	STRUCT
		DUMMY1		: INT;			// DBX 0.0
		DUMMY2		: INT;			// DBX 2.0
		DTVAR1		: DATE_AND_TIME;	// DBX 4.0
		DUMMY3		: INT;			// DBX 12.0
		DTVAR2		: DATE_AND_TIME;	// DBX 14.0
		DTVAR3		: DATE_AND_TIME;	// DBX 22.0
		DTVAR4		: DATE_AND_TIME;	// DBX 30.0
		ARR1		: ARRAY [1 .. 2] OF STRUCT
			V1	: INT;			// DBX 38.0 / 42.0
			V2	: INT;			// DBX 40.0 / 44.0
		END_STRUCT;
	END_STRUCT;
BEGIN
END_DATA_BLOCK


FUNCTION FC 50 : POINTER
	VAR_INPUT
		FCPTR1		: POINTER;
		FCPTR2		: POINTER;
		FCPTR3		: POINTER;
		FCPTR4		: POINTER;
		FCPTR5		: POINTER;
		FCPTR6		: POINTER;
		FCPTR7		: POINTER;
	END_VAR
	VAR_OUTPUT
		FCOUTPTR1	: POINTER;
	END_VAR
BEGIN
	L		P##FCPTR1
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	50
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 10.0

	L		P##FCPTR2
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	50
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 10.1

	L		P##FCPTR3
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#M 99.7

	L		P##FCPTR4
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#M 99.7

	L		P##FCPTR5
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#7.1

	L		P##FCPTR6
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	1
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 8.0

	L		P##FCPTR7
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000



	L		P##FCOUTPTR1
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#M 98.7



	L		P##RET_VAL
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#A 97.6
END_FUNCTION


FUNCTION_BLOCK FB 50
	VAR_INPUT
		FBPTR1		: POINTER;
		FBPTR2		: POINTER;
		FBPTR3		: POINTER;
		FBPTR4		: POINTER;
		FBPTR5		: POINTER;
		FBPTR6		: POINTER;
		FBPTR7		: POINTER;
	END_VAR
BEGIN
	L		P##FBPTR1
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	50
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 10.0

	L		P##FBPTR2
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	50
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 10.1

	L		P##FBPTR3
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#M 99.7

	L		P##FBPTR4
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#M 99.7

	L		P##FBPTR5
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#7.1

	L		P##FBPTR6
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	1
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 8.0

	L		P##FBPTR7
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0
	L		D [AR1, P#2.0]
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
END_FUNCTION_BLOCK


DATA_BLOCK DB 50
	FB 50
BEGIN
END_DATA_BLOCK


FUNCTION FC 60 : VOID
	VAR_INPUT
		FC_DTIMM_0	: DATE_AND_TIME;
	END_VAR
BEGIN
	// Load #FC_DTIMM_0 into AR1
	L		P##FC_DTIMM_0
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	// Check the DB-pointer pointed to by #FC_DTIMM_0
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	0 // DB-nr
	L		D [AR1, P#2.0]
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	// Check the actual values
	L		D [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	DW#16#98020316
	L		D [AR1, P#4.0]
	__ASSERT==	__ACCU 1,	DW#16#17202113
END_FUNCTION


FUNCTION_BLOCK FB 60
	VAR_INPUT
		FB_DTIMM_0	: DATE_AND_TIME;
	END_VAR
BEGIN
	// Load #FB_DTIMM_0 into AR1
	L		P##FB_DTIMM_0
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#85000000
	// Check the actual values
	L		D [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	DW#16#98020316
	L		D [AR1, P#4.0]
	__ASSERT==	__ACCU 1,	DW#16#17202113
END_FUNCTION_BLOCK


DATA_BLOCK DB 60
	FB 60
BEGIN
END_DATA_BLOCK


FUNCTION FC 70 : VOID
	VAR_INPUT
		FCP1	: POINTER;
	END_VAR
BEGIN
	// Load #FCP1 into AR1
	L		P##FCP1
	LAR1
	UD		DW#16#FF000000
	__ASSERT==	__ACCU 1,	DW#16#87000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	42 // DB-nr
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 38.0
END_FUNCTION


FUNCTION_BLOCK FB 70
	VAR_INPUT
		FBP1	: POINTER;
	END_VAR
BEGIN
	// Load #FBP1 into AR1
	L		P##FBP1
	LAR1
	__ASSERT==	__ACCU 1,	DW#16#85000000
	L		W [AR1, P#0.0]
	__ASSERT==	__ACCU 1,	42 // DB-nr
	L		D [AR1, P#2.0]
	__ASSERT==	__ACCU 1,	P#DBX 38.0
END_FUNCTION_BLOCK


DATA_BLOCK DB 70
	FB 70
BEGIN
END_DATA_BLOCK
