Previous | Index | Next

Master 512 Forum by Robin Burton
Beebug Vol. 8 No. 6 November 1989

As promised, this Forum includes a list of packages known to run with Problem Solver's assistance. This is at the end of the Forum for convenience, but first to more 'traditional' Forum matters.

The first snippet is that I understand Acorn no longer charge for the DOS Plus 2.1 upgrade. Send your original 1.2 discs to Acorn Computers Ltd., Customer Services, Fulbourn Rd., Cherry Hinton, Cambridge CB1 4JN.

BATCH FILES AGAIN

It's a couple of months since we looked at the 'PATH' command, so I thought it was time I kept my promise to cover batch files again. We also looked at the 127 byte buffer used to hold the command tail, the parameters entered when a program is first loaded. This time we'll be looking at precisely the other end of proceedings.

In particular, I've had several letters requesting information on 'ERRORLEVEL', a point missed entirely or poorly explained in so many DOS guides (could it be that the authors aren't sure either – surely not!). At the same time we'll investigate a little more how DOS programs work.

IF ERRORLEVEL

Most users are aware of this batch file construct, and how to include the relevant line in a batch file, but equally, many don't know how to use it. This is because good explanations of what 'ERRORLEVEL' means and how it works are few and far between. In fact it's quite simple, if the information is gathered together and given with an explanation, instead of being scattered throughout reference books with an assumption that you can make the connections yourself, as is too common.

The main point to appreciate is how programs terminate in DOS. Just like other DOS facilities and functions, if performed legally, this involves calling an interrupt. There are other, 'dirtier' methods of terminating, and there is a range of termination functions, but for illustration we'll confine ourselves to one legal technique. We'll consider the sort of program that loads, carries out one or two specific operations and then disappears, leaving its memory free for further use.

Most of the programs that operate like this are utilities, and are most frequently 'COM' files, (or 'CMD', but more in a moment about these). However, the principle applies equally to 'EXE' files, whether these are linked from object modules originally written in assembler, or compiled from high level languages like 'C', Basic, Pascal or whatever. Any program which, on final termination, can report overall success or failure to DOS is therefore included. What this topic doesn't include are user errors handled entirely within applications.

Let's take for example a program which reads a file, performs a specific operation (or several) and then terminates. Examples of this type of program are the 512 'FIND.EXE' and 'SORT.EXE' utilities included on two recent BEEBUG discs (Vol.8 Nos.4 & 5) – get the back-issues out if you missed them. These programs take a filename and one or more optional parameters when they are called from the command line, but then execute without further user input until completion. Of course, if you call the program manually and the parameters are invalid, you are informed at once and you simply re-enter them correctly.

On the other hand, if the program were to be called by commands contained in a batch file you wouldn't be given the opportunity to reenter the parameters correctly. In any case failure might have nothing to do with entered parameters, it might be a file error, the wrong disc in a drive and so on.

More importantly, if left to itself, a batch file will continue to execute subsequent instructions, probably quite pointlessly and possibly even dangerously if an earlier process has failed. Of course, you can always sit and watch the screen, issuing a hasty Ctrl-C when you spot a problem, but as usual there's a better way.

PROGRAM TERMINATION

To fully understand how this better method (i.e. ERRORLEVEL) works, we need to look at DOS program termination.

If a program is written correctly, that is according to accepted DOS standards, on termination it should set a condition which can be detected by the program or batch file that called it. Primarily this condition (a numeric value) indicates whether the program was completely successful or not, but by varying the value it can also be used to identify the seriousness and type of any error.

Using machine code in our example, here's how it's done. By the way, this applies only to DOS. Remember that in DOS Plus we have both CP/M (CMD) and MS/PC-DOS (COM) programs. While CP/M has a similar facility, it doesn't work with 'ERRORLEVEL'. CP/M return codes can only be obtained by a calling program, not by batch files, and they also differ in that they are two bytes, not one as in DOS.

We'll ignore 'terminate and stay resident' functions such as INT 21h function 31h or the now redundant INT 27h, as used by 'pop-ups' and programs like RAM discs. In the main, programs don't stay resident if they encounter errors (although a return code is also passed with INT 21h f31h).

For a permanent exit, programs can terminate using one of two interrupt 21h functions, 0 or 4Ch. INT 21h incidentally, is also commonly referred to as the general function despatcher.

For those not too interested in the internals of DOS or 80186 programming, INT 21h (which simply means operating system call number &21) can be regarded as a general purpose OS call combining most of the facilities provided in the BBC micro by OSBYTE, OSWORD and the filing system calls. Registers (and sometimes parameter blocks) are set up and the call is made with a number to identify it.

Other interrupts exist for more specialised purposes, but INT 21h provides most of the facilities users require. It is used for console line or character input/output, disc (directory, sector, file and record) operations, program and memory management as well as for miscellaneous tasks like reading or setting the system's clock or date. (It even includes functions for intercepting and re-directing the interrupt vectors!)

In order to end execution, a program can make a call to one of three other interrupts, INT 20h, 27h or 21h using either function 0 or function 4Ch.

INT 21h function 0 is of no use if we want to return a code (oddly enough called the return code) to indicate success or failure, because it doesn't provide this capability. Interrupt 20h is also a program termination call, but its use is not recommended either. In fact these two (and INT 27h) are all left-overs from DOS version 1, and are retained purely for compatibility with early software. For all current purposes these calls are obsolete and shouldn't be used.

This leaves INT 21h function 4Ch, which has been the recommended method of final program termination since DOS version 2 appeared, and it still is. Here's a short section of source code which will show how it's called in a program. Several other 'bits' would be needed for assembly, but this extract is enough to illustrate the point we're concerned with.

; Constant declarations

G_F_D       equ 021h   ; INT 21h
TERMINATE   equ 04Ch   ; with return code

; Program code
.....                  ; This is the main
.....                  ; body of the program

exit:                  ; Common exit point
mov al, [Return_Code]B ; The final result
mov ah, TERMINATE      ; Set up terminate...
int G_F_D              ; and do it!

; Variable declarations

Return_Code db 0       ; Default zero

The constant declarations at the top simply assign hex values 21h and 4Ch to the two names given. Between these and the label 'exit:' the main functions of the program would be coded, including suitable displays to advise about progress during execution.

In this example, I've assumed that whatever happens in the main code, the program always jumps to 'exit:' to terminate. The variable declared as 'Return_Code' at the bottom of the source has a default value of zero, which means successful execution. This is pre-set when the code is assembled, but if during execution the program detected an error the value would be changed.

When execution arrives at 'exit:' the value now in 'Return_Code' is moved into byte register AL, which is where INT 21h function 4Ch expects the return code to be placed. The next line moves the value 4Ch into byte register AH to identify the interrupt function required, and the last line, 'int G_F_D', calls interrupt 21h, which actually ends the program.

Within this call all file buffers are flushed (i.e. pending output records are written to disc), all files are closed, and the program's memory is freed for re-use. A few other things happen, which needn't concern us here, except to say that control then passes back to the original caller. This might be another program, a batch file or you, by means of the DOS command line.

If the caller was a program, the return code can be obtained by means of INT 21h function 4Dh, which will pass the return code back to the calling program in register AL. The program can then decide what action to take depending on the value returned.

If the caller was a batch file the return code is made available via the pseudo-variable 'ERRORLEVEL'. Again, by a suitable line in the batch file, subsequent execution can be controlled depending on the value returned (see below).

If you call a program manually from the command line, the return code should be irrelevant, because the program should have advised you of success or otherwise by a simple confirmation or an error message.

Interestingly, however, you can still enter an 'IF ERRORLEVEL' statement manually and it, will work normally (with, of course, the exception of jumping to a label – I hope I needn't explain that!). The format of the command, either manually or in a batch file is:

IF ERRORLEVEL <value> <command>

where <value> is a number between 0 and 255 (although higher values can be entered), and <command> is any DOS command except one which is itself conditioned by another 'IF'.

Note that there's no '=' sign. If you include one, you'll get an error. The most useful <command> of course is 'GOTO label', which allows you to change the execution route. A label can be any string ending with a colon, but only the first 8 characters are significant. For example:

LABEL1:
LABEL2:

and so on would be acceptable, but:

LABELNUMBER1:
LABELNUMBER2:

would be treated as duplicate labels.

IMPORTANT POINTS

The reason that this pseudo-variable is called 'ERRORLEVEL', rather than 'ERRORCODE' or something else is most important. You must remember that 'IF ERRORLEVEL' performs a 'greater than' test, not an equality test. In other words:

IF ERRORLEVEL 4 <command>

actually means, "If the return code is equal to OR GREATER than 4, execute the command".

This means that when you test for each of several results, you MUST test for the higher values first. Put another way, a return code of 255 (the standard 'general failure' code) always produces a 'TRUE' result no matter what value you test it with up to 255.

A side-effect of this is that if <value> in the statement is zero, i.e.:

IF ERRORLEVEL 0 <command>

<command> is ALWAYS executed. A value of zero in this statement is therefore utterly meaningless, since it always gives 'TRUE' for any value, including zero. The easiest way to remember this is that you can't directly test for success using 'ERRORLEVEL', only for failure.

PROBLEM SOLVER APPLICATIONS LIST

This list is compiled from information supplied by Shibumi Soft and 512 Forum readers. Where version numbers were available they are provided, but where omitted users should exercise care.

Title Publisher   Title Publisher
688 Attack Sub Electric Arts     Newword Newstar
Adventure Writer PD. Osbit  
Alley Cat Syn Soft Paperbase Deluxe  
Ancient Art of War   Payroll Micro-Aid
As Easy As 3.0 Trius Professional File  
Autoroute NextBase Professional Plan  
Brief Underware Inc Pango Sheng-Cheung L.
Bushido   PC Draw Micrografix
Cashbook Freeway Ltd. PC Calc Buttonware
Charlie Chaplin US Gold        PC Man Orion Software
Chiwriter Horstman PC Outline  
Cyrus Chess   PC Storyboard IBM
Dancad 3D   PC Tools Deluxe 4.11 Central P Soft
Dark Side   PC Tutor  
DBase III+ Ashton Tate (1.2) PC File+ PD.
Deluxe Paint 2   PC File 3 PD.
Digger Windmill Soft Pipedream Colton
Digita Diary   Pitstop Epyx
Dream Hiuse Computer Easy Planning Assistant IBM
Driller   Powermenu S.W.
Droege PD. Printshop Pixellite
Easy Boot   Print Master  
Elite Firebird Process Engineering Package       
Falcon Spectrum Professional Write  
Fast Graph   Prolog2 I.B.M.
First Publisher   Prospero Pascal  
Flight Simulator 2.13 Microsoft PSI Trader  
Flight Simulator 3 Microsoft Quadralien Logotron
Flodraw Dabs S.W. Reflex Borland
Flowcharting Patton & Patton Savoir Intelligent Software
Fontasy Prosoft Script IBM
Formtool Bloc Developments Sorceror Infocom
Formwork Analytex International Space Commanders Columbia
Framework II Ashton Tate Spell Microsoft
Freefile S.W. Starglider Firebird
Freelance Graphic Communications      Starquake Mandarin
French Teacher 1/2 Micro Tutor P. Strip Poker Artwork
Frogger   Strip Poker Electric Arts
FSD IBM Symphony 1.2 Lotus
Galaxy 2.3 Ominiverse Tas+ Database Megatech
Game of Life Scientific G. Teed-Off 3.0 S.W.
German Teacher 1/2 Micro Tutor P. Tennis  
Graphing Assists IBM Test Drive Mastertronic
Grime S.W. Topcopy Plus Innova Soft
Homebase Brown Bag Software Turbo Basic Borland
How's Your Heart   Turbo C 1.5 Borland
Impact   Turbo Calc Borland
Infidel Infocom Turbo Debug Borland
Infiltrator   Turbo Pascal 3.0 Borland
ISS Calendar Plus 2.2   Turbo Pascal 4.0 Borland
Jet   Turbo Prolog Borland
Leisure Suit Larry   VP Graphics Paperback Soft
Life Forms S.W. War Broderbund
Masterfile PC   Wizz Ball Ocean
Mandelbrot Generator PD. Where in the World is Carmen Sandiego
Microsoft Chart Microsoft Word Microsoft
Mindreader 2.0 Brown Bag Software Wordperfect 4.2 Wordperfect Corp.
Mini Office Pers.   World Class Golf  
Mix C Compiler Analytical Engineering World Class Leaderboard Access/US Gold
Mix C Editor/Trace Analytical Engineering World Tour Golf Electric Arts
Newsmaster 2   Yes Chancellor  
       
PD. = Public domain    
S.W. = Shareware    

Previous | Index | Next

About the Master 512 | Bibliography