home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1997 December
/
Internet_Info_CD-ROM_Walnut_Creek_December_1997.iso
/
faqs
/
comp
/
answers
/
msdos-programmer-faq
/
part3
< prev
next >
Wrap
Internet Message Format
|
1997-10-01
|
31KB
Path: senator-bedfellow.mit.edu!faqserv
From: jeffrey@carlyle.com (Jeffrey Carlyle)
Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer,comp.answers,alt.answers,news.answers
Subject: comp.os.msdos.programmer FAQ part 3/5
Supersedes: <msdos-programmer-faq/part3_873193441@rtfm.mit.edu>
Followup-To: comp.os.msdos.programmer
Date: 30 Sep 1997 09:50:04 GMT
Organization: The COMP-FAQ Project
Lines: 968
Sender: jeffrey@carlyle.com (Jeffrey Carlyle)
Approved: news-answers-request@MIT.Edu
Expires: 3 Nov 1997 09:49:05 GMT
Message-ID: <msdos-programmer-faq/part3_875612945@rtfm.mit.edu>
References: <msdos-programmer-faq/part1_875612945@rtfm.mit.edu>
Reply-To: jeffrey@carlyle.com (Jeffrey Carlyle)
NNTP-Posting-Host: penguin-lust.mit.edu
Summary: Frequently asked questions by DOS programmers with tested answers.
X-Last-Updated: 1997/08/04
Originator: faqserv@penguin-lust.MIT.EDU
Xref: senator-bedfellow.mit.edu comp.os.msdos.programmer:92882 alt.msdos.programmer:39079 comp.answers:28270 alt.answers:29277 news.answers:113415
Archive-name: msdos-programmer-faq/part3
Comp-os-msdos-programmer-archive-name: dos-faq-pt3.txt
Posting-frequency: 28 days
Last-modified: 04 Aug 97
------------------------------
Subject: comp.os.msdos.programmer FAQ part 3/5
For more information about this FAQ list please see Part 1.
FAQ updates can be found at
<http://www.premiernet.net/~carlyle>.
This is part 3 of the frequently asked question list for
the newsgroup comp.os.msdos.programmer.
Part 3:
Section 5. Disks and files
Section 6. Serial ports (COM ports)
------------------------------
Subject: comp.os.msdos.programmer FAQ
Comp.os.msdos.programmer FAQ Version 1997.08
Copyright 1997 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.
=============================
TABLE OF CONTENTS
=============================
Part 1:
Section 1. General FAQ and Newsgroup Information
Section 2. General Reference
Part 2:
Section 3. Compile and Link
Section 4. Keyboard
Part 3:
Section 5. Disks and files
Section 6. Serial ports (COM ports)
Part 4:
Section 7. Other hardware questions and problems
Section 8. Other software questions and problems
Part 5:
Section 9. Downloading
Section 10. Vendors and products
------------------------------
Subject: Section 5. Disks and files
<Q: 5.01> - What drive was the PC booted from?
<Q: 5.02> - How can I boot from drive B:?
<Q: 5.03> - Which real and virtual disk drives are valid?
<Q: 5.04> - How can I make my single floppy drive both B:
and B:?
<Q: 5.05> - How can I disable access to a drive?
<Q: 5.06> - How can a batch file test existence of a
directory?
<Q: 5.07> - Why won't my C program open a file with a path?
<Q: 5.08> - How can I redirect printer output to a file?
<Q: 5.09> - How can I redirect the output of a batch file?
<Q: 5.10> - How can I redirect stderr?
<Q: 5.11> - How can my program open more files than DOS's
limit of 20?
<Q: 5.12> - How can I read, create, change, or delete the
volume label?
<Q: 5.13> - How can I get the disk serial number?
<Q: 5.14> - What's the format of .OBJ, .EXE, .COM files?
<Q: 5.15> - How can I flush the software disk cache?
<Q: 5.16> - How can I see if a drive is a RAM drive?
------------------------------
Subject: <Q: 5.01> - What drive was the PC booted from?
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: 5.02> - How can I boot from drive B:?
Date: Sun, 03 Aug 97 20:07:24 CST
Downloadable shareware:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/diskutil/boot_b.
zip>
<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:
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.
------------------------------
Subject: <Q: 5.03> - Which real and virtual disk drives are
valid?
Date: Wed, 11 Jan 95 15:34:00 CDT
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: 2.03>.
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: 5.04> - How can I make my single floppy drive
both a: and b:?
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: 5.05> - How can I disable access to a drive?
Date: Sun, 03 Aug 97 20:08:47 CST
Reader Eric DeVolder writes that he has made available a
program to do this. I haven't tried it, but it's
downloadable as
<ftp://ftp.simtel.net/pub/simtelnet/msdos/diskutil/rmdriv30
.zip>
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: 5.06> - How can a batch file test existence of
a directory?
Date: Tue, 7 Mar 95 12:00:00 CDT
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. (I'm told 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/ts/tsfaqp*.zip>
------------------------------
Subject: <Q: 5.07> - Why won't my C program open a file with
a path?
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: 5.08> - How can I redirect printer output to a
file?
Date: Sun, 03 Aug 97 20:16:07 CST
Recommended: PRN2FILE from PC Magazine, downloadable as:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/printer/prn2fil3.
zip>
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: 5.09> - How can I redirect the output of a
batch file?
Date: Sun, 03 Aug 97 20:18:26 CST
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:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/batchutil/tsbat*.
zip>
<ftp://garbo.uwasa.fi/pc/ts/tsbat*.zip>
------------------------------
Subject: <Q: 5.10> - How can I redirect stderr?
Date: Sun, 03 Aug 97 20:20:33 CST
Use freopen(..., stderr) and then execute the desired
command via system(). There are downloadable versions of
programs to do this.
I recommend this file, which includes TP4 source and
executable:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/sysutl/rdstderr.z
ip>
A C example is downloadable as:
<ftp://ftp.simtel.net/pub/simtelnet/msdos/c/redirect.c>
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.
------------------------------
Subject: <Q: 5.11> - How can my program open more files than
DOS's limit of 20?
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: 5.12> - How can I read, create, change, or
delete the volume label?
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: 5.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: 5.13> - How can I get the disk serial number?
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: 2.03>, 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: 5.12> - "How can I read,
create, change, or delete the volume label?"
------------------------------
Subject: <Q: 5.14> - What's the format of .OBJ, .EXE., .COM
files?
Please see <Q: 3.06> "What's the format of an .OBJ file?";
<Q: 3.07> "What's the format of an .EXE header?"; and <Q:
3.08> "What's the difference between .COM and .EXE
formats?"
------------------------------
Subject: <Q: 5.15> - How can I flush the software disk
cache?
Please see "<Q: 8.01> - How can a program reboot my PC?"
(Trust me.)
------------------------------
Subject: <Q: 5.16> - How can I see if a drive is a RAM
drive?
Date: Tue, 7 Mar 95 12:00:00 CDT
Use INT 21 AX=4409h. See Ralph Brown's interrupt list <Q:
2.03> for more information.
------------------------------
Subject: Section 6. Serial ports (COM ports)
<Q: 6.01> - How do I set my machine up to use COM3 and COM4?
<Q: 6.02> - How do I find the I/O address of a COM port?
<Q: 6.03> - But aren't the COM ports always at I/O addresses
3F8, 2F8, 3E8, and 2E8?
<Q: 6.04> - How do I configure a COM port and use it to
transmit data?
------------------------------
Subject: <Q: 6.01> - How do I set my machine up to use COM3
and COM4?
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: 6.02> - How do I find the I/O address of a COM
port?
Date: Sun, 03 Aug 97 20:27:12 CST
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 "5.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:
<ftp://ftp.simtel.net/pub/msdos/io_util/pf271.zip>
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: 6.03> - But aren't the COM ports always at I/O
addresses 3F8, 2F8, 3E8, and 2E8?
The first two are usually right (though not always); the
last two are different on many machines.
------------------------------
Subject: <Q: 6.04> - How do I configure a COM port and use
it to transmit data?
Date: Sun, 03 Aug 97 20:27:31 CST
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,
<ftp://oak.oakland.edu/pub/msdos/c/pcl4c34.zip> (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:
<ftp://ftp.simtel.net/pub/msdos/turbo-c/bchelp10.zip>
<ftp://garbo.uwasa.fi/pc/turbopas/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.
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/*Serial*>
For rtfm.mit.edu instructions, see <Q: 1.13> "Where are FAQ
lists archived?"
------------------------------
Subject: End
(FAQ updates can be found at
<http://www.premiernet.net/~carlyle>.)
(End of comp.os.msdos.programmer FAQ Version 1997.08 Part
3/5)
(This text is copyright 1997 by Jeffrey Carlyle. All rights
reserved.)
// Jeffrey Carlyle, Bowling Green, Kentucy USA
//
// comp.os.msdos.programmer FAQ maintainer
// <http://www.premiernet.net/~carlyle>