Skip to content

Commit 9fef23c

Browse files
authored
Merge pull request #8 from bxparks/develop
merge 0.4.0 into master
2 parents c540246 + e6ca075 commit 9fef23c

19 files changed

+1817
-620
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
# Changelog
22

33
- Unreleased
4+
- More `BASE` menu functions:
5+
- `SL` (shift left), `SR` (shift right)`, `RL` (rotate left circular),
6+
`RR` (rotate right circular).
7+
- `B+`, `B-`, `B*`, `B/`
8+
- `BDIV` (division with remainder)
9+
- Map `+`, `-`, `*`, and `/` buttons to their bitwise counterparts when in
10+
`HEX`, `OCT`, or `BIN` modes.
11+
- Too confusing to have floating point operations bound to the
12+
easy-to-reach buttons while in HEX, OCT or BIN modes.
13+
- This is consistent with the HP-42S.
14+
- `PRIM` (isPrime)
15+
- change result values:
16+
- 1 if the number is a prime, or
17+
- smallest prime factor (always greater than 1) if not prime.
18+
- preserve the original `X`, and push it up to `Y`
19+
- allows the `/` button to be chained with additional `PRIM` to
20+
calculate all prime factors
21+
- see [Prime Factors](#USER_GUIDE.md#prime-factors]) for details
22+
- improve speed by 7X using u32 integer routines instead of floating
23+
point routines
424
- 0.3.3 (2023-08-14)
525
- Add `Makefile` targets for converting GitHub markdown files to PDF files.
626
- Update some sections in `README.md` and `USER_GUIDE.md`.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,15 @@ Here the quick summary of its features:
4141
- angle conversions: `>DEG`, `>RAD`, `>HR`, `>HMS`, `P>R`, `R>P`
4242
- unit conversions: `>C`, `>F`, `>km`, `>mi`, etc
4343
- base conversions: `DEC`, `HEX`, `OCT`, `BIN`
44-
- bitwise operations: `AND`, `OR`, `XOR`, `NOT`, `NEG`
44+
- bitwise operations: `AND`, `OR`, `XOR`, `NOT`, `NEG`, `SL`, `SR`, `RL`,
45+
`RR`, `B+`, `B-`, `B*`, `B/`, `BDIV`
4546
- various display modes
4647
- `RAD`, `DEG`
4748
- `FIX` (fixed point 0-9 digits)
4849
- `SCI` (scientific 0-9 digits)
4950
- `ENG` (engineering 0-9 digits)
5051

51-
**Version**: 0.3.3 (2023-08-14)
52+
**Version**: 0.4.0-dev (2023-08-16)
5253

5354
**Changelog**: [CHANGELOG.md](CHANGELOG.md)
5455

USER_GUIDE.md

Lines changed: 94 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
RPN calculator app for the TI-83 Plus and TI-84 Plus inspired by the HP-42S.
44

5-
**Version**: 0.3.3 (2023-08-14)
5+
**Version**: 0.4.0-dev (2023-08-16)
66

77
**Project Home**: https://github.com/bxparks/rpn83p
88

@@ -34,11 +34,12 @@ RPN calculator app for the TI-83 Plus and TI-84 Plus inspired by the HP-42S.
3434
- [Auto-start](#auto-start)
3535
- [Floating Point Display Modes](#floating-point-display-modes)
3636
- [Trigonometric Modes](#trig-modes)
37-
- [Base Functions](#base-functions)
38-
- [Base Modes](#base-modes)
39-
- [Base Rendering](#base-rendering)
40-
- [Base Integers](#base-integers)
37+
- [BASE Functions](#base-functions)
38+
- [BASE Modes](#base-modes)
39+
- [BASE Arithmetic](#base-arithmetic)
40+
- [BASE Integer Size](#base-integer-size)
4141
- [Storage Registers](#storage-registers)
42+
- [Prime Factors](#prime-factors)
4243
- [Future Enhancements](#future-enhancements)
4344
- [Near Future](#near-future)
4445
- [Medium Future](#medium-future)
@@ -86,7 +87,8 @@ Here the quick summary of its features:
8687
- angle conversions: `>DEG`, `>RAD`, `>HR`, `>HMS`, `P>R`, `R>P`
8788
- unit conversions: `>C`, `>F`, `>km`, `>mi`, etc
8889
- base conversions: `DEC`, `HEX`, `OCT`, `BIN`
89-
- bitwise operations: `AND`, `OR`, `XOR`, `NOT`, `NEG`
90+
- bitwise operations: `AND`, `OR`, `XOR`, `NOT`, `NEG`, `SL`, `SR`, `RL`,
91+
`RR`, `B+`, `B-`, `B*`, `B/`, `BDIV`
9092
- various display modes
9193
- `RAD`, `DEG`
9294
- `FIX` (fixed point 0-9 digits)
@@ -573,7 +575,10 @@ buttons just under the LCD screen. Use the `UP`, `DOWN`, `ON` (back), and `MATH`
573575
- `%CH`: percent change from `Y` to `X`, leaving `Y` unchanged
574576
- `GCD`: greatest common divisor of `X` and `Y`
575577
- `LCM`: lowest common multiple of `X` and `Y`
576-
- `PRIM`: determine if `X` is a prime, returning 1 if prime, 0 otherwise
578+
- `PRIM`: determine if `X` is a prime
579+
- returns 1 if prime
580+
- returns the smallest prime factor otherwise
581+
- See [Prime Factors](#prime-factors) section below.
577582
- `IP`: integer part of `X`, truncating towards 0, preserving sign
578583
- `FP`: fractional part of `X`, preserving sign
579584
- `FLR`: the floor of `X`, the largest integer <= `X`
@@ -662,6 +667,8 @@ buttons just under the LCD screen. Use the `UP`, `DOWN`, `ON` (back), and `MATH`
662667
- `ROOT` > `BASE`
663668
- ![BASE MenuStrip 1](docs/rpn83p-screenshot-menu-root-base-1.png)
664669
- ![BASE MenuStrip 2](docs/rpn83p-screenshot-menu-root-base-2.png)
670+
- ![BASE MenuStrip 3](docs/rpn83p-screenshot-menu-root-base-3.png)
671+
- ![BASE MenuStrip 4](docs/rpn83p-screenshot-menu-root-base-4.png)
665672
- `DEC`: use decimal base 10, set base indicator to `DEC`
666673
- `HEX`: use hexadecimal base 16, set base indicator to `HEX`
667674
- display all register values as 32-bit unsigned integer
@@ -675,6 +682,16 @@ buttons just under the LCD screen. Use the `UP`, `DOWN`, `ON` (back), and `MATH`
675682
- `XOR`: `X` `bit-xor` `Y`
676683
- `NOT`: one's complement of `X`
677684
- `NEG`: two's complement of `X`
685+
- `SL`: shift left one bit
686+
- `SR`: shift right one bit
687+
- `RL`: rotate left circular one bit
688+
- `RR`: rotate right circular one bit
689+
- `B+`: add `X` and `Y` using unsigned 32-bit integer math
690+
- `B-`: subtract `X` from `Y` using unsigned 32-bit integer math
691+
- `B*`: multiply `X` and `Y` using unsigned 32-bit integer math
692+
- `B/`: divide `X` into `Y` using unsigned 32-bit integer math
693+
- `BDIV`: divide `X` into `Y` with remainder, placing the quotient in `Y`
694+
and the remainder in `X`
678695
- `ROOT` > `STK`
679696
- ![STK MenuStrip 1](docs/rpn83p-screenshot-menu-root-stk-1.png)
680697
- `R(up)`: rotate stack up
@@ -820,6 +837,8 @@ The `BASE` functions are available through the `ROOT` > `BASE` hierarchy:
820837
- ![ROOT MenuStrip 2](docs/rpn83p-screenshot-menu-root-2.png)
821838
- ![BASE MenuStrip 1](docs/rpn83p-screenshot-menu-root-base-1.png)
822839
- ![BASE MenuStrip 2](docs/rpn83p-screenshot-menu-root-base-2.png)
840+
- ![BASE MenuStrip 3](docs/rpn83p-screenshot-menu-root-base-3.png)
841+
- ![BASE MenuStrip 4](docs/rpn83p-screenshot-menu-root-base-4.png)
823842

824843
These functions allow conversion of integers into different bases (10, 16, 8,
825844
2), as well as performing bitwise functions on those integers (bit-and, bit-or,
@@ -887,14 +906,23 @@ disabled.
887906

888907
> ![Numbers in Binary Mode](docs/rpn83p-screenshot-base-bin.png)
889908
890-
#### Base Rendering
909+
#### Base Arithmetic
891910

892-
Unlike the HP-42S, the `HEX`, `OCT` and `BIN` modes are simply *display* modes
893-
that only affect how the numbers are rendered. These modes do not affect any
894-
arithmetic or mathematical operations. In particular, the arithmetic buttons
895-
`/`, `*`, `-`, and `+` do not change their behavior in the `HEX`, `OCT`, `BIN`
896-
modes, in contrast to the HP-42S which remaps those buttons to the `BASE/`,
897-
`BASE*`, `BASE-`, and `BASE+` functions instead.
911+
Similar to the HP-42S, the `HEX`, `OCT` and `BIN` modes change how some
912+
arithmetic functions behave. Specifically, the keyboard buttons `+`, `-`, `*`,
913+
`/` are re-bound to their bitwise counterparts `B+`, `B-`, `B*`, `B/` which
914+
perform 32-bit unsigned arithmetic operations instead of floating point
915+
operations. The numbers in the `X` and `Y` registers are converted into 32-bit
916+
unsigned integers before the integer subroutines are called.
917+
918+
**HP-42S Compatibility Note**: The HP-42S calls these integer functions `BASE+`,
919+
`BASE-`, `BASE*`, and `BASE/`. The RPN83P can only display 4-characters in the
920+
menu bar so I needed to use shorter names. The HP-42S function called `B+/-` is
921+
called `NEG` on the RPN83P. Early versions of the RPN83P retained the keyboard
922+
arithmetic buttons bound to their floating point operations, but it became too
923+
confusing to see hex, octal, or binary digits on the display, but get floating
924+
point results when performing an arithmetic operation such as `/`. The RPN83P
925+
follows the lead of the HP-42S for the arithmetic operations.
898926

899927
For example, suppose the following numbers are in the RPN stack in `DEC` mode:
900928

@@ -904,24 +932,29 @@ Changing to `HEX` mode shows this:
904932

905933
> ![Base Arithmetic Part 2](docs/rpn83p-screenshot-base-arithmetic-2-hex.png)
906934
907-
Pressing the `+` button adds the `X` and `Y` registers, with no change in
908-
behavior from the `DEC` mode, including the hidden fractional part:
935+
Pressing the `+` button adds the `X` and `Y` registers, converting the
936+
values to 32-bit unsigned integers before the addition:
909937

910938
> ![Base Arithmetic Part 3](docs/rpn83p-screenshot-base-arithmetic-3-plus.png)
911939
912-
Changing back to `DEC` mode shows that the numbers were added normally:
940+
Changing back to `DEC` mode shows that the numbers were added using integer
941+
functions, and the fractional digits were truncated:
913942

914943
> ![Base Arithmetic Part 4](docs/rpn83p-screenshot-base-arithmetic-4-dec.png)
915944
916-
#### Base Integers
945+
You can perform integer arithmetic even in `DEC` mode, by using the `B+`, `B-`,
946+
`B*`, and `B/` menu functions, instead of the `+`, `-`, `*` and `/` keyboard
947+
buttons.
948+
949+
#### Base Integer Size
917950

918951
The HP-42S uses a 36-bit *signed* integer for BASE rendering and operations. To
919952
be honest, I have never been able to fully understand and become comfortable
920953
with the HP-42S implementation of the BASE operations. First, 36 bits is a
921954
strange number, it is not an integer size used by modern microprocessors (8, 16,
922955
32, 64 bits). Second, the HP-42S does not display leading zeros in `HEX` `OCT`,
923956
or `BIN` modes. While this is consistent with the decimal mode, I find it
924-
confusing to see the number of rendered bits change depending on its value.
957+
confusing to see the number of rendered digits change depending on its value.
925958

926959
The RPN83P deviates from the HP-42S by using a 32-bit *unsigned* integer
927960
internally, and rendering the various HEX, OCT, and BIN numbers using the same
@@ -948,7 +981,7 @@ the negative sign.
948981
Currently, the integer size for base conversions and functions is hardcoded to
949982
be 32 bits. I hope to add the ability to change the integer size in the future.
950983

951-
#### Storage Registers
984+
### Storage Registers
952985

953986
Similar to the HP-42S, the RPN83P provides **25** storage registers labeled
954987
`R00` to `R24`. They are accessed using the `STO` and `2ND` `RCL` keys. To store
@@ -970,6 +1003,47 @@ get to:
9701003

9711004
The message `REGS cleared` will be displayed on the screen.
9721005

1006+
### Prime Factors
1007+
1008+
The `PRIM` function calculates the lowest prime factor of the number in `X`. The
1009+
result will be `1` if the number is a prime. Unlike almost all other functions
1010+
implemented by RPN83P, the `PRIM` function does not replace the original `X`.
1011+
Instead it pushes the prime factor onto the stack, causing the original `X` to
1012+
move to the `Y` register. This behavior was implemented to allow easier
1013+
calculation of all prime factors of a number as follows.
1014+
1015+
After the first prime factor is calculated, the `/` can be pressed to calculate
1016+
the remaining factor in the `X` register. We can now press `PRIM` again to
1017+
calculate the next prime factor. Since the `PRIM` preserves the original number
1018+
in the `Y` register, this process can be repeated multiple times to calculate
1019+
all prime factors of the original number.
1020+
1021+
For example, let's find the prime factors of `119886 = 2 * 3 * 13 * 29 * 53`:
1022+
1023+
- Press `119886` `ENTER`
1024+
- Press `PRIM` to get `2`
1025+
- Press `/` to divide down to `59943`
1026+
- Press `PRIM` to get `3`
1027+
- Press `/` to divide down to `19981`
1028+
- Press `PRIM` to get `13`
1029+
- Press `/` to divide down to `1537`
1030+
- Press `PRIM` to get `29`
1031+
- Press `/` to divide down to `53`
1032+
- Press `PRIM` to get `1`, which makes `53` the last prime factor.
1033+
1034+
For computational efficiency, `PRIM` supports only integers between `2` and
1035+
`2^32-1` (4 294 967 295). This allows `PRIM` to use integer arithmetic, making
1036+
it about 7X faster than the equivalent algorithm using floating point routines.
1037+
Any number outside of this range produces an `Err: Domain` message. (The number
1038+
`1` is not considered a prime number.)
1039+
1040+
If the input number is a very large prime, the calculation may take a long time.
1041+
However, testing has verified that the `PRIM` algorithm will always finish in
1042+
less than about 30 seconds on a TI-83 Plus or TI-84 Plus calculator, no matter
1043+
how large the input number. During the calculation, the "run" indicator on the
1044+
upper-right corner will be active. You press `ON` key to break from loop, and
1045+
the function will exit the function with an `Err: Break` message.
1046+
9731047
## Future Enhancements
9741048

9751049
There seems to be almost an endless number of features that could go into a
@@ -978,18 +1052,6 @@ limited:
9781052

9791053
### Near Future
9801054

981-
- bit shift and rotation operators
982-
- shift left
983-
- shift right
984-
- rotate left
985-
- rotate right
986-
- arithmetic shift right (preserve sign bit)
987-
- `PRIM` (isPrime) is quite slow, about as slow as a TI-BASIC program.
988-
- Uses the TI-OS floating numbers and subroutines, which works pretty
989-
well for smallish integers.
990-
- Can probably make this significantly faster by implementing the algorithm
991-
using native Z80 integer operations.
992-
- (Need to write a `div(u32, u16) -> u32` function).
9931055
- `PROB` and `COMB` arguments are limited to `< 256`
9941056
- Maybe extend this to `< 2^16` or `<2^32`.
9951057
- `GCD` and `LCM` functions are slow
-6 Bytes
Loading
-24 Bytes
Loading
224 Bytes
Loading
254 Bytes
Loading

Makefile renamed to release/Makefile

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,31 @@ rpn83p.zip: $(TARGETS)
2626
zip -r $@ $^
2727

2828
# Convert markdown to PDF.
29-
README.pdf: README.md Makefile
30-
pandoc -V geometry:margin=1in -V fontsize=12pt -f gfm -s -o $@ $<
29+
README.pdf: ../README.md Makefile
30+
(cd ..; \
31+
pandoc -V geometry:margin=1in -V fontsize=12pt -f gfm -s -o $@ README.md; \
32+
mv -f $@ release)
3133

3234
# Convert markdown to PDF.
33-
USER_GUIDE.pdf: USER_GUIDE.md Makefile
34-
pandoc -V geometry:margin=1in -V fontsize=12pt -f gfm -s -o $@ $<
35+
USER_GUIDE.pdf: ../USER_GUIDE.md Makefile
36+
(cd ..; \
37+
pandoc -V geometry:margin=1in -V fontsize=12pt -f gfm -s -o $@ USER_GUIDE.md; \
38+
mv -f $@ release)
3539

3640
# Copy to local directory to place it at top level in the zip file.
37-
rpn83p.8xk: src/rpn83p.8xk
41+
rpn83p.8xk: ../src/rpn83p.8xk
3842
cp -f $< $@
3943

4044
# Compile the binary if needed.
41-
src/rpn83p.8xk: src/*.asm
42-
$(MAKE) -C src rpn83p.8xk
45+
../src/rpn83p.8xk: ../src/*.asm
46+
$(MAKE) -C ../src rpn83p.8xk
4347

4448
# Copy the animated GIF as a sample screenshot.
45-
rpn83p-example1.gif: docs/rpn83p-example1.gif
49+
rpn83p-example1.gif: ../docs/rpn83p-example1.gif
4650
cp -f $< $@
4751

4852
# Copy the animated GIF as a sample screenshot.
49-
rpn83p-example2.gif: docs/rpn83p-example2.gif
53+
rpn83p-example2.gif: ../docs/rpn83p-example2.gif
5054
cp -f $< $@
5155

5256
clean:

src/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ SRCS := \
1313
handlers.asm \
1414
handlertab.asm \
1515
input.asm \
16+
integer.asm \
1617
menu.asm \
1718
menudef.asm \
1819
menuhandlers.asm \
1920
pstring.asm \
21+
prime.asm \
2022
rpn83p.asm \
2123
vars.asm
2224

0 commit comments

Comments
 (0)