Please help with a protocol document

Dear All,

I am trying to understand how to approach a protocol document.
The idea is to get an Arduino talking to another system via RS232
The communication involves passing binary states for I/O, analogue states for temperature sensors, and serial data - text. In both directions.
Data is sent via packets, containing the "port" address, and the data itself.

I will be extremely grateful for any pointers on how best to approach decoding (and encoding) the data to facilitate bidirectional link between the two systems.

Many thanks!

Digital data is encoded in a 2-byte (16-bit) format, as follows:

1 0 C # # # # # 0 # # # # # # #
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (Bit Position)

Where bit 15 (the most significant bit) is set to 1 and bit 14 is set to 0, denoting the start of new digital data. Bit 13 is set to the complement of the signal state. That is, if the signal is high, C equals 0; if the signal is low, C equals 1. Bit 7 (the high-order bit of byte 2) is set to 0. The 12-bit index of the signal (identified by # signs) is spread out over bytes 1 and 2, with leading zeros used as fills.

For example, consider a digital signal at index 14 (binary 0000 1110) that goes low. Following the format just described, the data would be sent as:

1 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (Bit Position)

Analog data is encoded in a 4-byte (32-bit) format, as follows:

1 1 A A 0 # # # 0 # # # # # # #
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 (Bit Position)

0 A A A A A A A 0 A A A A A A A
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (Bit Position)

Where bit 31 (the most significant bit) and bit 30 are both set to 1, denoting the start of new analogue data. Bit 27 is set to 0, as are bits 23, 15, and 7 (the high-order bits of each byte). The 16-bit analogue value of the signal (identified by red "a" letters) is spread out over bytes 1, 3 and 4, with leading zeros used as fills. The 10-bit index of the signal (identified by # signs) is spread out over bytes 1 and 2, with leading zeros used as fills.

For example, consider an analogue signal at index 9 (binary 0000 1001) with a value of 233 (binary 1110 1001). Following the format just described, the data would be sent as:

1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 (Bit Position)

0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (Bit Position)

Unlike digital and analogue data, which is encoded in a format of fixed length, serial data can be of variable length and is encoded as follows:

Bytes 1 and 2 1 1 0 0 1 # # # 0 # # # # # # #
Serial data bytes (up to 252) d d d d d d d d ... ... ... Low-order Byte: 1 1 1 1 1 1 1 1

Where the five high-order bits are set to 1-1-0-0-1, denoting the start of new serial data. The high-order bit of byte 2 is set to 0. The 10-bit index of the signal (identified by # signs) is spread out over bytes 1 and 2, with leading zeros used as fills. This is followed by up to 252 bytes of serial data (identified by the "d" letters). Finally, the low-order byte is set to FFh (binary 1111 1111) denoting the end of the serial data.

enum {UNKNOWN, BINARY, ANALOG, ASCII} mode = UNKNOWN;

// in loop()
    character = Serial.read();
    if (mode == ASCII) {
        if (character == B11111111) {
            //  Process the input ASCII
        } else {
        if (asciiCount < 253) {
           asciiBuffer[asciiCount++] = character;
        }
    } else {
    if ((character & B11000000) == B10000000) {
        mode = BINARY;
        binaryCount = 0;
        binaryBuffer[binaryCount++] = character;
    } else {
    if ((character & B11001000) == B11000000) {
         mode = ANALOG;
         analogCount = 0;
         analogBuffer[analogCount++] = character;
    } else {
     if ((character & B11001000) == B11001000) {
          mode = ASCII;
         asciiCount = 0;
    } else {
      if ((character & B10000000) == B00000000) {
      switch (mode) {
        case BINARY:
              binaryBuffer[binaryCount++] = character;
              if (binaryCount == 2) {
                 // Process binary data
                 mode = UNKNOWN;
                 }
                 break;
       case ANALOG:
              analogBuffer[analogCount++] = character;
              if (analogCount == 4) {
                 // Process analog data
                 mode = UNKNOWN;
                 }
                 break;
                }