Table of Contents
Early July work on x2b2 and LZEXE
2025-07-06
x2b2
In getnum, allow underscore separator in /L= and /J= numbers, and reject hexits >= A if reading a decimal number. These changes were picked from LZEXE's COMTOEXE.
Optimise the Done code and optimise BinToStr. The latter now has two entrypoints. The first accepts a table made of a dword field (at dword [di - 5]), a byte field at byte [di - 1], and di -> the message. The byte field gives the offset in the message of the 10 blanks which represent the slot for writing the decimal number as a string. The second entrypoint doesn't take a dword field but rather reads dx:ax as the input number.
The new BinToStr can pick up the number, format it, and finally display the resulting string all in one go. This saves a lot of code in the callers. Except for one case, the variables used were moved from their original places into the message tables.
I did experiment with a further optimisation to drop the blanks from the message templates. However, trading these for some code led to increased file sizes once x2b2.com was converted to an .exe and compressed using LZEXE. The current revision compresses to exactly 2560 Bytes (5 sectors).
LZEXE
- INFOEXE: fix some WriteL calls that used to do word calculations instead of longint.
- COMTOEXE:
- Add stub choice 2 with switch /2, and switch /0 for original LZEXE v0.91 behaviour.
- Add /P=x switch to set minimum sp for /2 stub.
- Add /A=x switch to set minimum allocation.
- Reject empty file and fill main buffer initially.
- Add heuristic that scans for
cmp sp, imm16to automatically set minimum sp. - Display message if auto detection of minimum sp fails.
- Display two sizes for /2 stub.
- doc: List COMTOEXE switches.
- Display only process+image size for /0 or /1 (not irrelevant alloc+128).
- Ignore /A= switch if not /2, and add range checks for /A= and /P=
- Fill the full buffer initially (32 KiB), and process an initial jump, and search it for cmp sp instruction.
- Limit the cmp sp heuristic to 128 bytes again (after following the initial jump).
- doc: Update news.
- Indicate FPC build or TPC build in intro.
- Increment ecm release (of all tools) to release 3.
- Optimise a jump in exepack2.obj and exepack3.obj (chain one jump to another so it can be short).
Planned: lDOS COMLOADER
I am planning to add support for MZ EXE files to the COMLOADER. This would allow loading LZEXE compressed files.
There are some hurdles:
- Need to have enough memory to fulfill the minimum allocation of any executable.
- Need to shrink or grow memory to fit the minimum and maximum allocation of the executable.
- Need to switch stacks to header-indicated stack. (It can be assumed it points within the image or minimum allocation.)
- Need to transfer control to header-indicated entry.
- Need to set up ax, ds, es.
My plan is to:
- Allocate enough (in the real iniload MZ exe header) to fulfill the minimum allocation + relocated loader + loader stack.
- Relocate the loader.
- Apply relocation table to the image.
- Relocate the image.
- Set up the desired stack.
- Put a stub on the stack, and branch to it. This stub does:
- Resize the process memory block with maximum allocation. Will always at least get the minimum allocation.
- Set up ax, ds, es.
- Return far to desired entry, popping the stub off the stack.
This should solve all the problems. I considered previously to allocate a separate memory block, but this may require setting up the UMB link and would need more logic to ensure that the minimum allocation is met. Splitting the process MCB on our own would be a possibility but would make it less portable.
