!pr3
Generalized MLI System Error Handling.....Bob Sander-Cederlof

The ProDOS Machine Language Interface (MLI) returns an error code in the A-register if anything goes wrong.  There are about 30 error codes, with values from $01 to $5A.  BASIC.SYSTEM reduces the number of different error codes to 18, calling many of them simply "I/O ERROR".  A nearly complete description of the error codes can be found in several references:

       "Apple ProDOS--Advanced Features", pages 68-70.
       "Beneath Apple ProDOS", pages 6-59 thru 6-61.
       "ProDOS Technical Reference Manual", pages 77-79.

When I am working with a new program which has a lot of MLI calls, it is helpful to have one central error handler to print out the error information.  Gary Little gives us such a subroutine on pages 66 and 67 of his "Apple ProDOS -- Advanced Features."  Gary's program prints the message "MLI ERROR $xx OCCURRED AT LOCATION $yyyy", where xx is the hexadecimal error code and yyyy is the address of the next byte after the MLI call.  You can mentally subtract 6 from the yyyy address to get the actual address of the JSR $BF00 that caused the error.

I assume you already know, if you are following me this far, that MLI calls take the form "JSR $BF00", followed by three data bytes.  The first data byte is the opcode, and the other two are the address of the parameter block for the MLI call:

       JSR $BF00
       .DA #OPCODE,PARAMETERS

It would be nice if the general error handler would give us a little more information.  First, I would like for it to print out the actual address of the JSR $BF00, rather than the return address.  Second, I would like for it to print out the three bytes which follow the JSR $BF00.

First, I recoded Gary's routine so that it took a lot less space.  (Littler than Little's!)  I shortened the message and tightened the code.  My version prints simply "AT" in place of "OCCURRED AT LOCATION."  Then I used a message printing subroutine to print the two text strings, rather than the two separate loops he used.  His took 83 bytes, mine only 56.


<<<listing of short version>>>


Next, I started adding the features I mentioned above.  The final program takes 92 bytes, which is 9 more than Gary's.  It displays the error message "MLI ERROR $xx AT $yyyy (op.addr)."

Lines 1080-1160 pick up the address MLI saved in the System Global Page, and sbtract six from it.  The result is stored into the LDA $9999,Y instruction at line 1200.  Horrors!  Self-modifying code!  The loop at lines 1180-1240 copies the three data bytes which follow the JSR $BF00 into the three variables at lines 1390-1410.

Lines 1260-1360 print out the error message.  This loop differentiates between ASCII characters (bit 7 = 1) and data offsets (bit 7 = 0).  The text to be printed is in lines 1430- 1550.  Note that I used the negative ASCII form for the text, and .DA lines for the data bytes which will be printed in hexa- decimal.  The expressions in those .DA lines compute an offset from the beginning of the subroutine, which will come out as a value less than $7F.  I also used the value 00 to terminate the entire message.  The $8D bytes are RETURN characters, to make sure the error message prints on a line by itself.
