home *** CD-ROM | disk | FTP | other *** search
- 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 4/5
- Supersedes: <msdos-programmer-faq/part4_873193441@rtfm.mit.edu>
- Followup-To: comp.os.msdos.programmer
- Date: 30 Sep 1997 09:50:07 GMT
- Organization: The COMP-FAQ Project
- Lines: 1154
- 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/part4_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:92883 alt.msdos.programmer:39080 comp.answers:28271 alt.answers:29278 news.answers:113416
-
- Archive-name: msdos-programmer-faq/part4
- Comp-os-msdos-programmer-archive-name: dos-faq-pt4.txt
- Posting-frequency: 28 days
- Last-modified: 04 Aug 97
-
- ------------------------------
-
- Subject: comp.os.msdos.programmer FAQ part 4/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 4 of the frequently asked question list for
- the newsgroup comp.os.msdos.programmer.
-
- Part 4:
- Section 7. Other hardware questions and problems
- Section 8. Other software questions and problems
-
- ------------------------------
-
- 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 7. Other hardware questions and problems
-
- <Q: 7.01> - Which 80x86 CPU is running my program?
- <Q: 7.02> - How can a C program send control codes to my
- printer?
- <Q: 7.03> - How can I redirect printer output to a file?
- <Q: 7.04> - Which video adapter is installed?
- <Q: 7.05> - How do I switch to 43- or 50-line mode?
- <Q: 7.06> - How can I find the Microsoft mouse position and
- button status?
- <Q: 7.07> - How can I access a specific address in the PC's
- memory?
- <Q: 7.08> - How can I read or write my PC's CMOS memory?
- <Q: 7.09> - How can I access memory beyond 640K?
- <Q: 7.10> - How can I use the protected mode?
- <Q: 7.11> - How can I tell if my program is running on a
- PS/2-style machine.
- <Q: 7.12> - Is there a 80x87 math unit installed?
-
- ------------------------------
-
- Subject: <Q: 7.01> - Which 80x86 CPU is running my program?
- Date: Sun, 03 Aug 97 20:32:26 CST
-
-
- SNIPPETS (see <Q: 2.08>) contains C-callable x86 assembly
- language code for determining the type of CPU in
- CPUCHECK.ASM.
-
-
- ------------------------------
-
- Subject: <Q: 7.02> - How can a C program send control codes
- to my printer?
-
-
- If you just fprintf(stdprn, ...), C will translate some of
- your control codes. The way around this is to reopen the
- printer in binary mode:
-
- prn = fopen("PRN", "wb");
-
- You must use a different file handle because stdprn isn't
- an lvalue. By the way, in DOS 5.0 a colon must not follow
- PRN or LPT1.
-
-
- There's one special case, Ctrl-Z (ASCII 26), the DOS end-of-
- file character. If you try to send an ASCII 26 to your
- printer, DOS simply ignores it. To get around this, you
- need to reset the printer from "cooked" to "raw" mode.
- Microsoft C users must use INT 21 AH=44, "get/set device
- information". Turbo C and Borland C++ users can use ioctl
- to accomplish the same thing:
-
- ioctl(fileno(prn), 1, ioctl(fileno(prn),0) & 0xFF | 0x20,
- 0);
-
- An alternative approach is simply to write the printer
- output into a disk file, then copy the file to the printer
- with the /B switch.
-
-
- A third approach is to bypass DOS functions entirely and
- use the BIOS printer functions at INT 17. If you also
- fprintf(stdprn,...) in the same program, you'll need to use
- fflush() to synchronize fprintf()'s buffered output with
- the BIOS's unbuffered.
-
-
- By the way, if you've opened the printer in binary mode
- from a C program, remember that outgoing \n won't be
- translated to carriage return/line feed. Depending on your
- printer, you may need to send explicit \n\r sequences.
-
-
- ------------------------------
-
- Subject: <Q: 7.03> - How can I redirect printer output to a
- file?
-
-
- Please see <Q: 5.08> "How can I redirect printer output to
- a file?"
-
-
- ------------------------------
-
- Subject: <Q: 7.04> - Which video adapter is installed?
-
-
- The technique below should work if your BIOS is not too
- old. It uses three functions from INT 10, the BIOS video
- interrupt. (If you're using a Borland language, you may
- not have to do this the hard way. Look for a function
- called DetectGraph or something similar.)
-
-
- Set AX=1200, BL=32 and call INT 10. If AL returns 12, you
- have a VGA. If not, set AH=12, BL=10 and call INT 10
- again. If BL returns 0,1,2,3, you have an EGA with
- 64,128,192,256K memory. If not, set AH=0F and call INT 10
- a third time. If AL is 7, you have an MDA (original
- monochrome adapter) or Hercules; if not, you have a CGA.
-
-
- This worked when tested with a VGA, but I had no other
- adapter types to test it with.
-
-
- ------------------------------
-
- Subject: <Q: 7.05> - How do I switch to 43- or 50-line mode?
-
-
- The following file contains .COM utilities and .ASM source
- code:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/vidmode.zi
- p>
-
- ------------------------------
-
- Subject: <Q: 7.06> - How can I find the Microsoft mouse
- position and button status?
- Date: Sun, 03 Aug 97 20:35:38 CST
-
-
- Use INT 33 AX=3, described in Ralf Brown's interrupt list
- <Q: 2.03>.
-
-
- The Windows manual says that the Logitech mouse is
- compatible with the Microsoft one, so the interrupt will
- probably work the same.
-
-
- Also, many files are downloadable from
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/mouse>
-
- ------------------------------
-
- Subject: <Q: 7.07> - How can I access a specific address in
- the PC's memory?
-
-
- First check the library that came with your compiler. Many
- vendors have some variant of peek and poke functions. For
- example:
-
-
- - In Turbo Pascal, use the pseudo-arrays Mem, MemW, and
- MemL. Be sure you use the correct array for the size of
- data you want to access: byte, word, or double word.
-
-
- - In Turbo C/Borland C, and in recent versions of
- Microsoft C, use MK_FP; in older versions of Microsoft C,
- use FP_OFF and FP_SEG. (Caution: Turbo C and Turbo C++ also
- have FP_OFF and FP_SEG macros, but they can't be used to
- construct a pointer.) Be sure to pick the right data type:
- probably "unsigned char far *" if you're planning to access
- bytes and "unsigned short far *" for words. (The "far"
- isn't needed if your memory model uses 32-bit data pointers,
- but including it does no harm.)
-
-
- By the way, it's not useful to talk about "portable" ways
- to do this. Any operation that is tied to a specific
- memory address is not likely to work on another kind of
- machine.
-
-
- ------------------------------
-
- Subject: <Q: 7.08> - How can I read or write my PC's CMOS
- memory?
- Date: Sun, 03 Aug 97 20:35:57 CST
-
-
- There are a great many public-domain utilities that do
- this. The following files can be downloaded from
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/sysutl/>:
-
- cmos14.zip 5965 920817 Saves/restores CMOS to/from
- file
- cmoser11.zip 28323 910721 386/286 enhanced CMOS setup
- program
- cmosram.zip 76096 920214 Save AT/386/486 CMOS data to
- file and restore
- rom2.zip 15692 900131 Save AT and 386 CMOS data to
- file and restore
- setup21.zip 18172 880613 Setup program which modifies
- CMOS RAM
- viewcmos.zip 11068 900225 Display contents of AT CMOS
- RAM, w/C source
-
- A program to check and display CMOS memory (but not write
- to it) is downloadable as part of:
-
- <ftp://garbo.uwasa.fi/pc/ts/tsutle22.zip>
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/sysutl/tsutle22.z
- ip>
-
- Good reports of CMOS299.ZIP have been posted:
-
- <ftp://cantva.canterbury.ac.nz/pub/pc/cmos299.zip>
-
- Of the above, my only experience is with CMOSRAM, which
- seems to work fine. It contains an excellent (and witty)
- .DOC file that explains the hardware involved and gives
- specific recommendations for preventing disaster or
- recovering from it. It's $5 shareware.
-
-
- Robert Jourdain's {Programmer's Problem Solver for the IBM
- PC, XT, and AT} has code for accessing the CMOS RAM,
- according to an article posted in this newsgroup.
-
-
- ------------------------------
-
- Subject: <Q: 7.09> - How can I access memory beyond 640K?
- Date: Sun, 03 Aug 97 14:24:56 CST
-
-
- PC Magazine 29 June 1993 (xii: 12) pages 302-304 carry an
- article, "How DOS Programs Can Use Over 1MB of RAM".
-
-
- See also <Q: 7.10> - How can I use the protected mode?
-
-
- ------------------------------
-
- Subject: <Q: 7.10> - How can I use the protected mode?
- Date: Sun, 03 Aug 97 20:43:48 CST
-
-
- DJ Delorie has produced DJGPP, a protected mode programming
- environment which supports a port of the GNU C/C++/Ada. For
- more informat see "<Q: 10.06> - What and where is DJGPP?"
-
-
- If you are using Borland C++ Version 4.xx, you can purchase
- the Borland PowerPack for DOS Version 1.00. This package
- includes Borland C++ 4.02 Service Update, 16-bit DPMI
- libraries and extenders, 32-bit DPMI libraries and
- extenders, TurboVision 2.0 (16-bit DOS, 16-bit DPMI, 32-bit
- DPMI), SuperVGA BGI Drivers (16-bit DOS, 16-bit DPMI, 32-
- bit DPMI).
-
-
- There are more extenders out there. One notable DOS
- extender is Adam Seychell's DOS32. It can be found at:
-
-
- <ftp://ftp.cdrom.com/.24/demos/code/pmode/dos32b35.zip>
-
-
- ------------------------------
-
- Subject: <Q: 7.11> - How can I tell if my program is running
- on a PS/2-style machine.
-
-
- Use INT 15 AX=C0, described in Ralf Brown's interrupt list
- <Q: 2.03>.
-
-
- ------------------------------
-
- Subject: <Q: 7.12> - Is there a 80x87 math unit installed?
-
-
- SNIPPETS (see <Q: 2.08>) contains C-callable assembly code
- to determine presence of coprocessor in NDPCHECK.ASM.
-
-
- ------------------------------
-
- Subject: Section 8. Other software questions and problems
-
- <Q: 8.01> - How can a program reboot my PC?
- <Q: 8.02> - How can I time events with finer resolution than
- the system clock's 55 ms (about 18 ticks a second)?
- <Q: 8.03> - How can I find the error level of the previous
- program?
- <Q: 8.04> - How can a program set DOS environment variables?
- <Q: 8.05> - How can I change the switch character to - from
- /?
- <Q: 8.06> - How can I write a TSR (terminate-stay-resident
- utility)?
- <Q: 8.07> - Why does my interrupt function behave strangely?
- <Q: 8.08> - How can I write a device driver?
- <Q: 8.09> - What can I use to manage versions of software?
- <Q: 8.10> - What's this "null pointer assignment" after my C
- program executes?
- <Q: 8.11> - How can a batch file tell whether it's being run
- in a DOS box under Windows?
- <Q: 8.12> - How can my program tell if it's running under
- Windows?
- <Q: 8.13> - How can a program tell whether ANSI.SYS is
- installed?
- <Q: 8.14> - How do I copyright software that I write?
-
- ------------------------------
-
- Subject: <Q: 8.01> - How can a program reboot my PC?
- Date: Tue, 7 Mar 95 12:00:00 CDT
-
-
- You can generate a "cold" boot or a "warm" boot. A cold
- boot is the same as turning the power off and on; a warm
- boot is the same as Ctrl-Alt-Del and skips the power-on
- self 'test.
-
-
- For a warm boot, store the hex value 1234 in the word at
- 0040:0072. For a cold boot, store 0 in that word. Then, if
- you want to live dangerously, jump to address FFFF:0000.
- Here's C code to do it:
-
- /* WARNING: data loss possible */
- void bootme(int want_warm) /* arg 0 = cold boot, 1 = warm
- */
- {
- void (far* boot)(void) = (void
- (far*)(void))0xFFFF0000UL;
- unsigned far* type = (unsigned far*)0x00400072UL;
- *type = (want_warm ? 0x1234 : 0);
- (*boot)( );
- }
-
- What's wrong with that method? It will boot right away,
- without closing files, flushing disk caches, etc. If you
- boot without flushing a write-behind disk cache (if one is
- running), you could lose data or trash the file allocation
- table in your hard drive.
-
-
- There are two methods of signaling the cache to flush its
- buffers:
-
-
- (1) Simulate a keyboard Ctrl-Alt-Del in the keystroke
- translation function of the BIOS (INT 15 AH=4F; but see
- notes below)
-
-
- (2) Issue a disk reset (DOS function 0D). Most disk-cache
- programs hook one or both of those interrupts, so if you use
- both methods you'll probably be safe.
-
-
- When user code simulates a Ctrl-Alt-Del, one or more of the
- programs that have hooked INT 15 AH=4F can ask that the key
- be ignored by clearing the carry flag. For example,
- HyperDisk does this when it has started but not finished a
- cache flush. So if the carry flag comes back cleared, the
- boot code has to wait a couple of clock ticks and then try
- again. (None of this matters on older machines whose BIOS
- can't support 101- or 102-key keyboards; see the discussion
- of INT 21 AH=4F in "307. What is the SysRq key for?")
-
-
- C code that tries to signal the disk cache (if any) to
- flush is given below. Turbo Pascal code by Timo Salmi that
- does more or less the same job may be found at question 49
- (as of this writing) in the Turbo Pascal FAQ in
- comp.lang.pascal, and is downloadable as file FAQPAS2.TXT,
- which is part of:
-
- <ftp://garbo.uwasa.fi/pc/ts/tsfaqp*.zip>
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/info/tsfaqp*.zip>
-
- Here's C code that reboots after trying to signal the disk
- cache:
-
- #include <dos.h>
-
- void bootme(int want_warm) /* arg 0 = cold boot, 1 = warm
- */
- {
- union REGS reg;
- void (far* boot)(void) = (void
- (far*)(void))0xFFFF0000UL; unsigned far* boottype =
- (unsigned far*)0x00400072UL;
- char far* shiftstate = (char far*)0x00400017UL;
- unsigned ticks;
- int time_to_waste;
-
- /* Simulate reception of Ctrl-Alt-Del: */
- for (;;)
- {
- *shiftstate |= 0x0C; /* turn on Ctrl & Alt */
- reg.h.ah = 0x4F; /* see notes below */
- reg.h.al = 0x53; /* 0x53 = Del's scan code */
- reg.x.cflag = 1; /* sentinel for ignoring key
- */
- int86(0x15, ®, ®);
-
- /* If carry flag is still set, we've finished. */
- if (reg.x.cflag)
- break;
-
- /* Else waste some time before trying again: */
- reg.h.ah = 0;
- int86(0x1A, ®, ®);/* system time into CX:DX */
- ticks = reg.x.dx;
- for (time_to_waste = 3; time_to_waste > 0; ) {
- reg.h.ah = 0;
- int86(0x1A, ®, ®);
- if (ticks != reg.x.dx)
- ticks = reg.x.dx , --time_to_waste;
- }
- }
-
- /* Issue a DOS disk reset request: */
- reg.h.ah = 0x0D;
- int86(0x21, ®, ®);
- /* Set boot type and boot: */
- *boottype = (want_warm ? 0x1234 : 0);
- (*boot)( );
- }
-
- Reader Timo Salmi reported (26 July 1993) that the INT 15
- AH=4F call may not work on older PCs (below AT, XT2,
- XT286), according to Ralf Brown's interrupt list (<Q:
- 2.03>).
-
-
- Reader Roger Fulton reported (1 July 1993) that INT 15
- AH=4F hangs even a modern PC "ONLY when ANSI.SYS [is]
- loaded high using EMM386.EXE. (Other things loaded high
- with EMM386.EXE were OK; ANSI.SYS loaded high with
- QEMM386.SYS was OK; ANSI.SYS loaded low with EMM386.EXE
- installed was OK.)" His solution was to use only the disk
- reset, INT 21 AH=0D, which does flush SMARTDRV, then wait
- five seconds in hopes that any other disk-caching software
- would have time to flush its queue.
-
-
- Reader Per Bergland reported (10 Sep 1993) that the jump to
- FFFF:0000 will not work in Windows or other protected-mode
- programs. (For example, when the above reboot code ran in a
- DOS session under Windows, a box with "waiting for system
- shutdown" appeared. The PC hung and had to be reset by
- cycling power.) His solution, which does a cold boot not a
- warm boot, is to pulse pin 0 of the 8042 keyboard
- controller, which is connected to the CPU's "reset" line.
-
-
- He has tested the following code on various Compaqs, and
- expects it will work for any AT-class machine; he cautions
- that you must first flush the disk cache as indicated
- above.
-
- cli
-
- @@WaitOutReady: ; Busy-wait until 8042 ready for new
- command
- in al,64h ; read 8042 status byte
- test al,00000010b ; this bit indicates input buffer full
- jnz @@WaitOutReady
- mov al,0FEh ; Pulse "reset" = 8042 pin 0
- out 64h,al
- ; The PC will reboot now
-
- ------------------------------
-
- Subject: <Q: 8.02> - How can I time events with finer
- resolution than the system clock's 55 ms (about 18
- ticks a second)?
- Date: Sun, 03 Aug 97 20:47:02 CST
-
-
- The PC Timing FAQ / Application Note, maintained by Kris
- Heidenstrom (kheidenstrom@actrix.gen.nz), contains
- information relating to timing with PC hardware and
- software. It can be found on SimTel:
-
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/info/pctim*.zip>
-
-
- The following files, among others, are downloadable from
- SimTel:
-
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/sysutl>:
-
-
- atim.zip 4783 881126 Precision program timing for
- AT
-
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/c>
-
- millisec.zip 37734 911205 MSC/asm src for millisecond
- timing
- mschrt3.zip 53708 910605 High-res timer toolbox for
- MSC 5.1
- msec_12.zip 8484 920320 High-def timer v1.2 (C,ASM)
- ztimer11.zip 77625 920428 Microsecond timer for C, C++,
- ASM
-
- For Turbo Pascal users, source and object code are
- downloadable as:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/turbopas/bonus507
- .zip>
- <ftp://garbo.uwasa.fi/pc/turbopas/bonus507.zip>
-
-
-
-
- Also see "Q: How is millisecond timing done?" in
- FAQPAS.TXT, downloadable as part of:
-
- <ftp://garbo.uwasa.fi/pc/ts/tsfaqp*.zip>
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/info/tsfaqp*.zip>
-
- ------------------------------
-
- Subject: <Q: 8.03> - How can I find the error level of the
- previous program?
- Date: Sun, 03 Aug 97 20:47:59 CST
-
-
- First, which previous program are you talking about? If
- your current program ran another one, when the child
- program ends its error level is available to the program
- that spawned it. Most high-level languages provide a way
- to do this; for instance, in Turbo Pascal it's
- Lo(DosExitCode) and the high byte gives the way in which
- the child terminated. In Microsoft C, the exit code of a
- synchronous child process is the return value of the spawn-
- type function that creates the process.
-
-
- If your language doesn't have a function to return the
- error code of a child process, you can use INT 21 AH=4D
- (get return code). By the way, this will tell you the
- child's exit code and the manner of its ending (normal,
- Ctrl-C, critical error, or TSR).
-
-
- It's much trickier if the current program wants to get the
- error level of the program that ran and finished before
- this one started. G.A. Theall has published source and
- compiled code to do this; the code is downloadable as:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/batchutil/errlvl1
- 3.zip>
-
- (The code uses undocumented features in DOS 3.3 through
- 5.0. In the .DOC file Theall says that the values returned
- under 4DOS or other replacements won't be right.)
-
-
- ------------------------------
-
- Subject: <Q: 8.04> - How can a program set DOS environment
- variables?
- Date: Sun, 03 Aug 97 20:52:18 CST
-
-
- Program functions that read or write "the environment"
- typically access only the program's copy of it. What this
- Q really wants to do is to modify the active environment,
- the one that is affected by SET commands in batch files or
- at the DOS prompt. You need to do some programming to find
- the active environment, and that depends on the version of
- DOS.
-
-
- A fairly well-written article in PC Magazine 28 Nov 1989
- (viii:20), pages 309-314, explains how to find the active
- environment, and includes Pascal source code. The article
- hints at how to change the environment, and suggests
- creating paths longer than 128 characters as one
- application.
-
-
- Now as for downloadable source code, there are many
- possibilities.
-
-
- I looked at some of these, and liked this file the best:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/envutil/rbsetnv1.
- zip>
- <ftp://garbo.uwasa.fi/pc/envutil/rbsetnv1.zip>
-
- It includes some utilities to manipulate the environment,
- with source code in C. A newer program from PC Magazine 22
- Dec 1992 (XI: 22) is:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/batchutl/string25
- .zip>
- <ftp://garbo.uwasa.fi/pc/pcmagvol/vol11n22.zip>
-
- You can also use a call to INT 2E, Pass Command to
- Interpreter for Execution; see Ralf Brown's interrupt list
- <Q: 2.03> for details and cautions.
-
-
- ------------------------------
-
- Subject: <Q: 8.05> - How can I change the switch character
- to - from /?
-
-
- Under DOS 5.0 and above you can not. INT 21 AX=3700, get
- switch character, always returns a '/' (hex 2F). But the
- DOS commands don't even call that function: they simply
- hard code '/' as the switch character.
-
-
- Some history: DOS used to let you change the switch
- character by using SWITCHAR= in CONFIG.SYS or by calling
- DOS function 3701. DOS commands and other programs called
- DOS function 3700 to find out the switch character. If you
- changed the switch character to '-' (the usual choice), you
- could then type "dir c:/c700 -p" rather than "dir c:\c700
- /p". Under DOS 4.0, the DOS commands ignored the switch
- character but functions 3700 and 3701 still worked and
- could be used by other programs. Under DOS 5.0, even those
- functions no longer work, though all DOS functions still
- accept '/' or '\' in file specs.
-
-
- You can reactivate the functions to get and set switchar by
- using programs like SLASH.ZIP or the sample TSR called
- SWITCHAR in amisl091.zip (see <Q: 8.06> "How can I write a
- TSR (terminate-stay-resident utility)?"). DOS commands
- will still use the slash, but non-DOS programs that call
- DOS function 3700 will use your desired switch character.
- (DOS replacements like 4DOS may honor the switch character
- for internal commands.)
-
-
- Some readers may wonder why this is even an issue. Making
- '-' the switch character frees up the front slash to
- separate names in the path part of a file spec. This is
- easier for the ten-fingered to type, and it's one less
- difference to remember for commuters between DOS and Unix.
- The switch character is the only issue, since all the INT
- 21 functions accept '/' or '\' to separate directory names.
-
-
- ------------------------------
-
- Subject: <Q: 8.06> - How can I write a TSR (terminate-stay-
- resident utility)?
- Date: Sun, 03 Aug 97 21:03:10 CST
-
-
- There are books, and there's code to download.
-
-
- First, the books:
-
-
- - Ray Duncan's {Advanced MS-DOS}, ISBN 1-55615-157-8,
- gives a brief checklist intended for experienced
- programmers. The ISBN is for the second edition, through
- DOS 4; but check to see whether the DOS 6 version is
- available yet.
-
-
- - {DOS 5: A Developer's Guide} by Al Williams, ISBN 1-
- 55851-177-6, goes into a little more detail, 90 pages worth!
-
-
- - Pascal programmers might look at {The Ultimate DOS
- Programmer's Manual} by John Mueller and Wallace Wang, ISBN
- 0-8306-3534-3, for an extended example in mixed Pascal and
- assembler.
-
-
- - For a pure assembler treatment, check Steven Holzner's
- {Advanced Assembly Language}, ISBN 0-13-663014-6. He has a
- book with the same title out from Brady Press, but it's
- about half as long as this one.
-
-
- Next, the code. Some of it is companion code to published
- articles, which are also listed below:
-
-
- - The Alternate Multiplex Interrupt Specification,
- downloadable as
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/info/altmpx35.zip>
- or
- <ftp://garbo.uwasa.fi/pc/programming/altmpx35.zip>
-
-
- - Ralf Brown's assembly-language implementation of the
- spec, with utilities in C, is downloadable as
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/asmutil/amisl092.z
- ip>
- or
- <ftp://garbo.uwasa.fi/pc/c-lang/amisl092.zip>
-
-
- - John English has created a wonderful C++ class for
- creating TSRs which includes several examples. It is
- downloadable as:
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/cpluspls/tsr100je.
- zip>
-
-
- - Douglas Boling's MASM template for a TSR is
- downloadable as
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/asmutl/template.zi
- p>
-
-
- - A posted article mentions Boling's "Strategies and
- Techniques for Writing State-of-the-Art TSRs that Exploit MS-
- DOS 5", Microsoft Systems Journal, Jan-Feb 1992, Volume 7,
- Number 1, pages 41-59, with examples downloadable in
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/msjournl/msjv7-
- 1.zip>
-
-
- - Code for Al Stevens's "Writing Terminate-and-Stay-
- Resident Programs", Computer Language, February 1988, pages
- 37-48 and March 1988, pages 67-76 is downloadable as
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/c/tsrc.zip>
-
-
- - Software examples to accompany Kaare Christian's "Using
- Microsoft C Version 5.1 to Write Terminate-and-Stay-Resident
- Programs", Microsoft Systems Journal, September 1988, Volume
- 3, Number 5, pages 47-57 are downloadable as
- <ftp://oak.oakland.edu/pub/msdos/msjournl/msjv3-5.zip>
-
-
- Finally, there are commercial products, of which TesSeRact
- (for C-language TSRs) is one of the best known.
-
-
- ------------------------------
-
- Subject: <Q: 8.07> - Why does my interrupt function behave
- strangely?
- Date: Sun, 03 Aug 97 21:05:15 CST
-
-
- Interrupt service routines can be tricky, because you have
- to do some things differently from "normal" programs. If
- you make a mistake, debugging is a pain because the
- symptoms may not point at what's wrong. Your machine may
- lock up or behave erratically, or just about anything else
- can happen. Here are some things to look for. (See <Q:
- 8.06> "How can I write a TSR (terminate-stay-resident
- utility)?" for general techniques that may prevent a
- problem.)
-
-
- First, did you fail to set up the registers at the start of
- your routine? When your routine begins executing, you can
- count on having CS point to your code segment and SS:SP
- point to some valid stack (of unknown length), and that's
- it. In particular, an interrupt service routine must set
- DS to DGROUP before accessing any data in its data
- segments. (If you're writing in a high-level language, the
- compiler may generate this code for you automatically;
- check your compiler manual. For instance, in Borland and
- Microsoft C, give your function the "interrupt" attribute.)
-
-
- Did you remember to turn off stack checking when compiling
- your interrupt server and any functions it calls? The
- stack during the interrupt is not where the stack-checking
- code expects it to be. (Caution: Some third-party
- libraries have stack checking compiled in, so you can't
- call them from your interrupt service routine.)
-
-
- Next, are you calling any DOS functions (INT 21, 25, or 26)
- in your routine? DOS is not re-entrant. This means that
- if your interrupt happens to be triggered while the CPU is
- executing a DOS function, calling another DOS function will
- wreak havoc. (Some DOS functions are fully re-entrant, as
- noted in Ralf Brown's interrupt list <Q: 2.03>. Also, your
- program can test, in a way too complicated to present here,
- when it's safe to call non-re-entrant DOS functions. See
- INT 28, INT 21 AH=34, and INT 21 AX=5D06 or 5D0B; and
- consult {Undocumented DOS} by Andrew Schulman. Your
- program must read both the "InDOS flag" and the "critical
- error flag".)
-
-
- Is a function in your language library causing trouble?
- Does it depend on some initializations done at program
- startup that is no longer available when the interrupt
- executes? Does it call DOS (see preceding paragraph)? For
- example, in both Borland and Microsoft C the memory-
- allocation functions (malloc(), etc..) call DOS functions
- and also depend on setups that they can't get at from
- inside an interrupt; so do the standard I/O functions like
- scanf() and printf(). Many other library functions have
- the same problem, so you can't use them inside an interrupt
- function without special precautions.
-
-
- Is your routine simply taking too long? This can be a
- problem if you're hooking on to the timer interrupt, INT 1C
- or INT 8. That interrupt expects to be called about every
- 55 ms, which is 18.2 times a second. Therefore your
- routine, plus any others hooked to the same interrupts,
- must execute in less than 55 ms. If they use even a
- substantial fraction of that time, you'll see significant
- slowdowns of your foreground program. A good discussion is
- downloadable as:
-
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/info/intshare.zip
- >
-
-
- Did you forget to restore all registers at the end of your
- routine?
-
-
- Reader, Morten Welinder, notes that programmers of
- interrupt procedures in Borland/Turbo Pascal 7.0 should be
- aware that the high words or the 32-bit registers are not
- saved automatically and that the run-time library may trash
- them if, e.g., you use longint operations. The easy way
- around this is to do "Test8086 := 0;" before installing the
- interrupt handler.
-
-
- Did you chain improperly to the original interrupt? You
- need to restore the stack to the way it was upon entry to
- your routine, then do a far jump (not call) to the original
- interrupt service routine.
-
-
- (The process is a little different in high-level
- languages.)
-
-
- ------------------------------
-
- Subject: <Q: 8.08> - How can I write a device driver?
-
-
- Many books answer this in detail. Among them are {Advanced
- MS-DOS} and {DOS 5: A Developer's Guide}, cited in the
- preceding Q. Michael Tischer's {PC System Programming},
- ISBN 1-55755-036-0, has an extensive treatment, as does
- Dettman and Kyle's {DOS Programmer's Reference: 2d
- Edition}, ISBN 0-88022-458-4. For a really in-depth
- treatment, look for a specialized book like Robert Lai's
- {Writing MS-DOS Device Drivers}, ISBN 0-201-13185-4.
-
-
- ------------------------------
-
- Subject: <Q: 8.09> - What can I use to manage versions of
- software?
- Date: Sun, 03 Aug 97 21:07:50 CST
-
-
- A port of the Unix RCS utility is downloadable as:
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/gnuish/rcs55ax.z
- ip> (EXE and docs)
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/gnuish/rcs55as.z
- ip> (source)
- <ftp://garbo.uwasa.fi/pc/unix/alrcs5ex.zip> (EXE and
- docs?)
-
- This version of RCS is no longer limited to one-character
- extensions on filenames (for example, .CPP and .BAS are now
- OK).
-
-
- An RCS56 is available at a number of archive sites, but it
- appears to be unauthorized. In response to a query, Keith
- Petersen, SimTel administrator, said that RCS56 was removed
- from SimTel at the author's request because it did not
- contain source code and thus was in violation of the GNU
- copyleft.
-
-
- As for commercial software, I posted a question asking for
- readers' experiences in July 1993 and seven readers
- responded. PVCS from Intersolv (formerly Polymake) got
- five positive reviews, though several readers commented
- that it's expensive; RCS from MKS got one positive and one
- negative review; Burton TLIB got one negative review; DRTS
- from ILSI got one positive review.
-
-
- ------------------------------
-
- Subject: <Q: 8.10> - What's this "null pointer assignment"
- after my C
- program executes?
-
-
- Somewhere in your program, you assigned a value through a
- pointer without first assigning a value to the pointer.
- (This might have been something like a strcpy() or memcpy()
- with a pointer as its first argument, not necessarily an
- actual assignment statement.)
-
-
- Your program may look like it ran correctly, but if you get
- this message you can be certain that there's a bug
- somewhere.
-
-
- Microsoft and Borland C, as part of their exit code (after
- a call to exit() or a return from your main function),
- check whether the location 0000 in your data segment
- contains a different value from what you started with. If
- so, they infer that you must have used an uninitialized
- pointer. This implies that the message will appear at the
- end of execution of your program regardless of where the
- error actually occurred.
-
-
- To track down the problem, you can put exit() calls at
- various spots in the program and narrow down where the
- uninitialized pointer is being used by seeing which added
- exit() makes the null-pointer message disappear. Or, if
- your program was compiled with small or medium models,
- which use 16-bit data pointers, tell the debugger to set a
- watch at location 0000 in your data segment. (If data
- pointers are 32 bits, as in the compact and large models, a
- null pointer will overwrite the interrupt vectors at
- 0000:0000 and probably lock up your machine.)
-
-
- Under MSC/C++ 7.0, you can declare the undocumented library
- function:
-
- extern _cdecl _nullcheck(void);
-
- Sprinkle calls to _nullcheck() through your program at
- regular intervals.
-
-
- Borland's TechFax document TI726 discusses the null pointer
- assignment from a Borland point of view. It's one of many
- documents downloadable as part of
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/turbo-
- c/bchelp10.zip>
- <ftp://garbo.uwasa.fi/pc/turbopas/bchelp10.zip>
-
- ------------------------------
-
- Subject: <Q: 8.11> - How can a batch file tell whether it's
- being run in a DOS box under Windows?
-
-
- When Windows 3.0 or 3.1 is running, the DOS environment
- will contain a definition of the string windir, in lower
- case. That's not really useful, however, because the batch
- statement
-
- if "%windir%" == "" ...
-
- will test for an environment variable WINDIR in upper case.
-
-
- Your only real option is to write a program as suggested by
- the following question, and have it return a value which
- your batch file can test via "if errorlevel".
-
-
- ------------------------------
-
- Subject: <Q: 8.12> - How can my program tell if it's running
- under Windows?
- Date: Sun, 03 Aug 97 21:12:33 CST
-
-
- Execute INT 2F AX=4680. If AX returns 0, you're in Windows
- real mode or standard mode (or under the DOS shell).
- Otherwise, call INT 2F AX=1600. If AL returns something
- other than 0 or 80, you're in Windows 386 enhanced mode.
- See PC Magazine 24 Nov 1992 (xi:20) pages 492-493.
-
-
- For more information, see PC Magazine 26 May 1992 (xi:10)
- pages 345-346. A program, WINMODE, is available as part of
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/pcmag/vol11n10.zi
- p>
- <ftp://garbo.uwasa.fi/pc/pcmagvol/vol11n10.zip>
-
- PC Magazine 29 March 1994 (xiii: 6) pages 312 and 320
- published a new program, WINVER. This would be in
-
- <ftp://ftp.simtel.net/pub/simtelnet/msdos/pcmag/vol13n06.zi
- p>
- <ftp://garbo.uwasa.fi/pc/pcmagvol/vol13n06.zip>
-
- ------------------------------
-
- Subject: <Q: 8.13> - How can a program tell whether ANSI.SYS
- is installed?
-
-
- In DOS 4.0 and above, call INT 2F AX=1A00. If the value FF
- is returned in AL, ANSI.SYS is installed. For more
- information, see Ralf Brown's interrupt list (<Q: 2.03>).
-
-
- ------------------------------
-
- Subject: <Q: 8.14> - How do I copyright software that I
- write?
-
-
- You can download a very comprehensive answer from the
- Internet. Terry Carroll posts a six-part Copyright FAQ to
- misc.legal, news.answers and other groups. A short answer
- follows, not based on that article.
-
-
- Disclaimer: I am not a lawyer, and this is not legal
- advice. Also, there are very likely to be differences in
- copyright law among nations. No matter where you live, if
- significant money may be involved, get legal advice. The
- following is adapted (and greatly condensed) from chapter 4
- of the Chicago Manual of Style (13th edition, ISBN 0-226-
- 10390-0).
-
-
- In the U.S. (at least), when you write something, you own
- the copyright. (The exception that matters most to
- programmers is "works made for hire", i.e., code you write
- because your employer or client pays you to. A contract,
- agreed in advance, can vest the copyright in the programmer
- even if an employee; otherwise the employer owns the
- copyright.) You don't have to register the work with the
- Copyright Office unless (until) the copyright is infringed
- and you intend to bring suit; however, it is easier to
- recover damages in court if you did register the work
- within three months of publication.
-
-
- From paragraph 4.16 of the Chicago Manual:
-
-
- "... the [copyright] notice consists of three parts: (1)
- the symbol [C-in-a-circle] (preferred because it also
- suits the requirements of the Universal Copyright
- Convention), the word 'Copyright', or the abbreviation
- 'Copr.', (2) the year of first publication, and (3) the
- name of the copyright owner. Most publishers also add the
- phrase 'All rights reserved' because it affords some
- protection in Central and South American countries...."
-
-
- Surprise: "(C)" is legally not the same as the C-in-a-
- circle, so those of us who are ASCII-bound must use the
- word or the abbreviation.
-
-
- ------------------------------
-
- Subject: End
-
- (FAQ updates can be found at
- <http://www.premiernet.net/~carlyle>.)
- (End of comp.os.msdos.programmer FAQ Version 1997.08 Part
- 4/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>
-
-
-