+August 7, 2010 Wei Mingzhi <whistler_wmz@users.sf.net>\r
+\r
+ * libpcsxcore/r3000a.h: Refactored the interrupt scheduling code to make it a\r
+ little more readable than using the "magic" numbers.\r
+ * libpcsxcore/r3000a.c: Likewise.\r
+ * libpcsxcore/cdrom.c: Likewise.\r
+ * libpcsxcore/mdec.c: Likewise.\r
+ * libpcsxcore/sio.c: Likewise.\r
+ * libpcsxcore/psxdma.h: Likewise.\r
+ * libpcsxcore/misc.c: Bumped savestate version.\r
+ * debian/changelog: Updated version.\r
+ * macosx/Info.plist: Likewise.\r
+ * po/zh_TW.po: Corrected a minor translation error.\r
+\r
August 2, 2010 Wei Mingzhi <whistler_wmz@users.sf.net>\r
\r
* macosx/Pcsx.xcodeproj/project.pbxproj: Added some more optimizations\r
static struct SubQ *subq;
#define CDR_INT(eCycle) { \
- psxRegs.interrupt |= 0x4; \
- psxRegs.intCycle[2 + 1] = eCycle; \
- psxRegs.intCycle[2] = psxRegs.cycle; \
- new_dyna_set_event(0, eCycle); \
+ psxRegs.interrupt |= (1 << PSXINT_CDR); \
+ psxRegs.intCycle[PSXINT_CDR].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_CDR].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_CDR, eCycle); \
}
#define CDREAD_INT(eCycle) { \
- psxRegs.interrupt |= 0x40000; \
- psxRegs.intCycle[2 + 16 + 1] = eCycle; \
- psxRegs.intCycle[2 + 16] = psxRegs.cycle; \
- new_dyna_set_event(2, eCycle); \
+ psxRegs.interrupt |= (1 << PSXINT_CDREAD); \
+ psxRegs.intCycle[PSXINT_CDREAD].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_CDREAD, eCycle); \
}
#define StartReading(type, eCycle) { \
#define StopReading() { \
if (cdr.Reading) { \
cdr.Reading = 0; \
- psxRegs.interrupt &= ~0x40000; \
+ psxRegs.interrupt &= ~(1 << PSXINT_CDREAD); \
} \
cdr.StatP &= ~0x20;\
}
if (HW_DMA1_CHCR & SWAP32(0x01000000)) {
// Set a fixed value totaly arbitrarie another sound value is
// PSXCLK / 60 or PSXCLK / 50 since the bug happened at end of frame.
- // PSXCLK / 1000 seems good for FF9. (for FF9 need < ~28000)
+ // PSXCLK / 500 seems good for FF9.
// CAUTION: commented interrupt-handling may lead to problems, keep an eye ;-)
- MDECOUTDMA_INT(PSXCLK / 1000 * BIAS);
-// psxRegs.interrupt |= 0x02000000;
-// psxRegs.intCycle[5 + 24 + 1] *= 8;
-// psxRegs.intCycle[5 + 24] = psxRegs.cycle;
+ MDECOUTDMA_INT(PSXCLK / 500);
+// MDECOUTDMA_INT(psxRegs.intCycle[PSXINT_MDECOUTDMA].cycle * 8);
+
HW_DMA1_CHCR &= SWAP32(~0x01000000);
DMA_INTERRUPT(1);
} else {
// Savestate Versioning!
// If you make changes to the savestate version, please increment the value below.
-static const u32 SaveVersion = 0x8b410004;
+static const u32 SaveVersion = 0x8b410005;
int SaveState(const char *file) {
gzFile f;
#include "emu_if.h"
#include "pcsxmem.h"
#include "../psxhle.h"
+#include "../r3000a.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define evprintf(...)
char invalid_code[0x100000];
-u32 event_cycles[7];
+u32 event_cycles[PSXINT_COUNT];
static void schedule_timeslice(void)
{
{
psxHu16ref(0x1074) = value;
if (psxHu16ref(0x1070) & value)
- new_dyna_set_event(6, 1);
+ new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
}
static void io_write_ireg32(u32 value)
{
psxHu32ref(0x1074) = value;
if (psxHu32ref(0x1070) & value)
- new_dyna_set_event(6, 1);
+ new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
}
static void io_write_dma_icr32(u32 value)
#include "psxmem.h"
#define GPUDMA_INT(eCycle) { \
- psxRegs.interrupt |= 0x01000000; \
- psxRegs.intCycle[3 + 24 + 1] = eCycle; \
- psxRegs.intCycle[3 + 24] = psxRegs.cycle; \
- new_dyna_set_event(3, eCycle); \
+ psxRegs.interrupt |= (1 << PSXINT_GPUDMA); \
+ psxRegs.intCycle[PSXINT_GPUDMA].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_GPUDMA].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_GPUDMA, eCycle); \
}
#define SPUDMA_INT(eCycle) { \
- psxRegs.interrupt |= 0x04000000; \
- psxRegs.intCycle[1 + 24 + 1] = eCycle; \
- psxRegs.intCycle[1 + 24] = psxRegs.cycle; \
- new_dyna_set_event(5, eCycle); \
+ psxRegs.interrupt |= (1 << PSXINT_SPUDMA); \
+ psxRegs.intCycle[PSXINT_SPUDMA].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_SPUDMA].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_SPUDMA, eCycle); \
}
#define MDECOUTDMA_INT(eCycle) { \
- psxRegs.interrupt |= 0x02000000; \
- psxRegs.intCycle[5 + 24 + 1] = eCycle; \
- psxRegs.intCycle[5 + 24] = psxRegs.cycle; \
- new_dyna_set_event(4, eCycle); \
+ psxRegs.interrupt |= (1 << PSXINT_MDECOUTDMA); \
+ psxRegs.intCycle[PSXINT_MDECOUTDMA].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_MDECOUTDMA, eCycle); \
}
void psxDma2(u32 madr, u32 bcr, u32 chcr);
#endif
psxHu16ref(0x1074) = SWAPu16(value);
if (psxHu16ref(0x1070) & value)
- new_dyna_set_event(6, 1);
+ new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
return;
case 0x1f801100:
#endif
psxHu32ref(0x1074) = SWAPu32(value);
if (psxHu32ref(0x1070) & value)
- new_dyna_set_event(6, 1);
+ new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
return;
#ifdef PSXHW_LOG
void psxMemWrite32(u32 mem, u32 value);
void *psxMemPointer(u32 mem);
-extern u32 event_cycles[7];
-extern u32 next_interupt;
-
-#define new_dyna_set_event(e, c) { \
- s32 c_ = c; \
- u32 abs_ = psxRegs.cycle + c_; \
- s32 odi_ = next_interupt - psxRegs.cycle; \
- event_cycles[e] = abs_; \
- if (c_ < odi_) { \
- /*printf("%u: next_interupt %d -> %d (%u)\n", psxRegs.cycle, odi_, c_, abs_);*/ \
- next_interupt = abs_; \
- } \
-}
-
#ifdef __cplusplus
}
#endif
psxRcntUpdate();
if (psxRegs.interrupt) {
- if ((psxRegs.interrupt & 0x80) && !Config.Sio) { // sio
- if ((psxRegs.cycle - psxRegs.intCycle[7]) >= psxRegs.intCycle[7 + 1]) {
- psxRegs.interrupt &= ~0x80;
+ if ((psxRegs.interrupt & (1 << PSXINT_SIO)) && !Config.Sio) { // sio
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SIO].sCycle) >= psxRegs.intCycle[PSXINT_SIO].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_SIO);
sioInterrupt();
}
}
- if (psxRegs.interrupt & 0x04) { // cdr
- if ((psxRegs.cycle - psxRegs.intCycle[2]) >= psxRegs.intCycle[2 + 1]) {
- psxRegs.interrupt &= ~0x04;
+ if (psxRegs.interrupt & (1 << PSXINT_CDR)) { // cdr
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDR].sCycle) >= psxRegs.intCycle[PSXINT_CDR].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_CDR);
cdrInterrupt();
}
}
- if (psxRegs.interrupt & 0x040000) { // cdr read
- if ((psxRegs.cycle - psxRegs.intCycle[2 + 16]) >= psxRegs.intCycle[2 + 16 + 1]) {
- psxRegs.interrupt &= ~0x040000;
+ if (psxRegs.interrupt & (1 << PSXINT_CDREAD)) { // cdr read
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDREAD].sCycle) >= psxRegs.intCycle[PSXINT_CDREAD].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_CDREAD);
cdrReadInterrupt();
}
}
- if (psxRegs.interrupt & 0x01000000) { // gpu dma
- if ((psxRegs.cycle - psxRegs.intCycle[3 + 24]) >= psxRegs.intCycle[3 + 24 + 1]) {
- psxRegs.interrupt &= ~0x01000000;
+ if (psxRegs.interrupt & (1 << PSXINT_GPUDMA)) { // gpu dma
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_GPUDMA].sCycle) >= psxRegs.intCycle[PSXINT_GPUDMA].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_GPUDMA);
gpuInterrupt();
}
}
- if (psxRegs.interrupt & 0x02000000) { // mdec out dma
- if ((psxRegs.cycle - psxRegs.intCycle[5 + 24]) >= psxRegs.intCycle[5 + 24 + 1]) {
- psxRegs.interrupt &= ~0x02000000;
+ if (psxRegs.interrupt & (1 << PSXINT_MDECOUTDMA)) { // mdec out dma
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle) >= psxRegs.intCycle[PSXINT_MDECOUTDMA].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_MDECOUTDMA);
mdec1Interrupt();
}
}
- if (psxRegs.interrupt & 0x04000000) { // spu dma
- if ((psxRegs.cycle - psxRegs.intCycle[1 + 24]) >= psxRegs.intCycle[1 + 24 + 1]) {
- psxRegs.interrupt &= ~0x04000000;
+ if (psxRegs.interrupt & (1 << PSXINT_SPUDMA)) { // spu dma
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SPUDMA].sCycle) >= psxRegs.intCycle[PSXINT_SPUDMA].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_SPUDMA);
spuInterrupt();
}
}
PAIR p[32];
} psxCP2Ctrl;
+enum {
+ PSXINT_SIO = 0,
+ PSXINT_CDR,
+ PSXINT_CDREAD,
+ PSXINT_GPUDMA,
+ PSXINT_MDECOUTDMA,
+ PSXINT_SPUDMA,
+ PSXINT_NEWDRC_CHECK,
+ PSXINT_COUNT
+};
+
typedef struct {
psxGPRRegs GPR; /* General Purpose Registers */
psxCP0Regs CP0; /* Coprocessor0 Registers */
u32 code; /* The instruction */
u32 cycle;
u32 interrupt;
- u32 intCycle[32];
+ struct { u32 sCycle, cycle; } intCycle[32];
} psxRegisters;
extern psxRegisters psxRegs;
+/* new_dynarec stuff */
+extern u32 event_cycles[PSXINT_COUNT];
+extern u32 next_interupt;
+
+#define new_dyna_set_event(e, c) { \
+ s32 c_ = c; \
+ u32 abs_ = psxRegs.cycle + c_; \
+ s32 odi_ = next_interupt - psxRegs.cycle; \
+ event_cycles[e] = abs_; \
+ if (c_ < odi_) { \
+ /*printf("%u: next_interupt %d -> %d (%u)\n", psxRegs.cycle, odi_, c_, abs_);*/ \
+ next_interupt = abs_; \
+ } \
+}
+
#if defined(__BIGENDIAN__)
#define _i32(x) *(s32 *)&x
char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE];
+#define SIO_INT(eCycle) { \
+ if (!Config.Sio) { \
+ psxRegs.interrupt |= (1 << PSXINT_SIO); \
+ psxRegs.intCycle[PSXINT_SIO].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_SIO].sCycle = psxRegs.cycle; \
+ new_dyna_set_event(PSXINT_SIO, eCycle); \
+ } \
+}
+
// clk cycle byte
// 4us * 8bits = (PSXCLK / 1000000) * 32; (linuzappz)
// TODO: add SioModePrescaler and BaudReg
-static inline void SIO_INT() {
- if (!Config.Sio) {
- psxRegs.interrupt |= 0x80;
- psxRegs.intCycle[7 + 1] = 400;
- psxRegs.intCycle[7] = psxRegs.cycle;
- new_dyna_set_event(1, 400);
- }
-}
+#define SIO_CYCLES 535
void sioWrite8(unsigned char value) {
#ifdef PAD_LOG
PAD_LOG("sio write8 %x\n", value);
#endif
switch (padst) {
- case 1: SIO_INT();
+ case 1: SIO_INT(SIO_CYCLES);
if ((value & 0x40) == 0x40) {
padst = 2; parp = 1;
if (!Config.UseNet) {
parp++;
/* if (buf[1] == 0x45) {
buf[parp] = 0;
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
return;
}*/
if (!Config.UseNet) {
}
if (parp == bufcount) { padst = 0; return; }
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
return;
}
switch (mcdst) {
case 1:
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
if (rdwr) { parp++; return; }
parp = 1;
switch (value) {
}
return;
case 2: // address H
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
adrH = value;
*buf = 0;
parp = 0;
mcdst = 3;
return;
case 3: // address L
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
adrL = value;
*buf = adrH;
parp = 0;
mcdst = 4;
return;
case 4:
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
parp = 0;
switch (rdwr) {
case 1: // read
if (rdwr == 2) {
if (parp < 128) buf[parp + 1] = value;
}
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
return;
}
bufcount = 2;
parp = 0;
padst = 1;
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
return;
case 0x81: // start memcard
StatReg |= RX_RDY;
bufcount = 3;
mcdst = 1;
rdwr = 0;
- SIO_INT();
+ SIO_INT(SIO_CYCLES);
return;
}
}
if ((CtrlReg & SIO_RESET) || (!CtrlReg)) {
padst = 0; mcdst = 0; parp = 0;
StatReg = TX_RDY | TX_EMPTY;
- psxRegs.interrupt &= ~0x80;
+ psxRegs.interrupt &= ~(1 << PSXINT_SIO);
}
}