• Please review our updated Terms and Rules here

ERRORLEVEL using batch files

kc8eyt

Experienced Member
Joined
Aug 7, 2020
Messages
323
Does anyone know of a site that contains DOS commands that were specifically used in DOS batch files to return ERRORLEVEL values?

For instance, FINDRAMD.COM that is included on WIN95/98 CDs returns an ERRORLEVEL value corresponding to the drive letter of a RAM drive if one is present. FINDCD.COM is another one I've used in the past that returns an ERRORLEVEL value corresponding to the drive letter of a CDROM drive if one is present.

Specifically, I want to build a batch file that when run returns and reacts to various computer information such as:

- Machine Manufacturer/Model (IBM, Tandy, NEC. etc..)
- CPU installed (8088/86, NECV20/30, 286, 386, etc..)
- Total conventional RAM
- Total extended RAM (may be difficult/impossible without EMS/XMS driver installed)
- CMOS clock present/address
- Number/type of floppy drives
- Number/size of HDDs
- etc...

Even a program that returns these values into a file (text, CSV, etc..) would be useful as I could write a program that then reads that file and executes batch processes accordingly.

It's been many years since I've done any low-level coding in PASCAL or ASM on x86 hardware and I would rather not open that can of worms again if I can avoid it.

Any pointers on where to start would be most appreciated.
 
In Pascal it is quite simple: use the HALT(xx) instruction where xx is a number from 0 to 255. That number is copied into ERRORLEVEL by DOS. In ASM it is the value hold by register AL the moment the program quits to DOS.
 
Even a program that returns these values into a file (text, CSV, etc..) would be useful as I could write a program that then reads that file and executes batch processes accordingly.
Or maybe multiple programs. For example, let us suppose that there is a DOS program named CPUID.COM that displays the CPU type to screen. You could redirect its output to a text file (i.e. "C:\>CPUID > CPUID.TXT")
 
In Pascal it is quite simple: use the HALT(xx) instruction where xx is a number from 0 to 255. That number is copied into ERRORLEVEL by DOS. In ASM it is the value hold by register AL the moment the program quits to DOS.

Thank you for the reply. Yes, I know how to return the ERRORLEVEL in a few languages, but what I'm looking for are small .COM or .EXE files that return information in the form of ERRORLEVEL (or even an environment variable would work for that fact).

For instance, when FINDRAMD.COM is executed the ERRORLEVEL is set to a value corresponding to the drive letter of any RAM drive found. That behavior would be ideal.

As modem7 pointed out I may be able to redirect output to a file, but that would require me to write a program (a simple program I realize) that would need to parse a text file for information.

Over the years (especially back in the Compuserve days) It was quite common to find and use these types of little batch file enhancement programs. Shame on me for not saving them over the years as I should have.
 
As modem7 pointed out I may be able to redirect output to a file, ...
I am glad you used the word "may". I remember starting to write programs using Turbo Pascal and later discovering that for those programs, DOS output redirection to a file did not work. It turned out that the behaviour was a result of me using Turbo Pascal's CRT unit, and some commands were required to change the behaviour.

Code:
{ **********************************
  *                                *
  *    M A I N    P R O G R A M    *
  *                                *
  ********************************** }

BEGIN

{ The CRT unit normally directs screen output to the BIOS or hardware.
  Cancel that so that screen output goes to DOS
  This will allow the user of this program to perform redirection of this program's output to a file or printer. }
assign(Input,''); reset(Input);
assign(Output,''); rewrite(Output);
 
kc8eyt said:
- Machine Manufacturer/Model (IBM, Tandy, NEC. etc..)

While not every manufacturer gives that information, there are several that do it. At https://www.seasip.info there's a lot of useful information about this regard and how to detect some important old PCs.

For example, here's some code I wrote to detect Compaq computers based on the info I found at seasip. I wrote it in C (specifically Turbo/Borland C) but I guess it would not be too much complicated to translate it to Pascal:

Code:
bool Compaq()
{
    /* Detecting a Compaq PC clone, such as the gorgeous Compaq Portable,
    or the remarkable Compaq Deskpro (faster and cheaper than the IBM PC/XT)
    */

    char compaqString[6];

    compaqString[0] = peekb (0xF000,0xFFEA);
    compaqString[1] = peekb (0xF000,0xFFEA+1);
    compaqString[2] = peekb (0xF000,0xFFEA+2);
    compaqString[3] = peekb (0xF000,0xFFEA+3);
    compaqString[4] = peekb (0xF000,0xFFEA+4);
    compaqString[5] = peekb (0xF000,0xFFEA+5);

    /* In C, 'if (compaqString == "COMPAQ")' has no effect
    For string manipulation, comparison, etc. always use the funcions in string.h */
    if (strcmp (compaqString, "COMPAQ") == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

And here's a snippet of asm code to detect a Tandy 1000 or a PCjr:

Code:
PCjr equ 9
Tandy equ 10

@@is_PCjr:

mov ax,0ffffh
mov es,ax
mov di,000eh ; F000:FFFEh:  System Model ID
mov al,0fdh    ; FDh for PCjr
cmp es:[di],al
jne @@is_Tandy
mov ax,PCjr
jmp @@done

@@is_Tandy:

mov al,0ffh                     ; Again F000:FFFEh. This time we check for FFh. It stands for IBM PC
cmp es:[di],al                ; but it's also used by Tandy 1000s, so at this point we can discard
jne @@begin_detect      ; the non-1000 Tandys, which return another value.
mov ax,0fc00h
mov es,ax
xor di,di
mov al,21h
cmp es:[di],al                 ; FC00:0000 has 21h as a value in Tandys, so this discards IBM PC and compatibles
jne @@begin_detect
mov ax,Tandy                  ; Yes, it's a Tandy 1000
jmp @@done
- CPU installed (8088/86, NECV20/30, 286, 386, etc..)

I'm attaching a callable procedure, written in assembly, paired with a calling program in Pascal, named WHICHCPU 0.50, by Michael Holin. I tested it in 86Box with several machines ranging from 8088 to Pentium and it's quite accurate (I only got a Rapidcad false positive, provided only by the Pascal code, and several DX/SX were mismatched, but I have no way to know if it's a program issue or emulator's. Except for that, the program guessed everything right).

View attachment wcpu050.zip

- Total conventional RAM

That's easy: call Int 12h and pick the result in Kb from AX

- Number/type of floppy drives
- Number/size of HDDs
- etc...

There are several int 21h functions that can be useful to get sys info: http://bbc.nvg.org/doc/Master 512 Technical Guide/m512techb_int21.htm

You can also obtain several info from the BIOS data area: https://stanislavs.org/helppc/bios_data_area.html
 
I just saw that WhichCpu already does what you want without any modification. When running:

whichcpu ?

shows a help screen that states that running

whichcpu cpu

returns a cpu code as errorlevel for using with batch files. On whichcpu ? you get the details (for instance, 8088 is 0, 8086 is 1 and so on).
 
I just saw that WhichCpu already does what you want without any modification. When running:

whichcpu ?

shows a help screen that states that running

whichcpu cpu

returns a cpu code as errorlevel for using with batch files. On whichcpu ? you get the details (for instance, 8088 is 0, 8086 is 1 and so on).

Thank you for the heads-up on WhichCPU! The other programming info is valuable as well if I need to go that route.
 
Back
Top