Firstly, here's the docs:
http://amforth.sourceforge.net/TG/AVR8.html#interrupts
http://amforth.sourceforge.net/TG/recipes/Interrupt-Critical-Section.html
Source files:
amforth-6.9/avr8/lib/hardware/int-q.frt
etc.
Because of the way AmForth handles interrupts, the I-flag can be
cleared (disabling the interrupts globally) at any time during the
execution of a Forth primative. It can change to zero between any two
M/C code instructions.
So "int?" has to check both the I-flag and the value of "isrflag"
(T-flag) to come to a valid conclusion. "-int" cannot just perform a
CLI instruction as the next NEXT may process a pending (pending before
the CLI was executed) interrupt and re-enable them. Etc.
Reliable fetch of interrupt status.
Checks for pending interrupts.
I T*** int? Remarks
= = ==== =======
0 0 0 Interrupts disabled by the program.
0 1 -1 Interrupt pending*
1 0 -1 Normal operation.
1 1 -1 Shouldn't ever be**
* This will be serviced by the next NEXT and SREG:I will be
set once more.
** The interrupt will still get serviced, provided it isn't
overwritten.
*** The T-flag seems to be reserved as a holder for the ISR
status, but currently it isn't used. Location "isrflag" is used
instead and is a much slower.
Special care has to be taken to save and restore the I-flag. I have
written macro "no_ints". It uses MCUCR:IVCE to
disable interrupts without affecting the I-flag - see the docs.
Correctly preserve the interrupt status in @0:
.macro no_ints
in @0, MCUCR
ori @0, (1<<IVCE)
out MCUCR, @0
in @0, SREG
cli
.endmacro
Later Atmel cores automatically disable interrupts for a time if you
fiddle with the SP register, so "no_ints" is not required here. Maybe
there are other operations that do this too.
--
Regards,
Martin Nicholas.
E-mail: [email protected] (Address will be valid throughout 2026).
_______________________________________________
Amforth-devel mailing list for http://amforth.sf.net/
[email protected]
https://lists.sourceforge.net/lists/listinfo/amforth-devel