Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

comp.os.msdos.programmer FAQ part 1/5

0 views
Skip to first unread message

Jeffrey Carlyle

unread,
Apr 9, 2004, 7:57:16 AM4/9/04
to
Archive-name: msdos-programmer-faq/part1
Comp-os-msdos-programmer-archive-name: dos-faq-pt1.txt
Posting-frequency: 28 days
Last-modified: 14 Aug 2003

comp.os.msdos.programmer FAQ Version 2003.08.14

This is the Frequently Asked Questions list for the newsgroup
comp.os.msdos.programmer.

COPYRIGHT

Copyright 2003 by Jeffrey Carlyle. All rights reserved. This article is
not in the public domain, but it may be redistributed so long as this
notice, the acknowledgments, and the information on obtaining the latest
copy of this list are retained and no fee is charged. The code fragments
may be used freely; credit to the FAQ would be polite. This FAQ is not to
be included in any static: archive (e.g. CD-ROM or book); however, a
pointer to the FAQ may be included. See <Q:01.14> [Where can I get the
latest copy of this FAQ list?] for a link to the latest version of the
FAQ.)

This is part 1 of 5 parts.

TABLE OF CONTENTS

PART 1: (this part)
Section 1. General FAQ and Newsgroup Information
<Q:01.01> - Is MS-DOS Dead?
<Q:01.02> - What is this article for?
<Q:01.03> - Who has contributed to this article?
<Q:01.04> - How can I search this article for a particular topic?
<Q:01.05> - Are the answers guaranteed to be correct and complete?
<Q:01.06> - What is comp.os.msdos.programmer about?
<Q:01.07> - Is comp.os.msdos.programmer just for C programmers?
<Q:01.08> - What is comp.sys.ibm.pc.programmer?
<Q:01.09> - Is comp.os.msdos.programmer available as a mailing list?
<Q:01.10> - What's this netiquette?
<Q:01.11> - How can I learn more about Usenet?
<Q:01.12> - What other technical newsgroups should I know about?
<Q:01.13> - Where are FAQ lists archived?
<Q:01.14> - Where can I get the latest copy of this FAQ list?

Section 2. General Reference
<Q:02.01> - Are there any good on-line references for PC hardware
components?
<Q:02.02> - Are there any good on-line references for PC interrupts?
<Q:02.03> - What and where is Ralf Brown's interrupt list?
<Q:02.04> - Where can I find lex, yacc, and language grammars?
<Q:02.05> - What's the best book to learn programming?
<Q:02.06> - Why won't my code work?
<Q:02.07> - Are there any good sources of example code?
<Q:02.08> - What and where is SNIPPETS?
<Q:02.09> - Is the source code MS-DOS available?
<Q:02.10> - What are my alternatives for MS-DOS compatible OSes?
<Q:02.11> - What and where is FreeDOS?
<Q:02.12> - Where can I find out about batch files?

PART 2:
Section 3. Compile and link
<Q:03.01> - What the heck is DGROUP > 64K?
<Q:03.02> - How do I fix 'automatic data segment exceeds 64K' or 'stack
plus data exceed 64K'?
<Q:03.03> - Will Borland C code and Microsoft C code link together?
<Q:03.04> - Why did my program bomb at run time with 'floating point
formats not linked' or 'floating point not loaded'?
<Q:03.05> - How can I change the stack size in Borland's C compilers?
<Q:03.06> - What's the format of an .OBJ file?
<Q:03.07> - What's the format of an .EXE header?
<Q:03.08> - What's the difference between .COM and .EXE formats?
<Q:03.09> - How do I create a .COM file?
<Q:03.10> - Where is EXE2BIN located?
<Q:03.11> - What does this message mean: 'A20 already enabled so test
is meaning less?'

Section 4. Keyboard
<Q:04.01> - How can I read a character without echoing it to the
screen, and without waiting for the user to press the Enter
key?
<Q:04.02> - How can I find out whether a character has been typed,
without waiting for one?
<Q:04.03> - How can I disable Ctrl-C/Ctrl-Break and/or Ctrl-Alt-Del?
<Q:04.04> - How can I disable the print screen function?
<Q:04.05> - How can my program turn NumLock (CapsLock, ScrollLock) on
or off?
<Q:04.06> - How can I speed up the keyboard's auto-repeat?
<Q:04.07> - What is the SysRq key for?
<Q:04.08> - How can my program tell what kind of keyboard is on the
system?
<Q:04.09> - How can I tell if input, output, or stderr has been
redirected?
<Q:04.10> - How can I increase the size of the keyboard buffer?
<Q:04.11> - How can I stuff characters into the keyboard buffer?

PART 3:
Section 5. Disks and files
<Q:05.01> - What drive was the PC booted from?
<Q:05.02> - How can I boot from drive B:?
<Q:05.03> - Which real and virtual disk drives are valid?
<Q:05.04> - How can I make my single floppy drive both a: and b:?
<Q:05.05> - How can I disable access to a drive?
<Q:05.06> - How can a batch file test existence of a directory?
<Q:05.07> - Why won't my C program open a file with a path?
<Q:05.08> - How can I redirect printer output to a file?
<Q:05.09> - How can I redirect the output of a batch file?
<Q:05.10> - How can I redirect stderr?
<Q:05.11> - How can my program open more files than DOS's limit of 20?
<Q:05.12> - How can I read, create, change, or delete the volume label?
<Q:05.13> - How can I get the disk serial number?
<Q:05.14> - What's the format of .OBJ, .EXE., .COM files?
<Q:05.15> - How can I flush the software disk cache?
<Q:05.16> - How can I see if a drive is a RAM drive?
<Q:05.17> - How can I determine a hard drive's manufacturer?
<Q:05.18> - Where can I find information about the ATA/ATAPI
specification?
<Q:05.19> - How can I copy files to or from filenames containing date
information?

Section 6. Serial ports (COM ports)
<Q:06.01> - How do I set my machine up to use COM3 and COM4?
<Q:06.02> - How do I find the I/O address of a COM port?
<Q:06.03> - But aren't the COM ports always at I/O addresses 3F8, 2F8,
3E8, and 2E8?
<Q:06.04> - How do I configure a COM port and use it to transmit data?

PART 4:
Section 7. Other hardware questions and problems
<Q:07.01> - Which 80x86 CPU is running my program?
<Q:07.02> - How can a C program send control codes to my printer?
<Q:07.03> - How can I redirect printer output?
<Q:07.04> - Which video adapter is installed?
<Q:07.05> - How do I switch to 43- or 50-line mode?
<Q:07.06> - How can I find the Microsoft mouse position and button
status?
<Q:07.07> - How can I access a specific address in the PC's memory?
<Q:07.08> - How can I read or write my PC's CMOS memory?
<Q:07.09> - How can I access memory beyond 640K?
<Q:07.10> - How can I use the protected mode?
<Q:07.11> - How can I tell if my program is running on a PS/2-style
machine.
<Q:07.12> - Is there a 80x87 math unit installed?
<Q:07.13> - How can I power off the computer from a batch file?

Section 8. Other software questions and problems
<Q:08.01> - How can a program reboot my PC?
<Q:08.02> - How can I time events with finer resolution than the system
clock's 55 ms (about 18 ticks a second)?
<Q:08.03> - How can I find the error level of the previous program?
<Q:08.04> - How can a program set DOS environment variables?
<Q:08.05> - How can I change the switch character to - from /?
<Q:08.06> - How can I write a TSR (terminate-stay-resident utility)?
<Q:08.07> - Why does my interrupt function behave strangely?
<Q:08.08> - How can I write a device driver?
<Q:08.09> - What can I use to manage versions of software?
<Q:08.10> - What's this 'null pointer assignment' after my C program
executes?
<Q:08.11> - How can a batch file tell whether it's being run in a DOS
box under Windows?
<Q:08.12> - How can my program tell if it's running under Windows?
<Q:08.13> - How can a program tell whether ANSI.SYS is installed?
<Q:08.14> - How do I copyright software that I write?
<Q:08.15> - How can I place date and time information into environment
variables?

PART 5:
Section 9. Downloading
<Q:09.01> - What are SimTel and Garbo?
<Q:09.02> - Can I get archives on CD-ROM?
<Q:09.03> - Where do I find program <mumble>?

Section 10. Vendors and products
<Q:10.01> - How can I contact Borland?
<Q:10.02> - How can I contact Microsoft?
<Q:10.03> - What is the current version of DJGPP?
<Q:10.04> - What and where is DJGPP?
<Q:10.05> - Are there any good shareware/freeware compilers?
<Q:10.06> - Where is QBASIC?
<Q:10.07> - What is a vendor's web site address?

------------------------------

Subject: Section 1. General FAQ and Newsgroup Information
Date: 5 Feb 2002 22:03:03 -0400

The General FAQ and Newsgroup Information section contains information
about how to use the FAQ and the newsgroup.

------------------------------

Subject: <Q:01.01> - Is MS-DOS Dead?
Date: 7 Feb 2002 14:31:56 -0400

No. Though Microsoft may not be actively developing MS-DOS there are
still many computers that are not capable of running Microsoft Windows.
The current versions of Microsoft Windows will also run most MS-DOS
programs; therefore, MS-DOS is not dead, and will most- likely never die
just as Commodore-64s and Amigas have not completely died.

Indeed, DOS has found a new life in embedded systems. Other parties
continue to develop MS-DOS compatible operating systems for more
information see <Q:02.10> [What are my alternatives for MS-DOS
compatible OSes?]

Windows NT, 2000, and XP all have a "Command Prompt" which is similar to
the orignal MS-DOS command prompt. The new Windows command prompt has
some differences from the original MS-DOS command prompty; see <Q:01.12>
[What other technical newsgroups should I know about?] for pointers on
where to learn about these diffences.

------------------------------

Subject: <Q:01.02> - What is this article for?
Date: 5 Feb 2002 22:03:03 -0400

This is the FAQ (Frequently Asked Questions) list for the newsgroup
comp.os.msdos.programmer.

FAQ lists are intended to reduce the noise level in their newsgroups
that results from the repetition of the same questions, correct answers,
wrong answers, corrections to the wrong answers, corrections to the
corrections, debate, etc.

This list should serve as a repository of the canonical "best" answers
to the questions in it. The names of folks who have helped to improve
this FAQ list are listed in <Q:01.03> [Who has contributed to this
article?]

------------------------------

Subject: <Q:01.03> - Who has contributed to this article?
Date: 27 Jun 2003 07:18:11 -0400

This list is maintained and edited by Jeffrey Carlyle. To contact him
send email to <mailto:jef...@carlyle.com> or visit his website at
<http://www.jeffc.org/> for more information.

Stan Brown, as the former list maintainer, has been the major
contributor: Stan wrote most of this list.

Many articles posted in comp.os.msdos.programmer sparked ideas or
provided information for the first version of this list. Though they are
not responsible for any errors, thanks are due to the following persons
for posted articles or private email that led to improvements in this
FAQ list:

Jamshid Afshar, Mark Aitchison, Sanjay Aiyagari, George Almasi, Aaron
Auseth, Robert Baker, Preston Bannister, Scott Barman, Denis Beauregard,
Per Bergland, Mike Black, Chris Blum, Ron Bodkin, Mark Brader, Jon
Brinkmann, Andrew James Bromage, Glynn Brooks, Paul Brooks, Ralf Brown,
Stan Brown, Shaun Burnett, D'Arcy J.M. Cain, Jeffrey Carlyle, Raymond
Chen, Dale Curtis, Denny de Jonge, Eric DeVolder, Alan Drew, Paul
Ducklin, Gary Dueck, Dave Dunfield, Roland Eriksson, Mark Evans, Markus
Fischer, George Forsman, Roger Fulton, Vincent Giovannone, Robert
Grunloh, B.Haible, Janos Haide, Klaus Hartnegg, Kris Heidenstrom, Tom
Haapanen, Joel Hoffman, Ari Hovila, Chin Huang, Daniel P Hudson, Joe
Huffman, Michael Holin, Mike Iarrobino, Byrial Jensen, Rune Jorgensen,
Ajay Kamdar, Everett Kaser, Tim Kannel, JJ Keijser, Jeff Kellam, Igor
Kerp, Jen Kilmer, Reinhard Kirchner, Dave Kirsch, Chad Knudsen, Samuel
Ko, Jan Kotas, Janne Kukonlehto, Robert Luursema, Benjamin Lee, Stephen
Lee, Jim Lynch, Greg Malknecht, Sidney Markowitz, Jim Marks, Dimitri
Matzarakis, Fred McCall, Ken McKee, Doug Merrett, Tom Milner, Bill
Moore, Duncan Murdoch, Steve Murphy, Daniel Neri, Mert Nickerson, David
Nugent, John Oldenburg, David Pape, Keith Petersen, Kevin D. Quitt, Karl
Riedling, Arthur Rubin, Gerald Ruderman, Timo Salmi, Tapio Sand, Charles
Sandmann, John Schmid, Russell Schulz, Paul Schylter, Huseyin Sevay,
Adam Seychell, Ajay Shah, Bob Smith, John Stockton, Bob Stout, Sean
Sullivan, Steve Summit, Tom Swingle, Anders Thulin, Curt Tilmes, Rick
Watkins, Ya-Gui Wei, Morten Welinder, Joe Wells, Scott Winder, Gregory
Youngblood, Eli Zaretski, cei...@lis.net.au, kh...@vax1.umkc.edu

------------------------------

Subject: <Q:01.04> - How can I search this article for a particular
topic?
Date: 5 Feb 2002 22:03:03 -0400

To locate a certain word or phrase use your newsreader's, browser's, or
editor's search function.

------------------------------

Subject: <Q:01.05> - Are the answers guaranteed to be correct and
complete?
Date: 5 Feb 2002 22:03:03 -0400

There has been an attempt to check all facts, but THERE IS NO WARRANTY
ON THE CODE OR ON THE TECHNIQUES DESCRIBED HEREIN. Please send
corrections to <mailto:jef...@carlyle.org>. All the code has been
tested; but the testing may not have been perfect, and machines and
configurations vary. (Except where otherwise noted, C code was tested
with MSC 5, BC++ 2.0, BC++ 4.x, MSVC 5, or MSVC 6.)

The mention of particular books or programs must not be construed to
reflect unfavorably on any that are not mentioned.

If you encounter any errors in the FAQ please contact me via email.

------------------------------

Subject: <Q:01.06> - What is comp.os.msdos.programmer about?
Date: 5 Feb 2002 22:03:03 -0400

Comp.os.msdos.programmer (comp.sys.ibm.pc.programmer until September
1990) concerns programming for MS-DOS systems. The article "USENET
Readership report for Jul 94" in news.lists shows 120,000 readers of
this newsgroup worldwide. Traffic (exclusive of crossposts) was 1981
articles aggregating 3.1 Megabytes. It ranked as the 79th most popular
newsgroup.

More programming topics in the newsgroup focus on C than on any one
other language, but we are not just for C programmers (see <Q:01.07> [Is
comp.os.msdos.programmer just for C programmers?]).

Since most MS-DOS systems run on hardware that is roughly compatible
with the IBM PC, on Intel 8088, 80188, or 80x86 chips, we tend to get a
lot of questions and answers about programming other parts of the
hardware.

------------------------------

Subject: <Q:01.07> - Is comp.os.msdos.programmer just for C programmers?
Date: 7 Feb 2002 14:40:59 -0400

No, it is for all programmers who want to share information about
programming in MS-DOS and DOS replacements like 4DOS. Programs and
questions are also posted in Pascal, assembly, and other languages
(including MS-DOS batch programming).

Why does the newsgroup seem to be so C-oriented sometimes? There are two
reasons. First, comp.lang.c and comp.lang.pascal have evolved in
different directions. Comp.lang.pascal has split into discussions about
individual Pascal compilers. comp.lang.pascal.borland welcomes
discussion specific to Turbo Pascal, and the other new groups likewise.
Turbo Pascal programmers tend to find DOS questions welcomed in
comp.lang.pascal.borland, so that comp.os.msdos.programmer gets less of
the "DOS in Turbo Pascal" traffic. On the other hand, comp.lang.c has
stayed closer to talking only about the C language, and vendor-specific
or operating-system-specific questions are not welcome. This tends to
push questions about disks, DOS file structure, video, the keyboard,
TSRs, etc. to comp.os.msdos.programmer even when those programs are
written in C.

This FAQ is definitely C-oriented, not because that's necessarily best
but because I tried to stick to what I could verify personally. As a C
programmer (with some assembler), I could most carefully verify
solutions in C or assembler. I felt that short, clear programs could be
published in just one language and programmers could translate them into
their languages of choice. But the FAQ list also contains several long
programs written only in C; this is a defect with no obvious remedy.
Most answers that point to source code at archive sites include both C-
and Pascal- language source when available.

------------------------------

Subject: <Q:01.08> - What is comp.sys.ibm.pc.programmer?
Date: 5 Feb 2002 22:03:03 -0400

The newsgroup comp.sys.ibm.pc.programmer is the old name of the modern
newsgroup comp.os.msdos.programmer, and the old name has been obsolete
since September 1990; however, some systems may not have removed the old
group, or may have removed it but aliased it to the new name.This means
that some people still think they're posting to
comp.sys.ibm.pc.programmer even though they're actually posting to
comp.os.msdos.programmer.

You can easily verify the non-existence of comp.sys.ibm.pc.programmer by
reference to the "List of Active Newsgroups" posted to news.groups. It's
available at:

<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/active-newsgroups>

(For RTFM usage instructions see <Q:01.13> [Where are FAQ lists
archived?])

------------------------------

Subject: <Q:01.09> - Is comp.os.msdos.programmer available as a mailing
list?
Date: 5 Feb 2002 22:03:03 -0400

Sorry, the newsgroup is not available as a mailing list.

------------------------------

Subject: <Q:01.10> - What's this netiquette?
Date: 5 Feb 2002 22:03:03 -0400

Netiquette is good Usenet etiquette. It includes basic rules like the
ones below. (See also <Q:01.11> [How can I learn more about Usenet?])

* Always read a newsgroup for a reasonable time before you post an
article to it.

* Pick the one right group for your article; don't crosspost unless
absolutely necessary. If you absolutely must post an article to more
than one group, do crosspost it and don't post the same article
separately to each group. See <Q:01.12> [What other technical
newsgroups should I know about?] when considering where to post an
article.

* Before you post a question, make sure you're posting to the right
newsgroup; the best way to do that is to observe the proceeding rule.
Check the group's FAQ list (if it has one) to make sure that your
question isn't already answered there; see <Q:01.13> [Where are FAQ
lists archived?]

* When you post a question, if you ask for email responses then promise
to post a summary. Keep your promise. And make it a real summary:
don't just append all the email you got. Instead, write your own
(brief) description of the solution: this is the best way to make sure
you really understand it.

* Before you post a follow-up, read the other follow-ups. Very often
you'll find that someone else has already made the point you had in
mind.

* When someone posts a question, if you want to know the answer don't
post a "me, too". Instead send email to the poster asking him or her
to share responses with you.

* When posting a follow-up to another posted article, remove all headers
and signature lines from the old article; just keep the line "In
<article>, so-and-so writes:". Also cut the original article down as
much as possible; just keep enough of it to remind readers of the
context.

* Keep lines in posted articles to 72-75 characters. Many newsreaders
chop off column 81 or arbitrarily insert a newline there, which makes
longer lines difficult or impossible to read. But you need to keep
well below 80 characters per line to allow for the > characters that
get inserted when other people post follow-ups to your article.

* Keep your signature to 4 lines or less (including any graphics) and
for heaven's sake make sure it doesn't get posted twice in your
article.

* Don't post email without first obtaining the permission of the sender.

------------------------------

Subject: <Q:01.11> - How can I learn more about Usenet?
Date: 5 Feb 2002 22:03:03 -0400

There are two important newsgroups for learning about how Usenet and
newsreader software works:

* News.announce.newusers contains periodic postings that everybody is
asked to read before posting anything to Usenet. (In theory, all new
users are subscribed to news.announce.newusers automatically. But in
practice not all newsreader software does that, so that many people
violate the guidelines given there simply because they don't know
about them.)

* News.newusers.questions is described as "Q & A for users new to the
Usenet". But new and long-time users can ask or answer questions about
Usenet and newsreader software there. There's an important article,
"Welcome to news.newusers.questions! (Weekly posting)", that everyone
is asked to read before posting to news.newusers.questions. (See below
for ways to get a copy of that article.)

The following postings in news.announce.newusers might be considered the
"mandatory course" for new users:

* Introduction to news.announce.newusers

* What is Usenet

* Answers to Frequently Asked Questions

* Rules for posting to Usenet

* A Primer on How to Work with the Usenet Community

* Hints on writing style for Usenet

* Emily Postnews Answers Your Questions on Netiquette

The articles mentioned above are downloadable via ftp from rtfm.mit.edu
in the following files:

Welcome to news.newusers.questions (Weekly posting):
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/news-newusers-intro>

Introduction to news.announce.newusers:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/news-announce/introduction/part1>

What is Usenet:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/what-is/part1>
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/what-is/part2>

Answers to Frequently Asked Questions:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/faq/part1>

Rules for posting to Usenet:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/posting-rules/part1>

A Primer on How to Work with the Usenet Community:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/primer/part1>

Hints on writing style for Usenet:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/writing-style/part1>

Emily Postnews Answers Your Questions on Netiquette:
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/usenet/emily-postnews/part1>

For rtfm.mit.edu instructions, see <Q:01.13> [Where are FAQ lists
archived?]

------------------------------

Subject: <Q:01.12> - What other technical newsgroups should I know about?
Date: 7 Feb 2002 14:35:45 -0400

It is impractical to attempt to list all relevant newsgroups here. The
few that are listed are some of the older newsgroups. To find additional
groups use your newsreader's newsgroup search facility.

Caution: Some of these newsgroups have specialized charters; you'll
probably get flamed (and deserve it) if you post to an inappropriate
group. Most groups have FAQ lists that will tell you what's appropriate.
Don't post a request for the FAQ list; instead, retrieve it yourself:
see <Q:01.13> [Where are FAQ lists archived?]

* The various misc.forsale.computers.* are where you post notices of
equipment, software, or computer books that you want to sell. Please
don't post or crosspost those notices to comp.os.msdos.programmer.

* The various comp.os.ms-windows.programmer.* groups (formerly
comp.windows.ms.programmer) are for articles specifict to the various
Microsoft Windows platforms.

* The various comp.sys.ibm.pc.hardware.* groups are for more
hardware-oriented discussions of the machines that run DOS.

* The various comp.lang.* groups for articles and questions on the
programming languages. Caution: some groups welcome discussions that
are operating-system dependent or vendor specific; others do not. For
example, comp.lang.c is definitely _not_ for questions about
programming DOS or PC system features, even if the programs are
written in C.

* comp.binaries.ibm.pc.wanted: AFTER you have looked in the other
groups, this is the place to post a request for a particular binary
program.

* comp.archives.msdos.announce (moderated) explains how to use the
archive sites, especially Garbo and SimTel, and lists files uploaded
to them. Discussions belong in comp.archives.msdos.d, which replaced
comp.binaries.ibm.pc.archives in December 1992.

* comp.binaries.ibm.pc.d is for discussions about programs posted in
comp.binaries.ibm.pc, and only those programs. This is a good place to
report bugs in the programs, but not to ask where to find them (see
cbip.wanted, above). comp.binaries.ibm.pc.d is NOT supposed to be a
general PC discussion group.

* comp.sources.misc: a moderated group for source code for many computer
systems. It tends to get lots of Unix stuff, but you may also pick up
some DOS-compatible code here.

* alt.sources: an unmoderated group for source code. Guidelines are
posted periodically.

* comp.os.msdos.djgpp is specifically for support of DJGPP. For more
information on DJGPP see <Q:10.04> [What and where is DJGPP?]

* comp.os.msdos.programmer.turbovision is specifically for programming
in Turbo Vision.

* rec.games.programmer discusses many graphics programming topics.

* alt.msdos.batch specializes in the discussion of MS-DOS batch files.

* alt.msdos.batch.nt specializes in the discussion of batch files for
Windows NT, 2000, and XP.

------------------------------

Subject: <Q:01.13> - Where are FAQ lists archived?
Date: 5 Feb 2002 22:03:03 -0400

Very possibly the FAQ list you want is already at your site. Check the
newsgroup news.answers; if your site doesn't carry news.answers, check
comp.answers, rec.answers, etc., according to the top-level name in the
FAQ list's "home" newsgroup. Articles are posted to the *.answers groups
in a way that should make them last until the next versions are posted.
If they expire sooner at your site, you might want to lobby your
sysadmin to treat the moderated *.answers groups as a special case and
grant them longer expiration times than other groups.

To ftp most FAQ lists, connect to
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers>. The name of the
file that you want is the Archive-name from the top of the article. For
instance, if the Archive-name were software-eng/part1 you would retrieve
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/software-eng/part1>.

By email (only if you have no ftp access, please), the server is
<mailto:mail-...@rtfm.mit.edu>. It accepts "send" commands that omit
the leading "/pub/" from file names; for example:

send usenet-by-group/news.answers/software-eng/part1

For full instructions about the mail server, send it a message
consisting of these two lines:

help
index

Not just FAQ lists, but every article listed in the "List of Periodic
Informational Postings" (LoPIP) can be obtained by ftp or email from
rtfm.mit.edu. If you have an old copy of an informational article, look
for an "Archive-name" at the beginning. The article is stored under that
name at <ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers>. If the
article has no Archive-name, check the first name on the Newsgroups line
and change to that directory under
<ftp://rtfm.mit.edu/pub/usenet-by-group>.

Stan Brown also maintains a FAQ on finding FAQs. It can be found at
<http://www.mindspring.com/~brahms/faqget.htm>.

------------------------------

Subject: <Q:01.14> - Where can I get the latest copy of this FAQ list?
Date: 14 Aug 2003 06:46:14 -0400

The FAQ's home page is at <http://www.jeffc.org/msdos/>. The latest
version of the FAQ can always be found there.

Additionally there are several sites that archive the FAQ list. A couple
of the more popular FAQ archives are
<ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/msdos-programmer-faq>
and
<http://www.faqs.org/faqs/by-newsgroup/comp/comp.os.msdos.programmer.html>.

For more information on the FAQ archives, see <Q:01.13> [Where are FAQ
lists archived?]

------------------------------

Subject: Section 2. General Reference
Date: 5 Feb 2002 22:03:03 -0400

The General Reference section contains information about finding popular
online MS-DOS reference materials.

------------------------------

Subject: <Q:02.01> - Are there any good on-line references for PC
hardware components?
Date: 8 Feb 2002 19:36:40 -0400

Good reports of HELPPC21 have been posted. It is downloadable as:
<ftp://garbo.uwasa.fi/pc/programming/helppc21.zip>

This hypertext system contains much information on ports and other
hardware, as well as some overlap with Ralf Brown's interrupt list
<Q:02.03> [What and where is Ralf Brown's interrupt list?]. It is
shareware ($25).

Additional information (and more recent) information can be found in
Ralf Brown's interrupt list; see <Q:02.03> [What and where is Ralf
Brown's interrupt list?] for information on locating the list.

------------------------------

Subject: <Q:02.02> - Are there any good on-line references for PC
interrupts?
Date: 5 Feb 2002 22:03:03 -0400

The definitive work is Ralf Brown's interrupt list. For more information
see <Q:02.03> [What and where is Ralf Brown's interrupt list?].

------------------------------

Subject: <Q:02.03> - What and where is Ralf Brown's interrupt list?
Date: 8 Feb 2002 19:37:16 -0400

Ralf Brown's Interrupt List contains megabytes of information on
documented and (officially) undocumented BIOS and DOS interrupts, DOS
tables, and interrupts hooked by many software packages.

The distribution files contain not only the actual list, but also a
collection of utilities and conversion programs for the list.

Ralf Brown's Interrupt List can be downloaded from his page at:
<http://www.cs.cmu.edu/~ralf/files.html>

HTML versions of Ralf Brown's Interrupt List can be found at:

* <http://www.delorie.com/djgpp/doc/rbinter/>

* <http://ctyme.com/rbrown.htm>

Updates are announced in comp.archives.msdos.announce and on Ralf
Brown's web page at: <http://www.cs.cmu.edu/~ralf/>

Ralf's web page contains the somewhat unassuming line: "[h]e is
well-known in cyberspace for maintaining the Interrupt List..." Ralf has
done astounding work as the maintainer of the list; his work has been
greatly appreciated by thousands of programmers.

------------------------------

Subject: <Q:02.04> - Where can I find lex, yacc, and language grammars?
Date: 5 Feb 2002 22:03:03 -0400

The FAQ list of the comp.compilers newsgroup answers this for BASIC, C,
Pascal, and other languages. See <Q:01.13> [Where are FAQ lists
archived?]

------------------------------

Subject: <Q:02.05> - What's the best book to learn programming?
Date: 5 Feb 2002 22:03:03 -0400

Sorry, this FAQ list cannot settle religious arguments.

Much of the heat over this topic arises because each person believes
that the book that he or she learned from is the best book, but
different people have very different experiences of the same book. The
only person who can tell you which is the best book for learning a given
topic is you.

Your best bet is to go to a fairly well stocked bookstore when you have
a couple of hours to spare. Start at one end of the shelf and work your
way methodically through every book that looks like it might cover what
you want to learn. Look at the tables of contents; read a page or two
from each book. Then make your decision. If money is a problem or if
you're not sure of your choice, check out your top two or three from
your library.

------------------------------

Subject: <Q:02.06> - Why won't my code work?
Date: 7 Feb 2002 14:44:40 -0400

First you need to try to determine whether the problem is in your use of
the programming language or in your use of MS-DOS and your PC hardware.
(Your manual should tell you which features are standard and which are
vendor- or MS DOS- or PC-specific. You have read your manual carefully,
haven't you?)

If the feature that seems to be working wrong is something related to
your PC hardware or to the internals of MS-DOS, this group is the right
place to ask. (Please check this FAQ list first, to make sure your
question isn't already answered here.)

On the other hand, if your problem is with the programming language, the
comp.lang hierarchy (including comp.lang.pascal.* and comp.lang.c) is
probably a better resource. Please read the other group's FAQ list
thoroughly before posting. (These exist in comp.lang.c, comp.lang.c++,
comp.lang.modula3, comp.lang.lisp, comp.lang.perl; they may exist in
other groups as well. comp.lang.pascal.borland has a Mini-FAQ.) It's
almost never a good idea to crosspost between comp.os.msdos.programmer
and a language group.

Before posting in either place, try to make your program as small as
possible while still exhibiting the bad behavior. Sometimes this alone
is enough to show you where the trouble is. Also edit your description
of the problem to be as short as possible. This makes it look more like
you tried to solve the problem on your own, and makes people more
inclined to try to help you. See also <Q:01.10> [What's this
netiquette?]

------------------------------

Subject: <Q:02.07> - Are there any good sources of example code?
Date: 5 Feb 2002 22:03:03 -0400

Bob Stout maintains a very large archive called SNIPPETS. For more
information see <Q:02.08> [What and where is SNIPPETS?].

------------------------------

Subject: <Q:02.08> - What and where is SNIPPETS?
Date: 6 Feb 2002 00:00:45 -0400

Excerpt from the SNIPPETS FAQ follows:

The SNIPPETS archive, maintained by Bob Stout, contains public
domain/freeware portable C/C++ source code & instructional text.
There are more than 500 files, including:

Approx. 56,000 lines of code + approx. 10,000 lines of
tutorials.
Approx. 30% PC-specific, 70% portable
Approx. 6% C++-specific, 94% C/C++

The PC-specific functions are system-level utility code - no
multimedia or GUI code. Tested on all popular PC compilers plus
Unix compilers where possible. An eclectic collection with
everything from macros to complete cut-and-paste C/C++ code
solutions & utilities, along with FAQ and instructional files.

Official SNIPPETS sites: <ftp://ftp.snippets.org/>
<http://www.snippets.org/>

------------------------------

Subject: <Q:02.09> - Is the source code MS-DOS available?
Date: 5 Feb 2002 22:03:03 -0400

No, the source code to MS-DOS is not currently available; however, the
source code to an MS-DOS alternative known as FreeDOS is freely
available; see <Q:02.11> [What and where is FreeDOS?] for more
information.

------------------------------

Subject: <Q:02.10> - What are my alternatives for MS-DOS compatible OSes?
Date: 5 Feb 2002 22:03:03 -0400

The FreeDOS Project (see <Q:02.11> [What and where is FreeDOS?]) has
created an open source MS-DOS compatible operating system known as
FreeDOS. Additionly, IBM has released an updated version of their PC-DOS
known as PC-DOS 2000.

Lineo currently owns the rights to DR-DOS, but they appear to no longer
be developing or supporting it; however, one can still find DR-DOS and
even CP/M on their FTP site: <ftp://ftp.lineo.com/pub/drdos/>

------------------------------

Subject: <Q:02.11> - What and where is FreeDOS?
Date: 7 Feb 2002 00:49:45 -0400

The FreeDOS Project creates and maintains FreeDOS an open source
operating system covered by the GNU General Public License. FreeDOS is a
functional operating system; however, they have not yet reached their
stated of goal of being able to run Windows and DOOM. The FreeDOS
Project has not accessed any Microsoft source code and is creating
FreeDOS from scratch.

More information and the FreeDOS distribution itself can be found at:
<http://www.freedos.org>

------------------------------

Subject: <Q:02.12> - Where can I find out about batch files?
Date: 7 Feb 2002 12:59:56 -0400

If the question is not answered elsewhere in this FAQ, it may be
answered in Timo Salmi's "Frequently Asked Questions about MS-DOS
batches." This list can be found at
<ftp://garbo.uwasa.fi/pc/link/tsbat.zip>.

------------------------------

Subject: Conclusion

This is the end of part 1 of 5 parts.

This text is copyright 2003 by Jeffrey Carlyle. All rights reserved.
Please see the top of this article for additional copyright information.

Jeffrey Carlyle

unread,
Apr 9, 2004, 7:57:47 AM4/9/04
to
Archive-name: msdos-programmer-faq/part3
Comp-os-msdos-programmer-archive-name: dos-faq-pt3.txt

Posting-frequency: 28 days
Last-modified: 14 Aug 2003

comp.os.msdos.programmer FAQ Version 2003.08.14

This is the Frequently Asked Questions list for the newsgroup
comp.os.msdos.programmer.

COPYRIGHT

Copyright 2003 by Jeffrey Carlyle. All rights reserved. This article is
not in the public domain, but it may be redistributed so long as this
notice, the acknowledgments, and the information on obtaining the latest
copy of this list are retained and no fee is charged. The code fragments
may be used freely; credit to the FAQ would be polite. This FAQ is not to
be included in any static: archive (e.g. CD-ROM or book); however, a
pointer to the FAQ may be included. See <Q:01.14> [Where can I get the
latest copy of this FAQ list?] for a link to the latest version of the
FAQ.)

This is part 3 of 5 parts.

TABLE OF CONTENTS

PART 1:

PART 3: (this part)

------------------------------

Subject: Section 5. Disks and files


Date: 5 Feb 2002 22:03:03 -0400

Information about accessing disks and files from MS-DOS.

------------------------------

Subject: <Q:05.01> - What drive was the PC booted from?


Date: 5 Feb 2002 22:03:03 -0400

Under DOS 4.0 or later, use INT 21 AX=3305. DL is returned with an
integer indicating the boot drive (1=A:, etc.).

------------------------------

Subject: <Q:05.02> - How can I boot from drive B:?
Date: 8 Feb 2002 19:52:06 -0400

Downloadable shareware: <http://www.simtel.net/pub/pd/44102.html>
<ftp://garbo.uwasa.fi/pc/bootutil/boot_b.zip>

The included documentation says it works by writing a new boot sector on
a disk in your a: drive that redirects the boot to your B: drive. (A
similar utility is bboot.zip in the same directory at Garbo only.)

If that doesn't work, you can always interchange your A: and B: drives
by switching ribbon cables and changing the setup in your BIOS. From an
article posted 27 Jan 1993 on another newsgroup:

[begin quotation]
Take the "ribbon" connector, as you call it, and switch
them. To double-check, start at the end of the cable that
connects to the motherboard or floppy controller. Follow
the cable until you get to the first connector. Connect
this to the drive you want to be B:.

After this, there should be a few lines on the cable that
get flipped left to right. (On most cables, they just cut
the lines and physically reverse them. It should be quite
obvious from looking at the cable.) Anyway, the connector
after the pins get flipped right to left is the connector
for your a: drive.
[end quotation]

------------------------------

Subject: <Q:05.03> - Which real and virtual disk drives are valid?


Date: 5 Feb 2002 22:03:03 -0400

Use INT 21 AH=29 (parse filename). Point DS:SI at a null- terminated
ASCII string that contains the drive letter and a colon, point ES:DI at
a 37-byte dummy FCB buffer, and call INT 21 AX=2900. On return, AL is FF
if the drive is invalid, something else if the drive is valid. RAM disks
and SUBSTed drives are considered valid.

You can detect whether the drive is ASSIGNed by using INT 2F AX=0601. To
check whether the drive is SUBSTed, use INT 21 AX=4409; or use INT 21
AH=52 to test for both JOIN and SUBST. See Ralf Brown's interrupt list:


<Q:02.03> [What and where is Ralf Brown's interrupt list?].

Unfortunately, the b: drive is considered valid even on a
single-diskette system. You can check that special case by interrogating
the BIOS equipment byte at 0040:0010. Bits 7- 6 contain the one less
than the number of diskette drives, so if those bits are zero you know
that b: is an invalid drive even though function 29 says it's valid.

Following is some code originally posted by Doug Dougherty to test valid
drives (treating SUBSTed and JOINed drives as valid), with my fix for
the b: special case, tested in Borland C++ 4.5 (in the large model):

#include <dos.h>
#include <stdio.h>

void drvlist(void)
{
char s[3] = "A:", fcb_buff[37];
int valid;

for( ; *s<='Z'; (*s)++)
{
_SI = (unsigned) s;
_DI = (unsigned) fcb_buff;
_ES = _DS;
_AX = 0x2900;

geninterrupt(0x21);
valid = _AL != 0xFF;

if (*s == 'B' && valid)
{
char far *equipbyte = (char far *)0x00400010UL;
valid = (*equipbyte & (3 << 6)) != 0;
}

printf("Drive '%s' is %sa valid drive.\n", s, valid ? "" : "not ");
}
}

This code was translated to MSC 7.0 and tested it in small model:

#include <dos.h>
#include <stdio.h>

void drvlist(void)
{
char s[3] = "A:", fcb_buff[37], *buff=fcb_buff;
int valid;

for ( ; *s<='Z'; (*s)++)
{
__asm mov si,s __asm mov di,buff
__asm mov ax,ds __asm mov es,ax
__asm mov ax,0x2900 __asm int 21h
__asm xor ah,ah __asm mov valid,ax

valid = (valid != 0xFF);

if (*s == 'B' && valid)
{
char far *equipbyte = (char far *)0x00400010UL;
valid = (*equipbyte & (3 << 6)) != 0;
}

printf("Drive '%s' is %sa valid drive.\n", s, valid ? "" : "not");
}
}

------------------------------

Subject: <Q:05.04> - How can I make my single floppy drive both a: and
b:?


Date: 5 Feb 2002 22:03:03 -0400

Under any DOS since DOS 2.0, you can put the following command into your
AUTOEXEC.BAT file:

assign b=a

Then, when you type "dir b:" you'll no longer get the annoying prompt to
insert diskette B (and the even more annoying prompt to insert A the
next time you type "dir a:").

You may be wondering why anybody would want to do this. Suppose you use
two different machines, maybe one at home and one at work. One of them
has only a 3.5" diskette drive; the other machine has two drives, and b:
is the 3.5" one. You're bound to type "dir b:" on the first one, and get
the nuisance message:

Insert diskette for drive B: and press any key when ready.

But if you assign drive b: to point to a:, you avoid this problem.

Caution: there are a few commands, such as DISKCOPY, that will not work
right on ASSIGNed or SUBSTed drives. See the DOS manual for the full
list. Before typing one of those commands, be sure to turn off the
mapping by typing "assign" without arguments.

The DOS 5.0 manual says that ASSIGN is obsolete, and recommends the
equivalent form of SUBST: "subst b: a:\". Unfortunately, if this command
is executed when a: doesn't hold a diskette, the command fails. ASSIGN
doesn't have this problem, so under DOS 5.0 you should disregard that
particular bit of advice in the manual.

------------------------------

Subject: <Q:05.05> - How can I disable access to a drive?
Date: 8 Feb 2002 19:53:23 -0400

Reader Eric DeVolder writes that he has made available a program to do
this. I haven't tried it, but it's downloadable from
<http://www.simtel.net/pub/pd/44403.html>

Reader Igor Karp reports that MS-DOS version 5.0 and greater provides
two interrupts to do this.

--------D-215F07-----------------------------
INT 21 - DOS 5+ - ENABLE DRIVE
AX = 5F07h
DL = drive number (0=A:)
Return: CF clear if successful
CF set on error
AX = error code (0Fh) (see #0885 at AH=59h)
Notes: simply sets the "valid" bit in the drive's CDS
this function is not supported by Novell DOS 7
See Also: AH=52h,AX=5F08h"DOS"

--------D-215F08-----------------------------
INT 21 - DOS 5+ - DISABLE DRIVE
AX = 5F08h
DL = drive number (0=A:)
Return: CF clear if successful
CF set on error
AX = error code (0Fh) (see #0885 at AH=59h)
Notes: simply clears the "valid" bit in the drive's CDS
this function is not supported by Novell DOS 7

------------------------------

Subject: <Q:05.06> - How can a batch file test existence of a directory?
Date: 8 Feb 2002 19:54:04 -0400

The standard way, which in fact is documented in the DOS manual, is:

if exist d:\path\nul goto found

Unfortunately, this is not entirely reliable. I found it failed in
Pathworks (a/k/a PCSA, DEC's network that connects PCs and VAXes), or on
a MARS box that uses an OEM version of MS-DOS 5.0. Readers have reported
that it gave the wrong answer on Novell networks, on DR-DOS, and in a
DOS window under OS/2. By "failed" I mean that it "found" a directory
that didn't exist, or failed to find one that did exist, or both. (It
has been reported that IBM fixed the OS/2 bug in version 2.11 of OS/2.)
As a legacy from earlier versions of DOS it always succeeds if the path
is DEV.

There appears to be no foolproof way to use pure batch commands to test
for existence of a directory. The real solution is to write a program,
which returns a value that your batch program can then test with an "if
errorlevel". Reader Duncan Murdoch kindly posted the following Turbo
Pascal version:

program existdir;
{ Confirms the existence of a directory given on the
command line. Returns errorlevel 2 on error, 1 if not
found, 0 if found. }

uses dos;

var
s : searchrec;

begin
if paramcount <> 1 then
begin
writeln('Syntax: EXISTDIR directory');
halt(2);
end
else
begin
findfirst(paramstr(1),Directory,S);
while (Doserror = 0) and ((Directory and S.Attr) = 0) do
findnext(S);

if Doserror <> 0 then
begin
Writeln('Directory not found.');
halt(1);
end
else
begin
Writeln('Directory found.');
halt(0);
end;
end;
end.

Timo Salmi also has a Turbo Pascal version in his Turbo Pascal FAQ,
which is downloadable as <ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip>

------------------------------

Subject: <Q:05.07> - Why won't my C program open a file with a path?


Date: 5 Feb 2002 22:03:03 -0400

You've probably got something like the following code:

char *filename = "c:\foo\bar\mumble.dat";
FILE *fptr;
/*.*/
fptr = fopen(filename, "r");

The problem is that \f is a form feed, \b is a backspace, and \m is m.
Whenever you want a backslash in a string constant in C, you must use
two backslashes:

char *filename = "c:\\foo\\bar\\mumble.dat";

This is a feature of every C compiler, because Dennis Ritchie designed C
this way. It's a problem only on MS-DOS systems, because only DOS (and
Atari ST/TT running TOS) uses the backslash in directory paths. But even
in DOS this backslash convention applies _only_ to string constants in
your source code. For file and keyboard input at run time, \ is just a
normal character, so users running your program would type in file specs
the same way as in DOS commands, with single \ characters.

Another possibility is to code all paths in source programs with /
rather than \ characters:

char *filename = "c:/foo/bar/mumble.dat";

Ralf Brown writes, "All versions of the DOS kernel accept either forward
or backslashes as directory separators. I tend to use this form more
frequently than backslashes since it is easier to type and read." This
applies to DOS function calls (and therefore to calls to the file
library of every programming language), but not to DOS commands.

------------------------------

Subject: <Q:05.08> - How can I redirect printer output to a file?
Date: 8 Feb 2002 19:55:31 -0400

Recommended: PRN2FILE from PC Magazine, downloadable as:
<http://www.simtel.net/pub/pd/49066.html>

PRN2FILE contains ASM source code. PC Magazine has given copies away as
part of its utilities disks, so you may already have a copy.

The directories mentioned above have lots of other utilities to redirect
printer output.

------------------------------

Subject: <Q:05.09> - How can I redirect the output of a batch file?
Date: 7 Feb 2002 14:48:46 -0400

Assuming the batch file is called batch.bat, to send its output (stdout)
to another file, just invoke COMMAND.COM as a secondary command
processor:

command /c batch parameters_if_any >outfile

Timo Salmi's notes on this and other batch tricks are downloadable from:
<ftp://garbo.uwasa.fi/pc/link/tsbat.zip>

A reader of comp.os.msdos.programmer has created a utility that can
capture batch file output. It can be found at:
<http://www.simtel.net/pub/dl/11141.shtml>

------------------------------

Subject: <Q:05.10> - How can I redirect stderr?
Date: 8 Feb 2002 19:58:21 -0400

Use freopen(..., stderr) and then execute the desired command via
system(). There are downloadable versions of programs to do this.

This file includes TP4 source and an executable:
<http://www.simtel.net/pub/pd/50430.html>

A C example is downloadable as:
<http://www.simtel.net/pub/pd/41772.html>

I compiled it with MSC 7.0, and it works fine with one exception:
Contrary to the included comments, redirected output starts writing at
the beginning of the output file rather than appending. That is easily
solved by adding "fseek(stderr, 0L, SEEK_END);" after the freopen() call
for stderr.

A reader comp.os.msdos.programer has created a utilitiy that can capture
console output. It can be found at:
<http://www.simtel.net/pub/dl/11141.shtml>

------------------------------

Subject: <Q:05.11> - How can my program open more files than DOS's limit
of 20?


Date: 5 Feb 2002 22:03:03 -0400

This is a summary of an article Ralf Brown posted on 8 August 1992, with
some additions from a Microsoft tech note and information from Chin
Huang.)

DOS imposes some limits. Once you overcome those, which is pretty easy,
you may have to take additional measures to overcome the limitations
built into your compiler's run- time library.

1) Limitations imposed by DOS:

There are separate limits on files and file handles. For example, DOS
opens three files but five file handles: CON (stdin, stdout, and
stderr), AUX (stdaux), and PRN (stdprn).

The limit in FILES= in CONFIG.SYS is a system-wide limit on files opened
by all programs (including the three that DOS opens and any opened by
TSRs); each process has a limit of 20 handles (including the five that
DOS opens). Example: CONFIG.SYS has FILES=40. Then program #1 will be
able to open 15 file handles. Assuming that the program actually does
open 15 handles pointing to 15 different files, other programs could
still open a total of 22 files (40-3-15 = 22), though no one program
could open more than 15 file handles. If you're running DOS 3.3 or
later, you can increase the per-process limit of 20 file handles by a
call to INT 21 AH=67, Set Handle Count. Your program is still limited by
the system-wide limit on open files, so you may also need to increase
the FILES= value in your CONFIG.SYS file (and reboot). The run-time
library that you're using may have a fixed-size table of file handles,
so you may also need to get source code for the module that contains the
table, increase the table size, and recompile it.

2) Limitations in Microsoft C run-time library:

In Microsoft C the run-time library limits you to 20 file handles. To
change this, you must be aware of two limits:

File handles used with _open(), _read(), etc.: Edit _NFILE_ in
CRT0DAT.ASM.

Stream files used with fopen(), fread(), etc.: Edit _NFILE_ in _FILE.C
for DOS or FILE.ASM for Windows/QuickWin. This must not exceed the value
of _NFILE_ in CRT0DAT.ASM. (QuickWin uses the constant _WFILE_ in
CRT0DAT.ASM and WFILE.ASM for the maximum number of child text windows.)

After changing the limits, recompile using CSTARTUP.BAT. Microsoft
recommends that you first read README.TXT in the same directory.

3) Limitations in Borland C++ run-time library:

(Reader Chin Huang provided this information on 12 Sep 1993.) To
increase the open file limit for a program you compile with Borland C++
3.1, edit the file _NFILE.H in the include directory and change the
_NFILE_ value. Compile and link the modules FILES.C and FILES2.C from
the lib directory into your program.

------------------------------

Subject: <Q:05.12> - How can I read, create, change, or delete the volume
label?


Date: 5 Feb 2002 22:03:03 -0400

In DOS 5.0 (and possibly in 4.0 as well), there are actually two volume
labels: the LABEL command reports only the first but changes both of
them.

* The traditional volume label is an entry with "volume label" attribute
in the root directory of the disk. The DIR, VOL, and LABEL commands
report this volume label, and LABEL sets it.

* There is a second volume label, which may be different, in the boot
record along with the serial number. In DOS 4.0 and later, INT 21
AH=69 gets or sets the boot record's serial number and volume label
together; see <Q:05.13> [How can I get the disk serial number?] DIR
and VOL ignore this volume label; the LABEL command doesn't report it
but does set it.

The rest of this answer assumes that by "volume label" you mean the
traditional one, the one that DIR and VOL display. Though it's a
directory entry in the root directory, you can't change it using the
newer DOS file-access functions (INT 21 AH=3C, 41, 43); instead, use the
old FCB-oriented directory functions. Specifically, you need to allocate
a 64-byte buffer and a 41- byte extended FCB (file control block). Call
INT 21 AH=1A to find out whether there is a volume label. If there is,
AL returns 0 and you can change the label using DOS function 17 or
delete it using DOS function 13. If there's no volume label, function 1A
will return FF and you can create a label via function 16. Important
points to notice are that ? wildcards are allowed but * are not; the
volume label must be space filled not null terminated.

The following MSC 7.0 code worked for me in DOS 5.0; the functions it
uses have been around since DOS 2.0. The function parameter is 0 for the
current disk, 1 for a:, 2 for b:, etc. It doesn't matter what your
current directory is; these functions always search the root directory
for volume labels. (I didn't try to change the volume label of any
networked drives.)

// Requires DOS.H, STDIO.H, STRING.H

void vollabel(unsigned char drivenum)
{
static unsigned char extfcb[41], dta[64], status, *newlabel;
int chars_got = 0;

#define DOS(buff,func) __asm { __asm mov dx,offset buff \
__asm mov ax,seg buff __asm push ds __asm mov ds,ax \
__asm mov ah,func __asm int 21h __asm pop ds \
__asm mov status,al }

#define getlabel(buff,prompt) newlabel = buff; \
memset(newlabel,' ',11); printf(prompt); \
scanf("%11[^\n]%n", newlabel, &chars_got); \
if (chars_got < 11) newlabel[chars_got] = ' ';

// Set up the 64-byte transfer area used by function 1A.
DOS(dta, 1Ah)

// Set up an extended FCB and search for the volume label.
memset(extfcb, 0, sizeof extfcb);
extfcb[0] = 0xFF; // denotes extended FCB
extfcb[6] = 8; // volume-label attribute bit
extfcb[7] = drivenum; // 1=A,2=B,...; 0=current drive

memset(&extfcb[8], '?', 11);// wildcard *.*
DOS(extfcb,11h)
if(status == 0)
{ // DTA has volume label's FCB
printf("volume label is %11.11s\n", &dta[8]);
getlabel(&dta[0x18], "new label (\"delete\" to delete): ");

if(chars_got==0)
printf("label not changed\n");
else if (strncmp(newlabel,"delete ",11) == 0)
{
DOS(dta,13h)
printf(status ? "label failed\n":"label deleted\n");
}
else
{ // user wants to change label
DOS(dta,17h)
printf(status ? "label failed\n" : "label changed\n");
}
}
else
{ // no volume label was found
printf("disk has no volume label.\n");
getlabel(&extfcb[8], "new label (<Enter> for none): ");

if (chars_got > 0)
{
DOS(extfcb,16h)
printf(status ? "label failed\n" : "label created\n");
}
}
} // end function vollabel

------------------------------

Subject: <Q:05.13> - How can I get the disk serial number?


Date: 5 Feb 2002 22:03:03 -0400

If the disk was formatted by DOS 4.0 or later, use INT 21: AX=6900 gets
the serial number; AX=6901 sets it. (The disk serial number doesn't
exist if the disk was formatted with an earlier version of DOS, or with
some third-party formatters.) See Ralf Brown's interrupt list (<Q:02.03>
[What and where is Ralf Brown's interrupt list?]), or PC Magazine July
1992 (xi:13) page 496, for details.

INT 21 AH=69 also gets and sets the volume label in the boot record,
which is not necessarily the same as "the" volume label displayed by the
DIR, VOL, and LABEL commands. For that volume label, see <Q:05.12> [How
can I read, create, change, or delete the volume label?]

------------------------------

Subject: <Q:05.14> - What's the format of .OBJ, .EXE., .COM files?


Date: 5 Feb 2002 22:03:03 -0400

Please see <Q:03.06> [What's the format of an .OBJ file?]; <Q:03.07>
[What's the format of an .EXE header?]; and <Q:03.08> [What's the
difference between .COM and .EXE formats?]

------------------------------

Subject: <Q:05.15> - How can I flush the software disk cache?


Date: 5 Feb 2002 22:03:03 -0400

Please see <Q:08.01> [How can a program reboot my PC?] (Trust me.)

------------------------------

Subject: <Q:05.16> - How can I see if a drive is a RAM drive?


Date: 5 Feb 2002 22:03:03 -0400

Use INT 21 AX=4409h. See Ralph Brown's interrupt list (<Q:02.03> [What
and where is Ralf Brown's interrupt list?]) for more information.

------------------------------

Subject: <Q:05.17> - How can I determine a hard drive's manufacturer?


Date: 5 Feb 2002 22:03:03 -0400

Information about the hard drive's manufacturer is retrieved by using
the ATA and ATAPI specifications. Please see "<Q:05.18> [Where can I
find information about the ATA/ATAPI specification?]

------------------------------

Subject: <Q:05.18> - Where can I find information about the ATA/ATAPI
specification?


Date: 5 Feb 2002 22:03:03 -0400

The AT Attachment (ATA) standard is maintained by T13, a Technical
Committee for the National Committee on Information Technology Standards
which as accredited by ANSI. Their web site can be found at
<http://www.t13.org>. At that web site the ATA and ATAPI specifications
are availible in PDF form.

------------------------------

Subject: <Q:05.19> - How can I copy files to or from filenames containing
date information?
Date: 7 Feb 2002 14:26:15 -0400

You can use the NOWMINUS program. This program creates environment
variables containing date and time information. See <Q:08.15> [How can I
place date and time information into environment variables?] for more
information.

Here is an example of using NOWMINUS to rename the files thisweek.* to
{lastweeksdate}.*:

NOWMINUS d7 z7 f1 j0 vLASTWEEK
ren thisweek.* %LASTWEEK%.*
set LASTWEEK=

------------------------------

Subject: Section 6. Serial ports (COM ports)


Date: 5 Feb 2002 22:03:03 -0400

This section provides information about how to access the serial ports.
In the future I will be working on adding information about using MS-DOS
for networking and internet access.

------------------------------

Subject: <Q:06.01> - How do I set my machine up to use COM3 and COM4?


Date: 5 Feb 2002 22:03:03 -0400

Unless your machine is fairly old, it's probably already set up. After
installing the board that contains the extra COM port(s), check the I/O
addresses in word 0040:0004 or 0040:0006. (In DEBUG, type "D 40:4 L4"
and remember that every word is displayed low byte first, so if you see
"03 56" the word is 5603.) If those addresses are nonzero, your PC is
ready to use the ports and you don't need the rest of this answer.

If the I/O address words in the 0040 segment are zero after you've
installed the I/O board, you need some code to store these values into
the BIOS data segment:

0040:0004 word I/O address of COM3
0040:0006 word I/O address of COM4
0040:0011 byte (bits 3-1): number of serial ports installed

The documentation with your I/O board should tell you the port
addresses. When you know the proper port addresses, you can add code to
your program to store them and the number of serial ports into the BIOS
data area before you open communications. Or you can use DEBUG to create
a little program to include in your AUTOEXEC.BAT file, using this
script:

n SET_ADDR.COM <--- or a different name ending in .COM
a 100
mov AX,0040
mov DS,AX
mov wo [0004],aaaa <--- replace aaaa with COM3 address or 0
mov wo [0006],ffff <--- replace ffff with COM4 address or 0
and by [0011],f1
or by [0011],8 <--- use number of serial ports times 2
mov AH,0
int 21
<--- this line must be blank
rCX
1f
rBX
0
w
q

------------------------------

Subject: <Q:06.02> - How do I find the I/O address of a COM port?
Date: 8 Feb 2002 20:00:09 -0400

Look in the four words beginning at 0040:0000 for COM1 through COM4.
(The DEBUG command "D 40:0 L8" will do this. Remember that words are
stored and displayed low byte first, so a word value of 03F8 will be
displayed as F8 03.) If the value is zero, that COM port is not
installed (or you've got an old BIOS; see <Q:06.01> [How do I set my
machine up to use COM3 and COM4?]). If the value is nonzero, it is the
I/O address of the transmit/receive register for the COM port.

Each COM port occupies eight consecutive I/O addresses (though many
chips use only the first seven).

Here's some C code to find the I/O address:

unsigned ptSel(unsigned comport)
{
unsigned io_addr;

if (comport >= 1 && comport <= 4)
{
unsigned far *com_addr = (unsigned far *)0x00400000UL;
io_addr = com_addr[comport-1];
}
else
io_addr = 0;

return io_addr;
}

You might also want to explore Port Finder, downloadable as:
<http://www.simtel.net/pub/pd/47138.html>

I haven't tried it myself, but a posted article reviewed it very
favorably and said it also lets you swap ports around.

------------------------------

Subject: <Q:06.03> - But aren't the COM ports always at I/O addresses


3F8, 2F8, 3E8, and 2E8?

Date: 5 Feb 2002 22:03:03 -0400

The first two are usually right (though not always); the last two are
different on many machines.

------------------------------

Subject: <Q:06.04> - How do I configure a COM port and use it to transmit
data?
Date: 8 Feb 2002 20:03:52 -0400

Do you want actual code, or do you want books that explain what's going
on?

1) Source code

First, check your compiler's run-time library. Many compilers offer
functions similar to Microsoft C's _bios_serialcom() or Borland's
bioscom(), which may meet your needs.

Second, check for downloadable resources at SimTel and Garbo. At SimTel,
<http://www.simtel.net/pub/pd/41750.html> (March 1993) is described as
"Asynchronous communications library for C"; Garbo has a whole
<ftp://garbo.uwasa.fi/pc/comm> directory. Also, an extended example is
in Borland's TechFax TI445, downloadable as part of:
<http://www.simtel.net/pub/pd/50843.html>
<ftp://garbo.uwasa.fi/pc/c-lang/bchelp10.zip>

Though written by Borland, much of it is applicable to other forms of C,
and it should give you ideas for other programming languages.

Third, SNIPPETS (see <Q:02.08> [What and where is SNIPPETS?]) contains a
sample interrupt-driven serial communications library.

2) Reference books

Highly recommended: Joe Campbell's {C Programmer's Guide to Serial
Communications}, ISBN 0-672-22584-0. He gives complete details on how
serial ports work, along with complete programs for doing polled or
interrupt-driver I/O. The book is quite thick, and none of it looks like
filler.

If Campbell's book is overkill for you, you'll find a good short
description of serial I/O in {DOS 5: A Developer's Guide}, ISBN
1-55851-177-6, by Al Williams.

Finally, a reader has recommended {Serial Communications Programming in
C/C++} by Mark Goodwin (ISBN 1-55828-198-3), with source code in the
book and on disk. Topics include the basics, various methods of serial
communications on the PC (with consideration of high-speed modems), ANSI
screen interface, file transfer protocols (Xmodem and Ymodem), etc.
There is code in C, and that code is extended into a C++ class for those
who use C++. There are also subroutines in Assembly.

3) Downloadable information files

A "Serial Port FAQ" is occasionally posted to this newsgroup, and is
downloadable as multiple files:

<ftp://ftp.phil.uni-sb.de/pub/people/chris/>

This directory contains a series of files beginning with Serial_Port.

------------------------------

Subject: Conclusion

This is the end of part 3 of 5 parts.

Jeffrey Carlyle

unread,
Apr 9, 2004, 7:57:46 AM4/9/04
to
Archive-name: msdos-programmer-faq/part2
Comp-os-msdos-programmer-archive-name: dos-faq-pt2.txt

Posting-frequency: 28 days
Last-modified: 14 Aug 2003

comp.os.msdos.programmer FAQ Version 2003.08.14

This is the Frequently Asked Questions list for the newsgroup
comp.os.msdos.programmer.

COPYRIGHT

Copyright 2003 by Jeffrey Carlyle. All rights reserved. This article is
not in the public domain, but it may be redistributed so long as this
notice, the acknowledgments, and the information on obtaining the latest
copy of this list are retained and no fee is charged. The code fragments
may be used freely; credit to the FAQ would be polite. This FAQ is not to
be included in any static: archive (e.g. CD-ROM or book); however, a
pointer to the FAQ may be included. See <Q:01.14> [Where can I get the
latest copy of this FAQ list?] for a link to the latest version of the
FAQ.)

This is part 2 of 5 parts.

TABLE OF CONTENTS

PART 1:

PART 2: (this part)

------------------------------

Subject: Section 3. Compile and link


Date: 5 Feb 2002 22:03:03 -0400

The Compile and Link section contains information issues involving
compiling and linking of MS-DOS code.

------------------------------

Subject: <Q:03.01> - What the heck is DGROUP > 64K?
Date: 8 Feb 2002 19:38:12 -0400

This question explains the problem; the next question gives some
remedies.

DGROUP is a link-time group of data segments, and the compiler typically
generates code that expects DS to be pointing to DGROUP. (Exception:
Borland's huge model has no DGROUP.)

Here's what goes into DGROUP:

* Tiny models (all pointers near): DGROUP holds the entire program.

* Small and medium models (data pointers near): DGROUP holds all globals
and static variables including string literal data, plus the stack and
the heap.

* Large, compact, and huge models in Microsoft (data pointers far):
DGROUP holds only initialized globals and static variables including
string literal data, plus the stack and the near heap.

* Large and compact models in Borland (data pointers far): DGROUP holds
initialized and uninitialized globals and static variables including
string literal data, but not the stack or heap.

* Huge model in Borland (data pointers far): there is no DGROUP, so the
64K limit doesn't apply.

In all of the above, which is to say all six models in Microsoft C and
all but huge in Borland C, DGROUP is limited to 64K including string
literal data (which are treated as static data). This limitation is due
to the Intel CPU's segmented architecture.

For more information, see topics like "memory models" and "memory
management" in the index of your compiler manual. Also for an extended
general discussion of memory usage in Borland C programs, of which much
applies to any C compiler in DOS see TI738.asc, downloadable as part of:

<ftp://garbo.uwasa.fi/pc/c-lang/bchelp10.zip>

------------------------------

Subject: <Q:03.02> - How do I fix 'automatic data segment exceeds 64K' or


'stack plus data exceed 64K'?

Date: 5 Feb 2002 22:03:03 -0400

These messages are a variation of "DGROUP > 64K". For causes, please see
the preceding question.

If you get this error in tiny model, your program is simply too big and
you must use a different memory model. If you get this link error in
models small, compact, medium, large, or Microsoft's huge, there are
some things you can do. (This error can't occur in Borland's huge
model.)

If you have one or two big global arrays, simply declare them far. The
compiler takes this to mean that any references to them will use 32-bit
pointers, so they'll be in separate segments and no longer part of
DGROUP.

Or you can use the /Gt[number] option with Microsoft or - Ff[=size] with
Borland C++ 2.0 and up. This will automatically put variables above a
certain size into their own segments outside of DGROUP.

Yet another option is to change global arrays to far pointers. Then at
the beginning of your program, allocate them from the far heap
(_fmalloc() in Microsoft, farmalloc() in Borland).

Finally, you can change to huge model (with Borland compilers, not
Microsoft). Borland's H model still uses far pointers by default, but
"sets aside the [64K] limit" and has no DGROUP group, according to the
BC++ 2.0 Programmer's Guide. Microsoft's H model does use huge data
pointers by default but retains DGROUP and its 64K limit, so switching
to the huge model doesn't buy you anything if you have DGROUP problems.

------------------------------

Subject: <Q:03.03> - Will Borland C code and Microsoft C code link
together?


Date: 5 Feb 2002 22:03:03 -0400

Typically someone who owns compiler A and is trying to write code to
link with a third-party library that was compiled under compiler B asks
this question.

The answer to the question is, Not in general. Here are some of the
reasons:

* "Helper" functions (undocumented functions for stack checking,
floating-point arithmetic, and operations on longs) differ between the
two compilers.

* Extended dictionaries are not compatible between the 2 formats.
However, the basic structure of both MS and Borland OBJ formats is
based on the OMF format so specifying that the linker ignore the
extended dictionary records (/NOE for LINK, -e for TLINK) will disable
this little hassle.

* The compilers may embed instructions in the object code that tell the
linker to look for their own run-time libraries. You can use the
linker option that says to ignore such instructions: /n in TLINK, /NOD
in the Microsoft linker (the one that comes with the C compiler, not
the one that used to come with DOS). But getting around this problem
will very likely just reveal other problems, like different helper
functions, that have no easy solution.

Those problems will generate link-time errors. Others may not show up
until run time:

* Borland's compact, large, and huge models don't assume DS=SS, but
Microsoft's do. The -Fs option on the Borland compiler, or one of the
/A options on Microsoft, should take care of this problem-once you
know that's what's going on.

* Check conventions for ordering and packing structure members, and for
alignment of various types on byte, word, paragraph, or other
boundaries. Again, you can generally adjust your code to match if you
know what conventions were used in compiling the "foreign" libraries.

* Check the obvious and make sure that your code was compiled under the
same memory model as the code you're trying to link with. (That's
necessary, but no guarantee. Microsoft and Borland don't use exactly
the same conventions for segments and groups, particularly in the
larger memory models.)

That said, there are some circumstances where you can link hybrids. Your
best chance of success comes if you compile in large model with the
compiler switch that says to reload DS on entry to each function, avoid
longs and floating point, use only 16-bit pointers, suppress stack
checking, and specify all libraries used in the link.

------------------------------

Subject: <Q:03.04> - Why did my program bomb at run time with 'floating


point formats not linked' or 'floating point not loaded'?

Date: 5 Feb 2002 22:03:03 -0400

These messages look similar but have very different causes.

"Floating point not loaded" is Microsoft C's run-time message when the
code requires a numeric coprocessor but your computer doesn't have one
installed. If the program is yours, relink it using the xLIBCE or xLIBCA
library (where x is the memory model).

"Floating point formats not linked" is a Borland run-time error (Borland
C or C++, Turbo C or C++). Borland's compilers try to be smart and not
link in the floating- point (f-p) library unless you need it. Alas, they
all get the decision wrong. One common case is where you don't call any
f-p functions, but you have %f or other f-p formats in scanf() or
printf() calls. The cure is to call an f-p function, or at least force
one to be present in the link.

To do that, define this function somewhere in a source file but don't
call it:

static void forcefloat(float *p)
{
float f = *p;
forcefloat(&f);
}

It doesn't have to be in the module with the main program, as long as
it's in a module that will be included in the link.

If you have Borland C++ 3.0, the README file documents a slightly less
ugly work-around. Insert these statements in your program:

extern unsigned _floatconvert;
#pragma extref _floatconvert

------------------------------

Subject: <Q:03.05> - How can I change the stack size in Borland's C
compilers?


Date: 5 Feb 2002 22:03:03 -0400

In Turbo C, Turbo C++, and Borland C++, you may not find "stack size" in
the index but the global variable _stklen should be there. The manual
will instruct you to put a statement like

extern unsigned _stklen = 54321U;

in your code, outside of any function. You must assign the value right
in the extern statement; it won't work to assign a value at run time.
The linker may give you a duplicate symbol warning, which you can
ignore.

If you are using the Borland PowerPack for DOS _stklen does not change
the stack size. To change the stack size you must use STACKSIZE in your
.DEF file. HEAPSIZE can be used to change the size of your program's
heap.

------------------------------

Subject: <Q:03.06> - What's the format of an .OBJ file?
Date: 27 Jun 2003 07:17:15 -0400

Reader Bob Smith, reports that there is a free tool at
<ftp://ftp.sudleyplace.com/sudleyplace/dispobj.zip> which displays the
contents of an .OBJ file, as well as two more free tools at
<ftp://ftp.sudleyplace.com/sudleyplace/displib.zip> which display and
search the contents of .LIB files.

Information about the base .OBJ format can be found in Intel's document
number #121748-001, {8086 Relocatable Object Module Formats} (not
verified).

Both Microsoft and Borland have extended the .OBJ format, as has IBM for
OS/2; and according to the MS-DOS encyclopedia, Microsoft doesn't
actually use all the listed formats.

Microsoft-specific .OBJ formats:

* A 45-page article can be found in the {MS-DOS Encyclopedia}, ISBN
1-55615-049-0, now out of print.

* "Microsoft Object Module Format (OMF)" Specification, 22 Nov 1991, was
published by the Microsoft Languages Group (not verified).

Borland-specific .OBJ formats:

* Open Architecture Handbook. The Borland Developer's Technical Guide,
1991, no ISBN. Chapter 2, "Object file contents", (pages 27-50) covers
the comment records sent to the object file by Borland C++ version 3.0
and other Borland compilers. The comment records mostly contain
information for the Borland debugger (not verified).

A "tutorial on the .OBJ format" comes with the VAL experimental linker,
downloadable as <ftp://garbo.uwasa.fi/pc/assembler/linker.zoo>.

------------------------------

Subject: <Q:03.07> - What's the format of an .EXE header?


Date: 5 Feb 2002 22:03:03 -0400

See PC Magazine 30 June 1992 (XI: 12) pages 349-350 for the old and new
formats. For a more detailed layout, look under INT 21 AH=4B in Ralf
Brown's interrupt list <Q:02.03> [What and where is Ralf Brown's
interrupt list?] That list includes extensions for Borland's TLINK and
Borland debugger info.

Among the books that detail formats of executable files are {DOS
Programmer's Reference: 2d Edition} by Terry Dettman and Jim Kyle, ISBN
0-88022-458-4; and {Microsoft MS-DOS Programmer's Reference}, ISBN
1-55615-329-5.

------------------------------

Subject: <Q:03.08> - What's the difference between .COM and .EXE formats?
Date: 7 Feb 2002 14:47:51 -0400

To oversimplify: a .COM file is a direct image of how the program will
look in main memory, and a .EXE file will undergo some further
relocation when it is run (and so it begins with a relocation header). A
.COM file is limited to 64K for all segments combined, but a .EXE file
can have as many segments as your linker will handle and be as large as
RAM can take.

The actual file extension doesn't matter. DOS knows that a file being
loaded is in .EXE format if its first two bytes are MZ or ZM; otherwise
it is assumed to be in .COM format. For instance, DR-DOS 6.0's
COMMAND.COM is in .EXE format as is COMMAND.COM in recent versions of
MS-DOS.

Reader Paul Schylter posted this description of .COM files vs. .EXE
files to the newsgroup in message <a3rpp8$a9h$1...@merope.saaf.se>:

"Actually they must be less than 0xFF00 bytes long, since the PSP, which
isn't included in the COM file but is within those 64K, is 256 bytes
long.

"Then CAN use many segments, but they don't have to. In particular, any
.COM file can be converted to an .EXE file by adding an appropriate
header to it.

"There are some other differences between a .COM file and a single
segment .EXE file (both of which must be smaller than 64K):

"The entry point of the .COM file is _always_ 0x100, while the entry
point of the .EXE file can be at any address.

"The stack size of the .COM file is the remainder of those 64K which
isn't used by the code image, while the stack size if the single segment
.EXE file can be set at any size as long as it fits within those 64K.
Thus the stack can be smallere in the .EXE file.

"When a COM file is loaded, the entire TPA (= "free memory") of MS-DOS
is allocated for that COM file -- including those parts of the TPA which
are outside the 64k of the COM file. If you don't want this (e.g.
because your COM file is a TSR and you want to load other programs
later), you must explicitly free those parts of the TPA you want freed.
In the header of an .EXE file you can specify how large part of the TPA
that .EXE file should receive."

------------------------------

Subject: <Q:03.09> - How do I create a .COM file?


Date: 5 Feb 2002 22:03:03 -0400

There are two steps to creating a .COM file. First, your program must
not have a stack. In C, you must compile your program with the TINY
memory model. Second, use EXE2BIN or a similar program to convert an EXE
file to a COM file. To find EXE2BIN see subject: <Q:03.10> [Where is
EXE2BIN located?]

------------------------------

Subject: <Q:03.10> - Where is EXE2BIN located?


Date: 5 Feb 2002 22:03:03 -0400

EXE2BIN was formerly shipped with MS-DOS. If you are still using DOS 5.0
or earlier you can find EXE2BIN in your DOS directory. Users of DOS 6.x
need to get the MS-DOS Supplemental Disks. These disks are available via
FTP at ftp.microsoft.com.

<ftp://ftp.microsoft.com/peropsys/msdos/public/supplmnt>

------------------------------

Subject: <Q:03.11> - What does this message mean: 'A20 already enabled so
test is meaning less?'


Date: 5 Feb 2002 22:03:03 -0400

The DPMIINST program included with older versions of Borland C++ and
Turbo C++ compilers generates this message. Before running DPMIINST you
must clean boot your computer.

------------------------------

Subject: Section 4. Keyboard


Date: 5 Feb 2002 22:03:03 -0400

The keyboards sections coontains information about how to access the
keyboard.

------------------------------

Subject: <Q:04.01> - How can I read a character without echoing it to the


screen, and without waiting for the user to press the Enter key?

Date: 5 Feb 2002 22:03:03 -0400

The C compilers from Microsoft and Borland offer getch() (or getche() to
echo the character); Turbo Pascal has ReadKey.

In other programming languages, execute INT 21 AH=8; AL is returned with
the character from standard input (possibly redirected). If you don't
want to allow redirection, or you want to capture Ctrl-C and other
special keys, use INT 16 AH=10; this will return the scan code in AH and
ASCII code (if possible) in AL, but AL=E0 with AH nonzero indicates that
one of the gray "extended" keys was pressed. (If your BIOS doesn't
support the extended keyboard, use INT 16 AH=0 not 10.)

------------------------------

Subject: <Q:04.02> - How can I find out whether a character has been


typed, without waiting for one?

Date: 5 Feb 2002 22:03:03 -0400

In Turbo Pascal, use KeyPressed. Both Microsoft C and Turbo C offer the
kbhit() function. All of these tell you whether a key has been pressed.
If no key has been pressed, they return that information to your
program. If a keystroke is waiting, they tell your program that but
leave the key in the input buffer.

You can use the BIOS call, INT 16 AH=01 or 11, to check whether an
actual keystroke is waiting; or the DOS call, INT 21 AH=0B, to check for
a keystroke from stdin (subject to redirection). See Ralf Brown's


interrupt list <Q:02.03> [What and where is Ralf Brown's interrupt
list?].

------------------------------

Subject: <Q:04.03> - How can I disable Ctrl-C/Ctrl-Break and/or
Ctrl-Alt-Del?


Date: 5 Feb 2002 22:03:03 -0400

Several utilities are downloadable from:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/keyboard/>

In that directory, cadel.zip contains a TSR (with source code) to
disable those keys. Also, keykill.arc contains two utilities:
keykill.com lets you disable up to three keys of your choice, and
deboot.com changes the boot key to leftShift-Alt-Del. C programmers who
simply want to make sure that the user can't Ctrl-Break out of their
program can use the ANSI-standard signal() function; the Borland
compilers also offer ctrlbrk() for handling Ctrl-Break. However, if your
program uses normal DOS input such as getch(), ^C will appear on the
screen when the user presses Ctrl-C or Ctrl-Break. You can avoid the ^C
echo for Ctrl-C by using _bios_keybrd() in MSC or bioskey() in BC++;
however, Ctrl-Break will still terminate the program.

An alternative approach involves programming input at a lower level. You
can use INT 21 AH=7, which allows redirection but doesn't echo the ^C
(or any other character, for that matter); or use INT 16 AH=0 or 10; or
hook INT 9 to discard Ctrl-C and Ctrl-Break before the regular BIOS
keyboard handler sees them; etc., etc.

You should be aware that Ctrl-C and Ctrl-Break are processed quite
differently internally. Ctrl-Break, like all keystrokes, is processed by
the BIOS code at INT 9 as soon as the user presses the keys, even if
earlier keys are still in the keyboard buffer: by default the handler at
INT 1B is called. Ctrl-C is not special to the BIOS, nor is it special
to DOS functions 6 and 7; it is special to DOS functions 1 and 8 when at
the head of the keyboard buffer. You will need to make sure BREAK is OFF
to prevent DOS polling the keyboard for Ctrl-C during non-keyboard
operations.

Some good general references are {Advanced MS-DOS} by Ray Duncan, ISBN
1-55615-157-8; {8088 Assembler Language Programming: The IBM PC}, ISBN
0-672-22024-5, by Willen & Krantz; and {COMPUTE!'s Mapping the IBM PC},
ISBN 0-942386- 92-2.

------------------------------

Subject: <Q:04.04> - How can I disable the print screen function?


Date: 5 Feb 2002 22:03:03 -0400

There are really two print screen functions: 1) print current screen
snapshot, triggered by PrintScreen or Shift- PrtSc or Shift-gray*, and
2) turn on continuous screen echo, started and stopped by Ctrl-P or
Ctrl-PrtSc.

1) Screen snapshot to printer:

The BIOS uses INT 5 for this. Fortunately, you don't need to mess with
that interrupt handler. The standard handler, in BIOS versions dated
December 1982 or later, uses a byte at 0040:0100 (= 0000:0500) to
determine whether a print screen is currently in progress. If it is,
pressing PrintScreen again is ignored. So to disable the screen
snapshot, all you have to do is write a 1 to that byte. When the user
presses PrintScreen, the BIOS will think that a print screen is already
in progress and will ignore the user's keypress. You can re-enable
PrintScreen by zeroing the same byte.

Here's some simple code:

void prtsc_allow(int allow) /* 0=disable, nonzero=enable */
{
unsigned char far* flag = (unsigned char far*)0x00400100UL;
*flag = (unsigned char)!allow;
}

2) Continuous echo of screen to printer:

If ANSI.SYS is loaded, you can easily disable the continuous echo of
screen to printer (Ctrl-P or Ctrl- PrtSc). Just redefine the keys by
"printing" strings like these to the screen (BASIC print, C printf(),
Pascal Write statements, or ECHO command in batch files), where <27>
stands for the Escape character, ASCII 27:

<27>[0;114;"Ctrl-PrtSc disabled"p
<27>[16;"^P"p

If you haven't installed ANSI.SYS, I can't offer an easy way to disable
the echo-screen-to-printer function.

Actually, you might not need to disable Ctrl-P and Ctrl- PrtSc. If your
only concern is not locking up your machine, when you see the "Abort,
Retry, Ignore, Fail" prompt just press Ctrl-P again and then press I. As
an alternative, install one of the many print spoolers that intercept
printer-status queries and always return "Printer ready".

------------------------------

Subject: <Q:04.05> - How can my program turn NumLock (CapsLock,
ScrollLock) on or off?
Date: 12 Sep 2002 17:46:15 -0400

First, if you just don't want NumLock turned on when you reboot, check
your system's setups. (Press a special key like Del at boot time, or run
the setup program supplied with your system.) Many systems may have an
option in setup to turn NumLock off at boot time.

You need to twiddle bit 5, 6, or 4 of location 0040:0017. The code
example below demonstrates changing NumLock status: lck() turns on a
lock state, and unlck() turns it off.

/* The status lights on some keyboards may not reflect the
* change. If yours is one, call INT 16 AH=2, "get shift
* status", and that may update them. It will certainly do no
* harm.)
*/

#define NUM_LOCK (1 << 5)
#define CAPS_LOCK (1 << 6)
#define SCRL_LOCK (1 << 4)

void lck(int shiftype)
{
char far* kbdstatus = (char far*)0x00400017UL;
*kbdstatus |= (char)shiftype;
}
void unlck(int shiftype)
{
char far* kbdstatus = (char far*)0x00400017UL;
*kbdstatus &= ~(char)shiftype;
}

------------------------------

Subject: <Q:04.06> - How can I speed up the keyboard's auto-repeat?
Date: 8 Feb 2002 19:42:39 -0400

The keyboard speed has two components: delay (before a key that you hold
down starts repeating) and typematic rate (the speed once the key starts
repeating). Most BIOS versions since 1986 let software change the delay
and typematic rate by calling INT 16 AH=3, "set typematic rate and
delay"; see Ralf Brown's interrupt list <Q:02.03> [What and where is
Ralf Brown's interrupt list?]. If you have DOS 4.0 or later, you can use
the MODE CON command that you'll find in your DOS manual.

On 83-key keyboards (mostly XTs), the delay and typematic rate can't
easily be changed. According to PC Magazine 15 Jan 1991 (x: 1) page 409,
to adjust the typematic rate you need "a memory-resident program which
simply '[watches]' the keyboard to see if you're holding down a key .
and after a certain time [starts] stuffing extra copies of the held-down
key into the buffer." No source code is given in that issue; but the
QUICKEYS utility that PC Magazine published in 1986 does this sort of
watching (not verified); source and object code are downloadable from
<http://www.simtel.net/pub/pd/48667.html>

------------------------------

Subject: <Q:04.07> - What is the SysRq key for?


Date: 5 Feb 2002 22:03:03 -0400

There is no standard use for the key. The BIOS keyboard routines in INT
16 simply ignore it; therefore so do the DOS input routines in INT 21 as
well as the keyboard routines in libraries supplied with high-level
languages.

When you press or release a key, the keyboard triggers hardware line
IRQ1, and the CPU calls INT 9. INT 9 reads the scan code from the
keyboard and the shift states from the BIOS data area.

What happens next depends on whether your PC's BIOS supports an enhanced
keyboard (101 or 102 keys). If so, INT 9 calls INT 15 AH=4F to translate
the scan code. If the translated scan code is 54 hex (for the SysRq key)
then INT 9 calls INT 15 AH=85 and doesn't put the keystroke into the
keyboard buffer. The default handler of that function does nothing and
simply returns. (If your PC has an older BIOS that doesn't support the
extended keyboards, INT 15 AH=4F is not called. Early ATs have 84-key
keyboards, so their BIOS calls INT 15 AH=85 but not 4F.)

Thus your program is free to use SysRq for its own purposes, but at the
cost of some programming. You could hook INT 9, but it's probably easier
to hook INT 15 AH=85, which is called when SysRq is pressed or released.

------------------------------

Subject: <Q:04.08> - How can my program tell what kind of keyboard is on
the system?


Date: 5 Feb 2002 22:03:03 -0400

Ralf Brown's Interrupt List <Q:02.03> [What and where is Ralf Brown's
interrupt list?] includes MEMORY.LST, a detailed breakdown by Robin
Walker of the contents of the BIOS system block that starts at
0040:0000. Bit 4 of byte 0040:0096 is "1=enhanced keyboard installed".
Here is a C code example to test the keyboard type:

char far *kbd_stat_byte3 = (char far *)0x00400096UL;
if (0x10 & *kbd_stat_byte3)
{
/* 101- or 102- keyboard is installed */
}
else
{
/* Not installed */
}

PC Magazine 15 Jan 1991 (x: 1) suggests on page 412 that "for some
clones [the above test] is not foolproof". If you use this method in
your program you should provide the user some way to override this test,
or at least some way to tell your program to assume a non-enhanced
keyboard. The article suggests a different approach to determining the
type of keyboard.

------------------------------

Subject: <Q:04.09> - How can I tell if input, output, or stderr has been
redirected?
Date: 8 Feb 2002 19:49:17 -0400

Normally, input and output are associated with the console (i.e., with
the keyboard and the screen, respectively). If either is not, you know
that it has been redirected. Some source code to check this is available
at the usual archive sites.

Timo Salmi has created a collection of Turbo Pascal units, one of which
can be used to detect such redirection. These can be downloaded from
<http://garbo.uwasa.fi/pc/ts.html>. The files you are looking for have
names of the format tspaVV??.zip where the VV is the current version and
?? is 70, 60, 55, 50, or 40 for Turbo Pascal 7.0, 6.0, 5.5, 5.0, or 4.0
respectively.) Source code is not included. Also see the downloadable
Frequently Asked Questions files by Timo Salmi:
<ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip>

If you program in C, use isatty() if your implementation has it.

Good references for the principles are PC Magazine 16 Apr 1991 (x: 7)
page 374; Ray Duncan's {Advanced MS-DOS}, ISBN 1-55615-157-8, or Ralf
Brown's interrupt list (<Q:02.03> [What and where is Ralf Brown's
interrupt list?]) for INT 21 AX=4400; and Terry Dettman and Jim Kyle's
{DOS Programmer's Reference: 2d edition}, ISBN 0-88022-458-4, pages
602-603.

------------------------------

Subject: <Q:04.10> - How can I increase the size of the keyboard buffer?
Date: 8 Feb 2002 19:50:41 -0400

Microsoft has its own keyboard extender available on the MS-DOS
supplemental disks for MS-DOS 6.22 which can be found at:
<ftp://ftp.microsoft.com/peropsys/msdos/public/supplmnt/sup622.exe>

Stan Brown, the former list maintainer, tested only one of the many
available device drivers that do this, namely BUF160, which extends the
keyboard buffer to 160 characters. It performed flawlessly for two years
with MS-DOS 5 and Windows 3.1. It's downloadable as:
<http://www.simtel.net/pub/pd/47186.html>
<ftp://garbo.uwasa.fi/pc/keyboard/buf160_6.zip>

------------------------------

Subject: <Q:04.11> - How can I stuff characters into the keyboard buffer?


Date: 5 Feb 2002 22:03:03 -0400

If your computer has an enhanced keyboard (see <Q:04.08> [How can my
program tell what kind of keyboard is on the system?]), put the scan
code in CH and the ASCII character in CL, then execute INT 16 AH=5. The
return in AL is 0 for success or 1 for buffer full.

------------------------------

Subject: Conclusion

This is the end of part 2 of 5 parts.

Jeffrey Carlyle

unread,
Apr 9, 2004, 7:57:47 AM4/9/04
to
Archive-name: msdos-programmer-faq/part4
Comp-os-msdos-programmer-archive-name: dos-faq-pt4.txt

Posting-frequency: 28 days
Last-modified: 14 Aug 2003

comp.os.msdos.programmer FAQ Version 2003.08.14

This is the Frequently Asked Questions list for the newsgroup
comp.os.msdos.programmer.

COPYRIGHT

Copyright 2003 by Jeffrey Carlyle. All rights reserved. This article is
not in the public domain, but it may be redistributed so long as this
notice, the acknowledgments, and the information on obtaining the latest
copy of this list are retained and no fee is charged. The code fragments
may be used freely; credit to the FAQ would be polite. This FAQ is not to
be included in any static: archive (e.g. CD-ROM or book); however, a
pointer to the FAQ may be included. See <Q:01.14> [Where can I get the
latest copy of this FAQ list?] for a link to the latest version of the
FAQ.)

This is part 4 of 5 parts.

TABLE OF CONTENTS

PART 1:

PART 4: (this part)

------------------------------

Subject: Section 7. Other hardware questions and problems


Date: 5 Feb 2002 22:03:03 -0400

The subject says it all. Bv)

------------------------------

Subject: <Q:07.01> - Which 80x86 CPU is running my program?


Date: 5 Feb 2002 22:03:03 -0400

SNIPPETS (see <Q:02.08> [What and where is SNIPPETS?]) contains
C-callable x86 assembly language code for determining the type of CPU in
CPUCHECK.ASM.

------------------------------

Subject: <Q:07.02> - How can a C program send control codes to my
printer?


Date: 5 Feb 2002 22:03:03 -0400

If you just fprintf(stdprn, ...), C will translate some of your control
codes. The way around this is to reopen the printer in binary mode: prn
= fopen("PRN", "wb");

You must use a different file handle because stdprn isn't an lvalue. By
the way, in DOS 5.0 a colon must not follow PRN or LPT1.

There's one special case, Ctrl-Z (ASCII 26), the DOS end-of- file
character. If you try to send an ASCII 26 to your printer, DOS simply
ignores it. To get around this, you need to reset the printer from
"cooked" to "raw" mode. Microsoft C users must use INT 21 AH=44,
"get/set device information". Turbo C and Borland C++ users can use
ioctl to accomplish the same thing: ioctl(fileno(prn), 1,
ioctl(fileno(prn),0) & 0xFF | 0x20, 0);

An alternative approach is simply to write the printer output into a
disk file, then copy the file to the printer with the /B switch.

A third approach is to bypass DOS functions entirely and use the BIOS
printer functions at INT 17. If you also fprintf(stdprn,...) in the same
program, you'll need to use fflush() to synchronize fprintf()'s buffered
output with the BIOS's unbuffered.

By the way, if you've opened the printer in binary mode from a C
program, remember that outgoing \n won't be translated to carriage
return/line feed. Depending on your printer, you may need to send
explicit \n\r sequences.

------------------------------

Subject: <Q:07.03> - How can I redirect printer output?


Date: 5 Feb 2002 22:03:03 -0400

Please see <Q:05.08> [How can I redirect printer output to a file?]

------------------------------

Subject: <Q:07.04> - Which video adapter is installed?


Date: 5 Feb 2002 22:03:03 -0400

The technique below should work if your BIOS is not too old. It uses
three functions from INT 10, the BIOS video interrupt. (If you're using
a Borland language, you may not have to do this the hard way. Look for a
function called DetectGraph or something similar.)

Set AX=1200, BL=32 and call INT 10. If AL returns 12, you have a VGA. If
not, set AH=12, BL=10 and call INT 10 again. If BL returns 0,1,2,3, you
have an EGA with 64,128,192,256K memory. If not, set AH=0F and call INT
10 a third time. If AL is 7, you have an MDA (original monochrome
adapter) or Hercules; if not, you have a CGA.

This worked when tested with a VGA, but I had no other adapter types to
test it with.

------------------------------

Subject: <Q:07.05> - How do I switch to 43- or 50-line mode?
Date: 8 Feb 2002 20:05:49 -0400

The following file contains .COM utilities and .ASM source code:
<http://www.simtel.net/pub/pd/49657.html>

------------------------------

Subject: <Q:07.06> - How can I find the Microsoft mouse position and
button status?
Date: 8 Feb 2002 20:07:14 -0400

Use INT 33 AX=3, described in Ralf Brown's interrupt list (<Q:02.03>
[What and where is Ralf Brown's interrupt list?]).

The Windows manual says that the Logitech mouse is compatible with the
Microsoft one, so the interrupt will probably work the same.

Also, many files are downloadable from:
<http://www.simtel.net/pub/msdos/mouse/>

------------------------------

Subject: <Q:07.07> - How can I access a specific address in the PC's
memory?
Date: 7 Feb 2002 14:50:10 -0400

First check the library that came with your compiler. Many vendors have
some variant of peek and poke functions. For example:

* In Turbo Pascal, use the pseudo-arrays Mem, MemW, and MemL. Be sure
you use the correct array for the size of data you want to access:
byte, word, or double word. Alternatively, use pointers.

* In Turbo C/Borland C, and in recent versions of Microsoft C, use
MK_FP; in older versions of Microsoft C, use FP_OFF and FP_SEG.
(Caution: Turbo C and Turbo C++ also have FP_OFF and FP_SEG macros,
but they can't be used to construct a pointer.) Be sure to pick the
right data type: probably "unsigned char far *" if you're planning to
access bytes and "unsigned short far *" for words. (The "far" isn't
needed if your memory model uses 32-bit data pointers, but including
it does no harm.)

By the way, it's not useful to talk about "portable" ways to do this.
Any operation that is tied to a specific memory address is not likely to
work on another kind of machine.

------------------------------

Subject: <Q:07.08> - How can I read or write my PC's CMOS memory?
Date: 8 Feb 2002 20:11:37 -0400

There are a great many public-domain utilities that do this. The
following files can be downloaded from
<http://www.simtel.net/pub/msdos/sysutl/>:

cmos14.zip 5965 920817 Saves/restores CMOS to/from file
cmoser11.zip 28323 910721 386/286 enhanced CMOS setup program
cmosram.zip 76096 920214 Save AT/386/486 CMOS data to file and restore
rom2.zip 15692 900131 Save AT and 386 CMOS data to file and restore
setup21.zip 18172 880613 Setup program which modifies CMOS RAM
viewcmos.zip 11068 900225 Display contents of AT CMOS RAM, w/C source

A program to check and display CMOS memory (but not write to it) is
downloadable as part of: <http://www.simtel.net/pub/pd/50522.html>
<ftp://garbo.uwasa.fi/pc/ts/tsutle23.zip>

Good reports of CMOS299.ZIP have been posted, but it no longer appears
to be online.

Stan Brown, the former list maintainer, reports that he personally
tested CMOSRAM and that it worked fine. It contains an excellent (and
witty) .DOC file that explains the hardware involved and gives specific
recommendations for preventing disaster or recovering from it. It's $5
shareware.

Robert Jourdain's {Programmer's Problem Solver for the IBM PC, XT, and
AT} has code for accessing the CMOS RAM, according to an article posted
in this newsgroup.

------------------------------

Subject: <Q:07.09> - How can I access memory beyond 640K?
Date: 8 Feb 2002 20:50:34 -0400

Part of this involves switching into protected mode.

An article entitled "How DOS Programs Can Use Over 1MB of RAM" appeared
in PC Magazine 29 June 1993 (xii: 12) pages 302-304.

I also suggest John English's XMS classes for C++:
<ftp://ftp.brighton.ac.uk/pub/je/xms200je.zip>.

See also <Q:07.10> [How can I use the protected mode?]

------------------------------

Subject: <Q:07.10> - How can I use the protected mode?
Date: 8 Feb 2002 20:15:02 -0400

DJ Delorie has produced DJGPP, a protected mode programming environment
which supports a port of the GNU C/C++/Ada. For more informat see


<Q:10.04> [What and where is DJGPP?]

Users of Borland C++ Version 4.xx could once purchase the Borland
PowerPack for DOS Version 1.00; however, it appears that its sell has
been discontinued. This package includes Borland C++ 4.02 Service
Update, 16-bit DPMI libraries and extenders, 32-bit DPMI libraries and
extenders, TurboVision 2.0 (16-bit DOS, 16-bit DPMI, 32-bit DPMI),
SuperVGA BGI Drivers (16-bit DOS, 16-bit DPMI, 32- bit DPMI).

A reader of comp.os.msdos.programmer has the following updateu about the
PowerPack and additional information about DPMI programming:

[begin quote]
About protected-mode programming (Question 7.10), Borland no longer
supports the PowerPack (from what I've read in this newsgroup), so
I doubt that it can still be purchased. However, the FAQ could
mention that the extender is integrated into Borland C++ version 5.x
(and probably the Builder product as well).

Borland doesn't fully support that either, since the documentation
isn't very clear about compiling DPMI programs and a stub for the
executable has to be extracted from one of Borland's executables. The
necessary steps were posted a long time ago (by someone else), and I
can provide the information if necessary. Even if the FAQ didn't
describe those steps, it could at least indicate that version 5.x can
compile DPMI programs (as well as clarifying the PowerPack info).
[end quote]

There are more extenders out there. One notable DOS extender is Adam
Seychell's DOS32 Version 3.5 beta. It can be found at
<http://www.programmersheaven.com/zone5/cat19/1363.htm> Also check out
Adam's page at <http://www.geocities.com/SiliconValley/2151/pmode.html>

------------------------------

Subject: <Q:07.11> - How can I tell if my program is running on a
PS/2-style machine.


Date: 5 Feb 2002 22:03:03 -0400

Use INT 15 AX=C0, described in Ralf Brown's interrupt list (<Q:02.03>
[What and where is Ralf Brown's interrupt list?]).

------------------------------

Subject: <Q:07.12> - Is there a 80x87 math unit installed?


Date: 5 Feb 2002 22:03:03 -0400

SNIPPETS (see <Q:02.08> [What and where is SNIPPETS?]) contains
C-callable assembly code to determine presence of coprocessor in
NDPCHECK.ASM.

------------------------------

Subject: <Q:07.13> - How can I power off the computer from a batch file?
Date: 6 Feb 2002 20:36:38 -0400

A utility known as ATXOFF.COM is available at
<http://www.informatik.fh-muenchen.de/~ifw98223/dostools.htm>. It uses
APM 1.2 to power off the system but doesn't attempt to flush the disk
cache.

------------------------------

Subject: Section 8. Other software questions and problems


Date: 5 Feb 2002 22:03:03 -0400

This section is noteworthy for having the longest code snippets.

------------------------------

Subject: <Q:08.01> - How can a program reboot my PC?
Date: 8 Feb 2002 20:16:09 -0400

You can generate a "cold" boot or a "warm" boot. A cold boot is the same
as turning the power off and on; a warm boot is the same as Ctrl-Alt-Del
and skips the power-on self 'test.

For a warm boot, store the hex value 1234 in the word at 0040:0072. For
a cold boot, store 0 in that word. Then, if you want to live
dangerously, jump to address FFFF:0000. Here's C code to do it:

/* WARNING: data loss possible */
void bootme(int want_warm) /* arg 0 = cold boot, 1 = warm */
{
void (far* boot)(void) = (void (far*)(void))0xFFFF0000UL;

unsigned far* type = (unsigned far*)0x00400072UL;
*type = (want_warm ? 0x1234 : 0);
(*boot)( );
}

What's wrong with that method? It will boot right away, without closing
files, flushing disk caches, etc. If you boot without flushing a
write-behind disk cache (if one is running), you could lose data or
trash the file allocation table in your hard drive.

There are two methods of signaling the cache to flush its buffers:

(1) Simulate a keyboard Ctrl-Alt-Del in the keystroke translation
function of the BIOS (INT 15 AH=4F; but see notes below)

(2) Issue a disk reset (DOS function 0D). Most disk-cache programs hook
one or both of those interrupts, so if you use both methods you'll
probably be safe.

When user code simulates a Ctrl-Alt-Del, one or more of the programs
that have hooked INT 15 AH=4F can ask that the key be ignored by
clearing the carry flag. For example, HyperDisk does this when it has
started but not finished a cache flush. So if the carry flag comes back
cleared, the boot code has to wait a couple of clock ticks and then try
again. (None of this matters on older machines whose BIOS can't support
101- or 102-key keyboards; see the discussion of INT 21 AH=4F in
<Q:04.07> [What is the SysRq key for?])

C code that tries to signal the disk cache (if any) to flush is given
below. Turbo Pascal code by Timo Salmi that does more or less the same
job may be found at question 49 (as of this writing) in the Turbo Pascal
FAQ in comp.lang.pascal, and is downloadable as file FAQPAS2.TXT, which
is part of: <ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip>

Here's C code that reboots after trying to signal the disk cache:

#include <dos.h>

void bootme(int want_warm) /* arg 0 = cold boot, 1 = warm */
{
union REGS reg;

void (far* boot)(void) = (void (far*)(void))0xFFFF0000UL;
unsigned far* boottype = (unsigned far*)0x00400072UL;
char far* shiftstate = (char far*)0x00400017UL;
unsigned ticks;
int time_to_waste;

/* Simulate reception of Ctrl-Alt-Del: */
for (;;)
{
*shiftstate |= 0x0C; /* turn on Ctrl & Alt */
reg.h.ah = 0x4F; /* see notes below */
reg.h.al = 0x53; /* 0x53 = Del's scan code */
reg.x.cflag = 1; /* sentinel for ignoring key */
int86(0x15, &reg, &reg);

/* If carry flag is still set, we've finished. */
if(reg.x.cflag)
break;

/* Else waste some time before trying again: */
reg.h.ah = 0;
int86(0x1A, &reg, &reg); /* system time into CX:DX */

ticks = reg.x.dx;
for (time_to_waste = 3; time_to_waste > 0; )
{
reg.h.ah = 0;
int86(0x1A, &reg, &reg);
if (ticks != reg.x.dx)
ticks = reg.x.dx , --time_to_waste;
}
}

/* Issue a DOS disk reset request: */
reg.h.ah = 0x0D;
int86(0x21, &reg, &reg);

/* Set boot type and boot: */
*boottype = (want_warm ? 0x1234 : 0);
(*boot)( );
}

Reader Timo Salmi reported (26 July 1993) that the INT 15 AH=4F call may
not work on older PCs (below AT, XT2, XT286), according to Ralf Brown's
interrupt list (<Q:02.03> [What and where is Ralf Brown's interrupt
list?]).

Reader Roger Fulton reported (1 July 1993) that INT 15 AH=4F hangs even
a modern PC "ONLY when ANSI.SYS [is] loaded high using EMM386.EXE.
(Other things loaded high with EMM386.EXE were OK; ANSI.SYS loaded high
with QEMM386.SYS was OK; ANSI.SYS loaded low with EMM386.EXE installed
was OK.)" His solution was to use only the disk reset, INT 21 AH=0D,
which does flush SMARTDRV, then wait five seconds in hopes that any
other disk-caching software would have time to flush its queue.

Reader Per Bergland reported (10 Sep 1993) that the jump to FFFF:0000
will not work in Windows or other protected-mode programs. (For example,
when the above reboot code ran in a DOS session under Windows, a box
with "waiting for system shutdown" appeared. The PC hung and had to be
reset by cycling power.) His solution, which does a cold boot not a warm
boot, is to pulse pin 0 of the 8042 keyboard controller, which is
connected to the CPU's "reset" line.

He has tested the following code on various Compaqs, and expects it will
work for any AT-class machine; he cautions that you must first flush the
disk cache as indicated above.

cli
@@WaitOutReady: ; Busy-wait until 8042 ready for new command
in al,64h ; read 8042 status byte
test al,00000010b ; this bit indicates input buffer full
jnz @@WaitOutReady
mov al,0FEh ; Pulse "reset" = 8042 pin 0
out 64h,al ; The PC will reboot now

------------------------------

Subject: <Q:08.02> - How can I time events with finer resolution than the


system clock's 55 ms (about 18 ticks a second)?

Date: 8 Feb 2002 20:19:05 -0400

The PC Timing FAQ / Application Note, maintained by Kris Heidenstrom
(kheide...@actrix.gen.nz), contains information relating to timing
with PC hardware and software. It can be found on SimTel:
<http://www.simtel.net/pub/pd/46935.html>

The following files, among others, are downloadable from SimTel in the
<http://www.simtel.net/pub/msdos/sysutl/> directory:

atim.zip 4783 881126 Precision program timing for AT

In the <http://www.simtel.net/pub/msdos/c/> directory:

millisec.zip 37734 911205 MSC/asm src for millisecond timing
mschrt3.zip 53708 910605 High-res timer toolbox for MSC 5.1
msec_12.zip 8484 920320 High-def timer v1.2 (C,ASM)
ztimer11.zip 77625 920428 Microsecond timer for C, C++, ASM

For Turbo Pascal users, source and object code are downloadable as:
<ftp://garbo.uwasa.fi/pc/turbopas/bonus507.zip>

Also see "Q: How is millisecond timing done?" in FAQPAS.TXT,
downloadable as part of: <ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip>

------------------------------

Subject: <Q:08.03> - How can I find the error level of the previous
program?
Date: 8 Feb 2002 20:21:49 -0400

First, which previous program are you talking about? If your current
program ran another one, when the child program ends its error level is
available to the program that spawned it. Most high-level languages
provide a way to do this; for instance, in Turbo Pascal it's
Lo(DosExitCode) and the high byte gives the way in which the child
terminated. In Microsoft C, the exit code of a synchronous child process
is the return value of the spawn- type function that creates the
process.

If your language doesn't have a function to return the error code of a
child process, you can use INT 21 AH=4D (get return code). By the way,
this will tell you the child's exit code and the manner of its ending
(normal, Ctrl-C, critical error, or TSR).

It's much trickier if the current program wants to get the error level
of the program that ran and finished before this one started. G.A.
Theall has published source and compiled code to do this; the code is
downloadable as: <http://www.simtel.net/pub/pd/40610.html>

(The code uses undocumented features in DOS 3.3 through 5.0. In the .DOC
file Theall says that the values returned under 4DOS or other
replacements won't be right.)

------------------------------

Subject: <Q:08.04> - How can a program set DOS environment variables?
Date: 8 Feb 2002 20:22:43 -0400

Program functions that read or write "the environment" typically access
only the program's copy of it. What this Q really wants to do is to
modify the active environment, the one that is affected by SET commands
in batch files or at the DOS prompt. You need to do some programming to
find the active environment, and that depends on the version of DOS.

A fairly well-written article in PC Magazine 28 Nov 1989 (viii:20),
pages 309-314, explains how to find the active environment, and includes
Pascal source code. The article hints at how to change the environment,
and suggests creating paths longer than 128 characters as one
application.

Now as for downloadable source code, there are many possibilities.

Stan Brown, the former list maintainer recommends the following:
<ftp://garbo.uwasa.fi/pc/envutil/rbsetnv1.zip>

It includes some utilities to manipulate the environment, with source
code in C. A newer program from PC Magazine 22 Dec 1992 (XI: 22) is:
<ftp://garbo.uwasa.fi/pc/pcmagvol/vol11n22.zip>

You can also use a call to INT 2E, Pass Command to Interpreter for
Execution; see Ralf Brown's interrupt list (<Q:02.03> [What and where is
Ralf Brown's interrupt list?]) for details and cautions.

Reader Dr. John Stockton has written a unit for Turbo Pascal known as
jrs_envu.pas to facilitate writing to the environment. It is for DOS
(not DPMI) mode programs running under DOS to Win98, but not WinNT. It
can be downloaded from here:
<http://www.merlyn.demon.co.uk/programs/jrs_envu.pas>. For more
information, see <http://www.merlyn.demon.co.uk/batprogs.htm>.

------------------------------

Subject: <Q:08.05> - How can I change the switch character to - from /?


Date: 5 Feb 2002 22:03:03 -0400

Under DOS 5.0 and above you can not. INT 21 AX=3700, get switch
character, always returns a '/' (hex 2F). But the DOS commands don't
even call that function: they simply hard code '/' as the switch
character.

Some history: DOS used to let you change the switch character by using
SWITCHAR= in CONFIG.SYS or by calling DOS function 3701. DOS commands
and other programs called DOS function 3700 to find out the switch
character. If you changed the switch character to '-' (the usual
choice), you could then type "dir c:/c700 -p" rather than "dir c:\c700
/p". Under DOS 4.0, the DOS commands ignored the switch character but
functions 3700 and 3701 still worked and could be used by other
programs. Under DOS 5.0, even those functions no longer work, though all
DOS functions still accept '/' or '\' in file specs.

You can reactivate the functions to get and set switchar by using
programs like SLASH.ZIP or the sample TSR called SWITCHAR in
amisl091.zip (see <Q:08.06> [How can I write a TSR
(terminate-stay-resident utility)?]). DOS commands will still use the
slash, but non-DOS programs that call DOS function 3700 will use your
desired switch character. (DOS replacements like 4DOS may honor the
switch character for internal commands.)

Some readers may wonder why this is even an issue. Making '-' the switch
character frees up the front slash to separate names in the path part of
a file spec. This is easier for the ten-fingered to type, and it's one
less difference to remember for commuters between DOS and Unix. The
switch character is the only issue, since all the INT 21 functions
accept '/' or '\' to separate directory names.

------------------------------

Subject: <Q:08.06> - How can I write a TSR (terminate-stay-resident
utility)?
Date: 8 Feb 2002 20:31:08 -0400

There are books, and there's code to download.

First, the books:

* Ray Duncan's {Advanced MS-DOS}, ISBN 1-55615-157-8, gives a brief
checklist intended for experienced programmers. The ISBN is for the
second edition, through DOS 4; but check to see whether the DOS 6
version is available yet.

* {DOS 5: A Developer's Guide} by Al Williams, ISBN 1-55851-177-6, goes
into a little more detail, 90 pages worth!

* Pascal programmers might look at {The Ultimate DOS Programmer's
Manual} by John Mueller and Wallace Wang, ISBN 0-8306-3534-3, for an
extended example in mixed Pascal and assembler.

* For a pure assembler treatment, check Steven Holzner's {Advanced
Assembly Language}, ISBN 0-13-663014-6. He has a book with the same
title out from Brady Press, but it's about half as long as this one.

Next, the code. Some of it is companion code to published articles,
which are also listed below:

* John English (<http://www.it.bton.ac.uk/staff/je/>) has created a
wonderful C++ class for creating TSRs which includes several examples.
This one is my personal favorite. It is downloadable as:
<ftp://ftp.brighton.ac.uk/pub/je/tsr100je.zip>
<http://www.simtel.net/pub/pd/42697.html>

* The Alternate Multiplex Interrupt Specification (AMIS),downloadable
as: <http://www.simtel.net/pub/pd/46788.html>
<ftp://garbo.uwasa.fi/pc/programming/altmpx35.zip>

* Ralf Brown's assembly-language implementation of the AMIS spec, with
utilities in C, is downloadable as:
<ftp://garbo.uwasa.fi/pc/c-lang/amisl092.zip>

* Douglas Boling's MASM template for a TSR is downloadable as:
<http://www.simtel.net/pub/pd/40314.html>

* Code for Al Stevens's "Writing Terminate-and-Stay-Resident Programs",
Computer Language, February 1988, pages 37-48 and March 1988, pages
67-76 is downloadable as: <http://www.simtel.net/pub/pd/41812.html>

Finally, there are (were?) commercial products, of which TesSeRact (for
C-language TSRs) is one of the best known.

------------------------------

Subject: <Q:08.07> - Why does my interrupt function behave strangely?
Date: 8 Feb 2002 20:32:03 -0400

Interrupt service routines can be tricky, because you have to do some
things differently from "normal" programs. If you make a mistake,
debugging is a pain because the symptoms may not point at what's wrong.
Your machine may lock up or behave erratically, or just about anything
else can happen. Here are some things to look for. (See <Q:08.06> [How
can I write a TSR (terminate-stay-resident utility)?] for general
techniques that may prevent a problem.)

First, did you fail to set up the registers at the start of your
routine? When your routine begins executing, you can count on having CS
point to your code segment and SS:SP point to some valid stack (of
unknown length), and that's it. In particular, an interrupt service
routine must set DS to DGROUP before accessing any data in its data
segments. (If you're writing in a high-level language, the compiler may
generate this code for you automatically; check your compiler manual.
For instance, in Borland and Microsoft C, give your function the
"interrupt" attribute.)

Did you remember to turn off stack checking when compiling your
interrupt server and any functions it calls? The stack during the
interrupt is not where the stack-checking code expects it to be.
(Caution: Some third-party libraries have stack checking compiled in, so
you can't call them from your interrupt service routine.)

Next, are you calling any DOS functions (INT 21, 25, or 26) in your
routine? DOS is not re-entrant. This means that if your interrupt
happens to be triggered while the CPU is executing a DOS function,
calling another DOS function will wreak havoc. (Some DOS functions are
fully re-entrant, as noted in Ralf Brown's interrupt list (<Q:02.03>
[What and where is Ralf Brown's interrupt list?]). Also, your program
can test, in a way too complicated to present here, when it's safe to
call non-re-entrant DOS functions. See INT 28, INT 21 AH=34, and INT 21
AX=5D06 or 5D0B; and consult {Undocumented DOS} by Andrew Schulman. Your
program must read both the "InDOS flag" and the "critical error flag".)

Is a function in your language library causing trouble? Does it depend
on some initializations done at program startup that is no longer
available when the interrupt executes? Does it call DOS (see preceding
paragraph)? For example, in both Borland and Microsoft C the memory-
allocation functions (malloc(), etc..) call DOS functions and also
depend on setups that they can't get at from inside an interrupt; so do
the standard I/O functions like scanf() and printf(). Many other library
functions have the same problem, so you can't use them inside an
interrupt function without special precautions.

Is your routine simply taking too long? This can be a problem if you're
hooking on to the timer interrupt, INT 1C or INT 8. That interrupt
expects to be called about every 55 ms, which is 18.2 times a second.
Therefore your routine, plus any others hooked to the same interrupts,
must execute in less than 55 ms. If they use even a substantial fraction
of that time, you'll see significant slowdowns of your foreground
program. A good discussion is downloadable as:
<http://www.simtel.net/pub/pd/46893.html>

Did you forget to restore all registers at the end of your routine?

Reader, Morten Welinder, notes that programmers of interrupt procedures
in Borland/Turbo Pascal 7.0 should be aware that the high words or the
32-bit registers are not saved automatically and that the run-time
library may trash them if, e.g., you use longint operations. The easy
way around this is to do "Test8086 := 0;" before installing the
interrupt handler.

Did you chain improperly to the original interrupt? You need to restore
the stack to the way it was upon entry to your routine, then do a far
jump (not call) to the original interrupt service routine.

(The process is a little different in high-level languages.)

------------------------------

Subject: <Q:08.08> - How can I write a device driver?


Date: 5 Feb 2002 22:03:03 -0400

Many books answer this in detail. Among them are {Advanced MS-DOS} and
{DOS 5: A Developer's Guide}, cited in the preceding Q. Michael
Tischer's {PC System Programming}, ISBN 1-55755-036-0, has an extensive
treatment, as does Dettman and Kyle's {DOS Programmer's Reference: 2d
Edition}, ISBN 0-88022-458-4. For a really in-depth treatment, look for
a specialized book like Robert Lai's {Writing MS-DOS Device Drivers},
ISBN 0-201-13185-4.

------------------------------

Subject: <Q:08.09> - What can I use to manage versions of software?
Date: 8 Feb 2002 20:34:22 -0400

A port of the Unix RCS utility is downloadable as:
<http://www.simtel.net/gnudlpage.php?product=/gnu/gnuish/rcs57pc2.zip&name=rcs57pc2.zip>
(executable)
<http://www.simtel.net/gnudlpage.php?product=/gnu/gnuish/rcs57pc1.zip&name=rcs57pc1.zip>
(source)

This version of RCS is no longer limited to one-character extensions on
filenames (for example, .CPP and .BAS are now OK).

As for commercial software, I posted a question asking for readers'
experiences in July 1993 and seven readers responded. PVCS from
Intersolv (formerly Polymake) got five positive reviews, though several
readers commented that it's expensive; RCS from MKS got one positive and
one negative review; Burton TLIB got one negative review; DRTS from ILSI
got one positive review.

------------------------------

Subject: <Q:08.10> - What's this 'null pointer assignment' after my C
program executes?
Date: 8 Feb 2002 20:35:32 -0400

Somewhere in your program, you assigned a value through a pointer
without first assigning a value to the pointer. (This might have been
something like a strcpy() or memcpy() with a pointer as its first
argument, not necessarily an actual assignment statement.)

Your program may look like it ran correctly, but if you get this message
you can be certain that there's a bug somewhere.

Microsoft and Borland C, as part of their exit code (after a call to
exit() or a return from your main function), check whether the location
0000 in your data segment contains a different value from what you
started with. If so, they infer that you must have used an uninitialized
pointer. This implies that the message will appear at the end of
execution of your program regardless of where the error actually
occurred.

To track down the problem, you can put exit() calls at various spots in
the program and narrow down where the uninitialized pointer is being
used by seeing which added exit() makes the null-pointer message
disappear. Or, if your program was compiled with small or medium models,
which use 16-bit data pointers, tell the debugger to set a watch at
location 0000 in your data segment. (If data pointers are 32 bits, as in
the compact and large models, a null pointer will overwrite the
interrupt vectors at 0000:0000 and probably lock up your machine.)

Under MSC/C++ 7.0, you can declare the undocumented library function:
extern _cdecl _nullcheck(void);

Sprinkle calls to _nullcheck() through your program at regular
intervals.

Borland's TechFax document TI726 discusses the null pointer assignment
from a Borland point of view. It's one of many documents downloadable as
part of: <http://www.simtel.net/pub/pd/50843.html>
<ftp://garbo.uwasa.fi/pc/turbopas/bchelp10.zip>

------------------------------

Subject: <Q:08.11> - How can a batch file tell whether it's being run in


a DOS box under Windows?

Date: 5 Feb 2002 22:03:03 -0400

When Windows 3.0 or 3.1 is running, the DOS environment will contain a
definition of the string windir, in lower case. That's not really
useful, however, because the batch statement

if "%windir%" == "" ...

will test for an environment variable WINDIR in upper case.

Your only real option is to write a program as suggested by the
following question, and have it return a value which your batch file can
test via "if errorlevel".

------------------------------

Subject: <Q:08.12> - How can my program tell if it's running under
Windows?
Date: 8 Feb 2002 20:37:06 -0400

Execute INT 2F AX=4680. If AX returns 0, you're in Windows real mode or
standard mode (or under the DOS shell). Otherwise, call INT 2F AX=1600.
If AL returns something other than 0 or 80, you're in Windows 386
enhanced mode. See PC Magazine 24 Nov 1992 (xi:20) pages 492-493.

For more information, see PC Magazine 26 May 1992 (xi:10) pages 345-346.
A program, WINMODE, is available as part of:
<http://www.simtel.net/pub/pd/48500.html>
<ftp://garbo.uwasa.fi/pc/pcmagvol/vol11n10.zip>

PC Magazine 29 March 1994 (xiii: 6) pages 312 and 320 published a new
program, WINVER. This would be in:
<http://www.simtel.net/pub/pd/48540.html>
<ftp://garbo.uwasa.fi/pc/pcmagvol/vol13n06.zip>

------------------------------

Subject: <Q:08.13> - How can a program tell whether ANSI.SYS is
installed?


Date: 5 Feb 2002 22:03:03 -0400

In DOS 4.0 and above, call INT 2F AX=1A00. If the value FF is returned
in AL, ANSI.SYS is installed. For more information, see Ralf Brown's
interrupt list (<Q:02.03> [What and where is Ralf Brown's interrupt
list?]).

------------------------------

Subject: <Q:08.14> - How do I copyright software that I write?


Date: 5 Feb 2002 22:03:03 -0400

You can download a very comprehensive answer from the Internet. Terry
Carroll posts a six-part Copyright FAQ to misc.legal, news.answers and
other groups. A short answer follows, not based on that article.

Disclaimer: I am not a lawyer, and this is not legal advice. Also, there
are very likely to be differences in copyright law among nations. No
matter where you live, if significant money may be involved, get legal
advice. The following is adapted (and greatly condensed) from chapter 4
of the Chicago Manual of Style (13th edition, ISBN 0-226- 10390-0).

In the U.S. (at least), when you write something, you own the copyright.
(The exception that matters most to programmers is "works made for
hire", i.e., code you write because your employer or client pays you to.
A contract, agreed in advance, can vest the copyright in the programmer
even if an employee; otherwise the employer owns the copyright.) You
don't have to register the work with the Copyright Office unless (until)
the copyright is infringed and you intend to bring suit; however, it is
easier to recover damages in court if you did register the work within
three months of publication.

From paragraph 4.16 of the Chicago Manual: "... the [copyright] notice
consists of three parts: (1) the symbol [C-in-a-circle] (preferred
because it also suits the requirements of the Universal Copyright
Convention), the word 'Copyright', or the abbreviation 'Copr.', (2) the
year of first publication, and (3) the name of the copyright owner. Most
publishers also add the phrase 'All rights reserved' because it affords
some protection in Central and South American countries...."

Surprise: "(C)" is legally not the same as the C-in-a- circle, so those
of us who are ASCII-bound must use the word or the abbreviation.

------------------------------

Subject: <Q:08.15> - How can I place date and time information into
environment variables?
Date: 6 Feb 2002 10:16:12 -0400

You can use a program known as NOWMINUS. More information about NOWMINUS
can be found at <http://www.merlyn.demon.co.uk/programs/nowminus.txt>.
Pascal source code is included.

------------------------------

Subject: Conclusion

This is the end of part 4 of 5 parts.

Jeffrey Carlyle

unread,
Apr 9, 2004, 7:57:48 AM4/9/04
to
Archive-name: msdos-programmer-faq/part5
Comp-os-msdos-programmer-archive-name: dos-faq-pt5.txt

Posting-frequency: 28 days
Last-modified: 14 Aug 2003

comp.os.msdos.programmer FAQ Version 2003.08.14

This is the Frequently Asked Questions list for the newsgroup
comp.os.msdos.programmer.

COPYRIGHT

Copyright 2003 by Jeffrey Carlyle. All rights reserved. This article is
not in the public domain, but it may be redistributed so long as this
notice, the acknowledgments, and the information on obtaining the latest
copy of this list are retained and no fee is charged. The code fragments
may be used freely; credit to the FAQ would be polite. This FAQ is not to
be included in any static: archive (e.g. CD-ROM or book); however, a
pointer to the FAQ may be included. See <Q:01.14> [Where can I get the
latest copy of this FAQ list?] for a link to the latest version of the
FAQ.)

This is part 5 of 5 parts.

TABLE OF CONTENTS

PART 1:

PART 5: (this part)


Section 9. Downloading
<Q:09.01> - What are SimTel and Garbo?
<Q:09.02> - Can I get archives on CD-ROM?
<Q:09.03> - Where do I find program <mumble>?

Section 10. Vendors and products
<Q:10.01> - How can I contact Borland?
<Q:10.02> - How can I contact Microsoft?
<Q:10.03> - What is the current version of DJGPP?
<Q:10.04> - What and where is DJGPP?
<Q:10.05> - Are there any good shareware/freeware compilers?
<Q:10.06> - Where is QBASIC?
<Q:10.07> - What is a vendor's web site address?

------------------------------

Subject: Section 9. Downloading


Date: 5 Feb 2002 22:03:03 -0400

Where to do it and how to do it.

------------------------------

Subject: <Q:09.01> - What are SimTel and Garbo?
Date: 8 Feb 2002 20:39:08 -0400

These are three of the most popular archive sites, with a few bazillion
files available for free downloading by ftp. Many of the files are
shareware and you're expected to send a payment directly to the authors
if you use them regularly.

SimTel can be found at: <http://www.simtel.net>

Garbo can be found at: <http://garbo.uwasa.fi>

A few words about file names and versions: Many files at the archive
sites are updated from time to time. I verified every filename in this
FAQ as of 08 Feb 2002 by ftping to the named sites, or by consulting
their index files. If you can't find a file given in these articles as
mumble12.zip, perhaps there's a newer version; try mumble13.zip or
mumble14.zip, or mumble*.zip if your ftp program supports wildcards
(most do so). Please let me know of any out-of-date file names.

This FAQ should show both Garbo and SimTel directory and file names, if
available, for every file mentioned for downloading. If you see a
listing for only one of them, it means that the file was not found at
the other site, or that the other site's catalog shows an old version.

Also remember that caps and lower case filenames are not interchangeable
at most archive sites.

------------------------------

Subject: <Q:09.02> - Can I get archives on CD-ROM?


Date: 5 Feb 2002 22:03:03 -0400

Copies of the SimTel MS-DOS, Macintosh and Unix-C collections (also of
wuarchive, cica, and others) are available from Walnut Creek CDROM, 1547
Palos Verdes, Suite 260, Walnut Creek, CA 94596-2228, telephone (800)
786-9907 or +1 510 674-0783, or FAX +1 510 674-0821, or email
r...@cdrom.com.

For a catalog of disks available, send email to in...@cdrom.com, or ftp
the catalog as /cdrom/catalog from cdrom.com.

------------------------------

Subject: <Q:09.03> - Where do I find program <mumble>?


Date: 5 Feb 2002 22:03:03 -0400

You are asking about shareware, freeware, or public-domain programs,
right? Commercial software is not legally distributed through the net,
in general. (Occasionally vendors will make patches available, but these
are useful only to upgrade software you already own.)

That said, the quickest way to find a program you are looking for is to
use a WWW search utility such as Google at <http://www.google.com>.

There are also several newsgroups to help you find a program.
comp.binaries.ibm.pc.wanted is generally the best place to ask your
question. Please review the guidelines in <Q:01.12> [What other


technical newsgroups should I know about?]

------------------------------

Subject: Section 10. Vendors and products


Date: 5 Feb 2002 22:03:03 -0400

Where to find them.

------------------------------

Subject: <Q:10.01> - How can I contact Borland?
Date: 8 Feb 2002 01:50:16 -0400

On the Web:

Information about Borland products can be found at:
<http://www.borland.com>

Please notice Borland is marketing the newsest version of Borland C++ as
Borland C++Builder and the newest version of Borland Pascal as Borland
Delphi.

For awhile, Borland was known as Inprise, but now the name is back to
Borland.

------------------------------

Subject: <Q:10.02> - How can I contact Microsoft?
Date: 7 Feb 2002 01:08:35 -0400

Microsoft has stopped developing MS-DOS and most of the programming
information they now provide is focused more on Windows development
instead of MS-DOS programming.

In ther past, individual employees of Microsoft (not MicroSoft, please!)
have posted here. Their addresses all take the form
per...@microsoft.com. However, Microsoft as a company does not answer
individual questions via email through the Internet.

On the Web:

Microsoft's Web server <http://www.microsoft.com> contains information
on their products and allows users to search the Microsoft Knowledge
Base.

Via ftp:

Microsoft's anonymous FTP server <ftp://ftp.microsoft.com> offers a
variety of information for developers. This ftp server is run using
Windows NT, so it supports both UNIX- like and DOS-like path names. For
example \SOFTLIB\INDEX.TXT and /SOFTLIB/INDEX.TXT are both valid.
Filenames are not case sensitive.

Informarion related to MS-DOS can be found in the /SOFTLIB directory and
the /PEROPSYS directory.

------------------------------

Subject: <Q:10.03> - What is the current version of DJGPP?


Date: 5 Feb 2002 22:03:03 -0400

See <Q:10.04> [What and where is DJGPP?]

------------------------------

Subject: <Q:10.04> - What and where is DJGPP?


Date: 5 Feb 2002 22:03:03 -0400

DJGPP is a 32-bit C/C++/Ada95 development environment created by D.J.
Delorie for the MS-DOS environment, based on the GNU tools. A 16-bit
version of DJGPP also exists at: <http://www.delorie.com/djgpp/16bit/>

DJGPP can be retrieved from the following sites:
<http://www.delorie.com/djgpp/dl/ofc/>

More information on DJGPP can be found in the following places:

The DJGPP FAQ: (Where * is the current version.)
<http://www.delorie.com/djgpp/faq/>

WWW Home Page: <http://www.delorie.com/djgpp/>

Newsgroup: (preferred over the mailing list) <news:comp.os.msdos.djgpp>

------------------------------

Subject: <Q:10.05> - Are there any good shareware/freeware compilers?
Date: 8 Feb 2002 20:44:31 -0400

Borland has issued free versions of several Borland C and Pascal
compilers. Users can download the Borland C++ Compiler 5.5 from
<http://www.borland.com/bcppbuilder/freecompiler/>. It is an ANSI
compliant C++ compiler for Win32 with a number of extra feature;
however, it does not include a GUI and does not appear to support MS-DOS
executables.

Users can also download Turbo Pascal 1.0, 3.02, and 5.5 and Turbo C 1.01
and 2.01 from the Borland Community Museum if they first register as
Borland Community members at <http://community.borland.com/>.

There are several shareware/freeware compilers for MS-DOS, here are just
a few:

Digital Mars

C and C++ compilers for Win32, Win16, DOS32 and DOS. Fast compile and
link times, powerful optimization technology, design by contract,
complete library source, HTML browsable documentation, disassembler,
librarian, resource compiler, make, etc., command line and GUI versions,
tutorials, sample code, online updates, Standard Template Library, and
more.

<http://www.digitalmars.com/>

CC386:

K&R C with some ANSI extensions; 32 bit, requires 386+; a port/re-write
of a C compiler for the Motorola 68000 processor; freeware.

<http://www.members.tripod.com/~ladsoft/cc386.htm>

DJGPP

D.J. Delorie has ported the GNU C/C++ compiler to the 32-bit DOS
platform. There is also an incomplete 16-bit port. Supports ANSI C and
C++. Reported to be difficult for novice users. Very well supported by a
large user community. Covered under GNU GPL. For more information see
section <Q:10.04> [What and where is DJGPP?].

LCC:

LCC supports ANSI C and support a wide variety of development platforms.
Well documented in the book {A Retargetable C Compiler: Design and
Implementation} ISBN 0-8053-1670-1; however, there is little free
documenation. Not intended for novice users. Source code is freely
available. Freeware, but not public domain.

<http://www.cs.princeton.edu/software/lcc>

<http://www.cs.virginia.edu/~lcc-win32>

Magic Assembler:

Magic Assembler is a small easy-to-use x86 assembly language compiler.
It can produce .COM files as well as boot sector programs. It can also
print the source using the correct addresses. (Public Domain)

* <http://www.simtel.net/pub/pd/18391.html>

* <http://www.math.leidenuniv.nl/~bgreeven/masm.html>

MICRO-C:

Large ANSI subset; 16-bit; includes a DOS-based IDE and command-line
tools; well document (approx. 400 pages); Comprehensive PC library (~300
functions) including: TSR, windowing, serial communications, and
graphics; large collection of example programs (over 120); freeware;
commercial versions available for many embedded processors; library
source available with commercial version.

<ftp://ftp.dunfield.com/mc321pc.zip>

<http://www.dunfield.com/>

MIRACLE C:

Supports K&R C with minor ANSI extensions; 16 bit, compiled code runs
under DOS; Compiler/IDE requires windows, 386+; Somewhat documented
(approx 30 pages + windows help file); Compiler source code is available
with registration; Shareware.

<http://www.c-compiler.com/>

NASM:

NASM, the Netwide Assembler, is a free assembler for Intel 80x86 series
of microprocessors. Not only is the assembler compatible with MS-DOS,
but it will also work under Windows 95, Linux, and OS/2. More
information can be found on The Netwide Assembler Project website at:
<http://www.web-sites.co.uk/nasm/>

Open Watcom:

One of the old standards of DOS programming, the Watcom C++ compiler,
will soon be released as open source software. Sybase, the owners of
Watcom are currently (21-Jun-2001) in the process of preparing an open
source license for the compiler. Watcom C++ is a complete package
containing 16-bit and 32-bit compilers, an IDE, maker, linker,
assembler, and other tools. It supports DOS, Windows, and OS/2.

<http://www.openwatcom.org/>

PACIFIC C:

Supports ANSI C; 16 bit, runs on 8088+; Includes nice DOS IDE + command
line tools; Well documented via large PDF file (350+ pages); Commercial
versions available for several embedded processors; Freeware, but not
public domain.

<http://www.hitech.com.au/products/pacific.html>

PCC Personal C Compiler:

Supports K&R C only; 16 bit, runs on 8088+; Command line interface only;
Does not appear to be under current development / support; Well
documented (approx 100 page text file); Shareware.

<http://www.simtel.net/pub/pd/41749.shtml>

Much thanks to comp.os.msdos.programmer reader Dave Dunfield for
providing information about many of these compilers.

------------------------------

Subject: <Q:10.06> - Where is QBASIC?
Date: 6 Feb 2002 20:53:45 -0400

QBASIC is a stripped down version of Microsoft's QuickBASIC
interpretter. It is distributed with MS-DOS versions greater than 4.00.
(Earlier versions included GW-BASIC or BASICA.)

At first glance, Windows 95 and greater no longer included QBASIC;
however, they can still be found on Windows' CDs. To find QBASIC, use
the Find utility on the Start menu to search for "qbasic.*" on the
Windows CD. Once you have located "qbasic.exe" and "qbasic.hlp", copy
them to a folder on your hard drive.

Users without Windows CDs can download QBASIC from here:
<ftp://ftp.microsoft.com/Products/Windows/Windows95/CDRomExtras/OtherUtilities/olddos.exe>.

------------------------------

Subject: <Q:10.07> - What is a vendor's web site address?


Date: 5 Feb 2002 22:03:03 -0400

Have you tried http://www.<inset vendor name here>.com?

If that doesn't work use a directory service like the Open Directory
Project <http://www.dmoz.org/> or a search engine like Google
<http://www.google.com/> to search for your vendor's name.

------------------------------

Subject: Conclusion

This is the end of part 5 of 5 parts.

0 new messages