        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.27.5
        ============================================================

    1)  Zero a variable that could conceivably cause an error.
    2)  Compatibility with newest unreleased ShowMan.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.27.4
        ============================================================

    1)  Clean up message box formatting.
    2)  Clean up HEI repolling.
    3)  Add debug messages.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.27.3
        ============================================================

    1)  Clean up string formatting routine.
    2)  When saving port information it now clears everything out first.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.27.2
        ============================================================

    1)  Clean up a machine lockup on XP machine boot.
    2)  Clean up a crash in control panel.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.26.1
        ============================================================

    1) Clean up some logic that was too custom for my particular
       network topology.
    2) Clean up duplicate devices found when running two networks
       through one switch. (This is NOT a recommended network
       configuration except when using carefully setup managed
       switches.)

        MIDI_AutomationDirect2_IO Release Notes For Version 1.1.26.0
        ============================================================

    1) Windows 7 compatability.
    2) Self installing.
    3) Works with multiple NICs - picks IP address that returns the
       most responses.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.20.2
        ============================================================

	1) Minor fix to repair a technical problem with memory allocations.
	   This MIGHT make a change to behavior with ShowMan.

	2) Change to make multiple runs via Simple Config work properly.
 
        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.20.1
		============================================================

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.20.0
		============================================================

	1) Troubles again with XP SP2. Every program on the system opens the
	   MIDI drivers. This makes them slow to start. So we added some keys
	   to speed up the program startup process.

	2) IPConfig, a network utility for Windows, would fail to run. This
	   was traced to the above problem compounded by IPConfig trying to
	   set an alternate username and bollixing it up such that the
	   standard Windows function "GetUserName()" would crash. We used
	   GetUsername() to find safe times to allow the DLL to really run.

	   Now the DLL will really run only for processes enumerated in
	   one of two places. The first is a new registry key named
	   "MyOneTrueName". If that is not set or is set to an empty
	   string any program can run the DLL. Otherwise only the program
	   listed in the string or in the next set of strings may use the
	   DLL. The second new registry key is "MyTrueNamesN". The N is
	   any number or character desired. We suggest "0 to 9" for mnemonic
	   reasons. Only 10 names are allowed with no wild cards. If a
	   program by one of those ten names or MyOneTrueName opens the DLL
	   then it can run normally. No other programs may run the DLL.
	   This is simply to keep it from taking too long when loading
	   programs like NotePad that never use it. It's not any form of
	   license key issue.

	3) There were some problems on dual processor or hyperthreaded
	   machines wherein both processors were trying to access the
	   same data at the same time. This has been fixed.

	4) This is the full list of user set registry keys. These are
	   set by RegEdit.exe (start->run enter RegEdit) as follows.

The master key name is:
HKLM\Software\Showman\MIDI_AUTOMATIONDIRECT2_IO\<keyvalue>

There should be the "PreRead" key there already.

"UseBroadcastAtMyOwnRisk" is another "interesting" key. It potentially
disrupts networks that use hubs rather than switches. It uses an
alternative addressing mode for talking to the bases.

"PrintDebugInfo" set to 0 (my error in prior email message) turns off
debug messages. (They take relatively little time compared to the
repeated waits for polling responses within the HEI code.) Values up
to about 4 produce progressively more debug information.

"MediamationKludge" set to 1 to use note on and note off messages to
control individual coils. (This can result in MASSIVE network traffic
if there are a lot of coil changes happening at about the same time.)

"MediamationRepoll" set to 0 turns off the extra "wake the suckers up"
repolls.

"mediamationInitHEI" set to 1 will move the time the "InitHEI" (polling
code) is called. This is the one that might turn the polling off entirely
when things like ping or notepad are run.

"ThreadPriority" sets to values from 0 to 4:
      0: THREAD_PRIORITY_LOWEST
      1: THREAD_PRIORITY_BELOW_NORMAL
      2: THREAD_PRIORITY_NORMAL (This is default)
      3: THREAD_PRIORITY_ABOVE_NORMAL
      4: THREAD_PRIORITY_TIME_CRITICAL

"MyOneTrueName" is a REG_SZ with the name of the ONE program in the
system that will be allowed to actually run the driver. (The manager
will still be able to configure it.) If the value is set to "*", a null
string, or is not in the registry any program can be run. Delays will
exist. But, unlike before, IPConfig will not fail or crash.

"MyTrueNames0" through "MyTruenames9" are ten more names that are allowed
to open the DLL and operate it properly. This gives a total of 11 names
that will run DLLs properly.

That's all of the manual set key values.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.19.1
		============================================================

	1) For reasons only known to the odd gods of programming a bug in
	   the port initialization code picked now to show itself. The
	   base definition read from a base was getting overwritten with
	   a "non-slot" indication for all output points on the bases that
	   were opened. This be fixed now. This may be because of an
	   optimization that the prior fix "created".

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.19.0
		============================================================

	1) The Microsoft Wizards for reasons only to themselves killed
	   networking on XP Service Pack 2 during the boot process. They
	   killed it in such a way as to prevent the machine from booting.
	   (So now I know a wonderful way to kill an XP machine for poor
	   unsuspecting souls.) I had to develop a clever hack to wait
	   until the system was completely booted and the user is properly
	   logged on before I allow the networking interface to work.
	   I wonder what the Wizards of Redmond were thinking of at the
	   time.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.18
		============================================================

    1) Massive changes to protect itself against someone trying to read
       and write too quickly.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.17
		============================================================

    1) If an Automation Direct PLC dies and this DLL is restarted it could
    end up addressing a Device at index -1 causing a driver crash in this
    driver. This is now trapped.
    2) Cosmetic changes to the configuration help panel.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.16
		============================================================

    1) Another technical problem with HEI code.
    2) Change a debug print which was causing strange crashes and put
    protection around it. Note that there is a special key for outputting
    debug information even with the release builds.
    3) Change Help/About text.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.15
		============================================================

    There are two new elements in this version. First a potentially serious
    error was discovered in the HEI code. A variable was used after it was
    out of scope and potentially no longer valid. (The liklihood of this
    error being a problem is small.)
    
    The second new element is a test to see if there is an error reading
    each of the bases. The existing tests were not rigorous enough to catch
    a misaddressed base. The new test should discover it and post data that
    should help rectify the error in a message box. If such an error pops
    up it's ever so highly recommended it be fixed.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.14
		============================================================

    A broken base module prompted adding some status reporting and an option
    to attempt to continue in spite of the error. Enough information is provided
    that, one hopes, the Automation Direct people can decode the error. The
    unfortunate aspect of it is that someone needs to manually transcribe the
    error message from the requester. Another unfortunate side effect is that
    the error message appears whenever ANY program opens. This is a "Microsoft
    thing".

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.12
		============================================================

    Added three registry flags: UseBroadcastAtMyOwnRisk, SpecialTimeoutValue,
    and PrintDebugInfo. These must be manually set for debugging. defaults:
    UseBroadcastAtMyOwnRisk = 0  (false)
    SpecialTimeoutValue = 50  (ms)
    PrintDebugInfo = 0  ( no debuginfo., 1 moderate debug, 2 full debug.)

    Use the UseBroadcastAtMyOwnRisk only on guaranteed isolated networks or on
    non-routing networks. Otherwise the broadcast packets will leak out to the
    internet as a whole. If the network uses switches this will increase unwanted
    network traffic on nodes not interested in these packets.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.11
		============================================================

    1) Add some additional malformed MIDI command error checking.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.10
		============================================================

    1) Small change to the ECOM module support. A variable was uninitialized
       and could have theoretically caused a problem.
    2) Build in some additional debugging for Dan. Initialize with exactly
       the same command stream as NetEdit.
    3) Found a Get Device Capabilities problem with XP and repaired it.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.9
		============================================================

    1) Help/About box changes.
    2) Windows XP fix.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.8
		============================================================

    More special Mediamation kludge capability. Please don't ask.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.7
		============================================================

    More special Mediamation kludge capability. Please don't ask.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.6
		============================================================

    Special Mediamation kludge capability. Please don't ask.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.5
		============================================================

    1) With multiple bases present only the last one found and
polled for its description was properly remembered. This is fixed.
Now writing to multiple bases works.
    2) It seems this DLL forgot how to delete its  obsolete registry
entries. So deleting a port didn't work. Now it does.
    3) While looking for the above errors a possible other obscure
problem with debug versions was cured.
    4) Preread was a little too global in effect. It's fangs have
been pulled.
    5) In debugging MIDI_AutomationDirect2_IO for 1.0.18.2 mts232 serial
support was removed and not put back. It is present now. (This is still send
only support.)

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.4
		============================================================

    Interim build to reduce priority of the HEI buzz loop for a customer
experiencing near lockups.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.3
		============================================================

    Now correctly writes to multiple points on more than one slot
on a version 2 base.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.2
		============================================================

    Now correctly writes to slots more than 8 bits wide.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.1
		============================================================

    Changed behavior of Review copies.

        MIDI_AutomationDirect2_IO Release Notes For Version 1.0.18.0
		============================================================

1) Initial release for rev 2 of the full version of the
   Automation Direct HEI interface.

    Description
    ===========

    This is a commericial licenseable release for the MIDI_AutomationDirect_IO
type 2. It incorporates support exipry warnings and notices and tests for 
Midi Automation Direct being licensed. If it is not licensed or the demo flag
is set Midi Automation Direct will cease functioning after a half hour. The
device will then have to be closed and reopened before it can be used for an
additional half hour. If the Review flag is set the Review copy turns into a
demo mode copy and must be reset every 30 minutes.

    A single file supports both Safe Mode IO and Full Mode IO off separate
keys. If both keys are present this version comes up in Safe Mode.

USAGE NOTES:

  * The EBC, Ethernet Base Controller, serial IO is a cut rate set of the
    Richmond Sound Design MTS-232 hardware MSC command set.

    * Flow control does not exist.
    * Only 7 or 8 bits per character are allowed.
    * Only 1 or 2 stop bits are allowed.
    * Only none, even, abd odd parity settings are allowed.
    * Data Rates allowed:
      300
      600
      1200
      2400
      4800
      9600
      14400
      19200
      38400

  * Both the EBC and ECOM communicate via an MSC wrapper around a standard
    MODBUS protocol message. Only a minimal subset of the MODBUS messages
    are supported. At the moment only write commands function. You can write
    to a single point or to all points in the base addressed. And the ECOM
    modules are not supported in this release.

    Supported MODBUS Commands For EBC modules
        1   Read Coil Status (Read Output Bits)
        2   Read Input Status (Read Input Bits)
        5   Force Single Coil (Force Single Bit)
        15  Force Multiple Coils (Force a sequence of bits)

    Supported MODBUS Commands for ECOM modules
        1   Read Coil Status (Read Output Bits)
        2   Read Input Status (Read Input Bits)
        3   Read Holding Registers
        4   Read Input Registers
        5   Force Single Coil (Force Single Bit)
        6   Preset Single Register
        15  Force Multiple Coils (Force a sequence of bits)
        16  Preset Multiple Registers

    The read commands are supported only on units set to "read/write". Within
    ShowMan you can set the default show input to the same MIDI port as one
    of the MIDI_AutomationDirect_IO ports used for writing to an EBC
    controller. Then when a read command is "written" to the controller the
    capture buffer will be able to observe the results. This can be used for
    logging a show. Someday it will have other uses.

=== MIDI ModBus Command Descriptions ===

            Modified Modbus/TCP protocol over MIDI Sysex

Base message framing is an RSD Sysex very similar to an MTS-232 message.
Within the payload of this framing is a Modbus/TCP message in mostly Ascii
representation.  The ascii representation is used to get around the
inherent 7-bit problem of midi.  To save some space on Modbus/TCP message
overhead, the lead bytes are represented as 7-bit versions of the actual
8-bit values.  This isn't expected to cause any problems.

Only a subset of the Modbus messages are implemented.  This subset does
NOT correspond to any of the reccomended sets in the Modbus/TCP document!

MTS-232 message format (general, 'data' type message):

        F0  00 00 40  00  dd  ss  (7x 7x 7x  7x) F7
         0   1  2  3   4   5   6    7  8  9  10  11

        00 00 40    = RSD manuf ID
        00          = MTS-232 device class
        dd          = MTS-232 box address, 00..127 (set with jumpers)
        ss          = setup byte
        7x          = optional data nibbles, which must be in pairs

We use the format up through byte 5, then begin with the Modbus/TCP header:

        xx  xx  pp  pp  ll  ll  id  message

        xx xx       = transaction id, usually 00 00
        pp pp       = protocol identifier, always 00 00
        ll ll       = length in bytes of following data, <= 256
        id          = device identifier

Some parts of the standard Modbus/TCP header above are useless, since the
data already exists in another part of the message or is useless.  We will
therefore preform a perversion/translation on the header by deleting the
protocol identifier and using the "dd" device number from the MTS-232 header
in place of the "id" byte.  We will also drop the length, since the message
length will be obvious from the message code, and can be checked against the
F7 terminator.

==============================================================================
==============================================================================

This gives us a combined fixed header of:

        F0 00 00 40 04 dd rr tt tt message  F7
         0  1  2  3  4  5  6  7  8 9

        F0          = Sysex start
        00 00 40    = RSD Manuf Id.
        04          = Modbus Command device class
        dd          = Modbus PLC box address, 0..127
        rr          = Sender's ID, will be used in Response messages
        tt tt       = arbitrary transaction id echoed to response message

Once past this header we have a standard Modbus-Ascii message representation.
The Ascii representation is simply to take the two hex digits of each byte
and represent them in 0..F hex ascii characters.  (The spec doesn't indicate
if we should use upper or lower case A..F, so we will use upper.)

Message formats are dependent on opcode.  However, in general the opcode is
one byte, addresses are 2 bytes (16 bits), and data is in either 8 or 16 bit
framing units.  In 16 bit units, the data is represented in big-endian form.
In 8 bit units, the data is essentially little-endian if more than 8 bits
are represented.

==============================================================================
==============================================================================

Modbus responses are identical to Modbus commands, except for the device
class byte:

        F0 00 00 40 05 dd rr tt tt message  F7
         0  1  2  3  4  5  6  7  8 9

        F0          = Sysex start
        00 00 40    = RSD Manuf Id.
        05          = Modbus Response device class
        dd          = Command sender's ID
        rr          = Sending Modbus PLC box address, 0..127
        tt tt       = arbitrary transaction id echoed from command message

Once past this header we have a standard Modbus-Ascii message representation.
The Ascii representation is simply to take the two hex digits of each byte
and represent them in 0..F hex ascii characters.  (The spec doesn't indicate
if we should use upper or lower case A..F, so we will use upper.)

Message formats are dependent on opcode.  However, in general the opcode is
one byte, addresses are 2 bytes (16 bits), and data is in either 8 or 16 bit
framing units.  In 16 bit units, the data is represented in big-endian form.
In 8 bit units, the data is essentially little-endian if more than 8 bits
are represented.

==============================================================================
==============================================================================

Supported Modbus Opcodes:

        01      Read Coil Status
                Reads zero-relative bit array of output latches.

        02      Read Input Status
                Reads zero-relative bit array of input values.

        03      Read Holding Registers
                Reads array of V-memory holding registers.
                The input and output bit arrays are mapped into this space
                somewhere, so the inputs and outputs can be read in 16 bit
                words.  We need to define the shape of this mapping.

        04      Read Input Registers
                Reads zero-relative array of 16 bit words overlaying the
                input bit array accessed by function 02.

        05      Force Single Coil
                Sets a single bit in the zero-relative output bit array.

        06      Preset Single Register
                Sets a 16 bit quantity in mapped V-memory.
                We need to define the mapping.

        0F      Force Multiple Coils
                Set an array of bits in the zero-relative output bit array.

        10      Preset Multiple Registers
                Set an array of 16 bit quantities in V memory.
                We need to define the mapping of ins and outs to this space.


==============================================================================
==============================================================================

Command details:

    Read Coil Status

        Request:

            01  aaaa llll

            Read one or more output register bits.  The LOWEST numbered
            output bit is aaaa.  The number of bits is llll.  Both numbers
            are BIG-endian.  The maximum length is 2000 bits.

            A read that begins in a valid range and extends past the last valid
            coil will return zeros for the nonexistant coils.

            A read that starts past the last valid coil will return an error.

        Response:

            01 ll dd....

            ll = byte length of dd... in HEX DIGITS.  Multiply this by 2 for
            the actual returned Ascii section data length.

            dd  = returned coil data.  The lowest numbered coil is in bit 0x01
            of the first byte,  Coil 8 is bit 0x01 of the second byte, etc.

        If an error occurs no response is returned, instead there was an
        MMRESULT error code on the write of the request data.  The response
        is of course returned on the midi read port for the device.


    Read Input Status

        Request:

            02  aaaa llll

            Read one or more input register bits.  The LOWEST numbered
            input bit is aaaa.  The number of bits is llll.  Both numbers
            are BIG-endian.  The maximum length is 2000 bits.

            A read that begins in a valid range and extends past the last valid
            input will return zeros for the nonexistant coils.

            A read that starts past the last valid input will return an error.

        Response:

            02 ll dd....

            ll = byte length of dd... in HEX DIGITS.  Multiply this by 2 for
            the actual returned Ascii section data length.

            dd  = returned input data.  The lowest numbered input is in bit 
            0x01 of the first byte,  Coil 8 is bit 0x01 of the second byte, etc.

        If an error occurs no response is returned, instead there was an
        MMRESULT error code on the write of the request data.  The response
        is of course returned on the midi read port for the device.


    Read Holding Registers

        Request:

            03  aaaa llll

            Read one or more 16-bit quantities from V-memory.  V-memory
            includes both the input and output areas as well as any other
            ram-like functions that might be present in the device.

            In general each input or output module is mapped to a single
            16-bit word.  If the module has more than 16 points it is mapped
            to multiple contiguous words.  Modules containing both input and
            output will be mapped disjointly into the input and output areas
            of V-memory.

        Response:

            03 ll dddd...

            ll = byte length of dddd.... in HEX DIGITS.  Multiply this by 2 for
            the actual returned Ascii section data length.

            dddd = returned data as 16 bit BIG ENDIAN value for first (lowest
            addressed) item, followed by dddd items for sequentially higher
            addresses.

        If an error occurs no response is returned, instead there was an
        MMRESULT error code on the write of the request data.  The response
        is of course returned on the midi read port for the device.


    Read Input Registers

        Same format and semantics as Read Holding Registers, except that the
        data is limited to the input values and they start at relative
        address zero in the request.


    Read Input Registers

        Same format and semantics as Read Holding Registers, except that the
        data is limited to the input values and they start at relative
        address zero in the request.

         Request:

            04  aaaa llll

            Read one or more 16-bit quantities from input memory.

            In general each input or output module is mapped to a single
            16-bit word.  If the module has more than 16 points it is mapped
            to multiple contiguous words.  Modules containing both input and
            output will be mapped disjointly into the input and output areas.

        Response:

            03 ll dddd...

            ll = byte length of dddd.... in HEX DIGITS.  Multiply this by 2 for
            the actual returned Ascii section data length.

            dddd = returned data as 16 bit BIG ENDIAN value for first (lowest
            addressed) item, followed by dddd items for sequentially higher
            addresses.

        If an error occurs no response is returned, instead there was an
        MMRESULT error code on the write of the request data.  The response
        is of course returned on the midi read port for the device.


    Force Single Coil

        Request:

            05  aaaa vv 00

            Set the single output bit indexed (from zero) by aaaa to the
            value in vv.  If vv == FF the bit is turned on, else if vv == 00
            the bit is turned off.  Any other value is an error and rejected.

        Response:

            Other than the MMSTATUS value there is no response.


    Preset Single Register

        Request:

            06  aaaa dddd

            Using V-memory mapping stuff the 16 bit value dddd into the word
            at address aaaa.  If the word is really smaller than 16 bits some
            high-order bits could be lost.

        Response:

            Other than the MMSTATUS value there is no response.


    Force Multiple Coils

        Request:

            0F aaaa cccc ll dd....

            Set an array of output bits starting at the LOWEST numbered bit
            aaaa.  The number of bits to set is in cccc, big endian.  The
            length of the data byes in HEX BYTES is ll.  Multiply this by 2 for
            the actual returned Ascii section data length.  The actual data
            values are in the dd... bytes following.

            The first 8 or fewer coils are represented in the first dd byte.
            The lowest numbered coil is in bit 0x01.  If fewer than 8 coils
            are being set, the high-order bits are ignored and should be zero.
            If more than 8 coils are being set, the next 8 are in the following
            byte, and so on.

        Response:

            Other than the MMSTATUS value there is no response.


    Preset Multiple Registers

        Request:

            10 aaaa cccc ll dddd....

            Set an array of V-memory words beginning at the LOWEST numbered
            word aaaa.  The number of words to be set is cccc, max = 100.

            ll = the length of the data in HEX BYTES.  This should be twice
            the cccc value.  Multiply this by 2 to get the number of Ascii
            bytes.

            dddd = the first word of data in BIG ENDIAN format.

        Response:

            Other than the MMSTATUS value there is no response.


==============================================================================
==============================================================================
            Special EBC information

    Note that the ECOM module addressing for the local BASE relays starts at
a bit address of 2048. The EBC addressing has been modified so as to match
that for the ECOM modules as described below in the Special ECOM Information
section.


==============================================================================
==============================================================================
            Special ECOM Information

    Memory types accessible via Modbus commands of various types.

        Inputs  (Modbus 1x, CCM 32)
    ========================================
    GX      Global I/O (Inputs)
    X       Inputs
    SP      Special Purpose Relays (flags)

        Outputs (Modbus 0x, CCM 33)
    ========================================
    GY      Global I/O (Outputs)
    Y       Outputs
    C       Control Relays
    S       Stage Status Bits
    T       Timer Status Bits
    CT      Counter Status Bits

        Timer-Counter values (Modbus 3x, CCM 31)
    ========================================
    TV      Timer Current Values
    CV      Counter Current Values

        Data Memory (Modbus 4x, CCM 31)
    ========================================
    V       V Memory

        Special Memory
    ========================================
    L       Ladder Program
    Z       Scratchpad RAM


There does not appear to be a way to get to analog data except the read
multiple and write multiple commands.

The Output area (0x) also has a number of special-purpose latches such as
control relays, timer and counter status bits, and stage bits.  These
exist at higher offsets than the normal I/O pins.

V-memory can hold constants, or for some I/O modules it will also hold
auxilliary I/O data.


==============================================================================
==============================================================================
              Mapping PLC vs "CCM" command set vs Modbus Command

             PLC                      CCM                    Modbus
=============================   ===============     ========================
Type    Base O  Base V   Ct     Type     Base H     Type    Base D  Commands
        (octal) (octal) (Dec)   (hex)    (hex)      (..)    (dec)    (hex)
====    ======  ======  ====    ====     ======     ====    ======  ========
 GY       GY0           2048     33        001       0x         0   01 05 0F
 Y         Y0    40500   512     33        101       0x      2048   01 05 0F
 C         C0    40600  1024     33        181       0x      3072   01 05 0F
 S         S0    41000  1024     33        281       0x      5120   01 05 0F
 T         T0    41100   256     33        301       0x      6144   01 05 0F
 CT       CT0    41140   128     33        321       0x      6400   01 05 0F

 GX       GX0           2048     32        001       1x         0   02
 X         X0    40400   512     32        101       1x      2048   02
 SP       SP0    41200   512     32        181       1x      3072   02

 TV        V0        0   256     31        001       4x         0   03 04 06 10
 CV     V1000     1000   128     31        201       4x       512   03 04 06 10
 V      V1400     1400  3072     31        301       4x       768   03 04 06 10
 V     V10000    10000  4096     31       1001       4x      4096   03 04 06 10
 X         X0    40400   512     31       4101       4x     16640   03 04 06 10
 Y         Y0    40500   512     31       4141       4x     16704   03 04 06 10
 C         C0    40600  1024     31       4181       4x     16992   03 04 06 10
 S         S0    41000  1024     31       4201       4x     16896   03 04 06 10
 T         T0    41100   256     31       4241       4x     16960   03 04 06 10
 CT       CT0    41140   128     31       4261       4x     16992   03 04 06 10
 SP       SP0    41200   512     31       4281       4x     17024   03 04 06 10

 TV        V0        0   256     --        ---       3x         0   04
 CV     V1000     1000   128     --        ---       3x       512   04

==============================================================================
==============================================================================
          Concise Mapping of PLC Memory type access vs Modbus Command

PLC                Modbus
======     ===============================
Access     Type    Base D Base H  Commands
Type       (..)    (dec)  (hex)    (hex)
======     ====    ====== ======  ========
 GY         0x         0      0   01 05 0F (1)
 Y          0x      2048    800   01 05 0F (1)
 C          0x      3072    C00   01 05 0F (1)
 S          0x      5120   1400   01 05 0F (1)
 T          0x      6144   1800   01 05 0F (1)
 CT         0x      6400   1900   01 05 0F (1)

 GX         1x         0      0   02       (1)
 X          1x      2048    800   02       (1)
 SP         1x      3072    C00   02       (1)

 TV         4x         0    000   03 04 06 10
 CV         4x       512    200   03 04 06 10
 V          4x       768    300   03 04 06 10
 V          4x      4096   1000   03 04 06 10
 X          4x     16640   4100   03 04 06 10
 Y          4x     16704   4140   03 04 06 10
 C          4x     16992   4180   03 04 06 10
 S          4x     16896   4200   03 04 06 10
 T          4x     16960   4240   03 04 06 10
 CT         4x     16992   4260   03 04 06 10
 SP         4x     17024   4280   03 04 06 10

(1) Note that these are bit addresses vs the "byte" offsets in the CCM command
    set.

Base is in bits for ModBus type 0 and 1.
Base is in words (!) for ModBus type 3 and 4.
Length is in bytes for all size values. So for
ModBus type 3 and 4 commands multiply address range
by 2 to get legal sizes.... Translate to CCM values
by adding one to odd sizes.

V-Memory addresses are 16 bit values.

Please note that the addresses sent via MODBUS are all zero based.  The "CCM"
commands provided for the AutomationDirect PLCs are 1 based.  This can lead to
some confusion.

Also please note that the bit wise commands ( 1, 2, 5, and 15 ) speak with bit
addressing. Hence the offsets to the bits in C memory is 1024.

Thse mappings are the same as Automation Direct documents for their Modbus
serial interface.

==============================================================================
==============================================================================

                       Practical Modbus Command Examples

ModBus command 1    PLC-205 Read Output Bits 2-5
F0 00 00 40 04 28 7F 00 00 30 31 30 38 30 32 30 30 30 34 F7 

ModBus command 2    PLC-205 Read Input Bits 3-7
F0 00 00 40 04 28 7F 00 00 30 32 30 38 30 33 30 30 30 35 F7 

ModBus command 3    PLC-205 Read Memory Words 16640-16640 0x4100-0x4100 *
F0 00 00 40 04 28 7F 00 00 30 33 34 31 30 30 30 30 30 31 F7 

ModBus command 4    PLC-205 Read Input Words  16640-16640 0x4100-0x4100 *
F0 00 00 40 04 28 7F 00 00 30 34 34 31 30 30 30 30 30 31 F7 

ModBus command 5    PLC-205 Write Output Bit 1 On
F0 00 00 40 04 28 7F 00 00 30 35 30 38 30 31 46 46 30 30 F7 

ModBus command 6    PLC-205 Write Memory Word 16704 (0x4140) to value 3C69 *
F0 00 00 40 04 28 7F 00 00 30 36 34 31 34 30 33 43 36 39 F7 

ModBus command 15   PLC-205 Write Output Bits 2-7
F0 00 00 40 04 28 7F 00 00 30 46 30 38 30 32 30 30 30 36 30 31 33 46 F7 

ModBus command 16   PLC-205 Write Memory Words 16704-16704 (0x4140-0x4140) *
F0 00 00 40 04 28 7F 00 00 31 30 34 31 34 30 30 30 30 31 30 32 39 36 36 39 F7 

* Note that the address must correspond to V Memory addressing. This is
reading the Y values or Output Holding Registers per the offset into V Memory.
See the notes above for details.
