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:
...
}