Skip to content

Implement built-in MEM command - #128

Merged
stsp merged 1 commit into
masterfrom
add-mem-cmd-9759128799870124279
Sep 19, 2026
Merged

stsp merged 1 commit into
masterfrom
add-mem-cmd-9759128799870124279

Conversation

@stsp

@stsp stsp commented Aug 25, 2026

Copy link
Copy Markdown
Member

Implements a built-in MEM command similar to FreeDOS MEM in comcom64, placed in src/mem.c and src/mem.h. Updates build configurations (src/makefile.inc, djgpp/makefile) and registers 'mem' in command table in src/command.c.


PR created automatically by Jules for task 9759128799870124279 started by @stsp

@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@stsp

stsp commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

mem.c:439:14: warning: variable ‘xms_largest_free_kb’ set but not used [-Wunused-but-set-variable]
439 | uint32_t xms_largest_free_kb = 0;
| ^~~~~~~~~~~~~~~~~~~

@stsp

stsp commented Aug 25, 2026 •

Copy link
Copy Markdown
Member Author

You added empty commit, nice.
This besides the fact that you have
nonsense values like:
Conventional 796,224 143,408 652,816.
But anyway, its a good start.
@stuaxo would you like to ask Claude
to review this and fix remaining bugs? :)

@stuaxo

stuaxo commented Aug 26, 2026

Copy link
Copy Markdown

Will do. I wonder if we can have unit tests somehow for our DOS based C code.

@stsp

stsp commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

For example by adding the "secret"
unittest command to comcom, that
works only in debug builds.
I can't think of anything simpler, although
I only thought of it for 5 seconds. You
can ask Claude as well. :)

@stuaxo

stuaxo commented Aug 26, 2026

Copy link
Copy Markdown

Started as a PR against this PR, will have more of a look tomorrow.

@stsp
stsp force-pushed the add-mem-cmd-9759128799870124279 branch from bf57f37 to 75ff233 Compare September 19, 2026 14:54
@andrewbird

Copy link
Copy Markdown
Member

rebase?

@stsp

stsp commented Sep 19, 2026

Copy link
Copy Markdown
Member Author

This idiot Jules was reverting commits.
I removed him now and rebased.

@stsp
stsp force-pushed the add-mem-cmd-9759128799870124279 branch 4 times, most recently from 5773e34 to 4239672 Compare September 19, 2026 18:01
Report conventional, upper (UMB), reserved, extended (XMS) and expanded
(EMS) memory, the largest executable program size and the largest
available upper memory block, with /CLASSIFY, /FREE, /DEBUG, /PAGE and
/? switches. The report is laid out like the one real FreeDOS MEM
prints, and dosemu2's own test suite (test/func_comcom_internal.py)
compares the two tool's figures, so they follow MEM.EXE's conventions:

 - memory is accounted for, and displayed, in KB. Each source is
   converted to KB once, where it is read: INT 12h, XMS and INT
   15h/E820h already report KB, EMS counts 16KB pages, and the MCB chain
   is accumulated in paragraphs and converted at print time, rounding to
   nearest. The largest blocks and the EMS totals also carry the byte
   count MEM.EXE prints next to them;
 - conventional memory ends at the 640K line, so its total is capped
   there whatever INT 12h reports (dosemu2 with $_dosmem above 640
   reports 736K), and an MCB crossing the line is split between the two
   regions rather than charged whole to the one its first paragraph is
   in: with UMBs linked, DOS merges the top of conventional memory with
   the adjacent upper block into a single MCB;
 - above it, the first megabyte is divided the way MEM.EXE divides it:
   0xA000-0xDFFF is "Upper" and 0xE000-0xFFFF is "Reserved", both fixed
   regions rather than sums of the blocks found in them, with free UMBs
   counting towards upper memory wherever they sit;
 - the largest free block is measured over runs of adjacent free blocks,
   which DOS merges when it allocates - right after a program exits, the
   memory it used is several adjacent free MCBs that have not been
   merged yet, and reporting the largest of those understates what a
   program can actually get by a wide margin.

Extended memory has no XMS call reporting the installed total, so it
comes from INT 15h/E820h, same as FreeDOS MEM: under dosemu2 the older
E801h/88h calls report a much smaller compatibility figure than the pool
that is actually configured. UMBs are linked for the scan through INT
21h/58h(03h) directly, so the allocation strategy is never touched. The
MCB walk stops if the chain fails to advance past 0xffff, rather than
wrapping into low memory and counting it twice.

MEM /CLASSIFY groups blocks by their owner. DOS 4+ records the owner's
name only in the MCB that holds the program itself, so the names are
collected up front and looked up by owner: naming each block on its own
listed one module twice, once as COMMAND and once as PSP-xxxx. The
placeholder blocks that keep the upper memory chain linked across the
video memory and the option ROMs ("SC", owned by the kernel) are holes
in the address space rather than memory, so they are listed but not
counted, and the memory below the first MCB is charged to SYSTEM, the
way MEM.EXE charges it.

/PAGE follows the cursor the way "dir /p" does instead of counting the
lines printed, since the report starts wherever the command line left
the cursor and long lines wrap. Built-in commands are handed only the
first argument, so "mem /d /p" would arrive as just "/d"; get_cmd_args()
exposes the full argument string for commands taking several switches.

tests/compare_mem.sh runs this MEM and the real FreeDOS MEM.EXE in one
dosemu2 session and compares them, as a stand-alone version of the
dosemu2 test. Both dosemu2 and FreeDOS come from the dosemu2 PPA: the
FreeDOS userspace, where MEM.EXE comes from, is installed by dosemu2's
own insfdusr into a private HOME under the cache dir, and
DOSEMU2_COMCOM_DIR points dosemu2 at the build under test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kg5AbDqjCHbxSZzSpV6aRA
@stsp
stsp force-pushed the add-mem-cmd-9759128799870124279 branch from 4239672 to 4f749f1 Compare September 19, 2026 18:05
@stsp
stsp merged commit b1a78a7 into master Sep 19, 2026
2 checks passed
@stsp
stsp deleted the add-mem-cmd-9759128799870124279 branch September 19, 2026 18:44
@stsp

stsp commented Sep 19, 2026

Copy link
Copy Markdown
Member Author

Well, its new functionality, so it
can't regress. Also it was properly
tested (also by me). Who will properly
review such a large chunks of code...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants