|
|
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: */
1.1.1.2 root 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). */
1.1.1.3 root 18: /* 2008/04/14 [NP] Take nWaitStateCycles into account when computing the value of */
19: /* Cycles_GetCounterOnReadAccess and Cycles_GetCounterOnWriteAccess*/
1.1.1.4 root 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). */
1.1.1.2 root 23:
24:
1.1.1.4 root 25: const char Cycles_fileid[] = "Hatari cycles.c : " __DATE__ " " __TIME__;
1.1 root 26:
27: #include "main.h"
1.1.1.3 root 28: #include "m68000.h"
1.1.1.5 ! root 29: #include "memorySnapShot.h"
1.1 root 30: #include "cycles.h"
31:
32:
1.1.1.5 ! root 33: int nCyclesMainCounter; /* Main cycles counter */
1.1 root 34:
1.1.1.5 ! root 35: static int nCyclesCounter[CYCLES_COUNTER_MAX]; /* Array with all counters */
1.1 root 36:
1.1.1.2 root 37: int CurrentInstrCycles;
38:
1.1 root 39:
1.1.1.5 ! root 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:
1.1 root 54: /*-----------------------------------------------------------------------*/
1.1.1.2 root 55: /**
56: * Update all cycles counters with the current value of nCyclesMainCounter.
57: */
1.1 root 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: /*-----------------------------------------------------------------------*/
1.1.1.2 root 72: /**
73: * Set a counter to a new value.
74: */
1.1 root 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: /*-----------------------------------------------------------------------*/
1.1.1.2 root 86: /**
87: * Read a counter.
88: */
1.1 root 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: /*-----------------------------------------------------------------------*/
1.1.1.2 root 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: */
1.1 root 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:
1.1.1.4 root 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: }
1.1 root 120:
121: return nCyclesCounter[nId] + nAddCycles;
122: }
123:
124:
125: /*-----------------------------------------------------------------------*/
1.1.1.2 root 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: */
1.1 root 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:
1.1.1.4 root 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: }
1.1 root 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.