Annotation of frontvm/hardware/int.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   Hatari
                      3: 
                      4:   This code handles our interrupt table. So we do not need to test for every possible
                      5:   interrupt we add any pending interrupts into a table. We then scan the list if used
                      6:   entries in the table and copy the one with the least cycle count into the global
                      7:   'PendingInterruptCount' variable. This is then decremented by the execution loop -
                      8:   rather than decrement each and every entry (as the others cannot occur before this one)
                      9:   We have two methods of adding interrupts; Absolute and Relative. Absolute will set values
                     10:   from the time of the previous interrupt(eg, add HBL every 512 cycles), and Relative
                     11:   will add from the current cycle time.
                     12:   Note that interrupt may occur 'late'. Ie, if an interrupt is due in 4 cycles time but
                     13:   the current instruction takes 20 cycles we will be 16 cycles late - this is handled in
                     14:   the adjust functions.
                     15: */
                     16: 
                     17: #include "main.h"
                     18: #include "decode.h"
                     19: #include "int.h"
                     20: #include "m68000.h"
                     21: #include "memAlloc.h"
                     22: #include "misc.h"
                     23: #include "video.h"
                     24: 
                     25: /* List of possible interrupt handlers to be store in 'PendingInterruptTable', used for 'MemorySnapShot' */
                     26: void *pIntHandlerFunctions[] = {
                     27:   NULL,
                     28:   Video_InterruptHandler_VBL_Pending,
                     29:   NULL,
                     30:   NULL,
                     31:   NULL
                     32: };
                     33: 
                     34: INTERRUPTHANDLER InterruptHandlers[MAX_INTERRUPTS];
                     35: int nCyclesOver=0;
                     36: int ActiveInterrupt=0;
                     37: 
                     38: 
                     39: /*-----------------------------------------------------------------------*/
                     40: /*
                     41:   Reset interrupts, handlers
                     42: */
                     43: void Int_Reset(void)
                     44: {
                     45:   int i;
                     46: 
                     47:   /* Reset counts */
                     48:   PendingInterruptCount = 0;
                     49:   nCyclesOver = 0;
                     50: 
                     51:   /* Reset interrupt table */
                     52:   for(i=0; i<MAX_INTERRUPTS; i++) {
                     53:     InterruptHandlers[i].bUsed = FALSE;
                     54:     InterruptHandlers[i].pFunction = pIntHandlerFunctions[i];
                     55:   }
                     56: }
                     57: 
                     58: 
                     59: /*-----------------------------------------------------------------------*/
                     60: /*
                     61:   Convert interrupt handler function pointer to ID, used for saving
                     62: */
                     63: int Int_HandlerFunctionToID(void *pHandlerFunction)
                     64: {
                     65:   int i;
                     66: 
                     67:   /* Is NULL, return ID 0 */
                     68:   if (pHandlerFunction==NULL)
                     69:     return(0);
                     70: 
                     71:   /* Scan for function match */
                     72:   for(i=1; i<MAX_INTERRUPTS; i++) {
                     73:     if (pIntHandlerFunctions[i]==pHandlerFunction)
                     74:       return(i);
                     75:   }
                     76:   
                     77:   /* Didn't find one! Oops */
                     78:   return(0);
                     79: }
                     80: 
                     81: 
                     82: /*-----------------------------------------------------------------------*/
                     83: /*
                     84:   Convert ID back into interrupt handler function, used for restoring
                     85: */
                     86: void *Int_IDToHandlerFunction(int ID)
                     87: {
                     88:   /* Get function pointer */
                     89:   return( pIntHandlerFunctions[ID] );
                     90: }
                     91: 
                     92: 
                     93: /*-----------------------------------------------------------------------*/
                     94: /*
                     95:   Find next interrupt to occur, and store to global variables for decrement in instruction decode loop
                     96: */
                     97: void Int_SetNewInterrupt(void)
                     98: {
                     99:   int LowestCycleCount=999999,LowestInterrupt=0;
                    100:   int i;
                    101: 
                    102:   /* Find next interrupt to go off */
                    103:   for(i=0; i<MAX_INTERRUPTS; i++) {
                    104:     /* Is interrupt pending? */
                    105:     if (InterruptHandlers[i].bUsed) {
                    106:       if (InterruptHandlers[i].Cycles<LowestCycleCount) {
                    107:         LowestCycleCount = InterruptHandlers[i].Cycles;
                    108:         LowestInterrupt = i;
                    109:       }
                    110:     }
                    111:   }
                    112: 
                    113:   /* Set new counts, active interrupt */
                    114:   PendingInterruptCount = (short int)InterruptHandlers[LowestInterrupt].Cycles;
                    115:   PendingInterruptFunction = InterruptHandlers[LowestInterrupt].pFunction;
                    116:   ActiveInterrupt = LowestInterrupt;
                    117: 
                    118: }
                    119: 
                    120: 
                    121: /*-----------------------------------------------------------------------*/
                    122: /*
                    123:   Adjust all interrupt timings, MUST call Int_SetNewInterrupt after this
                    124: */
                    125: void Int_UpdateInterrupt(void)
                    126: {
                    127:   int CycleSubtract;
                    128:   int i;
                    129: 
                    130:   /* Find out how many cycles we went over (<=0) */
                    131:   nCyclesOver = PendingInterruptCount;
                    132:   /* Calculate how many cycles have passed, included time we went over */
                    133:   CycleSubtract = InterruptHandlers[ActiveInterrupt].Cycles-nCyclesOver;
                    134: 
                    135:   /* Adjust table */
                    136:   for(i=0; i<MAX_INTERRUPTS; i++) {
                    137:     if (InterruptHandlers[i].bUsed)
                    138:       InterruptHandlers[i].Cycles -= CycleSubtract;
                    139:   }
                    140: }
                    141: 
                    142: 
                    143: /*-----------------------------------------------------------------------*/
                    144: /*
                    145:   Adjust all interrupt timings as 'ActiveInterrupt' has occured, and remove from active list
                    146: */
                    147: void Int_AcknowledgeInterrupt(void)
                    148: {
                    149:   /* Update list cycle counts */
                    150:   Int_UpdateInterrupt();
                    151: 
                    152:   /* Disable interrupt entry which has just occured */
                    153:   InterruptHandlers[ActiveInterrupt].bUsed = FALSE;
                    154: 
                    155:   /* Set new */
                    156:   Int_SetNewInterrupt();
                    157: }
                    158: 
                    159: 
                    160: /*-----------------------------------------------------------------------*/
                    161: /*
                    162:   Add interrupt from time last one occurred
                    163: */
                    164: void Int_AddAbsoluteInterrupt(int CycleTime, int Handler)
                    165: {
                    166:   InterruptHandlers[Handler].bUsed = TRUE;
                    167:   InterruptHandlers[Handler].Cycles = CycleTime + nCyclesOver;
                    168: 
                    169:   /* Set new */
                    170:   Int_SetNewInterrupt();
                    171: }
                    172: 
                    173: 
                    174: /*-----------------------------------------------------------------------*/
                    175: /*
                    176:   Add interrupt to occur from now
                    177: */
                    178: void Int_AddRelativeInterrupt(int CycleTime, int Handler)
                    179: {
                    180:   InterruptHandlers[Handler].bUsed = TRUE;
                    181:   InterruptHandlers[Handler].Cycles = CycleTime;
                    182: 
                    183:   /* Set new */
                    184:   Int_SetNewInterrupt();
                    185: }
                    186: 
                    187: 
                    188: /*-----------------------------------------------------------------------*/
                    189: /*
                    190:   Remove a pending interrupt from our table
                    191: */
                    192: void Int_RemovePendingInterrupt(int Handler)
                    193: {
                    194:   /* Stop interrupt */
                    195:   InterruptHandlers[Handler].bUsed = FALSE;
                    196: 
                    197:   /* Update list cycle counts */
                    198:   Int_UpdateInterrupt();
                    199:   /* Set new */
                    200:   Int_SetNewInterrupt();
                    201: }
                    202: 
                    203: 
                    204: /*-----------------------------------------------------------------------*/
                    205: /*
                    206:   Return TRUE if interrupt is active in list
                    207: */
                    208: BOOL Int_InterruptActive(int Handler)
                    209: {
                    210:   /* Is timer active? */
                    211:   if (InterruptHandlers[Handler].bUsed)
                    212:     return(TRUE);
                    213: 
                    214:   return(FALSE);
                    215: }
                    216: 
                    217: 
                    218: /*-----------------------------------------------------------------------*/
                    219: /*
                    220:   Return cycles passed for an interrupt handler
                    221: */
                    222: int Int_FindCyclesPassed(int Handler)
                    223: {
                    224:   int CyclesPassed, CyclesFromLastInterrupt;
                    225: 
                    226:   CyclesFromLastInterrupt = (int)InterruptHandlers[ActiveInterrupt].Cycles-PendingInterruptCount;
                    227:   CyclesPassed = ((int)InterruptHandlers[Handler].Cycles-CyclesFromLastInterrupt);
                    228: 
                    229:   return(CyclesPassed);
                    230: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.