CPU-XA™ Instruction and Program FormatsJoe Pasqua |
This note describes the high level instruction set of the CPU-XA and of the .PGM file format used by the C-MAX™ software. I derived this information by inspecting sample .PGM files and by looking at the "Reference" field displayed by the C-MAX software.
I don't make any guarantees about the accuracy of this information. The information is also subject to change. I assume no responsibity for any problems you might experience by using the information contained here.
The file format is simply a collection of 2048 sequential 86 byte entries. Each entry represents a single line (instruction) in the source program. The first six bytes of the entry represent the instruction and the next 80 bytes represent the comment. If the comment is less than 80 bytes long, it is terminated by a null character. All entries after the end instruction (0xE07F00000000) are ignored.
Instructions have three basic parts: an opcode, an address, and a constant value. Each of these is represented with two bytes as shown below. The byte ordering shown here is what is found in the program file, not what is displayed in the Reference field of C-MAX.
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
Details of the instructions follow.
Note: The low nibble of the subcode is a don't-care unless a condition or arithmetic operator is explicitly added in. In this table that field is always shown to be 0. If you examine a .PGM file or the reference field dispayed by C-MAX, it will sometimes contain other values. The only exception to this is the "timer =" instruction which has a subcode of 0x83.
Code (1 byte) |
Subcode (1 byte) |
Address (2 bytes) |
Constant (2 bytes) |
|
IF | The Opcodes for AND are 0x0C, 0x0D, 0x0E, 0x0F The Opcodes for OR they are 0x10, 0x11, 0x12, 0x13 |
|||
0x00 | Module/Point | 0x00 | Module/Point Encoding | I/O Status |
Module/Param | 0x20 + Condition | Module/Param Encoding | Constant Value | |
Receive X10 | 0x40 | X10 Code | 0x0000 | |
Compare Bobcat Data | 0x60 + Condition | Bobcat Module | Bobcat Data Encoding | |
Timer | 0x80 + Condition | Timer Number | Constant Value | |
Variable | 0xA0 + Condition | Variable Number | Constant Value | |
Time of Day | 0xC0 + Is Condition | Encoded Time of Day | 0x0000 | |
Month | 0xE0 + Is Condition | 0x0000 | Month Code | |
0x01 | Day of Month | 0x00 + Is Condition | 0x0000 | Day of Month |
Day of Week | 0x20 + Is Condition | 0x0000 | Day Of Week | |
Year | 0x40 + Is Condition | 0x0000 | Year | |
Date | 0x60 + Is Condition | 0x0000 | Date | |
Receive IR | 0xA0 | Module | IR Code | |
X10 Status Change | 0xC0 | X10 Code | X10 Status | |
0x02 | I/O Error Occurs | 0x40 | 0x0000 | 0x0000 |
0x03 | Touch Button Rcv | 0x20 | Module | Button |
THEN | The Opcodes for ELSE are 0x08, 0x09, 0x0A, 0x0B | |||
0x04 | Module/Point | 0x00 | Module/Point Encoding | I/O State |
Set Slave Variable | 0x20 | Module/Number Encoding | Constant Value | |
Load Data To | 0x40 | Variable Number | 0x0000 | |
Transmit X10 | 0x60 | X10 Code | 0x0000 | |
Timer | 0x83 | Timer Number | Constant Value | |
Variable | 0xA0 + Arithm. Op | Variable Number | Constant Value | |
0x05 | Xmit Local IR | 0x80 | 0x0000 | IR Code |
Send RCS X10 | 0xA0 | RCS Module/Command/Value Encoding | ||
Send Bobcat T-Stat | 0xC0 | Bobcat Number/Command/Value Encoding | ||
X10 Preset Dim* | 0xE0 | X10 Code | Dim Level | |
0x06 | X10 Quick On | 0x00 | X10 Code | 0x0000 |
X10 Quick Off | 0x20 | X10 Code | 0x0000 | |
Send Page | 0x60 | Message Number | 0x0000 | |
Xmit Remote IR | 0x80 | Module/Zone Encoding | Extended IR Code | |
X10 Preset Dim** | 0xA0 | X10 Code | Preset Dim Level | |
Xmit X10 Group** | 0xC0 | X10 Group | Preset Dim Level | |
Xmit Speak Easy | 0xE0 | Module/Message | 0x0000 | |
0x07 | Xmit ASCII String | 0x00 | 0x0000 | ASCII String Number |
END | ||||
0x7F | END | 0xE0 | 0x0000 | 0x0000 |
* | PCS Preset |
** | Leviton Preset |
A time of day can be given as either an absolute time or as an offset from sunrise or sunset. An absolute time is encoded as a single number composed of two decimal numbers representing the hour (0-23) and the minute (0-59). They are composed by multiplying the hour by 100 and adding the minute. Thus 8:35 would be 835. Thus values must be in the range 0-2359 with no value in the tens place greater than 5. An offset from sunrise or sunset is marked by 0x40 (sunrise) or 0x80 (sunset) in the MSB. The LSB has values in the range 0-60 where 0 corresponds to 30 minutes before sunrise/sunset and 60 corresponds to 30 minutes after sunrise/sunset. Therefore a value of 30 corresponds to 0 minutes before sunrise/sunset. |
|
Month | Represented as a value in the range 0x0-0xc (0-12). |
Represented as a value in the range 0x00-0x1F (0-31). | |
Represented as a value in the range 0x00-0x06 (0-6). | |
Year | Represented as a value in the range 0x0000-0x0BB* (0-3000). |
Date | Represented as the number of days since December 31, 1998 (Or is it the beginning of the current year?). Dates from 1/1/1999 to 12/31/2020 can be represented. This corresponds to values of 0x0001-0x1f64 (1-8036). |
Represented as values between 0x00 (full OFF) and 0x1F (full ON). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Represented as values between 0x00 (full OFF) and 0x3F (full ON). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Groups | Consists of a house code (0x00-0x0F) followed by a group command. A group command is either 0x00 for "Group to OFF" or 0x01 for "Group to Preset" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Status (1 nibble) |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Codes (2 Bytes) |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*** The Dim and Bright commands also encode the number of times they repeat (between 1 and 16, encoded as 0x0-0xF). The repeat count is stored in the high order nibble of the house code. For example, the command to send dim 8 times on house code K would be (HouseCode=0x7A, KeyCode=0x14). The high nibble of the house code is 0x7 representing a repeat of 8 times. The low nibble is 0xA which is the code for 'K'. 0x14 is the Key Code for Dim. |
Module Encodings (2 Bytes) |
|
||||||||||||
I/O State |
|
||||||||||||
I/O Status |
|
||||||||||||
Button | Range from 0x00-0xff (0-255) | ||||||||||||
Message Numbers | Range from 0x01-0x0F (note that they do not start from 0) | ||||||||||||
ASCII String Numbers | Range from 0x00-0x7F (0-127) |
Bobcat Module | Ranges from 0x01 - 0x3F (1-63). | |||||||||||||||||||||||||||||
Bobcat Data Encoding | Ranges from -100 to 65435. Encoded by adding 100 to the number. | |||||||||||||||||||||||||||||
Bobcat Number/Command/Value Encoding |
|
RCS Encoding |
|
Statement | Reference |
|
|
|
|||
Subcode | Code | LSB | MSB | LSB | MSB | ||
If Module# 0/ Point# 2 Turns ON | 0000-0002-0003 | 00 | 00 | 02 | 00 | 03 | 00 |
If Module #3/Param #4 becomes > 511 | 0024-0304-01FF | 24 | 00 | 04 | 03 | FF | 01 |
If X10 K/9 is received | 0040-0A08-0000 | 40 | 00 | 08 | 0A | 00 | 00 |
If Timer 24 is = 13 | 0083-0018-0000 | 83 | 00 | 18 | 00 | 00 | 00 |
If Variable 31 becomes = 65535 | 00A7-001F-FFFF | A7 | 00 | 1F | 00 | FF | FF |
If Time of Day is < 13:45 | 00C1-0541-0000 | C1 | 00 | 41 | 05 | 00 | 00 |
If Month is Not = 12 | 00E2-0000-000C | E2 | 00 | 00 | 00 | 0C | 00 |
If Day of Month is < 15 | 0101-0000-000F | 01 | 01 | 00 | 00 | 0F | 00 |
If Weekday is < 3 | 0121-0000-0003 | 21 | 01 | 00 | 00 | 03 | 00 |
If Year is > 1979 | 0140-0000-07BB | 40 | 01 | 00 | 00 | BB | 07 |
If Date is Not = 12/31/99 | 0162-0000-016D | 62 | 01 | 00 | 00 | 6D | 01 |
If Receive Infra-Red#80 | 01A0-0000-0050 | A0 | 01 | 00 | 00 | 50 | 00 |
If X10 K/9 Turns OFF | 01C0-0A08-0002 | C0 | 01 | 08 | 0A | 02 | 00 |
If I/O Error Occurs | 0240-0000-0000 | 40 | 20 | 00 | 00 | 00 | 00 |
Then Module# 3/Point # 4 Turns ON | 0400-0304-0001 | 00 | 04 | 04 | 03 | 01 | 00 |
Then Xmit X10 D/18 (all lights on) | 0460-0311-0000 | 60 | 04 | 11 | 03 | 00 | 00 |
Then Xmit X10 K/21, 8 times (Dim) | 0460-7A14-0000 | 60 | 04 | 14 | 7A | 00 | 00 |
Then Timer 13 is = 5 | 0483-000D-0005 | 83 | 04 | 0D | 00 | 05 | 00 |
Then Variable 12 - 4 | 04A2-000C-0004 | A2 | 04 | 0C | 00 | 04 | 00 |
Then Transmit Infra-Red# 129 | 0580-0000-0081 | 80 | 05 | 00 | 00 | 81 | 00 |
Then X10 Preset Dim K/9 to 31 | 05E0-0A08-001F | E0 | 05 | 08 | 0A | 1F | 00 |
Then turn X10 K/9 ON | 0600-0A08-0000 | 00 | 06 | 08 | 0A | 00 | 00 |
Then turn X10 K/9 OFF | 0620-0A08-0000 | 20 | 06 | 08 | 0A | 00 | 00 |
Then Send Page #9 | 0660-0009-0000 | 60 | 06 | 09 | 00 | 00 | 00 |
Then Xmit Rmt IR3 to Mod1, Zone 2 | 0680-0102-0003 | 80 | 06 | 02 | 01 | 03 | 00 |
Then Lev PresetDim A/1 to Lvl 32 | 06A0-0001-0020 | A0 | 06 | 01 | 00 | 20 | 00 |
Then Lev Grp PRESET Command L/4 | 06C0-0B01-0004 | C0 | 06 | 01 | 0B | 04 | 00 |
Then Xmit Module# 3/ Message #5 | 06E0-0305-0000 | E0 | 06 | 05 | 03 | 00 | 00 |
Then Xmit Ascii String# 45 | 0700-0000-002D | 00 | 07 | 00 | 00 | 2D | 00 |