CPU-XA™ Instruction and Program Formats

Joe Pasqua
Last Updated: 10/14/1999

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.


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.

(1 byte)
(1 byte)
(2 bytes)
(2 bytes)
IF The Opcodes for AND are 0x0C, 0x0D, & 0x0E.
The Opcodes for OR they are 0x10, 0x11, 0x12
0x00 Module/Point 0x00 Module/Point Encoding I/O Status
Module/Param 0x20Condition Module/Param Encoding Constant Value
Receive X10 0x40 X10 Code 0x0000
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 0x0000 IR Code
X10 Status Change 0xC0 X10 Code X10 Status
0x02 I/O Error Occurs 0x40 0x0000 0x0000
THEN The Opcodes for ELSE are 0x08, 0x09, 0x0A, 0x0B
0x04 Module/Point 0x00 Module/Point Encoding I/O State
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
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
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-0x1F
Variable Numbers 0x00-0x1F
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.

Time Information

Time of day 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.
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"
(1 nibble)
Status Value
Is OFF 0
Is ON 1
Turns OFF 2
Turns ON 3
On Command Pair 4
Off Command Pair 5
(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 Lights 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 Point, Param, or Zone
0x00-0x80 (0-128) 0x00-0x0F (0-15)
Module Message
0x00-0x80 (0-128) 0x00-0x1F (0-31)
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
Message Numbers Range from 0x01-0x0F (note that they do not start from 0)
ASCII String Numbers Range from 0x00-0x7F (0-127)


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