|
|
|||||||
| Home | Register | Downloads | FAQ | Members List | Calendar | Arcade | Mark Forums Read |
» Less advertising throughout
» Post and participate in discussions
» Network with other forum members
» Free private messaging
![]() |
|
|
Thread Tools | Display Modes |
|
|
#61 |
|
Banned
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2006
Location: Sydney, Australia
Posts: 23,270
|
I'm not using images, im reading directly from disk. I've never had an issue booting from images as the drive emulator applies the required hacks and fakes the sub data. its reading subdata directly from the disk thats failing, and this works fine on epsxe with sapu 1.3 (1.0 only works on epsxe 1.6 and lower) but fails with PCSX. Its possible that PCSX isn't making use of IOCTL's subcode modes correctly. |
|
|
|
| Advertisement | [Remove Advertisement] | ||
|
|
|
#62 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
Okay, I understand you now. Maybe Whistler can help since I can't. If that new subQ fix doesn't help, sorry pal. xx( The part I can't understand about ePSXe is that SBI files don't return CRC data but FF8 PAL still booted. PCSX will always fail since the CRC LibCrypt sectors are not returning. With SaPu and a ccd/sub image, I get CRC and the game works. :undecided: |
|
|
|
|
|
#63 | |
|
Registered User
![]() Join Date: Feb 2010
Location: Singapore
Posts: 52
|
Quote:
6 threads to decode PSX A/V real-time in Java? (But his goal is to do it perfectly. I chuckled when I saw his image quality comparison and PCSX fared -- by far -- the worst.)As for smf, I wished he posted more PSX related stuff on his blog! At first, I thought he had implemented a full PSX emulator for MAME, but nothing turned up in google. (So the PSX emulation in MAME is only for PSX-based arcade consoles?) That's where I read that some games use the *load* delay slot. His earlier PSX entries have some "quiz" on officially undefined behaviour -- illegal instructions in delay slots, for example -- but still used in the real world. Needless to say, I got almost all of them wrong.
__________________
(void *) &NHY; |
|
|
|
|
|
|
#64 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
More interesting bits about subchannels. If your game reads audio subQ for time positions, you'll need to use this: (the cdr.Prev currently does not sync with the CDROM CDDA ptr and thus zaps the times, black screening the game; honestly don't know if it should sync) ex. Vib Ribbon Code:
// subQ integrity check (data track only..?)
if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) ) {
// wipe out time data
memset( cdr.Result+2, 0, 3+3 );
}
|
|
|
|
|
|
#65 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
I asked someone about this PSX subchannel data. She says that a bad CRC-16 for subQ should return zero times for PSX CDROM readers (since that's what we're apparently seeing; PC drives don't care and return raw results). The actual timestamps _should not_ play a part other than in computing the CRC. So even if they're invalid, just ignore them. LibCrypt will always XOR the CRC data to mark the subQ invalid and create the zero values. SBI files don't carry the CRC data because we already __intuitively__ know that it's a LibCrypt sector (aka. bad subQ). So our CDROM plugin should just return a zero time for us - or generate a bad CRC and let getlocP do it (maybe ePSXe is smart enough to detect this?). For iso + bin/cue, Virtual Clonedrive and Daemon Tools will return a CRC = 0 (update: not always true). So she says that we must create our own valid CRC to satisfy the subQ requirement; otherwise we will fail the subQ check since our CRC is bad. Or tell the emu to ignore it by returning a 'NULL' subQ ptr and let the emu create the times. Also said that VCD swaps the relative / absolute time positions. (234 <--> 567). And that Daemon Tools will return Track #1 for all CDDA times (update: not always true).For ccd/sub + mdf, the timestamps + CRC should be there and passed 'as-is'. No problems. Same with a normal CDROM drive reader. Her guess is that ePSXe / pSX are intelligent enough in faking the subdata so that we see transparency. And that the CDDA data should constantly show up in the cdr.buffer as it streams - her guess as to how Vib Ribbon works. And that cdr.Prev (CDROM ptr) probably keeps up-to-date with the CDDA ptr. So a DMA check is in order. UPDATE: I've got a note that redump SBI's are meant to be used with sbi2sub to generate a ccd/sub file. That SBI trick will only work with redump files since PEOPS SBI files are include normal sectors also. Last edited by shalma; February 18th, 2010 at 21:56.. |
|
|
|
|
|
#66 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
TEMP FIX: Policenauts swapping discs. Game calls CdlInit/CdlStop and checks for the CD case to open/close during that period. So checking CDR_getStatus during CdlNop/CdlID are not enough for this game. Code:
libpcsxcore/cdrom.c
case CdlStop:
cdr.CmdProcess = 0;
SetResultSize(1);
cdr.StatP &= ~0x2;
cdr.Result[0] = cdr.StatP;
cdr.Stat = Complete;
// cdr.Stat = Acknowledge;
// check case open/close
i = stat.Status;
if (CDR_getStatus(&stat) != -1) {
if (stat.Type == 0xff) cdr.Stat = DiskError;
if (stat.Status & 0x10) {
cdr.Stat = DiskError;
cdr.Result[0] |= 0x11;
cdr.Result[0] &= ~0x02;
}
else if (i & 0x10) {
cdr.StatP |= 0x2;
cdr.Result[0] |= 0x2;
CheckCdrom();
}
}
break;
---OR--- NOTE: Tends to work better with Policenauts Code:
libpcsxcore/cdrom.c
unsigned char cdrRead0(void) {
int i;
(..)
// check case open/close
i = stat.Status;
if (CDR_getStatus(&stat) != -1) {
if (stat.Type == 0xff) cdr.Stat = DiskError;
if (stat.Status & 0x10) {
cdr.Stat = DiskError;
cdr.Result[0] |= 0x11;
cdr.Result[0] &= ~0x02;
}
else if (i & 0x10) {
cdr.StatP |= 0x2;
cdr.Result[0] |= 0x2;
CheckCdrom();
}
}
Also noticed this curious note for music CDs: Code:
case CdlID + 0x20:
SetResultSize(8);
if (CDR_getStatus(&stat) == -1) {
cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player
cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD
}
|
|
|
|
|
|
#68 |
|
Banned
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2006
Location: Sydney, Australia
Posts: 23,270
|
pcsx-df /care/
|
|
|
|
|
|
#69 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
Just to comment on Policenauts some more: Policenauts swap fix You'll want to check for the shell open in CdlStop (or maybe every time a cdrWrite1 command is issued). :unsure: Using method 2 (inside cdrRead0) -will- break other swapping games. Using ISOs may not work: 1) You must eject the CD first 2) Press OK button (in-game) 3) This is when the game sees that the shell is open and waits for you to close it 4) Press OK button 5) Game loads Just immediately swapping the CD images, the game will not detect it. If the game freezes up, use SPU IRQ hack. Don't know why - Eternal or PEOPS. |
|
|
|
|
|
#70 | |
|
Whistler
![]() ![]() Join Date: Apr 2008
Location: Lanzhou, P. R. China
Posts: 133
|
Quote:
the only broken thing I found is the sio timing - using "(PSXCLK / 250000) * BIAS" which is 270 (while fixes issue with Need For Speed) does make some games like "Rhapsody: A Musical Adventure" (SLPS-01734/SLUS-01073) fail to boot however using 271 fixes the issue (although the game still freezes with pcsx-revolution). Also I think the 270 is commented out in the original code and replaced with 200. Have little clue about the exact timing though
__________________
Last edited by Whistler; April 15th, 2010 at 08:05.. |
|
|
|
|
|
|
#71 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
I was looking at pSXAuthor's GTE divide (MAME src + license). It's possible that PS1 uses an algorithm like this based on the code: Code:
8:8 division A fast division operation is occasionally nice to have, but is harder to implement than multiplication. The fastest way I have seen uses Newton-Raphson iteration and consists of several steps: 1. Strip off the sign of the denominator (D) to make it positive. 2. Scale D to the range 0.5<=D<=1.0 and record the number of shifts (N) necessary to to this. 3. Estimate of the reciprocal of the scaled D using a linear approximation requiring only shifts and adds. 4. Use Newton's method to iteratively improve the reciprocal approximation. 8:8 accuracy takes only one iteration to converge. 5. Shift the scaled approximation by N back to the correct magnitude. 6. Restore the sign to form the complete reciprocal. 7. Multiply the numerator by the reciprocal of D. Of course, we don't have actual hardware tests to prove it though (on our side). ;P I'll let everyone know if I manage to get some approximate results. EDIT: Pete may like this fix by edgbla to soft.c (PEOPS Soft): Code:
void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1)
if (dx < 0)
{
xt = x0;
yt = y0;
rgbt = rgb0;
x0 = x1;
y0 = y1;
rgb0 = rgb1;
x1 = xt;
y1 = yt;
rgb1 = rgbt; // used to be rgb0 (****)
dx = x1 - x0;
dy = y1 - y0;
}
m = dy / dx;
The current PCSX GTE method of: Code:
h_over_sz3 = limE((gteH * 65536) / (gteSZ3 + 0.5)); As a dummy test, I've been using this: Code:
UINT32 gte_divide3( INT16 numerator, UINT16 denominator )
{
if( numerator >= 0 && numerator < ( denominator * 2 ) )
{
UINT32 offset = denominator;
int shift = 0;
UINT64 reciprocal;
while( offset <= 0x8000 )
{
offset <<= 1;
shift++;
}
double p = 1.0 / 65536;
double q;
UINT32 r;
p = 1.0 / (offset/65536.0);
q = p-1.0;
r = q * 65536;
reciprocal = (UINT64)( 0x10000 | r ) << shift;
return (UINT32)( ( ( reciprocal * numerator ) + 0x8000 ) >> 16 );
}
return 0xffffffff;
}
Which is about the same accuracy as: Code:
UINT32 gte_divide2( INT16 numerator, UINT16 denominator )
{
if( numerator >= 0 && numerator < ( denominator * 2 ) )
{
return (numerator * 65536) / (denominator) + 0.5;
}
else
return 0xffffffff;
}
(same for RTPT)
Last edited by shalma; April 16th, 2010 at 01:24.. |
|
|
|
|
|
#72 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
NOTE: This is probably not how the PS1 does it for GTE division Mainly intended for a more freely usable license (non-MAME) that everyone can use - All based on pSXAuthor's research - A generic fixed-point division method that uses a 2-iteration Newton-Raphson based on initial guess tables (similar to SNES DSP-1). Accurately matches pSXAuthor's reciprocals table. Someone could optimize the table to 1-iteration Newton-Raphson, which would then look more similar to the reciprocals table. I just stuck with 2-pass since it converges really fast. |
|
|
|
|
|
#73 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
psxcounters.c (older writes of PCSX-r, PCSX 1.5+) Code:
void psxRcntUpd(unsigned long index) {
// check RCNT_IQ2 flag
if (psxCounters[index].mode & 0x40)
==>
// check RCNT_TARGET flag
if (psxCounters[index].mode & 0x08)
Improves Thousand Arms lockups (load game and such). Does not fix stomach growl glitch. EDIT: Didn't see the root counter updates done to PCSX-r. So ignore the above if you're using the latest PCSX-r SVN builds.
Last edited by shalma; May 3rd, 2010 at 13:35.. |
|
|
|
|
|
#74 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
In case some users aren't following the PCSX-reloaded changesets for awhile: PCSX-Reloaded SVN changelogs They've made lots of great overall + compatibility + core fixes to their PS1 project. More notably (for me) the Thousand Arms cutscene/dating sound lockups are fully gone (probably fixes Policenauts SPU also - same type of HW problem). Very nice work (: Now I've got a better ePSXe alternative to work with. Thank you weimingzhi & edgbla!
|
|
|
|
|
|
#75 |
|
Whistler
![]() ![]() Join Date: Apr 2008
Location: Lanzhou, P. R. China
Posts: 133
|
np, and I don't take credit on most of the core fixes/rewrites anyway (most of them are done by edgbla)
__________________
|
|
|
|
|
|
#76 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
Fear Effect 2 - Art Gallery Currently shows random garbage and then crashes NOTE: This will affect ePSXe also Problem: 24-bit MDEC interrupts run way too fast for the CPU decompression preparation. As you slow it down, you'll see strips of images with garbage in-between. And messed up colors. (ex. try 1000, 2000) So around 6000+ adjustment gets us the real image on the first pass. Garbage continues to spew on additional passes and eventual crash - unknown cause. Code:
mdec.c
} else { // 24-b decoding
//MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/ / BIAS);
MDECOUTDMA_INT((size / 4) / BIAS);
// Fear Effect 2 Artwork (6000+)
MDECOUTDMA_INT((size / 4) / BIAS * 6000);
size = size / ((24 * 16) / 2);
for (; size>0; size--, image += (24 * 16)) {
mdec.rl = rl2blk(blk, mdec.rl);
yuv2rgb24(blk, (u8 *)image);
}
}
For a real PSX example: YouTube - Fear Effect 2 35 Worst Ending, Art Gallery WARNING!! Bad ending spoiler up to 2:51. For just artwork, watch from 2:52 to end |
|
|
|
|
|
#77 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
ePSXe 170 uses memory access penalties (1f80 regs = 1, D-Cache + RAM + ROM? = 4) for both R/W. The Scratchpad / D-Cache is on-board the CPU and should only take 1-cycle (IMO). EDIT: Scratch that about 1f801c0c Last edited by shalma; May 28th, 2010 at 17:00.. |
|
|
|
|
|
#78 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
ePSXe 170 24-bit MDEC is missing (ex. Fear Effect 2 Art Gallery) They use something called 'mdec timing' - it only copies so many bytes per mdec interrupt or set amount of cycles. Don't quite understand what they're doing though. FE2 24-bit copies $5A10 bytes per DMA1 use. I had to use a 6800 multiplier because our output buffer was still in-use (we fill up the buffer in 0 cycles - right when DMA1 is called). The timing of how the MDEC output goes is a mystery to me. Maybe we should fill up the buffer when the MDEC IRQ fires? (this tells the game that -now- the data is ready)? Code:
DMA0 80115b3c 01b00020 01000201 DMA1 80110128 00b40020 01000200 (cmd = 30003600) mdec1Interrupt DMA1 8010a718 00b40020 01000200 (cmd = 30003600) mdec1Interrupt [$5A10 = 23056 bytes transfer] DMA1 80104d08 00b40020 01000200 (cmd = 30003600) mdec1Interrupt DMA1 800ff2f8 00b40020 01000200 (cmd = 30003600) mdec1Interrupt DMA1 800f98e8 00b40020 01000200 (cmd = 30003600) mdec1Interrupt DMA1 80110128 00b40020 01000200 (cmd = 30003600) f2:16.54 [A7430] f2:16.55 [A7431] f2:16.56 [A7432] |
|
|
|
|
|
#79 |
|
Whistler
![]() ![]() Join Date: Apr 2008
Location: Lanzhou, P. R. China
Posts: 133
|
seems epsxe 1.5.2 uses 0x217 for sio interrupt - but such value doesn't fix the some of the issues which seem to be sio timing issue in pcsx. EDIT: looks like epsxe also uses "hackish" way rather than accurate timing (I didn't see it adds additional cycles for multiply/division)... also, use the "1 cycle for all instructions + 4 additional cycles for memory access" to count the cycle and 0x217 for sio timing in pcsx fixes many of the games which has sio timing issues (FF8 with analog controller - the issue is mentioned in an "FF8 at Timber" thread below, Rhapsody, etc.)
__________________
Last edited by Whistler; June 6th, 2010 at 10:21.. |
|
|
|
|
|
#80 |
|
Discontinued
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Feb 2009
Location: Inactive
Posts: 1,192
|
Thanks for pointing out the Memory Access Time 'hack'. Didn't see that edit until now. ![]() Lemmings uses 24-bit MDEC. Just stating that the Fear Effect 2 hack is -way- too slow for the intro movie and eventually crashes the game (MDEC IRQ just didn't keep up with the CDROM). Lemmings also uses the commented-out code in cdrom.c when it detects CDDA (2 or more tracks): Code:
void cdrInterrupt() {
case CdlPlay:
(..)
// Unbreaks: Lemmings
if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime);
break;
case REPPLAY:
if ((cdr.Mode & 5) != 5) break;
if (CDR_getStatus(&stat) == -1) {
cdr.Result[0] = 0;
cdr.Result[1] = 0;
cdr.Result[2] = 0;
cdr.Result[3] = 0;
cdr.Result[4] = 0;
cdr.Result[5] = 0;
cdr.Result[6] = 0;
cdr.Result[7] = 0;
} else
// FIXME!
//memcpy(cdr.Result, &stat.Track, 8);
0;
cdr.Stat = 1;
SetResultSize(8);
AddIrqQueue(REPPLAY_ACK, cdReadTime);
break;
Last edited by shalma; June 12th, 2010 at 16:00.. |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|