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 }