Using the new function ROUNDX (see previous chapter) I now was able to change the floating point output. The floating point values are implicitly rounded to the needed decimal position before output; on both platforms, BTW (because sprintf et. al. don't do it right - no correction).
What made things complicated at this point:
WRR (write real) is a CSP function which is implemented in PASMONN.ASS on Hercules/VM. I wanted to call the Pascal function ROUNDX1 (which is implemented in PASLIBX.PAS) from this WRR function, but this was not supported up until now.
So I first tried to built an environment in PASMONN to be able to call a Pascal function from there; this required to understand the save area layout etc. that Pascal uses. The save area layout is the same, but the actions done in the function prologue and epilogue are quite different from MVS and VM standards. Anyway, I finally succeeded in building the environment and in calling the Pascal function from PASMONN.
But then, the program looped. As it turned out, the called Pascal function called another CSP (FLOOR, BTW), and the static save areas of PASMONN were overwritten on this second (recursive) call.
So I had to rethink about this. In the end, I managed to change $PASCSP (the part of PASMONN that implements the CSPs) in such a way that it does not provide its own save areas but it uses instead the Pascal stack to put its save areas there. This way, recursive calls are possible.
There are some drawbacks:
old calls to CSPs still come from PASMONN etc. and still need to be supported (two different strategies)
the new calling sequence for CSPs is a little bit more expensive (CSP number is communicated via storage, ST and L instructions involved etc., increment to stack register)
I tried to optimize the new calling sequence a bit by removing some reloads of the stack address register, which seemed unnecessary, but that did not work. Maybe some more examination and improvements can be done later.
Anyway:
At the end of this long story, the output of the floating point values of the old subway train speed program was exactly the same on both platforms.
If I've had this compiler available in 2001, it would not have been necessary to convert the program to C.
Floating point arithmetic seems to work correctly on all platforms
Output of a test program; the second column is printed without explicit rounding (using WRITE (x : 7 : 1)); the third column is printed with explicit rounding - as you can see, there is no difference:
|
Another test: here the same value is printed using different 2nd parameters for roundx. You can see the effects of roundx, but you can also see at this precision printed the "correction factor", which is x * (1E-13). This, BTW, is NOT the correction factor from ROUNDX, but is is instead another correction implied by WRR (write real) - which was 1E-12 before my change, BTW. It helps to move the value above the critical limit; without this correction, most values printed would be wrong. The correct value is 71.219154.
|
Another success story:
The size of the $PASCSP routine is almost 8k, and it is covered by two base registers (10 and 11). Some times during test, I already got addressability errors (when adding trace output etc.).
I managed to move some of the larger "procedures" to the end of the $PASCSP routine and make them define and use their own base register (11), so that the addressability restrictions on the $PASCSP mainline are removed (because it has become shorter). This way $PASCSP as a whole can become much larger than 8k, while still requiring only two base registers - which opens the way for further enhancements.