home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
- Message-ID: <msdos-programmer-faq/part3_1084010824@rtfm.mit.edu>
- Supersedes: <msdos-programmer-faq/part3_1081511793@rtfm.mit.edu>
- Expires: 11 Jun 2004 10:07:04 GMT
- References: <msdos-programmer-faq/part1_1084010824@rtfm.mit.edu>
- X-Last-Updated: 2003/08/14
- From: jeffrey@carlyle.org (Jeffrey Carlyle)
- Sender: jeffrey@carlyle.org (Jeffrey Carlyle)
- Reply-To: jeffrey@carlyle.org (Jeffrey Carlyle)
- Approved: news-answers-request@MIT.edu
- Organization: JeffC.org
- Subject: comp.os.msdos.programmer FAQ part 3/5
- Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer,comp.answers,alt.answers,news.answers
- Followup-To: poster
- Summary: Frequently asked questions from DOS programmers with tested answers.
- Originator: faqserv@penguin-lust.MIT.EDU
- Date: 08 May 2004 10:08:03 GMT
- Lines: 942
- NNTP-Posting-Host: penguin-lust.mit.edu
- X-Trace: 1084010883 senator-bedfellow.mit.edu 574 18.181.0.29
- Xref: senator-bedfellow.mit.edu comp.os.msdos.programmer:127444 alt.msdos.programmer:54822 comp.answers:57100 alt.answers:72787 news.answers:270991
-
- 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:
- 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: (this part)
- 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 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.
-
- This text is copyright 2003 by Jeffrey Carlyle. All rights reserved.
- Please see the top of this article for additional copyright information.
-
-