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.