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.
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 transfer begins with an handshake.
Then the transfer begins.
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
End of the loop
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).
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.
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.
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. “data.name” 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 += data.name[:8] + '\xff' * (8 - len(data.name[:8])) #10->17 header += '\xff' * 8 header += data.password[:8] + '\xff' * (8 - len(data.password[:8])) if data.use_base: header += 'BN' else: 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 += data.name 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.
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.
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.
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'
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)
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