Open snickerbockers opened 3 years ago
it looks like maybe the problem is that this game splits a single read operation up into multiple DMA transfers, and somehow WashingtonDC doesn't implement that correctly.
I seem to remember Windows CE having a similar problem back in March...
it looks like there's something fundamentally wrong with the way GDLEND is implemented, we only update it when state is GDROM_STATE_DMA_READING but some games may only read it after the transition to GDROM_STATE_DMA_WAITING; in this case the value of GDLEND will be incorrect because it will have retained the value it had before the DMA transfer.
but even though this needs to be fixed, it doesn't seem to be the reason why the 2k sports games are failing.
so it looks like i'm actually on the wrong track here, all i have to do is ignore all these errors and i can get in-game. maybe the game is actually doing weird things on purpose and i was wrong to assume it was being victimized by DMA bugs.
.
current status of 2k sports games with commit 931d7bab4ec73a08f8f8483fc738b2273d8a5367:
the "unimplemented texture format" mentioned above is YUV-422 with VQ compression
Tennis 2K2 is not included in this list since it's actually just Virtua Tennis 2 rebranded.
Going forward, the following things need to be done before merging this branch to master:
the NHL games are going to be handled in a separate bug since those don't seem to be using the same engine as the NBA and NFL games.
Oh geez, there's even more sports games on this console than I realized:
wrt to the 32767-sector read commands, one thing I've noticed is that it never actually transfers that much data to memory. It'll DMA something on the order of two or three figures. So maybe the reason why this works on real hardware is that it doesn't matter if programs over-read if they don't actually fetch the extra data from the drive.
regarding hang in NFL2K:
I have determined the cause of the hang is that the SH4 is stalled waiting for 0xa080203c to be non-zero.
0xa080203c is within AICA memory, and corresponds to 0x203c from the ARM7's perspective. This is the main-loop counter which is incremented once per iteration of the main loop in manatee.drv. If this is stuck at zero then the ARM7 is hanging somewhere at initialization or during its first iteration of the main loop. I have a high degree of confidence that fixing this will make the game bootable.
(gdb) hbreak *0x0c17218a
Hardware assisted breakpoint 1 at 0xc17218a
(gdb) c
Continuing.
Breakpoint 1, 0x0c17218a in ?? ()
1: x/i $pc
=> 0xc17218a: mov.l @r10,r8
(gdb) si
p0x0c17218c in ?? ()
1: x/i $pc
=> 0xc17218c: mov r13,r4
(gdb) p $r8
$3 = 0
(gdb) p/x $r10
$14 = 0xa080203c
the ARM7 is stuck in a loop at 0x2ceo where it polls address 0x3a04 until it is at least 3.
0x3a04 is a variable that counts how many times the FIQ vector has been invoked. So the problem is that it can't continue until FIQ has happened at least 3 times, and in our case it isn't happening.
Ergo the next step will be to understand why it is expecting FIQs, and why there have not been any.
bit 10 is the only bit in SCIEB which is set. This corresponds to "One-sample interval interrupt" according to neil corlett's AICA notes. I don't believe this is implemented yet, therefore this is highly likely to be the root-cause of the problem.
(WashDbg): x 0x0080289c
0x0080289c: 0x00000400
the one-sample interval interrupt has been implemented in commit 3221accd31c8d37e61a5c00e1b9d5e8e72274f55; with this commit, NFL2k is finally booting so that was indeed the root cause of the problem with that game.
current state of 2k-sports games in master vs the 2k_sports branch. MMU column denotes whether the given game requires MMU support.
| game | master | 2k_sports | MMU |
|----------------------------------------------------------------------------------+---------+-----------+-----|
| NBA 2K v1.008 (1999)(Sega)(US)[!][1S] | fails | in-game | no |
| NBA 2K1 v1.008 (2000)(Sega)(US)[!][1S] | fails | fails | yes |
| NBA 2K1 v1.008 (2000)(Sega)(US)[!][6S] | fails | fails | yes |
| NBA 2K2 v1.000 (2001)(Sega)(US)[!][1S] | fails | fails | yes |
| NCAA College Football 2K2 - Road to the Rose Bowl v1.003 (2001)(Sega)(US)[!][2S] | fails | fails | yes |
| NFL 2K v1.007 (1999)(Sega)(US)[!][10S] | fails | in-game | no |
| NFL 2K v1.007 (1999)(Sega)(US)[!][9S] | fails | in-game | no |
| NFL 2K v1.007 (1999)(Sega)(US)[!][13S] | fails | in-game | no |
| NFL 2K v1.007 (1999)(Sega)(US)[!][MT B08, B13, B19, B20] | fails | in-game | no |
| NFL 2K1 v1.003 (2000)(Sega)(US)[!][4S] | fails | fails | yes |
| NFL 2K2 v1.004 (2001)(Sega)(US)[!][2S] | fails | fails | yes |
| NHL 2K v1.000 (2000)(Sega)(US)[!] | fails | fails | no |
| NHL 2K2 v1.008 (2002)(Sega)(US)[!][5S] | fails | fails | no |
| Tennis 2K2 v1.003 (2001)(Sega)(US)(M5)[!] | in-game | in-game | no |
| Tennis 2K2 v1.009 (2001)(Sega)(US)(M5)[!] | in-game | in-game | no |
| World Series Baseball 2K1 v1.000 (2000)(Sega)(US)[!][3S] | hangs | hangs | no |
| World Series Baseball 2K1 v1.000 (2000)(Sega)(US)[!][5S] | hangs | hangs | no |
| World Series Baseball 2K2 v1.000 (2001)(Sega)(US)[!][1S] | fails | fails | no |
| World Series Baseball 2K2 v1.000 (2001)(Sega)(US)[!][3S] | fails | fails | no |
still trying to piece together what's going on, but the general gist is that these games are doing some erratic operations with the GD-ROM drive (such as sending DMA read packets but never initiating the DMA transfer) before ultimately trying to read past the end of the GD, which triggers an ERROR_UNIMPLEMENTED in WashingtonDC. The earliest sign of trouble and the first thing that should be investigated is when they use a NOP to cancel a read.
The most important thing to note about these games is that they do not appear to be using the firmware's system calls for GD-ROM drive access; I believe they have their own custom GD-ROM driver which would explain why this problem appears to be unique to 2K sports games.
I've only tried out NBA 2K and NFL 2K, but i assume that the same problem applies to most other games from the 2K sports series.