Archive for October, 2012

The COP Diary #3

Monday, October 1st, 2012

#15 Advanced Hit Test

With this we tried to understand better the collision detection, by repeately poll the collision ports but it didn’t gave reasonable results. Amusingly, if you don’t clear the unused data of the collision table it will give complete garbage.

#16 Purple Laser Test

a.k.a. test for 0x6200 COP macro, used by various games to calculate angle direction according to a fixed function.  This is used by Raiden 2 purple laser, chopper (first enemies ) facing direction, SD Gundam homing weapon and 3rd level mid-boss direction (and probably others too). We now do know that the algo does some corrections to the result in particular circumstances, discovering what these are is the next goal.
#17 Ext Pin Test

In Legionnaire program code there’s a weird r/w access to an i/o port in range 0x700-0x7ff while polling bit 13 of the external port (0x470), then it puts the results of this weird read to some work RAM addresses that are never readed-back by the program itself. We tried to read the contents of this while doing the exact same thing as Legionnaire, but it just returned 0xffff. So it’s very likely to be a development left-over (either debugging device or a feature of the game that was discarded at some point).

#18 OBJ Y Test


This tested video register 0x644. The test confirmed that is a simple Y base register for sprites.

#19 0905/0904/0903/0902/0985/0984 Test

This checked the simplest macro (the 0x905, aka read to work RAM address X, add with RAM address Y, write the result to RAM address Z) and tried various combinations of it. 0x905 behaves normally, 0x904 (used in Zero Team and X Se Dae) definitely does a subtraction instead of an addition, 0x903/0x902 doesn’t do anything and 0x985/0x984 behaves like 0x905/0x904, respectively.
There’s a new theory, where the COP trigger is masked with a ~0x281 value when it executes commands at 0x50x, to define what COP macro should be executed (and also explains why Seibu Cup Soccer tries to execute 0xe18e, that isn’t in the uploaded table at all).

#20 DDE5 Test

This is used by the radar in Seibu Cup Soccer, but what we do know about it is completely wrong, so it doesn’t return any result in there. It doesn’t help that we still don’t have a proper way to access COP registers that are above 3 (see also test #13).

#21 DMA 14/15 Test

This checked if the DMA is really a burst one (-> halts main CPU and takes complete control over the system). The algo is:


enable both DMAs (14/15)
\-resync to v-blank
\-set the vblank flag to 1
\-increment a variable by one, and check if vblank goes to 0, if not rinse and repeat.
\-Put the variable buffer to screen
Disable DMA 14, enable 15
\-(do the above again)
Enable DMA 14, disable 15
\-(do the above again)
Disable both DMAs (14/15)
\-(do the above again)

Disregard the snapshot, timings with this algo are: 0xaa1/0xaa2 for first test, 0xafb for second, 0xac6 for third and 0b1f for fourth. So the test confirmed that the DMA is really a burst one, and also that the original PCB is slighlty slower than emulation in “idle” mode (either refresh rate or waitstates). Next step is to extract the exact timings out of the DMA.

#22 680 Test

This test tried to check out what’s the meaning of writing to port 0x680 (that is done at irq routine by all games). I’ve expected a full stop of the operations (so that is an irq ack) or a jumpy sprite movement (so that is a sprite buffer copy). It’s neither of those, fun.

#23 COP R/W Test/COP Read Test/Bogus R/W Test/Bogus RAM Test

This one tries to r/w the COP ports (0x100400-0x1005ff). System locks up if there’s an attempt to write at 0x100430 for whatever reason. Every other register prior to that seems to be read-backable.
With Bogus RAM test, it tries to check out RAM addresses 0x100000-0x1003ff. It’s a normal RAM.
With the Read tests instead, we tried to only do a read to these addresses, and we did two discoveries. A) default RAM pattern seems to be:

if((ram_addr & 0x20) == 0x20)
return 0x4141
else
return 0x0f0f

B) none of the 0x5** COP registers have default RAM values (returns either 0xffff or default state values), while all of the 0x4** all returns 0x4141 / 0x0f0f except to where I’ve did mods for the correct functioning of the system (so it returns back last value I’ve written in there).