unknownbrackets / ps2autotests

A set of test programs run on a PS2, with accompanying results.
ISC License
25 stars 7 forks source link

Testing for existence of the GTE #30

Open Kingcom opened 8 years ago

Kingcom commented 8 years ago

The PSX had a Geometry Transformation Engine as COP2 for basic linear algebra calculations. It would be interesting to know if it still exists on the PS2's IOP, or is potentually emulated in software.

To enable the GTE, you first need to set bit 30 of COP0.r12.

Here is some sample code for using it, which calculates the weighted average of two color vectors: http://pastebin.com/0S3wGed9 The signature for the function there is void LoadAverageCol(unsigned char in1[3], unsigned char in2[3], long weight1, long weight2, unsigned char out[3]); Note that the last parameter is passed on the stack.

jpd002 commented 8 years ago

Came up with a very quick test case using the function you've provided (slightly modified to set bit 30 of COP0.r12):

#include <common-iop.h>
#include <stdio.h>
#include <tamtypes.h>

extern void LoadAverageCol(unsigned char*, unsigned char*, int, int, unsigned char*);

int _start(int argc, char **argv) {
    printf("-- TEST BEGIN\n");

    unsigned char inColor1[3] = { 0x00, 0xCC, 0x00 };
    unsigned char inColor2[3] = { 0xAA, 0x00, 0xAA };
    unsigned char outColor[3];

    LoadAverageCol(inColor1, inColor2, 0x1000, 0x1000, outColor);
    printf("outColor: %x, %x, %x\n", 
        outColor[0], outColor[1], outColor[2]);

    LoadAverageCol(inColor1, inColor2, 0x800, 0x800, outColor);
    printf("outColor: %x, %x, %x\n", 
        outColor[0], outColor[1], outColor[2]);

    printf("-- TEST END\n");

    return 0;
}

And this yields the following result:

-- TEST BEGIN
outColor: aa, cc, aa
outColor: 55, 66, 55
-- TEST END

Which seems to indicate that the IOP has the GTE. I will push a branch with the code later.

Kingcom commented 8 years ago

Very nice! Can you maybe test what happens if you don't set the COP0 bit, too?

unknownbrackets commented 8 years ago

Well, that's interesting. I guess that means we need a set of tests for all the GTE ops.

Do you know if there's any architecture docs for the GTE instructions? I'd probably want to create an "assembler" like with the VU.

-[Unknown]

jpd002 commented 8 years ago

@Kingcom If the bit is not set, the CPU throws a coprocessor unusable exception.

jpd002 commented 8 years ago

Here's the code for reference purposes: https://github.com/jpd002/ps2autotests/tree/gte_test/tests/cpu/gte.

For GTE instructions, there's this documentation that I know of, but I'm not sure about its completeness: http://psx.rules.org/gte.txt.

ramapcsx2 commented 8 years ago

Thanks a lot you guys :) There's also confusion about the MDEC unit, which is physically in the CPU and talks to the GPU via DMA. I don't know much more but I wonder if that's also still in IOP. Chances are, it is. But this GTE finding helps a lot :)

ramapcsx2 commented 8 years ago

@unknownbrackets I don't expect the IOP GTE to differ from a regular PSX. They use it in PSX mode, after all. People in the PSX dev scene would surely like it though. They're saying GTE isn't very well documented: http://www.psxdev.net/forum/viewtopic.php?f=70&t=551&start=40

ramapcsx2 commented 8 years ago

Regarding the MDEC, it's prolly the upper left here: https://i.imgur.com/gsxPq5i.jpg :)

refractionpcsx2 commented 8 years ago

Thank you for finding this out guys :) I was pretty sure this was the case, had no proof of it though and subsequently got my addition of it in PCSX2, now I have no reason not to put it back in again for the long quest of PSX emulation :)

ADormant commented 8 years ago

@jpd002 These GTE documentations are better @refractionpcsx2

http://problemkaputt.de/psx-spx.htm#geometrytransformationenginegte https://github.com/simias/psx-guide https://github.com/simias/pops-gte http://www.romhacking.net/documents/124/ https://github.com/ogamespec/psxdev https://sourceforge.net/projects/mednafen/

ADormant commented 8 years ago

By the way is it already known if PS2 has MDEC or not?

refractionpcsx2 commented 8 years ago

Yeh MDEC would be interesting to know or if that is fused to another unit in some way.

ADormant commented 8 years ago

https://github.com/simias/psx-hardware-tests/tree/master/tests https://github.com/simias/rustation/commit/f3f2aff7c8d5aeea52c4dadb88cd705198191087 @jpd002 @unknownbrackets

jpd002 commented 8 years ago

Reading from 0x1F801824 (which is the MDEC1 register from what I can gather) after writing 0x80000000 (which should reset the MDEC) at that address gives 0x80040000 which appears to be the "initial" value for that register according to the documentation I've read.

I'm not quite familiar with the MDEC, but I'll see if I can come up with a better test.

jpd002 commented 8 years ago

Thanks for the docs, @ADormant !

unknownbrackets commented 8 years ago

I messed with sending some data to the MDEC control register and MDEC data register, and aside from reset, garbage also affects it.

The results are repeatable. For example, writing 0x01230001 to MDEC command/data changes control to 0x80040001. This is exactly how Martin describes NOP operating. I'm not sure if it actually decodes macroblocks, etc., but there appears to be something there indeed. I'd guess it does function, but could be wrong.

And, 0x12345678 results in 0x84845678 for control. Which also makes sense, I think...

My test (using IOP_CFLAGS= -std=c99):

#include <stdio.h>
#include <tamtypes.h>

static volatile u32 *MDEC_DATA = (volatile u32 *)0x1F801820;
static volatile u32 *MDEC_CONTROL = (volatile u32 *)0x1F801824;

int _start(int argc, char **argv) {
    printf("-- TEST BEGIN\n");

    printf("Control: %08x\n", *MDEC_CONTROL);
    printf("Data: %08x\n", *MDEC_DATA);

    *MDEC_CONTROL = 0x40000000;
    printf("Control: %08x\n", *MDEC_CONTROL);

    for (int i = 0; i < 10000000; ++i) {
        if (*MDEC_CONTROL != 0x80040000) {
            printf("Control changed: %08x\n", *MDEC_CONTROL);
            break;
        }
    }

    *MDEC_DATA = 0x12345678;
    printf("Control: %08x\n", *MDEC_CONTROL);
    printf("Data: %08x\n", *MDEC_DATA);
    printf("Control: %08x\n", *MDEC_CONTROL);

    printf("-- TEST END\n");
    return 0;
}

-[Unknown]

ramapcsx2 commented 8 years ago

The GTE test works in PCSX2 now :) There's total confusion how to handle hardware reads and writes though.

https://github.com/PCSX2/pcsx2/blob/master/pcsx2/ps2/Iop/IopHwRead.cpp#L310 https://github.com/PCSX2/pcsx2/blob/master/pcsx2/ps2/Iop/IopHwWrite.cpp#L513

DMAs are going to be for SIF2 to handle. You can invoke it with WriteFifoSingleWord() / ReadFifoSingleWord(); Unfortunately, nothing in SIF2 is tested. Total lack of documentation and tests..

TheLastRar commented 8 years ago

Some more PS1 hardware tests http://psx.amidog.se/doku.php?id=psx:download:cpu http://psx.amidog.se/doku.php?id=psx:download:gpu http://psx.amidog.se/doku.php?id=psx:download:gte http://psx.amidog.se/doku.php?id=psx:download:misc

I don't know how feasible it is to run all of these on a PS2. But these tests have been used to compare PS1 emulators http://emulation.gametechwiki.com/index.php/PS1_Tests

refractionpcsx2 commented 8 years ago

Probably possible now on PCSX2, gregory has recently implemented IRX running support https://github.com/PCSX2/pcsx2/commit/c00b427efa9ec22c03e6ad1b6e3f0fe158616c94

this puts the EE idle and runs the IRX directly, we don't make the COP2 bit of the control registers mandatory for GTE support, so it will probably just work lol

TheLastRar commented 8 years ago

The tests I linked are pre-compiled PSX EXEs, which have a different header to IRX files. PCSX2 crashes when trying to load them.

refractionpcsx2 commented 8 years ago

oh yeh, they're exe's, forgot about that, damn, nevermind, they would probably need to be put on a psx format cd and executed that way for pcsx2, invoking the ps1 emulation, but that's the only way they would execute currently :(