24 September 2019, 17:39 | #1 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Interrupts, doing it low level, but properly.
I'm trying to set up some interrupt handlers, starting with some borrowed code. What I have works, but is limited to Vertical Blank interrupts only. How do I detect and process different kinds of (same level) interrupts, namely Blitter Finished?
So far, I have an interrupt handler: Code:
static __attribute__((interrupt)) void InterruptHandler(void) { custom->intreq = (1 << INTB_VERTB); custom->intreq = (1 << INTB_VERTB); // reset vbl req. twice for A4000 bug display->updateDisplay(display); } Code:
void SetInterruptHandler(APTR interrupt) { * (volatile APTR *) (((UBYTE *) VBR) + 0x6c) = interrupt; } Code:
custom->intena = (1 << INTB_SETCLR) | (1 << INTB_INTEN) | (1 << INTB_VERTB); custom->intreq = 1 << INTB_VERTB; // reset vbl req And is this code "complete" enough, or is there more that I need to do inside the interrupt handler, for instance? |
24 September 2019, 18:16 | #2 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
As a rough minimum,
This should be done after the Blitter has finished, and at the end of frame because otherwise, running DMA could potentially thrash memory. On exit, you do the same thing, but restoring instead of saving. To turn on only the interrupts you use, you must first clear the other bits. This is done the same way that you clear the INTREQ bit in your interrupt. Last edited by Photon; 24 September 2019 at 18:24. |
24 September 2019, 19:23 | #3 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
|
24 September 2019, 20:41 | #4 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
It clears the interrupt request bit for that level (by setting the SET/CLR bit to 0 = CLR, and setting the bit for VBLANK to 1). (It does this twice to be compatible with Amiga 4000, which has a hardware bug.)
The hardware sets this bit when it triggers an interrupt call. You can also read this (from INTREQR) to find out which of the interrupts on the same level as VBLANK that was triggered. They all use this vector. But if only the VBLANK interrupt is enabled, you don't have to check it. |
24 September 2019, 21:00 | #5 | ||
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Quote:
Quote:
And I need to clear whichever bit is set. I guess I do that straight away so I can exit from my handler whenever I want. Anything else I'm missing? Last edited by deimos; 25 September 2019 at 08:23. |
||
25 September 2019, 14:06 | #6 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
You should only check for the bit that corresponds to the interrupt you are handling, and at the very end of that handling you poll (clear) only that bit.
If several interrupt levels use the same vector call address, you must put a check (if statement) for each level that you have enabled. If a level is enabled that you have no code to handle, you can normally not pass it on to the OS interrupt handler. So under some circumstances, if you use a vector that has more than one level, you must disable the interrupts on that level that you don't handle, or the user must be OK with some interrupts not being handled. Last edited by Photon; 25 September 2019 at 14:14. |
25 September 2019, 14:19 | #7 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
So:
Code:
UWORD intreqr = custom->intreqr; if (intreqr & INTF_COPER) { processCopperInterrupt(); custom->intreq = (UWORD) INTF_COPER; custom->intreq = (UWORD) INTF_COPER; } else if (intreqr & INTF_VERTB) { processVerticalBlankInterrupt(); custom->intreq = (UWORD) INTF_VERTB; custom->intreq = (UWORD) INTF_VERTB; } else if (intreqr & INTF_BLIT) { processBlitterInterrupt(); custom->intreq = (UWORD) INTF_BLIT; custom->intreq = (UWORD) INTF_BLIT; } Code:
UWORD intreqr = custom->intreqr; if (intreqr & INTF_COPER) { processCopperInterrupt(); custom->intreq = (UWORD) INTF_COPER; custom->intreq = (UWORD) INTF_COPER; } if (intreqr & INTF_VERTB) { processVerticalBlankInterrupt(); custom->intreq = (UWORD) INTF_VERTB; custom->intreq = (UWORD) INTF_VERTB; } if (intreqr & INTF_BLIT) { processBlitterInterrupt(); custom->intreq = (UWORD) INTF_BLIT; custom->intreq = (UWORD) INTF_BLIT; } |
25 September 2019, 19:45 | #8 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
The last one is correct.
I wouldn't exclude the possibility that multiple interrupt sources may trigger at the same time. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Low-level workings of Paula | absence | Coders. General | 75 | 11 November 2013 17:53 |
USB Flash Disk Low-Level Format | prowler | support.Hardware | 53 | 03 August 2012 21:39 |
Low level format utility for the A1200 | Fabie | support.Hardware | 20 | 11 January 2010 19:13 |
When to low level format | Galaxy | support.Hardware | 6 | 30 January 2007 12:39 |
Low Level Format??? | Djay | support.Hardware | 4 | 01 March 2003 20:58 |
|
|