/* Hatari - int.c This file is distributed under the GNU Public License, version 2 or at your option any later version. Read the file gpl.txt for details. This code handles our interrupt table. So we do not need to test for every possible interrupt we add any pending interrupts into a table. We then scan the list if used entries in the table and copy the one with the least cycle count into the global 'PendingInterruptCount' variable. This is then decremented by the execution loop - rather than decrement each and every entry (as the others cannot occur before this one) We have two methods of adding interrupts; Absolute and Relative. Absolute will set values from the time of the previous interrupt(eg, add HBL every 512 cycles), and Relative will add from the current cycle time. Note that interrupt may occur 'late'. Ie, if an interrupt is due in 4 cycles time but the current instruction takes 20 cycles we will be 16 cycles late - this is handled in the adjust functions. */ const char Int_rcsid[] = "Hatari $Id: int.c,v 1.16 2007/01/16 18:42:59 thothy Exp $"; #include "main.h" #include "dmaSnd.h" #include "ikbd.h" #include "int.h" #include "m68000.h" #include "memorySnapShot.h" #include "mfp.h" #include "sound.h" #include "video.h" void (*PendingInterruptFunction)(void); short int PendingInterruptCount; static int nCyclesOver; /* List of possible interrupt handlers to be store in 'PendingInterruptTable', used for 'MemorySnapShot' */ static void (* const pIntHandlerFunctions[MAX_INTERRUPTS])(void) = { NULL, Video_InterruptHandler_VBL, Video_InterruptHandler_HBL, Video_InterruptHandler_EndLine, MFP_InterruptHandler_TimerA, MFP_InterruptHandler_TimerB, MFP_InterruptHandler_TimerC, MFP_InterruptHandler_TimerD, IKBD_InterruptHandler_ResetTimer, IKBD_InterruptHandler_ACIA, DmaSnd_InterruptHandler }; /* Event timer structure - keeps next timer to occur in structure so don't need to check all entries */ typedef struct { BOOL bUsed; /* Is interrupt active? */ int Cycles; void (*pFunction)(void); } INTERRUPTHANDLER; static INTERRUPTHANDLER InterruptHandlers[MAX_INTERRUPTS]; static int ActiveInterrupt=0; /*-----------------------------------------------------------------------*/ /** * Reset interrupts, handlers */ void Int_Reset(void) { int i; /* Reset counts */ PendingInterruptCount = 0; ActiveInterrupt = 0; nCyclesOver = 0; /* Reset interrupt table */ for(i=0; i