Classic Computer Magazine Archive COMPUTE! ISSUE 25 / JUNE 1982 / PAGE 153

A Subroutine Aid To Debugging Atari BASIC

Mark Thomas Greene, Ph.D.
Columbus, OH

Tired of searching through your BASIC manual, 850 manual, and DOS manual to find out what ERROR 175 means? This program should end that frustration once and for all.

The subroutine acts as a BASIC diagnostic that: a. describes in some detail what went wrong, b. indicates the line at which the error occurred, and c. lists the immediate environment of the problem line.

Here's how it works:

Line: 0 TRAP 30000

This causes the system to run the debugging routine whenever an error occurs. The subroutine should be stored on disk via a LIST command (e.g. L."D:ERRORS.LST") so that it may be merged with any program by means of an ENTER command (e.g. E."D:ERRORS.LST"). Use of line 0 and lines 30000 through 31173 makes it easy to avoid overwriting an existing program with "ERRORS" and vice-versa.

Any time a different TRAP is needed, TRAP 30000 should be reset as soon as possible.

Line: 30010? ""

This statement clears the screen.

Line: 30020 STPLN1 = PEEK (187) : STPLN2 = PEEK (186)

This statement retrieves the two byte representation of the line number at which the error occurred.

Line: 30030 ERR$ = "31"

We're going to build a line number beginning with thirty-one thousand and ending with the error number.

Line: 30040 IF PEEK(195) < 100 THEN ERR1$ = ‘0’

Line: 30050 IF PEEK (195) < 10 THEN ERR 1$ =‘00’

These lines create place holders in front of the error number if the error number is less than three digits long. Line 30050 overrides 30040 if the error number [PEEK (195)] is a single digit.

Line: 30060 ERR$(LEN(ERR$) + 1) = ERR 1$ This line adds the appropriate number of zeros to ERR$ ('31'). If the error number is three digits long it will have no effect.

Line: 30070 ERR$(LEN(ERR$)+ 1) = STR$ (PEEK (195)

This line adds the error number to our string so that we have a five digit string beginning with ‘31’ and ending with the error number.

Line: 30080 GOSUB VAL(ERR$)

This statement converts our string to a five digit number. GOSUB then executes the subroutine of that number. Each subroutine is contained entirely by that line. The subroutine prints the description unique to that error and then RETURNS to line 30080.

Program 1.

DIM Error: Attempt to reDIM or, DIM > 32767 or, reference out of DIMed size or not DIMed.

The error occurred at line 3345.

3330   DB$ (LEN (DB$) + 1 ) = CHR$ (155)
3340   DB$ (LEN (DB$) + l ) = STR$ (LVL)
3345   DB$ (LEN (DB$) + 1) = ANS$
3350   DB$ (LEN (DB$) + 1) = CHR$ (155)
3360   DB$ (LEN (DB$) + 1) = BONUS$

Program 2.

Readers with cassette systems can use this program by inserting a blank tape in the 418 recorder,
        and rewinding to start. Press PLAY and RECORD, then enter:
LIST "C:"
and then press <RETURN> twice. To add this program to a program you already have in memory, insert your"Errors" tape, rewind, press PLAY, arid enter:
        ENTER "C:"
and press >RETURN< twice. The program will be merged with yours. Remember that the routine
        uses line zero, so if you have a 1ine zero in your program, it will be replaced. Also,
        you may have to change any TRAP 40000 or TRAP 32768 statements to TRAP 30000.
0 TRAP 30000
30000 REM ********ERROR TRAP**********
30005 DIM ERR$(10), ERR1$(10)
30010 ? "{CLEAR}"
30020 STPLN1 = PEEK(187) = STPLN2 = PEEK(186)
30030 ERR$ = "31"
30040 IF PEEK(195) > 100 THEH ERR1$ = "0"
30050 IF PEEK(195) > 10 THEN ERR1$ = "00"
30060 ERR$(LEN(ERR$) + 1) = ERR1$
30070 ERR$(LEN(ERR$) + 1) = STR$(PEEK(195))
30080 GOSUB VAL(ERR$)
30090 POKE 195, 0
30095 STPLN = 256 * STPLN1 + STPLN2
30100 ? "The error occurred at line " ; STPLN; "."
30110 LIST STPLN - 20, STPLN + 28
30120 END
31002 ? "Not enough memory to store statement or the new variable name or to DIM a new
        string variable." : RETURN
31003 ? "A value expected to be a + integer isn't : a value expected to be in a specific range
        isn't. " : RETURN
31004 ? "Too Many variables : A maximum of 128 variable names is allowed." : RETURN
31005 ? "String Length Error : Attempted to store beyond the DIMensioned string length." : RETURN
31006 ? "Out of Data Error : READ statement requires more data than suppiled by data
        statement(s)." : RETURN
31007 ? "Number Greater than 32767 : Value is not a positive integer or is greater
        than 32767." : RETURN
31008 ? "Input Statement Error : Attempted to input a non-numeric value into a numeric variable." : RETURN
31009 ? "DIM Error : Attempt to reDIM or, DIM > 32767 or, reference out of DIMed size or not
        DIMed." : RETURN
31010 ? "Argument Stack Overflow : There are too many GOSUBs or too big an expression." : RETURN
31011 ? "Attempt to divide by zero or refer to a number < 10E98 or > 10E - 99.":RETURN
31012 ? "Line Not Found : A GOSUB, GOTO or THEH referenced a non-existant 1ine number." : RETURN
31013 ? "No Machine FOR Statements : Nested FOR/NEXT statements do not match or no FOR
        statement." : RETURN
31014 ? "Line too long: The Statement is too long or complex for basic to handle." : RETURN
31015 ? "A NEXT or RETURN was encountered and the GOSUB or FOR has been deleted since the
        last RUN." : RETURN
31016 ? "RETURN Error : A RETURN was encountered without a matchine GOSUB." : RETURN
31017 ? "Garbage Error : Execution of bad RAM bits was attempted. Usually a hardware or
        POKE problem." : RETURN
31018 ? "String does not start with a valid character, or string in VAL statement is not
        a numeric" : RETURN
31019 ? "LOAD Program too Long : Insufficient RAM to complete 1oad." : RETURN
31020 ? "Device number larger than 7 or equal to 0." : RETURN
31021 ? "LOAD File Error: Attempt to LOAD a non-LOAD file. " : RETURN
31128 ? "BREAK Abort : User hit |BREAK| key during I/O operation." : RETURN
31129 ? "IOCB already open." : RETURN
31130 ? "Nonexistent device specified." : RETURN
31131 ? "IOCB Write Only : READ command to a write only device." : RETURN
31132 ? "Invalid Command : The command is invalid for this device." : RETURN
31133 ? "Device or File not Open : No OPEN specified for this device." : RETURN
31134 ? "Bad IOCB Number : Illegal device number." : RETURN
31135 ? "IOCB Read Only Error : WRITE command to a read-only device." : RETURN
31136 ? "EOF : End of File has been reached." : RETURN
31137 ? "Truncated Record : Attempt to read a record longer than 256 characters." : RETURN
31138 ? "Device Timeout : Device doesn't respond." : RETURN
31139 ? "Device NAK : Garbage at serial part or bad disk drive." : RETURN31140 ? "Serial bus input framing error. " : RETURN
31141 ? "Cursor out of range. " : RETURN
31142 ? "Serial bus data frame overrun." : RETURN
31143 ? "Serial bus data frame checksum error." : RETURN
31144 ? "Device Done Error : (invalid ‘done’ byte) : Attempt to write on a
        write- protected diskette." : RETURN
31145 ? "Read after write compare error (disk handler) or bad screen mode handler." : RETURN
31146 ? "Function not implemented in handler." : RETURN
31147 ? "Insufficient RAM for operating in selected graphics mode." : RETURN
31150 ? "Port Already Open: Attempt to OPEN an RS-232 port already open through another IOCB." : RETURN
31151 ? "Concurrent I/O mode not enabled : Aux1 bit 0 not set for XIO 40. " : RETURN
31152 ? "Illegal User Supplied Buffer : Buffer length and/or address inconsistent in concurrent
        I/O mode." : RETURN
31153 ? "Active Concurrent I/O Error : Attempt to perform RS-232 I/O while concurrentmode
        I/O active." : RETURN
31154 ? "Concurrent Mode not Active : Concurrent I/O mode must be activated in order toperform
        INPUT or GET." :RETURN
31160 ? "Drive number error."
31161 ? "Too many OPEN files (no sector buffer avai1able)]" : RETURN
31162 ? "Disk full (no free sectors)]" : RETURN
31163 ? "Unrecoverable system data I/O error." : RETURN
31164 ? "File Number Mismatch : Links on disk are messed up." : RETURN
31165 ? "File Name Error." : RETURN
31166 ? "POINT data length error." : RETURN
31167 ? "File locked." : RETURN
31168 ? "Command invalid (special operation code)." : RETURN
31169 ? "Directory full (64 files)." : RETURN
31170 ? "File not found." : RETURN
31171 ? "POINT invalid.": RETURN
31172 ? "Illegal Append : DOS 1 cannot append to a DOS 2 file." : RETURN
31173 ? "Bad Sectors at Format Time : Disk drive found bad sectors while formatting a diskette." : RETURN

Line: 30090 POKE 195,0 This statement resets the error number to zero.

Line: 30095 STPLN = 256* STPLN1 + STPLN2

Line 30095 converts the two byte "binary" line number to its decimal equivalent. (See Line 30020.)

Line: 30100 ? "The error occurred at line"; STPLN; "."

This line prints the decimal value of the error line.

Line: 30110 LIST STPLN-20, STPLN + 20

This statement prints the statements immediately before, after and including the error.

The result of such an error is presented in Program 1.

Now you say, "This system will work for errors encountered during program execution but what about errors in direct mode?" Aha! It can still save trips to the manuals. As long as 'ERRORS' is loaded in RAM, just type GOSUB 3 1 xyz where xyz is your error number, and a description of your latest error will appear. Disregard the information about line numbers.

I have loaded "ERRORS" on to my master diskette so that it is automatically transferred to each disk along with the DOS programs whenever I create a new workdisk by duplicating the master.

The errors listed here may be changed or expanded to adapt to your hardware and software (e.g., the line printer and word processor software). A similar method may be used to trap the ASSEMBLER errors replacing BASIC errors one through nineteen.

Program 2 is the complete program.