On 2026-02-08 15:38, Martin Nicholas via Amforth-devel wrote:
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.

Hi Martin,

Thank you. Added to the list.

A preliminary check of the archives shows that the way interrupts were handled by the VM changed between releases 6.4 and 6.5

In 6.4 there is
brts DO_INTERRUPT

In 6.5 there is
cp isrflag, zerol
brne DO_INTERRUPT

The release notes for 6.5 [1] state that there was a bug in the interrupt handling on the avr8. Erich discovered and fixed the bug, and so may be able to help. Current avr8 documentation references the T flag but does not reference isrflag, so this is something that will need to be updated.

The file avr8//drivers/generic-isr.asm shows considerable related changes between the releases but I need more time to study it.

Best wishes,
Tristan

[1] https://sourceforge.net/p/amforth/mailman/message/35814877/


_______________________________________________
Amforth-devel mailing list for http://amforth.sf.net/
[email protected]
https://lists.sourceforge.net/lists/listinfo/amforth-devel

Reply via email to