English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Coders. General (http://eab.abime.net/forumdisplay.php?f=37)
-   -   BLIT interrupts being triggered, even when disabled? (http://eab.abime.net/showthread.php?t=99009)

deimos 30 September 2019 19:30

BLIT interrupts being triggered, even when disabled?
 
I've not enabled BLIT interrupts, only PORTS and VERTB:

Code:

    custom->intena = INTF_INTEN | INTF_ALL; // disable all interrupts
    custom->intreq = INTF_INTEN | INTF_ALL; // clear any interrupts that were pending

    ...

    custom->intena = INTF_SETCLR | INTF_INTEN | mask;
    custom->intreq = mask;

where mask is INTF_PORTS | INTF_VERTB

My main loop does four blits, calling WaitBlt before each one. I get the occasional BLIT interrupt triggered. About once for each four blits.

I can't understand this.

If I enable BLIT interrupts, I get an interrupt for each blit, as you would expect.

What on earth could I be doing wrong?

meynaf 30 September 2019 19:38

Does it still occur if you don't enable INTF_VERTB ?

a/b 30 September 2019 19:52

Maybe you are enabling them elsewhere in your code, or you are not properly preventing the OS from using the blitter (e.g. OwnBlitter)...

deimos 30 September 2019 19:59

Quote:

Originally Posted by meynaf (Post 1348646)
Does it still occur if you don't enable INTF_VERTB ?

Yes... But now, even though I've only enabled PORTS, I still seem to be getting VERTB and BLIT interrrupts...

deimos 30 September 2019 20:00

Quote:

Originally Posted by a/b (Post 1348650)
Maybe you are enabling them elsewhere in your code, or you are not properly preventing the OS from using the blitter (e.g. OwnBlitter)...

I'm quite sure I'm not, and that my startup code takes over everything properly, but I'm double checking now.

deimos 30 September 2019 20:10

Code:

void _InterruptHandler_enableInterrupts(UWORD mask) {
    if (DEBUG) KPrintF("In _InterruptHandler_enableInterrupts.\n");

    KPrintF("In _InterruptHandler_enableInterrupts - intena = 0x%04lx.\n", INTF_SETCLR | INTF_INTEN | mask);

    custom->intena = INTF_SETCLR | INTF_INTEN | mask;
    custom->intreq = mask;

    UWORD intenar = custom->intenar;
    KPrintF("In _InterruptHandler_enableInterrupts - intenar = 0x%04lx.\n", intenar);
}

outputs:

Code:

In _InterruptHandler_enableInterrupts.
In _InterruptHandler_enableInterrupts - intena = 0xC008.
In _InterruptHandler_enableInterrupts - intenar = 0x4028.

Which I find surprising.

meynaf 30 September 2019 20:18

Quote:

Originally Posted by deimos (Post 1348659)
Code:

In _InterruptHandler_enableInterrupts.
In _InterruptHandler_enableInterrupts - intena = 0xC008.
In _InterruptHandler_enableInterrupts - intenar = 0x4028.

Which I find surprising.

This code does not disable other interrupts before.
Read the interrupt register at start of the function and you will see this.

deimos 30 September 2019 20:27

Quote:

Originally Posted by meynaf (Post 1348661)
This code does not disable other interrupts before.
Read the interrupt register at start of the function and you will see this.

Correct:

Code:

In _InterruptHandler_enableInterrupts - intenar = 0x0020.
In _InterruptHandler_enableInterrupts - intena = 0xC008.
In _InterruptHandler_enableInterrupts - intenar = 0x4028.

I appear to have VERTB enabled. I don't know how, as I disable all interrupts when I take over the system. This is where I'm going to start looking.

deimos 30 September 2019 20:43

In my system takeover function I do this:

Code:

    KPrintF("In TakeSystem - intenar = 0x%04lx.\n", custom->intenar);

    custom->intena = INTF_INTEN | INTF_ALL; // disable all interrupts
    custom->intreq = INTF_INTEN | INTF_ALL; // clear any interrupts that were pending
   
    KPrintF("In TakeSystem - intenar = 0x%04lx.\n", custom->intenar);

Which outputs:

Code:

In TakeSystem - intenar = 0x202C.
In TakeSystem - intenar = 0x0000.

So, somewhere I'm screwing up intena. I'll update if I find anything else.

deimos 30 September 2019 20:49

Quote:

Originally Posted by deimos (Post 1348669)
So, somewhere I'm screwing up intena. I'll update if I find anything else.

So, my startup code calls LoadView(NULL). This seems to have a side effect of enabling VERTB. So I need to find a better example to copy my startup code from. In the meantime I'll disable interrupts again after that call, and see if I can get back to the original problem.

deimos 30 September 2019 21:12

Quote:

Originally Posted by meynaf (Post 1348646)
Does it still occur if you don't enable INTF_VERTB ?

I'm only getting the BLIT interrupts if I have VERTB interrupts enabled. I do not have BLIT interrupts enabled.

Code:

In _InterruptHandler_handleLevel2Interrupt.
In _GameInterruptHandler_processPORTS.
Key pressed:
    0x22
In _InterruptHandler_handleLevel2Interrupt.
In _GameInterruptHandler_processPORTS.
In Tick.
In _TripleBufferedDisplay_getScreenBuffer.
In _SplitDisplay_getScreenBuffer.
In _SplitDisplay_getPrimaryScreenBuffer.
In SetOrClearBitPlane - intenar = 0x4028.
Blitter started!
In SetOrClearBitPlane - intenar = 0x4028.
Blitter started!
In SetOrClearBitPlane - intenar = 0x4028.
Blitter started!
In _InterruptHandler_handleLevel3Interrupt (BLIT).
In _InterruptHandler_processUnimplementedInterrupt.
In SetOrClearBitPlane - intenar = 0x4028.
Blitter started!
In __TripleBufferedDisplay_flipDisplay.

The relevant part of my interrupt handler:

Code:

static __attribute__((interrupt)) void _InterruptHandler_handleLevel3Interrupt(void) {
    // if (DEBUG) KPrintF("In _InterruptHandler_handleLevel3Interrupt.\n");

    UWORD intreqr = custom->intreqr;

    if (intreqr & INTF_COPER) {
        // if (DEBUG) KPrintF("In _InterruptHandler_handleLevel3Interrupt (COPER).\n");

        interruptHandler->_processInterrupt(interruptHandler, INTB_COPER);
        custom->intreq = (UWORD) INTF_COPER; custom->intreq = (UWORD) INTF_COPER;
    }
   
    if (intreqr & INTF_VERTB) {
        // if (DEBUG) KPrintF("In _InterruptHandler_handleLevel3Interrupt (VERTB).\n");

        interruptHandler->_processInterrupt(interruptHandler, INTB_VERTB);
        custom->intreq = (UWORD) INTF_VERTB; custom->intreq = (UWORD) INTF_VERTB;
    }
   
    if (intreqr & INTF_BLIT) {
        if (DEBUG) KPrintF("In _InterruptHandler_handleLevel3Interrupt (BLIT).\n");

        interruptHandler->_processInterrupt(interruptHandler, INTB_BLIT);
        custom->intreq = (UWORD) INTF_BLIT; custom->intreq = (UWORD) INTF_BLIT;
    }
}


ross 30 September 2019 21:20

INTREQR is updated when the source trigger an IRQ, even if it is not enabled in INTENA.
Obviously the IRQ code handler does not start.
This is a normal behavior.

If another IRQ of the same level trigger then you need to check if enabled (INTENAR).
You can also optionally clean it (INTREQ), if you intend to use it in any way.

deimos 30 September 2019 21:30

Quote:

Originally Posted by ross (Post 1348675)
INTREQR is updated when the source trigger an IRQ, even if it is not enabled in INTENA.
Obviously the code handler does not start; this is normal.
If the source is of the same level is up to you to check if enabled (INTENAR) and clean it (INTREQ).

I'm not sure I understand - I need to check both INTENAR and INTREQR and ignore anything where the correct INTENAR bits aren't set (but still clear the INTREQ bit)?

ross 30 September 2019 21:36

Quote:

Originally Posted by deimos (Post 1348677)
I'm not sure I understand - I need to check both INTENAR and INTREQR and ignore anything where the correct INTENAR bits aren't set (but still clear the INTREQ bit)?

You can exclude INTENAR check if your code know that that source is enabled.
Of course you need to exclude the related INTREQR read in code.

deimos 30 September 2019 21:44

Quote:

Originally Posted by ross (Post 1348678)
You can exclude INTENAR check if your code know that that source is enabled.
Of course you need to exclude the related INTREQR read in code.

Yeah, I'm still not getting it. I don't have BLIT interrupts enabled (INTENAR = 0x4028), but they're still happening. Is this what I should expect?

ross 30 September 2019 21:56

Quote:

Originally Posted by deimos (Post 1348680)
Yeah, I'm still not getting it. I don't have BLIT interrupts enabled (INTENAR = 0x4028), but they're still happening. Is this what I should expect?

If you blit something sure BLIT in INTREQR goes to 1 when blitter finished!
But IRQ3 do not trigger if you not enable it in INTENA.

Is up to you to ignore it during the IRQ routine.
If you are unsure if you need it (cause a generic IRQ3 routine), then you have to also check INTENAR.

Example:
Code:

        move.w        #$7fff,(INTENA)
        move.w        #$7fff,(INTREQ)
        move.w        #$c030,(INTENA)
        ...

IRQ3:        moveq        #$VERTB,d1
        and.w        (INTREQR),d1        ;a VERT request?
        and.w        (INTENAR),d1        ;is the IRQ enabled?
        beq.b        .cop                ;no, skip

        ;handle VERTB
        ;clean VERTB in INTREQ
;        bra.b        .exit

.cop        moveq        #$COPER,d1
        and.w        (INTREQR),d1        ;a COPER request?
        and.w        (INTENAR),d1        ;is the IRQ enabled?
        beq.b        .bli                ;no, skip

        ;handle COPER
        ;clean COPER in INTREQ
;        bra.b        .exit

.bli        moveq        #$BLIT,d1
        and.w        (INTREQR),d1        ;a BLIT request?
        and.w        (INTENAR),d1        ;is the IRQ enabled?
        beq.b        .exit                ;no, skip

        ;handle BLIT
        ;clean BLIT in INTREQ

.exit


deimos 30 September 2019 21:58

Quote:

Originally Posted by ross (Post 1348682)
If you blit something sure BLIT in INTREQR goes to 1 when blitter finished!
But IRQ3 do not trigger if you not enable it in INTENA.

Oh.

ross 30 September 2019 22:08

Quote:

Originally Posted by deimos (Post 1348683)
Oh.

Sure VERTB IRQ trigger and shortly before BLIT in INTREQR goes to 1 and your code get confused (it handles the situation incorrectly :)).

I hope you understand now ;)

deimos 30 September 2019 22:16

Quote:

Originally Posted by ross (Post 1348686)
Sure VERTB IRQ trigger and shortly before BLIT in INTREQR goes to 1 and your code get confused (it handles the situation incorrectly :)).

I hope you understand now :)

Yes. And another impact of this is that if I'm enabling interrupts at specific points in my code I also need to clear the matching bits in intreq as I don't know what might be in there.

ross 30 September 2019 22:17

Quote:

Originally Posted by deimos (Post 1348687)
Yes. And another impact of this is that if I'm enabling interrupts at specific points in my code I also need to clear the matching bits in intreq as I don't know what might be in there.

:agree

EDIT: ah, clear before enable it, this avoid potential immediate trigger


All times are GMT +2. The time now is 20:55.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.

Page generated in 0.05736 seconds with 12 queries