My First MS-DOS! port
Hellooooo!!!!!
I haven't posted anything in a long while, I didn't have the motivation to write anything and thanks to my very close friend I was able to gain some of it back.
NOTE: I made use of Borland C++ 2.0 for the DOS, get it here if you are curious.
I have been slowly learning what I can about the MS-DOS, so far I have made simple graphical programs on it and I have been testing them using DOSBox-x (since I do not have access to an actual DOS machine, hopefully I will be able to get my hands on one). So far I have learned that making software on the MS-DOS can be pretty straight forward, at least when it comes to graphics. I remember trying to learn Modern OpenGL and holy shit I hated the setup part, I found myself writing a lot with nothing being displayed on the screen, and I found that pretty exhausting. Maybe there's something wrong with me but I liked learning old/legacy OpenGl, it was simple, perfect for someone like me.
Anyway enough yapping and lets talk about what I was able to do. I ported one of my previous programs: Flow Field with C to the MS-DOS, at first I thought it would be very difficult because there would be a lot of things I would have to deal with, like the old C syntax, trying to find the right graphics functions or some obscure issue that has unfortunately not been documented before. But since I am typing all this right now, it seems to have been fine.
I would say the only problem I had to deal with was the old C syntax and even that wasn't that much of a problem honestly, and my program is very simple so realistically I wouldn't really face a lot of problems. Another win for me is that I used a really nice C library that had functions that mimicked older DOS functions, so I didn't really have to change the structure of the program except changing all of the functions to the Borland equivalent.
So let's see the changes;
- The first thing I had to take note of were far pointers, far pointers was more of a DOS thing, mainly because of how memory worked on the 8086 (since the DOS was made for that CPU architecture in mind), I don't think other systems like the MAC (at the time) had the concept of far pointers (I could be VERY wrong). But basically far pointers make it possible to point to addresses outside of their own memory segment (this was a thing with the 8086 architecture and it's 64kb memory segments), There's a nice article about it right here and another one here by the same author.
but to get access to the "time", which I will use for the random seed, I had to make use of a far pointer that points to the internal clock
unsigned long far *clock = (unsigned long far *)0x0000046CL;
//////a bunch of code////////
srand(*clock);
The non-DOS dos-like I made previously, looked like this:
#include <time.h>
///////a bunch of code/////////
srand(time(NULL));
Another thing I had to change was how I declared variables, with the old syntax you have to declare it above before you make use of it. This wasn't much of a problem.
Now to start drawing, this was the part were I had to actually read the Borland Reference manual lol, I was like "wait how do you draw anything with this". Thankfully, the manual is very straight forward when it comes to making use of the BGI (Borland Graphics Interface). So I had to initialize the BGI:
#include <graphics.h>
///////code//////////
int driver = 1, mode = 1;
initgraph(&driver, &mode, "");
if you are confused about the int driver and int mode, the manual explains it properly but there are different graphics drivers you can make use of whenever you are dealing with the MS-DOS. The graphics driver I am using here is '1' which is the CGA (Color Graphics Adapter) and the mode is '1' which is for the resolution and color depth, which in our case is <320x200>. Like I mentioned earlier the Borland reference manual has a lot of information on it, there is a website for just the BGI and it's right here. I almost forgot about the last parameter "", this is the location of the driver files (*.BGI) in my case the driver file is located in my current working directory.
- I have a delay function towards the end of my while loop, whenever the program reaches that line it will wait for 100 milliseconds before running the while loop again (if the condition is still valid). I added this because on my VM it was really fast, and it is part of the BGI.
#include <graphics.h>
////////code/////////
delay(100) // in milliseconds
- this is about the not so significant changes but I have a check that breaks the loop whenever it detects a keyboard press, and a
getch()I actually don't know why I added this, it's supposed to get the keyboard characters and return it in hexadecimal (I think I was going to use it for the keyboard check if statement I created). And lastly there is aclosegraph()which de-initializes the BGI (I am not sure if that's even a word).
So far, it was really easy to do, since I made use of a library that does a very good job mimicking DOS functions, it made it very easy when it came to porting it.



The code is right here, if you are interested, please leave a star too lol.
NOTE: THIS WAS TESTED ON DOSBox, DOSBox-X, DOSBox Staging and a FreeDOS VM, I unfortunately did (and Still do) not have access to DOS compatible Hardware for testing.
I want to thank my very close friend for giving me the motivation to write this, and for indirectly giving me the idea in the first place. Thank you T.
And thank you for taking your time to read this, if you want to leave anything for me or if you have any feedback it would be nice to leave a message right here
Thank you, Kenny.