BE CAREFUL: This machine has no brain, use your own

(Ab)using DEBUG

Note: This page shows some uses of the DEBUG command.
It is not about debugging.
If you are looking for my page on debugging batch files, follow this link.

 

A note on DEBUG and Windows XP

Back in the MS-DOS era, DEBUG used to be able to read and write directly to memory.
In Windows 2000 and XP (and most likely in NT 4 as well, though I didn't verify this assumption) however, DEBUG doesn't really have access to the physical memory, as it runs in an emulated 16-bit environment. So even when DEBUG seems to access memory and CPU registers directly, it only accesses an emulated copy. This means that in these 32-bit environments, DEBUG can no longer be used to change/write to memory, but you can still use it to read from memory.
That's why KeyLocks.bat does work and CAPS_OFF does not.

 

Reboot DOS


ECHO G=FFFF:0000 | DEBUG
Note: Using this command usually results in a "warm restart" of the computer, like pressing Ctrl-Alt-Del.
You might even use it in Windows (3), where it will bring up the process list; again, like pressing Ctrl-Alt-Del.
Sometimes, however, it will result in a "cold restart", like pressing the reset button. In Windows, this could lead to loss of data and even to corruption of the file system.
You should let your batch files check for the operating system if you use tricks like these.
Use with extreme care and at your own risk!

See the Shutdown and Reboot page for related commands for Windows 3.*, 95/98, NT and for OS/2.

 

Back to the top of this page...

 

KeyLocks

Returns the status of the CapsLock, NumLock and ScrollLock keys

@GOTO :Batch

D 0:417 L 1
Q

:Batch
@ECHO OFF
:: Check the command line arguments
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
IF NOT "%˜2"=="" GOTO Syntax
IF NOT "%˜1"=="" IF /I NOT "%˜1"=="C" IF /I NOT "%˜1"=="N" IF /I NOT "%˜1"=="S" GOTO Syntax


:: Run DEBUG with the temporary script and capture the result
FOR /F "skip=4 tokens=2" %%A IN ('DEBUG ˆ< "%˜f0" 2ˆ>NUL') DO SET /A KeyLocks = 0x%%A

:: Calculate the status of the individual keys
SET /A CapsLock   = "(%KeyLocks% & 0x40) / 0x40"
SET /A NumLock    = "(%KeyLocks% & 0x20) / 0x20"
SET /A ScrollLock = "(%KeyLocks% & 0x10) / 0x10"

:: Display the requested result(s)
IF /I NOT "%˜1"=="N" IF /I NOT "%˜1"=="S" SET CapsLock
IF /I NOT "%˜1"=="C" IF /I NOT "%˜1"=="S" SET NumLock
IF /I NOT "%˜1"=="C" IF /I NOT "%˜1"=="N" SET ScrollLock

:: Default return code is the combined status
SET /A KeyLocks = "%KeyLocks% & 0x70"
:: If a single key lock was requested on the command
:: line, the return code will be that key's status
IF /I "%˜1"=="C" SET KeyLocks=%CapsLock%
IF /I "%˜1"=="N" SET KeyLocks=%NumLock%
IF /I "%˜1"=="S" SET KeyLocks=%ScrollLock%

:: Return the requested key lock's status as "errorlevel"
EXIT /B %KeyLocks%


:Syntax
ECHO KeyLocks.bat,  Version 1.20 for Windows NT 4 / 2000 / XP
ECHO Return the status of the CapsLock, NumLock and ScrollLock keys
ECHO.
IF NOT "%OS%"=="Windows_NT" ECHO Usage:  KEYLOCKS  [ C ³ N ³ S ]
IF     "%OS%"=="Windows_NT" ECHO Usage:  KEYLOCKS  [ C ˆ| N ˆ| S ]
ECHO.
ECHO Where:  C is for CapsLock status, N for NumLock, and S for ScrollLock.
ECHO         By default the status for all three is displayed.
ECHO.
ECHO Notes:  The status of either the requested or all key lock(s) is displayed
ECHO         on screen, and each is stored in the environment variables CapsLock,
ECHO         NumLock and ScrollLock. The value of the environment variable
ECHO         KeyLocks, which will also be returned as an "errorlevel", will
ECHO         either be the status of the requested key lock (0=OFF, 1=ON) or
ECHO         a combination of the three (C=64, N=32, S=16).
ECHO         This batch file uses DEBUG to read the keyboard status.
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com

 

Perl is better suited to handle 16-bits processes, that's why I also wrote a Perl version: KeyLocks.pl.

 

Click to download the ZIPped sources
Dowload all DEBUG sources

 

Related utilities:

My own CapsLock.exe and NumLock.exe utilities return the CapsLock and NumLock states respectively as "errorlevels" (they both require the .NET Framework 2.0)

DKpcCODE's DK:Keyboard-Status (Popup balloon displaying the CapsLock, Insert and NumLock key's status of the keyboard) and DKOSD (CapsLock, On Screen Display).

 

Back to the top of this page...

 

VideoROM

This script is based on the simple DEBUG command D C000:0040, which I found at Computer Hope.
The resulting screen output looks like this, depending of course on your video card:

C000:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
C000:0050  E9 19 71 00 43 10 31 40-E9 3C 10 E9 43 10 50 4D   ..q.C.1@.<..C.PM
C000:0060  49 44 58 00 5B 00 00 00-00 A0 00 B0 00 B8 00 C0   IDX.[...........
C000:0070  00 5B FF 7F 4E 56 00 05-14 C5 BD E0 24 01 11 03   .[..NV......$...
C000:0080  00 00 00 00 CE AA 59 AC-EF 01 D0 A4 08 A4 7C A4   ......Y.......|.
C000:0090  08 01 50 00 8C 74 71 28-13 66 6D 66 FB 6A B0 6A   ..P..tq(.fmf.j.j
C000:00A0  C4 6A 99 01 BC 01 C4 B1-00 01 01 00 3F 3E 37 36   .j..........?>76
C000:00B0  00 7E 66 10 67 20 A1 07-00 90 D0 03 00 32 AA 82   .~f.g .......2..

Using FOR's /F switch in NT 4 I filtered out the hexadecimal stuff, and I added 8 more lines of output with a second DEBUG line:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS

SET Single=0
IF "%1"=="/1" SET Single=1
IF NOT "%1"=="" IF NOT "%1"=="/1" GOTO Syntax

SET FullParam=
SET DebugScript=%Temp%.\%~n0.dbg
(ECHO d C000:0040) >  %debugscript%
(ECHO d C000:00C0) >> %debugscript%
(ECHO q)           >> %DebugScript%
ECHO.
FOR /F "tokens=*" %%a IN ('DEBUG ˆ< %DebugScript%') DO CALL :Subroutine %%a
DEL %DebugScript%
IF %Single%==1 ECHO.%FullParam%
GOTO End

:Subroutine
FOR /F "tokens=1 delims=: " %%A IN ("%1") DO IF NOT "%%A"=="C000" GOTO:EOF
SET Param=%*
SET Param=%Param:~61%
VER | FIND "Windows NT" >NUL
IF NOT ERRORLEVEL 1 SET Param=%Param:~1%
SET Param=%Param:(=ˆ(%
SET FullParam=%FullParam%%Param%
IF NOT %Single%==1 ECHO.%Param%
GOTO:EOF

:Syntax
ECHO.
ECHO VideoROM.cmd,  Version 2.01 for Windows NT 4 / 2000
ECHO Reads and displays manufacturer information from your video adapter ROM
ECHO.
ECHO Usage:  %~n0  [ /1 ]
ECHO         /1 switch results in single line output
ECHO            ˆ(will be wrapped on screen thoughˆ)
ECHO            default is 16 lines of 16 characters each
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Idea by ComputerHope
ECHO http://www.computerhope.com/rdebug.htm

:End
ENDLOCAL

Now the screen output may look like this:

................
..q.C.1@.
IDX.[...........
.[..NV......$...
..P..tq(.fmf.j.j
.j..........?
.~f.g .......2..
................
............g.g.
..........g.g...
PCIR............
d.......ASUS V71
00PRO VGA BIOS V
ersion 3.11.01.2
4.AS09..........

 

I'm afraid version 3.00 is much harder to read, and much much harder to explain. However, I like this one because it does not use any temporary files at all and its output is more readable (one single line, multiple dots are replaced by single dots and unprintable characters are removed).

@ECHO OFF
:: For Windows NT 4/2000/XP only
IF NOT [%OS%]==[Windows_NT] GOTO Syntax
:: No command line parameters required, "/2nd" is for internal use only
IF NOT [%1]==[] IF NOT [%1]==[/2nd] GOTO Syntax

:: OK, let's go
SETLOCAL
IF [%1]==[/2nd] (
	:: DEBUG commands, to be piped to DEBUG.EXE
	FOR %%A IN ("d C000:0040" "d C000:00C0" "q") DO ECHO.%%~A
) ELSE (
	SET Info=
	:: Recursive call is needed to enable piping screen output to DEBUG.EXE
	FOR /F "tokens=16* delims= " %%A IN ('ˆ(CMD.EXE /C "%~f0" /2nd 2ˆ>NULˆ) ˆ| DEBUG.EXE ˆ| FIND "C000:"') DO CALL :Parse "%%B"
)
:: Remove multiple dots
CALL :StripDots
:: Show result with several blank lines inserted in one single ECHO command
ECHO ˆ

Video adapter ROM manufacturer info:ˆ

ˆ

%Info%
:: Done
ENDLOCAL
GOTO:EOF


:AddStr
:: Remove quotes and append to existing string
SET Info=%Info%%~1
GOTO:EOF


:Parse
:: Remove "unprintable" characters
SET Line=%1
SET Line=%Line:|=%
SET Line=%Line:<=%
SET Line=%Line:>=%
:: Remove quotes and append to existing string
CALL :AddStr %Line%
GOTO:EOF


:StripDots
:: Quit when no multiple dots are left
ECHO.%Info% | FIND ".." >NUL
IF ERRORLEVEL 1 GOTO:EOF
:: Remove multiple dots
SET Info=%Info:..=.%
:: Repeat
GOTO :StripDots


:Syntax
ECHO.
ECHO VideoROM.cmd,  Version 3.00 for Windows NT 4 / 2000 / XP
ECHO Reads and displays manufacturer information from your video adapter ROM
ECHO.
ECHO Usage:  %~n0
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Original idea by ComputerHope
ECHO http://www.computerhope.com/rdebug.htm

This is what version 3's output looks like:

Video adapter ROM manufacturer info:

.q.C.1@.C.PMIDX.[.[.NV.$.Y.P.tq(.fmf.j.j.j.?76.~f.g .2.g.g.g.g.PCIR.d.ASUS V7100
PRO VGA BIOS Version 3.11.01.24.AS09.

 

If you thought version 3 was hard to read, you'd better skip version 4.
However, I like this one best because it not only doesn't use temporary files, but most of all because it displays a really "clean" output.

@ECHO OFF
:: For Windows NT 4/2000/XP only
IF NOT [%OS%]==[Windows_NT] GOTO Syntax
:: No command line parameters required, "/2nd" is for internal use only
IF NOT [%1]==[] IF NOT [%1]==[/2nd] GOTO Syntax

:: OK, let's go
SETLOCAL
IF [%1]==[/2nd] (
	:: DEBUG commands, to be piped to DEBUG.EXE
	FOR %%A IN ("d C000:0040" "d C000:00C0" "q") DO ECHO.%%~A
) ELSE (
	SET Info=
	:: Recursive call is needed to enable piping screen output to DEBUG.EXE
	FOR /F "tokens=16* delims= " %%A IN ('ˆ(CMD.EXE /C "%~f0" /2nd 2ˆ>NULˆ) ˆ| DEBUG.EXE ˆ| FIND "C000:"') DO CALL :Parse "%%B"
)
:: Remove multiple dots
CALL :StripDots
:: Tidy up resulting string
CALL :Tidy
:: Show result
ECHO.
ECHO Video adapter ROM manufacturer info:
ECHO.
ECHO.%Info%
:: Done
ENDLOCAL
GOTO:EOF


:AddStr
:: Remove quotes and append to existing string
SET Info=%Info%%~1
GOTO:EOF


:Parse
:: Remove "unprintable" characters
SET Line=%1
SET Line=%Line:|=%
SET Line=%Line:<=%
SET Line=%Line:>=%
:: Remove quotes and append to existing string
CALL :AddStr %Line%
GOTO:EOF


:Reverse
:: Subroutine that reverses the specified input string
:: Initialize variables
SET Reverse=
SET Input=%*
:: Strip leading space in NT 4 only
VER | FIND "Windows NT" >NUL
IF NOT ERRORLEVEL 1 SET Input=%Input:~1%
:Loop
:: Continue till the input string's last character
IF NOT DEFINED Input GOTO:EOF
:: Separate first character from input string
SET FirstChar=%Input:~0,1%
SET Input=%Input:~1%
:: Rebuild string in reverse order
SET Reverse=%FirstChar%%Reverse%
:: Next character
GOTO Loop


:StripDots
:: Quit when no multiple dots are left
ECHO.%Info% | FIND ".." >NUL
IF ERRORLEVEL 1 GOTO:EOF
:: Remove multiple dots
SET Info=%Info:..=.%
:: Repeat
GOTO :StripDots


:Tidy
:: Split string at first space
FOR /F "tokens=1* delims= " %%A IN ('ECHO.%Info%') DO (
	SET Prefix=%%A
	SET TempInfo=%%B
)
:: Quit if string wasn't split
IF NOT DEFINED TempInfo GOTO:EOF
:: Split at next space if first space was followed by a dot
IF "%TempInfo:~0,1%"=="." FOR /F "tokens=1* delims= " %%A IN ('ECHO.%TempInfo%') DO (
	SET Prefix=%Prefix% %%A
	SET TempInfo=%%B
)
:: Quit if string wasn't split
IF NOT DEFINED TempInfo GOTO:EOF
:: Split at next space if previous space was followed by a dot
IF "%TempInfo:~0,1%"=="." FOR /F "tokens=1* delims= " %%A IN ('ECHO.%TempInfo%') DO (
	SET Prefix=%Prefix% %%A
	SET TempInfo=%%B
)
:: Quit if string wasn't split
IF NOT DEFINED TempInfo GOTO:EOF
:: Reverse first part of string
CALL :Reverse %Prefix%
:: Quit if last character of first string part was a dot
IF "%Reverse:~0,1%"=="." GOTO:EOF
:: Remove everything after first dot, efectively keeping
:: only the reversed last "word" of first part of string
FOR /F "tokens=1 delims=." %%a IN ('ECHO.%Reverse%') DO SET Prefix=%%a
:: Reverse again
CALL :Reverse %Prefix%
:: Concatenate the 2 parts
SET Info=%Reverse% %TempInfo%
GOTO:EOF


:Syntax
ECHO.
ECHO VideoROM.cmd,  Version 4.00 for Windows NT 4 / 2000 / XP
ECHO Reads and displays manufacturer information from your video adapter ROM
ECHO.
ECHO Usage:  %~n0
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Original idea by ComputerHope
ECHO http://www.computerhope.com/rdebug.htm

This is what version 4's output looks like:

Video adapter ROM manufacturer info:

ASUS V7100 PRO VGA BIOS Version 3.11.01.24.AS09.

 

And here is the MS-DOS version of the batch file, which isn't easy reading either ... of course.
The DOS version doesn't handle < and > characters in the string very well, which may result in stray files or unexpected error messages.
You may want to execute this batch file in your TEMP directory only.

@ECHO OFF
ECHO.
ECHO VideoROM.bat,  Version 1.00 for DOS
ECHO Reads and displays manufacturer information from your video adapter ROM
ECHO.
ECHO Usage:  %0
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Idea by ComputerHope
ECHO http://www.computerhope.com/rdebug.htm
ECHO.

:: Check if running in true DOS mode
ECHO.%COMSPEC% | FIND /I "COMMAND.COM" > NUL
IF ERRORLEVEL 1 GOTO Error

:: Create temporary DEBUG script to gather video info
>  VIDEO.DBG ECHO d C000:0040
>> VIDEO.DBG ECHO d C000:00C0
>> VIDEO.DBG ECHO q

:: Create temporary batch file to display 17th "word" in a line
>  C000.BAT ECHO @ECHO OFF
>> C000.BAT ECHO FOR %%%%A IN (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) DO SHIFT
>> C000.BAT ECHO ECHO %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9

:: Gather video adapter ROM info and store in a temporary file
DEBUG < VIDEO.DBG | FIND "  " > VIDEO.DAT

:: Read the 16 lines of video info one line at a time
:: and display each line starting at the 17th "word"
TYPE VIDEO.DAT | FIND "C000:0040  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0050  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0060  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0070  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0080  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0090  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00A0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00B0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00C0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00D0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00E0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:00F0  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0100  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0110  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0120  " > VIDEO_.BAT
CALL VIDEO_.BAT
TYPE VIDEO.DAT | FIND "C000:0130  " > VIDEO_.BAT
CALL VIDEO_.BAT

:: Remove temporary files
DEL VIDEO_.BAT
DEL VIDEO.DAT
DEL VIDEO.DBG
DEL C000.BAT
GOTO End

:Error
ECHO ERROR: This batch file is meant for DOS only!
ECHO.

:End

 

Perl and Rexx are much better suited for parsing strings, that's why I combined this DEBUG trick with Perl and Rexx string parsing to create VideoROM.pl and VideoROM.rex.
Both scripts filter and display the relevant output perfectly:

ASUS V7100PRO VGA BIOS Version 3.11.01.24.AS09

I also created KiXtart and VBScript versions that use WMI instead of DEBUG to retrieve the information from Windows:

Video summary for MYOWNPC:

    Name:                    NVIDIA GeForce2 MX/MX 400
    Description:             NVIDIA GeForce2 MX/MX 400
    Video Processor:         GeForce2 MX//MX 400
    Adapter RAM:             32 MB
    Video Mode Description:  1600 x 1200 x 65536 colors

 

Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

GETPORTS

I created this batch file after reading a tip by Alfred Poor in PC Magazine.
GetPorts displays the hexadecimal I/O addresses for COM1 through COM4 and LPT1 through LPT3.
It has been tested in Windows 98 (Dutch), OS/2 Warp 4 (English and Dutch) and Windows NT 4 (English, though by using completely different commands this should be really language independent in NT). It should prove not too hard to add other languages.

@ECHO OFF
REM * GetPorts, Version 2.12 for all DOS flavours
REM * Written by Rob van der Woude, http://www.robvanderwoude.com
REM * Needs DEBUG and CHOICE.COM


REM * "Initialize" variables used
FOR %%A IN (1 2 3 4) DO SET COM%%A=
FOR %%A IN (1 2 3) DO SET LPT%%A=

REM * Create DEBUG script and use it to read port addresses
REM * (information provided by Alfred Poor in PC Magazine)
ECHO D 40:0 L E> GETPORTS.SCR
ECHO Q>> GETPORTS.SCR
DEBUG < GETPORTS.SCR | FIND "40:0" | FIND /V "-D " > GETPORTS.DAT

REM * All code following is used to parse the string
REM * that DEBUG returned into readable information

REM * NT only
VER | FIND "Windows NT" > NUL
IF ERRORLEVEL 1 GOTO DOS
FOR /F "TOKENS=2-16* DELIMS=- " %%A IN (GETPORTS.DAT) DO (
	SET COM1=%%B%%A
	SET COM2=%%D%%C
	SET COM3=%%F%%E
	SET COM4=%%H%%G
	SET LPT1=%%J%%I
	SET LPT2=%%L%%K
	SET LPT3=%%N%%M
)
GOTO DisplayAll

:DOS
REM * Use DATE to store the string in several variables, as
REM * explained in http://www.robvanderwoude.com/datetime.html
ECHO.>> GETPORTS.DAT
TYPE GETPORTS.DAT | DATE | FIND "40:0" > GETPORT$.BAT

REM * Different DOS versions and languages
REM * need different temporary batch files
VER | DATE | FIND /I "VOER" > NUL
IF NOT ERRORLEVEL 1 SET ENTER=VOER
VER | DATE | FIND /I "TYP" > NUL
IF NOT ERRORLEVEL 1 SET ENTER=TYP
VER | DATE | FIND /I "CURRENT" > NUL
IF NOT ERRORLEVEL 1 SET ENTER=ENTER
GOTO Make%ENTER%

:MakeENTER
REM * English DOS version
ECHO @ECHO OFF> %ENTER%.BAT
ECHO IF "%%1"=="Loop2" GOTO Loop2>> %ENTER%.BAT
ECHO FOR %%%%A IN (1 2 3 4 5) DO SHIFT>> %ENTER%.BAT
GOTO MakeAll

:MakeTYP
REM * Dutch Win98 version
ECHO @ECHO OFF> %ENTER%.BAT
ECHO IF "%%1"=="Loop2" GOTO Loop2>> %ENTER%.BAT
ECHO FOR %%%%A IN (1 2 3 4) DO SHIFT>> %ENTER%.BAT
GOTO MakeAll

:MakeVOER
REM * Dutch DOS version
ECHO @ECHO OFF> %ENTER%.BAT
ECHO IF "%%1"=="Loop2" GOTO Loop2>> %ENTER%.BAT
ECHO FOR %%%%A IN (1 2 3 4 5 6) DO SHIFT>> %ENTER%.BAT
GOTO MakeAll

:MakeAll
REM * Common to all DOS versions
ECHO SET COM1=%%2%%1>> %ENTER%.BAT
ECHO SET COM2=%%4%%3>> %ENTER%.BAT
ECHO SET COM3=%%6%%5>> %ENTER%.BAT
ECHO SET COM4=%%7>> %ENTER%.BAT

REM * Get rid of the hyphen connecting two
REM * parameters, using Outsider's CHOICE trick
ECHO SET Loop2=>> %ENTER%.BAT
ECHO EXIT|%COMSPEC%/KPROMPT $_ECHO ]$BCHOICE/C:[;%%8;] %ENTER%.BAT Loop2 ;$G%ENTER%$$.BAT$_|FIND "Loop2">>%ENTER%.BAT

ECHO CALL %ENTER%$.BAT>> %ENTER%.BAT
ECHO FOR %%%%A IN (1 2 3 4 5 6 7) DO SHIFT>> %ENTER%.BAT
ECHO SET LPT1=%%2%%Loop2%%>> %ENTER%.BAT
ECHO SET LPT2=%%4%%3>> %ENTER%.BAT
ECHO SET LPT3=%%6%%5>> %ENTER%.BAT
ECHO GOTO End>> %ENTER%.BAT

REM * Part two of Outsider's CHOICE trick
ECHO :Loop2>> %ENTER%.BAT
ECHO IF "%%2"=="-" SET COM4=%%Loop2%%%%COM4%%>> %ENTER%.BAT
ECHO IF "%%2"=="-" SET Loop2=>> %ENTER%.BAT
ECHO IF "%%2"=="0" SET Loop2=%%Loop2%%0>> %ENTER%.BAT
ECHO IF "%%2"=="1" SET Loop2=%%Loop2%%1>> %ENTER%.BAT
ECHO IF "%%2"=="2" SET Loop2=%%Loop2%%2>> %ENTER%.BAT
ECHO IF "%%2"=="3" SET Loop2=%%Loop2%%3>> %ENTER%.BAT
ECHO IF "%%2"=="4" SET Loop2=%%Loop2%%4>> %ENTER%.BAT
ECHO IF "%%2"=="5" SET Loop2=%%Loop2%%5>> %ENTER%.BAT
ECHO IF "%%2"=="6" SET Loop2=%%Loop2%%6>> %ENTER%.BAT
ECHO IF "%%2"=="7" SET Loop2=%%Loop2%%7>> %ENTER%.BAT
ECHO IF "%%2"=="8" SET Loop2=%%Loop2%%8>> %ENTER%.BAT
ECHO IF "%%2"=="9" SET Loop2=%%Loop2%%9>> %ENTER%.BAT
ECHO IF "%%2"=="A" SET Loop2=%%Loop2%%A>> %ENTER%.BAT
ECHO IF "%%2"=="B" SET Loop2=%%Loop2%%B>> %ENTER%.BAT
ECHO IF "%%2"=="C" SET Loop2=%%Loop2%%C>> %ENTER%.BAT
ECHO IF "%%2"=="D" SET Loop2=%%Loop2%%D>> %ENTER%.BAT
ECHO IF "%%2"=="E" SET Loop2=%%Loop2%%E>> %ENTER%.BAT
ECHO IF "%%2"=="F" SET Loop2=%%Loop2%%F>> %ENTER%.BAT
ECHO SHIFT>> %ENTER%.BAT
ECHO IF NOT "%%2"=="" GOTO Loop2>> %ENTER%.BAT
ECHO :End>> %ENTER%.BAT

REM * Finally, let's USE all those batch files we just created
CALL GETPORT$.BAT

:DisplayAll
REM * Display the results (no FOR loop possible because of Win98)
ECHO.
ECHO COM1=%COM1%
ECHO COM2=%COM2%
ECHO COM3=%COM3%
ECHO COM4=%COM4%
ECHO LPT1=%LPT1%
ECHO LPT2=%LPT2%
ECHO LPT3=%LPT3%
ECHO.

REM * Clean up the mess
FOR %%A IN (%ENTER% %ENTER%$ GETPORT$) DO IF EXIST %%A.BAT DEL %%A.BAT
FOR %%A IN (DAT SCR) DO IF EXIST GETPORTS.%%A DEL GETPORTS.%%A
SET Loop2=

:End

Perl and Rexx both are very good at handling redirected standard input and output, so I combined this DEBUG trick with Perl's and Rexx's standard output handling to create GetPorts.pl and GetPorts.rex.

Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

How to use the following DEBUG scripts

To create any of the following utilities, first create the script using any text editor. You may type the scripts manually, but it is safer to copy and paste the scripts from this web page to your text editor.
Don't skip the blank lines, they are absolutely necessary.
Next, execute the following command:
DEBUG < MYSCRIPT.SCR
Substitute the appropriate file name for MYSCRIPT.SCR and make sure the script is in the current directory (or precede it with its full path).

A great way to use DEBUG scripts in batch files could once be found at McAfee's website.

In their SAVEMBR batch files the following trick is used:

debug < %0.BAT
goto around

a 300
mov ax,201
 .
 .
 .
rcx
200
w

q

:around

(Do not skip the empty lines, they are absolutely necessary)

The trick is that the first two lines and the last line will be ignored by DEBUG since they do not contain valid DEBUG commands.
This way the batch file can also serve as a DEBUG script, so you don't need two separate files.
This trick can be used for any DEBUG script.

And while at the subject of saving MBRs: Roger Layton's MBRWizard can do just that and restore it as well, plus more.

Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

Ask for user input

This script came from Microsoft Knowledge Base article Q77457: Accepting Keyboard Input in Batch Files.
It will create a 14 byte executable file named REPLY.COM which can be used to retrieve single key user input in batch files.


A 100
MOV AH,08
INT 21
CMP AL,0
JNZ 010A
INT 21
MOV AH,4C
INT 21

RCX
E
N REPLY.COM
W
Q

Though the Microsoft article states that the information applies to MS-DOS versions 3.1 through 6.22, the REPLY.COM utility works fine in Windows 2000's COMMAND.COM sessions too. Just use COMMAND /E:8192 /C to call the batch files that use REPLY.COM.

MS-DOS 6.* and Windows 9x don't need this utility, of course, since these DOS versions come with the CHOICE command.

 

Back to the top of this page...

 

Return a character's ASCII value

This script returns the ASCII value for any given character, like the Asc( ) function found in several scripting languages.
The script combines the 2 previous tricks and uses redirection to send a character to the utility created by DEBUG.


@GOTO :Batch

A 100
MOV AH,08
INT 21
CMP AL,0
JNZ 010A
INT 21
MOV AH,4C
INT 21

RCX
E
N ASC.COM
W
Q

:Batch
@ECHO OFF
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
IF "%˜1"=="" GOTO Syntax

PUSHD "%Temp%"
DEBUG < "%˜f0" >NUL
POPD

SET Chr=%˜1
ECHO.%Chr%| "%Temp%.\ASC.COM"
SET Asc=%ErrorLevel%
DEL "%Temp%.\ASC.COM"
SET Chr
SET Asc
EXIT /B %Asc%


:Syntax
ECHO.
ECHO Asc.bat,  Version 1.00 for Windows NT 4 / 2000 / XP
ECHO Return the ASCII number for the specified character, more or less
ECHO like many scripting languages' Asc( ) functions
ECHO.
ECHO Usage:  ASC.BAT  char
ECHO.
ECHO    or:  ASC.BAT  "char"
ECHO.
ECHO Where:  "char"   is the character whose ASCII value you want to know
ECHO                  (space or "interpreted" characters in doublequotes)
ECHO.
ECHO Notes:  This batch file cannot handle a single doublequote character
ECHO         (ASCII value 34) nor a carriage return (13), linefeed (10),
ECHO         ampersand (38), less than (60), greater than (62) or pipe (124).
ECHO         The result is displayed on screen and returned as "errorlevel".
ECHO         This batch file uses DEBUG to create a temporary utility ASC.COM.
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com

 

Back to the top of this page...

 

Display Grayscales

The next DEBUG script creates two tiny programs, GSON.COM and GSOFF.COM. GSON will set Gray Scale display ON, GSOFF will return to color display again. I have used these scripts many times to check if fancy color combinations would produce acceptable contrast on monochrome monitors.


A 100
MOV AX,1200
MOV BL,33
INT 10
MOV AH,0F
INT 10
MOV AH,00
INT 10
MOV AX,4C00
INT 21

N GSON.COM
R CX
14
W
A 100
MOV AX,1201

N GSOFF.COM
W
Q
Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

RESET

A reboot tool that works in any DOS environment, even Quarterdeck's QEMM or Desqview.
Create RESET.COM by copying the following script, RESET.SCR, and executing the command:
DEBUG < RESET.SCR
Make sure that RESET.SCR is in the current directory, or precede it with its full path.


N RESET.COM
A 100
MOV AX,0040
MOV DX,AX
MOV AX,1234
MOV [0072],AX
JMP F000:FFF0

RCX
10
W
Q
Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

LPTSTAT

I'm not sure where this script came from, most likely some PC magazine.
Typing the command LPTSTAT will display a message like this one, stating if your printer ports are ready to accept print jobs:

LPT1: printer not busy, no ack, paper, selected, no error.
LPT2: printer not busy, no ack, paper, selected, no error.
LPT3: printer not busy, no ack, paper, selected, no error.

N lptstat.com
E100 06 B8 40 00 8E C0 26 A1 08 00 3D 00 00 74 0D BA
E110 A5 01 B4 09 CD 21 BA 00 00 E8 31 00 26 A1 0A 00
E120 3D 00 00 74 0D BA AC 01 B4 09 CD 21 BA 01 00 E8
E130 1B 00 26 A1 0C 00 3D 00 00 74 0D BA B3 01 B4 09
E140 CD 21 BA 02 00 E8 05 00 B8 00 4C CD 21 B4 02 CD
E150 17 50 80 E4 80 BA BA 01 74 03 BA C9 01 B4 09 CD
E160 21 58 50 80 E4 40 BA DC 01 74 03 BA E5 01 B4 09
E170 CD 21 58 50 80 E4 20 BA EB 01 74 03 BA F3 01 B4
E180 09 CD 21 58 50 80 E4 10 BA FF 01 74 03 BA 0E 02
E190 B4 09 CD 21 58 80 E4 08 BA 19 02 74 03 BA 25 02
E1A0 B4 09 CD 21 C3 4C 50 54 31 3A 20 24 4C 50 54 32
E1B0 3A 20 24 4C 50 54 33 3A 20 24 70 72 69 6E 74 65
E1C0 72 20 62 75 73 79 2C 20 24 70 72 69 6E 74 65 72
E1D0 20 6E 6F 74 20 62 75 73 79 2C 20 24 6E 6F 20 61
E1E0 63 6B 2C 20 24 61 63 6B 2C 20 24 70 61 70 65 72
E1F0 2C 20 24 70 61 70 65 72 20 6F 75 74 2C 20 24 6E
E200 6F 74 20 73 65 6C 65 63 74 65 64 2C 20 24 73 65
E210 6C 65 63 74 65 64 2C 20 24 6E 6F 20 65 72 72 6F
E220 72 2E 0D 0A 24 65 72 72 6F 72 2E 0D 0A 24
RCX
12E
W
Q
Click to download the ZIPped sources
Dowload all DEBUG sources

 

Back to the top of this page...

 

 

CHKDRV

CHKDRV by Richard D. Benton and Robert L. Hummel was published in PC Tutor, February 28, 1989 (Volume 8 Number 4).
It is a small utility that lets a batch file test a floppy drive specification for various errors.
Click here for the ZIPped documentation with source, example batch file and the 48 byte program itself.


N CHKDRV.COM
A 100
OR   AL,AL   ;AL=0 if 1st drive valid
JZ   010A       ; or FF if invalid
MOV  AL,02      ;Return errorlevel=2
MOV  AH,4C      ;Terminate
INT  21         ; thru DOS
MOV  DL,[005C]  ;Get drive number+1
DEC  DL         ; subtract 1
JNS  0116       ; not negative if okay
MOV  AL,03      ;Return errorlevel=3
JMP  0106       ; exit
MOV  AH,04      ;Verify diskette fn
MOV  AL,01      ; 1 sector
MOV  CH,00      ; track 0
MOV  CL,01      ; sector 1
MOV  DH,00      ; side 0
INT  13         ; thru BIOS
JNC  012C       ;NoCarry=okay
MOV  AH,00      ;Reset diskette
INT  13         ; thru BIOS
MOV  AL,01      ;Return errorlevel=1
JMP  0106       ; exit
MOV  AL,00      ;Return errorlevel=1
JMP  0106       ; exit

RCX
30
W
Q
Click to download the ZIPped sources
Dowload all DEBUG sources

Back to the top of this page...

 

FIND-CD

This script by Charles Dye finds the drive letter of the CD-ROM drive.
See the Solutions found on alt.msdos.batch page for more details.


N FIND-CD.COM
E100 E8 "P"0 BA 96 2 B4 9 CD "!1"C9 B8 B 15 "1"DB CD "/"81
E114 FB AD AD "u"B 9 C0 "u"19 "A"81 F9 1A 0 "r"E8 BA A4 2 B4
E128 9 CD "!"BD B9 2 E8 D3 0 B8 1 "L"CD "!"80 C1 "A"88 E B4
E13C 2 88 E BF 2 BA B1 2 B4 9 CD "!"BD B9 2 E8 DC 0 B8 0 "L"
E151 CD "!"8B 1E 16 0 83 FB 8 "vY"8E C3 "&"A1 0 0 "="CD " u"
E166 "N&"A1 ","0 "H"8E C0 40 "&"8A E 0 0 80 F9 "Mt"5 80 F9
E17B "Zu7&;"1E 1 0 "u0&"8B 1E 3 0 83 FB 2 "r&"F6 C7 F0 "u!"
E194 B1 4 D3 E3 89 1E "^"0 A3 "\"0 8E C0 BE FF FF "F&"83 "<"
E1A8 0 "u"F9 "FF)"F3 89 1E "`"0 F8 C3 "1"C0 A3 "\"0 A3 "^"0
E1BD A3 "`"0 F9 C3 A1 "\"0 83 F8 0 "t4"8E C0 "1"DB "&9"1F 74
E1D2 "+1"F6 8A 2 "&:"0 "u"11 "F<=u"F4 "&"80 "8"0 "t"3 "F"EB
E1E9 F7 "F"F8 C3 "&"8B 0 "F<"0 "u"F8 80 FC 0 "t"4 1 F3 EB D5
E1FE "1"DB 89 DE F9 C3 E8 BB FF "r"1F 1 "6`"0 "&"80 "8"0 "u"
E212 7 "&"C7 7 0 0 F8 C3 "&"8B 0 "&"89 7 "C"83 F8 0 "u"F4 F8
E227 C3 F9 C3 A1 "\"0 83 F8 0 "tb"8E C0 "1"F6 89 F2 8A 2 "F"
E23B "<=u"6 9 D2 "u"2 89 F2 "<"0 "u"EF 9 D2 "tGB9"F2 "t"B2
E252 89 F1 E8 "k"FF A1 "`"0 "r"2 1 F0 "9"C1 "w2"E8 9F FF "1"
E266 DB "&9"1F "u"8 A1 "`"0 ")"C8 "H"EB C 8B 1E "^"0 A1 "`"0
E27B ")"C3 "K)"C8 A3 "`"0 "1"F6 8A 2 "&"88 0 "F<"0 "u"F6 "&"
E290 88 0 F8 C3 F9 C3 "CD-ROM drive $not found."D A "$is A:"
E2B6 D A "$CDROM=A:"0
RCX
1C2
W
Q
Click to download the ZIPped sources
Dowload all DEBUG sources

Back to the top of this page...

 

Daniel B. Sedory's excellent Guide to DEBUG contains extensive help on the DEBUG command and its usage.

Microsoft's DEBUG command syntax (or use the Windows XP Professional specific version)

Microsoft's article on How to Toggle the CAPS LOCK and NUM LOCK Keys.

Terry Newton's CHKINT.BAT is a batchfile that performs magic using the DEBUG command.
Check out his Batch Programming Stuff pages.

Many Debug Routines can be found at Computer Hope TM

 

Back to the top of this page...