typo/overstatement in HP-16c manual?



#18

On page 32, the HP-16c manual states:

Quote:
A current word size smaller than 8 will limit the size of the number you can enter to stipulate a new word size; but you can always enter 0 f WSIZE to set a word size of 64.

That seems to be overstating matters. 7 bits is enough in signed mode to enter any valid word size (0-63) and 6 bits is enough in unsigned mode.

I took a doubletake when I first read this, until I realized that they were talking about entering 64 (instead of 0) in signed mode.


#19

Quote:
7 bits is enough in signed mode to enter any valid word size (0-63)

The valid word sizes are 1 through 64; it is not possible to actually set the word size to zero. Representing 64 as a signed integer requires 8 bits; 7 bits only gives you the range -64..63 (two's complement) or -63..63 (one's complement).


#20

Quote:
The valid word sizes are 1 through 64; it is not possible to actually set the word size to zero.

It is not possible to set the word size to zero bits, but it is certainly possible to do a set word size of 0!

Doing 0 WSIZE sets the word size to 64; it is exactly equivalent to 64 WSIZE except that you can do it even if the word size is 1 bit. That's how you can recover from an ill-advised word size setting.

Therefore, you only need the range 0..63 to set all possible word sizes. 7 bits suffices for signed, and 6 bits suffices for unsigned.

As a side note, word size 1 in signed mode means that only 0 and -1 are valid numbers.


#21

The argument to WSIZE is the desired word size. Zero is handled as a special case alias for 64. Nevertheless, representing a valid word size requires seven bits (unsigned) or eight bits (signed), which is what the quoted paragraph is describing. Zero is not a valid word size; it is just a valid argument to the WSIZE function.


#22

Please turn to page 32 of the HP-16c manual and consider the entire paragraph in question:

Quote:
A current word size smaller than 8 will limit the size of the number you can enter to stipulate a new word size; but you can always enter 0 f WSIZE to set a word size of 64. (You can then set any word size.) Error 2 results if you attempt to specify a word size larger than 64.*

Thus, the manual is talking about the need to use a two-step process to recover from setting the word size smaller than 8: 0 f WSIZE then n f WSIZE where n is the desired new word size. It is not talking about "representing a valid word size".

This two-step process is completely unnecessary in the case of a current word size of 7, and in the case of a current word size of 6 if the mode is unsigned. There is no need for the additional bit because 0 is treated as equivalent to 64, and works no matter what the word size may be.

You only need to use the two step process if:

. signed, current word size 6, desired new word size 32 or greater
. unsigned, current word size 5, desired new word size 32 or greater
. signed, current word size 5, desired new word size 16 or greater
. unsigned, current word size 4, desired new word size 16 or greater
. signed, current word size 4, desired new word size 8 or greater
. unsigned, current word size 3, desired new word size 8 or greater
. signed, current word size 3, desired new word size 4 or greater
. unsigned, current word size 2, desired new word size 4 or greater
. signed, current word size 2, desired new word size 3 or greater
. current word size 1

Note: "3 or greater" is not a typo. If the desired word size is 2 you don't need to do anything!

As for whether zero is (or is not) a valid word size, without referring to the microcode (have you?), there is no particular reason to believe that "0 is handled as a special case alias for 64." It is quite possible that 64 is the special case for zero in the microcode. Consider, for example, a 6-bit register which holds the "word size restriction", where zero means "unrestricted".

Regardless of what how the microcode implements it, the effect is the same: the range of values accepted by WSIZE is 0..64, and 0 and 64 are functionally identical.

Go ahead and argue semantics if you wish; the fact is that in terms of keystrokes entered the manual overstates the need to do the two-step process.


#23

Speaking of HP-16c microcode, does the source exist anywhere? All I can find is an object file. I'm not interested in disassembling it myself just to determine how WSIZE is implemented.


#24

Quote:
Speaking of HP-16c microcode, does the source exist anywhere?

Unknown, but I suspect not. There have been stories from seemingly reliable sources that the original HP-12C source code was lost, but other seemingly reliable sources state otherwise. Possibly it was lost and later recovered. A lot can be lost when responsibility for a product line shifts between different corporate divisions scattered across the world three times after the product was discontinued.

The survival of HP-16C source code seems less likely than that of HP-12C source code, since the former has not had any commercial value for HP in more than 16 years.

But in any case, if the HP-16C source code still exists, it's relatively unlikely that copies will be made available to the general public. AFAIK, the only HP-16C object code publicly available is the modified version I released with Nonpareil.

#25

Quote:
Go ahead and argue semantics if you wish;

OK, I don't mind killing another five minutes.

Suppose I design a product in which feature X has limitation Y, so I add a subfeature Z that effectively changes the limitation to Y2. I would write in the manual an explanation that in order for the user to circumvent limitation Y, the subfeature Z is provided. It wouldn't make sense to say that in order to circumvent limitation Y2, the subfeature Z is provided, because the limitation Y2 doesn't even exist without subfeature Z.

For the HP-16C:

feature X is user-adjustable word size of 1 to 64 bits by way of the WSIZE function

limitation Y is that a minimum of 8 bits are required (in signed modes) to represent any valid word size (in signed modes)

subfeature Z is the ability to use the value 0 to specify a word size of 64

limitation Y2 is that a minimum of 7 bits are required (in signed modes) to represent any valid input to the WSIZE function when taking advantage of subfeature Z.

Plugh!


Edited: 29 Oct 2005, 12:38 a.m.


#26

Well, the argument would probably be answered by disassembling the 16c microcode. I suspect that if that is done, it will be seen that the WSIZE value is actually between 0 and 63, and 64 is supported by a special hack (both for input and display with status).

0..63 is what makes sense. 64 is what some PHB would have forced the microcoder to do.


#27

If the processor were particularly optimized for six-bit operations, you would likely be right. But it's not; it's optimized for operations on multiples of four bits, for obvious reasons. So I suspect that it internally uses the true count of 1..64.

If the WSIZE were internally stored as 0..63, as you suggest, everywhere that loops over the bits would have to special-case 0 and convert it to 64 for the loop counter. And everywhere that multiplies by the WSIZE/4 would have to do likewise.

I haven't yet located the particular code that is responsbile for WSIZE, but I'm working on it. At this point we're both just guessing. I'll post an update here when I find it, but it might not be for a while.

Eric


#28

It doesn't have to be optimized for 6-bit operations. Rather, it's a matter of how the WSIZE value is stored. You're probably right that it is stored in two 4-bit nybbles.

However, in the early 1980s memory was still quite expensive, and register memory was particularly expensive. I doubt that they would have wasted two bits like that.

It seems more likely to me that they used six bits for WSIZE and two bits for something else. They could have offset by 1, so 0..63 meant 1-64, which would match your idea of 0 being a special hack, but still not wasted two bits.

My guess is that they had 0 mean 64 (= "don't apply a WSIZE, use the full 64-bits"). Rather than "convert to 64 for the loop counter" as you suggest; suppose that WSIZE was a masking operation, and in the case of WSIZE=0 there was no masking.

One way to check for this would be to do some timing tests of 64 bit vs. other bit sizes. If my guess is correct, we probably would see 64 be faster.

As for the other two bits, a possible use was for the base. You could only set the base to one of four values (2, 8, 10, 16). So, that byte would effectively be the display/input mode.

I'm definitely interested in the result of the microcode analysis.

This also suggests a useful hack for nonpareil -- the ability to patch memory or a register and see what happens. If they really use a full byte for the word size, I wonder what happens if the WSIZE is forcibly set to 72.


#29

From the HP-35 through the HP-41C, HP routinely stored internal values using space rounded up to the next multiple of 4 bits. Most of their calculators that had flags stored each flag (1 bit) in its own 4-bit digit, though the 41C did not since it had so many. And most of the models that had two or three display modes (FIX, SCI, ENG) used 4 bits to store that, or in some cases, 8 bits.

Your masking idea is plausible, though 0 still wouldn't be "no masking". It's a 56-bit machine, so they still have to mask the high part. In fact, they go through all sorts of gyrations to deal with the high part of each stack location.

The low 56 bits of X is stored in the CPU's M and/or N registers.
The low 56 bits of Y, Z, T, and L are stored in memory locations
0x00 through 0x03. The high 8 bits of all of these are stored
together in location 0x07:

          CSC LL TT ZZ YY 0 XX 


Where CSC is the Cold Start Constant 0xEAE, and the digit shown
as zero might be used for something, but is more likely always zero because it makes extracting and inserting the X extension more efficient, and they obviously have to do that a lot. The Nut processor has a defined field for digits 0 though 2 (the rightmost three) used for dealing with the exponent and sign. To insert and extract the other fields, they have to do rotations and pointer operations.


#30

Sheesh, so the 64-bit limitation is complete arbitrary!

At the time the HP-16c came out, 36-bit systems (with 72-bit doublewords) were still very much alive, and there were microcode engines which used word sizes of 80 bits. They could have used another word for extension and supported 72 bits, or just do the simple thing and use a doubleword for each register (thus up to 112 bits).

Having played with a 16c for a while now, I've concluded that it is most useful in doing 16 and 32 bit hex calculations and conversions to/from decimal. It does that quite well.

In floating point, it is little more than a four function calculator. Ditto for decimal. In octal and especially binary, the small (8-digit) display forces you to use scrolling too much.

That probably explains why sales were poor. Had I looked at it at the time, my first reaction would have been that with all the physical space they had on top it could have had a display with many more digits of precision. Two more precious digits would have been available if hex, oct, bin, and dec were annunciators. With all the need for scrolling, having it be a shift was a drag. etc. etc.

Of course, they were limited by the 10c series form factor and display; and in particular they couldn't change annunciators. IIRC, the series was all the same hardware, with just different paint on the keytops and different microcode, right?

Interestingly, the HP-33s is a 36-bit machine, although it limits the word size to 36 bits. It's interesting to think what kind of programmer's calculator can be done with that platform, given the two-line display and additional keys

#31

Much of the 16C's general state is stored in the register at hardware location 0x06. Thus far I've only seen the leftmost 8 digits of this register have non-zero values. The encoding is:

    R S D M WW FF 000000

R is the radix setting: 0=hex, 2=oct, 4=bin, 8=dec, c=float
(the floating point digit setting is stored in the
processor's G register, with values 0 through 9 or
A for "FLOAT ."

S is the sign mode: 0=unsigned, 1=one's comp, 2=2's comp

WSIZE is stored in the D and M digits.

D is the number of digits unused at the left end of the word
M is the mask of the bits used in the leftmost used digit of the word (always f, 7, 3, or 1)

Examples:

      WSIZE (decimal)    DM
--------------- --
64 0f
63 07
62 03
61 01
60 1f
59 17

56 2f

39 67

1 f1

WW is the window position, as an 8-bit binary number indicating
displayed digits shifted to the left. WINDOW 0 through 7 are
represented as 00, 08, 10, 18, 20, 28, 30, and 38 (hex). Using
the arrow keys, you can get any window position from 00 through ff.
(Shortly after I got my first 16C in July 1982, I verified that
there are 256 window positions in binary mode, and that the arrow
key will wrap from position 255 back to 0. I never tried it in
other radix modes.)

FF is the flags, binary xx54 3210


#32

Quote:
WSIZE is stored in the D and M digits.

D is the number of digits unused at the left end of the word M is the mask of the bits used in the leftmost used digit of the word (always f, 7, 3, or 1)


That settles it. You're right, then; the word size is 1..64 and 0 is a special hack. My consolation is I guessed that the WSIZE is not stored as 1..64 in an 8-bit value. I agree that the format that it uses makes sense, and it does use all 8 bits.

Thank you for hunting up that information.

It's interesting how the R and S data is stored.

Are you certain that 0=hex instead of 1=hex? That means that instead of testing the 0x1 bit being set, it would have to test the 0xe bits being unset. Or maybe it tests for R being zero?

Even more interesting is c=float; this suggests that it first tests for decimal and then uses the 0x4 (nominally binary) flag to do floating.

What happens if you try various invalid states, e.g. R=1, S=3, etc.?


#33

Quote:
Are you certain that 0=hex instead of 1=hex?

Yes. I went through about a zillion (technical term) combinations of mode settings, dumping the internal registers after each, and zero definitely is hex. I was rather surprised at the encoding, but it must make sense for some reason that isn't immediately apparent. I think only the display code uses the radix, and I haven't yet studied that code at all.

Quote:
What happens if you try various invalid states, e.g. R=1, S=3, etc.?

I haven't had time to try any. If you care to try it with Nonpareil, here's what you do:

  1. Get the simulated calculator into the state you want base your modifications to
  2. Save the state. If you use "Save" it will by default go into the ".nonpareil" directory under your home directory (no leading dot on Windows), with a name like 16C.nst. You can use "Save as" to save the state file anywhere you like.
  3. The save file is a gzipped XML file, and the XML is not formatted for human consumption, so you can decompress and format it by a command like "zcat 16C.nst | xmllint --format - >16C.xml"
  4. Make your changes to the XML file using either a text editor or an XML editor. For playing with the 16C mode settings, you're looking for a line like:
        <loc addr="006" data="000f0000000010"/>
    where the data attribute consists of the 14 hexadecimal digits of internal memory location 0x06.
  5. Rename/move the resulting file so that it has a ".nst" extension. It is not necessary to gzip it, as Nonpareil will happily read an uncompressed XML file. Note that the Load command in Nonpareil uses the standard GTK file selection dialog, which will usually not let you select files in hidden directories.

It's a bit cumbersome, but it's a lot easier than trying to do this stuff on the real hardware. Though there's always the danger that the simulator might have bugs and behave differently than the real hardware in subtle ways. However, I think Nonpareil's simulation of the Nut processor used in the 41C and Voyager families is pretty well shaken out, with the exception that I probably haven't matched all of the bugs in the real chips. The programmers at HP generally didn't rely on the bugs, because they new that future hardware revisions could eliminate them.


#34

Thanks for the information.

Quote:
I think Nonpareil's simulation of the Nut processor used in the 41C and Voyager families is pretty well shaken out, with the exception that I probably haven't matched all of the bugs in the real chips. The programmers at HP generally didn't rely on the bugs, because they new that future hardware revisions could eliminate them.

I think that you're doing the right thing here by not worrying excessively about a bug-for-bug reimplementation.

I don't see much point in reimplementing a processor bug in an emulator unless it is necessary for the correct operation of the software. I agree with the general observation that programmers avoid relying upon processor bugs since future hardware revisions can eliminate them. The main benefit of intentionally using a bug is for code to detect and report a particular hardware revision.

More importantly, if Nonpareil is used as part of a platform to reimplement a physical Voyager family calculator, I think that most of us would prefer one that works as if it were an updated model from HP as opposed to one that slavishly reimplements bugs from the 1980s.


Possibly Related Threads...
Thread Author Replies Views Last Post
  Bought a 16C to compensate a little Eelco Rouw 23 924 12-07-2013, 01:26 PM
Last Post: Eelco Rouw
  [HP Prime] Typo in English Users Guide Timothy Roche 2 174 11-15-2013, 04:10 AM
Last Post: dg1969
  Shiny new 16C! Keith Midson 7 365 10-27-2013, 02:22 AM
Last Post: Keith Midson
  Joys of eBay: HP-32S, HP-32SII, HP-42S, HP-16C, ... Sasu Mattila 7 334 09-23-2013, 04:39 PM
Last Post: Julián Miranda (Spain)
  Typo in wp34s PRINTED manual (not pdf) Barry Mead 3 207 08-05-2013, 04:21 PM
Last Post: Walter B
  Typo in wp34s Manual Barry Mead 12 438 07-23-2013, 07:23 AM
Last Post: Paul Dale
  HP-16C simulator fhub 12 543 06-30-2013, 10:14 PM
Last Post: Robert Prosperi
  Program for HP-16c... Leonid 9 424 06-07-2013, 08:51 PM
Last Post: David Hayden
  HP 11C/12C/15C/16C case Philippe Cairic 4 284 11-06-2012, 06:04 PM
Last Post: Matt Agajanian
  Understanding HP-16C integer division Jimi 18 739 10-16-2012, 09:13 PM
Last Post: Eddie W. Shore

Forum Jump: