2025-01-19
This week I first uploaded some changes from the last 20 days concerning an adaptation of the MS-DOS v2.11 buffers subsystem to the lMS-DOS code base. Then I worked on splitting the DOSCODE segment from DOSDATA. This work isn't finished: While the split is done, it is not yet useful. But the hardest part seems to be done.
This older repo, based on the free software release in 2018, received an update. I used a perl scriptlet to strip non-printable ASCII codepoints from the assembly language source files. This allows to view the files as text using the hgweb server.
The scriptlet is perl -i -pe 's/[\x00-\x08\x0B\x0C\x0E-\x1F]/ /g' *.ASM
Two updates: Harden a non-default code path in init, and document the DOSSPACE Extension for lDebug (ELD).
Pick a change first done on lmacros2.mac in the lMS-DOS repo. Allow the use of lframe -2
(in 16-bit code) to enable using the macros without pushing the BP register to the expected spot.
This is used in lMS-DOS's function restore_world
which has the final output BP within its stack frame so we do not want to additionally push the input BP. This is achieved by combining lframe -2
with several lpar
uses, and an lemit off
followed by lenter
. After the non-emittng lenter
we place a manual mov bp, sp
which sets up the Base Pointer register to the right offset to allow access to the declared parameters. As is usual for more complex stack frames we clean up with an lleave ctx
mmacro call.
Document that the LBA set type byte may be expected for MS-DOS v7 load protocol. Inspired by a mention on the retrocomputing stackexchange.
Fix a typo in prior changeset.
This work results in a build-time choice of two different buffer subsystems: The original MS-DOS v4 one with hash buckets, a secondary cache, and ability to use EMS for buffers, and the transplanted MS-DOS v2 one with some adjustments to work with MS-DOS v4 such as extending the sector numbers to 32 bits.
The choice is controlled using the src/INC/buf2sw.mac file, which either adds a define called BUF2 or does not do so. Using BUF2 saves about 2 KiB of resident memory use when comparing apples to apples (ie without BUFFERS /X EMS use).
I started this work in late 2024 December, but only uploaded it within the last week. The individual steps:
do_ext
mmacro call, which appears to be an unneeded leftover of the macro collection used for MS-DOS v2This last change was what took me so long to finish. When I had almost prepared it, I tested assembling without BUF2 defined. I found that in one spot I had the condition backwards. Other than that it seems to have worked out of the box.
I noted in the changeset message that the change "still has bugs". This seems to have been wrong however; a different bug seems to have affected my testing. I did not find any other bugs in the buffer conversion yet.
perl -i -pe 'if (not s/^; //) { $_ = "; $_"; }' src/INC/buf2sw.mac
buf_snbuf
lframe -2
in lmacros2.mac, as described above in the lmacros sectionPrepare a transfer function (transfer_doscode_to_dosdata) to allow running critical sections functions in DOSDATA from code running in DOSCODE. The transfer function already "works" despite being unneeded at this point.
At this point I believe the error occurred that I wrote xchg ax, [?in_ax_out_dosdata_retf]
without using BP as the base address register. This, of course, lead to a crash.
The interrupt list documents that MS-DOS v3.10+ has a table of patches, in the pre-SDA data, that specifies four offsets in DOSDATA to patch from retn
to push ax
to enable some critical section calls. It also documents that as of MS-DOS v4 all four words point to the same byte and the patch should be from 00h to a nonzero value instead.
This appears to be inaccurate, in the v4 release these are still the v3-style code patchsites. The different style probably was introduced with v5's DOSDATA/DOSCODE split. In lMS-DOS I chose to retain the old-style patchsites, hence the transfer function to pass the control flow from DOSCODE to DOSDATA and back.
The build promptly failed in IFSFUNC because (like SHARE before it) it includes some object files of the MSDOS kernel module to get the data layout right. Fixed by adding the new patchsite names to the list of placeholder entrypoints in IFSFLINK.ASM.
transfer_doscode_to_dosdata
function from the critical section functions is re-used, pushing a placeholder for the near return offset then the original BX value (twice push bx
) and adding 6 to SP after the transfer to get rid of the two return addresses.A single changeset with several changes:
nano *.nas
to work through all files, searching for section
, \bCODE\b
, and \bcs\b
in every file.nano *.nas
again, searching only for DOSGROUP this time. The LEAVEDOS entrypoint in DOSDATA does a transfer to doscode_leavedos to preserve the prior protocol. (The interrupt list calls this the "offset in DOS CS of code to return from INT 21 call". Unclear what MS-DOS v5 does.)wrt DOSGROUP
from short_addr mmacro. This was the last apparent roadblock to the DOSCODE split. (I tried to run the updated kernel and the int 21h dispatcher got the wrong addresses because of this wrt clause.)Today's last changeset finally splits DOSCODE from DOSDATA. Most of the changes to 59 files was done using a perl scriptlet. Its purpose is to change all instances of DOSDATACODE or DOSDATATABLE to the respective DOSCODE sections, except where a line is marked with an "in DOSDATA" comment. The scriptlet reads:
perl -i -pe ' if (not /in DOSDATA/) { s/DOSDATA(TABLE|CODE)/DOSCODE$1/g; }' src/DOS/*.nas src/INC/*.nas src/BIOS/*.nas src/BIOS/*.asm; hg revert -C src/INC/dosseg.nas
A small manual change in entry.asm is to use the DOSCODETABLE section for the initial entry. This is relevant because of the doscode_start label which we want to be at offset 0 within the DOSCODE segment. (For HMA use later we will also want to accurately place the CALL 5 entry at 10_00C0h.)
msinit.nas places DOSCODE to the for now final position before its first call to the DOS (either using transfers or int 21h).
I want to place DOSCODE and later DOSDATA in temporary locations in the LMA initially, so as to allow relocating them to the UMA (either) or the HMA (DOSCODE only) later without creating memory fragmentation. Of course, if no HMA nor UMA is available then the final relocation would be to a low part of the LMA.
I want to add lDOS's memory handling to allow operating on the UMA, along with handling for DEVICEHIGH=, SHELLHIGH=, and other data UMA or HMA relocations.
Further, the integration of msbio (BIOCODE aka DOSENTRY) and msdos (DOSDATA / DOSCODE) is still poor. Moving parts of msbio into DOSCODE or DOSDATA will shrink the parts that have to remain in DOSENTRY.
Another missing bit is the Interrupt Restoration Table of at least 5 entries at 70h:100h.
At this point I will likely change the reported DOS version to some v5.xx value as feature parity with MS-DOS v5.00 will have been reached. (v5.00 and v5.50 have been used by official Microsoft releases (MS-DOS and the NTVDM DOS, respectively) so I will likely avoid these specific numbers.) As part of this change, 21.3306 "get true version number" should be supported. Albeit of course the "true" version number is some sort of fiction by now.