Restored F80 compiler code for CP/M
github.com
github.com
At that time I have also disassembled a part of it, but not the compiler executable.
I have disassembled the Fortran runtime library used by the compiler for generating code.
Disassembling the library was more useful, because I wanted to modify some of the standard functions, e.g. be replacing the multiplication algorithms with faster algorithms.
Because the target CPU for the compiler were the 8-bit processors compatible with Intel 8080, which could perform in a single instruction only very simple operations, the code generated by the F80 compiler consisted mostly in a sequence of function invocations for functions from the runtime library.
Even a 16-bit multiplication or a 32-bit addition were operations complex enough to be done by library functions.
So the runtime library included a set of functions for implementing all the Fortran operators and all the Fortran intrinsic functions, for all the sizes of floating-point numbers or integer numbers, including operators with mixed operand types, e.g. besides functions for multiplying double precision numbers or single precision numbers there were also functions for multiplying a double-precision with a single-precision, or a double precision with a short integer, or a single-precision with a long integer, and so on.
So there were many functions in the runtime library. The reason why separate functions for mixed types were used instead of applying implicit conversions, was that multiplication, divisions and other such operations were very slow on 8080/Z80 (requiring many milliseconds, instead of much less than a nanosecond on modern CPUs). So taking advantage that one of the operands was smaller could make the function faster.
I guess all we really have to go on is cfront or early gcc (1.15.3 was the first version with a c++ front end). We also have Walter Bright's Digital Mars compiler but how different is this from Zortech?
Pretty horrible. I attempted to use the E (education) release of cfront, and failed miserably (couldn't install it).
I then was forced to use the Glockenspiel compiler (based on cfront) and running on OS/2 (eek!) who's favourite error message was a core dump - this was at a training company, and the combination of very bad error messages and OS/2 was not popular with our clients.
The Zortech compiler was the first good one, and then Microsofts. Then IBM came out with a very good one on AIX.
I may well have got the sequencing wrong here - so long ago and far away :-)
And of course many people in SE Asia are still being damaged by still being taught using Turbo C++ when they could be usefully using GCC or clang.
Reason number X for someone to work on semi-faithfully cloning that MS-DOS-era TUI interface so that it can work as an IDE on modern systems and compilers, piggibacking on things like LSP servers. It was done already for the Pascal version ("fp" ide), and we also have things like QB64. Hopefully it's just a matter of someone being inspired to do the work.
https://web.archive.org/web/20160321050842/http://www.aljex....
It's like an X11 rendition of the Borland tui.
It didn't have a logo or icon so I made one. (several crap ones actually)
Now the modern system I was using that emulated-old-thing on is itself even older than turboc was at the time.
What anyone does or doesn't do with that which is possible is no excuse to tolerate, let alone advocate, things being not-possible.
ZTC++ came out, and a ton of magazine articles came out about C++ using Zortech C++. ObjectiveC fell away, and most of the C++ programming was in ZTC++.
Zortech, Borland, Watcom, Metaware all beat Microsoft to it, which released their first support on Microsoft C/C++ 7.0, their very last MS-DOS compiler.
In the end, I have used mostly the Microsoft C++ compiler, but not because I had noticed any problem with the Borland compiler, but because the library delivered by Microsoft happened to include some functions that I needed frequently, and which were missing in the Borland library.
Because at that time there was no standard, even if the language accepted by the two compilers was mostly the same, the libraries were quite different.
I do not know how well templates worked in those early compilers, because I did not attempt to use templates in any program written during those years.
Except for templates and for multiple inheritance, which I have used only seldom, I had exercised all other language features in some complex programs, which simulated some physical models.
In general using C++ at that stage was, at least for me, a pleasant experience in comparison with the earlier use of languages like C, Fortran, Pascal or Basic. Because my programs included a lot of complicated formulae whose operands were matrices or vectors of complex numbers, I have especially appreciated using overloaded operators to reduce dramatically the size of the formulae, making them much more easy to read than in my earlier programs.
In my opinion, the Java creators had some weird mental problems, because they believed that it is better to write and read something like:
cplx_vector_add(A, cplx_vector_sub(cplx_mat_vec_mul(B, C), cplx_mat_vec_mul(D, cplx_mat_vec_mul(E, F))))
instead of writing and reading something like:
A + B * C - D * E * F
(The formulae that I had to use were much more complicated than in the example above, so the reduction in text size was much larger)
I did not have any complaints about the performance of the compilation or execution of the programs.
I have found once a bug in a certain version of the Microsoft C++ compiler, where depending on the order of some declarations, for which there was no reason to be significant, either correct or buggy code was generated. However the next compiler version no longer had the bug.
Both the Microsoft C++ compiler and the Borland Turbo C++ compiler had superb documentation.
Even without knowing anything about C++ and without any other books or publications on the subject (and obviously without Internet), just reading carefully the set of manuals provided with the compiler was enough for becoming a good C++ programmer (assuming that you were familiar with programming in any other language).
I think that actually the largest difference that I feel when I compare now an early C++ compiler with a current C++ compiler, is not that the current C++ language has 5 times more features than early C++, but that the early compilers were paired with a huge quantity of documentation, which seemed to have required about as much writing effort as writing the compiler.
It's the same compiler, but upgraded for C++98. It's Open Source now.
It would have made very little sense for a company willing to make a FORTRAN 77 compiler to target already obsolete microprocessors, instead of targetting the state-of-the-art Intel 8086/8088 or Motorola MC68000.
The Microsoft F80 compiler would have indeed been useless for anyone having unlimited access to a CPU more powerful than a Z80.
Nevertheless there were many who had to be content with an 8080/8085/Z80. For them, there was nothing better than Microsoft F80 for serious numeric computation.
FORTRAN IV was the language in which a huge amount of high quality numeric computation libraries were easily available. No library was available in Fortran 77 at that time.
The language implemented by F80 was pretty standard. It lacked many extensions frequently provided by other compilers, but that did not matter much, because the libraries that you would want to use were written to use only strictly standard features, and not vendor extensions.
Before using MS F80, I had used IBM mainframes and DEC PDP-11 minicomputers. I do not remember any special difficulty in porting the IBM/DEC Fortran programs to MS F80.
Obviously, an 8080/Z80, when doing floating-point computations, was between 10 times and 1000 times slower than an IBM or DEC computer with hardware FPU.
Even so, for me, passing to MS F80, where I had exclusive access to the computer 24/7, was a huge progress in comparison to using a shared mainframe or minicomputer, and I could be much more productive, despite the slow computer.
I'm glad that you were able to port your code from DEC FORTRAN IV. I may be younger than you because I learned FORTRAN 77 first, but IIRC Microsoft's F80 had some serious shortcomings and was not a "full" implementation of FORTRAN IV. That's probably why they called it "FORTRAN 80" instead.
- No COMPLEX type - Specification statements must be ordered FUNCTION/type/COMMON/EQUIVALENCE/DATA/statement functions - differing storage requirement for types
then again, even MATLAB (for example) doesn't need COMPLEX
I do not remember that they have bought any CP/M compiler.
In any case, I can guarantee that the Microsoft Fortran compiler was written by the same people who had written the Microsoft Basic interpreter.
I have disassembled both the MS Fortran and the MS Basic for CP/M, and they shared many unusual tricks.
For example both Microsoft programs included machine instructions that were executed with different meanings, depending on whether the instruction was entered sequentially or by a jump in the middle of the instruction.
A frequent use of this technique was for skipping the first instruction of a loop, when the loop was executed the first time (e.g. for skipping the incrementing of the loop counter after the initial value is assigned to it).
This was done by using a 3-byte load-register-with-immediate-value instruction, which loaded a 16-bit register with a 2-byte constant, but then the register was not used, so the load had the effect of a NOP.
At the end of the loop, there was a jump to the initial load instruction, but not to its beginning, but 1 byte later. So starting from the second execution of the loop what had initially been interpreted as 16-bit constant to be loaded in a register, was interpreted as an operation code and executed.
The net effect of the trick was that the program code was shorter by 2 bytes for each occurrence of the trick, in comparison with a program written in the standard way, where a jump instruction would have been needed to skip the first instruction of the loop.
The trick had the added benefit that it would confuse naive automatic disassemblers, which would attempt to disassemble sequentially, instead of disassembling by tracing the execution.