3 ms·
A few additions, in case someone goes back to this post for reference, and because I cannot edit it anymore: * As far as I know, you are unfortunately limited
by anyfoo 7y ago
A few additions, in case someone goes back to this post for reference, and because I cannot edit it anymore:
* As far as I know, you are unfortunately limited to 32bit OSs, as x86_64 got rid of the vm86 mode necessary for hosting DOS. In 64bit long mode, you would probably need to run a full x86 emulator to achieve the same (of which there are plenty), although I haven't looked into that aspect of x86_64 yet. That being said, for a toy OS 32bit is plenty, and I haven't run into anything yet where I wish it was 64bit.
* The DOS busy flag's use is actually more to know whether DOS is still busy with a DOS function invocation by something other than your OS. Your OS code can trivially know by itself that it performed a call which did not complete yet (DOS is not reentrant, so you can only perform one call at a time). However, the DOS task is actually everything within DOS, including TSRs (which are essentially programs running in DOS's background, including many device drivers), or, depending on how you structure it, maybe even a plain old foreground DOS application that has nothing to do with your OS. Both will make DOS calls as well. The busy flag was actually introduced to support TSRs, which also need to prevent stepping on DOS calls performed by other TSRs or the foreground running app.
* Besides the busy flag, there is actually a second flag, the "critical error" flag, which you should just treat as another busy flag.
* A useful technique at the beginning is to have DOS programs that perform system calls (e.g. through an INTn instruction) into your OS, which then may call back into DOS in various ways to perform functions. That way you already have the ability to launch programs from DOS's shell which can do something related to your OS. But they will overall still be 16bit programs.
* To run "native" programs in your OS, have some kind of loader that just loads your program into memory, and then just calls into your OS to start executing it as its own task. You can either let your loader return to DOS immediately, going back to the shell independently of your new OS task, or have your loader stay running until the task is finished, which is useful if you want to do console input/output through DOS's console.
* Again, this has a lot of overlap with what DOS extenders (like DOS4/GW) do. The main difference is that DOS extenders more or less only provide everything necessary to build "32bit DOS apps" (and are likely mostly single-tasked, with the exception of the additional vm86 task), while your own OS can be pretty much anything.