home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
- Message-ID: <msdos-programmer-faq/part2_1084010824@rtfm.mit.edu>
- Supersedes: <msdos-programmer-faq/part2_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 2/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:02 GMT
- Lines: 831
- NNTP-Posting-Host: penguin-lust.mit.edu
- X-Trace: 1084010882 senator-bedfellow.mit.edu 580 18.181.0.29
- Xref: senator-bedfellow.mit.edu comp.os.msdos.programmer:127443 alt.msdos.programmer:54821 comp.answers:57099 alt.answers:72786 news.answers:270990
-
- 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:
- 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: (this part)
- 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 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.
-
- This text is copyright 2003 by Jeffrey Carlyle. All rights reserved.
- Please see the top of this article for additional copyright information.
-
-