[HP35S] Disassembling ROM
02-21-2015, 12:30 PM (This post was last modified: 02-21-2015 04:03 PM by Tugdual.)
Post: #1
 Tugdual Senior Member Posts: 756 Joined: Dec 2013
[HP35S] Disassembling ROM
Of course it seems difficult to read the ROM (Brouhaha did an amazing work on this in the past) but we now have simulators and I believe the ROM is this file here:
C:\Program Files (x86)\Hewlett-Packard\HP 35s Virtual Calculator\Models\Model.dat

I checked the preliminary SPLB31A datasheet but couldn't figure out where the RESET vector is. We also don't have a clear idea of where the ROM is loaded though $C800 seems to be a good candidate. If anybody has a clue about that... Did anybody already attempted to disassemble the 35s ROM? Note: the ROM is actually embedded into the file 35s.sml 02-22-2015, 10:26 AM (This post was last modified: 02-22-2015 10:59 AM by Tugdual.) Post: #2  Tugdual Senior Member Posts: 756 Joined: Dec 2013 RE: [HP35S] Disassembling ROM Found some constants in the ROM. Code: -4.95920119017593E2 3.03479606073615E1 -7.65594818140208E1 9.33584905660377 -1.21142857142857 0.4 .918938533204673 .5 7 90 100 180 200 Googling these values pointed me on "Hp48Sx Machine Language, Par Paul Courbis,Paul Courbis et Sébastien Lalande" Anybody knows what these constants are? Edit: ok found that these are constants used for various polynomial approximations. For example .918938533204673 is used during gamma log approximation. 02-22-2015, 12:07 PM Post: #3  Dieter Senior Member Posts: 2,397 Joined: Dec 2013 RE: [HP35S] Disassembling ROM (02-22-2015 10:26 AM)Tugdual Wrote: Edit: ok found that these are constants used for various polynomial approximations. For example .918938533204673 is used during gamma log approximation. Ah, that's interesting. I always thought the 35s used some kind of approximation for Gamma resp. factorials. You may try the x! key with some non-integers so that the 35s has to evaluate the Gamma function. The result appears almost immediately. Try some integers and you'll notice an increasing lag as the values increase. 10! is returned instantly, but 150! requires roughly a second. Try 160! and the result appears immediately again. In fact the 35s seems to calculate factorials up to 158! by iterative multiplication, while 159! and up is evaluated by means of the Gamma function. In this case not Γ, but ln Γ seems to be calculated. This would also explain slight errors for large arguments. Try 225,5! and the result is exact (1,89218764486 E434 with the last digit correctly rounded up from ...856). Try 225,6! and the last digit is 3 ULP low: 3,25375380207 E434 instead of ...210). This is the point where ln Γ exceeds 1000. Even if ln Γ is evaluated accurately to all internal 15 digits, there still is a potential absolute error of 1 E–11 in ln Γ which means a relative error of this order in Γ itself so that not more than 11 correct digits can be expected. Dieter 02-22-2015, 02:43 PM (This post was last modified: 02-22-2015 04:49 PM by Tugdual.) Post: #4  Tugdual Senior Member Posts: 756 Joined: Dec 2013 RE: [HP35S] Disassembling ROM I struggle with few technical aspects: - lack of SPLB31A detailed doc (for example about registers usage) - how to disassemble segmented ROM - not sure I really understand how the segmented ROM works. I would imagine that before any jump the code is refreshing the BANK register and then proceeds with normal jump. Providing that I'm not sure at all about the way the ROM is organized in the 35s.sml file, that is quite a lot of try/fail. I could verify that changing the file has an effect on the simulator, so the ROM is definitely there. 02-22-2015, 03:30 PM Post: #5  EdS2 Senior Member Posts: 344 Joined: Apr 2014 RE: [HP35S] Disassembling ROM An interesting adventure anyway. I downloaded a copy and am poking around. 02-22-2015, 06:32 PM Post: #6  Thomas Ritschel Member Posts: 66 Joined: Feb 2014 RE: [HP35S] Disassembling ROM Looking at the hex dump of the file 35s.sml, there seems to be a code segment starting at$85c0. The output of the DCC6502 disassembler looks like some legit 6502/8502 code:

Code:
 $85C0> D8: CLD ;$85C1> A2 96:    LDX #$96 ;$85C3> A0 C8:    LDY #$c8 ;$85C5> EA:    NOP        ; $85C6> 88: DEY ;$85C7> D0 FC:    BNE $85C5 ;$85C9> A0 C8:    LDY #$c8 ;$85CB> CA:    DEX        ; $85CC> D0 F7: BNE$85C5        ; $85CE> A9 FF: LDA #$ff    ; $85D0> 85 07: STA$07        ; $85D2> A9 00: LDA #$00    ; $85D4> 85 06: STA$06        ; $85D6> 85 08: STA$08        ;

BTW: There are some more "human readable" parts in the file, e.g. the constants library (speed of light, etc.) starting at $18750, some warning messages starting at$201c0, the messages of the self test starting at $e7f0, and a lot of function names and symbols every here and there, e.g. starting at$182f0.

If there is no checksum, one could easily poke around...
02-22-2015, 07:21 PM (This post was last modified: 02-22-2015 07:26 PM by Tugdual.)
Post: #7
 Tugdual Senior Member Posts: 756 Joined: Dec 2013
RE: [HP35S] Disassembling ROM
Using IDA you rapidly accumulate a lot legit 6502 fragments and it doesn't even look like it was compiled from C which I found surprising.
The difficulty is the ROM paging to know how to segment the file and detect ROM changes. There is a specific BANK register address (apparently $0000) where you select a segment and then it would map 2 blocks of 16kB respectively in$4000 and $8000. I suspect that the ROM organization should be pretty much the same as for the 48g with basically a library by segment (I'm not an expert on 48g). You can find SPLB31A datasheets here There is a test ROM located in$C000-$C7FF (not sure if it is the something built in the processor) and then you can have another range from$C800-$FFFF for a custom ROM. So this is a 16kB area. If you open the 35s.sml file with a text editor, you find the settings of the emulator at the beginning of the file: Code: ;============================================================================== ; SPLB31A. ;============================================================================== [SPLB31A_MEMORYMAP] REG_ADDR_START =0x0000 REG_ADDR_END =0x003F RAM_ADDR_START =0x0040 RAM_ADDR_END =0x10FF LCD_ADDR_START =0x3E00 LCD_ADDR_END =0x3FFF BANK_ADDR_START =0x4000 BANK_ADDR_END =0xBFFF ROM_ADDRESS_START=0xC000 ROM_ADDRESS_END =0xFFFF MAX_ADDRESS_SPACE=0x10000 MAX_BANK_NUM =8 [SPLB31A_IOPort] Number=6 [SPLB31A_IOItem0] Name=PortA Address=0x08 Input = 0xFF Output = 0xFF [SPLB31A_IOItem1] Name=PortB Address=0x0A Input = 0xFF Output = 0xFF [SPLB31A_IOItem2] Name=PortC Address=0x0B Input = 0xFF Output = 0xFF [SPLB31A_IOItem3] Name=PortD Address=0x09 Input = 0x3F Output = 0x3F [SPLB31A_IOItem4] Name=Keyscan1 Address=0x3B Input = 0x00 Output = 0xFF [SPLB31A_IOItem5] Name=Keyscan2 Address=0x3C Input = 0x00 Output = 0xFF [SPLB31A_LCDSetting] BaseAddress=0x3E00 SegmentNum=74 CommNum=32 Interval=16 bMinToMax=1 bVert=0 bMirror=1 ENDADDRESS=0x3FFF [SPLB31A_BUSMEMORYINTERFACE] BODYNAME =SPLB01A DLL =BusMemoryInterface.DLL BODYMAXSIZE =7 BODYINFO =SPLB30A_BUSMEMORYINTERFACE_BODY ADDRESS_MAP =SPLB30A_BUSMEMORYINTERFACE_ADDRESS_MAP CONDITON =SPLB30A_BUSMEMORYINTERFACE_COND NOT_CONDITON =SPLB30A_BUSMEMORYINTERFACE_NOT_COND DVP =OFF DVP_RAM =SPLB30A_BUSMEMORYINTERFACE_BODY_DVP_RAM DVP_ROM =SPLB30A_BUSMEMORYINTERFACE_BODY_DVP_ROM BUSEXT_INTERFACE_COND=0x09 So with 8 banks (max) of 32K and 16K for the fixed ROM we're looking for a block of 272kB (278528 bytes) inside 35s.sml. Now how is that organized? My best guess would be: Code: $C000 - $FFFF BANK0-H -> remap to$8000 BANK0-L -> remap to $4000 BANK1-H -> remap to$8000 BANK1-L -> remap to $4000 ... BANK8-H -> remap to$8000 BANK8-L -> remap to $4000 That's all I know at the moment. I wonder where the code is cold booting, possibly$C000, I wonder what registers are and how they work.
02-24-2015, 01:46 PM (This post was last modified: 02-24-2015 01:48 PM by Thomas Ritschel.)
Post: #8
 Thomas Ritschel Member Posts: 66 Joined: Feb 2014
RE: [HP35S] Disassembling ROM
(02-22-2015 10:26 AM)Tugdual Wrote:  Found some constants in the ROM.

Code:
-4.95920119017593E2 3.03479606073615E1 -7.65594818140208E1 9.33584905660377 -1.21142857142857 0.4 .918938533204673 .5 7 90 100 180 200

The same data block can be found in the ROM entry points of the HP-48SX:
Code:
2B2DC %% HP:%%12 2B300 %% HP:%%60 2B31F %% %%-495.920119017593 2B343 %% %%30.3479606073615 2B36C %% %%-76.5594818140208 2B390 %% %%9.33584905660377 2B3B9 %% %%-1.21142857142857 2B3DD %% HP:%%.4 2B410 %% %%0.918938533204673

What makes me puzzling is why these values are stored in the HP 35S in ASCII format and not as binary or BCD numbers...
02-24-2015, 02:27 PM
Post: #9
 Tim Wessman Senior Member Posts: 2,277 Joined: Dec 2013
RE: [HP35S] Disassembling ROM
(02-22-2015 07:21 PM)Tugdual Wrote:  Using IDA you rapidly accumulate a lot legit 6502 fragments and it doesn't even look like it was compiled from C which I found surprising.

Hmm... maybe you start to understand the problem/difficulty in fixing things... :-)

Completely non-documented (at least in anything but sparse chinese) source, non-English tools, extensive regions of assembly using non-standard assembly heavily dependent on non-documented features and registers requiring a close working relationship with the exact chip manufacturer (who doesn't have anyone who understands the chip anymore), no way to flash or change the firmware once flashed, etc

If you can imagine it, chances are it is part of the issue.

TW

Although I work for the HP calculator group, the views and opinions I post here are my own.
02-24-2015, 02:45 PM
Post: #10
 matthiaspaul Senior Member Posts: 385 Joined: Jan 2015
RE: [HP35S] Disassembling ROM
(02-24-2015 01:46 PM)Thomas Ritschel Wrote:  What makes me puzzling is why these values are stored in the HP 35S in ASCII format and not as binary or BCD numbers...
Perhaps the compiler/assembler used didn't natively support the numerical data format used by those libraries, so that it would have been difficult to write those constants in the source code. If the data would have to be converted into another representation before it could be used, it wouldn't have harmed to store them in ASCII strings, anyway. ASCII strings of (almost) arbitrary length are supported by virtually all computer languages.

Another possibility might be that these numbers were meant to be patchable. It is quite common to store such numbers or strings in some easy recognizable and parsable format in binaries, so that they can be changed later on without having to recompile the sources, often even without having access to the sources (f.e. by OEMs or end-users).

Greetings,

Matthias

--
"Programs are poems for computers."
02-24-2015, 04:43 PM
Post: #11
 Tugdual Senior Member Posts: 756 Joined: Dec 2013
RE: [HP35S] Disassembling ROM
(02-24-2015 02:45 PM)matthiaspaul Wrote:
(02-24-2015 01:46 PM)Thomas Ritschel Wrote:  What makes me puzzling is why these values are stored in the HP 35S in ASCII format and not as binary or BCD numbers...
Perhaps the compiler/assembler used didn't natively support the numerical data format used by those libraries, so that it would have been difficult to write those constants in the source code. If the data would have to be converted into another representation before it could be used, it wouldn't have harmed to store them in ASCII strings, anyway. ASCII strings of (almost) arbitrary length are supported by virtually all computer languages.

Another possibility might be that these numbers were meant to be patchable. It is quite common to store such numbers or strings in some easy recognizable and parsable format in binaries, so that they can be changed later on without having to recompile the sources, often even without having access to the sources (f.e. by OEMs or end-users).

Greetings,

Matthias
I would say for the sake of consistency. The constants are also stored using ASCII because we need to pick a constant on screen and then it is represented as a tiny EQN inside the code.
Also whatever constant is entered manually is the same, a mini ASCII EQN.
Of course this is to the detriment of performance.
I wonder if the whole calculator operates in ASCII, a bit like BCD but ASCII version. That would be pretty unique!
02-24-2015, 04:56 PM
Post: #12
 Han Senior Member Posts: 1,881 Joined: Dec 2013
RE: [HP35S] Disassembling ROM
(02-24-2015 04:43 PM)Tugdual Wrote:  I would say for the sake of consistency. The constants are also stored using ASCII because we need to pick a constant on screen and then it is represented as a tiny EQN inside the code.
Also whatever constant is entered manually is the same, a mini ASCII EQN.
Of course this is to the detriment of performance.
I wonder if the whole calculator operates in ASCII, a bit like BCD but ASCII version. That would be pretty unique!

Haven't looked at the ROM a single "bit" but could it be that these are simply the ASCII representations of the constants for... display purposes (and that there is a binary representation elsewhere)?

Graph 3D | QPI | SolveSys
02-24-2015, 06:48 PM
Post: #13
 Tugdual Senior Member Posts: 756 Joined: Dec 2013
RE: [HP35S] Disassembling ROM
(02-24-2015 04:56 PM)Han Wrote:
(02-24-2015 04:43 PM)Tugdual Wrote:  I would say for the sake of consistency. The constants are also stored using ASCII because we need to pick a constant on screen and then it is represented as a tiny EQN inside the code.
Also whatever constant is entered manually is the same, a mini ASCII EQN.
Of course this is to the detriment of performance.
I wonder if the whole calculator operates in ASCII, a bit like BCD but ASCII version. That would be pretty unique!

Haven't looked at the ROM a single "bit" but could it be that these are simply the ASCII representations of the constants for... display purposes (and that there is a binary representation elsewhere)?
Good suggestion but the ASCII is definitely the value. If you change the ASCII string in the emulator you really see a different values during the code execution. Now there could be a cached binary version in memory.
 « Next Oldest | Next Newest »

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