R-Tape wrote: ↑Sat Apr 18, 2020 10:13 pmPlease keep dumping.
Time for Dump Number Two (ooer, sounds a bit rude!): something I made in my last Spectrum-programming-frenzy that didn't last quite as long as I'd intended, but still made this. Presented as it was then... mostly.
INITIAL IMPORTANT NOTE BEFORE ANYONE ASKS ME: Although these were written on Spectaculator and just about everyone will only ever test them for two minutes on an emulator, they were written to be as easy as possible to use on a real Spectrum - right down to the original rubber-keys model which needed SYMBOL SHIFT for the decimal point and the simple mathematical functions. So I made the keypresses shift-free, i.e.:
To multiply 2.4 by 0.3 you'd need to press: 2, M, 4, ENTER (to put 2.4 on the stack), M, 3, B.
Were I to make a third "Spectrum Brain RPN calculator" I'd check for all the shifted keypresses (with either shift key), and probably run it though a compiler to see if that could make it any less slow. But I've got plenty more to be getting on with for now!
-------------------------------------------------------------------------
MARCH 2017...
I set myself a small challenge. Back in the mid-90s when I was still at school, my physics teacher, who was something of an Apple devotee (it was probably his decision that the school used Mac Plus, Classic and LC II models) as well as Hewlett-Packard RPN scientific calculators. He showed us how RPN worked and how it was different to the Casio and Sharp models we all had, and he showed us an RPN calculator program he'd written on an Apple IIe.
I could have done the same in my first enthusiastic stint here alongside the CCSCGC programs, but for whatever reason, it took until 2017 for me to get the idea that if my physics teacher of 20 years ago could write an RPN calculator program, why couldn't I? Why had I never tried to do it before?
So I did.
Download link: http://www.rickdangerous.co.uk/hammer/ms/zx/rpn.zip (contains all versions on this thread)
I'd already written a screen-drawing routine for a "ZX81 Brain" version when I realised, it was a bit ambitious to make a calculator with all the scientific functions I could fit on it, until I'd tested the routines I'd need to set up on a simpler four-function version which I've called the "ZX80 Brain". (Such names were the bottom two skill levels of
Starfire, the early, mostly BASIC-based release from Virgin Games that Codemasters would have called "Super Star Trek Simulator" - which is obvious when the game draws the ship's top and side views.) And I'm quite pleased that I've made some routines work in BASIC that I could never have come up with when I was a nipper:
- Loaded in the ZX80 character set (which I'd saved ages ago and I have a program to make defining character sets really easy).
- The number keys are all centralised into 2x2 squares by PRINTing them where I've put the stack with INK and PAPER the same, then reading the 6x7 areas with the POINT function and PLOTting them in the right place. If they'd only had to be centralised between two rows I could have used POKE 23606 to shift them vertically, but I needed to do it horizontally as well.
- Shown a "keypress on the screen" by temporarily turning on the BRIGHT channel for that 2x2 square and turning it off again when the process was done, with a POKE of the display file where the attributes are held. It may seem excessive to define an array - DIM z(90) - with 90 values, most of which are unused, but I'd read the keypress with LET i=CODE INKEY$, then z(i) would hold the address that needed to be POKEd (up or down by 64) for the top-left of the 2x2 square that I'd defined for that key on screen. It's four POKEs in total (value, +1, +32, +33).
I am not an advanced programmer by any means, I know next to nothing about machine code. But seeing as this is my level, shown here, imagine my delight when I managed to get those last two routines above to work without consulting anyone who would be able to do it in five seconds. That's the crucial point.
(NOTE: the BRIGHT channel POKE is something I'd use a lot more regularly these days, now that I know how it's done.)
Other things I managed to check for, given that the number at the bottom of the stack has to be held in a string and that makes it harder, is:
- only keys shown on screen will actually do anything
- you're not trying to divide by zero
- the stack won't fill beyond 17 values or empty beyond a zero stored at the bottom
- the decimal point can't be entered twice
- there's no exponential key (in this version) but it checks to see if there is one anyway, for calculated values that are beyond 99,999,999
- leading zeroes aren't entered
It's slow, I know that - because I've written it in +3 BASIC which goes mad if I try to use redefined character sets on the BASIC editor, I've had to POKE 23607,249 every time I want to PRINT something on the stack, and POKE 23607,60 at the end of the subroutine every time. Hence I thought the "ZX80 Brain" was an appropriate name. For the "ZX81 Brain" version I could use the standard character set, but I thought I'd make it a bit like the early Sinclair RPN calculators and redefine 0-9, E and + to make it look like a seven-segment LED display in the stack, so I'll have to keep those POKEs in.
I know what you're all thinking: "...but the ZX80 couldn't handle decimals!" Well... like a "ZX80-and-a-half", if you like, it can handle decimals, but doesn't always get it right when checking that there is one. I've set two variables as flags - d and e, set to either 0 or 1. d=1 if there's a decimal point in the value at the bottom of the stack, e=1 if there's an E+ value in there; if one appears as the result of a calculation, d and e are both automatically set to 1. I've set d to 1 if the M key (for .) is pressed, and both d and e back to 0 once the ENTER key is pressed and that number is moved up the stack. I've used the variable o to hold the result of a calculation before the stack is moved, and I've checked:
IF o=INT o THEN LET d=0
IF o<>INT o THEN LET d=1 (both lines are in just to make sure)
IF o>=1e8 THEN LET d=1: LET e=1 (because such a number will be held in scientific notation, and even if it's one digit with no decimal point such as 1E+8, the decimal point key needs to be disabled anyway until this number is put into the stack).
Whatever I do, I find the decimal point flag gets stuck on and it beeps at me as if there's a decimal point there, even when there isn't. Sometimes it's because the display is holding a non-integer value but it can't display the decimal point because there are too many digits, other times it's a mystery.
And just to make it look like I'm doing a thorough job, the ZIP package contains the program in tape, +3 disc and microdrive formats, all with the LOAD command for the character set modified appropriately!
-------------------------------------------------------------------------
LATER IN MARCH 2017...
Hey! Great news! I've upgraded the "ZX80 Brain" calculator to the new "ZX81 Brain" version, complete with scientific functions - at least, as many as I could jam onto the screen and make work.
Download link: http://www.rickdangerous.co.uk/hammer/ms/zx/rpn.zip (contains all versions on this thread)
Updated package includes:
- Tape (.TZX), microdrive (.MDR), +3 disc (.DSK) formats;
- Each of these contains the program, separate screenshot and redefined character set for the ZX80 Brain and ZX81 Brain versions of the calculator;
- ZX Printer listings for both the ZX80 Brain and ZX81 Brain calculators, taken from the tape format - in Spectrum graphics as a .PNG image and outputted to text as a .TXT file;
- Documentation, mostly adapted from the wordy waffle in these two posts.
The screen for the "ZX81 Brain" calculator was designed first, with 30 keys in a 6 × 5 array - the space for the top two rows in the "ZX80 Brain" version was instead filled with the ZX80 logo. I hadn't decided what extra scientific functions should be added on the top two rows when I switched to the "ZX80 Brain" version, so it gave me time to work out the best permutation of such functions.
For the "ZX81 Brain" version I could have used the standard character set, but I thought I'd make it a bit more like the early Sinclair calculators and redefine 0-9, E, + and - to make it look like a seven-segment LED display in the stack. This has meant I have had to keep all the constant swapping between the redefined character set (POKE 23607,249) and the standard character set (POKE 23607,60) to ensure the screen doesn't fill with junk in 128/+3 BASIC. (It's annoying, because I'd have liked to see the listing for the "ZX80 Brain" calculator in the authentic ZX80 font!)
The extra features the "ZX81 Brain" calculator adds over the "ZX80 Brain" are:
- a fifth "regular" function, the power key;
- the plus/minus key and the ABS function to convert any value to always positive (which was really a result of me having one key spare and not wanting to waste it...);
= a routine will disable trying to negate zero; ABS has no effect on zero
- trigonometric functions SIN, COS, TAN;
= the routine can check for values where TAN has an asymptote, but though it is correctly coded it won't always work (see "known problems" below)
- logarithmic functions, ln and log10;
= a routine disables taking logarithms of zero or negative numbers
- pi key
- reciprocal key;
= a routine will disable taking the reciprocal of zero
- square root key;
= a routine will disable square roots of negative numbers
= this is intended as a short cut, other roots are available by calculating powers of reciprocals e.g. cube root of x = x^(1/3)
- an exponential key allows values up to 10^38 to be entered (beyond which the program will stop with "6 Number too big" - see "known problems" below);
- an inverse function key, which inverts five functions and extends the exponent
= press it and the BRIGHT channel stays on until the next key press
= logarithm functions are inverted; ln becomes e^x, log10 becomes 10^x
= trigonometric functions are inverted; SIN, COS, TAN become ASN, ACS, ATN respectively
= a routine disables calculating ASN and ACS for values greater than +1 or less than -1
= using the INV key before the EXP key produces "E-" on the current entry instead of "E+" and allows entry of reciprocal scientific notation
= the key is always reset after the second key press; it will have no effect on any keys other than these six
- a redesigned screen to reflect the black, red and white of the ZX81;
- the aforementioned seven-segment character set, in bright red to look like glowing LEDs.
In a horrible twist of irony, the extra features added to the "ZX81 Brain" calculator - which mean many more key presses to check for in each program cycle - have slowed it down to the point where it really struggles with a full stack, particularly when executing a single-value function - there are more of these and five have inverses, which means there are a lot of lines of code to execute every time one is used! So the "ZX80 Brain" calculator is faster for the basics, the "ZX81 Brain" calculator can do more. (Of course, you could just use the Spectrum's functions in BASIC, I've just made them look flash with all my screen POKEs!)
Features I haven't managed to get on this calculator (and would never have been likely to anyway) are:
- non-decimal number bases (binary and hexadecimal at least) and the ability to convert between them;
- complex numbers;
- logical operators NOT, AND, OR and XOR;
- angle measurements other than radians (degrees, mils, grads... whatever they are!);
- degree-minute-second notation;
- fractions;
- hyperbolic functions (though these can be calculated with exponential identities);
- derived trigonometric functions (SEC, CSC, COT - though these can also be calculated with reciprocals of COS, SIN and TAN respectively, and has anyone ever seen these on a scientific calculator, let alone an 8-bit micro?)
- average and standard deviation calculated from all the values entered into the stack.
Known problems:
- doesn't always recognise when a number no longer has a decimal point, usually because there is a very small decimal in the string that the number display can't handle when it tries to print VAL of the string.
- no exponent key, but the calculator can handle numbers from 10^8 to (somewhere between 10^38 and 10^39) as the result of a calculation. Any calculation that exceeds 10^38, or an attempt to press number keys that take the exponent above 10^38, will crash the program with "6 Number too big". (This also happens with exponents below -38.)
- exponent key added; so far there appears to be no easy way to prevent the exponent from exceeding 10^38 accidentally, or as the result of a calculation. (Believe me, I tried, and setting the correct flags, trying to read the exponent as a separate part of a string called f$ and a numerical value f (=VAL f$) at the same time without one or the other getting out of hand was huge, convoluted, slowed the program down even further, and never worked properly. Just be careful around large numbers, right?)
- PI is stored to 7 decimal places. Trig functions work OK except in certain cases where the value of the trig function should be 0 but the accuracy of the stored value of PI is not enough and the function returns the value 7.3145904E-10.
= e.g.: if X = PI*0.5, COS X should be 0 but returns 7.3145904E-10; the same result occurs with COS of-PI*0.5. Strangely, using PI/2 returns the correct value 0. Higher values of X where COS X should equal 0 - i.e. PI*1.5, PI*2.5, etc - are fine whether using PI*1.5 or 3*PI/2. TAN of -PI does the same and TAN of multiples of -PI returns the same multiple of the inaccurate value - i.e. X = 2*PI, TAN X = 2*(7.1345904E-10).
= annoyingly, this means the attempt to check for asymptotes in the TAN function fails for any value of X for which this program will return COS X = 7.1345904E-10; this is because it does not recognise the variable OT = ((s(1)+(PI/2))/PI as being an integer (because it's very slightly off, not even enough for the display to handle) and an attempt to evaluate TAN X returns a very large value that crashes the program with "6 Number too big". The routine does at least work in theory - divide PI by 2 (don't multiply by 0.5!), COS returns 0, TAN will beep for an error.
-------------------------------------------------------------------------
As I've been asked to do, when I'm done with these weekly dumps (and there might only be one more unless I get digging) I'll allow them for submission to ZXDB. Anyway, have fun with this little lot, if you weren't too traumatised by maths lessons at school all those years ago.