|
|
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 root 29: #include "cycles.h"
30:
31:
32: int nCyclesMainCounter; /* Main cycles counter */
33:
34: static int nCyclesCounter[CYCLES_COUNTER_MAX]; /* Array with all counters */
35:
1.1.1.2 root 36: int CurrentInstrCycles;
37:
1.1 root 38:
39: /*-----------------------------------------------------------------------*/
1.1.1.2 root 40: /**
41: * Update all cycles counters with the current value of nCyclesMainCounter.
42: */
1.1 root 43: static void Cycles_UpdateCounters(void)
44: {
45: int i;
46:
47: for (i = 0; i < CYCLES_COUNTER_MAX; i++)
48: {
49: nCyclesCounter[i] += nCyclesMainCounter;
50: }
51:
52: nCyclesMainCounter = 0;
53: }
54:
55:
56: /*-----------------------------------------------------------------------*/
1.1.1.2 root 57: /**
58: * Set a counter to a new value.
59: */
1.1 root 60: void Cycles_SetCounter(int nId, int nValue)
61: {
62: /* Update counters first (nCyclesMainCounter must be 0 afterwards) */
63: Cycles_UpdateCounters();
64:
65: /* Now set the new value: */
66: nCyclesCounter[nId] = nValue;
67: }
68:
69:
70: /*-----------------------------------------------------------------------*/
1.1.1.2 root 71: /**
72: * Read a counter.
73: */
1.1 root 74: int Cycles_GetCounter(int nId)
75: {
76: /* Update counters first so we read an up-to-date value */
77: Cycles_UpdateCounters();
78:
79: return nCyclesCounter[nId];
80: }
81:
82:
83: /*-----------------------------------------------------------------------*/
1.1.1.2 root 84: /**
85: * Read a counter on CPU memory read access by taking care of the instruction
86: * type (add the needed amount of additional cycles).
87: */
1.1 root 88: int Cycles_GetCounterOnReadAccess(int nId)
89: {
90: int nAddCycles;
91:
92: /* Update counters first so we read an up-to-date value */
93: Cycles_UpdateCounters();
94:
1.1.1.4 ! root 95: if ( BusMode == BUS_MODE_BLITTER )
! 96: {
! 97: nAddCycles = 4 + nWaitStateCycles;
! 98: }
! 99: else /* BUS_MODE_CPU */
! 100: {
! 101: /* TODO: Find proper cycles count depending on the type of the current instruction */
! 102: /* (e.g. movem is not correctly handled) */
! 103: nAddCycles = CurrentInstrCycles + nWaitStateCycles; /* read is effective at the end of the instr ? */
! 104: }
1.1 root 105:
106: return nCyclesCounter[nId] + nAddCycles;
107: }
108:
109:
110: /*-----------------------------------------------------------------------*/
1.1.1.2 root 111: /**
112: * Read a counter on CPU memory write access by taking care of the instruction
113: * type (add the needed amount of additional cycles).
114: */
1.1 root 115: int Cycles_GetCounterOnWriteAccess(int nId)
116: {
117: int nAddCycles;
118:
119: /* Update counters first so we read an up-to-date value */
120: Cycles_UpdateCounters();
121:
1.1.1.4 ! root 122: if ( BusMode == BUS_MODE_BLITTER )
! 123: {
! 124: nAddCycles = 4 + nWaitStateCycles;
! 125: }
! 126: else /* BUS_MODE_CPU */
! 127: {
! 128: /* TODO: Find proper cycles count depending on the type of the current instruction */
! 129: /* (e.g. movem is not correctly handled) */
! 130: nAddCycles = CurrentInstrCycles + nWaitStateCycles;
! 131:
! 132: /* assume the behaviour of a 'move' (since this is the most */
! 133: /* common instr used when requiring cycle precise writes) */
! 134: if ( nAddCycles >= 8 )
! 135: nAddCycles -= 4; /* last 4 cycles are for prefetch */
! 136: }
1.1 root 137:
138: return nCyclesCounter[nId] + nAddCycles;
139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.