The file syslib_old.i is the version of the system library included in the original manual. RTFM for descriptions of the routines. Only minimal changes have been made in the current version, as follows: 1. Someone added PLEASE KNOCK BEFORE ENTERING as the first line, presumably to prevent programs from running off the end and into the first library routine by mistake. The other two changes are bug fixes. The bugs appear in all copies of the library that I have, including the manual from Don Woods (via Mike Ernst) with carriage controls in the first column. Unless a still more ancient copy of the library can be found (like in the Dead Sea Scrolls, perhaps?) we have to assume these bugs have been in there from the beginning, or at least since the library was converted from EBCDIC to ASCII and incorporated into the manual. 2. Jacob Mandelson found a bug in the 32-bit division routine where a select (~) had been substituted for a mingle ($) by mistake. This is at the end of line 229 of syslib_old.i. I have not checked or tested this correction, but it seems reasonable since select at that position would be pointless, but mingle is plausible. 3. I have found either two or three bugs in the 32-bit multiplication routines, depending on how you count. These only affected the overflow checking, but the effect was that every single call to (1540) or (1549) would behave as if there were an overflow. The first is straightforward. The statement PLEASE DO :1 <- ":3~'#65280$#65280'"$":5~'#652 80$#65280'" must be changed to PLEASE DO :1 <- ":3~'#65280$#65280'"$":4~'#652 80$#65280'" Not only is this the "right thing to do", but the position of this statement just after :4 has been computed suggests that it was what the original author intended. The remaining problems, however, are not so clearly due to typos. The 32-bit multiplication is done by splitting each input into its low and high 16-bit halves, computing partial products with the (1530) 16 to 32-bit multiplication routine, and then adding them together using (1509), addition with overflow check. The statements to look at are the ones where the overflow flags from successive steps are accumulated in .5, as follows: [a] DO .5 <- ':1~:1'~#1 ... [b] PLEASE DO .5 <- '"':1~:1'~#1"$.5'~#3 ... DO (1509) NEXT [c] DO .5 <- !5$":4~#3"'~#15 ... DO (1509) NEXT [d] PLEASE DO .5 <- !5$":4~#3"'~#63 DO .5 <- '?"!5~.5'~#1"$#1'~#3 .5 gets a bit if the high-high product is nonzero (wasteful to even compute this product, actually), and another if either of the high-low products overflows (that's the statement with the previous bug, above). It then gets combined with the overflow flags in :4 from the two addition calls. Each new flag is mingled with the ones already in .5, so various bits of .5 correspond to the different possible overflows. Finally, .5 is tested to see if it is nonzero, and if so an overflow results. Note the expressions ":4~#3". :4 is returned by (1509) as #2 if there is an overflow, #1 if not. It either case a bit is set in .5. This is why the routines signaled an overflow every time. Note also the ~#63 in line [d]. At this point the bit representing existence of the high-high product has shifted out to the 128-bit, so ~#63 will miss it. I see three ways out, none of which are obviously the author's intent: (1) At statement [d] the bit pattern is 101011XX, where 1's indicate overflows and X's are set by (1509) without overflow. If we replace ~#63 with ~#172 we test exactly the bits we want. This is the one I've used since it is the minimal change. (2) If we replace ":4~#3" with ":4~#2" we only have bits set on overflow, which seems cleaner. The bit pattern is 10001011 so we still can't use ~#63, we have to use ~#139 or ~#255 or something similar to get all the bits. Actually, the final selects in lines [b], [c] and [d] are all superfluous in this case since the bits discarded are all zero and the selected quantity can be safely assigned to the 16-bit .5. (3) If we replace ":4~#3" with ":4~#2" and reverse the mingles to look like '":4~#2"$.5' then the final bit pattern is 10111 and ~#63 will work, though it is not necessary. There are other solutions, of course, but I don't see any simpler ones than these. If you think ":4~#3" accomplishes nothing, so ":4~#2" must be meant, note that ":4~#3" converts :4 to 16-bit. The original compiler apparently required arguments to mingle to be 16-bit, whereas I think the C-INTERCAL compiler only requires them to be less than #0$#256. ":4$.5" would thus be technically illegal, even though it might work in C-INTERCAL. Louis Howell May 25, 1996