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.
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.
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.
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 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:
and so on would be acceptable, but:
would be treated as duplicate labels.
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.
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.
|688 Attack Sub||Electric Arts||Newword||Newstar|
|Alley Cat||Syn Soft||Paperbase Deluxe|
|Ancient Art of War||Payroll||Micro-Aid|
|As Easy As 3.0||Trius||Professional File|
|Brief||Underware Inc||Pango||Sheng-Cheung L.|
|Cashbook||Freeway Ltd.||PC Calc||Buttonware|
|Charlie Chaplin US Gold||PC Man||Orion Software|
|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.|
|Dream Hiuse||Computer Easy||Planning Assistant||IBM|
|Easy Boot||Print Master|
|Elite||Firebird||Process Engineering Package|
|First Publisher||Prospero Pascal|
|Flight Simulator 2.13||Microsoft||PSI Trader|
|Flight Simulator 3||Microsoft||Quadralien||Logotron|
|Flowcharting||Patton & Patton||Savoir||Intelligent Software|
|Formwork||Analytex International||Space Commanders||Columbia|
|Framework II||Ashton Tate||Spell||Microsoft|
|French Teacher 1/2||Micro Tutor P.||Strip Poker||Artwork|
|Frogger||Strip Poker||Electric Arts|
|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|
|Infiltrator||Turbo Pascal 3.0||Borland|
|ISS Calendar Plus 2.2||Turbo Pascal 4.0||Borland|
|Leisure Suit Larry||VP Graphics||Paperback Soft|
|Masterfile PC||Wizz Ball||Ocean|
|Mandelbrot Generator||PD.||Where in the World is Carmen Sandiego|
|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|