|
|
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.