# Need a sysRPL CRC16 routine. - Hewlett Packard

This is a discussion on Need a sysRPL CRC16 routine. - Hewlett Packard ; The rules are: 1. Load a 16-bit register with all 1's (FFFFh) 2. XOR the first 8-bit byte with the high order byte of the 16-bit register. Put the result in a in the 16-bit register. 3. Shift the 16-bit ...

# Thread: Need a sysRPL CRC16 routine.

1. ## Need a sysRPL CRC16 routine.

The rules are:

1. Load a 16-bit register with all 1's (FFFFh)

2. XOR the first 8-bit byte with the high order byte of the 16-bit
register. Put the result in a in the 16-bit register.

3. Shift the 16-bit register one bit to the right.

4a. If the bit shifted out to the right is one, XOR the generating
polynomial 1010 0000 0000 0001 (A001h) with the 16 bit
register.

4b. If the bit shifted out to the right is zero, return to step 3.

5. Repeat steps 3 and 4 until 8 shifts have been performed.

6. XOR the next 8-bit byte with the 16-bit register.

7. Repeat steps 3 through 6 until all bytes of the message have
been XOR'd with the 16-bit register and shifted 8 times.

8. The contents of the 16-bit register are the 2-byte CRC error check
and is added to the message most sifnificant bits first.

For a message = 0207h the resulting CRC16 is 1241h. The completed
message would then need to be formatted like this: 12 41 07 02.

I would sure appreciate some help getting this into a sysRPL program.
Just getting the hex strings into a form I can manipulate is very
tricky, and my experience isn't up to the task (yet!). Would some

Thank you!

-Dot-

2. ## Re: Need a sysRPL CRC16 routine.

On Mon, 02 Apr 2007 22:26:14 -0500, dot wrote:

[about getting a CRC-16, but for what object?]

> For a message = 0207h the resulting CRC16 is 1241h.
> The completed message would then need to be formatted
> like this: 12 41 07 02

What type of object do you mean by "message"?

Isn't the built-in hardware CRC that very same CRC-16?

However, it seems that you may want to include
only the bytes of a string (or hex string?),
without its prolog word?

A small modification of OCRC (in ML) might be able
to accomplish that (although I am not going to try

Finally, hex string concatenation via "&HXS" ?
(to append the 4-nibble CRC to the original object?)

[r->] [OFF]

3. ## Re: Need a sysRPL CRC16 routine.

hello,

did you try the CRC function in the hacker's library (256)

cyrille

"dot" wrote in message
news:7q8313521cuq2464gtkcq0c4lrjeb1ei60@4ax.com...
> The rules are:
>
> 1. Load a 16-bit register with all 1's (FFFFh)
>
> 2. XOR the first 8-bit byte with the high order byte of the 16-bit
> register. Put the result in a in the 16-bit register.
>
> 3. Shift the 16-bit register one bit to the right.
>
> 4a. If the bit shifted out to the right is one, XOR the generating
> polynomial 1010 0000 0000 0001 (A001h) with the 16 bit
> register.
>
> 4b. If the bit shifted out to the right is zero, return to step 3.
>
> 5. Repeat steps 3 and 4 until 8 shifts have been performed.
>
> 6. XOR the next 8-bit byte with the 16-bit register.
>
> 7. Repeat steps 3 through 6 until all bytes of the message have
> been XOR'd with the 16-bit register and shifted 8 times.
>
> 8. The contents of the 16-bit register are the 2-byte CRC error check
> and is added to the message most sifnificant bits first.
>
> For a message = 0207h the resulting CRC16 is 1241h. The completed
> message would then need to be formatted like this: 12 41 07 02.
>
> I would sure appreciate some help getting this into a sysRPL program.
> Just getting the hex strings into a form I can manipulate is very
> tricky, and my experience isn't up to the task (yet!). Would some
>
> Thank you!
>
> -Dot-

4. ## Re: Need a sysRPL CRC16 routine.

On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:

> did you try the CRC function in the hacker's library (256)

I wondered what that was!

Expecially since an *empty* string gives #5285 (as a system binary).

So I just looked it up in the AUR:

This command gives you the CRC of the data in
a library object or string (the CRC computation
starts on the *size* [field] of the object
and finishes 4 nibbles *before* the end of the object).

Is that what you wanted, Dot?

One could compensate for the ending point by appending
four nibbles in advance, but how can one compensate
for the starting point?

[r->] [OFF]

5. ## Re: Need a sysRPL CRC16 routine.

On Tue, 03 Apr 2007 02:12:52 -0500, "John H Meyers"
wrote:

>On Mon, 02 Apr 2007 22:26:14 -0500, dot wrote:
>
>[about getting a CRC-16, but for what object?]
>
>> For a message = 0207h the resulting CRC16 is 1241h.
>> The completed message would then need to be formatted
>> like this: 12 41 07 02

>
>What type of object do you mean by "message"?

The CRC16 is needed to satisfy the modbus message protocol. There is
a string of hex digits (depending on the modbus message) which will
need to be processed, and the resulting CRC16 values added in big
endian fashion (least significant byte then most significant byte).
The modbus message string becomes one long hex string.
>
>Isn't the built-in hardware CRC that very same CRC-16?

It does not seem to be. The test message "0207" yielded 5B04h
and the reverse string, "0702" yields 0CA9h. I need to end up with
1241h for the valid test message CRC16.
>
>However, it seems that you may want to include
>only the bytes of a string (or hex string?),
>without its prolog word?

In general, this shouldn't be that difficult to implement. I am
having trouble just getting started, though. Starting out with the
string "0207" I need to break that message into the upper byte (02h)
and the lower byte (07h). I think I could use the shift byte commands
xSRB and xRLB to do that, but I havent't gotten that far yet.
>
>A small modification of OCRC (in ML) might be able
>to accomplish that (although I am not going to try
>
>Finally, hex string concatenation via "&HXS" ?
>(to append the 4-nibble CRC to the original object?)
>
>[r->] [OFF]

6. ## Re: Need a sysRPL CRC16 routine.

hello,

to compensate for the start, just do:
->H H->S

cyrille

"John H Meyers" wrote in message
newsp.tp7usy1ynn735j@w2kjhm.ia.mum.edu...
> On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:
>
>> did you try the CRC function in the hacker's library (256)

>
> I wondered what that was!
>
> Expecially since an *empty* string gives #5285 (as a system binary).
>
> So I just looked it up in the AUR:
>
> This command gives you the CRC of the data in
> a library object or string (the CRC computation
> starts on the *size* [field] of the object
> and finishes 4 nibbles *before* the end of the object).
>
> Is that what you wanted, Dot?
>
> One could compensate for the ending point by appending
> four nibbles in advance, but how can one compensate
> for the starting point?
>
> [r->] [OFF]

7. ## Re: Need a sysRPL CRC16 routine.

On Tue, 03 Apr 2007 16:45:27 -0500, cyrille kindly wrote:

> to compensate for the start, just do:
> ->H H->S

"ABC" \->H H\->S

now we have "xxxxxABC"
(including its original prolog and length inside the string?)

Does this offer us a way to get the CRC of just the bytes "ABC"
ignoring all prolog and/or length nibbles?

Sorry I'm not catching on yet.

[r->] [OFF]

8. ## Re: Need a sysRPL CRC16 routine.

On Tue, 03 Apr 2007 13:46:00 -0500, dot wrote:

>> What type of object do you mean by "message"?

> The CRC16 is needed to satisfy the modbus message protocol. There is
> a string of hex digits (depending on the modbus message) which will
> need to be processed, and the resulting CRC16 values added in big
> endian fashion (least significant byte then most significant byte).
> The modbus message string becomes one long hex string.

>> Isn't the built-in hardware CRC that very same CRC-16?

> It does not seem to be. The test message "0207" yielded 5B04h
> and the reverse string, "0702" yields 0CA9h.
> I need to end up with 1241h for the valid test message CRC16.

What object type was each "message," how did you create it,
and what internal function did you use for CRC?
("yielded" means when you did what?)

Even if you constructed a proper 2-byte hex string as input
(which can't be done via UserRPL), neither the BYTES nor CRC
nor OCRC etc. commands can be used as-is, because they
start performing CRC on a *prefix* to those actual bytes
(BYTES starts at the prolog and goes to the end of the object;
CRC starts at the "length" field and stops 4 nibbles short
of the end of the object, if the AUR is correct -- the latter
seems to have been specially designed to compute a library CRC).

I suppose that all might be done upon hex strings
(very slowly), but it sure would be nice to have
a straightforward *ML* function for the CRC
of an arbitrary *string* (no prolog, no length,
just the string itself) -- in general, this should
also accommodate "odd-nibble" strings and general hex strings,
whose internal structures are all identical
[prolog, length in nibbles (including length field itself), data]

Note that "user" binary objects are also hex strings,
but are fixed-length (16d nibbles of data):

#123456789ABCDEF0h \->H ==> E4A20 51000 0FEDCBA987654321
#1234567h \->H ==> E4A20 51000 7654321000000000

OTOH, "ABC" BYTES DROP \->H ==> E4A20 90000 7DC9 [four nibbles only]

And of course "ABC" \->H ==> C2A20 B0000 142434

So, umm, would "ABC" in my computer have the same or different CRC-16?

[r->] [OFF]

9. ## Re: Need a sysRPL CRC16 routine.

On Tue, 03 Apr 2007 11:30:24 -0500, "John H Meyers"
wrote:

>On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:
>
>> did you try the CRC function in the hacker's library (256)

>
>I wondered what that was!
>
>Expecially since an *empty* string gives #5285 (as a system binary).
>
>So I just looked it up in the AUR:
>
> This command gives you the CRC of the data in
> a library object or string (the CRC computation
> starts on the *size* [field] of the object
> and finishes 4 nibbles *before* the end of the object).
>
>Is that what you wanted, Dot?
>
>One could compensate for the ending point by appending
>four nibbles in advance, but how can one compensate
>for the starting point?
>
>[r->] [OFF]

Well, folks ... you'll probably just laugh at my feeble sysrpl
attempts, but I seem to have the program working. The program has the
test message string "0207" built in, just for test purposes; and the
crc-16 computed result is to be concatenated to the end of the test
message in "big endian" fashion and the correct calculated
crc-16 in this case is 1241h. So the final message would be the
string "02074112"

There is a lot of hex and string manipulation going on here. The true
sysrpl experts will probably find much better ways of doing this. I
thought I would share my solution and see if there are any of you that
would care to show this novice the ropes!

-Dot-

RPL
( D:\hp49g+\Projects\ModBus\CRC.s, part of the ModBus.hpp project,
created by <> on 4/2/2007 )

INCLUDE ModBus.h

*********************************************
* CRC-16 Cyclical Redundancy Check *
* INPUTS: msg *
* OUTPUTS: msg + CRC-16 *
*********************************************

xNAME
::
xHEX ( Set Hex Mode )
xCLEAR ( Clear the display )
#1 ClrUserFlag ( Clear the carry flag )

* Initial test message for address 02 function 07 which is for a
* status request. The crc16 should be 12 41

* Dummy message string: normally from the stack on entry
"0207" ( Initial test message )
"#FFFF" DOSTR> ( Initial crc16 all 1's = FFFFh )
#4 ( Initial message length )
"#A001" DOSTR> ( CRC16 generating polynomial )
"#001" DOSTR> ( Carry bit tester )

{
LAM msg ( Message string from stack )
LAM crc16 ( Initially all 1's = FFFFh )
LAM len ( Message length )
LAM poly ( CRC16 generating polynomial )
LAM oflag ( Carry bit tester )
}
BIND

LAM msg LEN\$ ( Get message length )
' LAM len STO ( Save message length )

LAM len BINT1 ( Process each Byte in the message string )
DO
LAM crc16 ( Step 1: Load FFFFh into 16-bit
register )
"#" LAM msg INDEX@ INDEX@ #1+ SUB\$ &\$ DOSTR> ( Get msg
Byte )

bitXOR ( Step 2: XOR crc16 Register with
current Byte )
DUPDUP ' LAM crc16 STO ( Save the resulting
crc. Leave on stack )

BINT9 BINT1 ( Eight shifts required )
DO
* Step 3: Shift CRC one bit right check for carry
LAM oflag bitAND ( Examine
lsb for 1: signifies carry )
LAM oflag EQUAL ( check
for carry )
SWAP
bitSR
SWAP

* If TRUE use polynomial and save result to crc register
IT :: LAM poly bitXOR ; ( Step
4: if carry out use polynomial )
DUPDUP
' LAM crc16 STO ( Step 5:
process each byte through 8 shifts. )

LOOP

#2 +LOOP ( Step 6: Get next Byte )

* Step 7: Shift CRC16 byte order and append to message
LAM msg
LAM crc16 BINT1 BINT2 SUBHXS hxs>\$ BINT3 BINT4 SUB\$ &\$
LAM crc16 BINT3 BINT4 SUBHXS hxs>\$ BINT3 BINT4 SUB\$ &\$
' LAM msg STO

* ----- Debug code ------
xCLEAR
"Msg = " LAM msg &\$
;

10. ## Re: Need a sysRPL CRC16 routine.

On Fri, 06 Apr 2007 16:55:36 -0500, dot wrote:

[Source code]

> * Dummy message string: normally from the stack on entry
> "0207" ( Initial test message )

That looks like a *string* object
containing characters used to *represent*hex*digits*
which ultimately represents *another* object
whose CRC is to be computed, is that not so?

In that case, the built-in CRC could not possibly help,
because it operates on actual bytes in memory,
automatically computing the running CRC
as those actual bytes are accessed from memory.

I thought you meant an actual object like a hex string
(the exact same type of object as a user binary integer,
each byte itself being two hex digits' worth of bits,
and which in general can be any length); the built-in CRC
might very well be useful there, or at least
more relevant to the general idea of taking
the real CRC of the *body* portion
of real calculator objects
(without the prolog and/or count).

[r->] [OFF]

11. ## Re: Need a sysRPL CRC16 routine.

Yes, the message object is a string object representing hex digits.
In the modbus protocol, there are functions that are given hex codes
and usually a start and end address that represent a number of
registers that are to be involved in some way. So each message string
then, is the function code, and the register count as a string of hex
digits.

It's confusing until you get your mind wrapped around that. It makes
programming it interesting. The crc-16 generator is crucial to the
process, since the protocol requires it, successful communication with
modbus devices won't work without it.

Most of the documentation found on the 'net seems to have errors in
the table of intermediate results. Close inspection reveals it
though, and so I was able to work through the example until I
*finally* got it right!

-Dot-
On Fri, 06 Apr 2007 17:32:19 -0500, "John H Meyers"
wrote:

>On Fri, 06 Apr 2007 16:55:36 -0500, dot wrote:
>
>[Source code]
>
>> * Dummy message string: normally from the stack on entry
>> "0207" ( Initial test message )

>
>That looks like a *string* object
>containing characters used to *represent*hex*digits*
>which ultimately represents *another* object
>whose CRC is to be computed, is that not so?
>
>In that case, the built-in CRC could not possibly help,
>because it operates on actual bytes in memory,
>automatically computing the running CRC
>as those actual bytes are accessed from memory.
>
>I thought you meant an actual object like a hex string
>(the exact same type of object as a user binary integer,
>each byte itself being two hex digits' worth of bits,
>and which in general can be any length); the built-in CRC
>might very well be useful there, or at least
>more relevant to the general idea of taking
>the real CRC of the *body* portion
>of real calculator objects
>(without the prolog and/or count).
>
>
>[r->] [OFF]

12. ## Re: Need a sysRPL CRC16 routine.

On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:

> the "message object" is a string object representing hex digits

Then here's a little program which converts such a string
into a genuine internal "hex string" (do HOME 256 ATTACH
before program entry or transfer):

@ "123ABC" -> #123ABCh [C# 6 CBA321]
\<< SREV DUP HEAD DROP @ Empty string is invalid
H\->S #2A4Eh SB~B #5AB3h SYSEVAL \>>

At this point, a slightly modified CRC (in ML)
which should start after the prolog+length
and continue to the end of the object
might give the correct answer, and one could use &HXS
to append the 16-bit checksum to the original hex string.

To convert an internal hex string back to a string:

@ #123ABCh -> "123ABC"
\<< DUP B\->R DROP \->H 11 OVER SIZE SUB SREV \>>

Note that these programs work on any-length strings
(whereas "user binary integers" are 16 digits),
and that longer hex strings are never fully displayed
on the stack or when edited (HP48[S/G] shows "C#" notation
when edited, although it can't re-compile that notation).

The usual "back up memory first" advice
is of course strongly recommended.

Might anyone care to examine OCRC and xCRC,
and supply the modified SysRPL/ML for obtaining the CRC
of the entire body (without length field) of a hex string?

[r->] [OFF]

13. ## Re: Need a sysRPL CRC16 routine.

Hi,

"John H Meyers" schrieb im Newsbeitrag
newsp.tqek1pivnn735j@w2kjhm.ia.mum.edu...
> On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
>
> [..]
> Might anyone care to examine OCRC and xCRC,
> and supply the modified SysRPL/ML for obtaining the CRC
> of the entire body (without length field) of a hex string?
>

In the HP-48, the PCO =OCRC first calls a subroutine to get the ob's size.
The 2nd subroutine call does the actual CRC calculation,
with the following input:
A[A]: #nibbles to do CRC on
C[A]: @object_data to do CRC for
Output:
A[A]: CRC

So if someone would like to exclude the ob's length field from CRC
calculation,
it should be sufficient to insert two lines between
the first and the 2nd subroutine call, like this:

=OCRC CON(5) (*)+5
GOSUB GetSize

***
A=A-CON A,5 * Decrement nib count
C=C+CON A,5 * Increment start address
***

GOSUB DoCRC
....

HTH

Happy Easter days:-)

Raymond

14. ## Re: Need a sysRPL CRC16 routine.

Thanks for your thoughts on the string > hex and vice versa. It is an
underlying goal in my effort, though, to keep the program in a sysrpl
program.

One of the more demanding issues associated with this is the string
and hex handling. Sysrpl is not particularly intuitive on this point.
It might be useful to create stand alone programs to manipulate
strings and hex (back and forth). I haven't fully tested the program
that I submitted yesterday, and one of the things I anticipate might
happen will be the need to pad the result with leading zeros if the
result happens to be less than four characters (hex digits) long.

If the result of some message string would happen to produce the
crc-16 value of "1" (for example), then there would be a need to
prefix "000" to the crc-16 string before breaking it into the two
bytes and interposing them for the big endian result. Likewise for
other results that might require "00" or "0" to be the prefix pad
needed.

For the hex numbering system in the hp calc, it's almost like there is
a 'hex' (voodoo curse!) put on it.

I forgot to say thank you to William Graves for his dilligence and the
effort he has put into the Debug4x programming environment. I have
used Debug4x, and now with the latest version, all along. It's been a
very useful tool. So, "thank you, William!"

I have crashed it a few times, and find that recovery most of the time
is as simple as reloading the emulator with a version of the .e49 file
that I have set up for my needs (flags and all). Other times
resetting the emulator works, and a few times I had to shut down
Debug4x as it was hopelessly stalled (unresponsive program). Usually
the Debug4x lock up was related to running out of stack room; and that
was caused by an error in my programming code.

-Dot-
On Sat, 07 Apr 2007 02:42:51 -0500, "John H Meyers"
wrote:

>On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
>
>> the "message object" is a string object representing hex digits

>
>Then here's a little program which converts such a string
>into a genuine internal "hex string" (do HOME 256 ATTACH
>before program entry or transfer):
>
>@ "123ABC" -> #123ABCh [C# 6 CBA321]
>\<< SREV DUP HEAD DROP @ Empty string is invalid
>H\->S #2A4Eh SB~B #5AB3h SYSEVAL \>>
>
>At this point, a slightly modified CRC (in ML)
>which should start after the prolog+length
>and continue to the end of the object
>might give the correct answer, and one could use &HXS
>to append the 16-bit checksum to the original hex string.
>
>To convert an internal hex string back to a string:
>
>@ #123ABCh -> "123ABC"
>\<< DUP B\->R DROP \->H 11 OVER SIZE SUB SREV \>>
>
>Note that these programs work on any-length strings
>(whereas "user binary integers" are 16 digits),
>and that longer hex strings are never fully displayed
>on the stack or when edited (HP48[S/G] shows "C#" notation
>when edited, although it can't re-compile that notation).
>
>The usual "back up memory first" advice
>is of course strongly recommended.
>
>Might anyone care to examine OCRC and xCRC,
>and supply the modified SysRPL/ML for obtaining the CRC
>of the entire body (without length field) of a hex string?
>
>[r->] [OFF]

15. ## Re: Need a sysRPL CRC16 routine.

On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:

> the message object is a string object representing hex digits.

This seems to indicate the ASCII version of "modbus" (see below).

> In the modbus protocol, there are functions that are given hex codes
> and usually a start and end address that represent a number of
> registers that are to be involved in some way.So each message string then, is the function code,
> and the register count as a string of hex digits.
>
> It's confusing until you get your mind wrapped around that.
> It makes programming it interesting. The crc-16 generator
> is crucial to the process, since the protocol requires it,
> successful communication with modbus devices won't work without it.

I finally looked up "modbus" and found this:

http://en.wikipedia.org/wiki/Modbus
"Two variants exist, with different representations
of numerical data and slightly different protocol details.
Modbus RTU is a compact, binary representation of the data.
Modbus ASCII is human readable, and more verbose.
Both of these variants use serial communication.
The RTU format follows the commands/data
with a cyclic redundancy check checksum,
while the ASCII format uses a longitudinal redundancy check checksum."
[NOTE that last sentence!]

http://www.modicon.com/techpubs/toc7.html

http://www.modicon.com/techpubs/intr7.html
(says the same things about RTU vs. ASCII formats)
"When controllers are setup to communicate on a Modbus network
using ASCII mode, each eight-bit byte in a message
is sent as two ASCII characters... [and the]
Error Check Field [is] Longitudinal Redundancy Check (LRC)"

http://www.modicon.com/techpubs/crc7.html
"The Longitudinal Redundancy Check (LRC) field is one byte,
containing an eight-bit binary value.
The LRC is calculated by adding together successive eight-bit bytes,
discarding any carries, then two's complementing the result.
The eight-bit LRC (two ASCII characters) is transmitted
high order character first, followed by the low order character"

Bottom line:

Are you communicating with *binary* data (needing a binary CRC),
or *ascii* data (neededing an ascii -- and much simpler -- LRC)?

The particular "A001" CRC polynomial used in "modbus RTU"
is labeled "Reversed original CRC-16-IBM polynomial"
in http://en.wikipedia.org/wiki/Cyclic_redundancy_check
and may not be what's used in HP calcs anyway, in which case
the HP hardware CRC of only the body of a [hex]string
won't be useful, even for "modbus RTU"

[r->] [OFF]

16. ## Re: Need a sysRPL CRC16 routine.

[Backup memory *before* using anything in this post!]

On Sat, 07 Apr 2007 06:35:54 -0500, Raymond Del Tondo wrote:

> In the HP-48, the PCO =OCRC
> first calls a subroutine to get the ob's size.
> The 2nd subroutine call does the actual CRC calculation,
> with the following input:
> A[A]: #nibbles to do CRC on
> C[A]: @object_data to do CRC for
> Output:
> A[A]: CRC
>
> So to exclude the ob's length field from CRC calculation,
> it should be sufficient to insert two lines between
> the first and the 2nd subroutine call, like this:
>
> =OCRC CON(5) (*)+5
> GOSUB GetSize
>
> ***
> A=A-CON A,5 * Decrement nib count
> C=C+CON A,5 * Increment start address
> ***
>
> GOSUB DoCRC
> ...

Thanks to the above helpful analysis
(but any errors in the following due to my mangling),
here's what I've got for a CRC of [hex]string *body* only
(doesn't Kermit also need to do this for packets?)

"
(Based on CRC - ROMPTR 100 1B and OCRC )
::
CK1NoBlame
DUPTYPECSTR?
OVER
TYPEHSTR?
OR
NOTcase
SETTYPEERR
CODE
A=DAT1 A
D1+5
D=D+1 A
GOSBVL SAVPTR
GOSBVL DisableIntr
D0=A
D0+5
A=DAT0 A
D0+5
A-5 A
GOSBVL DoCRC
R1=A A
GOSBVL PUSH#
GOVLNG 05965
ENDCODE
;
@" -92 SF ASM 'CRCC' STO @ CRC of [hex]string *body* only
@ Backup memory before use!

The same should of course work also in HP48[S/G]
(except for above being specified in MASD style

I was surprised that the HP CRC starts with an initial value #0000
(rather than #FFFF), but this does seem to agree with Kermit,
as specified in the original Kermit protocol manual
(Sixth Edition, June 1986, by Frank da Cruz, see page 39)
http://www.columbia.edu/kermit/ftp/e/kproto.for

On the other hand, the Kermit manual says that they are using
"16-bit CRC-CCITT," while others dispute what that means:
http://www.joegeluso.com/software/articles/ccitt.htm
(same polynomial, but initializing to #FFFF)

Thus the above program produces #0h for an empty string,
or for any string of all null characters [0 CHR],
and also for #0h, no matter what actual length hex string.

Although #0 entered in the command line always compiles
to a 64-bit value (and R\->B also always produces a 64-bit value),
operations which are restricted to the current binary word size
(e.g. adding 0) actually result in the shortest hex string
having at least as many bits as the word size;
this was news to me, although it has always been so,
possibly hidden by the fact that different-length hex strings
starting with different number of leading zero bits
all normally display the same on the calc stack,
although the difference is displayed in SysRPL display mode
(SSTK with Jazz, or setting flag -85 in HP50/49/48Gii)

The actual length of calculator hex strings can also be discerned
by converting them to strings of hex digits, using the following
(HP50/49/48Gii only, needs HOME 256 ATTACH before entry or transfer)

@ "123ABC" <-> #123ABCh [C# 6 CBA321]
\<< DUP TYPE 10 \=/ @ Empty string is invalid
{ SREV DUP HEAD DROP H\->S #2A4Eh SB~B #5AB3h SYSEVAL }
{ \->H 11 OVER SIZE SUB SREV } IFTE \>> 'S~B' STO
@ Backup memory before use!

In HP48[S/G], \->H can be found as \->ASC in the "Hack" library
(#4C301Bh LIBEVAL, which is *not* the same as \->ASC by Bill Wickes),
so at least the binary -> string direction can be done with that tool;
converting in the other direction may be performed
by assembling (with Jazz) "HXS length reversed_digits"

[r->] [OFF]

17. ## Re: Need a sysRPL CRC16 routine.

On Mon, 09 Apr 2007 03:22:19 -0500, "John H Meyers"
wrote:

>On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
>
>> the message object is a string object representing hex digits.

>
>This seems to indicate the ASCII version of "modbus" (see below).

No, I'm using the modbus RTU format. Requires CRC error check
>

>
>Bottom line:
>
>Are you communicating with *binary* data (needing a binary CRC),

I'm using modbus RTU. The data in modbus RTU is packed two hex
characters per byte, whereas, in modbus ASCII the data is only one hex
character per byte. Additionally, the packet format in modbus ASCII
is different than modbus RTU. There is a prefixed ":" character in
the ASCII version, which uses the LRC as you pointed out. There is no
prefix character in modbus RTU and it uses the CRC with the A001h
polynomial.

I have the crc generator program working fine, although it surely can
be made more efficient. The big boys generally use a software driven
look up table, for the sake of speed. These days, with the increased
processing horsepower, I'm not sure look up tables offer much

>or *ascii* data (neededing an ascii -- and much simpler -- LRC)?
>
>The particular "A001" CRC polynomial used in "modbus RTU"
>is labeled "Reversed original CRC-16-IBM polynomial"
>in http://en.wikipedia.org/wiki/Cyclic_redundancy_check
>and may not be what's used in HP calcs anyway, in which case
>the HP hardware CRC of only the body of a [hex]string
>won't be useful, even for "modbus RTU"
>
>[r->] [OFF]

18. ## Re: Need a sysRPL CRC16 routine.

Have you tried changing the wordsize?
4; 8; ... 60; 64
_____________________________________________
"John H Meyers" wrote in message
newsp.tp8d85a7nn735j@w2kjhm.ia.mum.edu...
On Tue, 03 Apr 2007 13:46:00 -0500, dot wrote:

Note that "user" binary objects are also hex strings,
but are fixed-length (16d nibbles of data):

#123456789ABCDEF0h \->H ==> E4A20 51000 0FEDCBA987654321
#1234567h \->H ==> E4A20 51000 7654321000000000