Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #6125 > unrolled thread

Using Applesoft Internal Error Messages in a BASIC Error Handler

Started byBill Chatfield <billchatfield1@gmail.com>
First post2023-11-29 10:31 -0800
Last post2024-01-17 07:19 +0000
Articles 7 — 4 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  Using Applesoft Internal Error Messages in a BASIC Error Handler Bill Chatfield <billchatfield1@gmail.com> - 2023-11-29 10:31 -0800
    Re: Using Applesoft Internal Error Messages in a BASIC Error Handler fadden <fadden@fadden.com> - 2023-11-29 22:23 -0800
      Re: Using Applesoft Internal Error Messages in a BASIC Error Handler Bill Chatfield <billchatfield1@gmail.com> - 2023-11-30 07:14 -0800
        Re: Using Applesoft Internal Error Messages in a BASIC Error Handler Jerry Penner <jerry+a2@jpen.ca> - 2023-11-30 11:00 -0700
          Re: Using Applesoft Internal Error Messages in a BASIC Error Handler fadden <fadden@fadden.com> - 2023-11-30 13:23 -0800
          Re: Using Applesoft Internal Error Messages in a BASIC Error Handler Bill Chatfield <billchatfield1@gmail.com> - 2023-12-01 07:10 -0800
      Re: Using Applesoft Internal Error Messages in a BASIC Error Handler Michael J. Mahon <mjmahon@aol.com> - 2024-01-17 07:19 +0000

#6125 — Using Applesoft Internal Error Messages in a BASIC Error Handler

FromBill Chatfield <billchatfield1@gmail.com>
Date2023-11-29 10:31 -0800
SubjectUsing Applesoft Internal Error Messages in a BASIC Error Handler
Message-ID<010cc230-427a-485e-9a90-bcd294ba96b5n@googlegroups.com>
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)

[toc] | [next] | [standalone]


#6126

Fromfadden <fadden@fadden.com>
Date2023-11-29 22:23 -0800
Message-ID<95461d63-9b7a-47b8-b433-c31432d43d24n@googlegroups.com>
In reply to#6125
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

[toc] | [prev] | [next] | [standalone]


#6127

FromBill Chatfield <billchatfield1@gmail.com>
Date2023-11-30 07:14 -0800
Message-ID<249c977a-9c90-4b82-8996-16a65fc8a368n@googlegroups.com>
In reply to#6126
On Thursday, November 30, 2023 at 1:23:58 AM UTC-5, fadden wrote:
> 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

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!

[toc] | [prev] | [next] | [standalone]


#6129

FromJerry Penner <jerry+a2@jpen.ca>
Date2023-11-30 11:00 -0700
Message-ID<yubv89j5dfr.fsf@jpen.ca>
In reply to#6127
Bill Chatfield <billchatfield1@gmail.com> writes:

> On Thursday, November 30, 2023 at 1:23:58 AM UTC-5, fadden wrote:
>> 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
>
> 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!


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

[toc] | [prev] | [next] | [standalone]


#6130

Fromfadden <fadden@fadden.com>
Date2023-11-30 13:23 -0800
Message-ID<90b7cc73-782d-406d-bf15-8189c7ee00e2n@googlegroups.com>
In reply to#6129
On Thursday, November 30, 2023 at 10:00:27 AM UTC-8, Jerry Penner wrote:
> 1010 FOR X = 0 TO 1 STEP 0 

Nice. :-)

[toc] | [prev] | [next] | [standalone]


#6138

FromBill Chatfield <billchatfield1@gmail.com>
Date2023-12-01 07:10 -0800
Message-ID<0e9645e0-623e-4f3d-b868-e753aca4173an@googlegroups.com>
In reply to#6129
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.

[toc] | [prev] | [next] | [standalone]


#6302

FromMichael J. Mahon <mjmahon@aol.com>
Date2024-01-17 07:19 +0000
Message-ID<HOKdnXI0TYkR4jr4nZ2dnZfqnPWdnZ2d@giganews.com>
In reply to#6126
fadden <fadden@fadden.com> wrote:
> 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
> 

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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.sys.apple2.programmer


csiph-web