Link to home
Start Free TrialLog in
Avatar of Narcisius
Narcisius

asked on

Visual C++ and 16bit DOS (That's all the points I have left)

I am trying to write a 16bit DOS app from Visual C++ 6 is this even possible?  If so how? I am getting errors right now about how the program isn't able to run in DOS outside of the emulated DOS Enviroment in Windows.  If not, what can I use to compile C++ code to a 16 bit console app, thank you.
Avatar of Narcisius
Narcisius

ASKER

I know this isn't many points but it is all I have left... please someone answer me..
If you want to make a 16bit DOS application try compiling with Borland C++ 3.1
You can also use Visual C++ 1.52C
I think it must be somewhere in the MSDN package ...

See also the followin link :

https://www.experts-exchange.com/questions/10858901/Writing-MSDOS-program-in-Visual-C.html
No, it is not possible to make a 16 bit DOS application using VC++ 6.0.

Use Borland C++ 3.1 or some similar compiler for that purpose.

Borland C++ 3.1 is free and available for download so as nistorm suggest you should try to use that compiler.

Note that Borland C++ 3.1 is NOT standard C++. It is from the days before the standard was made. No templates, not even sure if it has exceptions (doubt it - at least it is not implemented the same way modern exception is implemented) and it certainly have no STL. It has the old #include <iostream.h> though.

Some other old stuff is there but I do believe they have overload of new() and delete() so you don't do the ancient thing of assigning this pointer in constructor. So at least on that point they are in line with modern C++ compilers.

I think they even have overloads on return type for new:

void __near * operator new(size_t sz);

void __far * operator new(size_t sz);

are two separate overloads. It is the only function/operator that overloads on return type and as such is an exception to the rule that you don't overload on return type.

void * operator new(size_t sz);

is not a separate overload, it is one of the two above depending on your MODEL. The MODEL is important and determine the size of your pointers and how the segment registers are used.

Tiny model - everything in one segment, all pointers are near pointers and all segment registers have the same value. You can use far pointers but the C library only support near pointers.

Small model - one data segment and one separate code segment. All pointers are near pointers but CS and DS have different value. SS == ES == DS.

Medium model - one data segment but several code segments. Data pointers are near pointers but function pointers are far pointers. DS SS and ES has the same value but CS is set to a separate value and will from time to time change value, all - or most - function calls are far calls that causes the CS to change value.

Compact model - several data segments but only one code segment. Data pointers are far pointers and function pointers are near pointers. DS has one value, SS has probably another value and ES often change value. DS also some times change value. All function calls are near calls but data loads are typically done using far pointers and segment registers.

Large model - several data segments and several code segments. All pointers are far pointers and you frequently switch segment registers. All function calls are far calls. All data loads are using far pointers and data segment registers. Any data element must fit inside one 64K bytes segment though.

Huge model - Just like large model but in addition one single array or other data structure can span several segments. So you can make an array like:

int arr[100000];

which would be too big for a large model.

The huge heap (hmalloc) can also allocate data elements bigger than a segment.

The hmalloc function is also available in other models but beware that only in huge model will the systme do proper pointer arithmetic when calculating position.

The difference in pointer arithmetic is as follows:

If the pointer is near pointer it is only a 16 bit value and only that 16 bit value is modified.

If the pointer is far pointer then the pointer is 32 bit and is made up of a 16 bit segment and a 16 bit near pointer. You can extract the near pointer by simply casting the pointer to a near pointer. The segment can also be extract using the 'data type' _segment. __segment is a 16 bit value that can be stored in a segment register or used together with a near pointer to make a far pointer.

In all models where far pointers are used except for huge, the pointer arithmetic only affect the near pointer part of the far pointer. The segment is not modified. So if p is s:0xffff where s is some segment value and the near pointer is 0xffff then ++p will produce a value of s:0x0000 which really isn't the next position in memory.

In huge model the segment is taken into account and the next value is (s + 0x1000):0x0000.

This also implies that pointer arithmetic is slower in huge model compared to the other models.

All in all, the 32 bit code is much easier than these silly models. In 32 bit mode you essentially run Tiny model with CS, DS, ES and SS all pointing to the same segment but this one segment is 4Gb and not 64Kb.

Also, modern CPU's (386 and later) have two additional segment registers which you can use named FS and GS. The runtime system for MS-DOS doesn't do anything with them though but you can use them whenever you run out of segment registers to use. So, if ES isn't enough for you, specify FS and GS. Just remember to load them first :-)

Hope this is of help.

Alf
Would it be better to use Pascal to write these programs then? I can program in that as well.  If so, I tried using Code Warrior to compile in Pascal and I had the same problem with it not working in the old MSDOS enviroment?  I am trying to write a bunch of recovery CD's for work and for friends so I don't have to drop everything I am doing when they have problems to fix thier computer.  I am trying to write some CD's that can diagnose and fix small problems.
ASKER CERTIFIED SOLUTION
Avatar of Salte
Salte

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok, will someone respond to my question about Pascal then?
If you feel comfortable with pascal you can use it, but Borland C++ 3.1 is just as well. It all depends on what you prefer. They are identical as far as feature list goes.

Alf
Ok Salte I will give you the points even though my problem isn't really solved but thank you for the effort.