Copy - The Copy Command

This command copies a specified number of bytes from a source to a specified location. It has three parameters: Source, Destination, and Length.
The source can be either the receive buffer (@) or a label. The specified source is the start location. It will copy the specified number of bytes starting from that location.
The destination it stores to can be either a tilde memory (~) or a persistent memory ($). The location you specify is the start location. The bytes stored with go into sequentially numbered location from there.
The third value is the number bytes to be stored.
When copying from the receive buffer you can use @0 to copy from the start or specified a byte to start copying from. For instance, @3 would start copying from the fourth byte which is typically the opcode. This directly follows the Start() command typically.
It may make sense to only copy a single byte or pair of bytes in that packet if you have no need of the full message to take up less memory or reduce excessive EEPROM writes.
Copying an entire DyNet message into a set of tilde memory locations then editing individual bytes before using the TX command to re-send the edited message can be a powerful way to send DyNet packets. This use is often in the startup task.

Copying from the @ receive buffer can only be performed once in a task, so if you need 2 bytes that are 6 bytes apart you will need to capture all 6.

Syntax

Copying from the receive buffer Copy @x,destination,length
Where "x" is the location in the message you want to start storing from, "destination" is the memory location you want to start storing from, and "length" is how many bytes you want to capture.

Copying from an archetypal message Copy label,destination,length
Where "label" is the message you want to store, "destination" is the memory location you want to start storing from, and "length" is how many bytes you want to capture(usually 7).

The archetypal message does not have to be part of a task. It can be placed prior to the startup task or between two tasks.

Examples

Example 1

This is a very common use of the copy command to capture and interrogate all logical messages.

Task1()
{
Name="Logical Message Watcher"  //Captures all incomming logical messages.
Start(0x1C,x,x,x,x,x,0xFF)      //Starts on all logical messages
Copy @0,~0,7    //Copies the entire message. ~1=Area, ~3=Opcode
LDA ~1          //Load the area byte
CMP #2          //Is it for area 2?
BRZ Area2       //If so branch to area 2
CMP #3          //Is it for area 3?
BRZ Area3       //If so branch to area 3
...
}

Example 2

A more targeted use that only grabs the preset number (opcode) for a specific area.

Task1()
{
Name="Kitchen Preset Watcher"
Start(0x1C,4,x,x,x,x,0xFF)      //Starts on all logical messages for area 4
Copy @3,~0,3    //Copies the 4th-6th bytes and stores them for later.
LDA ~0          //Load the first captured byte (opcode)
CMP #0x00       //Is it preset 1?
BRZ Preset
CMP #0x01       //Is it preset 2?
BRZ Preset
CMP #0x02       //Is it preset 3?
BRZ Preset
CMP #0x03       //Is it preset 4?
BRZ Preset
CMP #0x0a       //Is it preset 5?
BRZ Preset
CMP #0x0b       //Is it preset 6?
BRZ Preset
CMP #0x0c       //Is it preset 7?
BRZ Preset
CMP #0x0d       //Is it preset 8?
BRZ Preset
Null
Preset:
    LDA ~2      //Load the bank
    BRZ Bank1
    CMP #0x01
    BRZ Bank2
    Null
...
}

Example 3

Capturing a handful of bytes from a D2 message.

Task1()
{
Name="DyNet2 Watcher Task"
Start(0xAC,x,x,x,x,x,0x00,x,x)  //Trigger on a DyNet2 message
Copy @2,~50,8	    //Copy 8 of the bytes starting at the 3rd byte and store into
                    //~50-59 ~50=Opcode 54&55=Area 58=preset base 1
LDA ~50             //Load the Accumulator with the opcode
CMP #0x01	        //Is it a preset message?
BRZ D2_AREA_CHECK
Null
 D2_AREA_CHECK:
    LDA ~54	        //Load the first Area Byte?
    CMP #0xFD       //Is it FD? (64768-65023)
    BNE DYNET2_END	//If not End
    LDA ~55			//Load the second byte
    CMP #0xE8		//Is the second byte E8?  (65000)
    BRZ GLOBAL_AREA1
    CMP #0xE9		//Is the second byte E9?  (65001)
    BRZ GLOBAL_AREA2
    CMP #0xEa		//Is the second byte E8?  (65002)
    BRZ GLOBAL_AREA3
    CMP #0xEb		//Is the second byte E8?  (65003)
    BRZ GLOBAL_AREA4
    CMP #0xEc		//Is the second byte E8?  (65004)
    BRZ GLOBAL_AREA5
    Null
    GLOBAL_AREA1:
        LDA ~58	    //Get the preset byte. D2 presets are linear with a base of 1.
        CMP #1	    //Is it Preset 1? (Day)
        BRZ DAY_NIGHT_P1
        CMP #2	    //Is it Preset 2? (Dawn)
        BRZ DAY_NIGHT_P2
        CMP #3		//Is it Preset 3? (Dusk)
        BRZ DAY_NIGHT_P3
        CMP #4		//Is it Preset 4? (Night)
        BRZ DAY_NIGHT_P4
        Null
        DAY_NIGHT_P1:
    ...
}

Example 4

Copying from an archetypal message so we can edit the bytes and TX it out later.

OneTouch_Message: DyNet(0x1C,0x02,0x00,0x6B,0x00,0x00,0xFF)   //One Touch Message

Startup1()
{
Name="Start Task"
Copy OneTouch_Message, ~30,7 // Copy a default status message to ~30-36
}

Example 5

Copying to persistent memories.

Task14()
{
Name="Do Not Disturb Tracker"
Start(0x1C,3,0x00,0x4C,0x00,x,0xFF)      //Starts on DND for Area 3
Copy @5,$10,1   //Copies the DND state to $10
Null
}