ZP Location 216 ($D8) holds the ONERR Flag(s) it is non-zero whenever an
ONERR target is set. To reset just poke zero here. This is by the way also the recomended method to start any error handling so an Error within the errorhandler will not cause any deadlock.
So your Programm might look like this:
10 ONERR GOTO 100
20 POKE 0, 400 : REM INVALID VALUE WILL CAUSE ERROR
100 POKE 216,0
110 PRINT "ERROR!"
ONERR handler has some problems with the stack, as it leaves a bit garbage. Therefore additional code to fix this is needed.
If your programm doesn't have any open
FOR...NEXT items, or if you want to continue from the error handler without using
RESUME (and geting rid of whatever happened before), a simple stack reset by calling the stack initialization at
$F328 will do it:
120 CALL -3288
Continuing without will slowly fill up the stack each time an error occures, leting your programm crash after ~80 iteration in an uncatchable out of memory error.
Now if you want to use
RESUME from anywhere, you need to do a little stack magic, as the
ONERR code screws the stack pointer this is described in the Applesoft Basic Programming Reference Manual on page 136 (*1):
10 FOR I=768 TO 777 : READ X : POKE I, X : NEXT
20 DATA 104, 168, 104, 166, 223, 154, 72, 152, 72, 96
Establishes a machine-language routine at location 768, which can be used
in an error-handling routine. Clears up some
ONERR GOTO problems and
?OUT OF MEMORY ERROR messages. Use the command
CALL 768 in the error-
What is does is pulling the last return address of the stack (the one to return from this
CALL), correcting the stack to what the stack pointer was when the error occured and puting the return address there (*2) and returning. So when
RESUMEing the stack again looks the way it was when the error occured.
All of this works since Applesoft saves the stack pointer in location $F8 (248) at the beginning of every statement (*3), and copies it to location $DF (223) whenever an error is trapped by
Locations related to Error handling:
$D8 (216) ONERR flag - if >127 then an error has occurred
$DA/DB (218/219) Line number last error occured in (LN=PEEK(218)+PEEK(219)*256)
$DC/DD (220/221) ONERR error address
$DE (222) Error Code
$DF (223) Stack pointer at the time of an error
*1 - The BASIC code is sightly modified from the original
POKE pile, but produceing the same machine code.
*2 - To save you from pulling out your 6502 code tables (the weired decimal ones), here's the disassembly:
300: PLA * Pull Return Address (to BASIC) from Stack
303: LDX $DF * Get Stack Pointer of Error Line
305: TXS * Restore it
306: PHA * Restore Return Address
309: RTS * Return to BASIC
*3 - Jup, every statement, not line, as resume should also work with multi statement lines, shouldn't it?