ericb59 / Fusion-C-v1.2

MSX C Library for SDCC compiler
Other
71 stars 7 forks source link

Interrupt Handler: interrupts not enabled before reti #11

Open baktery opened 3 years ago

baktery commented 3 years ago

If I understand well, at the end of a interrupt handler routine interrupts must be enabled again. I read it from several sources, this is one of them: http://map.grauw.nl/articles/interrupts.php

Current fusion c implementation does not call EI before RETI. From interrupt.s file:

; ---------------------------------------------------------
;   intr_handler
; ---------------------------------------------------------
intr_handler:
    push    af
    push    bc
    push    de
    push    hl
    push    ix
    push    iy
    exx
    ex      af,af'
    push    af
    push    bc
    push    de
    push    hl
    push    ix
    push    iy

user_intr_handler:
    call    dummy_handler

    xor     a
    or      l
    call    z, backup_keyint

    pop     iy
    pop     ix
    pop     hl
    pop     de
    pop     bc
    pop     af
    ex      af,af'
    exx
    pop     iy
    pop     ix
    pop     hl
    pop     de
    pop     bc
    pop     af
    reti

and, if I'm right, it should be:

; ---------------------------------------------------------
;   intr_handler
; ---------------------------------------------------------
intr_handler:
    push    af
    push    bc
    push    de
    push    hl
    push    ix
    push    iy
    exx
    ex      af,af'
    push    af
    push    bc
    push    de
    push    hl
    push    ix
    push    iy

user_intr_handler:
    call    dummy_handler

    xor     a
    or      l
    call    z, backup_keyint

    pop     iy
    pop     ix
    pop     hl
    pop     de
    pop     bc
    pop     af
    ex      af,af'
    exx
    pop     iy
    pop     ix
    pop     hl
    pop     de
    pop     bc
    pop     af
        ei
    reti

To reproduce the issue you can use the interrupt.c example file and comment the DisableInterrupt()/EnableInterrupt() calls from the main loop.

You will see that the interrupt handle is called only once, the first vsync, and will never be called again because interrupts are not enabled after the first interrupt handler call.