;Simple ModBus demonstration

;This is a companion to the VB6 demo program BasicModBus.VB6
;Stuff in the SPLat is reflected in the PC and visa versa.
;It works in an MMiXXX with ModBus slave mode (Dialect 17 or later).
;It can be used as a basis for programs in other controllers with ModBus slave.

***** CAUTION *******
;When a SPLat switches to ModBus it cannot connect to SPLat/PC.
;The board will not switch in the first 10S after turn-on,
;so to get controll of it from SPLat/PC power up then quickly hit the
;connect button.

;-----------------------------------------
;Absolute RAM locations for ModBus

;Transfers are done in words, so allocation must be in pairs of bytes.
;I will do all transfers via RAM using functions 3 (read) and 16 (write).
;The first bunch of 16 bytes is for inputs. The second is for outputs.
;They are not all used in this demo

mbTxData	mEQU		200,16	; SPLat-> PC 	Modicon ref 40201, Hi byte
mbRxData	mEQU		216,16	; PC -< SPLat 	Modicon ref 40217, Hi byte

;The Hi byte is the first of the pair transmitted (furthest left in Visual Basic strings).
;This means that when data is packed in binary into a VB string,
;it will map to SPLat RAM bytes in the same sequence. 
;Left to right in VB = Lowest to highest address in SPLat.

;Bus addresses (addresses in ModBus messages) are identical to the 
;SPLat RAM address for the start of each block.

;Once ModBus has been invoked in a board, the only way to connect SPLat/PC to that board is
;within 10s of the board being powered up. The following splash screen is a reminder.

SPLashCount	defBYTE

		SetMem		SPLashCount,10
				;0123456789012345
		OBLCD_Text	" 10S to connect"
		OBLCD_SetCur	1,0
		OBLCD_Text	"to SPLat/PC"		
Splash1:
		OBLCD_SetCur	0,0
		OBLCD_UDecDispMFW	SPLashCount
		Pause		100
		DMGNZ		SPLashCount,Splash1


;Get ModBus going...
		COMSetCCB	ModBusCCB
		OBLCD_Cls

;Get tasks going
		LaunchTask		TransferIO
		LaunchTask		DumbDemoCounter
		RunTasksForever

;----------------------------------------------
;This task transfers RAM<==>Other stuff
;The RAM usage is:

;Stuff written from the PC:
;	Addr		Used for
;	216		Lower 7 bits to FP LEDs.
;	217		Select message to be displayed on top line of LCD

;Stuff sent to PC

;	Addr		Used for
;	200		Front panel push buttons
;	201		Count button presses (i/p 12, top button)

TransferIO:
		YieldTask

		GoSub		SetBusAddr
		Recall		216
		LoadX		'7F		'Select 7 bits
		OutputM		9		;FP LEDs

		InputFM		8
		LoadX		'1F		;Mask 5 bits
		AndM
		Store		200

		GoIfMGT		217,3,TransferIO	;Protect against bad message number
		OBLCD_SetCur	0,0
		BranchM		217			;Test message number
		Target		Msg0
		Target		Msg1
		Target		Msg2
		Target		Msg3

Msg0:				;0123456789012345
		OBLCD_Text	"Hello world     "
		GoTo		TransferIO
Msg1:				;0123456789012345
		OBLCD_Text	"SPLat is great! "
		GoTo		TransferIO
Msg2:				;0123456789012345
		OBLCD_Text	"ModBus is handy "
		GoTo		TransferIO
Msg3:				;0123456789012345
		OBLCD_Text	"Let's go fishin'"
		GoTo		TransferIO



		GoTo		TransferIO

;Sett the bus address from the MMI option jumpers (inputs 13, 14)
;Note: This is just to illustrate a point. The jumpers are not usable if 
;you are using a SPice board.
SetBusAddr:
		InputFM		13
		LoadX		3
		AndM
		IncX
		Push
		COMDevAddr
		oblcd_SetCur		1,0
		oblcd_Text		"Addr:"
		oblcd_hexdispx
		Return

;--------------------------------------
;Taks to coungt button presses just for someting to do
DumbDemoCounter:
		WaitOnK		12
		incM			201
		OBLCD_SetCur	1,8
		OBLCD_UDecDispMFW	201
		GoTo			DumbDemoCounter

************************************************************************

               NVEM0           ;
ModBusCCB:
                NV0Byte         1       ;Protocol
                NV0Byte         1       ;Bus Address
                NV0Byte         0       ;Character = 8,1,N
                NV0Byte         7       ;38400
                NV0Byte         1       ;Half duplex, echo suppression
                NV0Byte         0       ;Flags: No RTC writes
                NV0Byte         255     ;RTS: use dedicated line
                NV0Byte         10      ;RTSDelay = 10mS
                NV0Byte         0       ;RTSLeadOut
                NV0Byte         10      ;Message gap 100mS
                NV0Byte         100     ;Query timeout 1S
                NV0Byte         3       ;Query attempts
                NV0Byte         0,250   ;ModBus writable RAM
                NV0Byte         255,0   ;Prevent output writes
                NV0Byte         #65535,#0 ;Prevent NVEM0 writes