I'm wanting to try out this opensource lib, but the GTE stuff is missing. They have the functions address (I assume) ie: Code: /** Perspective transformation */ GTE_OP_RTPS = 0x0180001, /** Perspective Transformation on 3 points */ GTE_OP_RTPT = 0x0280030, Here: https://github.com/ColdSauce/psxsdk/blob/master/libpsx/include/psxgte.h I've grep'ed to see if it's used anywhere in the code base and it's not. No$PSX doc explains how to use these op codes, but need help converting to C ( I'm not an asm guy): Code: GTE Operation The GTE doesn't have any memory or I/O ports mapped to the CPU memory bus, instead, it's solely accessed via coprocessor opcodes: mov cop0r12,rt ;-enable/disable COP2 (GTE) via COP0 status register mov cop2r0-63,rt ;\write parameters to GTE registers mov cop2r0-31,[rs+imm] ;/ mov cop2cmd,imm25 ;-issue GTE command mov rt,cop2r0-63 ;\read results from GTE registers mov [rs+imm],cop2r0-31 ;/ jt cop2flg,dest ;-jump never ;\implemented (no exception), but, jf cop2flg,dest ;-jump always ;/flag seems to be always "false" Would this be used for all GTE op codes? What variable do I swap out (hardcode) with the op code? ie: If I were to use GTE_OP_RTPS (Perspective transformation) do I replace imm25 with 0x0180001 And where do the variables go? Thanks for any info. Cheers
OK, unfortunately, it's pretty complicated - and Martin doesn't help by expressing things using his 'x86 like' assembler syntax rather than the one that the PSX assembler actually uses. The coprocessor interface on MIPS uses only 3 instructions (x is coprocessor #, so 2 for the GTE) COPx {opcode} MTCx {register},{coproc reg#} MFCx {register},{coproc reg#} COPx issues commands, so that's what you would use the numbers in the header file with The MTC (move to coprocessor) and MFC (move from coprocessor) commands are the only way to get data in and out of the coproc. The GTE generally puts control related data in the higher register numbers (32 to 63) and actual data in the lower registers (0 to 31), although this line is somewhat blurred. In general, the process goes something like this: Put the data that's going to be true for several operations (I.E. things like the rotate matrix and the translation values) into the high-numbered coproc registers and then loop around sticking the per object data into the lower coproc registers, issuing the command then fishing the results out of the FIFOs. I'm sorry this is so vague, but different instructions do different things, and use different subsets of the registers. If we take RTPT as an example, then the things that need to be set up (using MTC2) are: Rotation matrix (COP2 r32 to r36) Translation vector (COP2 r37 to r39) Eye transform data (COP2 r56 to r60) For the operation, you need to fill in the 3 vectors for the poly - these go in COP2 r{0,1}, r{2,3}, r{4,5}, Then execute COP2 0x0280030 After it completes, the transformed values are in the screen x y and z fifos (COP2 r12 to r19) and the depth cue value is in COP2 r8 - use MFC2 to read them
Hey thanks man! Yeah that is complicated MPIS asm.. ha shame. Someone built that GNU PSXSDK and tool chain for cygwin, was hoping to use that instead of the net yaroze stuff. Cool, thanks again.
I suspect your alternative for an open sdk and gcc development is to compile your own build and make tweaks specifically for the GTE, with all the rules it requires. On that matter, I think I will be releasing soon my source of dmpsx, the GTE interpreter for PSY-Q, which could be integrated into gcc for adapting these rules like in Sony's specs. As for C code, you are pretty much stuck with inline assembly. There is really no other way around it, even if you wanted to avoid using cache optimizations with actual functions (whether or not they are forced inline code). Side note: I tried some newer version of gcc (4.5.x) and it generated awful r3000 code (with other MIPS machines with a real cache it should be fine). It completely breaks the flow for proper caching, with weird jumps at the end of a logical block only to go back in the middle at random points of execution. I suspect there may be some gcc flags to lay instructions in a similar order to what your C code is written like, but I could barely recompile binutils with mingw so no idea how feasible that is in reality.
Oh no no.. I just don't want to use psy-q and thought that psxsdk could be a usable alternative to the Net Yaroze stuff I own. But what's required is just over my head! re: dmpsx, the GTE interpreter for PSY-Q I doubt I could use the asm info to port it something usable in C (even inline!)
I wasn't talking about using PSY-Q, but some of its internal functioning for injecting proper instructions. dmpsx is pretty much essential for any GTE code, especially for how cop2 instructions work on hardware. gcc shouldn't be able to tell for how many cycles the GTE is busy doing its calculations, which is where dmpsx comes into action to tell you if you're doing it correctly or not. Of course, that can be fixed if you change gcc for MIPS by implementing dmpsx checks on GTE instructions that require a specific delay, like RTPT.
Thanks Gemini man, but yeah over my head :/ Is this your blog? http://appleofeden.de-doc.com/index.php/2016/04/14/the-weird-art-of-optimization/#comments Based on what triMesh said and that post, that's a good guide, thanks guys! I'll see if I can use it.
GCC hasn't been great for me outside of ARM and x86, I imagine the r3000 target hasn't been touched in a while. With that said it did work pretty good on SH-4 once I compiled GCC with the proper configuration flags for the FPU. I imagine there are similar flags for the cache configurations on the r3000. Wasn't GCC forked to create the PSY-Q compiler for the official kits? Also as a side note, if LTO is enabled you will get some truly strange code. I imagine the output makes sense for more congruent CPUs but if you are looking for very literal assembly make sure you have it disabled.
Anyone else interested in an open/free PSXSDK: fanzyflani did a small yet inpressive SDK and on top made a game with it! https://fanzyflani.itch.io/frametime And also https://github.com/fanzyflani/mld62 My dev env is winXP, this toolchain works natively without msys https://code.google.com/archive/p/psxsdk/downloads psxsdk-20120303-win32-inst.exe PSXSDK 20120303 installer for Windows May 25, 2012 52.94MB Yeah it's old, I figured it would work :/ but getting undefined's
gcc optimised for ps1 would be pretty cool, it could move gte instructions and writes to memory around so that as much is done in parallel as possible. The write fifo allows multiple values to be stored in main memory, but they get written out while other instructions are running. The cpu block when the fifo is full, possibly also on reads (but I'm not 100% sure on that). If it could analyse code layout to make the most of the ps1 cache then that would be amazing.
I got it working: Code: mipsel-unknown-elf-gcc -IC:\psx-sdk\include -c -fomit-frame-pointer -fno-stack-protector -G1 -O3 -msoft-float -nostdlib -nodefaultlibs -mips1 -march=3000 *.c mipsel-unknown-elf-as -G1 -o head.o head.S mipsel-unknown-elf-gcc -o main.elf *.o -T link.ld -LC:\psx-sdk\lib\ -LC:\psx-sdk\lib\gcc\mipsel-unknown-elf\4.7.0\soft-float\ -LC:\psx-sdk\libpsone -lm -lc -lgcc -lmg strip -R .reginfo -R .pdr -R .text.startup -R .eh_frame -R .comment -R .gnu.attributes -R .rel.dyn main.elf objcopy -O binary main.elf main.tmp cp main.tmp main.exe