The HP-65 “delayed select group” microinstruction doesn’t behave the way you’d expect. I don’t know whether its behaviour changed for the ’65 or if it was like this on the earlier calculators too. Here’s what it doesn’t and what it does …
The problem with the early calculator processors is the addressing range. It isn’t a fault. It is a limitation that early designers had to work with. Microinstructions were all 10 bit words. A lot of the microinstructions were jump instructions, either “goto” and an address or “jsb” and an address. The combination, including the address, fitted into a single word. Two bits at the end were used to encode the instruction type. This allowed four types. “goto” was one type. “jsb” (jump subroutine) was another. After deducting 2 bits from the 10 bit word, you are left with 8 bits for the goto / jsb address.
You can’t go anywhere further than 256 instructions away. What’s more, the processors used absolute addressing rather than relative addressing. This ruled out tricks where you could get to the end of address space and still access (almost) 256 instructions beyond there. Repeating the process would have allowed access to even more addresses. However, the point is, that wasn’t available. Absolute addressing means you can only access 256 instructions from instruction 0.
It was actually a lot of possible addresses and there was a lot that could be done in “that much” space. It seemed a lot (or at least, more than enough) at the time the processors were developed.
Of course back then; calculators would add, subtract, multiply and even divide. That was before HP decided to add trigonometric functions and subsequently everything else. This required a lot more than 256 instructions.
The solution was called “bank switching” though the use of that term probably came later. The processor would be happily running instructions in its 256 word instruction space and, at some point, you’d “unplug” the ROM with the instructions and “plug in” another instead. This was done through a “select rom (n)” instruction.
What really impresses me is the effort that had to go into making a program work with that approach. Every transition between ROMs has to match up with an instruction in exactly the right place in the target ROM. Not too hard, perhaps, if you’re always going in the same direction (eg ROM 0 to ROM 1) but imagine having to fit and position program parts so that you can criss-cross back and forth between them. One instruction too long and you need to move things around so all the bits mesh up again.
Bank switching in later times worked by loading registers with values, jumping to one fixed address, and then doing the bank switch. The same bit of code was always present in the same address in every ROM. What happened in the rest of the ROM differed between them. It is a technique that got worked out over time.
HP came up with a useful trick: the “delayed select rom (n)” instruction. You could swap between any of 8 ROMs but, because the swap was delayed, you could put a goto instruction after it and effectively jump to any address in any of the 8 ROMs. It may even be the origin of modern “multibyte” instructions.
This worked really well until bigger and better calculators were conceived. Eight ROMs allows 2048 instructions spanning addresses 00000 – 03777 (in octal). If you see a microcode program with an address beyond those you are seeing access outside the 8 ROMs. They solved that with a “ROM group.” It’s the same concept, but “bank switching” another whole set of 8 ROMs.
Here’s where the “delayed select group (n)” instruction comes in.
It is effectively a three word way to goto a group, ROM and instruction. The idea is for sequences like:
delayed select group 2
delayed select rom 6
goto 123
That would take you to 2:6:123 or, assuming octal (2*04000 + 6*0400 + 0123 =) address 013123.
However, it doesn’t work that way.
The Important Part
Many calculator emulators modify the behaviour of the goto and jsb instructions to take earlier “delayed select …” instructions into account. BUT it doesn’t work that way.
The hint was from something Francois Roulet said recently, “the Java Emulator of Jacques Laporte works perfectly” and “the original HP firmware is identical for these 2 Emulators.”
Jacques’ emulator has a “.jar” file (http://wiki.epfl.ch/polymac/documents/Laporte/hp65/sim65.jar) which is a ZIP archive of, mainly, compiled Java. It also contains another ZIP file, hp65.zip. That is a listing file with the microcode for the HP65. It unZIPs as “hp65.lst”.
Jacques commented the microcode and one of the interesting bits is the R/S sequence:
0578 L02101: ..11...11. data0: 0 -> c[m] 0579 L02102: 1.1.11.1.. delayed select group 1 ;-> r12104 0580 L02103: ..1.1.1... entr1_2: c exchange m 0581 L02104: .1..1.1... c -> stack
The line numbers (L02101 etc) refer to ROM 2, address 101 etc (octal 01101 etc).
Jacques says here that the delayed select group 1 instruction is about to head off to “12104” or group 1, ROM 2, address 104. Yet it is at address 102. It isn’t going to go directly to that address. It has to execute the instruction at 103 first.
The “delayed select group (n)” instruction branches after one more instruction. It doesn’t matter whether that instruction is a goto/jsb or not. In effect, the new group number is going to get slammed into the program counter even though there’s no sign of a branch yet.
The Good News
With a simple tweak to how the Control and Timing chip is emulated, the javascript microcode emulators for the HP-65 should all work just as well as Jacques’ Java one.
Thank you Jacques. Gone but still contributing.