X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fsio.c;h=b3732d298ba623ad296c9a640931354e30c8b53a;hp=230bfed17c1c13708a791d3b2c7d8c361fbf09d9;hb=HEAD;hpb=ae602c19f527fbc1f44cdb744cf824d04b8eceb1 diff --git a/libpcsxcore/sio.c b/libpcsxcore/sio.c index 230bfed1..0bc763ca 100644 --- a/libpcsxcore/sio.c +++ b/libpcsxcore/sio.c @@ -21,9 +21,16 @@ * SIO functions. */ +#include "misc.h" +#include "psxcounters.h" +#include "psxevents.h" #include "sio.h" #include +#ifdef USE_LIBRETRO_VFS +#include +#endif + // Status Flags #define TX_RDY 0x0001 #define RX_RDY 0x0002 @@ -48,7 +55,8 @@ // *** FOR WORKS ON PADS AND MEMORY CARDS ***** static unsigned char buf[256]; -unsigned char cardh[4] = { 0x00, 0x00, 0x5a, 0x5d }; +static unsigned char cardh1[4] = { 0xff, 0x08, 0x5a, 0x5d }; +static unsigned char cardh2[4] = { 0xff, 0x08, 0x5a, 0x5d }; // Transfer Ready and the Buffer is Empty // static unsigned short StatReg = 0x002b; @@ -64,80 +72,57 @@ static unsigned char adrH, adrL; static unsigned int padst; char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE]; +char McdDisable[2]; // 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, psxRegs.cycle + 400); - } -} +#define SIO_CYCLES 535 void sioWrite8(unsigned char value) { -#ifdef PAD_LOG - PAD_LOG("sio write8 %x\n", value); + int more_data = 0; +#if 0 + s32 framec = psxRegs.cycle - rcnts[3].cycleStart; + printf("%d:%03d sio write8 %04x %02x\n", frame_counter, + (s32)(framec / (PSXCLK / 60 / 263.0f)), CtrlReg, value); #endif switch (padst) { - case 1: SIO_INT(); + case 1: if ((value & 0x40) == 0x40) { padst = 2; parp = 1; - if (!Config.UseNet) { - switch (CtrlReg & 0x2002) { - case 0x0002: - buf[parp] = PAD1_poll(value); - break; - case 0x2002: - buf[parp] = PAD2_poll(value); - break; - } - }/* else { -// SysPrintf("%x: %x, %x, %x, %x\n", CtrlReg&0x2002, buf[2], buf[3], buf[4], buf[5]); - }*/ - - if (!(buf[parp] & 0x0f)) { - bufcount = 2 + 32; - } else { - bufcount = 2 + (buf[parp] & 0x0f) * 2; + switch (CtrlReg & 0x2002) { + case 0x0002: + buf[parp] = PAD1_poll(value, &more_data); + break; + case 0x2002: + buf[parp] = PAD2_poll(value, &more_data); + break; } - if (buf[parp] == 0x41) { - switch (value) { - case 0x43: - buf[1] = 0x43; - break; - case 0x45: - buf[1] = 0xf3; - break; - } + + if (more_data) { + bufcount = parp + 1; + set_event(PSXINT_SIO, SIO_CYCLES); } } else padst = 0; return; case 2: parp++; -/* if (buf[1] == 0x45) { - buf[parp] = 0; - SIO_INT(); - return; - }*/ - if (!Config.UseNet) { - switch (CtrlReg & 0x2002) { - case 0x0002: buf[parp] = PAD1_poll(value); break; - case 0x2002: buf[parp] = PAD2_poll(value); break; - } + switch (CtrlReg & 0x2002) { + case 0x0002: buf[parp] = PAD1_poll(value, &more_data); break; + case 0x2002: buf[parp] = PAD2_poll(value, &more_data); break; } - if (parp == bufcount) { padst = 0; return; } - SIO_INT(); + if (more_data) { + bufcount = parp + 1; + set_event(PSXINT_SIO, SIO_CYCLES); + } return; } switch (mcdst) { case 1: - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); if (rdwr) { parp++; return; } parp = 1; switch (value) { @@ -147,7 +132,7 @@ void sioWrite8(unsigned char value) { } return; case 2: // address H - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); adrH = value; *buf = 0; parp = 0; @@ -155,7 +140,7 @@ void sioWrite8(unsigned char value) { mcdst = 3; return; case 3: // address L - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); adrL = value; *buf = adrH; parp = 0; @@ -163,7 +148,7 @@ void sioWrite8(unsigned char value) { mcdst = 4; return; case 4: - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); parp = 0; switch (rdwr) { case 1: // read @@ -202,10 +187,18 @@ void sioWrite8(unsigned char value) { return; case 5: parp++; + if ((rdwr == 1 && parp == 132) || + (rdwr == 2 && parp == 129)) { + // clear "new card" flags + if (CtrlReg & 0x2000) + cardh2[1] &= ~8; + else + cardh1[1] &= ~8; + } if (rdwr == 2) { if (parp < 128) buf[parp + 1] = value; } - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); return; } @@ -213,56 +206,41 @@ void sioWrite8(unsigned char value) { case 0x01: // start pad StatReg |= RX_RDY; // Transfer is Ready - if (!Config.UseNet) { - switch (CtrlReg & 0x2002) { - case 0x0002: buf[0] = PAD1_startPoll(1); break; - case 0x2002: buf[0] = PAD2_startPoll(2); break; - } - } else { - if ((CtrlReg & 0x2002) == 0x0002) { - int i, j; - - PAD1_startPoll(1); - buf[0] = 0; - buf[1] = PAD1_poll(0x42); - if (!(buf[1] & 0x0f)) { - bufcount = 32; - } else { - bufcount = (buf[1] & 0x0f) * 2; - } - buf[2] = PAD1_poll(0); - i = 3; - j = bufcount; - while (j--) { - buf[i++] = PAD1_poll(0); - } - bufcount+= 3; - - if (NET_sendPadData(buf, bufcount) == -1) - netError(); - - if (NET_recvPadData(buf, 1) == -1) - netError(); - if (NET_recvPadData(buf + 128, 2) == -1) - netError(); - } else { - memcpy(buf, buf + 128, 32); - } + switch (CtrlReg & 0x2002) { + case 0x0002: buf[0] = PAD1_startPoll(1); break; + case 0x2002: buf[0] = PAD2_startPoll(2); break; } - - bufcount = 2; + bufcount = 1; parp = 0; padst = 1; - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); return; case 0x81: // start memcard + if (CtrlReg & 0x2000) + { + if (McdDisable[1]) + goto no_device; + memcpy(buf, cardh2, 4); + } + else + { + if (McdDisable[0]) + goto no_device; + memcpy(buf, cardh1, 4); + } StatReg |= RX_RDY; - memcpy(buf, cardh, 4); parp = 0; bufcount = 3; mcdst = 1; rdwr = 0; - SIO_INT(); + set_event(PSXINT_SIO, SIO_CYCLES); + return; + default: + no_device: + StatReg |= RX_RDY; + buf[0] = 0xff; + parp = 0; + bufcount = 0; return; } } @@ -277,10 +255,10 @@ void sioWriteMode16(unsigned short value) { void sioWriteCtrl16(unsigned short value) { CtrlReg = value & ~RESET_ERR; if (value & RESET_ERR) StatReg &= ~IRQ; - if ((CtrlReg & SIO_RESET) || (!CtrlReg)) { + if ((CtrlReg & SIO_RESET) || !(CtrlReg & DTR)) { padst = 0; mcdst = 0; parp = 0; StatReg = TX_RDY | TX_EMPTY; - psxRegs.interrupt &= ~0x80; + psxRegs.interrupt &= ~(1 << PSXINT_SIO); } } @@ -319,8 +297,10 @@ unsigned char sioRead8() { } } -#ifdef PAD_LOG - PAD_LOG("sio read8 ;ret = %x\n", ret); +#if 0 + s32 framec = psxRegs.cycle - rcnts[3].cycleStart; + printf("%d:%03d sio read8 %04x %02x\n", frame_counter, + (s32)((float)framec / (PSXCLK / 60 / 263.0f)), CtrlReg, ret); #endif return ret; } @@ -341,36 +321,47 @@ unsigned short sioReadBaud16() { return BaudReg; } -void netError() { - ClosePlugins(); - SysMessage(_("Connection closed!\n")); - - CdromId[0] = '\0'; - CdromLabel[0] = '\0'; - - SysRunGui(); -} - void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif // SysPrintf("Sio Interrupt\n"); - StatReg |= IRQ; - psxHu32ref(0x1070) |= SWAPu32(0x80); + if (!(StatReg & IRQ)) { + StatReg |= IRQ; + psxHu32ref(0x1070) |= SWAPu32(0x80); + } } void LoadMcd(int mcd, char *str) { FILE *f; char *data = NULL; - if (mcd == 1) data = Mcd1Data; - if (mcd == 2) data = Mcd2Data; + if (mcd != 1 && mcd != 2) + return; - if (*str == 0) { - sprintf(str, "memcards/card%d.mcd", mcd); - SysPrintf(_("No memory card value was specified - creating a default card %s\n"), str); + if (mcd == 1) { + data = Mcd1Data; + cardh1[1] |= 8; // mark as new + } + if (mcd == 2) { + data = Mcd2Data; + cardh2[1] |= 8; } + + McdDisable[mcd - 1] = 0; +#ifdef HAVE_LIBRETRO + // memcard1 is handled by libretro + if (mcd == 1) + return; +#endif + + if (str == NULL || strcmp(str, "none") == 0) { + McdDisable[mcd - 1] = 1; + return; + } + if (*str == 0) + return; + f = fopen(str, "rb"); if (f == NULL) { SysPrintf(_("The memory card %s doesn't exist - creating it\n"), str); @@ -385,7 +376,12 @@ void LoadMcd(int mcd, char *str) { else if(buf.st_size == MCD_SIZE + 3904) fseek(f, 3904, SEEK_SET); } - fread(data, 1, MCD_SIZE, f); + if (fread(data, 1, MCD_SIZE, f) != MCD_SIZE) { +#ifndef NDEBUG + SysPrintf(_("File IO error in <%s:%s>.\n"), __FILE__, __func__); +#endif + memset(data, 0x00, MCD_SIZE); + } fclose(f); } else @@ -400,7 +396,12 @@ void LoadMcd(int mcd, char *str) { else if(buf.st_size == MCD_SIZE + 3904) fseek(f, 3904, SEEK_SET); } - fread(data, 1, MCD_SIZE, f); + if (fread(data, 1, MCD_SIZE, f) != MCD_SIZE) { +#ifndef NDEBUG + SysPrintf(_("File IO error in <%s:%s>.\n"), __FILE__, __func__); +#endif + memset(data, 0x00, MCD_SIZE); + } fclose(f); } } @@ -413,6 +414,9 @@ void LoadMcds(char *mcd1, char *mcd2) { void SaveMcd(char *mcd, char *data, uint32_t adr, int size) { FILE *f; + if (mcd == NULL || *mcd == 0 || strcmp(mcd, "none") == 0) + return; + f = fopen(mcd, "r+b"); if (f != NULL) { struct stat buf; @@ -612,6 +616,7 @@ void ConvertMcd(char *mcd, char *data) { fclose(f); } f = fopen(mcd, "r+"); + if (f == NULL) return; s = s + 3904; fputc('1', f); s--; fputc('2', f); s--; @@ -646,6 +651,7 @@ void ConvertMcd(char *mcd, char *data) { fclose(f); } f = fopen(mcd, "r+"); + if (f == NULL) return; s = s + 64; fputc('V', f); s--; fputc('g', f); s--; @@ -671,13 +677,19 @@ void ConvertMcd(char *mcd, char *data) { } void GetMcdBlockInfo(int mcd, int block, McdBlock *Info) { - unsigned char *data = NULL, *ptr, *str, *sstr; + char *data = NULL, *ptr, *str, *sstr; unsigned short clut[16]; unsigned short c; int i, x; memset(Info, 0, sizeof(McdBlock)); + if (mcd != 1 && mcd != 2) + return; + + if (McdDisable[mcd - 1]) + return; + if (mcd == 1) data = Mcd1Data; if (mcd == 2) data = Mcd2Data; @@ -758,7 +770,7 @@ void GetMcdBlockInfo(int mcd, int block, McdBlock *Info) { strncpy(Info->Name, ptr, 16); } -int sioFreeze(gzFile f, int Mode) { +int sioFreeze(void *f, int Mode) { gzfreeze(buf, sizeof(buf)); gzfreeze(&StatReg, sizeof(StatReg)); gzfreeze(&ModeReg, sizeof(ModeReg));