HP Forums
WIP: 16C firmware hack for more memory - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: General Forum (/forum-4.html)
+--- Thread: WIP: 16C firmware hack for more memory (/thread-19458.html)

Pages: 1 2 3 4 5


RE: WIP: 16C firmware hack for more memory - blackjetrock - 11-11-2023 01:56 AM

(11-10-2023 11:07 PM)brouhaha Wrote:  
(11-10-2023 08:38 PM)blackjetrock Wrote:  As this is emulated code, surely it is possible to have more than one instruction at an address? The strict one to one relationship between addresses and instructions that the hardware imposes on a real machine doesn't necessarily need to apply when emulating instructions?

I have a simulated program counter that points to an simulated ROM word, so without going too crazy in inventing new embellishments to the Nut architecture, I still only get two instructions in two ROM addresses. Or one two-word instruction, such as a subroutine call to elsewhere else.

The two-word thing was interesting, in that it limited the choices available unless I replaced it with a subroutine call. A much bigger acoomplishment was fitting a higher-precision divide-by-14 routine (multiplication by a higher-precision approximation of the reciprocal of 14) in the less space than the original, and having it work just slightly faster.

When I got the HP-41C and HP-41CX microcode running on the DIY5 hardware the late Richard Ottosen and I built, in order to add four-level stack display, I had the simulator trap certain PC addresses and do special things. The four-level stack display actually runs the microcode that formats the X register display four times instead of just one, for T, Z, Y, and X in that order, so that at the end of the iterations, the calculator state should be identical to what it would be if only X were displayed. There were several other such hacks to increase the number of flags, etc. (I have no idea whether the SwissMicros firmware for their DM41X uses similar techniques.)

In the case of the HP-41, I was worried that actually changing the mainframe ROM image could break things. In the case of the HP-16C, it is a much more contained problem, due to having no plug-in ROMs, so I'm more confident in my ROM patches.

Could you not have the following:?

When address x is executed,

1. Execute the instruction from the ROM
2. Execute extra instructions

It sound like the 41C insertion you did. I think even jumps to X still work and you can squish more functionality onto the code. It's really like having a new, longer opcode added to the instruction set I suppose. It does mean that you can never put it in a ROM, but you do get your extra functionality, and it shouldn't break anything, which is the big advantage.
I've not done this at all, so it's interesting to see that you did it in the 41C work.
It doesn't get the elegance award, but does get the job done.


RE: WIP: 16C firmware hack for more memory - brouhaha - 11-11-2023 12:53 PM

(11-11-2023 01:56 AM)blackjetrock Wrote:  Could you not have the following:?

When address x is executed,

1. Execute the instruction from the ROM
2. Execute extra instructions

Yes, I could do that. I prefer to stick to code that can execute on the HP Nut processors. When I first hacked HP-15C firmware in 2004-2005 (leading to the expanded memory of the SwissMicros DM15[L] and the HP 15C CE), I cut the ISA line between the Nut and R2D2 chips of an old 12C, and inserted an FPGA and two parallel NOR flash chips between, to replace the ROM of the R2D2. I'd hoped to later do the same with a low power microcontroller, that might actually fit inside the calculator and run from its batter without completely devastating the battery life. I didn't complete that, but I still prefer code that could, in principle, run on the original hardware.

If I was going to patch it in native code, I'd do the same thing HP has done on some ARM-based Voyagers, which is to usurp some undefined opcode(s), to avoid having any address comparisons added to the interpreter loop.


RE: WIP: 16C firmware hack for more memory - blackjetrock - 11-28-2023 03:40 PM

I've just found out that running code in the space of a single instruction is an old idea:

https://en.wikipedia.org/wiki/Atlas_(computer)#Extracode


RE: WIP: 16C firmware hack for more memory - brouhaha - 11-28-2023 10:24 PM

(11-28-2023 03:40 PM)blackjetrock Wrote:  I've just found out that running code in the space of a single instruction is an old idea:
https://en.wikipedia.org/wiki/Atlas_(computer)#Extracode

There have been machines that stored multiple instructions in one word, but Atlas, despite being very influential on later processor architectures, was not one of them. The CDC 6600 was a notable such machine, introduced in 1964. The CDC 6600 central processor packed 15-bit and 30-bit instructions into a 60-bit machine word. The IBM 7030 ("STRETCH", 1961) used 32-bit and 64-bit instructions, but could directly address the 32-bit instructions, so it was not really the same concept.

Atlas Extracodes were subroutine call instructions, and were the same size as other Atlas instructions. Quoting that Wikipedia article:

Quote:If the uppermost bit was set to one, this was an Extracode and was implemented as a special kind of subroutine jump to a location in the fixed store (ROM), its address being determined by the other nine bits. About 250 extracodes were implemented, of the 512 possible.

Extracodes were what would be called software interrupts or traps today.

The subroutine call was arguably invented in 1842, though not implemented at that time. In modern times, it can be considered to have been invented in 1946. The original purpose of the subroutine was in fact to save memory. Mark Smotherman's web site gives a lot of historical information on computer architecture, including this history of subroutines:

https://people.computing.clemson.edu/~mark/subroutines.html

The IBM System/360 (1964) SVC (supervisor call) was similar to an Atlas Extracode, though the call was to main memory, and wasn't typically used for mathematical functions.

The DEC 36-bit machines, starting with the PDP-6 (1964) had UUO instructions, "Unimplemented User Operations", which were essentially the same as Extracodes. These were divided into User UUOs, which callec a subroutine at the current privilege level, and Monitor UUOs, which trapped to supervisor mode, like the IBM 360 SVC.

It is my understanding that the IBM 360 SVC and DEC UUOs were inspired by Atlas.

Any processor with an undefined instruction trap effectively has the equivalent of the Extracode.

What has, AFAIK, never existed, is a processor that packs multiple n-bit instructions into a single n-bit data word. The closest thing I know of is the OPR ("operate") instruction of the DEC 18-bit and 12-bit processors (e.g. PDP-8). Individual bits in the encoding perform distinct operations and can be combined, thus you can have an instruction to complement the accumulator, complement the link flag (carry), or do both in one instruction (possibly with additional operations as well). This was called "microcoding", by analogy to horizontal microcode,. The combination of functions performed is, however, considered to be a single machine instruction.

The HP calculator microarchitectures do, of course, have subroutine calls. In a simulator, it is possible to use otherwise unassigned opcodes to implement more specialize subroutine calls. But then, in the simulator one could simply interpret an undefined opcode to perform any desired operations in native code. HP's ARM-based 12C and 15C do that. Alternatively, a simulator can trap micrpinstruction fetches from specific microcode addresses, without changing the microcode ROM image at all, which is what I did in the 41C version of the ARM-based 41CV prototype Rich Ottosen and I developed, I order to provide four-level stack display, 100 flags, etc.


RE: WIP: 16C firmware hack for more memory - RPNerd - 08-23-2024 04:55 PM

This is a 9-month-old thread, I know, but I'm shamelessly piggy-backing on it because I have a couple of questions about the NUT instruction set on which the participants in this thread might be able to shed some light.

As I understand it:
  • instruction $3CC (CHK KB or ?KEY depending on the syntax you're using, I'll stick with the HP syntax here, so CHK KB) checks the CPU's KB register and if a key is pressed, sets the carry flag.
  • Instruction $3C8 (RST KB) clears the KB register, although if a key is pressed when this is executed, the KB register will still contain the code of the key pressed.
  • Instruction $220 (C=KEY) grabs the content of the KB register and sticks it in nybbles 3 & 4 of the C register.

On a Voyager unit, what exactly is the value of the KB register for each key pressed? Is it a scancode of sorts that's common to all Voyager units? Is there a resource online somewhere that can explain how this works in detail? I've not found anything yet.

Thanks in advance.


RE: WIP: 16C firmware hack for more memory - brouhaha - 08-24-2024 01:38 AM

(08-23-2024 04:55 PM)RPNerd Wrote:  Instruction $3C8 (RST KB) clears the KB register, although if a key is pressed when this is executed, the KB register will still contain the code of the key pressed.

It clears the key flag, but only if the key is not still pressed. It does not clear the keycode register. They are two separate things.

Quote:what exactly is the value of the KB register for each key pressed? Is it a scancode of sorts that's common to all Voyager units?

Same on all Nut-based Voyagers.

See the keyboard section of the Nonpareil 15c.ncd.tmpl file, starting at line 187.


RE: WIP: 16C firmware hack for more memory - RPNerd - 08-24-2024 06:45 AM

(08-24-2024 01:38 AM)brouhaha Wrote:  See the keyboard section of the Nonpareil 15c.ncd.tmpl file, starting at line 187.

Thanks, that's a great help. Stuff like this (in the HP-10C ROM) is beginning to make more sense:

Code:

0028:2b9 000                    GSUBNC 00ae        ; Get the current pressed key
002a:366                        ?A<>C X            ; If not 018
002b:360                        RTN C            ; ...then return
...
...
...
; Loads the current pressed key into A.X and 018 into C.X
00ae:04e                        C=0
00af:220                        C=KEY
00b0:03c                        RCR 3
00b1:106                        A=C X
00b2:130 018                    LDI 018
00b4:3e0                        RTN

With the values in that template file (key $018 is the ON key) I now know exactly what the calc is looking for and also stuff like GOKEYS will make more sense.

Again, thanks for the insight.


RE: WIP: 16C firmware hack for more memory - RPNerd - 08-24-2024 07:06 AM

As a follow-up to this, could I just ask for confirmation of the template for the 10C...

I get it that the 10C is a machine that doesn't get a whole lot of attention so it's easy for something to be missed.

Looking at https://github.com/brouhaha/nonpareil/blob/main/ncd/10c/10c.ncd.tmpl lines 192-201 that define the second row of keys on the keyboard:

Code:
    <key user_keycode="21" hw_keycode="0x10"/> <!-- %          ->R        -->
    <key user_keycode="22" hw_keycode="0x30"/> <!-- GTO        ->P        -->
    <key user_keycode="23" hw_keycode="0x70"/> <!-- SIN        SIN-1      -->
    <key user_keycode="24" hw_keycode="0xc0"/> <!-- COS        COS-1      -->
    <key user_keycode="25" hw_keycode="0x80"/> <!-- TAN        TAN-1      -->
    <key user_keycode="26" hw_keycode="0x87"/> <!-- 4          DEG        -->
    <key user_keycode="27" hw_keycode="0xc7"/> <!-- 5          RAD        -->
    <key user_keycode="28" hw_keycode="0x77"/> <!-- 6          GRD        -->
    <key user_keycode="29" hw_keycode="0x37"/> <!-- multiply   x=0        -->
    <key user_keycode="20" hw_keycode="0x17"/>

Should the keys 4, 5, 6 and multiply not be shifted one position to the right with EEX as hw_keycode 0x87 and user keycode 26?


RE: WIP: 16C firmware hack for more memory - brouhaha - 08-24-2024 09:10 AM

Yes, it appears that the comments are wrong.

Unfortunately, the compiler doesn't check those. :-)