CPU-XA™ Instruction and Program Formats

Joe Pasqua
Last Updated: 5/30/2000

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.


File Format

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.

Opcode
Address
Constant
Subcode
Code
LSB
MSB
LSB
MSB
0
1
2
3
4
5

Details of the instructions follow.


Instructions

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 0x20Condition 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 0xA0Arithm. 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


General CPU-XA Information

Constant Values 2 bytes in the range of 0x0000-0xFFFF (0-65535)
Timer Numbers 0x00-0x3F (0-63)
Variable Numbers 0x00-0x7F (0-127)
Slave Module Data Value 0x00-0x7FFF (0-32767)
Condition Codes
(1 nibble)
Condition Code Value
is > 0*
is < 1*
is NOT = 2*
is = 3*
becomes > 4
becomes < 5
becomes NOT = 6
becomes = 7
* "Is" Conditions
Arithmetic Ops
(1 nibble)
Operation Value
= (set equal to) 0
+ 1
- 2
* 3
/ 4
IR codes Ranges from 0x0000-0x03FF (0-1024). Only values from 0x01-0x50 (1-80) can be received. External modules can accept extended IR codes with values up to 0xFFFF.
Slave Encoding The Module number is stored in the Address MSB (range 0x00 - 0x3F). The Variable number is stored in the LSB (range 0x00 - 0x3F). If the Slave device is an Leopard, then you add 64 to the LSB -- otherwise it is assumed to be an Ocelot.


Time Information

Time of day 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).
Day of Month Represented as a value in the range 0x00-0x1F (0-31).
Day of Week 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).


X10 Information

Dim Levels Represented as values between 0x00 (full OFF) and 0x1F (full ON).
Preset Dim Levels 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)
Status Value
Is OFF 0
Is ON 1
Turns OFF 2
Turns ON 3
On Command Pair 4
Off Command Pair 5
Codes
(2 Bytes)
House Code
(First Byte)
Key Code
(Second Byte)
A 0x00
B 0x01
C 0x02
D 0x03
E 0x04
F 0x05
G 0x06
H 0x07
I 0x08
J 0x09
K 0x0A
L 0x0B
M 0x0C
N 0x0D
O 0x0E
P 0x0F
Units 1-16 0x00-0x0F
All Units Off 0x10
All Lights On 0x11
ON 0x12
OFF 0x13
Dim*** 0x14
Bright*** 0x15
All Units OFF 0x16
All Units ON 0x17
Extended Code 0x18
Hail Request 0x19
Hail Ack 0x1a
Preset Dim 0 0x1b
Extended Data 0x1c
Status ON 0x1d
Status OFF 0x1e
Preset Dim 1 0x1f
*** 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 Information

Module Encodings
(2 Bytes)
Module
0x00-0x80 (0-128)

Module Point, Zone
0x00-0x80 (0-128) 0x00-0x0F (0-15)

Module Message, Param
0x00-0x80 (0-128) 0x00-0x1F (0-31)

Note: Though a value of 0 is accepted for a module, the Adicon manual states that the first module number is 1.
I/O State
Turns OFF 0
Turns ON 1
Used to set state, not test
I/O Status
Is OFF 0
Is ON 1
Turns OFF 2
Turns ON 3
Used to test state, not set
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 Information

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
Address MSB Address LSB Constant LSB Command
Bobcat Module 0x00 0x00 - 0x64 Setpoint. Range: 0-100.
0x01 0x00 System Mode Auto
0x01 0x01 System Mode Cool
0x01 0x02 System Mode Heat
0x01 0x03 System Mode Off
0x02 0x00 Fan Mode Auto
0x02 0x01 Fan Mode On
0x03 0x00 Hold Release


RCS Information

RCS Encoding
Address MSB Address LSB Constant LSB Command
X10 House Code 0x00
0x01
0x02
0x00 - 0x1F Setpoint. Range: 4-100. To encode a Setpoint: subtract 4 from the setpoint, divide it by 32, set the Address LSB to the quotient and the Constant LSB to the remainder (in other words, the setpoint is equal to: (Address LSB) * 32 + (Constant LSB) + 4.
0x03 0x00 System OFF
0x01 Heat Mode
0x02 Cool Mode
0x03 Auto Mode
0x04 Fan ON
0x05 Fan OFF
0x06 Setback ON
0x07 Setback OFF
0x08 Increase 1 Degree
0x09 Decrease 1 Degree
0x0A Setback Delta 6F/3C
0x0B Setback Delta 8F/4C
0x0C Setback Delta 10F/5C
0x0D Setback Delta 12F/6C
0x0E Setback Delta 14F/7C
0x0F Setback Delta 16F/8C
0x10 Unit ON
0x11 Unit OFF
0x12 Preset ON
0x13 Preset OFF
0x14 Ack ON
0x15 Ack OFF
0x16 Echo ON
0x17 Echo OFF
0x18 Safe ON
0x19 Safe OFF
0x1A Autosend ON
0x1B Autosend OFF
0x1C DT1
0x1D DT2
0x1E DT3
0x1F DT4
0x04 0x00 Request Temperature


Examples

Statement Reference
Opcode
Address
Constant
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