Line 439:
Line 439:
=== 0x83 DVDLowGetLength ===
=== 0x83 DVDLowGetLength ===
−
Stores the last DILENGTH value into outbuf, which must be at least 4 bytes in size (or else 0x20 is returned). Note that this doesn't directly read DILENGTH, but rather a separate value that is set when DILENGTH is set, but zero'd after reading for most commands. The only commands that leave a nonzero value are DVDLowInquiry and DVDLowRead (which doesn't even record the right field...).
+
Stores the last DILENGTH value into outbuf, which must be at least 4 bytes in size (or else 0x20 is returned). Note that this doesn't directly read DILENGTH, but rather a separate value that is set when DILENGTH is set (and zero'd if a read error occurs on a command that uses DILENGTH; this means that this command cannot be used to get the amount of data still left to be transfered when the error happened).
{| class="wikitable"
{| class="wikitable"
Line 622:
Line 622:
Before any of these commands are executed (other than 0x8A DVDLowReset and 0xE0 DVDLowRequestError), the error interrupt status is checked, and if it is set, it will clear it by setting bit 2 of DISR. <!-- Note that there are messages for if clearing it fails, but no way for it to actually fail. -->
Before any of these commands are executed (other than 0x8A DVDLowReset and 0xE0 DVDLowRequestError), the error interrupt status is checked, and if it is set, it will clear it by setting bit 2 of DISR. <!-- Note that there are messages for if clearing it fails, but no way for it to actually fail. -->
−
If an output buffer size check fails, DIMAR, DILENGTH, and Last_DILENGTH will not be written, and there is code that sets the return value to 0x20. However, the driver still attempts to start the transfer, which will fail due to not writing DILENGTH (which should have counted back down 0 after any previous successful transfer{{check}}); this will result in an eventual timeout and returning of 0x10{{check}}. <!-- This seems completely wack, but it seems to be how the code works... -->
+
If an output buffer size check fails, DIMAR and DILENGTH will not be written, and there is code that sets the return value to 0x20. However, the driver still attempts to start the transfer, which will fail due to not writing DILENGTH (which should have counted back down 0 after any previous successful transfer{{check}}); this will result in an eventual timeout and returning of 0x10{{check}}. <!-- This seems completely wack, but it seems to be how the code works... -->
=== 0x12 DVDLowInquiry ===
=== 0x12 DVDLowInquiry ===
Line 634:
Line 634:
DICMDBUF0 = 0x12000000
DICMDBUF0 = 0x12000000
DILENGTH = 0x20
DILENGTH = 0x20
−
Last_DILENGTH = 0x20
DIMAR = outbuf
DIMAR = outbuf
DICMDBUF1 = 0
DICMDBUF1 = 0
Line 656:
Line 655:
This command cannot be used while the drive interface is resetting (if [[IOS/Syscalls|syscall]] 0x46 syscall_check_di_reset returns true); in which case it will return 0x80. 0x80 will also be returned if the output buffer is not 32-byte aligned.
This command cannot be used while the drive interface is resetting (if [[IOS/Syscalls|syscall]] 0x46 syscall_check_di_reset returns true); in which case it will return 0x80. 0x80 will also be returned if the output buffer is not 32-byte aligned.
−
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion.
+
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written.
DICMDBUF0 = 0xA8000040
DICMDBUF0 = 0xA8000040
Line 662:
Line 661:
DICMDBUF2 = 0x20
DICMDBUF2 = 0x20
DILENGTH = 0x20
DILENGTH = 0x20
−
// Last_DILENGTH = 0x20
DIMAR = dest
DIMAR = dest
DICR = TSTART | DMA
DICR = TSTART | DMA
Line 677:
Line 675:
|}
|}
−
After this command has finished reading, the driver will also look at the 4 bytes at offset 0x18 in the output (i.e. outbuf[6] if outbuf is a u32 array) for the Wii magicword 0x5D1C9EA3 to determine if it is a [[Wii Disc|Wii disc]]. If it is a Wii disc, and it has not already read it, it will read 0x44 (padded to 0x60) bytes starting at byte 0x20 (i.e. the game title, and the disable hashing and disable encryption flags).
+
After this command has finished reading, the driver will also look at the 4 bytes at offset 0x18 in the output (i.e. outbuf[6] if outbuf is a u32 array) for the Wii magicword 0x5D1C9EA3 to determine if it is a [[Wii Disc|Wii disc]]. If it is a Wii disc, and it has not already read it, it will read 0x44 (padded to 0x60) bytes starting at byte 0x20 (i.e. the game title, and the disable hashing and disable encryption flags). Thus, after the first call, DVDLowGetLength will return 0x60, and on later calls it will return 0x20.
=== 0x71 DVDLowRead ===
=== 0x71 DVDLowRead ===
Line 687:
Line 685:
This command immediately returns 0x20 if the buffer is too small, and also returns 0x20 if something went wrong with decryption or hashing and 2 for a drive error.
This command immediately returns 0x20 if the buffer is too small, and also returns 0x20 if something went wrong with decryption or hashing and 2 for a drive error.
−
If everything completed successfully, Last_DILENGTH is set to offset. Otherwise, it is set to 0.
+
If everything completed successfully, the last length value used by DVDLowGetLength is set to offset (almost certainly a mistake on Nintendo's end). Otherwise, it is set to 0.
{| class="wikitable"
{| class="wikitable"
Line 744:
Line 742:
Probably related to DVD-Video{{check}}.
Probably related to DVD-Video{{check}}.
−
The output buffer size must be ≥ 0x800, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x800, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xAD000000 | (position << 8) // AD00XX00
DICMDBUF0 = 0xAD000000 | (position << 8) // AD00XX00
Line 798:
Line 796:
Probably related to DVD-Video{{check}}.
Probably related to DVD-Video{{check}}.
−
The output buffer size must be ≥ 0x800, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x800, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xAD020000 | (position << 8) // AD02XX00
DICMDBUF0 = 0xAD020000 | (position << 8) // AD02XX00
Line 899:
Line 897:
The output buffer must be 32-byte aligned and the length must also be a multiple of 32; otherwise, 0x80 is returned.
The output buffer must be 32-byte aligned and the length must also be a multiple of 32; otherwise, 0x80 is returned.
−
The output buffer size must be ≥ length, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion.
+
The output buffer size must be ≥ length, or DIMAR and DILENGTH will not be written.
DICMDBUF0 = 0xA8000000
DICMDBUF0 = 0xA8000000
Line 1,083:
Line 1,081:
Nintendo titles send this after performing the off-disc DVDLowUnencryptedRead check to verify that they are on official hardware; specifically, the first parameter is set to 4 (internally, 0x40000 >> 16) and the second parameter is set to 0. If this call returns anything other than 2, the "An error has occurred" message will be shown. If the drive error is anything other than 0x0053100 (OK/Invalid Request Medium Format Corrupted) or 0x0052000 (OK/Invalid command operation code), the "Error #001" message will be shown.
Nintendo titles send this after performing the off-disc DVDLowUnencryptedRead check to verify that they are on official hardware; specifically, the first parameter is set to 4 (internally, 0x40000 >> 16) and the second parameter is set to 0. If this call returns anything other than 2, the "An error has occurred" message will be shown. If the drive error is anything other than 0x0053100 (OK/Invalid Request Medium Format Corrupted) or 0x0052000 (OK/Invalid command operation code), the "Error #001" message will be shown.
−
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xA4000000 | (param1 << 16) // A4XX0000
DICMDBUF0 = 0xA4000000 | (param1 << 16) // A4XX0000
Line 1,147:
Line 1,145:
Probably related to DVD-Video{{check}}.
Probably related to DVD-Video{{check}}.
−
The output buffer size must be ≥ 0x800 * length, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x800 * length, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xD0000000 | ((flag1 & 1) << 7) | ((flag2 & 1) << 6) // D00000C0, D0000080, D0000040, D0000000
DICMDBUF0 = 0xD0000000 | ((flag1 & 1) << 7) | ((flag2 & 1) << 6) // D00000C0, D0000080, D0000040, D0000000
Line 1,270:
Line 1,268:
Reads the first 0x40 bytes of the [https://en.wikipedia.org/wiki/Burst_cutting_area burst cutting area]. Note that [https://debugmo.de/2008/11/anatomy-of-an-optical-medium-authentication/ the actual BCA is 188 (0xBC) bytes long] (at least for some games){{check}}.
Reads the first 0x40 bytes of the [https://en.wikipedia.org/wiki/Burst_cutting_area burst cutting area]. Note that [https://debugmo.de/2008/11/anatomy-of-an-optical-medium-authentication/ the actual BCA is 188 (0xBC) bytes long] (at least for some games){{check}}.
−
The output buffer size must be ≥ 0x40, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x40, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xDA000000
DICMDBUF0 = 0xDA000000
Line 1,354:
Line 1,352:
Unknown{{check}}.
Unknown{{check}}.
−
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written. Last_DILENGTH is reset to 0 after completion. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
+
The output buffer size must be ≥ 0x20, or DIMAR and DILENGTH will not be written. The output buffer also needs to be 32-byte aligned, or else the driver will hang.
DICMDBUF0 = 0xDF000000 | ((flag1 & 1) << 17) | ((flag2 & 1) << 16) // DF030000, DF010000, DF020000, DF000000
DICMDBUF0 = 0xDF000000 | ((flag1 & 1) << 17) | ((flag2 & 1) << 16) // DF030000, DF010000, DF020000, DF000000