Thread overview
8086 PC-DOS 1.0 .COM target for C
Jun 07
Steve
Jun 07
Steve
Jun 07
Steve
Jun 07
Steve
June 07

I'm trying to go back to 1981 :)

Actually, I already went to 1977 and have my C code compiling for the Commodore PET, TRS80, and Apple ][ (using cc65 and z88dk). I'm now trying to target the x86, but without being dependent on DOS (MS-DOS or PC-DOS). Ideally my resulting .COM file would be loadable from a cassette (the original IBM user manual describes loading a diagnostic program, using the original ROM {cassette} BASIC C1.0).

I've had success with Turbo C 2.01 from 1988/1989. When you install Turbo C, it includes an example main C that describes some of the steps (including the use of EXE2BIN). i.e. (note I had to install Turbo Assembler 1.01 also)...

tcc -c -ms main
tasm c0 /D__TINY__ /D__NOFLOAT /t/mx;
tasm setargv /D__TINY__ /t/mx;
tlink c0 main setargv /c/m,main

exe2bin main.exe main.com
del main.exe

Getting the resulting main.com onto a single-sided 160KB disk was the next challenge, since WinImage actually doesn't support that original IBM PC format. So as an alternative, instead I booted PC-DOS 2.10 that supports double-sided disk - I "injected" my main.com onto a 360KB disk image, and PC-DOS 2.10 executed my .COM file!!

NOTE: I don't literally want to load my binary from a cassette - I just want to know it would be possible with the .COM binary that is produced (just as I know it is possible on the PET, TRS80, and Apple][ builds -- where for the PET, I did verify my binary does load from a cassette tape).

I get there is no "real" reason to do a real-mode 16-bit .COM using C - still, it's just something I'd like to be able to do.

While old-school Turbo C in a 86BOX has worked - it's very annoying to use (e.g. TurboC the max file size is 64KB for its editor, then just having to work WinImage to copy the file from a DOS 3.X image over to a DOS 1.X or 2.X image, and that DOS 3.X and turboC is limited to 8.3 filenames, etc -- it's tedious for the compile, test, debug, turn around time).

So I explored WATCOM. WATCOM is compiling all my C code, and did produce a .COM file (it has a 16-bit DOS target and .COM selection), I believe they are actually using 80186 or 80286 instructions - I may try again, but the .COM it produced didn't run on the PC-DOS 2.10 image for me.

So now I'd like to explore if Digital Mars C can do this. If I can get DM to build a .COM under my Windows machine, then I certainly don't mind buying the full development environment. I see the 16-bit x86 package for DM. But I may need some guidance through the command line options to build to a "pure" 8086/8088 target, to ASM,OBJ, and link together a .COM result (but the 16-bit package includes EXE2BIN, so I imagine that will still be required).

Every "correct" .COM program I am seeing starts with E9 or EB (a JMP instruction) - my understanding is .COMs start at 0x0100 (of the current segment?? or always segment 0? that wasn't very clear to me yet -- but I read the 0x0100 was a legacy reason because of the CP/M heritage associated with DOS, where CP/M had some 256-byte header maybe for passing command arguments?).

Any advise on if DM can target the original IBM PC 8086, and outline of steps to do so, would be appreciated. And I'll update if I can get any further on my own, I just encountered DM today and just starting to learn.

-Steve

June 07

On Monday, 7 June 2021 at 03:41:28 UTC, Steve wrote:

>

I'm trying to go back to 1981 :)

Actually, I already went to 1977 and have my C code compiling for the Commodore PET, TRS80, and Apple ][ (using cc65 and z88dk). I'm now trying to target the x86, but without being dependent on DOS (MS-DOS or PC-DOS). Ideally my resulting .COM file would be loadable from a cassette (the original IBM user manual describes loading a diagnostic program, using the original ROM {cassette} BASIC C1.0).

I've had success with Turbo C 2.01 from 1988/1989. When you install Turbo C, it includes an example main C that describes some of the steps (including the use of EXE2BIN). i.e. (note I had to install Turbo Assembler 1.01 also)...

tcc -c -ms main
tasm c0 /D__TINY__ /D__NOFLOAT /t/mx;
tasm setargv /D__TINY__ /t/mx;
tlink c0 main setargv /c/m,main

exe2bin main.exe main.com
del main.exe

Getting the resulting main.com onto a single-sided 160KB disk was the next challenge, since WinImage actually doesn't support that original IBM PC format. So as an alternative, instead I booted PC-DOS 2.10 that supports double-sided disk - I "injected" my main.com onto a 360KB disk image, and PC-DOS 2.10 executed my .COM file!!

NOTE: I don't literally want to load my binary from a cassette - I just want to know it would be possible with the .COM binary that is produced (just as I know it is possible on the PET, TRS80, and Apple][ builds -- where for the PET, I did verify my binary does load from a cassette tape).

I get there is no "real" reason to do a real-mode 16-bit .COM using C - still, it's just something I'd like to be able to do.

While old-school Turbo C in a 86BOX has worked - it's very annoying to use (e.g. TurboC the max file size is 64KB for its editor, then just having to work WinImage to copy the file from a DOS 3.X image over to a DOS 1.X or 2.X image, and that DOS 3.X and turboC is limited to 8.3 filenames, etc -- it's tedious for the compile, test, debug, turn around time).

So I explored WATCOM. WATCOM is compiling all my C code, and did produce a .COM file (it has a 16-bit DOS target and .COM selection), I believe they are actually using 80186 or 80286 instructions - I may try again, but the .COM it produced didn't run on the PC-DOS 2.10 image for me.

So now I'd like to explore if Digital Mars C can do this. If I can get DM to build a .COM under my Windows machine, then I certainly don't mind buying the full development environment. I see the 16-bit x86 package for DM. But I may need some guidance through the command line options to build to a "pure" 8086/8088 target, to ASM,OBJ, and link together a .COM result (but the 16-bit package includes EXE2BIN, so I imagine that will still be required).

Every "correct" .COM program I am seeing starts with E9 or EB (a JMP instruction) - my understanding is .COMs start at 0x0100 (of the current segment?? or always segment 0? that wasn't very clear to me yet -- but I read the 0x0100 was a legacy reason because of the CP/M heritage associated with DOS, where CP/M had some 256-byte header maybe for passing command arguments?).

Any advise on if DM can target the original IBM PC 8086, and outline of steps to do so, would be appreciated. And I'll update if I can get any further on my own, I just encountered DM today and just starting to learn.

-Steve

FYI, for my first attempt:

dmc -0 -mt test.c

-0 for 8088
-mt for TINY (.COM) memory model

But the first issue is: this is invoking EXE2BIN for me... and the EXE2BIN.COM doesn't run under Windows 10 64-bit. I understand why, it just means to complete the build I have to transfer to the PC-DOS 2.10, insert the PC-DOS 2.10 Disk #2 supplement, and use that EXE2BIN over there (I'm not sure if PC-DOS supported batch files yet - maybe).

And I just did this - I copied the resulting TEST.EXE to the PC-DOS 2.10 supplement disk 2. Boot PC-DOS 2.10 in 86BOX. Went to B: drive, ran EXE2BIN:
exe2bin.exe test.exe test.com
del test.exe

Then I tried to run test.com, and - it doesn't work (and then I tried it with the DOS 3.1 version of EXE2BIN, the resulting .COM is identical - so it's not that). The result is that the 86BOX emulator freezes, which is like the WATCOM build did. It's here where I'm saying TurboC 2 did create a .COM file that worked under PC-DOS 2.10.

It's funny how there is no native EXE2BIN built for 64-bit Windows -- I get WHY the original code of it won't run. But it's just a data conversion tool, it doesn't actually need to invoke any 16-bit calls. i.e. it's just manipulating the format of the EXE to be more compliant as a .COM file. I've read thru the MS-DOS source - they use their LINK, and like FORMAT.EXE gets EXE2BIN over to a FORMAT.COM (several utilities they compile are like that). That'd be an interesting project, to port the EXE2BIN.ASM over to a modern C program, hmm....

June 07

re: in trying to ensure the .COM build is making a proper TINY 64K x86 target

NOTE: I've read through the wcc command line options.
I see -0 is the default (8086) [even though there are only lib286 and lib386 folders, I'll assume it is arranged such that in the -0 option, only original 8086 instructions are truly being used]
I'm not sure what -bt=dos will do in my case (maybe specifies the .com should .org at 0x0100?)

What I'm most suspect about is in the cguide.pdf and compiler switches and command line options, there is no mention of a TINY mode.

-m{c,h,l,m,s} Memory model
c - compact - small code/large data
h - huge - large code/huge data
l - large - large code/large data
m - medium - large code/small data
s - small - small code/small data (defaul)

In WATCOM C, does small actually mean tiny ?

-Steve

June 07

On Monday, 7 June 2021 at 07:41:50 UTC, Steve wrote:

>

NOTE: I've read through the wcc command line options.

WATCOM C is working fine for me, producing .COM and running on PC-DOS 2.10.

I'm not sure what I changed - but the "16-bit DOS" target and .COM setting all seems to be fine.