Transfer protocol documentation

This page describe the transfer documentation used by Casio calculators Casio graph 25+/35+/65.

This documentation was written thanks to the work of Cafix authors.

Serial port configuration

  • Baud rate: 9600 bps
  • Parity: none
  • Bye size: 8 bits
  • Stop bits: 1
  • X ON/X OFF: none
  • rtscts: none

A part of this information was extracted from the Casio Graph 65 manual.


In this document, we'll refer to a sender and a receiver. They can be both calculator and computer, but we describe what a computer does if it is this sender/receiver, a calculator may act differently.

When a sender/receiver send 0xff, this means that it send the byte with the hexadecimal value ff.

The communication


The transfer begins with an handshake.

  1. The receiver wait a byte from the sender.
  2. When the sender is ready, it can send:
    • 0x15: a request for interactive handshake.
    • 0x16: a request for non-interactive handshake. This is the most current case to transfer data.
  3. The receiver answer by 0x13.

Then the transfer begins.

The transfer

The sender will send an header, which contains information about the data it will transfer. The header give some information about the following data.

There is a special header, the END header. This header is the last of a communication. Some data, like backups and screen captures, end the communication without END header.

To have more informations about header and data blocks, see the right part.

The transfer works following this loop:

Begin of the loop

  1. The sender sends a header (the len of the header depends on the data type, specified at the beginning of the header).
  2. If it's an END header, it's the end of the transfer, exit the loop
  3. The receiver checks the header
    • If the data type is unknown, the receiver refuses the header by sending 0x00 (or maybe 0x24). The transfer aborts.
    • If the checksum of the header isn't correct, the receiver send 0x2b. The transfer aborts.
    • If the data already exists in the receiver memory, the receiver send 0x21 to ask to overwrite.
      • If the sender refuses to overwrite:
        1. It send 0x15 (abort code)
        2. The receiver answers by 0x06, the transfer aborts
      • If the sender accepts to overwrite:
        1. It send 0x06
        2. The receiver answer:
          • 0x06 if it agrees. The transfer continues.
          • Something different than 0x06: the receiver cannot overwrite, the transfer aborts.
    • If there are errors in the header, the receiver send 0x51. The transfers aborts.
    • If the receiver accepts the header, it send 0x06.
  4. For each data part:
    1. The sender sends 0x3a
    2. The sender sends the data part (the length of the data part is specified in the header or defined by the data type).
    3. The sender sends the checksum of this part.
    4. The receiver checks the checksum:
      • If the checksum is right, the receiver send 0x06
      • Else, the receiver send something different than 0x06. The transfers aborts.
  5. If the data is a backup or a screen capture, it's the end of the transfer. Exit the loop.

End of the loop

The interactive transfer

Casio calculators are also able to send or receive some data types in “interactive mode”, through the functions Send( and Receive. Data types which can be transferred this way include all types of variables (Simple variables, lists, matrices).

Data Receipt

Receiving data sent using the Send( function of the calculator can be done exactly the same way as receiving data “normally”. This only difference is that the handshake byte is 0x15 rather than 0x16. The Send( function takes an argument which represents the data which will be sent.

Data sending

The Receive( function of the calculator takes an argument. This argument is the name of a variable, a matrix or a list. Therefore the calculator decides the data it wants to receive, given as the argument of the Send( function.

After the computer has answered to the handshake, the calculator sends a header telling what data type should be sent. The computer answers to this header with 0x06. Then the calculator also answers with 0x06.

Now, the computer sends a header specifying the data type (Simple variable, Matrix, List, see below for details) it will send. So for only one data transfer, two headers are exchanged : the first is the request header sent by the calculator and the second is a “normal” header sent by the computer. The computer is then allowed to send the data. The communication is ended by a end header. I think the same error codes/conditions can be used, as during a normal transfer.

Headers and data parts

END header

The END header is 46 bytes long. The three first bytes are the word “END”, the 45 others are 0xff.



A program header is 49 bytes long.

Here is how to made an header for a program (in python). The “data_len” is the length of the program in the raw formats plus two. “” is the name of the program, 8 characters maximum, same for “data.password”.

header = 'TXT\x00PG'
header += chr(data_len / (256 ** 3))
header += chr((data_len % 256 ** 3) / (256 ** 2))
header += chr((data_len % 256 ** 2) / 256)
header += chr(data_len % 256) # 0 -> 9
header +=[:8] + '\xff' * (8 - len([:8])) #10->17
header += '\xff' * 8
header += data.password[:8] + '\xff' * (8 - len(data.password[:8]))
if data.use_base:
    header += 'BN'
    header += 'NL'
header += '\xff' * 12
header += header_checksum

“header_checksum” is the calculated header checksum (see the checksum part).


Program data is the raw data, all in one data part.

The length of the program data is in the header.



A backup header is 49 bytes long.

The following python code make a backup header from the raw data of the backup.

header = data.raw_data[2048: 2048 + 48]
header = header[:33] + '\x00\x10\x00\x00\x00\x00' + header[39:]
header += header_checksum


A backup is transfered in one part, which contain the memory raw dump.

The backup length is to be read in the header, by example with this python code:

std_len = ord(header[6]) * (256 ** 3) + ord(header[7]) * (256 ** 2) + \
          ord(header[8]) * 256 + ord(header[9]) - 2



A picture header is 49 bytes long.

The following python code make a picture header:

header = 'IMG\x00PC'
header += '\x00\x40\x00\x80'
header +=
header += '\xff' * 8
header += 'DRUWF'
header += '\x00\x04\x00\x01'
header += '\xff' * 13
header += header_checksum


Before the transfer, a picture must be converted in the Casio Image format, with the pallet [Orange, Blue, Green, White] and all sheet have the header “\x00\x01\x00”.

Each sheet (with the header) is a data part. Each data part is 1028 bytes long.

Mono screen captures


A mono screen capture header is 39 bytes long.

header = 'DD'
header += '\x40\x80\x10'
header += 'DWF'
header += '\xff' * 30
header += header_checksum


A mono screen capture is one part of 1024 bytes, in the Casio mono screen capture format.

Color screen captures


A color screen capture header is 39 bytes long.

header = 'DC'
header += '\x40\x80\x11'
header += 'UWF'
header += '\x03'
header += '\xff' * 29
header += header_checksum


A color screen capture is transfered in three data parts of 1024 bytes, one for each sheet. The capture and its sheets are in the Casio color screen capture format.

It seems there is a problem with checksums: maybe the calculator send wrong checksums, or the checksum calculation for color screen captures isn't the same than other data types.

Request header

It is the header sent by the calculator by the Receive( function, during an interactive transfer. It is 49 bytes long.

header = 'REQ'
header += 'VM' # or 'MT' or LT'


Header checksum

The header checksum is a byte calculates from the header (without the checksum, of course).

Here a python code to calculate the checksum of a header:

header_checksum = 0
for byte in header:
    header_checksum = (header_checksum + ord(byte)) % 256
header_checksum = (0 - header_checksum) % 256
# Append the checksum to the header
header += chr(header_checksum)

Data part checksum

A header must also be calculated for each data part. Here is a python code to calculate this checksum.

checksum = 0
for byte in raw_data:
    checksum += ord(byte)
    if checksum > 255:
        checksum -= 256
checksum = 256 - checksum

Powered by PHP Valid XHTML 1.0 strict Valid CSS Driven by DokuWiki

The content of this website is, without another mention, under the GNU Free Documentation License.