summaryrefslogtreecommitdiff
path: root/PcsxSrc/PsxCounters.c
diff options
context:
space:
mode:
Diffstat (limited to 'PcsxSrc/PsxCounters.c')
-rw-r--r--PcsxSrc/PsxCounters.c404
1 files changed, 202 insertions, 202 deletions
diff --git a/PcsxSrc/PsxCounters.c b/PcsxSrc/PsxCounters.c
index a9bdabf..39a8a41 100644
--- a/PcsxSrc/PsxCounters.c
+++ b/PcsxSrc/PsxCounters.c
@@ -1,202 +1,202 @@
-/* Pcsx - Pc Psx Emulator
- * Copyright (C) 1999-2002 Pcsx Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <string.h>
-
-#include "PsxCommon.h"
-
-static int cnts = 4;
-
-static void psxRcntUpd(unsigned long index) {
- psxCounters[index].sCycle = psxRegs.cycle;
- if ((!(psxCounters[index].mode & 1)) || (index!=2)) {
- if (psxCounters[index].mode & 0x08) { // Count to target
- psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
- }
- else { // Count to 0xffff
- psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
- }
- } else psxCounters[index].Cycle = 0xffffffff;
-}
-
-static void psxRcntReset(unsigned long index) {
- psxCounters[index].count = 0;
- psxRcntUpd(index);
-
- if ((psxCounters[index].mode & 0x50) == 0x50) psxHu32(0x1070)|= psxCounters[index].interrupt;
-}
-
-static void psxRcntSet() {
- int i;
-
- psxNextCounter = 0x7fffffff;
- psxNextsCounter = psxRegs.cycle;
-
- for (i=0; i<cnts; i++) {
- long count = psxCounters[i].Cycle - (psxRegs.cycle - psxCounters[i].sCycle);
-
- if (count < 0) {
- psxNextCounter = 0; break;
- }
-
- if (count < (long)psxNextCounter) {
- psxNextCounter = count;
- }
- }
-}
-
-void psxRcntInit() {
-
- memset(psxCounters, 0, sizeof(psxCounters));
-
- psxCounters[0].rate = 1; psxCounters[0].interrupt = 16;
- psxCounters[1].rate = 1; psxCounters[1].interrupt = 32;
- psxCounters[2].rate = 1; psxCounters[2].interrupt = 64;
-
- psxCounters[3].interrupt = 1;
- psxCounters[3].mode = 0x58; // The VSync counter mode
- psxCounters[3].target = 1;
- UpdateVSyncRate();
-
- if (SPU_update != NULL) {
- cnts = 5;
-
- if (Config.PsxType)
- psxCounters[4].rate = (262 / 32) * 50; // pal
- else
- psxCounters[4].rate = (312 / 32) * 60; // ntsc
- psxCounters[4].target = 1;
- psxCounters[4].mode = 0x8;
- } else if (SPU_async != NULL) {
- cnts = 5;
-
- psxCounters[4].rate = 768 * 64;
- psxCounters[4].target = 1;
- psxCounters[4].mode = 0x8;
- } else cnts = 4;
-
- psxRcntUpd(0); psxRcntUpd(1); psxRcntUpd(2); psxRcntUpd(3);
- psxRcntSet();
-}
-
-void UpdateVSyncRate() {
- if (Config.PsxType) // ntsc - 0 | pal - 1
- psxCounters[3].rate = (PSXCLK / 50);// / BIAS;
- else psxCounters[3].rate = (PSXCLK / 60);// / BIAS;
-}
-
-void psxRcntUpdate() {
- if ((psxRegs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) {
- psxRcntReset(3);
- GPU_updateLace(); // updateGPU
- SysUpdate();
-#ifdef GTE_LOG
- GTE_LOG("VSync\n");
-#endif
- }
-
- if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) {
- psxRcntReset(0);
- }
-
- if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) {
- psxRcntReset(1);
- }
-
- if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) {
- psxRcntReset(2);
- }
-
- if (cnts >= 5) {
- if ((psxRegs.cycle - psxCounters[4].sCycle) >= psxCounters[4].Cycle) {
- if (SPU_update != NULL)
- SPU_update();
- if (SPU_async != NULL)
- SPU_async((psxRegs.cycle - psxCounters[4].sCycle) * BIAS);
- psxRcntReset(4);
- }
- }
-
- psxRcntSet();
-}
-
-void psxRcntWcount(unsigned long index, unsigned long value) {
-// SysPrintf("writeCcount[%d] = %x\n", index, value);
-// PSXCPU_LOG("writeCcount[%d] = %x\n", index, value);
- psxCounters[index].count = value;
- psxRcntUpd(index);
- psxRcntSet();
-}
-
-void psxRcntWmode(unsigned long index, unsigned long value) {
-// SysPrintf("writeCmode[%ld] = %lx\n", index, value);
- psxCounters[index].mode = value;
- if(index == 0) {
- switch (value & 0x300) {
- case 0x100:
- psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok
- break;
- default:
- psxCounters[index].rate = 1;
- }
- }
- else if(index == 1) {
- switch (value & 0x300) {
- case 0x100:
- psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok
- break;
- default:
- psxCounters[index].rate = 1;
- }
- }
- else if(index == 2) {
- switch (value & 0x300) {
- case 0x200:
- psxCounters[index].rate = 8; // 1/8 speed
- break;
- default:
- psxCounters[index].rate = 1; // normal speed
- }
- }
-
- // Need to set a rate and target
- psxRcntUpd(index);
- psxRcntSet();
-}
-
-void psxRcntWtarget(unsigned long index, unsigned long value) {
-// SysPrintf("writeCtarget[%ld] = %lx\n", index, value);
- psxCounters[index].target = value;
- psxRcntUpd(index);
- psxRcntSet();
-}
-
-unsigned long psxRcntRcount(unsigned long index) {
-// if ((!(psxCounters[index].mode & 1)) || (index!=2)) {
- return (psxCounters[index].count + BIAS * (psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate) & 0xffff;
-// } else return 0;
-}
-
-int psxRcntFreeze(gzFile f, int Mode) {
- char Unused[4096 - sizeof(psxCounter)];
-
- gzfreezel(psxCounters);
- gzfreezel(Unused);
-
- return 0;
-}
+/* Pcsx - Pc Psx Emulator
+ * Copyright (C) 1999-2002 Pcsx Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string.h>
+
+#include "PsxCommon.h"
+
+static int cnts = 4;
+
+static void psxRcntUpd(unsigned long index) {
+ psxCounters[index].sCycle = psxRegs.cycle;
+ if ((!(psxCounters[index].mode & 1)) || (index!=2)) {
+ if (psxCounters[index].mode & 0x08) { // Count to target
+ psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
+ }
+ else { // Count to 0xffff
+ psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
+ }
+ } else psxCounters[index].Cycle = 0xffffffff;
+}
+
+static void psxRcntReset(unsigned long index) {
+ psxCounters[index].count = 0;
+ psxRcntUpd(index);
+
+ if ((psxCounters[index].mode & 0x50) == 0x50) psxHu32(0x1070)|= psxCounters[index].interrupt;
+}
+
+static void psxRcntSet() {
+ int i;
+
+ psxNextCounter = 0x7fffffff;
+ psxNextsCounter = psxRegs.cycle;
+
+ for (i=0; i<cnts; i++) {
+ long count = psxCounters[i].Cycle - (psxRegs.cycle - psxCounters[i].sCycle);
+
+ if (count < 0) {
+ psxNextCounter = 0; break;
+ }
+
+ if (count < (long)psxNextCounter) {
+ psxNextCounter = count;
+ }
+ }
+}
+
+void psxRcntInit() {
+
+ memset(psxCounters, 0, sizeof(psxCounters));
+
+ psxCounters[0].rate = 1; psxCounters[0].interrupt = 16;
+ psxCounters[1].rate = 1; psxCounters[1].interrupt = 32;
+ psxCounters[2].rate = 1; psxCounters[2].interrupt = 64;
+
+ psxCounters[3].interrupt = 1;
+ psxCounters[3].mode = 0x58; // The VSync counter mode
+ psxCounters[3].target = 1;
+ UpdateVSyncRate();
+
+ if (SPU_update != NULL) {
+ cnts = 5;
+
+ if (Config.PsxType)
+ psxCounters[4].rate = (262 / 32) * 50; // pal
+ else
+ psxCounters[4].rate = (312 / 32) * 60; // ntsc
+ psxCounters[4].target = 1;
+ psxCounters[4].mode = 0x8;
+ } else if (SPU_async != NULL) {
+ cnts = 5;
+
+ psxCounters[4].rate = 768 * 64;
+ psxCounters[4].target = 1;
+ psxCounters[4].mode = 0x8;
+ } else cnts = 4;
+
+ psxRcntUpd(0); psxRcntUpd(1); psxRcntUpd(2); psxRcntUpd(3);
+ psxRcntSet();
+}
+
+void UpdateVSyncRate() {
+ if (Config.PsxType) // ntsc - 0 | pal - 1
+ psxCounters[3].rate = (PSXCLK / 50);// / BIAS;
+ else psxCounters[3].rate = (PSXCLK / 60);// / BIAS;
+}
+
+void psxRcntUpdate() {
+ if ((psxRegs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) {
+ psxRcntReset(3);
+ GPU_updateLace(); // updateGPU
+ SysUpdate();
+#ifdef GTE_LOG
+ GTE_LOG("VSync\n");
+#endif
+ }
+
+ if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) {
+ psxRcntReset(0);
+ }
+
+ if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) {
+ psxRcntReset(1);
+ }
+
+ if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) {
+ psxRcntReset(2);
+ }
+
+ if (cnts >= 5) {
+ if ((psxRegs.cycle - psxCounters[4].sCycle) >= psxCounters[4].Cycle) {
+ if (SPU_update != NULL)
+ SPU_update();
+ if (SPU_async != NULL)
+ SPU_async((psxRegs.cycle - psxCounters[4].sCycle) * BIAS);
+ psxRcntReset(4);
+ }
+ }
+
+ psxRcntSet();
+}
+
+void psxRcntWcount(unsigned long index, unsigned long value) {
+// SysPrintf("writeCcount[%d] = %x\n", index, value);
+// PSXCPU_LOG("writeCcount[%d] = %x\n", index, value);
+ psxCounters[index].count = value;
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+void psxRcntWmode(unsigned long index, unsigned long value) {
+// SysPrintf("writeCmode[%ld] = %lx\n", index, value);
+ psxCounters[index].mode = value;
+ if(index == 0) {
+ switch (value & 0x300) {
+ case 0x100:
+ psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok
+ break;
+ default:
+ psxCounters[index].rate = 1;
+ }
+ }
+ else if(index == 1) {
+ switch (value & 0x300) {
+ case 0x100:
+ psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok
+ break;
+ default:
+ psxCounters[index].rate = 1;
+ }
+ }
+ else if(index == 2) {
+ switch (value & 0x300) {
+ case 0x200:
+ psxCounters[index].rate = 8; // 1/8 speed
+ break;
+ default:
+ psxCounters[index].rate = 1; // normal speed
+ }
+ }
+
+ // Need to set a rate and target
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+void psxRcntWtarget(unsigned long index, unsigned long value) {
+// SysPrintf("writeCtarget[%ld] = %lx\n", index, value);
+ psxCounters[index].target = value;
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+unsigned long psxRcntRcount(unsigned long index) {
+// if ((!(psxCounters[index].mode & 1)) || (index!=2)) {
+ return (psxCounters[index].count + BIAS * (psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate) & 0xffff;
+// } else return 0;
+}
+
+int psxRcntFreeze(gzFile f, int Mode) {
+ char Unused[4096 - sizeof(psxCounter)];
+
+ gzfreezel(psxCounters);
+ gzfreezel(Unused);
+
+ return 0;
+}