thomasokken / free42

Free42 : An HP-42S Calculator Simulator
https://thomasokken.com/free42/
GNU General Public License v2.0
280 stars 54 forks source link

Bit shift functions #23

Closed jonbakke closed 3 years ago

jonbakke commented 3 years ago

Hello, and thank you for this fantastic tool.

I don't see a way to apply a bit shift operation. I suspect I'm missing something obvious, in which case a nudge in a useful direction would be greatly appreciated. Otherwise, I think it would be a useful addition.

My first thought is to add a page to the BASE > LOGIC menu with y<>x operations. This becomes thorny when moving away from strictly correct behavior and toward expected behavior, specifically: signed values, right operand larger than precision, and negative right operand. I think it'd be nice to have the other menu keys toggle options for applying arithmetic shift to negative values (on by default), warning when right operand larger than precision (on by default, else return 0), and warning when the right operand is negative (on by default, else overflow right operand to the word size). But first I'd want to see at least how the 16C (SL, SR) and 48G (SL, SR, ASR) work.

If this sounds like an appropriate feature for Free42, I'd be happy to give it a try and continue this discussion in reference to a potential PR.

thomasokken commented 3 years ago

SL, SR, and ASR could be implemented in user code. FUNC makes that a bit easier than it used to be, but I agree it would be nice if they were built-in functions. (FUNC is a recent addition, documented here.)

It sounds like the options you're talking about should already be taken care of by the BSIGNED and BWRAP mode settings.

jonbakke commented 3 years ago

Bit shifts are unary in other HP calculators. This is according to their manuals: the HP-16C (which also has ASR, omitted in my prior comment) manual pages 46-47 and HP-48G user guide section-page 15-5. Differences I noticed are: (1) The 16C also assigns the carry flag the value of the displaced bit; I couldn't find references to a carry flag for either the 42S or 48G. (2) The 16C maintains the word size of the x register, while the 48G assumes a word size of 24 but can be set otherwise.

I'm a little delighted to learn this. I had not considered bit shifting as a unary operation before, despite frequently using them that way.

I'll close this with a solution of writing user functions, as you mentioned. I might still offer a PR, as I want to learn your coding style well enough to make useful contributions, but that will be unrelated to the resolution of this issue.

Thank you!

thomasokken commented 3 years ago

Note that the word size is configurable in Free42 as well -- this is fairly new, introduced in 2.4, along with wrapped and unsigned modes. https://thomasokken.com/free42/#base-enh