[comp.sys.handhelds] usrlib format

alo@kampi.hut.fi (Antti Louko) (07/27/90)

I have done some reverse-engineering to find out the library format.
Everything else seems to be quite clear but I don't have any idea how
the checksum is calculated. This checksum appears to be 16-bit.
One-bit change in the library contents seem to change whole checksum.

	Antti Louko (alo@hut.fi)
	Helsinki University of Technology
	Computing Centre
	Otakaari 1
	SF-02150, Espoo
	FINLAND
	tel. work +358 0 4514314
	telefax   +358 0 464788

alonzo@microsoft.UUCP (Alonzo GARIEPY) (08/04/90)

alo@kampi.hut.fi (Antti Louko) writes:
> I have done some reverse-engineering to find out the library format.
> Everything else seems to be quite clear but I don't have any idea how
> the checksum is calculated. This checksum appears to be 16-bit.
> One-bit change in the library contents seem to change whole checksum.

The HP 48 has a hardware CRC.  Every time you read a nibble from memory
the 16 bit CRC at address #00104 is updated.  Checksumming a block of
memory (as the BYTES command does) involves zeroing that location and
then reading the entire block of memory.  The CRC hardware picks the data 
right off the bus.  Among other things, this means you can checksum a block 
of memory at the same time you move it.  Libraries use the same CRC.  You
must disable interrupts if you do this from machine language.

Experiment
----------
Since Kermit also needs a CRC, my guess was that they may be using the Kermit 
CRC throughout.  Here is a fragment of C code that calculates the type-3 
Kermit checksum.  It is based on the CRC-CCITT polynomial x^16+x^12+x^5+1.

crc()
{   	/* Compute a nibble-oriented type-3 Kermit block check.             */
    	/* This algorithm was invented by Andy Lowry of Columbia University */
	unsigned n, crc;  

	crc = 0;
	while (getnibble(&n))
		crc = (crc >> 4) ^ (((n ^ crc) & 0x0f) * 0x1081);

	return (crc);
}

Alas, this doesn't seem to correspond to the HP 48 hardware CRC.  

HP, can you post a C program fragment that calculates a checksum 
equivalent to the one in hardware?

Thanks,

Alonzo Gariepy
alonzo@microsoft

kevinc@tekig5.PEN.TEK.COM (Kevin E Cosgrove) (08/06/90)

In article <56291@microsoft.UUCP> alonzo@microsoft.UUCP (Alonzo GARIEPY) writes:
>alo@kampi.hut.fi (Antti Louko) writes:
[lots of stuff deleted]
>HP, can you post a C program fragment that calculates a checksum 
>equivalent to the one in hardware?

Speaking of checksum source code, would anyone know where to get a GOOD
C source code package for checksumming in general?

Thanks...

Kevin Cosgrove <tektronix.TEK.COM!tessi!escargot!cathouse!kevinc>

chekmate@athena.mit.edu (Adam Kao) (08/06/90)

NOTE1: I am posting this from a friend's account - please respond to the
       address below, and not anything from the headers.

NOTE2: This is the first time I've posted something myself.  Please forgive
       my impending ineptness.


Alonso Gariepy writes:

>Since Kermit also needs a CRC, my guess was that they may be using the Kermit 
>CRC throughout.  Here is a fragment of C code that calculates the type-3 
>Kermit checksum.  It is based on the CRC-CCITT polynomial x^16+x^12+x^5+1.
>
>crc()
>{   	/* Compute a nibble-oriented type-3 Kermit block check.             */
>    	/* This algorithm was invented by Andy Lowry of Columbia University */
>	unsigned n, crc;  
>
>	crc = 0;
>	while (getnibble(&n))
>		crc = (crc >> 4) ^ (((n ^ crc) & 0x0f) * 0x1081);
>
>	return (crc);
>}
>
>Alas, this doesn't seem to correspond to the HP 48 hardware CRC.  
>

Ah, but I think that it actually does.  A while back, I set out to determine
the HP48's CRC algorithm.  I wrote a machine language routine to run the CRC
portion of the BYTES command on an arbitrary address and length of nibbles.
Then, by examining various nibble patterns and their CRCs, I came up with the
following algorithm:

unsigned int crc(long addr, int len)
{
	unsigned int crc = 0;
	unsigned int new_nib;

	while (len--) {
		new_nib = (crc ^ nib(addr++)) & 0xf;
		crc = crc >> 4;
		crc ^= (new_nib | (new_nib << 7) | (new_nib << 12));
	}
	return crc;
}

If you squint carefully, I think they turn out to be equivalent - I just
coded bit-shifts instead of a multiplication.

There is one important thing to note, however, which may explain why Alonso
didn't think this was the correct CRC algorithm.  The CRC that is stored
with a library object does not include the five prolog nibbles 04B20.  It
starts with the library length field, just after the prolog.



Dave Kaffine
For now, try email at    dkaffine@east.sun.com