Networking With HP Calculators

Hi everybody!

I send this file because it might answer some common questions about 
networks and the serial port.

Daniel Roggen
droggen@dico.epfl.ch

*******************************************************************
*******************************************************************
**                                                               **
**                         December 1995                         **
**                                                               **
**                    Networks - Serial port                     **
**                           on HP 48                            **
**                                                               **
*******************************************************************
*******************************************************************


             1       Introduction
             2       The HP 48 serial interface
              2.1     pineout
              2.2     An HP-PC cable
              2.3     An HP-HP cable
             3       Networks with the HP 48
              3.1     A Token Ring network
               3.1.1   Wiring a Token Ring network
               3.1.2   Software for the Token Ring network
             4       Contacting me


1 Introduction
--------------

Many questions are asked about the HP 48 serial port and the
calculator networking capabilities. I'll explain in here the pineout
of the 48G serial port and then how to make a TokenRing network for this
calculator.

I hope that this text will answer the most FAQ...



Note: I have made the HP-HP, HP-PC cable and a simple network for 4 HP's,
I had no particular problems, but if you have, please let me know so that
I can report here those problems.
If you have some ideas on another method to make a network (or other), let
me know too so that I can make this documentation more complete.
You can find how to call me at the end of this document.






2 The HP 48 serial interface
----------------------------

I won't rewrite the whole theory of serial interfaces and asynchronous
communications, I just want to explain *HOW* to make an HP-PC, HP-HP cable.



**** 2.1 pineout ****


Fig 2.1.1 shows the pineout of the HP 48 serial interface.
Meaning of the pins:


#1   GND                 This is the logical 0 Volt
#2   RX                  The data are received through this pin
#3   TX                  The data are transmitted through this pin
#4   SHIELD              Protects TX and RX against interferences

+-------------------------+
I                         I
I  -----\                 I
I       I                 I
I       I                 I
I       I                 I
I   *   I                 I
I   T   I                 I
I   O   I                 I
I   P   +--GND-----  #1   I
I   *   +---<<-RX--  #2   I
I       +--->>-TX--  #3   I
I       +--SHIELD--  #4   I
I       I                 I
I       I                 I
I  -----/                 I
I                         I
I                         I
+-------------------------+
 Fig 2.1.1 pineout of the serial interface



**** 2.2 An HP-PC cable  ****

To make an HP-PC cable, you need a connector fitting in the HP serial
port, another connector for your PC ( D-SUB 9 or D-SUB 25 depending
on your serial port).

All you need to do is to link the HP ground with the PC ground,
HP shield with PC shield, HP TX with PC RX and HP RX with PC TX. Fig 2.2.1
shows how this works.


+------------------------------------------------------------+
I  HP 48               PC                                    I
I  -----\                                                    I
I       I                                                    I
I       I                                                    I
I       I                       D-SUB 9    or   D-SUB 25     I
I   *   I                                                    I
I   T   I                                        /---        I
I   O   I                       /--             /   I        I
I   P   +--GND-----...---GND---+5 I    -GND----+ 7  I        I
I   *   +---<<-RX--...---TX----+3 I    -TX-----+ 2  I        I
I       +--->>-TX--...---RX----+2 I    -RX-----+ 3  I        I
I       +--SHIELD--...---------+  I    -SHIELD-+ 1  I        I
I       I                       \--             \   I        I
I       I                                        \---        I
I  -----/                                                    I
I                                                            I
I                                                            I
+------------------------------------------------------------+
 Fig 2.2.1 HP-PC cable

Note that with a D-SUB 9 connector SHIELD remains unconnected, although
you could solder it with GND.
Pay attention to the TX and RX pins on the D-SUB 9 and D-SUB 25:
on the D-SUB 9, TX is pin 3 and on the D-SUB 25, TX is pin 2.



**** 2.3 An HP-HP cable ****

Making an HP-HP cable is quite the same as making an HP-PC cable.
You link the two GROUNDs together, the two SHIELDs together
and link TX #1 to RX #2 and RX #1 to TX #2. Fif 2.3.1 shows this.


+------------------------------------------------+
I  HP 48 #1                            HP 48 #2  I
I  -----\                            /-----      I
I       I                            I           I
I       I                            I           I
I       I          /----------SHIELD-+           I
I   *   I          I     /-----TX-<<-+   *       I
I   T   I          I  /--I-----RX->>-+   T       I
I   O   I          I  I  I    ---GND-+   O       I
I   P   +--GND-----I--I--I----/      I   P       I
I   *   +---<<-RX--I--I--/           I   *       I
I       +--->>-TX--I--/              I           I
I       +--SHIELD--/                 I           I
I       I                            I           I
I       I                            I           I
I  -----/                            \-----      I
I                                                I
I                                                I
+------------------------------------------------+
 Fig 2.3.1 HP-HP cable






3 Networks with the HP 48
-------------------------

We can imagine to link several HPs together with their serial
ports. We could thus play multiplayer games or we could use it to
cheat at school (...) but let us say it is only for a technical purpose
that we do it.


**** 3.1 A Token Ring network ****

I have thought of several different means to do a network for HP 48, I
finally decided to make a kind of Token Ring network.
The principle of Token Ring is quite easy to understand: a token travels
from an HP to the following one until the addressee receives it.

+---------------------------+
I     <---                  I
I           --              I
I      ----I#1I-----        I
I      I    --     I        I
I      I           I        I
I     --           --       I
I    I#2I         I#6I      I
I     --           --       I
I      I           I        I
I     --           --       I
I    I#3I         I#5I      I
I     --           --       I
I      I           I        I
I      I    --     I        I
I      ----I#4I----         I
I           --              I
I                           I
+---------------------------+
 Fig 3.1.1 A Token Ring with 6 HPs with it's direction

This kind of network has advantages and disadvantages. For example, it
requires no electronics, but it is not the fastest network that can be
made: if HP #1 wants to send a message to HP #6, the message has to travel
through HP #2,#3,#4,#5.


****** 3.1.1 Wiring a Token Ring network ******


It's quite easy to wire a Token Ring network for HP. Fig 3.1.1.1 shows how
to do it.


+--------------------------------------------------+
I                                                  I
I     --     --     --     --     --     --        I
I    ITRI   ITRI   ITRI   ITRI   ITRI   ITRI       I
I     ++     ++     ++     ++     ++     ++        I
I     II     II     II     II     II     II        I
I  ..-  -----  -----  -----  -----  -----  -..     I
I                                                  I
I T = Transmit                                     I
I R = Receive                                      I
I                                                  I
+--------------------------------------------------+
 Fig 3.1.1.1 Wiring a Token Ring network


Each HP Transmit pin is wired to the following HP receive pin, at last
all the HP are wired together ( the last HP transmit pin is wired to the
first HP receive pin).

When HP #1 sends a message, HP #2 receives it. If the message is for this
calculator, it can process it, otherwise it sends it to the following
HP (HP #3) which will either process it or send it to HP #4.
You see here that some strange things can happen (in fact it happened
to me!): there may be *LOST* messages, with no destination (or an incorrect
one). In this case, the message will endlessly travel from an HP to another!!



****** 3.1.2 Software for the Token Ring network ******

There is another disadventage of the Token Ring network: unless
dedicated cards are used, the HP must read all incoming caracters and
send them to the next HP, thus consuming a lot of proc time...

First of all we must define a protocol to communicate through this network.
The protocol that I have used is the following one: each message
begins with the ID of the receiver, followed by the ID of the sender, then
the size of the block and finally the data. (see Fig 3.1.2.1)

+--------------------------------------------------------+
I Description  I Receiver I Sender I Size of Data I Data I
+--------------------------------------------------------+
I Size (bytes) I        1 I      1 I            2 I    n I
+--------------------------------------------------------+
 Fig 3.1.2.1 Protocol used for the network

As you can see, the ID of the HPs is one byte in length, allowing
a maximum of 256 different HP. In my protocol, I defined a special ID
0x3f = '?' for the receiver. All the HP will have to read the message,
process it and then transmit it to the next HP. This allows to send
interrogation messages to detect how many HP are on the net without
having to send 255 different messages for each ID.
Note: I used a non-optimized form for the size of the data. For example,
23 meant 23 bytes and not 0x3233.

A software using this kind of net will have to permanently detect incoming
datas, process them, or retransmit them. Thus we could write a function that
fill this job. This function would be typically called periodically in a
loop. I wrote the followin GetToken function:

- GetToken -
<< 0 0 0 -> t s n
  <<
  IF BUFLEN DROP 4 >=           // Enough chars to define the message?
  THEN                          // yes
    4 SRECV DROP DUP            // read those characters
    't' STO 3 4 SUB OBJ->
    'n' STO                     // n = size of message
    DO BUFLEN DROP              // wait until n characters are present
      UNTIL n >=
    END
    n SRECV DROP 's' STO        // read them
    IF t 1 1 SUB MachineName == // if for us (MachineName = HP's ID)
    t 1 1 SUB "?" == OR         // or '?'
    THEN t 2 2 SUB s t s
      + 3 ->LIST 1              // return a list
    ELSE t s + XMIT DROP 0      // if not for us, send the message
    END
  ELSE 0
  END
  >>
>>    // Returns a list (stk 2) and 1 if a token was read, 0 otherwise



We can define a WaitToken function that waits a predefined amount of
time for a token before returning:

- WaitToken -
<< TIME 0 -> t r
  <<
  DO GetToken 'r' STO                     // Waits until a token comes
    UNTIL r 1 == TIME t HMS- .0005 >= OR  // for a maximum of 5 sec.
  END r
  >>
>>



Before initiating transmissions, we could check the ring, to see if it is
not broken. We could for example send a message to ourself and if 5 sec
later it hasn't come back, it would mean that the ring is broken. The
following function does this:

- CHKRING -
<<
  "Checking ring" 4 DISP
  MachineName DUP + "04+CHK" +              // Sends the message
  XMIT DROP
  WaitToken                                 // Waits a token for 5 sec
  IF 0 ==                                   // no token came -> 0 in the stack
  THEN 0
  ELSE
    IF 3 GET MachineName DUP
      + "04+CHK" + ==
    THEN 1
    ELSE 0                                  // wrong token -> 0 in the stack
    END
  END
  IF NOT                                    // if 0 in the stack, ring is broken
  THEN "Ring broken" MSGBOX KILL
  END
>>



We could now make a little application to try this network. RPL isn't
the good language to make this network: too slow. It would be better
to do it in ML and to redirect interrupts, but I show it here in RPL
so that everybody can understand.
This program is a "Talk" program: once all the HPs are connected, it
allows us to send a message to one of the HP on the net.


The following table reports how 3 HP's could detect how many calculators
are on the network and then communicate together. There is a special HP,
called Server, the other are Clients. There is only a little difference
between Client and Server: the server initiates the communication; the
clients wait an order before starting.
Server has ID M, the clients have ID A,B,...
Note: this protocol doesn't automatically detect the machines IDs. You
have to manually choose a different ID for each calculator.

--------------------------------------------------------------------------------------
Note: -> means that the token is send to the next HP.
      R  means that the message is received
      S  means that the message is send
--------------------------------------------------------------------------------------
M                               A                               B
--------------------------------------------------------------------------------------
*Special code for server*
Initialization of variables.
Ring checking

S MM04+CHK
                                -> MM04CHK
                                                                -> MM04CHK
R MM04CHK
The ring is OK.
Sending a start message to
ourself

S MM02+S

*Normal code for server and
client*
                                -> MM02+S
                                                                -> MM02+S
R MM02+S
Start message received.
Who is on the net?

S ?M04+ASK
                                R ?M04+ASK
                                S MA07+ANSWER
                                S ?M04+ASK
                                                                -> MA07+ANSWER
                                                                R ?M04+ASK
                                                                S MB07+ANSWER
                                                                S ?M04+ASK
R MA07+ANSWER
Ok, HP A on the net
R MB07+ANSWER
Ok, HP B on the net
R ?M04+ASK
It's my ask message -> I have
all the HP on the net.
If I am the server (and I am),
I can send a start message to
each of the HP on the net.

S AM02+S
S BM02+S
                                R AM02+S
                                Ok, I can ask who is on the net
                                S ?A04+ASK
                                -> BM02+S
                                                                R ?A04+ASK
                                                                S AB07+ANSWER
                                                                S ?A04+ASK
                                                                R BM02+S
                                                                Ok, I can ask...
                                                                S ?B04+ASK
-> AB07+ANSWER
R ?A04+ASK
I am here...
S AM07+ANSWER
S ?A04+ASK
R ?B04+ASK
I am here...
S BM07+ANSWER
S ?B04+ASK
                                R AB07+ANSWER
                                HP B on the net
                                R AM07+ANSER
                                HP M on the net
                                R ?A04+ASK
                                It's my ask message -> I have all
                                the HP on the net in the list.
                                I am not the server -> I don't
                                send a start message. (It is
                                only the server who does this)
                                -> BM07+ANSWER
                                R ?B04+ASK
                                I am here...
                                S BA07+ANSWER
                                S ?B04+ASK
                                                                R BM07+ANSWER
                                                                HP M on the net
                                                                R BA07+ANSWER
                                                                HP A on the net
                                                                R ?B04+ASK
                                                                It's my ask message
                                                                -> I have all the
                                                                HP on the net.
--------------------------------------------------------------------------------------
At this point, each HP has a list of all the other HP on the net.


I hope that you understood the above table... I know, it isn't easy, that's
why I haven't make a table with 4 or 5 HP !...


I can explain this protocol once more.
Each HP waits for a start message. Once it came, the HP asks every other HP
with the "?x02+ASK". ? means "to all HP". When an HP receives an ASK message,
it checks if it is its own message. If it is, it means that everybody has
received this ASK message and thus answered. It means that an HP receiving
its own ASK message has also received all ANSWER message from the other HP,
and thus, that its list of HP is complete.
If the ASK message received isn't its own ask message, the HP sends an
ANSWER message and then retransmits the ASK message.
When an HP receives an ANSWER message, it adds the sender of the message
to the list of HP present on the net.



Here is the listing of the TALK program.

- SERVE -        This program must be used on only one HP
<<
  CLRBUF                         // a function to clear the serial port buffer
  OPENIO                         // not included here
  { } 'MACHINES' STO             // Empty list of HP on the net
  1 'SRV?' STO                   // I am the server
  0 'CANSEND' STO                // I can't send. An HP can send only when its
  CLLCD                          // list of HP present on the net is complete.
  CHKRING                        // Check ring
  MachineName
  DUP + "02+S" + XMIT DROP       // Sending a start message to itself
  PROCESSMESSAGE                 // Processes incoming messages.
>>

- CLIENT -       This is the client program run on all the other HP
<<
  CLRBUF
  OPENIO
  0 'SRV?' STO                   // I am NOT the server
  { } 'MACHINES' STO
  0 'CANSEND' STO
  CLLCD "Waiting..." 4 DISP
  PROCESSMESSAGE
>>


- PROCESSMESSAGE -    Main loop, calls each time GetToken
<<
  WHILE 1                        // Main loop
  REPEAT
    IF KEY 0 =/ CANSEND 1 == AND // If a key is pressed and I can send
      THEN                         // -> calls TALK module
        DROP TALK
      END
      IF GetToken 1 ==             // If a token has been received
      THEN                         // then process it.
        PROCCASE
      END
  END
>>

- PROCCASE -          Module processing all incoming messages (see table above
                      to understand how it works)
<<
  DUP 2 GET -> t m                // m=message t=list returned by GetToken
  <<
    CASE m "+S" ==                     // START message
    THEN
      "Scanning stations..." 4 DISP
      "?" MachineName + "04+ASK" +     // sends the ASK message to all HP
      XMIT DROP
    END

    m "+ASK" ==                        // ASK message
    THEN
      IF t 1 GET MachineName ==        // If it is my own ASK message
      THEN                             // I can now talk because I have
        1 'CANSEND' STO                // received all ANSWER messages
        IF SRV?
        THEN                           // If I am the server, I send
          MACHINES 1                   // a start message to each HP on the net
            << MachineName + "02+S" +
               XMIT DROP
            >> DOSUBS
        END                            // The list of HP present on the net
        CLLCD "Ready" 1 DISP           // is now full. I'm ready
      ELSE                             // If it wasn't my own ASK message
        t 1 GET MachineName +          // -> I must answer
        "07+ANSWER" + XMIT DROP
        t 3 GET XMIT DROP
      END
    END

    m "+ANSWER" ==                     // ANSWER message, add sender
    THEN                               // to list of HP present on the net
      'MACHINES' t 1 GET STO+
    END

    m t 1 GET DISPM                    // If it is another message,
    END                                // displays it.
  >>
>>



- TALK -              Called when a key is pressed.
                      Not a very good example for this token ring:
                      while HP waits an input string, all token
                      are stored in the 256-byte buffer. and none can
                      be retransmitted to the next HP.
<<
  "MACHINES ON NETWORK" MACHINES 1
  IF CHOOSE
  THEN
    "Message:" "" INPUT
    DUP SIZE NBCNVRT
    SWAP + SWAP
    MachineName + SWAP +
    XMIT DROP CLLCD
  END
>>

- NBCNVRT -           Converts a number to a string of at least 2 chars.
<<
  ->STR -> s
  <<
    IF s SIZE 2 <
    THEN
      "0" s + 's' STO
    END
    s
  >>
>>

- DISPM -             Displays incoming messages
<<
  -> m f
  <<
    0 5 FOR i
      m i 21 * 1 + i 21 *
      21 + SUB
      i 2 + DISP
    NEXT
    "From " f + 1 DISP
  >>
>>






Thats all for this Token Ring network!
If you have other ideas please send them to me, so that I can include
them in this text


4 Contacting me
---------------

If you have suggestions, ideas, etc, send them! I will include them
in this text with your name.

My address:

Daniel Roggen
Moineaux 1
CH-1028 Pr‚verenges (Switzerland)

Voice: +41 21 801 9020
Fax:   +41 21 803 5636
EMail: droggen@dico.epfl.ch

---------------------------------------------------------------------------

Thanks to Olivier Saudan (Adventurer), Y.B. (makes nice games in RPL!) and
DZiR (the first to have an HP in our class).

