From 89ec56af209740711ee442d93c2e80fe3cf2d79f Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 11 Jan 2013 02:47:50 +0200 Subject: cdrom: fix ID also adjust ReadTOC timing and logs --- libpcsxcore/cdrom.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 2a1ce61..17fbf4c 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -941,34 +941,23 @@ void cdrInterrupt() { case CdlID + 0x20: SetResultSize(8); + cdr.Result[0] = cdr.StatP; + cdr.Result[1] = 0; + cdr.Result[2] = 0; + cdr.Result[3] = 0; + // 0x10 - audio | 0x80 - unlicensed if (CDR_getStatus(&stat) == -1) { - cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player cdr.Result[1] = 0x80; // 0x80 leads to the menu in the bios, else loads CD } else { - if (stat.Type == 2) { - // Music CD - cdr.Result[0] = 0x08; - cdr.Result[1] = 0x10; - + if (stat.Type == 2) + cdr.Result[1] |= 0x10; + if (CdromId[0] == '\0') cdr.Result[1] |= 0x80; - } - else { - // Data CD - if (CdromId[0] == '\0') { - cdr.Result[0] = 0x00; - cdr.Result[1] = 0x80; - } - else { - cdr.Result[0] = 0x08; - cdr.Result[1] = 0x00; - } - } } + cdr.Result[0] |= (cdr.Result[1] >> 4) & 0x08; - cdr.Result[2] = 0x00; - cdr.Result[3] = 0x00; strncpy((char *)&cdr.Result[4], "PCSX", 4); cdr.Stat = Complete; break; @@ -1000,7 +989,7 @@ void cdrInterrupt() { cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; - AddIrqQueue(CdlReadToc + 0x20, 0x800); + AddIrqQueue(CdlReadToc + 0x20, cdReadTime * 16); break; case CdlReadToc + 0x20: @@ -1068,8 +1057,8 @@ void cdrInterrupt() { setIrq(); #ifdef CDR_LOG_CMD_IRQ - SysPrintf("cdrInterrupt() Log: CDR Interrupt IRQ %d %02x: ", - cdr.Stat != NoIntr && cdr.Reg2 != 0x18, Irq); + SysPrintf("IRQ %d cmd %02x stat %02x: ", + !!(cdr.Stat & cdr.Reg2), Irq, cdr.Stat); for (i = 0; i < cdr.ResultC; i++) SysPrintf("%02x ", cdr.Result[i]); SysPrintf("\n"); @@ -1295,7 +1284,7 @@ void cdrWrite1(unsigned char rt) { cdr.OCUP = 0; #ifdef CDR_LOG_CMD_IRQ - SysPrintf("cdrWrite1() Log: CD1 write: %x (%s)", rt, CmdName[rt]); + SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); if (cdr.ParamC) { SysPrintf(" Param[%d] = {", cdr.ParamC); for (i = 0; i < cdr.ParamC; i++) -- cgit v1.2.3 From cd0c9f5b179b2fac3397cb4aa1de1509247a27d0 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 11 Jan 2013 03:51:58 +0200 Subject: cdrom: minor cleanup --- libpcsxcore/cdrom.c | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 17fbf4c..c96eac7 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -108,6 +108,7 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; #define MODE_STRSND (1<<6) // 0x40 ADPCM on/off #define MODE_SIZE_2340 (1<<5) // 0x20 #define MODE_SIZE_2328 (1<<4) // 0x10 +#define MODE_SIZE_2048 (0<<4) // 0x00 #define MODE_SF (1<<3) // 0x08 channel on/off #define MODE_REPORT (1<<2) // 0x04 #define MODE_AUTOPAUSE (1<<1) // 0x02 @@ -124,7 +125,6 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; #define STATUS_ERROR (1<<0) // 0x01 - // 1x = 75 sectors per second // PSXCLK = 1 sec in the ps // so (PSXCLK / 75) = cdr read time (linuzappz) @@ -617,7 +617,7 @@ void cdrInterrupt() { SetResultSize(1); cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; + cdr.Stat = Acknowledge; break; case CdlNop: @@ -1160,24 +1160,14 @@ void cdrReadInterrupt() { cdr.Channel = cdr.Transfer[4 + 1]; } - if ((cdr.Transfer[4 + 2] & 0x4) && + if((cdr.Transfer[4 + 2] & 0x4) && (cdr.Transfer[4 + 1] == cdr.Channel) && - (cdr.Transfer[4 + 0] == cdr.File)) { + (cdr.Transfer[4 + 0] == cdr.File)) { int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); if (!ret) { - cdrAttenuate(cdr.Xa.pcm, cdr.Xa.nsamples, cdr.Xa.stereo); SPU_playADPCMchannel(&cdr.Xa); cdr.FirstSector = 0; - -#if 0 - // Crash Team Racing: music, speech - // - done using cdda decoded buffer (spu irq) - // - don't do here - - // signal ADPCM data ready - setIrq(); -#endif } else cdr.FirstSector = -1; } @@ -1338,23 +1328,8 @@ void cdrWrite1(unsigned char rt) { // Vib Ribbon: try same track again StopCdda(); -#if 0 - if (!cdr.SetSector[0] & !cdr.SetSector[1] & !cdr.SetSector[2]) { - if (CDR_getTN(cdr.ResultTN) != -1) { - if (cdr.CurTrack > cdr.ResultTN[1]) - cdr.CurTrack = cdr.ResultTN[1]; - if (CDR_getTD((unsigned char)(cdr.CurTrack), cdr.ResultTD) != -1) { - int tmp = cdr.ResultTD[2]; - cdr.ResultTD[2] = cdr.ResultTD[0]; - cdr.ResultTD[0] = tmp; - if (!Config.Cdda) CDR_play(cdr.ResultTD); - } - } - } -#endif // Vib Ribbon - decoded buffer IRQ for CDDA reading // - fixes ribbon timing + music CD mode - //TODO? //CDRDBUF_INT( PSXCLK / 44100 * 0x100 ); cdr.Play = TRUE; @@ -1579,10 +1554,11 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { // - fix boot if( cdsize == 0 ) { - switch (cdr.Mode & 0x30) { - case 0x00: cdsize = 2048; break; - case MODE_SIZE_2328: cdsize = 2328; break; + switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { case MODE_SIZE_2340: cdsize = 2340; break; + case MODE_SIZE_2328: cdsize = 2328; break; + default: + case MODE_SIZE_2048: cdsize = 2048; break; } } -- cgit v1.2.3 From e999be41a61fbcdac56a2082e277d22aa7349bcc Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 12 Jan 2013 02:48:41 +0000 Subject: cdriso: improve .toc handling --- libpcsxcore/cdriso.c | 53 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 94bd3eb..7798774 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -289,10 +289,11 @@ static void startCDDA(void) { static int parsetoc(const char *isofile) { char tocname[MAXPATHLEN]; FILE *fi; - char linebuf[256], dummy[256], name[256]; + char linebuf[256], tmp[256], name[256]; char *token; char time[20], time2[20]; - unsigned int t, sector_offs; + unsigned int t, sector_offs, sector_size; + unsigned int current_zero_gap = 0; numtracks = 0; @@ -328,17 +329,21 @@ static int parsetoc(const char *isofile) { memset(&ti, 0, sizeof(ti)); cddaBigEndian = TRUE; // cdrdao uses big-endian for CD Audio + sector_size = CD_FRAMESIZE_RAW; sector_offs = 2 * 75; // parse the .toc file while (fgets(linebuf, sizeof(linebuf), fi) != NULL) { // search for tracks - strncpy(dummy, linebuf, sizeof(linebuf)); - token = strtok(dummy, " "); + strncpy(tmp, linebuf, sizeof(linebuf)); + token = strtok(tmp, " "); if (token == NULL) continue; if (!strcmp(token, "TRACK")) { + sector_offs += current_zero_gap; + current_zero_gap = 0; + // get type of track token = strtok(NULL, " "); numtracks++; @@ -349,9 +354,11 @@ static int parsetoc(const char *isofile) { // check if this image contains mixed subchannel data token = strtok(NULL, " "); - if (token != NULL && !strncmp(token, "RW_RAW", 6)) { + if (token != NULL && !strncmp(token, "RW", 2)) { + sector_size = CD_FRAMESIZE_RAW + SUB_FRAMESIZE; subChanMixed = TRUE; - subChanRaw = TRUE; + if (!strncmp(token, "RW_RAW", 6)) + subChanRaw = TRUE; } } else if (!strncmp(token, "AUDIO", 5)) { @@ -362,8 +369,7 @@ static int parsetoc(const char *isofile) { if (ti[numtracks].type == CDDA) { sscanf(linebuf, "DATAFILE \"%[^\"]\" #%d %8s", name, &t, time2); ti[numtracks].start_offset = t; - t /= CD_FRAMESIZE_RAW + (subChanMixed ? SUB_FRAMESIZE : 0); - t += sector_offs; + t = t / sector_size + sector_offs; sec2msf(t, (char *)&ti[numtracks].start); tok2msf((char *)&time2, (char *)&ti[numtracks].length); } @@ -375,22 +381,39 @@ static int parsetoc(const char *isofile) { else if (!strcmp(token, "FILE")) { sscanf(linebuf, "FILE \"%[^\"]\" #%d %8s %8s", name, &t, time, time2); tok2msf((char *)&time, (char *)&ti[numtracks].start); + t += msf2sec(ti[numtracks].start) * sector_size; ti[numtracks].start_offset = t; - t /= CD_FRAMESIZE_RAW + (subChanMixed ? SUB_FRAMESIZE : 0); - t += msf2sec(ti[numtracks].start) + sector_offs; + t = t / sector_size + sector_offs; sec2msf(t, (char *)&ti[numtracks].start); tok2msf((char *)&time2, (char *)&ti[numtracks].length); } - else if (!strcmp(token, "ZERO")) { - sscanf(linebuf, "ZERO AUDIO RW_RAW %8s", time); - tok2msf((char *)&time, dummy); - sector_offs += msf2sec(dummy); + else if (!strcmp(token, "ZERO") || !strcmp(token, "SILENCE")) { + // skip unneeded optional fields + while (token != NULL) { + token = strtok(NULL, " "); + if (strchr(token, ':') != NULL) + break; + } + if (token != NULL) { + tok2msf(token, tmp); + current_zero_gap = msf2sec(tmp); + } if (numtracks > 1) { t = ti[numtracks - 1].start_offset; - t /= CD_FRAMESIZE_RAW + (subChanMixed ? SUB_FRAMESIZE : 0); + t /= sector_size; pregapOffset = t + msf2sec(ti[numtracks - 1].length); } } + else if (!strcmp(token, "START")) { + token = strtok(NULL, " "); + if (token != NULL && strchr(token, ':')) { + tok2msf(token, tmp); + t = msf2sec(tmp); + ti[numtracks].start_offset += (t - current_zero_gap) * sector_size; + t = msf2sec(ti[numtracks].start) + t; + sec2msf(t, (char *)&ti[numtracks].start); + } + } } fclose(fi); -- cgit v1.2.3 From a2d3ccb80003794a38ee9183b6f01de189beaff0 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 12 Jan 2013 22:22:58 +0000 Subject: cdrom: set proper reset values fixes HLE --- libpcsxcore/cdrom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index c96eac7..3117a9b 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -1630,6 +1630,8 @@ void cdrReset() { cdr.CurTrack = 1; cdr.File = 1; cdr.Channel = 1; + cdr.Reg2 = 0x1f; + cdr.Stat = NoIntr; pTransfer = cdr.Transfer; // BIOS player - default values -- cgit v1.2.3 From 9a11a883128d9df1fb3e6cce8bde69834c766266 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 13 Jan 2013 00:26:15 +0200 Subject: frontend: save gamma too --- frontend/menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/menu.c b/frontend/menu.c index 7dab2e6..3a6ae9c 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -8,7 +8,7 @@ * See the COPYING file in the top-level directory. */ -#define _GNU_SOURCE +#define _GNU_SOURCE 1 #include #include #include @@ -327,6 +327,7 @@ static void menu_set_defconfig(void) g_opts = 0; g_scaler = SCALE_4_3; + g_gamma = 100; volume_boost = 0; frameskip = 0; analog_deadzone = 50; @@ -391,6 +392,7 @@ static const struct { CE_CONFIG_VAL(Cpu), CE_INTVAL(region), CE_INTVAL_V(g_scaler, 2), + CE_INTVAL(g_gamma), CE_INTVAL(g_layer_x), CE_INTVAL(g_layer_y), CE_INTVAL(g_layer_w), -- cgit v1.2.3 From d8432250e1574fb95bd8aab5b7a0231d0c3c3ded Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 13 Jan 2013 20:35:14 +0200 Subject: cdrom: fix ID, again --- libpcsxcore/cdrom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 3117a9b..3e95742 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -946,9 +946,9 @@ void cdrInterrupt() { cdr.Result[2] = 0; cdr.Result[3] = 0; - // 0x10 - audio | 0x80 - unlicensed - if (CDR_getStatus(&stat) == -1) { - cdr.Result[1] = 0x80; // 0x80 leads to the menu in the bios, else loads CD + // 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed + if (CDR_getStatus(&stat) == -1 || stat.Type == 0 || stat.Type == 0xff) { + cdr.Result[1] = 0xc0; } else { if (stat.Type == 2) -- cgit v1.2.3 From 968795e31448884c2e46b5f4518a4cbe8ba7dac2 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 13 Jan 2013 21:08:36 +0200 Subject: cdrom: remove stopping on TN breaks N2O, does not make sense too --- libpcsxcore/cdrom.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 3e95742..034e657 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -852,11 +852,6 @@ void cdrInterrupt() { break; case CdlGetTN: - // 5-Star Racing: don't stop CDDA - // - // Vib Ribbon: CD swap - StopReading(); - cdr.CmdProcess = 0; SetResultSize(3); cdr.StatP |= STATUS_ROTATING; -- cgit v1.2.3 From 6320e9bf2cb2e02dabae682385d5fa9410114c9d Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 13 Jan 2013 21:48:48 +0200 Subject: cdrom: some swap cd tuning because last commit removed wrong read stop --- libpcsxcore/cdrom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 034e657..bcf83e7 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -298,13 +298,14 @@ static void Check_Shell( int Irq ) { // Vib Ribbon: pre-CD swap StopCdda(); + StopReading(); // GameShark Lite: Death if DiskError happens // // Vib Ribbon: Needs DiskError for CD swap - if (Irq != CdlNop) + //if (Irq != CdlNop) { cdr.Stat = DiskError; -- cgit v1.2.3 From 80f91a20e39eed8294b125af199c504cf8519d45 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 16 Jan 2013 04:12:50 +0200 Subject: cdrom: rewrite lid code based on tests on real hardware --- libpcsxcore/cdrom.c | 234 +++++++++++++++++----------------------------------- libpcsxcore/cdrom.h | 2 +- 2 files changed, 76 insertions(+), 160 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index bcf83e7..95e1f05 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -130,6 +130,13 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; // so (PSXCLK / 75) = cdr read time (linuzappz) #define cdReadTime (PSXCLK / 75) +enum drive_state { + DRIVESTATE_STANDBY = 0, + DRIVESTATE_LID_OPEN, + DRIVESTATE_RESCAN_CD, + DRIVESTATE_PREPARE_CD, +}; + // for cdr.Seeked enum seeked_state { SEEK_PENDING = 0, @@ -218,166 +225,76 @@ static void setIrq(void) psxHu32ref(0x1070) |= SWAP32((u32)0x4); } +// timing used in this function was taken from tests on real hardware +// (yes it's slow, but you probably don't want to modify it) void cdrLidSeekInterrupt() { - // turn back on checking - if( cdr.LidCheck == 0x10 ) - { - cdr.LidCheck = 0; - } - - // official lid close - else if( cdr.LidCheck == 0x30 ) - { - // GS CDX 3.3: $13 - cdr.StatP |= STATUS_ROTATING; - - - // GS CDX 3.3 - ~50 getlocp tries - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x40; - } - - // turn off ready - else if( cdr.LidCheck == 0x40 ) - { - // GS CDX 3.3: $01 - cdr.StatP &= ~STATUS_SHELLOPEN; - cdr.StatP &= ~STATUS_ROTATING; - - - // GS CDX 3.3 - ~50 getlocp tries - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x50; - } - - // now seek - else if( cdr.LidCheck == 0x50 ) - { - // GameShark Lite: Start seeking ($42) - cdr.StatP |= STATUS_SEEK; - cdr.StatP |= STATUS_ROTATING; - cdr.StatP &= ~STATUS_ERROR; - - - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x60; - } - - // done = cd ready - else if( cdr.LidCheck == 0x60 ) - { - // GameShark Lite: Seek detection done ($02) + switch (cdr.DriveState) { + default: + case DRIVESTATE_STANDBY: cdr.StatP &= ~STATUS_SEEK; - cdr.LidCheck = 0; - } -} - -static void Check_Shell( int Irq ) -{ - // check case open/close - if (cdr.LidCheck > 0) - { - CDR_LOG( "LidCheck\n" ); + if (CDR_getStatus(&stat) == -1) + return; - // $20 = check lid state - if( cdr.LidCheck == 0x20 ) + if (stat.Status & STATUS_SHELLOPEN) { - u32 i; - - i = stat.Status; - if (CDR_getStatus(&stat) != -1) - { - // BIOS hangs + BIOS error messages - //if (stat.Type == 0xff) - //cdr.Stat = DiskError; - - // case now open - if (stat.Status & STATUS_SHELLOPEN) - { - // Vib Ribbon: pre-CD swap - StopCdda(); - StopReading(); - - - // GameShark Lite: Death if DiskError happens - // - // Vib Ribbon: Needs DiskError for CD swap - - //if (Irq != CdlNop) - { - cdr.Stat = DiskError; - - cdr.StatP |= STATUS_ERROR; - cdr.Result[0] |= STATUS_ERROR; - } - - // GameShark Lite: Wants -exactly- $10 - cdr.StatP |= STATUS_SHELLOPEN; - cdr.StatP &= ~STATUS_ROTATING; - - - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x10; - - - // GS CDX 3.3 = $11 - } - - // case just closed - else if ( i & STATUS_SHELLOPEN ) - { - cdr.StatP |= STATUS_ROTATING; - - CheckCdrom(); - - - if( cdr.Stat == NoIntr ) - cdr.Stat = Acknowledge; - - setIrq(); + StopCdda(); + cdr.DriveState = DRIVESTATE_LID_OPEN; + CDRLID_INT(0x800); + } + break; - // begin close-seek-ready cycle - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x30; + case DRIVESTATE_LID_OPEN: + if (CDR_getStatus(&stat) == -1) + stat.Status &= ~STATUS_SHELLOPEN; + // 02, 12, 10 + if (!(cdr.StatP & STATUS_SHELLOPEN)) { + StopReading(); + cdr.StatP |= STATUS_SHELLOPEN; - // GameShark Lite: Wants -exactly- $42, then $02 - // GS CDX 3.3: Wants $11/$80, $13/$80, $01/$00 - } + // could generate error irq here, but real hardware + // only sometimes does that + // (not done when lots of commands are sent?) - // case still closed - wait for recheck - else - { - CDRLID_INT( cdReadTime * 3 ); - cdr.LidCheck = 0x10; - } - } + CDRLID_INT(cdReadTime * 30); + break; } + else if (cdr.StatP & STATUS_ROTATING) { + cdr.StatP &= ~STATUS_ROTATING; + } + else if (!(stat.Status & STATUS_SHELLOPEN)) { + // closed now + CheckCdrom(); + // cdr.StatP STATUS_SHELLOPEN is "sticky" + // and is only cleared by CdlNop - // GS CDX: clear all values but #1,#2 - if( (cdr.LidCheck >= 0x30) || (cdr.StatP & STATUS_SHELLOPEN) ) - { - SetResultSize(16); - memset( cdr.Result, 0, 16 ); - - cdr.Result[0] = cdr.StatP; + cdr.DriveState = DRIVESTATE_RESCAN_CD; + CDRLID_INT(cdReadTime * 105); + break; + } + // recheck for close + CDRLID_INT(cdReadTime * 3); + break; - // GS CDX: special return value - if( cdr.StatP & STATUS_SHELLOPEN ) - { - cdr.Result[1] = 0x80; - } + case DRIVESTATE_RESCAN_CD: + cdr.StatP |= STATUS_ROTATING; + cdr.DriveState = DRIVESTATE_PREPARE_CD; + // this is very long on real hardware, over 6 seconds + // make it a bit faster here... + CDRLID_INT(cdReadTime * 150); + break; - if( cdr.Stat == NoIntr ) - cdr.Stat = Acknowledge; + case DRIVESTATE_PREPARE_CD: + cdr.StatP |= STATUS_SEEK; - setIrq(); - } + cdr.DriveState = DRIVESTATE_STANDBY; + CDRLID_INT(cdReadTime * 26); + break; } } @@ -626,7 +543,8 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; - if (cdr.LidCheck == 0) cdr.LidCheck = 0x20; + if (cdr.DriveState != DRIVESTATE_LID_OPEN) + cdr.StatP &= ~STATUS_SHELLOPEN; break; case CdlSetloc: @@ -747,8 +665,6 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; // cdr.Stat = Acknowledge; - - if (cdr.LidCheck == 0) cdr.LidCheck = 0x20; break; case CdlPause: @@ -1046,7 +962,18 @@ void cdrInterrupt() { break; } - Check_Shell( Irq ); + if (Irq != CdlNop) { + switch (cdr.DriveState) { + case DRIVESTATE_LID_OPEN: + case DRIVESTATE_RESCAN_CD: + case DRIVESTATE_PREPARE_CD: + SetResultSize(2); + cdr.Result[0] = cdr.StatP | STATUS_ERROR; + cdr.Result[1] = 0x80; + cdr.Stat = DiskError; + break; + } + } cdr.ParamC = 0; @@ -1196,8 +1123,6 @@ void cdrReadInterrupt() { // update for CdlGetlocP ReadTrack(cdr.SetSector); - - Check_Shell(0); } /* @@ -1628,6 +1553,7 @@ void cdrReset() { cdr.Channel = 1; cdr.Reg2 = 0x1f; cdr.Stat = NoIntr; + cdr.DriveState = DRIVESTATE_STANDBY; pTransfer = cdr.Transfer; // BIOS player - default values @@ -1685,17 +1611,7 @@ int cdrFreeze(void *f, int Mode) { } void LidInterrupt() { - cdr.LidCheck = 0x20; // start checker - getCdInfo(); - StopCdda(); - CDRLID_INT( cdReadTime * 3 ); - - // generate interrupt if none active - open or close - if (cdr.Irq == 0 || cdr.Irq == 0xff) { - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(CdlNop, 0x800); - } + cdrLidSeekInterrupt(); } diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h index fc1df46..c2c5464 100644 --- a/libpcsxcore/cdrom.h +++ b/libpcsxcore/cdrom.h @@ -97,7 +97,7 @@ typedef struct { u8 Seeked; - u8 LidCheck; + u8 DriveState; u8 FastForward; u8 FastBackward; u8 pad; -- cgit v1.2.3 From e4268a49793ded1cfe669ad740078bbc5cb5a310 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 18 Jan 2013 02:30:00 +0200 Subject: cdrom: cleanup, support errors, improve timing most changes verified on real thing --- libpcsxcore/cdrom.c | 260 ++++++++++++++++++++++++---------------------------- libpcsxcore/cdrom.h | 3 +- 2 files changed, 123 insertions(+), 140 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 95e1f05..ab56734 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -76,6 +76,7 @@ static unsigned char *pTransfer; #define CdlID 26 #define CdlReadS 27 #define CdlReset 28 +#define CdlGetQ 29 #define CdlReadToc 30 char *CmdName[0x100]= { @@ -124,6 +125,10 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; #define STATUS_ROTATING (1<<1) // 0x02 #define STATUS_ERROR (1<<0) // 0x01 +/* Errors */ +#define ERROR_NOT_READY (1<<7) // 0x80 +#define ERROR_INVALIDCMD (1<<6) // 0x40 +#define ERROR_INVALIDARG (1<<5) // 0x20 // 1x = 75 sectors per second // PSXCLK = 1 sec in the ps @@ -135,6 +140,7 @@ enum drive_state { DRIVESTATE_LID_OPEN, DRIVESTATE_RESCAN_CD, DRIVESTATE_PREPARE_CD, + DRIVESTATE_STOPPED, }; // for cdr.Seeked @@ -405,9 +411,16 @@ static void ReadTrack(const u8 *time) { cdr.subq.Absolute[0], cdr.subq.Absolute[1], cdr.subq.Absolute[2]); } -static void AddIrqQueue(unsigned char irq, unsigned long ecycle) { - if (cdr.Irq != 0) +static void AddIrqQueue(unsigned short irq, unsigned long ecycle) { + if (cdr.Irq != 0) { + if (irq == cdr.Irq || irq + 0x100 == cdr.Irq) { + cdr.IrqRepeated = 1; + CDR_INT(ecycle); + return; + } + CDR_LOG_I("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq); + } cdr.Irq = irq; cdr.eCycle = ecycle; @@ -517,8 +530,11 @@ void cdrPlayInterrupt() } void cdrInterrupt() { - int i; - unsigned char Irq = cdr.Irq; + u16 Irq = cdr.Irq; + int no_busy_error = 0; + int start_rotating = 0; + int error = 0; + int delay; // Reschedule IRQ if (cdr.Stat) { @@ -527,32 +543,35 @@ void cdrInterrupt() { return; } - cdr.Irq = 0; cdr.Ctrl &= ~0x80; + // default response + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + + if (cdr.IrqRepeated) { + cdr.IrqRepeated = 0; + if (cdr.eCycle > psxRegs.cycle) { + CDR_INT(cdr.eCycle); + goto finish; + } + } + + cdr.Irq = 0; + switch (Irq) { case CdlSync: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; + // TOOD: sometimes/always return error? break; case CdlNop: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - if (cdr.DriveState != DRIVESTATE_LID_OPEN) cdr.StatP &= ~STATUS_SHELLOPEN; + no_busy_error = 1; break; case CdlSetloc: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; break; case CdlPlay: @@ -604,30 +623,21 @@ void cdrInterrupt() { // Vib Ribbon: gameplay checks flag cdr.StatP &= ~STATUS_SEEK; - - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; cdr.StatP |= STATUS_PLAY; - // BIOS player - set flag again cdr.Play = TRUE; CDRMISC_INT( cdReadTime ); + start_rotating = 1; break; case CdlForward: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; + // TODO: error 80 if stopped cdr.Stat = Complete; - // GameShark CD Player: Calls 2x + Play 2x if( cdr.FastForward == 0 ) cdr.FastForward = 2; else cdr.FastForward++; @@ -636,13 +646,8 @@ void cdrInterrupt() { break; case CdlBackward: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; - // GameShark CD Player: Calls 2x + Play 2x if( cdr.FastBackward == 0 ) cdr.FastBackward = 2; else cdr.FastBackward++; @@ -651,27 +656,34 @@ void cdrInterrupt() { break; case CdlStandby: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; + if (cdr.DriveState != DRIVESTATE_STOPPED) { + error = ERROR_INVALIDARG; + goto set_error; + } + AddIrqQueue(CdlStandby + 0x100, cdReadTime * 125 / 2); + start_rotating = 1; + break; + + case CdlStandby + 0x100: cdr.Stat = Complete; break; case CdlStop: - cdr.CmdProcess = 0; - SetResultSize(1); + delay = 0x800; + if (cdr.DriveState == DRIVESTATE_STANDBY) + delay = cdReadTime * 30 / 2; + + cdr.DriveState = DRIVESTATE_STOPPED; + AddIrqQueue(CdlStop + 0x100, delay); + break; + + case CdlStop + 0x100: cdr.StatP &= ~STATUS_ROTATING; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; -// cdr.Stat = Acknowledge; break; case CdlPause: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - /* Gundam Battle Assault 2: much slower (*) - Fixes boot, gameplay @@ -682,80 +694,52 @@ void cdrInterrupt() { InuYasha - Feudal Fairy Tale: slower - Fixes battles */ - AddIrqQueue(CdlPause + 0x20, cdReadTime * 3); + AddIrqQueue(CdlPause + 0x100, cdReadTime * 3); cdr.Ctrl |= 0x80; break; - case CdlPause + 0x20: - SetResultSize(1); + case CdlPause + 0x100: cdr.StatP &= ~STATUS_READ; - cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlInit: - SetResultSize(1); - cdr.StatP = STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; -// if (!cdr.Init) { - AddIrqQueue(CdlInit + 0x20, 0x800); -// } - break; + AddIrqQueue(CdlInit + 0x100, cdReadTime * 6); + no_busy_error = 1; + start_rotating = 1; + break; - case CdlInit + 0x20: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; + case CdlInit + 0x100: cdr.Stat = Complete; - cdr.Init = 1; break; case CdlMute: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; break; case CdlDemute: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; break; case CdlSetfilter: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; break; case CdlSetmode: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; + no_busy_error = 1; break; case CdlGetmode: SetResultSize(6); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; cdr.Result[1] = cdr.Mode; cdr.Result[2] = cdr.File; cdr.Result[3] = cdr.Channel; cdr.Result[4] = 0; cdr.Result[5] = 0; - cdr.Stat = Acknowledge; + no_busy_error = 1; break; case CdlGetlocL: SetResultSize(8); - for (i = 0; i < 8; i++) - cdr.Result[i] = cdr.Transfer[i]; - cdr.Stat = Acknowledge; + memcpy(cdr.Result, cdr.Transfer, 8); break; case CdlGetlocP: @@ -764,15 +748,20 @@ void cdrInterrupt() { if (!cdr.Play && !cdr.Reading) cdr.Result[1] = 0; // HACK? + break; - cdr.Stat = Acknowledge; + case CdlReadT: // SetSession? + // really long + AddIrqQueue(CdlReadT + 0x100, cdReadTime * 290 / 4); + start_rotating = 1; + break; + + case CdlReadT + 0x100: + cdr.Stat = Complete; break; case CdlGetTN: - cdr.CmdProcess = 0; SetResultSize(3); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; if (CDR_getTN(cdr.ResultTN) == -1) { cdr.Stat = DiskError; cdr.Result[0] |= STATUS_ERROR; @@ -784,10 +773,8 @@ void cdrInterrupt() { break; case CdlGetTD: - cdr.CmdProcess = 0; cdr.Track = btoi(cdr.Param[0]); SetResultSize(4); - cdr.StatP |= STATUS_ROTATING; if (CDR_getTD(cdr.Track, cdr.ResultTD) == -1) { cdr.Stat = DiskError; cdr.Result[0] |= STATUS_ERROR; @@ -802,11 +789,7 @@ void cdrInterrupt() { case CdlSeekL: case CdlSeekP: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; cdr.StatP |= STATUS_SEEK; - cdr.Stat = Acknowledge; /* Crusaders of Might and Magic = 0.5x-4x @@ -823,10 +806,10 @@ void cdrInterrupt() { */ CDRMISC_INT(cdr.Seeked == SEEK_DONE ? 0x800 : cdReadTime * 4); cdr.Seeked = SEEK_PENDING; + start_rotating = 1; break; case CdlTest: - cdr.Stat = Acknowledge; switch (cdr.Param[0]) { case 0x20: // System Controller ROM Version SetResultSize(4); @@ -841,17 +824,14 @@ void cdrInterrupt() { memcpy(cdr.Result, Test23, 4); break; } + no_busy_error = 1; break; case CdlID: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlID + 0x20, 0x800); + AddIrqQueue(CdlID + 0x100, 20480); break; - case CdlID + 0x20: + case CdlID + 0x100: SetResultSize(8); cdr.Result[0] = cdr.StatP; cdr.Result[1] = 0; @@ -875,40 +855,28 @@ void cdrInterrupt() { break; case CdlReset: - SetResultSize(1); - cdr.StatP = STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; + // yes, it really sets STATUS_SHELLOPEN + cdr.StatP |= STATUS_SHELLOPEN; + cdr.DriveState = DRIVESTATE_RESCAN_CD; + CDRLID_INT(20480); + no_busy_error = 1; + start_rotating = 1; break; - case CdlReadT: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlReadT + 0x20, 0x800); - break; - - case CdlReadT + 0x20: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; + case CdlGetQ: + // TODO? + CDR_LOG_I("got CdlGetQ\n"); break; case CdlReadToc: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlReadToc + 0x20, cdReadTime * 16); + AddIrqQueue(CdlReadToc + 0x100, cdReadTime * 180 / 4); + no_busy_error = 1; + start_rotating = 1; break; - case CdlReadToc + 0x20: - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; - cdr.Result[0] = cdr.StatP; + case CdlReadToc + 0x100: cdr.Stat = Complete; + no_busy_error = 1; break; case CdlReadN: @@ -951,40 +919,54 @@ void cdrInterrupt() { CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1); } - SetResultSize(1); - cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; + start_rotating = 1; break; default: - cdr.Stat = Complete; + CDR_LOG_I("Invalid command: %02x\n", Irq); + error = ERROR_INVALIDCMD; + // FALLTHROUGH + + set_error: + SetResultSize(2); + cdr.Result[0] = cdr.StatP | STATUS_ERROR; + cdr.Result[1] = error; + cdr.Stat = DiskError; break; } - if (Irq != CdlNop) { + if (cdr.DriveState == DRIVESTATE_STOPPED && start_rotating) { + cdr.DriveState = DRIVESTATE_STANDBY; + cdr.StatP |= STATUS_ROTATING; + } + + if (!no_busy_error) { switch (cdr.DriveState) { case DRIVESTATE_LID_OPEN: case DRIVESTATE_RESCAN_CD: case DRIVESTATE_PREPARE_CD: SetResultSize(2); cdr.Result[0] = cdr.StatP | STATUS_ERROR; - cdr.Result[1] = 0x80; + cdr.Result[1] = ERROR_NOT_READY; cdr.Stat = DiskError; break; } } - cdr.ParamC = 0; - +finish: setIrq(); + cdr.ParamC = 0; #ifdef CDR_LOG_CMD_IRQ - SysPrintf("IRQ %d cmd %02x stat %02x: ", - !!(cdr.Stat & cdr.Reg2), Irq, cdr.Stat); - for (i = 0; i < cdr.ResultC; i++) - SysPrintf("%02x ", cdr.Result[i]); - SysPrintf("\n"); + { + int i; + SysPrintf("CDR IRQ %d cmd %02x stat %02x: ", + !!(cdr.Stat & cdr.Reg2), Irq, cdr.Stat); + for (i = 0; i < cdr.ResultC; i++) + SysPrintf("%02x ", cdr.Result[i]); + SysPrintf("\n"); + } #endif } diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h index c2c5464..5d7c358 100644 --- a/libpcsxcore/cdrom.h +++ b/libpcsxcore/cdrom.h @@ -92,7 +92,8 @@ typedef struct { int Init; - unsigned char Irq; + u16 Irq; + u8 IrqRepeated; u32 eCycle; u8 Seeked; -- cgit v1.2.3 From 030bd76a17021cb6e56aad5ae5d0320d7d43133b Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 18 Jan 2013 03:47:14 +0200 Subject: cdrom: move more handling to cdrInterrupt --- libpcsxcore/cdrom.c | 132 +++++++++------------------------------------------- 1 file changed, 22 insertions(+), 110 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index ab56734..ca7f9f7 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -575,6 +575,7 @@ void cdrInterrupt() { break; case CdlPlay: + StopCdda(); if (cdr.Seeked == SEEK_PENDING) { // XXX: wrong, should seek instead.. memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 ); @@ -669,6 +670,18 @@ void cdrInterrupt() { break; case CdlStop: + if (cdr.Play) { + // grab time for current track + CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD); + + cdr.SetSectorPlay[0] = cdr.ResultTD[2]; + cdr.SetSectorPlay[1] = cdr.ResultTD[1]; + cdr.SetSectorPlay[2] = cdr.ResultTD[0]; + } + + StopCdda(); + StopReading(); + delay = 0x800; if (cdr.DriveState == DRIVESTATE_STANDBY) delay = cdReadTime * 30 / 2; @@ -715,12 +728,16 @@ void cdrInterrupt() { break; case CdlMute: + cdr.Muted = TRUE; break; case CdlDemute: + cdr.Muted = FALSE; break; case CdlSetfilter: + cdr.File = cdr.Param[0]; + cdr.Channel = cdr.Param[1]; break; case CdlSetmode: @@ -789,6 +806,8 @@ void cdrInterrupt() { case CdlSeekL: case CdlSeekP: + StopCdda(); + StopReading(); cdr.StatP |= STATUS_SEEK; /* @@ -881,7 +900,8 @@ void cdrInterrupt() { case CdlReadN: case CdlReadS: - if (!cdr.Reading) return; + cdr.Reading = 1; + cdr.FirstSector = 1; // Fighting Force 2 - update subq time immediately // - fixes new game @@ -1194,22 +1214,7 @@ void cdrWrite1(unsigned char rt) { AddIrqQueue(cdr.Cmd, 0x800); switch (cdr.Cmd) { - case CdlSync: - case CdlNop: - case CdlForward: - case CdlBackward: - case CdlReadT: - case CdlTest: - case CdlID: - case CdlReadToc: - case CdlGetmode: - case CdlGetlocL: - case CdlGetlocP: - case CdlGetTD: - break; - case CdlSetloc: - StopReading(); for (i = 0; i < 3; i++) set_loc[i] = btoi(cdr.Param[i]); @@ -1227,54 +1232,9 @@ void cdrWrite1(unsigned char rt) { cdr.SetSector[3] = 0; break; - case CdlPlay: - // Vib Ribbon: try same track again - StopCdda(); - - // Vib Ribbon - decoded buffer IRQ for CDDA reading - // - fixes ribbon timing + music CD mode - //CDRDBUF_INT( PSXCLK / 44100 * 0x100 ); - - cdr.Play = TRUE; - - cdr.StatP |= STATUS_SEEK; - cdr.StatP &= ~STATUS_ROTATING; - break; - case CdlReadN: - StopReading(); - cdr.Reading = 1; - cdr.FirstSector = 1; - cdr.Readed = 0xff; - break; - - case CdlStandby: - StopCdda(); - StopReading(); - break; - - case CdlStop: - // GameShark CD Player: Reset CDDA to track start - if (cdr.Play) { - // grab time for current track - CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD); - - cdr.SetSectorPlay[0] = cdr.ResultTD[2]; - cdr.SetSectorPlay[1] = cdr.ResultTD[1]; - cdr.SetSectorPlay[2] = cdr.ResultTD[0]; - } - - StopCdda(); - StopReading(); - break; - + case CdlReadS: case CdlPause: - /* - GameShark CD Player: save time for resume - - Twisted Metal - World Tour: don't mix Setloc / CdlPlay cursors - */ - StopCdda(); StopReading(); break; @@ -1286,28 +1246,6 @@ void cdrWrite1(unsigned char rt) { StopReading(); break; - case CdlMute: - cdr.Muted = TRUE; - // Duke Nukem - Time to Kill - // - do not directly set cd-xa volume - //SPU_writeRegister( H_CDLeft, 0x0000 ); - //SPU_writeRegister( H_CDRight, 0x0000 ); - break; - - case CdlDemute: - cdr.Muted = FALSE; - - // Duke Nukem - Time to Kill - // - do not directly set cd-xa volume - //SPU_writeRegister( H_CDLeft, 0x7f00 ); - //SPU_writeRegister( H_CDRight, 0x7f00 ); - break; - - case CdlSetfilter: - cdr.File = cdr.Param[0]; - cdr.Channel = cdr.Param[1]; - break; - case CdlSetmode: CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]); @@ -1318,32 +1256,6 @@ void cdrWrite1(unsigned char rt) { if( cdr.Play && (cdr.Mode & MODE_CDDA) == 0 ) StopCdda(); break; - - case CdlGetTN: - //AddIrqQueue(cdr.Cmd, 0x800); - - // GameShark CDX CD Player: very long time - AddIrqQueue(cdr.Cmd, 0x100000); - break; - - case CdlSeekL: - case CdlSeekP: - // Tomb Raider 2 - reset cdda - StopCdda(); - StopReading(); - break; - - case CdlReadS: - StopReading(); - cdr.Reading = 2; - cdr.FirstSector = 1; - cdr.Readed = 0xff; - break; - - default: - cdr.ParamC = 0; - CDR_LOG_I("cdrWrite1() Log: Unknown command: %x\n", cdr.Cmd); - return; } } -- cgit v1.2.3 From 888468ff06c19ff646bdcdb2d64727fcf1fc4e94 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 18 Jan 2013 04:34:23 +0200 Subject: psxbios: handle u modifier --- libpcsxcore/psxbios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index fdc129e..b3435ad 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -990,7 +990,7 @@ _start: case 'g': case 'G': ptmp += sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break; case 'p': - case 'i': + case 'i': case 'u': case 'd': case 'D': case 'o': case 'O': case 'x': case 'X': -- cgit v1.2.3 From deebc67fc5c5027248842562e02d71d5f683a1e2 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 02:31:53 +0200 Subject: cdriso: merge cdda code from pcsxr my own code.. --- libpcsxcore/cdriso.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 7798774..90c9d85 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -16,7 +16,7 @@ * 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., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #include "psxcommon.h" @@ -28,6 +28,7 @@ #ifdef _WIN32 #include #include +#define strcasecmp _stricmp #else #include #include @@ -46,6 +47,8 @@ static boolean subChanMixed = FALSE; static boolean subChanRaw = FALSE; static boolean subChanMissing = FALSE; +static boolean multifile = FALSE; + static unsigned char cdbuffer[CD_FRAMESIZE_RAW]; static unsigned char subbuffer[SUB_FRAMESIZE]; @@ -71,6 +74,8 @@ static unsigned int cdda_file_offset; * XXX: there could be multiple pregaps but PSX dumps only have one? */ static unsigned int pregapOffset; +#define cddaCurPos cdda_cur_sector + // compressed image stuff static struct { unsigned char buff_raw[16][CD_FRAMESIZE_RAW]; @@ -93,10 +98,8 @@ long CALLBACK CDR__getStatus(struct CdrStat *stat); static void DecodeRawSubData(void); -extern void *hCDRDriver; - struct trackinfo { - enum {DATA, CDDA} type; + enum {DATA=1, CDDA} type; char start[3]; // MSF-format char length[3]; // MSF-format FILE *handle; // for multi-track images CDDA @@ -558,8 +561,10 @@ static int parsecue(const char *isofile) { } // update global offset if this is not first file in this .cue - if (numtracks + 1 > 1) + if (numtracks + 1 > 1) { + multifile = 1; sector_offs += file_len; + } file_len = 0; if (ti[numtracks + 1].handle == NULL) { @@ -1215,6 +1220,7 @@ static long CALLBACK ISOopen(void) { subChanRaw = FALSE; pregapOffset = 0; cdrIsoMultidiskCount = 1; + multifile = 0; CDR_getBuffer = ISOgetBuffer; cdimg_read_func = cdread_normal; @@ -1349,7 +1355,6 @@ static long CALLBACK ISOgetTN(unsigned char *buffer) { // byte 2 - minute static long CALLBACK ISOgetTD(unsigned char track, unsigned char *buffer) { if (track == 0) { - // CD length according pcsxr-svn (done a bit different here) unsigned int sect; unsigned char time[3]; sect = msf2sec(ti[numtracks].start) + msf2sec(ti[numtracks].length); @@ -1466,20 +1471,74 @@ static unsigned char* CALLBACK ISOgetBufferSub(void) { } static long CALLBACK ISOgetStatus(struct CdrStat *stat) { - int sec; - + u32 sect; + CDR__getStatus(stat); - + if (playing) { stat->Type = 0x02; stat->Status |= 0x80; } else { - stat->Type = 0x01; + // BIOS - boot ID (CD type) + stat->Type = ti[1].type; + } + + // relative -> absolute time + sect = cddaCurPos; + sec2msf(sect, (char *)stat->Time); + + return 0; +} + +// read CDDA sector into buffer +long CALLBACK ISOreadCDDA(unsigned char m, unsigned char s, unsigned char f, unsigned char *buffer) { + unsigned char msf[3] = {m, s, f}; + unsigned int file, track, track_start = 0; + int ret; + + cddaCurPos = msf2sec((char *)msf); + + // find current track index + for (track = numtracks; ; track--) { + track_start = msf2sec(ti[track].start); + if (track_start <= cddaCurPos) + break; + if (track == 1) + break; + } + + // data tracks play silent + if (ti[track].type != CDDA) { + memset(buffer, 0, CD_FRAMESIZE_RAW); + return 0; + } + + file = 1; + if (multifile) { + // find the file that contains this track + for (file = track; file > 1; file--) + if (ti[file].handle != NULL) + break; } - sec = cdda_cur_sector; - sec2msf(sec, (char *)stat->Time); + ret = cdimg_read_func(ti[file].handle, ti[track].start_offset, + buffer, cddaCurPos - track_start); + if (ret != CD_FRAMESIZE_RAW) { + memset(buffer, 0, CD_FRAMESIZE_RAW); + return -1; + } + + if (cddaBigEndian) { + int i; + unsigned char tmp; + + for (i = 0; i < CD_FRAMESIZE_RAW / 2; i++) { + tmp = buffer[i * 2]; + buffer[i * 2] = buffer[i * 2 + 1]; + buffer[i * 2 + 1] = tmp; + } + } return 0; } @@ -1497,6 +1556,7 @@ void cdrIsoInit(void) { CDR_stop = ISOstop; CDR_getBufferSub = ISOgetBufferSub; CDR_getStatus = ISOgetStatus; + CDR_readCDDA = ISOreadCDDA; CDR_getDriveLetter = CDR__getDriveLetter; CDR_configure = CDR__configure; -- cgit v1.2.3 From 22bbabf6807d704b1a8c9231d55f139e3e00b8dd Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 02:47:12 +0200 Subject: merge minor fixes from pcsxr my own code.. --- libpcsxcore/cdriso.c | 8 +++++--- libpcsxcore/cdrom.c | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 90c9d85..21203da 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -470,10 +470,12 @@ static int parsecue(const char *isofile) { // build a path for files referenced in .cue strncpy(filepath, cuename, sizeof(filepath)); - tmp = strrchr(filepath, '/') + 1; - if (tmp == NULL) - tmp = strrchr(filepath, '\\') + 1; + tmp = strrchr(filepath, '/'); if (tmp == NULL) + tmp = strrchr(filepath, '\\'); + if (tmp != NULL) + tmp++; + else tmp = filepath; *tmp = 0; filepath[sizeof(filepath) - 1] = 0; diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index ca7f9f7..966bb70 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -14,10 +14,10 @@ * 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., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ -/* +/* * Handles all CD-ROM registers and functions. */ @@ -1448,6 +1448,7 @@ void cdrReset() { cdr.Reg2 = 0x1f; cdr.Stat = NoIntr; cdr.DriveState = DRIVESTATE_STANDBY; + cdr.StatP = STATUS_ROTATING; pTransfer = cdr.Transfer; // BIOS player - default values -- cgit v1.2.3 From 1ae8c5a80945e4e8d549e0bd763ad1fd132e888e Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 02:48:01 +0200 Subject: frontend: path handling fix --- frontend/menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/menu.c b/frontend/menu.c index 3a6ae9c..9ca5f95 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -251,7 +251,9 @@ static int optional_cdimg_filter(struct dirent **namelist, int count, p = strrchr(buf2, '/'); if (p == NULL) p = strrchr(buf2, '\\'); - if (p == NULL) + if (p != NULL) + p++; + else p = buf2; snprintf(buf, sizeof(buf), "%s/%s", basedir, p); -- cgit v1.2.3 From 45b97ede8128bd0217943e6b4b88a08a3c1a7003 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 05:06:43 +0200 Subject: frontend: logging updates go to logcat on Android --- frontend/libpicofe | 2 +- frontend/main.c | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/frontend/libpicofe b/frontend/libpicofe index 4db0222..215e7ed 160000 --- a/frontend/libpicofe +++ b/frontend/libpicofe @@ -1 +1 @@ -Subproject commit 4db02226eb3c80f49f5c412f7718c437c5e817fc +Subproject commit 215e7ed2510e191664b611a578ffb987cf4fdab3 diff --git a/frontend/main.c b/frontend/main.c index 43a1a03..8b35b09 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -454,6 +454,8 @@ int emu_core_preinit(void) int emu_core_init(void) { + SysPrintf("Starting PCSX-ReARMed " REV "\n"); + CheckSubDir(); check_memcards(); @@ -553,7 +555,8 @@ int main(int argc, char *argv[]) plat_init(); menu_init(); // loads config - emu_core_init(); + if (emu_core_init() != 0) + return 1; if (psxout) Config.PsxOut = 1; @@ -761,6 +764,8 @@ int emu_load_state(int slot) return LoadState(fname); } +#ifndef ANDROID + void SysPrintf(const char *fmt, ...) { va_list list; @@ -769,16 +774,31 @@ void SysPrintf(const char *fmt, ...) { va_end(list); } +#else + +#include + +void SysPrintf(const char *fmt, ...) { + va_list list; + + va_start(list, fmt); + __android_log_vprint(ANDROID_LOG_INFO, "PCSX", fmt, list); + va_end(list); +} + +#endif + void SysMessage(const char *fmt, ...) { - va_list list; - char msg[512]; + va_list list; + char msg[512]; + int ret; - va_start(list, fmt); - vsnprintf(msg, sizeof(msg), fmt, list); - va_end(list); + va_start(list, fmt); + ret = vsnprintf(msg, sizeof(msg), fmt, list); + va_end(list); - if (msg[strlen(msg) - 1] == '\n') - msg[strlen(msg) - 1] = 0; + if (ret < sizeof(msg) && msg[ret - 1] == '\n') + msg[ret - 1] = 0; SysPrintf("%s\n", msg); } -- cgit v1.2.3 From b0dd9956467322aca812db75b5e0f11f23c1910b Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 05:09:23 +0200 Subject: psxmem: try to choose mem addresses more carefully --- libpcsxcore/psxmem.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c index 27663f1..9e44267 100644 --- a/libpcsxcore/psxmem.c +++ b/libpcsxcore/psxmem.c @@ -42,10 +42,15 @@ void *psxMap(unsigned long addr, size_t size, int is_fixed, enum psxMapTag tag) { int flags = MAP_PRIVATE | MAP_ANONYMOUS; + int tried_to_align = 0; + unsigned long mask; void *req, *ret; - if (psxMapHook != NULL) - return psxMapHook(addr, size, is_fixed, tag); +retry: + if (psxMapHook != NULL) { + ret = psxMapHook(addr, size, is_fixed, tag); + goto out; + } if (is_fixed) flags |= MAP_FIXED; @@ -55,9 +60,24 @@ void *psxMap(unsigned long addr, size_t size, int is_fixed, if (ret == MAP_FAILED) return NULL; - if (req != NULL && ret != req) - SysMessage("psxMap: warning: wanted to map @%p, got %p\n", - req, ret); +out: + if (addr != 0 && ret != (void *)addr) { + SysMessage("psxMap: warning: wanted to map @%08x, got %p\n", + addr, ret); + + if (ret != NULL && ((addr ^ (long)ret) & 0x00ffffff) + && !tried_to_align) + { + psxUnmap(ret, size, tag); + + // try to use similarly aligned memory instead + // (recompiler needs this) + mask = (addr - 1) & ~addr & 0x07ffffff; + addr = (unsigned long)(ret + mask) & ~mask; + tried_to_align = 1; + goto retry; + } + } return ret; } @@ -110,7 +130,7 @@ int psxMemInit() { psxM = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM); #ifndef RAM_FIXED if (psxM == NULL) - psxM = psxMap(0x70000000, 0x00210000, 0, MAP_TAG_RAM); + psxM = psxMap(0x78000000, 0x00210000, 0, MAP_TAG_RAM); #endif if (psxM == NULL) { SysMessage(_("mapping main RAM failed")); -- cgit v1.2.3 From 6f18d16a0abcbc0655ed82fd30796fa06242c2b8 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 20:14:54 +0200 Subject: ange how no memcards are specified empty string now just means "don't save/load" --- frontend/menu.c | 4 ++-- libpcsxcore/sio.c | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/frontend/menu.c b/frontend/menu.c index 9ca5f95..8119505 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -1700,10 +1700,10 @@ out: static void handle_memcard_sel(void) { - Config.Mcd1[0] = 0; + strcpy(Config.Mcd1, "none"); if (memcard1_sel != 0) snprintf(Config.Mcd1, sizeof(Config.Mcd1), ".%s%s", MEMCARD_DIR, memcards[memcard1_sel]); - Config.Mcd2[0] = 0; + strcpy(Config.Mcd2, "none"); if (memcard2_sel != 0) snprintf(Config.Mcd2, sizeof(Config.Mcd2), ".%s%s", MEMCARD_DIR, memcards[memcard2_sel]); LoadMcds(Config.Mcd1, Config.Mcd2); diff --git a/libpcsxcore/sio.c b/libpcsxcore/sio.c index ea96e95..b3732d2 100644 --- a/libpcsxcore/sio.c +++ b/libpcsxcore/sio.c @@ -409,10 +409,13 @@ void LoadMcd(int mcd, char *str) { } McdDisable[mcd - 1] = 0; - if (str == NULL || *str == 0) { + 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); @@ -455,6 +458,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; -- cgit v1.2.3 From e6495add01b91c6ebb9fdb15920fc7fa431d647e Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 20:19:46 +0200 Subject: frontend: don't set up profile paths without frontend --- frontend/main.c | 93 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index 8b35b09..0f0e641 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -33,6 +33,8 @@ #include "libpicofe/readpng.h" static void toggle_fast_forward(int force_off); +static void check_profile(void); +static void check_memcards(void); #endif #ifndef BOOT_MSG #define BOOT_MSG "Booting up..." @@ -66,28 +68,6 @@ static void make_path(char *buf, size_t size, const char *dir, const char *fname #define MAKE_PATH(buf, dir, fname) \ make_path(buf, sizeof(buf), dir, fname) -static void create_profile_dir(const char *directory) { - char path[MAXPATHLEN]; - - MAKE_PATH(path, directory, NULL); - mkdir(path, S_IRWXU | S_IRWXG); -} - -static void CheckSubDir() { - // make sure that ~/.pcsx exists - create_profile_dir(PCSX_DOT_DIR); - - create_profile_dir(BIOS_DIR); - create_profile_dir(MEMCARD_DIR); - create_profile_dir(STATES_DIR); - create_profile_dir(PLUGINS_DIR); - create_profile_dir(PLUGINS_CFG_DIR); - create_profile_dir(CHEATS_DIR); - create_profile_dir(PATCHES_DIR); - create_profile_dir(PCSX_DOT_DIR "cfg"); - create_profile_dir("/screenshots/"); -} - static int get_gameid_filename(char *buf, int size, const char *fmt, int i) { char trimlabel[33]; int j; @@ -126,9 +106,12 @@ void set_cd_image(const char *fname) static void set_default_paths(void) { +#ifndef NO_FRONTEND + snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "." PATCHES_DIR); MAKE_PATH(Config.Mcd1, MEMCARD_DIR, "card1.mcd"); MAKE_PATH(Config.Mcd2, MEMCARD_DIR, "card2.mcd"); strcpy(Config.BiosDir, "bios"); +#endif strcpy(Config.PluginsDir, "plugins"); strcpy(Config.Gpu, "builtin_gpu"); @@ -137,8 +120,6 @@ static void set_default_paths(void) strcpy(Config.Pad1, "builtin_pad"); strcpy(Config.Pad2, "builtin_pad"); strcpy(Config.Net, "Disabled"); - - snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "." PATCHES_DIR); } void emu_set_default_config(void) @@ -175,25 +156,6 @@ void emu_set_default_config(void) in_type2 = PSE_PAD_TYPE_STANDARD; } -static void check_memcards(void) -{ - char buf[MAXPATHLEN]; - FILE *f; - int i; - - for (i = 1; i <= 9; i++) { - snprintf(buf, sizeof(buf), ".%scard%d.mcd", MEMCARD_DIR, i); - - f = fopen(buf, "rb"); - if (f == NULL) { - SysPrintf("Creating memcard: %s\n", buf); - CreateMcd(buf); - } - else - fclose(f); - } -} - void do_emu_action(void) { int ret; @@ -456,8 +418,10 @@ int emu_core_init(void) { SysPrintf("Starting PCSX-ReARMed " REV "\n"); - CheckSubDir(); +#ifndef NO_FRONTEND + check_profile(); check_memcards(); +#endif if (EmuInit() == -1) { SysPrintf("PSX emulator couldn't be initialized.\n"); @@ -474,6 +438,47 @@ int emu_core_init(void) } #ifndef NO_FRONTEND +static void create_profile_dir(const char *directory) { + char path[MAXPATHLEN]; + + MAKE_PATH(path, directory, NULL); + mkdir(path, S_IRWXU | S_IRWXG); +} + +static void check_profile(void) { + // make sure that ~/.pcsx exists + create_profile_dir(PCSX_DOT_DIR); + + create_profile_dir(BIOS_DIR); + create_profile_dir(MEMCARD_DIR); + create_profile_dir(STATES_DIR); + create_profile_dir(PLUGINS_DIR); + create_profile_dir(PLUGINS_CFG_DIR); + create_profile_dir(CHEATS_DIR); + create_profile_dir(PATCHES_DIR); + create_profile_dir(PCSX_DOT_DIR "cfg"); + create_profile_dir("/screenshots/"); +} + +static void check_memcards(void) +{ + char buf[MAXPATHLEN]; + FILE *f; + int i; + + for (i = 1; i <= 9; i++) { + snprintf(buf, sizeof(buf), ".%scard%d.mcd", MEMCARD_DIR, i); + + f = fopen(buf, "rb"); + if (f == NULL) { + SysPrintf("Creating memcard: %s\n", buf); + CreateMcd(buf); + } + else + fclose(f); + } +} + int main(int argc, char *argv[]) { char file[MAXPATHLEN] = ""; -- cgit v1.2.3 From 17f84149a604fefb8181a280487bd48ca7a353b2 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 28 Jan 2013 21:17:09 +0200 Subject: libretro: handle regions --- frontend/libretro.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/libretro.c b/frontend/libretro.c index e7153ac..4f6879e 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -35,6 +35,7 @@ static bool vout_can_dupe; static int samples_sent, samples_to_send; static int plugins_opened; +static int is_pal_mode; /* memory card data */ extern char Mcd1Data[MCD_SIZE]; @@ -182,6 +183,7 @@ void pl_frame_limit(void) void pl_timing_prepare(int is_pal) { + is_pal_mode = is_pal; } void plat_trigger_vibrate(int is_strong) @@ -254,7 +256,7 @@ void retro_get_system_info(struct retro_system_info *info) void retro_get_system_av_info(struct retro_system_av_info *info) { memset(info, 0, sizeof(*info)); - info->timing.fps = 60; + info->timing.fps = is_pal_mode ? 50 : 60; info->timing.sample_rate = 44100; info->geometry.base_width = 320; info->geometry.base_height = 240; @@ -446,7 +448,7 @@ void retro_unload_game(void) unsigned retro_get_region(void) { - return RETRO_REGION_NTSC; + return is_pal_mode ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } void *retro_get_memory_data(unsigned id) @@ -501,7 +503,7 @@ void retro_run(void) stop = 0; psxCpu->Execute(); - samples_to_send += 44100 / 60; + samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60; video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL, vout_width, vout_height, vout_width * 2); -- cgit v1.2.3