The Museum of HP Calculators

HP Articles Forum

Internet Protocol (v4) Addresses on the HP-16C

Posted by Cameron Paine on 20 Dec 2005, 2:36 a.m.

An IPv4 address is simply a 32-bit unsigned integer. An address is given a sub-structure by conventional rules that divide the address pool into three classes based on numerical range. The sub-structure can be further refined by applying a 32-bit mask to the address.

Conventionally, addresses and masks are written using dotted-decimal notation. In this system, each of the four octets that make up the address (or the mask) are expressed in decimal, with a dot separating each octet. The left-hand position holds the most-significant octet.

For example:

192.168.192.42 255.255.192.0

There is an alternative notation for network masks in which a single integer, representing the number of bits that are set in the mask, is appended to a dotted-decimal address, preceded by a slash character. This is sometimes called CIDR notation. Using this scheme, the above address/mask combination would be expressed as:

192.168.192.42/18

This is a useful notation because the actual mask can be conveniently generated using the number after the slash and the 16C's left mask (MASKL) operator.

## The Package

The routines in this package manipulate IPv4 addresses and network masks in various useful ways. None of the functions provided are particularly ingenious but collectively they can save quite a few keystrokes.

User Routines

```GSB A - JOIN dotted decimal octets to 32-bit integer
GSB B - SPLIT 32-bit integer to dotted decimal octets
GSB C - NETwork address from CIDR
```

Service Routines

```GSB 9 - convert MASK in register 0 to CIDR form.
GSB 8 - OCTET processor for SPLIT
GSB 7 - convert mask in X to CIDR MASK in X
```

Input and Output

The 16C has no native dotted-decimal representation. Therefore we use the four stack registers as follows:

```T := octet 3 (ms)
Z := octet 2
Y := octet 1
X := octet 0 (ls)
```

For those functions that require CIDR addresses, the mask should be stored in Register 0. If the mask is in binary form it will be converted to CIDR form as required. Thus 192.168.192.42/26 is entered as:

```26 STO 0
192 ENTER
168 ENTER
192 ENTER
42
```

The four octets in a returned address can be retrieved by using the roll-down key.

All routines use I for temporary storage. They may be trivially modified to use another register for that purpose. The calculator must be in unsigned decimal mode with a 32-bit word size.

```; JOIN - dotted decimal octets to 32-bit integer
+01 - LBL JOIN (A)
+02 - R^
+03 - STO I	; I = o3
+04 - Rv
+05 - X-Y	; x = o1; y = o0
+06 - [8]	; discards T
+07 - RLn	; x = o1 << 8
+08 - LSTx	; bring back 8...
+09 - Rv	; ...and put it in T
+10 - OR	; x = o0 | o1 << 8; y = o2; z = 8; t = 8
+11 - X-Y	; x = o2
+12 - R^	; bring back 8...
+13 - SL	; ...make it 16
+14 - RLn	; x = o2 << 16
+15 - LSTx	; bring back 16...
+16 - R^	; bring back 8...
+17 - OR	; ...make it 24
+18 - Rv	; x = o2 << 16; y = o0 | o1 << 8; t = 24
+19 - OR	; x = o2 << 16 | o0 | o1 << 8
+20 - RCL I	; x = o3
+21 - R^	; x = 24
+22 - RLn	; x = o3 << 24
+23 - OR	; x = o3 << 24 | o2 << 16 | o0 | o1 << 8
+24 - RTN
; SPLIT - 32-bit integer to dotted decimal octets
+25 - LBL SPLIT (B)
+26 - GSB OCTET	; do o0
+27 - Rv
+28 - STO I	; stash in I
+29 - R^
+30 - GSB OCTET	; do o1
+31 - Rv
+32 - X-I	; stash o1, stack o0
+33 - R^
+34 - GSB OCTET	; do o2 and o3
+35 - X-Y	; x = o2; y = o3
+36 - R^
+37 - X-I	; x = o1; y = o2; z = o3
+38 - R^	; x = o0; y = o1; z = o2; t = o3
+39 - RTN
+40 - LBL NET (C)
+41 - GSB JOIN
+44 - AND
+45 - GTO SPLIT
+46 - LBL BCAST (D)
+47 - GSB JOIN
+50 - NOT
+51 - OR
+52 - GTO SPLIT
+54 - X=0?
+55 - RCL 0
+56 - X=0?
+57 - RTN
+60 - NOT
+61 - [1]
+62 - [-]
+63 - RTN
;
; Service Routines
;
; If the high bit of X is set we assume it contains a binary
; mask and we convert it to CIDR form. Otherwise we leave it
; alone.
+65 - [3]
+66 - [1]
+67 - B?
+68 - B#
+69 - RTN
; Places the low-order octet of X in Y and the remaining
; high-order bits, right justified, in X.
+70 - LBL OCTET (8)
+71 - [8]
+73 - X-Y	; swap so we stash in LSTx
+74 - AND	; clear high bits
+75 - LSTx	; X = word; Y = octet;
+76 - [8]	; Clear low octet so we can rotate
+78 - NOT	; ...becomes remaining octet mask
+79 - AND	; clear low octet
+80 - [8]
+81 - RRn	; rotate cleared octet to MSB
+82 - RTN
+84 - RCL 0
```P - 6  r - 028