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
30 END
100 POKE 216,0
110 PRINT "ERROR!"
Caveats
The 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 GOSUB
or 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-
handling routine."
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 RESUME
ing 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 ONERR
.
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
301: TAY
302: PLA
303: LDX $DF * Get Stack Pointer of Error Line
305: TXS * Restore it
306: PHA * Restore Return Address
307: TYA
308: PHA
309: RTS * Return to BASIC
*3 - Jup, every statement, not line, as resume should also work with multi statement lines, shouldn't it?
ONERROR GOTO 0
for this, but it's been a long time and I've never really used AppleSoft BASIC.