[comp.lang.perl] 'H' and 'h' in pack/unpack.

mcr@Sandelman.OCUnix.on.ca (Michael Richardson) (05/27/91)

  I haven't been reading comp.lang.perl regularly, nor have I been
using Perl for more than a month, but I don't think this is a FAQ. 

  I have some binary data which I'd like to turn into S-records. (My
knowledge of S-records is far from complete though). I also have a
6809 assemblers that produce S-records in a format that I don't think
is appropriate for the 6809 board I want to download them to.
  I thought that Perl would be appropriate, with the use of
pack/unpack for the S-record manipulation. Checking my copy of the
Perl book, I see 
  h - A hexadecimal string, low nybble first.
  H - A hexadecimal string, high nybble first.

  (I've never seen hex where the low nybble was first..)

  I've come to the conclusion that these options are NOT for extracting
hexadecimal data to and from (binary) strings. I finally checked the
code (in doarg.c and dolist.c) but that didn't help. I'm really not
sure what that code does as it doesn't seem to have the loop in the
right place. 
  What are they for?? Is there a way to use pack/unpack to do what I
want?
  S-record format, btw, is something like this:


S113AABB00112233445566778899aabbccddeeffZZ

	S1	start of data record
	13	number of data bytes in the record + 3 (16 decimal)
	AABB	data to be loaded at address AABB (16 bit address)
	00112233445566778899aabbccddeeff	data
	ZZ	checksum of all bytes (include 13, don't include S1)


  I'm resorting to hex(), loops and sprintf("%02x",$val) right now.

  BTW: this is 4.003 as posted to comp.sources.unix.
  Thanks.




-- 
   :!mcr!:            |  The postmaster never | So much mail, 
   Michael Richardson |    resolves twice.    |  so little time.
HOME: mcr@sandelman.ocunix.on.ca 	Bell: (613) 237-5629
    Small Ottawa nodes contact me about joining ocunix.on.ca!

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (06/11/91)

In article <1991May27.043119.12173@Sandelman.OCUnix.on.ca> mcr@Sandelman.OCUnix.on.ca (Michael Richardson) writes:
:   I have some binary data which I'd like to turn into S-records. (My
: knowledge of S-records is far from complete though). I also have a
: 6809 assemblers that produce S-records in a format that I don't think
: is appropriate for the 6809 board I want to download them to.
:   I thought that Perl would be appropriate, with the use of
: pack/unpack for the S-record manipulation. Checking my copy of the
: Perl book, I see 
:   h - A hexadecimal string, low nybble first.
:   H - A hexadecimal string, high nybble first.
: 
:   (I've never seen hex where the low nybble was first..)

Me neither, but if someone had a vec($nums, $offset, 4) kind of string, they
might want it unpacked into the same order as the offsets would imply.

:   I've come to the conclusion that these options are NOT for extracting
: hexadecimal data to and from (binary) strings. I finally checked the
: code (in doarg.c and dolist.c) but that didn't help. I'm really not
: sure what that code does as it doesn't seem to have the loop in the
: right place. 
:   What are they for?? Is there a way to use pack/unpack to do what I
: want?

The hex pack/unpack options are indeed for converting a string of nybbles to 
a string of bytes, and versa vica.  There was a bug in 4.003 in packing
anything other than H*, but that's not how you'd use it here anyway.

:   S-record format, btw, is something like this:
: 
: 
: S113AABB00112233445566778899aabbccddeeffZZ
: 
: 	S1	start of data record
: 	13	number of data bytes in the record + 3 (16 decimal)
: 	AABB	data to be loaded at address AABB (16 bit address)
: 	00112233445566778899aabbccddeeff	data
: 	ZZ	checksum of all bytes (include 13, don't include S1)
: 
: 
:   I'm resorting to hex(), loops and sprintf("%02x",$val) right now.
: 
:   BTW: this is 4.003 as posted to comp.sources.unix.

Okay, I just ran this under 4.003:

    #!/usr/bin/perl

    for (0..15) {
	$bytes[$_] = $_ + ($_ << 4);
    }
    $addr = 0xaabb;
    $bytes = pack('C n C16', 0x13, $addr, @bytes);
    $csum = unpack('%8C*', $bytes);
    $bytes .= pack('C', $csum);
    $nybbles = unpack('H*', $bytes);
    print 'S1', $nybbles, "\n";;

and it printed out:

    S113aabb00112233445566778899aabbccddeeff70

I'm presuming you really wanted a checkSUM and not a checkXOR.

Larry