I’ve already posted about the fun I’m having with the Z80 singleboard computer (kit from CPUville) recently.
In addition to a FORTRAN compiler (Microsoft F80), I added the High Tech C compiler. I’ve written programs in FORTRAN, C and 8080 Assembler. I’ve used both the CP/M 2.2 ASM assembler and the M80 assembler that came with the F80 compiler. Except for one instance where my port reading assembly program won’t actually read the port, it’s been fun and games.
I’ve even created assembler programs that can be called from FORTRAN (the aforementioned port reading routine).
Last week, while exploring the various archives of CP/M software, especially compilers, I spied the DEC PL/I compiler. That looked really promising.
Back at my first job after my B.Sc., I worked at an IBM shop that sent me on a PL/I course. Afterward I spent the next year writing software in PL/I for a pair of IBM 3033 mainframes. It was all great fun.
Finding a working PL/I compiler was too good to pass up, so I grabbed the archive and beamed them to the Z80. After a bit of digging, I found my 1980 PL/I reference book, “PL/I Structured Programming” by Joan K. Hughes (2nd edition, Wiley, 1973). After reading through it to refresh my memory, I started building a few PL/I programs, following the examples in the book and then the chapter problems.
Some features of the IBM compiler were not available in the DEC (CP/M) version, but I had the DEC PL/I documentation to help me with the transition. Eventually I had written several working PL/I programs.
The past few days I’ve been playing with a Taylor series program for calculating Sin(x) (x in radians). I have the program working, but the answers diverge from ‘actual’ values in the range PI to 2PI. I had full debugging in the code, but could not really see the reason.
I decided to try converting the PL/I program to C, and then running it on a modern C compiler on one of my Ubuntu 18.04 servers.
SURPRISE!!! The C program has the exact same divergence! Even switching from ‘float’ to ‘double’ didn’t remove the divergence in the C program on a modern machine. I’ll definitely have to investigate further.
Just for fun I then took the working C program and beamed the code over to the Z80. The High Tech C compiler is sound, so it compiled the program easily. The run on the Z80 gave the exact same answers (with a small nod to precision on various platforms) as both the C/Linux version and the PL/I CP/M version. It’s either a really difficult to find coding mistake in my work, or a real phenomenon. As I said, I’ll have to investigate.
Where it all gets cute is timings. On the Linux box (big AMD 6-core server with loads of memory) the C program runs so fast it would be timed in milliseconds were I to try. Certainly faster than one could manually time it. The PL/I program on the Z80 takes 3min, 40.15 seconds to run. What was a surprise is the C program on the Z80 took 5min, 34.40 seconds! I never expected a C program to be that much slower than the PL/I program.
Now that I have FORTRAN, PL/I, C and Assembler all working, time to continue playing.
One last thing: I found a printing “bug” in the PL/I textbook. The formula for the Sin(x) Taylor series has two major errors. First, the terms have a denominator that is (2n+1)! (factorial), or 3!, 5!, 7!, 9! in the expanded formula found in the book. But some typesetter must have thought that an error, as the book has replace the ! with 1, giving denominators of 31, 51, 71 and 91. Not a small error when you are coding!. The other error is the terms alternate in sign (-1**n) so x-a+b-c+d and so on. The book had all + signs.
When debugging the massively incorrect results, I simply did a google search on ‘series solution of sin(x)’ and found the correct formula, then coded that. It is that corrected formula that still diverges from actual results for values of ‘x’ greater than PI.