Subject: HP 48SX GROB Format

Date: 12 Mar 90 19:08:06 GMT
Organization: Hewlett-Packard Co., Corvallis, OR, USA
Lines: 32

Many people seem interested in working with HP-48SX graphics objects (grobs)
on their PC's.  To save you some trouble, here is the binary format:

<prolog><length><height><width><data....>

where the first four are 5-nibble fields:

prolog = grob object identifier = 02B1E
length = distance in nibbles from start of length field to (just past) the
         object end = F + # of data nibbles
height = height in pixels
width = width in pixels

To make life more interesting, the fields are written backwards (this is
how the CPU reads memory), so e.g. the prolog is written E1B20.

The data starts at the upper left corner of the grob and proceeds
left-to-right, top-to-bottom.  But--each pixel row must be a integral
number of bytes (even number of pixels).  The data may therefore be
padded with garbage bits to satisy this.  And--each nibble is written
backwards compared to the LCD order, so the leftmost pixel in a group
of four is the least-significant bit of the stored nibble.

A blank screen-sized grob looks like this:

E1B20|F8800|04000|38000|000000.... (2176 0'S),

where the |'s are for legibility.  The width of 83h = 131d pixels needs
17 bytes or 34 nibbles, so 40h = 64d rows gives 34x64 = 2176 nibbles of
data. 2176 + 15 = 2191d = 88Fh, which is the length field content.
If the upper-left-most pixel was turned on, the first data nibble would
be a 1.

Date: 25 May 90 19:23:08 GMT
From: rayde@hpcvia.UUCP  (ray_depew)
Organization: Hewlett-Packard Co., Corvallis, Oregon
Subject: Re: HP28--->HP48 CHARACTER STRING CONVERSIONS
Message-Id: <31210026@hpcvia.CV.HP.COM>
References: <9709@hydra.gatech.EDU>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com

> I'm trying to write a program to convert an hp28 graphic character
> string into an hp48 GROB.  I understand how the 28s CHR string works
> but I don't know much about the 48's GROB (the manual doesn't help
> much).

> DELANO,ANDREW DOUGLAS

(I didn't invent them, I just like playing with them.)

Bill W. posted a great bit-level explanation of grobs in here a little
while ago.  But if you want to play with them on your own, here's an easier
way to think of them.

If you put a grob in Level 1 and press [Darrow], you will see something in
the command line like

     GROB 131 64 nnnnnnn....

(assuming you have enough memory and the grob's not too big).
The first number is the width, or number of pixel columns in the grob.
The second number is the height, or number of pixel rows.
The nnnnnnn.... is the hex bitmap representing the picture.

The pixel values in the hex bitmap are reversed from what you think they
should be.  For example, if you had a row like this (1 is "on", 0 is "off")

1 1 0 0 1 0 0 0

you would think that the bit values should go from MSB on the left to LSB
on the right, like this:


bit value   8 4 2 1 8 4 2 1
------------------------------
hex value   A       8
------------------------------
status      1 1 0 0 1 0 0 0         and therefore hex "A8"


but the bit values actually go from LSB on the left, to MSB on the right:

Bit value   1 2 4 8 1 2 4 8
------------------------------
Hex value   3       1
------------------------------
status      1 1 0 0 1 0 0 0         and therefore hex "31".


In addition, the HP48SX likes to pretend that each row is a multiple of 8
pixels.  It makes internal bookkeeping easier.  In other words, a 3-pixel
row will take up as much memory as an 8-pixel row.  If you only use 3 pixelsm
what happens to the other 5 digits in the number?  The HP-48SX *usually*
zeroes them out, but I would guess they're free for you to play with.

You can enter grobs directly via the command line.  Sometimes I find this
easier than going through the menus.  Examples follow.  Type everything
as shown on one line and without quotes.

To create a blank 3x3 grob, type

     GROB 3 3 0 [ENTER]

You will see "Graphic 3x3" on Level 1.  Press [Darrow] to review it, and
you will see that the HP48SX has filled in the rest of the grob for you.
You should see

     GROB 3 3 000000

on the command line.  (Press [ATTN] to get out of the CL)

To create a # symbol, type

     GROB 5 5 A0F1A0F1A0 [ENTER]

You will see "Graphic 5x5" on Level 1.  Press [PRG] |DSPL| |PICT| [STO]
[Larrow] to see your creation.

$DRIFT ON

I use graphics so much that I keep an
automated version of this in my home directory.  The program is

     \<< PICT STO GRAPH \>>

and I store it as 'SEE'.  That's easy to type in, and I can get at it from
any directory.  A variation on it is

     \<< PICT STO { } PVIEW \>>

I think John Peterson at BYU came up with that one?  It works nicely too,
especially with really big grobs that you have to scan around.  He calls it
'PVER', and it comes with the gorgeous BYU grob offerings on the HP BBS.

$DRIFT OFF

When you transfer grobs between a PC and the HP48SX, if you use ASCII mode,
the 48 has to translate the grob into a string.  Grobs do use up a ton of
memory.  Binary uses up much less, but I haven't figured out how much yet.

You needn't restrict yourself to grobs <= 131x64.  Think of the 48's
display as a window onto a much bigger bitmap.  You can create grobs as
big as your 48's memory can handle (bring on the 128K RAM cards, for which
there was supposed to be "no demand"!).  WHen I do serious plotting on my
48, I create 200x200 and 200x300 grobs on the command line, then I get
into the PLOT application and draw/annotate a decent graph, not the default
low-res ones you got on the HP28, HP42 and 131x64 HP48SX.
They look especially impressive when you upload them to your PC or Mac,
convert them to the proper format and paste them into your MSWord document.

(Note to ChemE's:  unit ops labs will NEVER be the same!)

This should be enough information to help you write your 28-to-48 graphics
conversion program.  When you finish it, please post it on the BBS.  I
think many people will find it extremely useful.

Ray Depew
HP InkJet Components Operation
rayde@hpcvia.cv.HP.COM
---------------------------------------------------------------
disclaimers:
I've never used a 28C/S, but I was glad they included the graphics "string".
I did write a nice DRAW program on my HP42S.
I don't work in calculators; I just use them, same as you.
I don't speak officially for HP.
----------------------------------------------------------------

Date:         Wed, 28 Mar 90 11:22:00 EST
Reply-To:     HP-28 -  HP-28C and HP-28S Calculators <HP-28@NDSUVM1>
Sender:       HP-28 -  HP-28C and HP-28S Calculators <HP-28@NDSUVM1>
From:         "Achh, Who wants to set pers's anyway?" <IUGC500@INDYVAX.BITNET>
Subject:      Grob Format's

Okay, for those of you with 48sx's, and are curious....
This is what i've figured out about the format of GROB's

An example would probably be the easiest.

say you've got a
Graphic 7 x 3 that looks (internally) - > GROB 7 3 B2B2B2

it looks on the screen (1=pixels on, 0=pixels off)
1101010
1101010
1101010
                (yes, I know its a dumb object but it serves my point)

the GROB's are padded with zero bits untill they are a even multiple of 8
so that it comes out to be a even byte, so that each line gets at least
one complete byte.

now when they're put on the screen, they're not treated as bytes, but as
4 bit nybbles, with the LSB on the left, and MSB to the right (similar
to the way Apple //'s did they're display memory)

so that one line of our graphic object (in binary is)
10110010
if you grab the first four bits, turn them around, and display them, and
continue to the next four it works out ie.
1  0  1  1  0  0  1  0
|  |  |  |  |  |  |  |
|  |  |  |  |  |  |  --- Bit #5
|  |  |  |  |  |  ------ Bit #6
|  |  |  |  |  --------- Bit #7 (right most display'd bit)
|  |  |  |  ------------ Padded Zero Bit
|  |  |  --------------- Bit #1 (left most display'd bit)
|  |  ------------------ Bit #2
|  --------------------- Bit #3
------------------------ Bit #4

I think this explains them well enough that you should be able to convert
28S LCD screens to 48SX GROB's.

For those of you who don't know, 28S lcd screens are created by taking
a vertical column of 8 dots, converting it into a binary # with
LSB at top, and MSB at bottom, and then converting the #, into its character
equivilent. (ie convert binary to decimal and then use the CHR function)

I'm also going to post this to comp.sys.handhelds to.....

Hope this explains them a bit
David Holland
IUGC500@INDYVAX.BITNET

PS- this could be slightly messed up, bit it seems to work.

