10 REM > LocErrTest 0.10 15-Oct-2016 J.G.Harston
   20 REM Source and demo code
   30 :
   40 REM Implement LOCAL ERROR and ON ERROR LOCAL for 6502 BASIC
   50 REM Works within PROCs and FNs
   60 :
   70 :
   80 PROCerr_local(1)
   90 :
  100 REM PROC test:
  110 A%=-5
  120 ON ERROR PRINT"Global PROC error: ";:REPORT:PRINT" at ";ERL:IF ERR=17:PROCerr_local(0):END
  130 REPEAT
  140   A%=A%+1:PROCtest(A%):IF A%=-3:ERROR 100,"Hello"
  150 UNTIL A%=4:PRINT
  160 :
  170 REM FN test:
  180 A%=-5
  190 ON ERROR PRINT"Global FN error: ";:REPORT:PRINT" at ";ERL:IF ERR=17:PROCerr_local(0):END
  200 REPEAT
  210   A%=A%+1:B%=FNtest(A%):PRINT"Result=";B%:IF A%=-3:ERROR 100,"Hello"
  220 UNTIL A%=4
  230 :
  240 PROCerr_local(0)
  250 END
  260 :
  270 DEFPROCtest(A%)
  280 LOCAL ERROR:ON ERROR LOCAL:PRINT"Local PROC error: ";:REPORT:PRINT" at ";ERL:ENDPROC
  290 PRINT "100/";A%;"=";:PRINT ;100/A%
  300 ENDPROC
  310 :
  320 DEFFNtest(A%)
  330 LOCAL ERROR:ON ERROR LOCAL:PRINT"Local FN error: ";:REPORT:PRINT" at ";ERL:=FALSE
  340 PRINT "100/";A%;"=";:PRINT ;100/A%
  350 =TRUE
  360 :
  370 :
  380 REM PROCerr_local(1) to enable local error handler
  390 REM PROCerr_local(0) to restore default error handler
  400 REM Usage: LOCAL ERROR:ON ERROR LOCAL local error handler
  410 :
  420 DEFPROCerr_local(A%):IF HIMEM>&FFFF:ENDPROC         :REM Not 8-bit BASIC
  430 IF (?&FFF7 AND &DF)<>&4C:ENDPROC                    :REM Not 6502 BASIC
  440 IF A%=0:?&202=err_0%:?&203=err_0%DIV256:ENDPROC     :REM Restore default handler
  450 A%=!&202:REPEATA%=A%+1:UNTIL(!A%AND&8000FF)=&80004C :REM Find end of default handler
  460 DIM err_% 119:FOR B%=0 TO 1:P%=err_%:[OPT 0
  470   LDY #0:LDA (&FD),Y:CMP #16:BNE E%                 :\ Not Syntax error
  480   LDY &0A:DEY:LDA (&0B),Y:CMP #&EA:BNE E%:.C%       :\ Not LOCAL
  490   INY:LDA (&0B),Y:CMP #32:BEQ C%:CMP #&85:BNE E%    :\ Not LOCAL ERROR
  500   INY:STY &0A:INC &1FB                              :\ Continue after 'ERROR'
  510   LDA 4:SBC #8:STA 4:LDA 5:SBC #0:STA 5:LDY #7      :\ Make space on BASIC stack
  520   LDA &1F9:STA (&04),Y:DEY:.D%                      :\ Stack overlapped byte from PTRB
  530   LDA &12,Y:STA (&04),Y:DEY:CPY #3:BNE D%           :\ Push !&16
  540   LDA #0:STA (&04),Y:DEY:LDA #4:STA (&04),Y:DEY     :\ Push 'word'
  550   LDA #0:STA (&04),Y:DEY:LDA #&16:STA (&04),Y:BNE G%:\ Push &16
  560   .E%
  570   LDY #0:LDA (&16),Y:CMP #&EA:BEQ P%+5:.F%:JMP !&202:\ Not ON ERROR LOCAL
  580   LDA &16:ADC #0:STA &0B:LDA &17:ADC #0:STA &0C     :\ Continue after 'LOCAL'
  590 LDA #0:STA &0A:.G%:LDX #&F5:TXS:JMP A%!1:]:NEXT   :REM Restore stack and jump to execution loop
  600 ?&202=err_%:?&203=err_%DIV256:err_0%=F%!1
  610 ENDPROC
  620 :