0

I have an embedded application written in C, running on FreeDOS on a 486/386DX-style processor (http://www.dmp.com.tw/tech/vortex86dx). The computer has 256MB memory, but I don't seem to have access to most it.

I've written a simple program to investigate (calls malloc() in a loop until null pointer is returned) and although the size of each malloc() request affects the result slightly, it's always around 300kB limit. My code is having to map blocks of 16-bit memory as my implementation of malloc() seems to accept only unsigned short argument. Not terrible as I need only 3MB or so, so about 50 blocks (it's a circular buffer for acquisition data so this roundabout approach isn't that cumbersome). Since I'm getting much more than 16 bits worth of memory (300k vs 64k), I know this isn't entirely a 16-bit problem. I'm guessing this is associated with the 640kB limit I've read about in my research, but I don't understand if this is a compiler problem or an OS problem.

I'm using Borland BC5 compiler and I've tried all kinds of tweaks to the memory model and compiler options, which have had minimal effect on the results. I'm currently looking into HIMEMX.EXE and JEMM386.EXE but as I've barked up so many wrong trees so far, thought it worth a question in the meantime. I've also started looking into Linux though this is a major major change as the code is very DOS specific, and I have zero experience with Linux.

I'm hoping there are just some settings or commands that I need to take advantage of without having to do some huge port to and OS I'm not familiar with. My DOS installation currently consists only of copying files config.sys and sys.com to the hard drive, so I don't have access to the extended memory executables above yet to experiment. Guessing that will only get me to the next difficulty, so hopefully somebody with experience in this ancient department can lend a hand until I have more time to familiarize myself with modern tools.

So should I be concerned more with the OS settings or compiler settings (or compiler itself)?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
robisrob
  • 940
  • 12
  • 23
  • 1
    What is Unreal Mode? [accessing 4GB RAM in real mode](https://stackoverflow.com/questions/32807155/accessing-4gb-ram-in-real-mode) – Swordfish May 10 '19 at 20:16
  • Back in the old DOS days, we used DOS Extenders to extend the memory beyond 640k. Then you could use up to if I remember correctly 2GB. – Romain Hippeau May 10 '19 at 20:26
  • 1
    Look for the Borland powerpack for DOS. it should work with your BC 5 – Romain Hippeau May 10 '19 at 20:36
  • @RomainHippeau I've already forgotten about this but it's one of the many trees I've barked up. I downloaded it, installed it, seemed to do some things in the background, and then I didn't see any difference in Borland or the compiled result. The worst thing about this platform (beside this memory limit) is the lack of online resource for any of this. Is there something I need to do with this addon? – robisrob May 10 '19 at 20:40
  • 1
    If your application is running on FreeDOS, then it's not an embedded application in the usual sense of that term, which conveys running directly on the hardware, without an OS. To me, at least. Yours is a FreeDOS application, because that's the environment that hosts it. – John Bollinger May 10 '19 at 20:46
  • @robisrob obviously if there's no changes in your program then it cannot access the remaining memory because there are no changes in the addressing scheme and the memory model is still sixteen 64KB segments. You can only see the high addresses in small chunks at a time by mapping them to some part of your 20-bit address space – phuclv May 11 '19 at 01:56
  • 1
    It's exactly the same as in Windows where you enable PAE or use 64-bit Windows and **expect 32-bit apps to access more than 4GB of memory without any code changes from you**. There's AWE to remap other parts of memory to yours so that you can access more than 4GB of memory, but you can still only see 4GB at a time. Just stop using DOS and care about modern OSes unless this is just for fun or you're selling apps for DOS – phuclv May 11 '19 at 04:36
  • I would agree with phuclv. You need a more modern toolset. If not finding help for any issue is going to be complicated – Romain Hippeau May 11 '19 at 13:50
  • If not take a look at https://www.digitalmars.com/ctg/dos32.html just googled never used – Romain Hippeau May 11 '19 at 13:55
  • PS I voted you up – Romain Hippeau May 11 '19 at 13:57

2 Answers2

3

Specifically with respect to malloc(), as I recall the Borland implementation takes a 16 bit size argument. The Borland library has "huge" memory model a version halloc() (and a correspinding hfree()) which can allocate larger blocks (larger than 64kb).

JEMM386 it is an extended memory manager, which pages memory above 1Mb into the "high-memory" region above 640K - this region is only 384Kb in size, not all of which is available for memory paging, and that is probably the cause of the 300Kb limit you have observed by experiement.

To make full use of memory resources for both code and data it is necessary to use DPMI (DOS Protected Mode Interface). A DPMI program is a true 32 bit protected mode program with a mechanism to access the DOS API (this is how Windows 3.x worked before Windows 95 became an operating system in its own right rather then a graphical environment over DOS).

DPMI programs run the processor in protected rather then real mode. This is complicated a little by the fact that there are two protected modes; the 16 bit 80286 protected mode (DPMI16) and the 32-bit 80386 protected mode (DPMI32). In your case you need only be concerned with DPMI32.

For the Borland compiler, DPMI was supported via the DOS Power Pack tools. However Power Pack was designed to work with Borland C++ 4.02 and 4.5x not 5.0. This technical note, explains how you can use Power Pack with BC++5, but advises against it. It states that it only works with the command line tools - not the IDE. That said this other technical note then explains how to get it to work in the IDE, but explains that the BC++5 RTL will not work. Overall, it does not sound like a pleasant experience.

However there is no need at all to contemplate switching to Linux - you simply need to use a toolchain that supports DPMI32 and allows you to build your code as true 32 bit code in a DOS environment.

Suitable tool-chains may include:

All of the above except DJGPP require third-party DOS extenders (DPMI hosts) some of which are listed here. DJGPP includes an extender (as described here), so may be the simplest choice if not the most modern (but then neither is Borland). Consult the toolchain documentation to determine what you need. The problem with those that use third-party extenders is that while the compiler might continue to be available, the extender may disappear (as is the case I think with Digital Mars).

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    Yes, EMM86 and HIMEM.SYS were everone's friends back then. And we even got partition sizes greater than 32M! – David C. Rankin May 10 '19 at 22:39
  • I am looking into DJGPP. This seems like the holy grail I've been after. Will update as I move along if this is accepted answer, but already so grateful for a nudge in a hopeful direction! – robisrob May 13 '19 at 17:33
  • @robisrob - Yes that would be my choice. It is probably not the best compiler - I cannot find what version of GCC it is based on, the documentation if for GCC v3.2.1 (released in 2002) - but it is certainly the best choice for longevity and availability, and not relying on third-party extender support makes it the safest choice IMO. – Clifford May 13 '19 at 17:54
  • I don't really understand the DOS extender availability worries. The environment is FreeDOS. FreeDOS has different DOS extenders that certainly won't disappear as long as FreeDOS itself won't disappear. – BlackJack Dec 15 '22 at 09:52
  • @BlackJack - You don't understand, or you simply disagree? It was a while ago, but was an answer from research and experience (even longer ago) of MS-DOS development, I am not familiar with FreeDOS specifically. You are probably right, but if the rights owner of the extender is not the same as that of FreeDOS, it is not quite that certain perhaps. Certainly worth posting an answer if you know something about it. In the context of the question, how these extenders can be used with the OP's BC5 compiler, or some other toolchain would be interesting (to me at least). – Clifford Dec 15 '22 at 23:12
  • FreeDOS packages free DOS software and it includes Open Watcom 1.9 including several (now) free DOS extenders. Namely CauseWay (the one from DJGPP), DOS4/GW, DOS/32A, and PMODE/W. Those are part of the Watcom package. So they can't really disappear separately from FreeDOS. The Open Watcom 2 fork repository includes CauseWay and DOS/32A. And also Orange C/C++ comes with the necessary extender(s). – BlackJack Dec 18 '22 at 01:52
  • @BlackJack I take your point, much of this answer could be changed to use the tools _currently_ included with FreeDOS. However, I don't know if that was true at the time this was written. I would not have researched it and the OP seems unaware of it if it was. Certainly Orange was not available at that time - I am not maintaining this list! Clearly scope for a new answer covering all that, and I'd encourage you to post one. – Clifford Dec 18 '22 at 08:40
0

Good old DOS only was set up to use 640 kiB of memory, and the address space only went up to 1 MiB.

Newer techniques include the "unreal mode" (of which I just heard for the first time, but it seems logical to me).

But in the DOS times, you had to use EMS and/or XMS (edit: or use the protected mode, either with DPMI or do it completely on your own).

These were techniques to access memory outside of the usable memory window.

EMS had memory windows where pages of that extra memory could be mapped in.

With XMS, you had a special function which helped you copying the data from and to the memory using a certain function address.

edit: DPMI gave you a way to use the protected mode in a "controlled" way, but with a little bit of effort, you also can enter the protected mode on your own. But as I never gained experience with either of these, I don't know how good the support for DOS functions are in this case (I think, DPMI helps you a little bit there, but I am not sure).

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • You don't *had* to use EMS/XMS, unless you limit „DOS times“ to processors before the 286. With 286 there is 16 bit protected mode, used by Turbo/Borland Pascal and many programs written in it for instance, and from 386 on there is 32 bit protected mode, which many DOS programs used. The question talks about a _„486/386DX style processor“_ so 32 bit protected mode is possible. – BlackJack Dec 15 '22 at 10:00
  • @BlackJack XMS wasn't possible with "before 286". On 8088 and friends, only EMS was possible. XMS required some kind of actually switching to protected mode and back (the latter being a little bit tricky on 286). Of course, you also could do the "protected mode" stuff on your own, or use the DPMI. But that's what I never gained experience with. – glglgl Dec 16 '22 at 07:49
  • 1
    @glglgl : HIMEM eventually used the 286's LOADALL instruction to access XMS memory on the 286 without the need to enter protected mode (avoiding the issues of getting back to real mode by resetting the processor). On the 386 HIMEM implemented XMS memory using unreal mode which did require entering protected mode and immediately switching back to real mode after setting the segment limits to 4GiB. – Michael Petch Dec 16 '22 at 08:34