Help with DIY XenoGC emulation

Portables, case replacements, mods etc, all in here!
Post Reply
Posts: 3
Joined: Tue Jun 02, 2020 4:55 pm

Help with DIY XenoGC emulation

Post by AuHewitt » Tue Jun 02, 2020 7:49 pm

Hello everyone,

I have recently set about attempting to make my own XenoGC drive chip based off the released source code and translating that to a PIC18LF25K80. I have a few questions that I think this community will be able to help me answer, I'll put the questions in list format with documentation for ease when answering.

Reference Material:
(A) viewtopic.php?t=403
(B) viewtopic.php?t=439

(1) Does the SPI port on the drive chip operate in SPI mode 3? What CLK speed should transmissions be sent? Are bytes sent lsb first?

- Probing the CLK line of the GC when powered on shows an idle state of high, narrowing the possible modes to 2 & 3. Based on the source code in reference B (in the XenoAT.c file, specifically the io function within that file) I initially thought the falling edge of the CLK line sampled data (SPI mode 2). However, after failing to get expected responses I changed my code to sample on the rising edge and the data I receive appears accurate.

- I set my clock speed to approximately 5 kHz, a post on the second page of reference A states that the per bit time frame is about 130 us. Not sure if he means the whole period or the half period, but 130 us and 260 us equates to 7.62 kHz and 3.85 kHz, respectively. At my set speed I receive good data, so I am assuming the CLK speed is not an issue.

- From the source code in reference B (in the XenoAT.c file, send8 function) it appears that bytes are shifted out lsb first to the io function. Just wanting to confirm that I am correct in that assumption.

(2) What is the memory location that I must read to determine the state of the buttons being pressed on a connected controller?

- From the source code in reference B (in the XenoAT.c file, when the read_mem function is called) the base address read appears to be 0x40D100 with a read length of 2 bytes. From a post in source A, on page 1, the response to issuing the read_mem command (which is the following sequence of bytes: 0xFF,0x00,0xD1,0x00,0x00,0x40,0x00,0x00,0x02,0x00) should be: 0x00,0x00,0xFF,0xFD. However, when I issue the command I receive: 0x00,0x00,0x5D,0x49 or sometimes: 0x00,0x00,DD,0xFF. From the source code in reference B (in the XenoAT.c file, read_mem function) I know that the first 2 bytes returned are related to any errors that might occur, with 0x00 for both bytes meaning the request was error free. I attempted to find a memory map of where various values are stored, I searched all through reference C, and read them back as a sanity check, but I cannot find complete enough documentation that is clear enough to me to do so (my opinion of reference C).

Below is a snippet of the code execution halted right after receiving the response to the read command, I have highlighted the important values:

(3) Does the required upload.bin, qcodes.bin and credits.bin need to be read out in a special way? (weird question, let me clarify)

- I am not a novice in embedded coding, but instead of including the .bin files when I compile my source code I have opted to have them stored in an array within my source code (makes more sense to me that way). To do this, I wrote a small python program that reads in the .bin files (byte at a time) and then outputs them to a new text file in the form of: {0x00,0x00,0x00,etc} for copying to my program and also outputs the total length of the array.

- After reading the controller state, which may not even be working, I begin to write the associated "upload.bin" in its array form starting at the memory location 0x40D000 (reference B, in the XenoAT.c file). In reference A, in a first page post, I am able to track the commands he recorded with my code until about the 6th write transmission:

Synchronizing CMD: {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} Response: 0xEE,0xEE
Read (0x40D100) CMD: {0xFF,0x00,0xD1,0x00,0x00,0x40,0x00,0x00,0x02,0x00} Response: 0x00,0x00,0x5D,0x49 (suppose to be 0x00,0x00,0xFF,0xFD???)
Write (0x40D000) CMD: {0xFE,0x00,0xD0,0x00,0xF7,0x40,0x10,0x00,0x02,0x00} Response: 0x00,0x00,0xF7,0x10
Write (0x40D002) CMD: {0xFE,0x00,0xD0,0x02,0xFF,0x40,0xF7,0x00,0x02,0x00} Response: 0x00,0x00,0xFF,0xF7
Write (0x40D004) CMD: {0xFE,0x00,0xD0,0x04,0xF5,0x40,0xD9,0x00,0x02,0x00} Response: 0x00,0x00,0xF5,0xD9
Write (0x40D006) CMD: {0xFE,0x00,0xD0,0x06,0xC8,0x40,0xFF,0x00,0x02,0x00} Response: 0x00,0x00,0xC8,0xFF
Write (0x40D008) CMD: {0xFE,0x00,0xD0,0x08,0xF4,0x40,0xC0,0x00,0x02,0x00} Response: 0x00,0x00,0xC4,0xC0
Write (0x40D00A) CMD: {0xFE,0x00,0xD0,0x08,0xF4,0x40,0xC0,0x00,0x02,0x00}
------*My Write CMD is: {0xFE,0x00,0xD0,0x08,0xA0,0x40,0xF4,0x00,0x02,0x00}

- Since my command packets seem to match with what an actual XenoGC would send out, I believe that the method I used to convert the upload.bin to array format might be causing the data to be inaccurate after the 10th byte in the array.

Thank you for any help, I've had fun so far attempting this emulation/hack. Ill upload my main.c for viewing and supply more info if needed.
relevant files
(13.09 KiB) Downloaded 8 times
Posts: 3
Joined: Tue Jun 02, 2020 4:55 pm

Re: Help with DIY XenoGC emulation

Post by AuHewitt » Fri Jun 12, 2020 8:28 pm

Since my original post, I have solved all the problems I was having. I am now at the stage in the Xeno code where I begin to upload the drive code! However, during the transfer the previously uploaded code (boot loader) responsible for receiving the drive code stops responding.

Uploading drive code length:

After writing the value of: 0x0086 to address: 0x804D (which redirects a jump toward the bootstrap), I write: 0x00, 0x00, 0x04, 0x82 to the SPI with the last two bytes being bit shifted values of the drive code size (0x904 for QCodes). Shifting of the upload size was done like the original Xeno source code where 0x04 comes from 0x904 >> 9 and 0x82 from 0x904 >> 1 which is truncated to a char size. I know that I have successfully uploaded the boot loader code as the game cube responds how it should at the beginning of the transfer (relaying the past byte received on the next transfer), however despite following the original source code for relaying the upload size, the transfer always stops short. See the image below.

Transfer working at the start:

Suddenly stops responding mid transfer:

I have tried to analyze the boot loader code, but it has been a few years since I took a class on assembly language. Referencing the image below, I can tell that at the start of the transfer the BL code sends out: Q(0x51), C(0x43), O(0x4F), D(0x44) which I see in the first image above. It appears that when I receive C(0x43) and send the shifted drive code length (0x04), that the BL multiplies that value by 256 and stores it in variable(not sure if it is actually a register) d1. Then on the next transfer (receiving O(0x4F) and sending 0x82) the BL adds the received value to the d1 variable (or register haha). The transfer of the drive code then begins and the BL decrements the d1 value every time a byte is received. Doing the math myself, the d1 value at the start of the transfer should be over 2000 bytes (pretty sure the 256 is in hex and not decimal), but the interruption of the transfer seems to occur around 102 bytes and I have no idea why. Ill add some images below to show my method for uploading the drive code length in comparison to the original source code.

Boot loader code:

Comparison of drive code upload length method:

Comparison of drive code upload method:

Any help would be great, thanks!
User avatar
Diego borella
Posts: 127
Joined: Sat Jan 11, 2020 8:37 pm
Location: Brazil

Re: Help with DIY XenoGC emulation

Post by Diego borella » Fri Jun 12, 2020 9:43 pm

of everything I can say about my experience with the Xeno code and chip, is as follows:
inside the Xeno fork code, there are 2 specific DOLs.
and xenoshell.p.dol

if I enter xenoshell.p.dol.
falls there on that yellow screen ....
however, if I start GCos. and then launch xenoshell.p.dol
it will fall on a GCos screen.
there is something broken; or the embedded GCos would be getting in the way ... :idea: :?:
Posts: 3
Joined: Tue Jun 02, 2020 4:55 pm

Re: Help with DIY XenoGC emulation

Post by AuHewitt » Fri Jun 12, 2020 10:27 pm

I think the .dol files are for SD loading the exploit. I emulate the XenoGC mod chip with a PIC18. I first sync the spi line on start up, read 0x40D000 to check if the credits binary was requested (if not i upload the qcodes), then I upload the boot loader, upload the redirection code that will hook the processor to the boot loader code, then redirect the processor to the start of the hook code and finally upload the drive code (qcodes or credits binary).

Ill attach the respective binary files I am uploading.
(4.32 KiB) Downloaded 8 times
Post Reply