• Please review our updated Terms and Rules here

What do DOS programmers expect?

mattrix

Member
Joined
Sep 15, 2010
Messages
17
Not sure what I'll do with this, but ...
just trying to define what a "dos like" programming environment would require.

I've got these:

interupts: dos & bios
DPMI,VCPI,xms services.
Video memory access
i/o port access

are there any other resources, special addresses or hidden whatever that a program would need?


Sorry this is a bit vague,
 
Well... vague it is, since I'm not entirely certain what you are asking... when you say "programming environment" are you talking about a IDE or RAD or some such nonsense? (which I don't even use in modern environments)

I mean, programming DOS I don't even expect half the stuff you listed like DMPI, VCPI, XMS, etc since I'm targeting 8088 where those don't even EXIST. The others of course you'd have to have access to, otherwise it's not DOS -- I'm just not getting why you wouldn't have those if you were in DOS.

As to what a programmer might expect access to, if you're talking DOS the answer is EVERYTHING; If it's a memory address, IO Port or ROM at ANY address range you should have access to it because there is nothing that is blocked/protected, particularly in 8088/8086/"real" mode code. If it exists in the system you can access it directly.

Could you explain better what it is you are trying to do/build?
 
are there any other resources, special addresses or hidden whatever that a program would need?
Sorry this is a bit vague,

Sounds like you're building an emulator. If that's correct, then typically what you do is:


  1. Write a CPU emulator
  2. Run already-compiled code through the emulator as a unit test
  3. Provide the bare minimum of an environment to load real-world code (games are always fun), and run said code
  4. When your code attempts to do something (instruction, memory reference, interrupt/BIOS call, etc.) that you haven't implemented, log it
  5. Implement the missing things the code found in step #4
  6. Repeat steps #4 and #5 until your emulator runs everything you throw at it

Alternately, ask Mike Chambers how he did it. But that's how many (most?) people do it.
 
Indeed, I usually have HXDOS installed on my P1+ system DOS drives. Lets me compile and run Win32 console programs. Is that still considered DOS? :)
 
Guess I'm just wondering what an "emulator" requires. Although I wouldn't want to go as low as a CPU so I guess its a "virtualizer".

When I think of programming for dos, I think of:
interrupts: dos & bios
Video memory access
i/o port access

I don't think I've ever written a program that has used more than these.
I threw DPMI,VCPI,xms services, as an after-thought, as I've definitely run programs that need these.
Mind you I'm a user now, I haven't written a program for ages.

4. When your code attempts to do something (instruction, memory reference, interrupt/BIOS call, etc.) that you haven't implemented, log it
5. Implement the missing things the code found in step #4
6. Repeat steps #4 and #5 until your emulator runs everything you throw at it

Guess I want to know what the "gotcha's" are before I'd even start.

I've since thought that the device chain structure would probably have to be the same and available; and probably the "memory block headers" would have to be there too. But I cant think of any other internal DOS structures or entry points that programmers would access.
 
When I think of programming for dos, I think of:
interrupts: dos & bios
Video memory access
i/o port access

I don't think I've ever written a program that has used more than these.

There are things that DOS programmers access via reading and writing memory other than video memory (e.g. BIOS variables) and there are interrupts other than those provided by DOS and the BIOS (e.g. an INT 10h provided by the video card ROM). But that about covers it - there isn't really much a DOS program can do in terms of IO that isn't an IO port access, a memory access or an interrupt. I guess some DOS programs call into BIOS services directly (via a far call rather than an interrupt). There are also CPU things like FPU instructions and control registers - without knowing what you're trying to do I'm not sure if those would count or not.

Basically "IO port access" covers much of the hardware by itself - to emulate/virtualize "IO port access" you would need to individually emulate/virtualize each piece of hardware that you want the emulator/virtualizer to support.
 
I guess the problem I have with the question is what are we getting at? If you just want to do a x86 emulator that will run DOS, that's one thing. On the other hand, if you're trying to emulate the DOS interface, but not DOS, that's another. And that latter may be a bit tough--note that Linux DOSEMU is an x86 emulator and that it loads a DOS your choice (e.g. FreeDOS) and has some hooks to tie it into the host (Linux) filesystem.

Like reenigne said, there's a lot of stuff not interrupt-related. Again, see Ralf Brown's List
 
I guess the problem I have with the question is what are we getting at?
I'll try to explain. I don't know if any of the following is correct. My question comes to the top of my brain every now and then. My thinking goes something like:

EMM386 sort of inserts itself between an application and DOS; In V86 mode any interupts generate GPF, which has to handled by EMM386 and passed onto DOS, the results collected and passed back to the application.

Why does the application need to be in the same V86 space as DOS? Then the application could have a full 640k (or more).
Might have to page some memory areas the same between the two, but EMM386 enables paging anyway.

Whats the catch? If its so easy why didn't it get done?

And if its not too difficult why can't we have more than 1 V86 application, effectively multitasking DOS.
In this case the applications are RM, But why can't we have PM tasks as well?

[/thinking]

This only needs a modified EMM386, no change to DOS or the application.
A small price for more "conventional" memory and multitasking to boot.

ps of course this assumes lots of memory and requires a 386, but so does EMM386.
 
Last edited:
And if its not too difficult why can't we have more than 1 V86 application, effectively multitasking DOS.

I never used it myself, but isn't that what DESQview is? I wouldn't be surprised if there were other things along the same lines.

As for "swapping DOS out of conventional RAM" - I think that would work as long as the program doesn't do anything strange (like reading the interrupt table and doing far calls instead of INT instructions, or poking about inside DOS data structures). It might be prohibitively slow ti copy big chunks of DOS and the user program back and forth on every interrupt call though, especially when running a program that reads/writes files (or to the screen) a byte at a time.
 
DesqView uses EEMS swapping functions to move entire applications out of the 640kB region into EMS and then move a different application into the 640kB region so it can run. On a 386, these remapping activities are very fast. But a copy of DOS and device drivers is always loaded in memory below the small resident portion of DesqView and in the address spaces for all applications.

You will need to have the OS be in the same address space as the application or the application can't call the OS. Simplest is to have one copy of DOS that is shared by all applications with code that keeps the DOS data structures in sync even as different applications do different tasks. That is how DesqView and Windows/386, Win 3.x, and Win 9x did it. More complicated is to allow each VDM to have its own OS which requires a method of intercepting calls and having the underlying host OS process them. OS/2 did this permitting the running of many different DOS versions and non-DOS 8086 OSes and even self-booting disks (yay!) at the cost of increased memory and having all the VDMs unable to access the system hard disk without special drivers.
 
You will need to have the OS be in the same address space as the application or the application can't call the OS.

Oh yes, that's a good point. Lots of interrupts require passing data by pointer. If the application decides to use one of those interrupts with a pointer that points into the memory that DOS would be using (if it was swapped in) then the swapper would have to relocate the data to a suitable address before passing the interrupt request to DOS and relocate the data back again after the interrupt completes. The swapper would have to know about all such interrupts and how to find the addresses and lengths for incoming and outgoing data. Not a trivial bit of code at all!
 
I never used it myself, but isn't that what DESQview is?

Desqview is that, but it is actually much more elegant: If you don't have a 386, it still works to a degree by intercepting every single interrupt. It's really quite amazing to run it on an 8088 with an EMS board; all applications that don't write directly to video ram can run simultaneously (round-robin multitasking) in resizable windows.

mattrix: Are you attempting a specific goal, or just wondering out loud? It's hard to answer questions directly if they aren't direct themselves. Are you writing an emulator?
 
Yes pointers are a problem. You just can't know the parameters of every possible interrupt/call.
I knew it couldn't be that simple.

: Are you attempting a specific goal, or just wondering out loud?
I think just wondering out load, trying to understand how things work.
 
I think you could do at least as well as Windows NT/XP/2K when it comes to creating some space for MS-DOS-type applications:

655360 bytes total conventional memory
655360 bytes available to MS-DOS
633744 largest executable program size

So, about 20K of memory space taken up by stuff that has to be in the same space. But it'd take some scribbling.
 
Why does the application need to be in the same V86 space as DOS? Then the application could have a full 640k (or more).
Might have to page some memory areas the same between the two, but EMM386 enables paging anyway.
In case of such overlapping memory how would you tell which memory application is trying to access - its own or DOS's (given a real mode segment:eek:ffset addresses)?
It is possible to get more memory using other tricks. For example nobody really requires 09FFFFh to be the top of the memory. If your application is not using EGA/VGA frame buffer at 0A0000h, you could extend the memory to 0B0000h or even to 0B8000h. Also there is UMB and EMS memory which can be emulated by EMM386.

And if its not too difficult why can't we have more than 1 V86 application, effectively multitasking DOS.
In this case the applications are RM, But why can't we have PM tasks as well?

That's what Windows 3.1+ and other more modern (than DOS) OSes do. They can run multiple DOS applications using VM86 boxes, and some protected mode applications at the same time.

Now if you want to do something simpler (say just the ability to run multiple DOS applications without all the Windows overhead), you'll really need to visualize all of I/O at all possible levels (MS-DOS, BIOS, direct access to I/O ports, DMAC, interrupt controller, and such).
There are quite a few problems with that:
- DOS by itself is not intended to be multitasking OS. It is not reenterant - which can be resolved by monitoring DOS functions, and making sure it is being called only by one application at the time. But then some DOS functions might block (making all applications wait). Simply running multiple DOS copies is not a solution either (at least not if they share same disks).
- Same situation (even worse) with BIOS.
- Finally you need to think what to do with I/O. In some cases it might be OK to simply pass I/O to hardware, but in most cases you'll want to understand what is that the application is trying to do, and make sure it doesn't conflict with other applications, or will not cause system crash. Just to give an example - an application can try to change the interval of the timer interrupt IRQ0 (which games frequently do). But there are other things that use the same interrupt - e.g. BIOS uses it for clock and delays. So if you don't take case of this, it will potentially break things for other applications. And it is just a simple example...
 
Last edited:
Back
Top