Mercurial > audlegacy
comparison Plugins/Input/sexypsf/PsxCounters.c @ 333:42cdc99e395a trunk
[svn] Now that the build system is ready, upload the plugin code.
author | chainsaw |
---|---|
date | Sun, 25 Dec 2005 13:11:21 -0800 |
parents | |
children | 61e7332e0652 f12d7e208b43 |
comparison
equal
deleted
inserted
replaced
332:07576d3ed844 | 333:42cdc99e395a |
---|---|
1 /* Pcsx - Pc Psx Emulator | |
2 * Copyright (C) 1999-2002 Pcsx Team | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * This program is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with this program; if not, write to the Free Software | |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 */ | |
18 | |
19 #include <string.h> | |
20 | |
21 #include "PsxCommon.h" | |
22 | |
23 static int cnts = 4; | |
24 static u32 last=0; | |
25 | |
26 static void psxRcntUpd(u32 index) { | |
27 psxCounters[index].sCycle = psxRegs.cycle; | |
28 if (((!(psxCounters[index].mode & 1)) || (index!=2)) && | |
29 psxCounters[index].mode & 0x30) { | |
30 if (psxCounters[index].mode & 0x10) { // Interrupt on target | |
31 psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS; | |
32 } else { // Interrupt on 0xffff | |
33 psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS; | |
34 } | |
35 } else psxCounters[index].Cycle = 0xffffffff; | |
36 } | |
37 | |
38 static void psxRcntReset(u32 index) { | |
39 psxCounters[index].count = 0; | |
40 psxRcntUpd(index); | |
41 | |
42 psxHu32(0x1070)|= BFLIP32(psxCounters[index].interrupt); | |
43 if (!(psxCounters[index].mode & 0x40)) { // Only 1 interrupt | |
44 psxCounters[index].Cycle = 0xffffffff; | |
45 } | |
46 } | |
47 | |
48 static void psxRcntSet() { | |
49 int i; | |
50 | |
51 psxNextCounter = 0x7fffffff; | |
52 psxNextsCounter = psxRegs.cycle; | |
53 | |
54 for (i=0; i<cnts; i++) { | |
55 s32 count; | |
56 | |
57 if (psxCounters[i].Cycle == 0xffffffff) continue; | |
58 | |
59 count = psxCounters[i].Cycle - (psxRegs.cycle - psxCounters[i].sCycle); | |
60 | |
61 if (count < 0) { | |
62 psxNextCounter = 0; break; | |
63 } | |
64 | |
65 if (count < (s32)psxNextCounter) { | |
66 psxNextCounter = count; | |
67 } | |
68 } | |
69 } | |
70 | |
71 void psxRcntInit() { | |
72 | |
73 memset(psxCounters, 0, sizeof(psxCounters)); | |
74 | |
75 psxCounters[0].rate = 1; psxCounters[0].interrupt = 0x10; | |
76 psxCounters[1].rate = 1; psxCounters[1].interrupt = 0x20; | |
77 psxCounters[2].rate = 1; psxCounters[2].interrupt = 64; | |
78 | |
79 psxCounters[3].interrupt = 1; | |
80 psxCounters[3].mode = 0x58; // The VSync counter mode | |
81 psxCounters[3].target = 1; | |
82 psxUpdateVSyncRate(); | |
83 | |
84 cnts = 4; | |
85 | |
86 psxRcntUpd(0); psxRcntUpd(1); psxRcntUpd(2); psxRcntUpd(3); | |
87 psxRcntSet(); | |
88 last=0; | |
89 } | |
90 | |
91 | |
92 int CounterSPURun(void) | |
93 { | |
94 u32 cycles; | |
95 | |
96 if(psxRegs.cycle<last) | |
97 { | |
98 cycles=0xFFFFFFFF-last; | |
99 cycles+=psxRegs.cycle; | |
100 } | |
101 else | |
102 cycles=psxRegs.cycle-last; | |
103 | |
104 if(cycles>=16) | |
105 { | |
106 if(!SPUasync(cycles)) return(0); | |
107 last=psxRegs.cycle; | |
108 } | |
109 return(1); | |
110 } | |
111 | |
112 /* Set by spu irq stuff in spu code to number of cpu cycles to back | |
113 up(if necessary). Very crazy hack. Eh, not implemented. Hmm. | |
114 TODO! | |
115 */ | |
116 s32 spuirqvoodoo=-1; | |
117 | |
118 void CounterDeadLoopSkip() | |
119 { | |
120 s32 min,x,lmin; | |
121 | |
122 lmin=0x7FFFFFFF; | |
123 | |
124 for(x=0;x<4;x++) | |
125 { | |
126 if (psxCounters[x].Cycle != 0xffffffff) | |
127 { | |
128 min=psxCounters[x].Cycle; | |
129 min-=(psxRegs.cycle - psxCounters[x].sCycle); | |
130 if(min<lmin) lmin=min; | |
131 // if(min<0) exit(); | |
132 // printf("Poo: %d, ",min); | |
133 } | |
134 } | |
135 | |
136 if(lmin>0) | |
137 { | |
138 // printf("skip %u\n",lmin); | |
139 psxRegs.cycle+=lmin; | |
140 } | |
141 } | |
142 | |
143 void psxUpdateVSyncRate() { | |
144 //if (Config.PsxType) // ntsc - 0 | pal - 1 | |
145 // psxCounters[3].rate = (PSXCLK / 50);// / BIAS; | |
146 //else | |
147 psxCounters[3].rate = (PSXCLK / 60);// / BIAS; | |
148 } | |
149 | |
150 void psxRcntUpdate() | |
151 { | |
152 if ((psxRegs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) { | |
153 //printf("%d\n",(psxRegs.cycle - psxCounters[3].sCycle)- psxCounters[3].Cycle); | |
154 psxRcntUpd(3); | |
155 psxHu32(0x1070)|= BFLIP32(1); | |
156 } | |
157 if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) { | |
158 psxRcntReset(0); | |
159 } | |
160 | |
161 if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) { | |
162 psxRcntReset(1); | |
163 } | |
164 | |
165 if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) { | |
166 psxRcntReset(2); | |
167 } | |
168 | |
169 psxRcntSet(); | |
170 | |
171 } | |
172 | |
173 void psxRcntWcount(u32 index, u32 value) { | |
174 psxCounters[index].count = value; | |
175 psxRcntUpd(index); | |
176 psxRcntSet(); | |
177 } | |
178 | |
179 void psxRcntWmode(u32 index, u32 value) { | |
180 psxCounters[index].mode = value; | |
181 psxCounters[index].count = 0; | |
182 | |
183 if(index == 0) { | |
184 switch (value & 0x300) { | |
185 case 0x100: | |
186 psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok | |
187 break; | |
188 default: | |
189 psxCounters[index].rate = 1; | |
190 } | |
191 } | |
192 else if(index == 1) { | |
193 switch (value & 0x300) { | |
194 case 0x100: | |
195 psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok | |
196 //psxCounters[index].rate = (PSXCLK / 60)/262; //(psxCounters[3].rate*16/262); | |
197 //printf("%d\n",psxCounters[index].rate); | |
198 break; | |
199 default: | |
200 psxCounters[index].rate = 1; | |
201 } | |
202 } | |
203 else if(index == 2) { | |
204 switch (value & 0x300) { | |
205 case 0x200: | |
206 psxCounters[index].rate = 8; // 1/8 speed | |
207 break; | |
208 default: | |
209 psxCounters[index].rate = 1; // normal speed | |
210 } | |
211 } | |
212 | |
213 // Need to set a rate and target | |
214 psxRcntUpd(index); | |
215 psxRcntSet(); | |
216 } | |
217 | |
218 void psxRcntWtarget(u32 index, u32 value) { | |
219 // SysPrintf("writeCtarget[%ld] = %lx\n", index, value); | |
220 psxCounters[index].target = value; | |
221 psxRcntUpd(index); | |
222 psxRcntSet(); | |
223 } | |
224 | |
225 u32 psxRcntRcount(u32 index) { | |
226 u32 ret; | |
227 | |
228 // if ((!(psxCounters[index].mode & 1)) || (index!=2)) { | |
229 if (psxCounters[index].mode & 0x08) { // Wrap at target | |
230 //if (Config.RCntFix) { // Parasite Eve 2 | |
231 // ret = (psxCounters[index].count + /*BIAS **/ ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; | |
232 //} else { | |
233 ret = (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; | |
234 //} | |
235 } else { // Wrap at 0xffff | |
236 ret = (psxCounters[index].count + BIAS * (psxRegs.cycle / psxCounters[index].rate)) & 0xffff; | |
237 //if (Config.RCntFix) { // Vandal Hearts 1/2 | |
238 // ret/= 16; | |
239 //} | |
240 } | |
241 // return (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; | |
242 // } else return 0; | |
243 | |
244 // SysPrintf("readCcount[%ld] = %lx (mode %lx, target %lx, cycle %lx)\n", index, ret, psxCounters[index].mode, psxCounters[index].target, psxRegs.cycle); | |
245 | |
246 return ret; | |
247 } |