Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using Applesoft Internal Error Messages in a BASIC Error Handler

60 views
Skip to first unread message

Bill Chatfield

unread,
Nov 29, 2023, 1:31:29 PM11/29/23
to
I need an ONERR GOTO error handler to CLOSE files or return to TEXT mode or various other situations. In the error handler, I can get the error code with PEEK(222). Error codes are a waste of time because it just forces the user to look up what the error code means. That is often very hard to do, especially for retro computing. Computers are much better than humans at looking up error messages corresponding to error codes. A good user interface should never display an error code. It should always display the error message corresponding to the error code.

I could write BASIC code in every BASIC program to convert the error code into and an error message. But that is silly when those messages are already in the Applesoft source code, which is here: https://github.com/cmosher01/Apple-II-Source/blob/master/src/system/applesoft/applesoft.m4

I've copied the error table itself below. How can I use this from BASIC? There is an error subroutine called ERROR, but I don't think it does an RTS and I don't understand how it works. It would be nice if there was a standard subroutine in the Applesoft code that I could CALL to display the error message. But at least I could use the error table to get the messages. But I'm not sure how to do that either. Any ideas?

; --------------------------------
; --------------------------------
; ERROR MESSAGES
; --------------------------------
ERROR_MESSAGES
ERR_NOFOR = *-ERROR_MESSAGES
LHASCII(`NEXT WITHOUT FOR')
ERR_SYNTAX = *-ERROR_MESSAGES
LHASCII(`SYNTAX')
ERR_NOGOSUB = *-ERROR_MESSAGES
LHASCII(`RETURN WITHOUT GOSUB')
ERR_NODATA = *-ERROR_MESSAGES
LHASCII(`OUT OF DATA')
ERR_ILLQTY = *-ERROR_MESSAGES
LHASCII(`ILLEGAL QUANTITY')
ERR_OVERFLOW = *-ERROR_MESSAGES
LHASCII(`OVERFLOW')
ERR_MEMFULL = *-ERROR_MESSAGES
LHASCII(`OUT OF MEMORY')
ERR_UNDEFSTAT = *-ERROR_MESSAGES
LOASCII(`UNDEF')
ASM_DATA($27)
LHASCII(`D STATEMENT')
ERR_BADSUBS = *-ERROR_MESSAGES
LHASCII(`BAD SUBSCRIPT')
ERR_REDIMD = *-ERROR_MESSAGES
LOASCII(`REDIM')
ASM_DATA($27)
LHASCII(`D ARRAY')
ERR_ZERODIV = *-ERROR_MESSAGES
LHASCII(`DIVISION BY ZERO')
ERR_ILLDIR = *-ERROR_MESSAGES
LHASCII(`ILLEGAL DIRECT')
ERR_BADTYPE = *-ERROR_MESSAGES
LHASCII(`TYPE MISMATCH')
ERR_STRLONG = *-ERROR_MESSAGES
LHASCII(`STRING TOO LONG')
ERR_FRMCPX = *-ERROR_MESSAGES
LHASCII(`FORMULA TOO COMPLEX')
ERR_CANTCONT = *-ERROR_MESSAGES
LOASCII(`CAN')
ASM_DATA($27)
LHASCII(`T CONTINUE')
ERR_UNDEFFUNC = *-ERROR_MESSAGES
LOASCII(`UNDEF')
ASM_DATA($27)
LHASCII(`D FUNCTION')
; --------------------------------

QT_ERROR LOASCII(` ERROR')
ASM_DATA($07,0)

QT_IN LOASCII(` IN ')
ASM_DATA(0)

QT_BREAK ASM_DATA($0D)
LOASCII(`BREAK')
ASM_DATA($07,0)

fadden

unread,
Nov 30, 2023, 1:23:58 AM11/30/23
to
The error code, passed in the X register, is just the index of the start of the error text (table at $d260). The error routine prints "?", then the error text, then "ERROR" and a bell (from $d350). If the code was running, it prints the line number, and does the Applesoft error handling.

So for example, SYNTAX ERROR is error code 16. $d260 + 16 = $d270, which is the string "SYNTAX". The last letter has the high bit set (Dextral Character Inverted format, or DCI), which is how the code knows when to stop printing characters.

Try this:

100 BASE = 53856: REM $D260
110 ERRCODE = 16: GOSUB 1000: REM SYNTAX ERROR
120 ERRCODE = 53: GOSUB 1000: REM ILLEGAL QUANTITY
130 END
1000 PTR = BASE + ERRCODE
1010 L = PEEK (PTR): IF L > = 128 THEN PRINT CHR$ (L - 128);: PRINT " ERROR": RETURN
1020 PRINT CHR$ (L);:PTR = PTR + 1: GOTO 1010

Bill Chatfield

unread,
Nov 30, 2023, 10:14:37 AM11/30/23
to
Wow, that makes a lot more sense in BASIC. I'm use to an ASCII code 0 terminator for strings, so setting the high bit is new to me. But it is more efficient because it saves one character. It's also more efficient than using a length byte at the beginning.

Yeah, this is just what I was looking for. This is so much better than an IF/THEN for each error code in every BASIC program.

I thought I was getting good at reading 6502 assembly, but the Applesoft source code is a little harder. I guess Bill Gates wrote it. Haha.

Thank you so much for translating!

Jerry Penner

unread,
Nov 30, 2023, 1:00:27 PM11/30/23
to
Here's another way to see the errors:

10 ONERR GOTO 1000
20 REM make line 30 have your error of choice
30 NEXT
1000 PTR = 53856 + PEEK (222)
1005 POKE 216,0
1010 FOR X = 0 TO 1 STEP 0
1020 C = PEEK (PTR): PTR = PTR + 1: X = C > = 128
1030 PRINT CHR$ (C - 128 * (C > = 128));
1040 NEXT
1050 PRINT " ERROR IN LINE " PEEK (218) + PEEK (219) * 256


Try different things for line 30:

]30 ASDF
]RUN

SYNTAX ERROR IN LINE 30

]30 NEXT
]RUN

NEXT WITHOUT FOR ERROR IN LINE 30

]30 X = 1 / 0
]RUN

DIVISION BY ZERO ERROR IN LINE 30

]30 POKE 0,256
]RUN

ILLEGAL QUANTITY ERROR IN LINE 30

--
--
Jerry jerry+a2 at jpen.ca

fadden

unread,
Nov 30, 2023, 4:23:22 PM11/30/23
to
On Thursday, November 30, 2023 at 10:00:27 AM UTC-8, Jerry Penner wrote:
> 1010 FOR X = 0 TO 1 STEP 0

Nice. :-)

Bill Chatfield

unread,
Dec 1, 2023, 10:11:00 AM12/1/23
to
On Thursday, November 30, 2023 at 1:00:27 PM UTC-5, Jerry Penner wrote:
> 1020 C = PEEK (PTR): PTR = PTR + 1: X = C > = 128
> 1030 PRINT CHR$ (C - 128 * (C > = 128));

Line 1030 Could be simplified, right?
1030 PRINT CHR$(C - 128 * X);

I also think the boolean for loop is very cool.

Michael J. Mahon

unread,
Jan 17, 2024, 2:19:52 AMJan 17
to
When writing the NadaNet ampersand extension for Applesoft, I needed a
“standard” way to signal a data packet error. Since there is no easy way to
extend the error message table, I chose to piggyback on an existing message
by choosing an error number that points to the last word in the “OUT OF
DATA” error, creating a “DATA” error message for NadaNet communication
errors. ;-)

--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
0 new messages