|
|
1.1 ! root 1: /* ! 2: Hatari - cycles.c ! 3: ! 4: This file is distributed under the GNU Public License, version 2 or at ! 5: your option any later version. Read the file gpl.txt for details. ! 6: ! 7: Here we take care of cycle counters. For performance reasons we don't increase ! 8: all counters after each 68k instruction, but only one main counter. ! 9: When we need to read one of the normal counters (currently only for video ! 10: and sound cycles), we simply update these counters with the main counter ! 11: before returning the current counter value. ! 12: */ ! 13: ! 14: ! 15: /* 2007/03/xx [NP] Use 'CurrentInstrCycles' to get a good approximation for */ ! 16: /* Cycles_GetCounterOnReadAccess and Cycles_GetCounterOnWriteAccess*/ ! 17: /* (this should work correctly with 'move' instruction). */ ! 18: /* 2008/04/14 [NP] Take nWaitStateCycles into account when computing the value of */ ! 19: /* Cycles_GetCounterOnReadAccess and Cycles_GetCounterOnWriteAccess*/ ! 20: /* 2008/12/21 [NP] Use BusMode to adjust Cycles_GetCounterOnReadAccess and */ ! 21: /* Cycles_GetCounterOnWriteAccess depending on who is owning the */ ! 22: /* bus (cpu, blitter). */ ! 23: ! 24: ! 25: const char Cycles_fileid[] = "Hatari cycles.c : " __DATE__ " " __TIME__; ! 26: ! 27: #include "main.h" ! 28: #include "m68000.h" ! 29: #include "memorySnapShot.h" ! 30: #include "cycles.h" ! 31: ! 32: ! 33: int nCyclesMainCounter; /* Main cycles counter */ ! 34: ! 35: static int nCyclesCounter[CYCLES_COUNTER_MAX]; /* Array with all counters */ ! 36: ! 37: int CurrentInstrCycles; ! 38: ! 39: ! 40: ! 41: /*-----------------------------------------------------------------------*/ ! 42: /** ! 43: * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type) ! 44: */ ! 45: void Cycles_MemorySnapShot_Capture(bool bSave) ! 46: { ! 47: /* Save/Restore details */ ! 48: MemorySnapShot_Store(&nCyclesMainCounter, sizeof(nCyclesMainCounter)); ! 49: MemorySnapShot_Store(nCyclesCounter, sizeof(nCyclesCounter)); ! 50: MemorySnapShot_Store(&CurrentInstrCycles, sizeof(CurrentInstrCycles)); ! 51: } ! 52: ! 53: ! 54: /*-----------------------------------------------------------------------*/ ! 55: /** ! 56: * Update all cycles counters with the current value of nCyclesMainCounter. ! 57: */ ! 58: static void Cycles_UpdateCounters(void) ! 59: { ! 60: int i; ! 61: ! 62: for (i = 0; i < CYCLES_COUNTER_MAX; i++) ! 63: { ! 64: nCyclesCounter[i] += nCyclesMainCounter; ! 65: } ! 66: ! 67: nCyclesMainCounter = 0; ! 68: } ! 69: ! 70: ! 71: /*-----------------------------------------------------------------------*/ ! 72: /** ! 73: * Set a counter to a new value. ! 74: */ ! 75: void Cycles_SetCounter(int nId, int nValue) ! 76: { ! 77: /* Update counters first (nCyclesMainCounter must be 0 afterwards) */ ! 78: Cycles_UpdateCounters(); ! 79: ! 80: /* Now set the new value: */ ! 81: nCyclesCounter[nId] = nValue; ! 82: } ! 83: ! 84: ! 85: /*-----------------------------------------------------------------------*/ ! 86: /** ! 87: * Read a counter. ! 88: */ ! 89: int Cycles_GetCounter(int nId) ! 90: { ! 91: /* Update counters first so we read an up-to-date value */ ! 92: Cycles_UpdateCounters(); ! 93: ! 94: return nCyclesCounter[nId]; ! 95: } ! 96: ! 97: ! 98: /*-----------------------------------------------------------------------*/ ! 99: /** ! 100: * Read a counter on CPU memory read access by taking care of the instruction ! 101: * type (add the needed amount of additional cycles). ! 102: */ ! 103: int Cycles_GetCounterOnReadAccess(int nId) ! 104: { ! 105: int nAddCycles; ! 106: ! 107: /* Update counters first so we read an up-to-date value */ ! 108: Cycles_UpdateCounters(); ! 109: ! 110: if ( BusMode == BUS_MODE_BLITTER ) ! 111: { ! 112: nAddCycles = 4 + nWaitStateCycles; ! 113: } ! 114: else /* BUS_MODE_CPU */ ! 115: { ! 116: /* TODO: Find proper cycles count depending on the type of the current instruction */ ! 117: /* (e.g. movem is not correctly handled) */ ! 118: nAddCycles = CurrentInstrCycles + nWaitStateCycles; /* read is effective at the end of the instr ? */ ! 119: } ! 120: ! 121: return nCyclesCounter[nId] + nAddCycles; ! 122: } ! 123: ! 124: ! 125: /*-----------------------------------------------------------------------*/ ! 126: /** ! 127: * Read a counter on CPU memory write access by taking care of the instruction ! 128: * type (add the needed amount of additional cycles). ! 129: */ ! 130: int Cycles_GetCounterOnWriteAccess(int nId) ! 131: { ! 132: int nAddCycles; ! 133: ! 134: /* Update counters first so we read an up-to-date value */ ! 135: Cycles_UpdateCounters(); ! 136: ! 137: if ( BusMode == BUS_MODE_BLITTER ) ! 138: { ! 139: nAddCycles = 4 + nWaitStateCycles; ! 140: } ! 141: else /* BUS_MODE_CPU */ ! 142: { ! 143: /* TODO: Find proper cycles count depending on the type of the current instruction */ ! 144: /* (e.g. movem is not correctly handled) */ ! 145: nAddCycles = CurrentInstrCycles + nWaitStateCycles; ! 146: ! 147: /* assume the behaviour of a 'move' (since this is the most */ ! 148: /* common instr used when requiring cycle precise writes) */ ! 149: if ( nAddCycles >= 8 ) ! 150: nAddCycles -= 4; /* last 4 cycles are for prefetch */ ! 151: } ! 152: ! 153: return nCyclesCounter[nId] + nAddCycles; ! 154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.