blog:pushbx:2026:0304_late_february_early_march_work_on_warplink
Late February (+ early March) work on WarpLink
WarpLink
-
-
-
-
-
Split wllist errors into multiple error codes. Each one has a unique "problem" line while the "cause" and "solution" lines are shared across all of the wllist errors.
-
-
Comment on the GRP_ENT_STRUC structure, and add a label to it (ges_flags). The comments include a bug: Two instructions both write to the same field of the structure, with different contents.
-
-
-
-
Hack mlerror.nas
so it shows only a symbol for wlcalc errors. The problem that this was to solve was that the wrong filename would show up in the error messages, as the
filename variable at this point held the last object's name, not necessarily that of the object in which the wlcalc request originated.
-
-
Add the twlObjIndex field to the tempwllist structure, and use it to recover the correct object filename that originated a wllist label. This re-uses .get_object_filename of the wlcalc code, adding in three push and three pop instructions to preserve the variables used by get_curr_obj. (These variables need to be preserved if the error were to be handled as a warning, to allow the remainder of pass 1 and all of pass 2 to access the correct object files.)
-
Add the WRT clause for EXT operations. To simplify parsing, WRT is treated as an operation that comes first, followed by a segment or group name, then followed by the actual operation - which must be one of the EXT-related operations. To allow underscores in WRT segment names, an '@' sign can be used which is followed by a quote mark byte (usually a second @).
-
-
-
-
-
-
-
-
-
-
-
Fix the image_size variable if the last section is empty. This undoes the prior changeset. An empty section would leave the segment_stop variable equal to the segment's start, ie the total size of the image at this point. But the code expected segment_stop + 1 to yield a size, assuming that segment_stop pointed
at the last byte, not past it. All users of image_size seem to assume it holds a size, not size+1, so this patch addresses the root cause of this assumption being wrong.
Add the ITOA operation, which formats a number into text. As yet the input and output buffers are the same size, limiting the range of permissible numbers. The numeric base (assumed as 2 ⇐ base ⇐ 36) is passed in the constant given to the ITOA operation.
Allow to enlarge the output buffer for ITOA, to up to 10 bytes. This trades off the slightly larger stack frame in handle_wlcalc (for
all wlcalc operations) for the simplicity of expanding the output buffer for ITOA. Buffer size is passed in ch (ie, the second-least significant byte of the constant value).
Add the ITOA
flags for filling with zero digit text rather than blanks, and for shuffling the buffer so padding ends up at the end instead of the beginning. The shuffle operation was a little tricky to get right. First I reset bx within the innermost loop, causing it to run infinitely. Then I left the initial load of al in the innermost loop, overwriting everything with the padding. At some point I operated on the total buffer size rather than only the part populated according to ?size. Finally I had fixed the pointers but still counted down bx to the total buffer size (negative) rather than the used buffer size. I also found it difficult to track how the shuffling works, but the basic idea is sound.
Explicitly check for ITOA bases 0 and 1, which would result in a divide exception and an unbounded loop respectively (though the overflow detection should eventually bail you out of the loop when the buffer is full of zeroes).
-
-
ETA 2026-03-04:
-
-
Fix cutting the 256-byte prefix with /TZ /C switches. This error could occur in the original WarpLink revision, but only if the setup_exe_image function (in mlimage1.nas) found more than 20 KiB of free DOS memory but below what would be needed to hold the entire executable image. (Note that the progbits image size used to be limited to <= 64 KiB minus the 256 Bytes prefix.)
-
-
-
-
Add DOS error code -2 for "short read", and set it when detecting a short read in several spots. This doesn't fix all possible cases of short reads as yet. As the custom "solution" text states, a short read is likely to be an internal error of the linker.
Add the /XCW switch, treat /XC wlcalc "unknown" errors as warnings. This is useful to enumerate multiple wlcalc errors at once, rather than having to fix them one by one to discover the next one. The wlcalc overflow errors are unaffected. This also adds an /XLW switch for wllist, though this is less useful.
Fix
to reset es after the _wlcalc_get_segdef_entry or _wlcalc_get_grpdef_entry functions. This seems to have caused some funny crashes. It now makes use of the fact that these functions leave ds => DGROUP.
Fix:
Do not zero the file_mod_id field of segpart structures. I don't know why this should be cleared here. According to the comment next to it, it was "overwriting [the] unneeded file_mod_id". I don't know whether "unneeded" means this was merely to tidy up loose ends and not really needed (I hope!) or whether there is more of a reason why this should be done. In any case, it foiled my attempt to use the segpart structure's object index to get the correct object filename for wlcalc errors. I didn't notice the failure before working on lDebug's _LINK option because the clearing would set the field to zero, which is a valid object index and would appear to point to the first object file.
-
-
Add optional digit groups with separators to the ITOA wlcalc operation. This adds a rare use of an "inner" lframe, which re-uses the bp as set up by the outer frame (actually a non-emitting copy of the handle_wlcalc lframe here). By using lpar and lpar_return, the minimum amount of instructions (exactly 1) is used to modify sp in the function. In this case, access to the outer lframe isn't needed, but using the inner frame is still advantageous as compared to using a "nested" lframe because it uses fewer setup instructions. Also in this case, the outer frame could be used as is to add more lvar variables – but this is possible only once, whereas the inner lframe can be used for multiple functions with possibly different inner stack frames.
-
blog/pushbx/2026/0304_late_february_early_march_work_on_warplink.txt · Last modified: 2026-03-04 17:14:00 +0100 Mar Wed by ecm