Skip to content

Commit 419ba06

Browse files
committed
mem: don't count reserved memory as used upper memory
Upper memory was a fixed 256K region, 0xA000-0xDFFF, with used taken as that total minus the free blocks found in the chain. Anything in the region that the upper memory chain does not reach - video memory, option ROMs, the BIOS - was therefore reported as in use by somebody, although DOS can neither give it out nor account for it. Take the upper total from the chain instead, as FreeDOS MEM does: the blocks themselves, allocated and free, wherever they sit, and the rest of the area above 640K is the reserved region, whose size is now what is left over rather than a fixed 128K. Measured under dosemu2 with the FreeDOS MEM.EXE beside our own, which is what dosemu2's test/func_comcom_internal.py compares. With a 32K hole in the chain, which `$_umb_b0 = (0)` makes: before after FreeDOS MEM.EXE Upper 256K 120K 136K 224K 88K 136K 224K 88K 136K Reserved 128K 128K 0K 160K 160K 0K 160K 160K 0K The two agreed in the default configuration only by accident: the 36K hole the chain skips at 0xB800 happens to be the size of the free area it reports above 0xE000, and the two errors cancelled. With the holes of any other size, the fixed total charged the difference to "used". Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 167666c commit 419ba06

1 file changed

Lines changed: 21 additions & 14 deletions

File tree

‎src/mem.c‎

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,15 @@
5353
#define CONV_MAX_KB (UMB_START_SEG / PARAS_PER_KB)
5454

5555
/*
56-
* Above conventional memory, FreeDOS MEM splits the first megabyte the
57-
* way MS-DOS MEM did: 0xA000-0xDFFF is "Upper", and 0xE000-0xFFFF is
58-
* "Reserved" - the BIOS and option ROM area, reported as entirely in
59-
* use. Both are fixed-size regions, not sums of the blocks found in
60-
* them, and free UMBs count towards upper memory wherever they sit.
61-
* Report them the same way, so our numbers can be compared with
62-
* MEM.EXE's directly.
56+
* Above conventional memory, FreeDOS MEM splits what it finds in two:
57+
* the blocks of the upper memory chain are "Upper", and everything else
58+
* below 1 MB is "Reserved" - video memory, option ROMs and the BIOS -
59+
* reported as entirely in use. So upper memory is the sum of the blocks
60+
* themselves, wherever they sit, and the area the chain does not reach
61+
* is reserved rather than used. Report them the same way, so our
62+
* numbers can be compared with MEM.EXE's directly.
6363
*/
64-
#define RESERVED_START_SEG 0xE000
65-
#define UMB_TOTAL_KB ((RESERVED_START_SEG - UMB_START_SEG) / PARAS_PER_KB)
66-
#define RESERVED_TOTAL_KB ((0x10000 - RESERVED_START_SEG) / PARAS_PER_KB)
64+
#define UPPER_AREA_KB ((0x10000 - UMB_START_SEG) / PARAS_PER_KB)
6765

6866
/* Rounds to nearest, as FreeDOS MEM does. */
6967
static uint32_t paras_to_kb(uint32_t paras)
@@ -572,6 +570,7 @@ void perform_mem(const char *arg)
572570
uint32_t conv_free_paras = 0;
573571
uint32_t conv_largest_paras = 0;
574572

573+
uint32_t umb_total_paras = 0;
575574
uint32_t umb_free_paras = 0;
576575
uint32_t umb_largest_paras = 0;
577576

@@ -662,7 +661,12 @@ void perform_mem(const char *arg)
662661

663662
/* the MCB header itself belongs to the region it sits in */
664663
if (!is_umb)
664+
{
665665
conv_total_paras += conv_paras + 1;
666+
umb_total_paras += umb_paras;
667+
}
668+
else
669+
umb_total_paras += umb_paras + 1;
666670

667671
if (mcb.owner_psp == 0)
668672
{
@@ -789,10 +793,13 @@ void perform_mem(const char *arg)
789793
uint32_t conv_free_kb = paras_to_kb(conv_free_paras);
790794
uint32_t conv_used_kb = (conv_total_kb > conv_free_kb) ?
791795
(conv_total_kb - conv_free_kb) : 0;
792-
uint32_t umb_total_kb = UMB_TOTAL_KB;
796+
uint32_t umb_total_kb = paras_to_kb(umb_total_paras);
793797
uint32_t umb_free_kb = paras_to_kb(umb_free_paras);
794798
uint32_t umb_used_kb = (umb_total_kb > umb_free_kb) ?
795799
(umb_total_kb - umb_free_kb) : 0;
800+
/* what the chain never reached is reserved, not used upper memory */
801+
uint32_t reserved_total_kb = (UPPER_AREA_KB > umb_total_kb) ?
802+
(UPPER_AREA_KB - umb_total_kb) : 0;
796803

797804
if (opt_classify)
798805
{
@@ -924,7 +931,7 @@ void perform_mem(const char *arg)
924931
"Upper", str_tot, str_used, str_free);
925932
print_line(line_buf);
926933

927-
format_kb(RESERVED_TOTAL_KB, str_tot, sizeof(str_tot));
934+
format_kb(reserved_total_kb, str_tot, sizeof(str_tot));
928935
format_kb(0, str_free, sizeof(str_free));
929936
snprintf(line_buf, sizeof(line_buf), "%-16s %8s %8s %8s",
930937
"Reserved", str_tot, str_tot, str_free);
@@ -942,9 +949,9 @@ void perform_mem(const char *arg)
942949

943950
print_line("---------------- -------- -------- --------");
944951

945-
format_kb(conv_total_kb + umb_total_kb + RESERVED_TOTAL_KB + xms_total_kb,
952+
format_kb(conv_total_kb + umb_total_kb + reserved_total_kb + xms_total_kb,
946953
str_tot, sizeof(str_tot));
947-
format_kb(conv_used_kb + umb_used_kb + RESERVED_TOTAL_KB + xms_used_kb,
954+
format_kb(conv_used_kb + umb_used_kb + reserved_total_kb + xms_used_kb,
948955
str_used, sizeof(str_used));
949956
format_kb(conv_free_kb + umb_free_kb + xms_free_kb, str_free, sizeof(str_free));
950957
snprintf(line_buf, sizeof(line_buf), "%-16s %8s %8s %8s",

0 commit comments

Comments
 (0)