/* 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 #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= 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; }