Post Reply 
Funny HP-16C quirk
11-06-2024, 04:33 PM
Post: #1
Funny HP-16C quirk
Try this simple 16C program in either float or integer mode:

Code:
001-   21  A      GSB A   
002-43,22, A      LBL A   
003-      31      R/S     

Run it with [RTN] [R/S] then switch to program mode.
You will see the step 0 as:

000-       F

Was it already known? Or other similar quirks?

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
11-06-2024, 08:02 PM (This post was last modified: 11-06-2024 08:03 PM by ThomasF.)
Post: #2
RE: Funny HP-16C quirk
(11-06-2024 04:33 PM)J-F Garnier Wrote:  Was it already known? Or other similar quirks?

J-F

Hi J-F,

Never seen that before!

It works the same if you end a program with similar steps, SST to the GSB line, then SST in run mode until R/S.
Seems to be related to a pending return (i.e. must end with R/S and not RTN).

Same on the go16 Android app, so ROM related, and maybe would be possible to track down if the code is disassembled ... Wink

Cheers,
Thomas

[35/45/55/65/67/97/80 21/25/29C 31E/32E/33E|C/34C/38E 41C|CV|CX 71B 10C/11C/12C/15C|CE/16C 32S|SII/42S 28C|S 48GX/49G/50G 35S 41X]
Find all posts by this user
Quote this message in a reply
11-08-2024, 09:08 AM
Post: #3
RE: Funny HP-16C quirk
(11-06-2024 08:02 PM)ThomasF Wrote:  Same on the go16 Android app, so ROM related, and maybe would be possible to track down if the code is disassembled ... Wink

Interesting quirk. It's the same on a 15C CE thrown into 16C mode.

Current daily drivers: HP-41CL, HP-15C, HP-16C
Find all posts by this user
Quote this message in a reply
11-08-2024, 02:42 PM
Post: #4
RE: Funny HP-16C quirk
We can check how the program lines are represented internally:

   000-
0xf000bffffff000

   001-  21 A       ; GSB A
0xf001bff21fa000

   002-4322 A       ; LBL A
0xd002b4322fa000

   003-    31       ; R/S
0xf003bffff31000

   000-     F
0xf000bffffff000

We can see that the line 000 is represented identically in both cases.
This is an excerpt from the comparison (side-by-side of the differences) when running P/R in both cases:
Code:
0-bf8  038   c = data                   reg['C'] = 0x00000000000000     addr = 255                 |    0-bf8  038   c = data                   reg['C'] = 0x000000003fc000     addr = 255
0-bf9  3e0   rtn                                                                                        0-bf9  3e0   rtn
0-804  311   ? nc gsb                                                                                   0-804  311   ? nc gsb
0-805  008     2c4                                                                                      0-805  008     2c4
0-2c4  0ae   acex all                   reg['A'] = 0x00000000000000     reg['C'] = 0xf00000        |    0-2c4  0ae   acex all                   reg['A'] = 0x000000003fc000     reg['C'] = 0xf00000
0-2c5  1d8   cmex                       reg['C'] = 0x000000000000fd     reg['M'] = 0xf000000000    |    0-2c5  1d8   cmex                       reg['C'] = 0x000000000003fc     reg['M'] = 0xf000000000
0-2c6  0ae   acex all                   reg['A'] = 0x000000000000fd     reg['C'] = 0x000000        |    0-2c6  0ae   acex all                   reg['A'] = 0x000000000003fc     reg['C'] = 0x000000
0-2c7  05e   c = 0 s                    reg['C'] = 0x00000000000000                                |    0-2c7  05e   c = 0 s                    reg['C'] = 0x000000003fc000
(…)
0-bf7  270   dadd = c           addr = 255                                                              0-bf7  270   dadd = c           addr = 255
0-bf8  038   c = data                   reg['C'] = 0x00000000000000     addr = 255                 |    0-bf8  038   c = data                   reg['C'] = 0x000000003fc000     addr = 255
0-bf9  3e0   rtn                                                                                        0-bf9  3e0   rtn
0-a16  0ee   bcex all                   reg['B'] = 0x00000000000000     reg['C'] = 0x000000        |    0-a16  0ee   bcex all                   reg['B'] = 0x000000003fc000     reg['C'] = 0x000000
0-a17  04e   c = 0 all                  reg['C'] = 0x00000000000000                                     0-a17  04e   c = 0 all                  reg['C'] = 0x00000000000000
0-a18  270   dadd = c           addr = 0                                                                0-a18  270   dadd = c           addr = 0
0-a19  0ee   bcex all                   reg['B'] = 0x00000000000000     reg['C'] = 0x000000        |    0-a19  0ee   bcex all                   reg['B'] = 0x00000000000000     reg['C'] = 0x000000
0-a1a  2ee   ? c != 0 all                                                                               0-a1a  2ee   ? c != 0 all
0-a1b  07b   jnc +0xf                                                                                   0-a1b  07b   jnc +0xf
                                                                                                   >    0-a1c  178   c = regn 5                 reg['C'] = 0xf000bffffff920     addr = 5
                                                                                                   >    0-a1d  33c   rcr 1                      reg['C'] = 0x0f000bffffff92
                                                                                                   >    0-a1e  0cc   ? st = 1 10
                                                                                                   >    0-a1f  23d   ? nc gsb
                                                                                                   >    0-a20  01c     78f
                                                                                                   >    0-78f  05a   c = 0 m                    reg['C'] = 0x00000000000f92
                                                                                                   >    0-790  05c   pt = 4             pt = 04
                                                                                                   >    0-791  0d0   lc 3                       reg['C'] = 0x00000000030f92
                                                                                                   >    0-792  033   jnc +0x6
                                                                                                   >    0-798  3d0   lc f                       reg['C'] = 0x0000000003ff92
                                                                                                   >    0-799  013   jnc +0x2
                                                                                                   >    0-79b  2fc   rcr 13                     reg['C'] = 0x000000003ff920
                                                                                                   >    0-79c  330   cxisa                      reg['C'] = 0x000000003ff074
                                                                                                   >    0-79d  0f6   bcex xs                    reg['B'] = 0x00000000000000     reg['C'] = 0x0000000
                                                                                                   >    0-79e  05a   c = 0 m                    reg['C'] = 0x00000000000074
                                                                                                   >    0-79f  056   c = 0 xs                   reg['C'] = 0x00000000000074
                                                                                                   >    0-7a0  3e0   rtn
                                                                                                   >    0-a21  0cc   ? st = 1 10
                                                                                                   >    0-a22  24d   ? c gsb
                                                                                                   >    0-a23  01d     793
                                                                                                   >    0-a24  2d6   ? b != 0 xs
                                                                                                   >    0-a25  01b   jnc +0x3
                                                                                                   >    0-a28  23c   rcr 2                      reg['C'] = 0x74000000000000
                                                                                                   >    0-a29  14e   a = a + c all      reg['A'] = 0x74000000000000
(…)
0-b63  1ee   c = c + c all      reg['C'] = 0x00000000000000                                             0-b63  1ee   c = c + c all      reg['C'] = 0x00000000000000
0-b64  1ee   c = c + c all      reg['C'] = 0x00000000000000                                             0-b64  1ee   c = c + c all      reg['C'] = 0x00000000000000
0-b65  14e   a = a + c all      reg['A'] = 0x00000000000000                                        |    0-b65  14e   a = a + c all      reg['A'] = 0x74000000000000
(…)
0-762  14e   a = a + c all      reg['A'] = 0x00000000000000                                        |    0-762  14e   a = a + c all      reg['A'] = 0x74000000000000
0-763  178   c = regn 5         reg['C'] = 0xf000bffffff720     addr = 5                                0-763  178   c = regn 5         reg['C'] = 0xf000bffffff720     addr = 5
0-764  276   c = c - 1 xs       reg['C'] = 0xf000bffffff620                                             0-764  276   c = c - 1 xs       reg['C'] = 0xf000bffffff620
0-765  067   jc +0xc                                                                                    0-765  067   jc +0xc
0-766  168   regn = c 5         reg[005] = 0xf000bffffff620                                             0-766  168   regn = c 5         reg[005] = 0xf000bffffff620
0-767  3e0   rtn                                                                                        0-767  3e0   rtn
(…)
0-a4c  01c     762                                                                                      0-a4c  01c     762
0-762  14e   a = a + c all      reg['A'] = 0x00000000000000                                        |    0-762  14e   a = a + c all      reg['A'] = 0x74000000000000
0-763  178   c = regn 5         reg['C'] = 0xf000bffffff620     addr = 5                                0-763  178   c = regn 5         reg['C'] = 0xf000bffffff620     addr = 5
0-764  276   c = c - 1 xs       reg['C'] = 0xf000bffffff520                                             0-764  276   c = c - 1 xs       reg['C'] = 0xf000bffffff520
0-765  067   jc +0xc                                                                                    0-765  067   jc +0xc
0-766  168   regn = c 5         reg[005] = 0xf000bffffff520                                             0-766  168   regn = c 5         reg[005] = 0xf000bffffff520
0-767  3e0   rtn                                                                                        0-767  3e0   rtn
(…)
0-b63  1ee   c = c + c all      reg['C'] = 0x00000000000000                                             0-b63  1ee   c = c + c all      reg['C'] = 0x00000000000000
0-b64  1ee   c = c + c all      reg['C'] = 0x00000000000000                                             0-b64  1ee   c = c + c all      reg['C'] = 0x00000000000000
0-b65  14e   a = a + c all      reg['A'] = 0x00000000000000                                        |    0-b65  14e   a = a + c all      reg['A'] = 0x74000000000000
0-b66  3e0   rtn                                                                                        0-b66  3e0   rtn
0-a56  0ae   acex all                   reg['A'] = 0x00000000000000     reg['C'] = 0x000000        |    0-a56  0ae   acex all                       reg['A'] = 0x00000000000000     reg['C'] = 0x740000
0-a57  201   ? nc gsb                                                                                   0-a57  201   ? nc gsb
0-a58  01c     780                                                                                      0-a58  01c     780
0-780  2a8   regn = c 10        reg[010] = 0x00000000000000                                        |    0-780  2a8   regn = c 10        reg[010] = 0x74000000000000
0-781  18c   ? st = 1 11                                                                                0-781  18c   ? st = 1 11
0-782  02b   jnc +0x5                                                                                   0-782  02b   jnc +0x5
0-787  34c   ? st = 1 12                                                                                0-787  34c   ? st = 1 12
0-788  360   rtn c                                                                                      0-788  360   rtn c
0-789  3c8   rstkb                                                                                      0-789  3c8   rstkb
0-78a  3cc   chkkb                                                                                      0-78a  3cc   chkkb
0-78b  360   rtn c                                                                                      0-78b  360   rtn c
0-78c  188   st = 1 11                  status = 0x0805                                                 0-78c  188   st = 1 11                  status = 0x0805
0-78d  2e5   ? nc goto                                                                                  0-78d  2e5   ? nc goto
0-78e  002     0b9                                                                                      0-78e  002     0b9
0-0b9  130   ldi                                                                                        0-0b9  130   ldi
0-0ba  004     004                      reg['C'] = 0x00000000000004                                |    0-0ba  004     004                      reg['C'] = 0x74000000000004
0-0bb  3c8   rstkb                                                                                      0-0bb  3c8   rstkb
0-0bc  3cc   chkkb                                                                                      0-0bc  3cc   chkkb
0-0bd  266   c = c - 1 x        reg['C'] = 0x00000000000003                                        |    0-0bd  266   c = c - 1 x        reg['C'] = 0x74000000000003
0-0be  3eb   jnc -0x3                                                                                   0-0be  3eb   jnc -0x3
0-0bb  3c8   rstkb                                                                                      0-0bb  3c8   rstkb
0-0bc  3cc   chkkb                                                                                      0-0bc  3cc   chkkb
0-0bd  266   c = c - 1 x        reg['C'] = 0x00000000000002                                        |    0-0bd  266   c = c - 1 x        reg['C'] = 0x74000000000002
0-0be  3eb   jnc -0x3                                                                                   0-0be  3eb   jnc -0x3
0-0bb  3c8   rstkb                                                                                      0-0bb  3c8   rstkb
0-0bc  3cc   chkkb                                                                                      0-0bc  3cc   chkkb
0-0bd  266   c = c - 1 x        reg['C'] = 0x00000000000001                                        |    0-0bd  266   c = c - 1 x        reg['C'] = 0x74000000000001
0-0be  3eb   jnc -0x3                                                                                   0-0be  3eb   jnc -0x3
0-0bb  3c8   rstkb                                                                                      0-0bb  3c8   rstkb
0-0bc  3cc   chkkb                                                                                      0-0bc  3cc   chkkb
0-0bd  266   c = c - 1 x        reg['C'] = 0x00000000000000                                        |    0-0bd  266   c = c - 1 x        reg['C'] = 0x74000000000000
0-0be  3eb   jnc -0x3                                                                                   0-0be  3eb   jnc -0x3
0-0bb  3c8   rstkb                                                                                      0-0bb  3c8   rstkb
0-0bc  3cc   chkkb                                                                                      0-0bc  3cc   chkkb
0-0bd  266   c = c - 1 x        reg['C'] = 0x00000000000fff                                        |    0-0bd  266   c = c - 1 x        reg['C'] = 0x74000000000fff
(…)
0-77e  2b8   c = regn 10        reg['C'] = 0x00000000000000     addr = 10                          |    0-77e  2b8   c = regn 10        reg['C'] = 0x74000000000000     addr = 10
0-77f  370   c = c or a                 reg['C'] = 0x00000000000000                                |    0-77f  370   c = c or a                 reg['C'] = 0x74000000000000
0-780  2a8   regn = c 10        reg[010] = 0x00000000000000                                        |    0-780  2a8   regn = c 10        reg[010] = 0x74000000000000
0-781  18c   ? st = 1 11                                                                                0-781  18c   ? st = 1 11
0-782  02b   jnc +0x5                                                                                   0-782  02b   jnc +0x5
0-783  3cc   chkkb                                                                                      0-783  3cc   chkkb
0-784  3a0   rtn nc                                                                                     0-784  3a0   rtn nc
(…)
0-77e  2b8   c = regn 10        reg['C'] = 0x00000000000000     addr = 10                          |    0-77e  2b8   c = regn 10        reg['C'] = 0x74000000000000     addr = 10
0-77f  370   c = c or a                 reg['C'] = 0x00010000000000                                |    0-77f  370   c = c or a                 reg['C'] = 0x74010000000000
0-780  2a8   regn = c 10        reg[010] = 0x00010000000000                                        |    0-780  2a8   regn = c 10        reg[010] = 0x74010000000000
0-781  18c   ? st = 1 11                                                                                0-781  18c   ? st = 1 11
0-782  02b   jnc +0x5                                                                                   0-782  02b   jnc +0x5
0-783  3cc   chkkb                                                                                      0-783  3cc   chkkb
0-784  3a0   rtn nc                                                                                     0-784  3a0   rtn nc

Since F can be used as a label with the HP-16C, it can appear in the last position.
Therefore, there must be another way to distinguish the usual interpretation of f as a space in this case.
I assume this is related to the value 3fc read from the address 255.
Later, it is converted to 74 and written to reg[010].
It is probably written when subroutine A is executed, but as ThomasF already mentioned, it is not reset anymore.

I've attached the full diff in a zip-file.


Attached File(s)
.zip  funny-hp-16c-quirk.zip (Size: 6.29 KB / Downloads: 3)
Find all posts by this user
Quote this message in a reply
11-08-2024, 02:55 PM
Post: #5
RE: Funny HP-16C quirk
(11-08-2024 09:08 AM)RPNerd Wrote:  It's the same on a 15C CE thrown into 16C mode.

Hardly shocking since that is a emulation of real 16C firmware. Any bugs/quirks would therefore be present.

A1

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
11-09-2024, 03:44 AM
Post: #6
RE: Funny HP-16C quirk
(11-08-2024 02:42 PM)Thomas Klemm Wrote:  I assume this is related to the value 3fc read from the address 255.
Later, it is converted to 74 and written to reg[010].
It is probably written when subroutine A is executed, but as ThomasF already mentioned, it is not reset anymore.

Yes, reg 0xff contains the current program position in the lowest three digits, 0x000 for line 0. The next three digits to the left of the progran position are the first return level, with 0x3fc being to line 3.

At 0x0a14, a subtroutine is called to read that register, which of course gets all 56 bits of it. However, the microcode programmer apparently assumed that all of the digits 13..3 would be zero. At 0x0a1a, the entire C register is checked for zero, where the check should only be for the exponent and exponent sign digits. When there's no pending return, it jumps ahead to L0a2a. Because of the pending return, the code falls through into 0x0a1c, which formats one digiit of the display, then falls into the comnon path at 0x0a2a.

The code from 0x0a1c to 0x0a29 is what would usually format the base indicator in integer modes, or the least significant display digit (of mantissa, exponent, or blank) in FLOAT. It shouldn't be executed in PRGM mode on line 0. It is being executed with wrong flag settings, so a 0xf in one of the display formatting temporary registers is being formatted in hexadecimal mode as "F", rather than in decimal and special mode where it would be a blank.

Replacing the "? c#0 w" instruction (0x2ee) at 0x0a1a with "? c#0 x" (0x2e6) should fix it. HP used that to test for line 0 in other places in the code, such as 0x0c25. That works because the program pointer register number can never be 0x00, which is in the status registers, so if it is 0x00, it doesn't matter what digit 2 contains (1-7 for byte), though that should always be zero when the register is 0x00.

Are there any other known bugs in the ORIGINAL 16C firmware? At least this one is only cosmetic, and won't lose or corrupt any data.
Find all posts by this user
Quote this message in a reply
11-09-2024, 09:15 AM (This post was last modified: 11-09-2024 12:54 PM by J-F Garnier.)
Post: #7
RE: Funny HP-16C quirk
(11-09-2024 03:44 AM)brouhaha Wrote:  Are there any other known bugs in the ORIGINAL 16C firmware? At least this one is only cosmetic, and won't lose or corrupt any data.

There are two bugs shared with the 15C:
- in float mode, CHS doesn't enable the stack lift when the X-register is 0.
- If a program ends with a conditional test that is evaluated false, program pointer skips to line 1 and continue from there, instead of stopping at line 0.

There is no "GSB I with I<0" bug as in the 15C because the I<0 case doesn't exist (the absolute value of I is used as described in the manual).

I can also mention another quirk (can't really call it a bug) found by Mike (Stgt) years ago who just reminded me about it:
> Clear Prefix in integer mode does not end digit entry, in floating mode it does
This is likely because Clear Prefix is a nop in integer mode. In the same way, integer-only functions are nop in float mode and don't end digit entry either.

J-F
[edit: stack lift bug in float mode only]
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 2 Guest(s)