converted PICBASIC PRO subroutine called setipaddrs is
responsible for the address reconfiguration.
;* This subroutine builds the IP header.
;move IP source address to destination address
;make ethernet module IP address source address
;move hardware source address to destinatin address
;make ethernet module mac address the source address
Porting the initial portion of the setipaddrs subroutine
was a piece of cake as all I had to do was remove the
semicolons from the ends of the ported statements. In
actuality, I could have left the semicolons in place as they
are comment delimiters in PICBASIC PRO. The downside
to this laziness is that sometimes an active statement
following the semicolon that needs to be ported gets the
commented color scheme, and can be accidentally
erased or ignored. During porting, I had the “ignore”
scenario occur just before I was about to execute the
“erase” scenario. So, I’ve eliminated the end-of-C-statement semicolons in our C-to-PICBASIC PRO port. As
you can see in the setipaddrs code snippet, the setipaddrs
subroutine simply swaps the source and destination IP
and MAC addresses in preparation for the transmission of
the PING reply packet.
Just when you think things are in hand, the bottom of
your basket falls through. In the C source we’re porting,
the 16-bit IP header and ICMP header checksums are
calculated using 32-bit variables. Unfortunately, PICBASIC
PRO knows what a 32-bit variable is, but it has no
orders to do anything about them. The PICBASIC
PRO DIV32 mnemonic and some tricky Darrel Taylor
PICBASIC PRO/assembler code are all that we have to
work with when it comes to using ported unsigned
long C variables with PICBASIC PRO. Unfortunately, I
was unable to think (or should that be trick) my way
through the 16-bit checksum problem using Darrel’s
readily-available algorithms. That was a loss as Darrel’s
DIV32 code is compact and efficient. So, I had to resort
THE DESIGN CYCLE
to Plan B from outer space. Here’s the first of the alien
Let’s translate. Note that there are four acc word
variables and four arg byte variables. The acc variables are
accumulator variables while the arg variables I’ve declared
are arguments or mathematical operands. When all is
said and done, the chksum16 variable will contain our
magic checksum, which was calculated with the help of the
accumulators and arguments.
The IP checksum is defined as the 16-bit one’s
complement sum of all 16-bit words in the header.
PICBASIC PRO can natively manipulate 16-bit variables.
Our problem lies in the fact that when accumulating 16-bit
values, an overflow into the 17th bit can possibly occur.
PICBASIC PRO will throw the 17th bit in the bit bucket.
Our checksum calculation uses all of the bits from bit
17 up to bit 31. Our job is to arrange all of the IP header
bytes into words, add them all together with the carries out
into bit 17 and beyond, and invert the sum by performing a
one’s complement against it. Simple, huh? Yep ... and here’s
how we’ll do it.
In your mind, group the arg variables into a 32-bit
variable with arg3 representing the most significant byte
of the 32-bit long variable and arg0 acting as the least
significant byte of the 32 bit variable. For instance, if
arg3=$03, arg2=$02, arg1=$01, and arg0=$00, that would
equate logically to a 32-bit value of $3210. Get the idea?
The same logic applies to the accumulators with a twist.
Each accumulator is a word variable and is 16 bits in
length. PICBASIC PRO doesn’t natively allow the programmer to interrogate carry situations. So, if we declared each
accumulator variable as a byte, the addition of $FF and $01
in an accumulator variable would render $100, which is
out of the bounds of an eight-bit variable. The carry out of
the addition of $FF + $01 would be lost to us as the
accumulator variable would simply roll over to $00.
The accumulators are all declared as words to trap any
byte addition overflows. Consider this. We load acc0 with
$FF. We then load arg0 with $01. The values are then
added together and stored in acc0 like this: acc0 = acc0 +
arg0. Since acc0 is a word variable, the value stored in acc0
following the addition will be $0100. Here’s where our
logic becomes magic.
We have arranged the accumulators as four logical
words with acc0 being the least significant word and acc3
as the most significant word. That’s logically 64 bits. The
magic comes in as we treat each accumulator as a byte not
as a word. The most significant byte of each accumulator
September 2007 91