https://www.3dbrew.org/w/api.php?action=feedcontributions&user=Lectem&feedformat=atom
3dbrew - User contributions [en]
2024-03-28T10:37:20Z
User contributions
MediaWiki 1.35.8
https://www.3dbrew.org/w/index.php?title=KSession&diff=18443
KSession
2016-10-20T23:15:21Z
<p>Lectem: </p>
<hr />
<div>[[Category:Kernel objects]]<br />
class [[KSession]] extends [[KAutoObject]];<br />
<br />
Size : 0x4C bytes<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Type<br />
! Description<br />
|-<br />
| 0x0<br />
| u32<br />
| Pointer to vtable<br />
|-<br />
| 0x4<br />
| u32<br />
| Reference count<br />
|-<br />
| 0x20<br />
| [[KThread]]*<br />
| X ?<br />
|-<br />
| 0x24<br />
| [[KThread]]*<br />
| Y ?<br />
|-<br />
| 0x2C<br />
| [[KThread]]*<br />
| Z ?<br />
|}<br />
It seems X=Y=Z. X, Y and Z can be NULL.<br />
<br />
<br />
Structure for [[7.0.0-13]] NATIVE_FIRM upward:<br />
<br />
Size : 0x4C bytes ([[KAutoObject]], [[KServerSession]], [[KClientSession]], sequentially):<br />
<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
!colspan="2"|Type<br />
! Description<br />
|-<br />
| 0x0<br />
|rowspan="2"|[[KAutoObject]]<br />
| u32<br />
| Pointer to vtable<br />
|-<br />
| 0x4<br />
| u32<br />
| Reference count<br />
|-<br />
| 0x8<br />
|rowspan="9"|[[KServerSession]]<br />
| u32<br />
| Pointer to vtable<br />
|-<br />
| 0xC<br />
| u32<br />
| Reference count<br />
|-<br />
| 0x10<br />
| u32<br />
| Node count for threads<br />
|-<br />
| 0x14<br />
| [[KLinkedListNode]]*<br />
| Pointer to first KLinkedListNode in the list of threads that sync with this object<br />
|-<br />
| 0x18<br />
| [[KLinkedListNode]]*<br />
| Pointer to last KLinkedListNode in the list of threads that sync with this object<br />
|-<br />
| 0x1C<br />
| KSession* <br />
| Pointer to parent session<br />
|-<br />
| 0x20<br />
| [[KThread]]* <br />
| Last stolen KThread during sync request- current thread when KServerSession code is running during svc - noted in KThread+0xA8 as well<br />
|-<br />
| 0x24<br />
| [[KThread]]*<br />
| First stolen KThread during sync request<br />
|-<br />
| 0x28<br />
| [[KThread]]*<br />
| KThread that originated the session<br />
|-<br />
| 0x2C<br />
|rowspan="8"|[[KClientSession]]<br />
| u32<br />
| Pointer to vtable<br />
|-<br />
| 0x30<br />
| u32<br />
| Reference count<br />
|-<br />
| 0x34<br />
| u32 <br />
| KLinkedListNode count for object<br />
|-<br />
| 0x38<br />
| KLinkedListNode*<br />
| Pointer to first KLinkedListNode in list of KThreads using this client session<br />
|-<br />
| 0x3C<br />
| KLinkedListNode*<br />
| Pointer to last KLinkedListNode in list of KThreads using this client session<br />
|-<br />
| 0x40<br />
| KSession* <br />
| Pointer to parent session<br />
|-<br />
| 0x44<br />
| u32 <br />
| Session status<br />
|-<br />
| 0x48<br />
| KClientPort* <br />
| Pointer to associated client port inside parent KPort<br />
|-<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=SRV:EnableNotification&diff=17856
SRV:EnableNotification
2016-07-30T16:55:14Z
<p>Lectem: /* Response */</p>
<hr />
<div>=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00020000]<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| {{IPC/TranslationDescriptor|Copy handle 0x0}}<br />
|-<br />
| 3<br />
| Handle to semaphore signaled on process notification<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=CAMU:GetBufferErrorInterruptEvent&diff=17854
CAMU:GetBufferErrorInterruptEvent
2016-07-30T15:53:26Z
<p>Lectem: /* Response */</p>
<hr />
<div>=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00060040]<br />
|-<br />
| 1<br />
| [[Camera_Services#Port|Port]]<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| Copy handle descriptor (0x0) <br />
|-<br />
| 3<br />
| Event Handle<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=CAMU:GetVsyncInterruptEvent&diff=17853
CAMU:GetVsyncInterruptEvent
2016-07-30T15:38:50Z
<p>Lectem: /* Response */</p>
<hr />
<div>=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00050040]<br />
|-<br />
| 1<br />
| [[Camera_Services#Port|Port]]<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| Copy handle descriptor (0x0)<br />
|-<br />
| 3<br />
| Event Handle<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=CAMU:SetReceiving&diff=17852
CAMU:SetReceiving
2016-07-30T15:38:30Z
<p>Lectem: /* Response */</p>
<hr />
<div>=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00070102]<br />
|-<br />
| 1<br />
| Destination Pointer<br />
|-<br />
| 2<br />
| [[Camera_Services#Port|Port]]<br />
|-<br />
| 3<br />
| Image Size<br />
|-<br />
| 4<br />
| s16, Transfer Unit<br />
|-<br />
| 5<br />
| 0x0<br />
|-<br />
| 6<br />
| Destination Process Handle (usually 0xFFFF8001)<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| Copy handle descriptor (0x0)<br />
|-<br />
| 3<br />
| Receive Event Handle<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=FS:OpenFile&diff=17851
FS:OpenFile
2016-07-30T14:44:46Z
<p>Lectem: /* Response */</p>
<hr />
<div>=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x080201C2]<br />
|-<br />
| 1<br />
| Transaction (usually 0)<br />
|-<br />
| 2-3<br />
| u64, Archive Handle<br />
|-<br />
| 4<br />
| [[Filesystem_services#PathType|Path Type]]<br />
|-<br />
| 5<br />
| Path Size<br />
|-<br />
| 6<br />
| [[Filesystem_services#OpenFlags|Open Flags]]<br />
|-<br />
| 7<br />
| [[Filesystem_services#Attributes|Attributes]] (usually 0)<br />
|-<br />
| 8<br />
| (PathSize << 14) <nowiki>|</nowiki> 2<br />
|-<br />
| 9<br />
| Path Data Pointer<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| Move handle descriptor (0x10)<br />
|-<br />
| 3<br />
| File client session handle<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15485
Socket Services
2016-01-20T03:01:57Z
<p>Lectem: /* Socket user service "soc:U" */</p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]]<br />
|-<br />
| 0x00100102<br />
| [[SOCU:getnameinfo|getnameinfo]]<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 5-7<br />
| getaddrinfo<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}<br />
<br />
=IPV6=<br />
<br />
It seems that Nintendo planned ahead and included IPv6 support to some extent in their code.<br />
Name resolution functions support IPv6 (such as [[SOCU:getnameinfo|getnameinfo]]), but [[SOCU:socket|socket]] doesn't.<br />
<br />
The ipv6 sockaddr size is 0x1C and is required for some IPC commands, even when using sockaddr_in which in reality is of size 8.<br />
The sockaddr_in6 struct is the following:<br />
<br />
struct in6_addr<br />
{<br />
uint8_t s6_addr[16];<br />
};<br />
<br />
struct sockaddr_in6<br />
{<br />
sa_family_t sin6_family;<br />
in_port_t sin6_port;<br />
struct in6_addr sin6_addr;<br />
u32 sin6_flowinfo; // Not confirmed<br />
u32 sin6_scope_id; // Not confirmed<br />
};</div>
Lectem
https://www.3dbrew.org/w/index.php?title=SOCU:getaddrinfo&diff=15307
SOCU:getaddrinfo
2016-01-17T19:48:06Z
<p>Lectem: Created page with " int socu_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res, addrinfo_3ds_t *info, s32 info_count, s32 * count) This fun..."</p>
<hr />
<div> int socu_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res, addrinfo_3ds_t *info, s32 info_count, s32 * count)<br />
<br />
This function will store each result entry in the form of the following structure :<br />
<br />
struct addrinfo_3ds_t<br />
{<br />
s32 ai_flags;<br />
s32 ai_family;<br />
s32 ai_socktype;<br />
s32 ai_protocol;<br />
u32 ai_addrlen;<br />
char ai_canonname[256];<br />
struct sockaddr_storage ai_addr;<br />
};<br />
<br />
Its size is 0x130.<br />
<br />
Note that the command will simply fill whatever it can, but never issue any error if there isn't enough memory provided to store those entries. However, the count of entries will always hold the correct value, that way you can reallocate memory and call the function again.<br />
<br />
=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00F0106]<br />
|-<br />
| 1<br />
| 0 if node is NULL, strlen(node)+1 otherwise<br />
|-<br />
| 2<br />
| 0 if service is NULL, strlen(service)+1 otherwise<br />
|-<br />
| 3<br />
| 0 if hints is NULL, sizeof(struct addrinfo) otherwise<br />
|-<br />
| 4<br />
| sizeof(addrinfo_3ds_t) * info_count<br />
|-<br />
| 5<br />
| (value used for word 1) <<14 <nowiki>|</nowiki> 8 << 10 <nowiki>|</nowiki> 2 // IPC_Desc_StaticBuffer(cmdbuf[1], 5)<br />
|-<br />
| 6<br />
| node<br />
|-<br />
| 7<br />
| (value used for word 2) <<14 <nowiki>|</nowiki> 8 << 10 <nowiki>|</nowiki> 2 // IPC_Desc_StaticBuffer(cmdbuf[2], 6)<br />
|-<br />
| 8<br />
| service<br />
|-<br />
| 9<br />
| (value used for word 3) <<14 <nowiki>|</nowiki> 8 << 10 <nowiki>|</nowiki> 2 // IPC_Desc_StaticBuffer(cmdbuf[3], 4)<br />
|-<br />
| 10<br />
| hints<br />
|}<br />
<br />
==Thread Static Buffers==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| (sizeof(addrinfo_3ds_t) * info_count) <<14 // IPC_Desc_StaticBuffer(sizeof(addrinfo_3ds_t) * info_count, 0)<br />
|-<br />
| 1<br />
| info<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| POSIX return value<br />
|-<br />
| 3<br />
| count (number of entries available)<br />
|}<br />
<br />
=Known error codes=<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error name<br />
! Value<br />
|-<br />
| EAI_FAMILY<br />
| -303<br />
|-<br />
| EAI_MEMORY<br />
| -304<br />
|-<br />
| EAI_NONAME<br />
| -305<br />
|-<br />
| EAI_SOCKTYPE<br />
| -307<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15306
Socket Services
2016-01-17T16:50:49Z
<p>Lectem: /* Socket module static buffers */</p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]] ? This resolves the IP address(es) for the specified host-name.<br />
|-<br />
| 0x00100102<br />
| [[SOCU:getnameinfo|getnameinfo]]<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 5-7<br />
| getaddrinfo<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}<br />
<br />
=IPV6=<br />
<br />
It seems that Nintendo planned ahead and included IPv6 support to some extent in their code.<br />
Name resolution functions support IPv6 (such as [[SOCU:getnameinfo|getnameinfo]]), but [[SOCU:socket|socket]] doesn't.<br />
<br />
The ipv6 sockaddr size is 0x1C and is required for some IPC commands, even when using sockaddr_in which in reality is of size 8.<br />
The sockaddr_in6 struct is the following:<br />
<br />
struct in6_addr<br />
{<br />
uint8_t s6_addr[16];<br />
};<br />
<br />
struct sockaddr_in6<br />
{<br />
sa_family_t sin6_family;<br />
in_port_t sin6_port;<br />
struct in6_addr sin6_addr;<br />
u32 sin6_flowinfo; // Not confirmed<br />
u32 sin6_scope_id; // Not confirmed<br />
};</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15280
Socket Services
2016-01-13T00:27:41Z
<p>Lectem: getnameinfo is now described in its own page</p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]] ? This resolves the IP address(es) for the specified host-name.<br />
|-<br />
| 0x00100102<br />
| [[SOCU:getnameinfo|getnameinfo]]<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}<br />
<br />
<br />
=IPV6=<br />
<br />
It seems that Nintendo planned ahead and included IPv6 support to some extent in their code.<br />
Name resolution functions support IPv6 (such as [[SOCU:getnameinfo|getnameinfo]]), but [[SOCU:socket|socket]] doesn't.<br />
<br />
The ipv6 sockaddr size is 0x1C and is required for some IPC commands, even when using sockaddr_in which in reality is of size 8.<br />
The sockaddr_in6 struct is the following:<br />
<br />
struct in6_addr<br />
{<br />
uint8_t s6_addr[16];<br />
};<br />
<br />
struct sockaddr_in6<br />
{<br />
sa_family_t sin6_family;<br />
in_port_t sin6_port;<br />
struct in6_addr sin6_addr;<br />
u32 sin6_flowinfo; // Not confirmed<br />
u32 sin6_scope_id; // Not confirmed<br />
};</div>
Lectem
https://www.3dbrew.org/w/index.php?title=SOCU:getnameinfo&diff=15279
SOCU:getnameinfo
2016-01-13T00:25:51Z
<p>Lectem: Created page with " int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) =Request= {| class="wikitable" border="1..."</p>
<hr />
<div> int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)<br />
<br />
=Request=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code [0x00100102]<br />
|-<br />
| 1<br />
| value 0x1C // size of sockaddr_in6<br />
|-<br />
| 2<br />
| socklen_t hostlen<br />
|-<br />
| 3<br />
| socklen_t servlen<br />
|-<br />
| 4<br />
| int flags<br />
|-<br />
| 5<br />
| 0x1C <<14 <nowiki>|</nowiki> 8 << 10 <nowiki>|</nowiki> 2 // IPC_Desc_StaticBuffer(0x1C,8);<br />
|-<br />
| 6<br />
| const struct sockaddr *sa<br />
|}<br />
<br />
==Thread Static Buffers==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| hostlen<<14 // IPC_Desc_StaticBuffer(hostlen,0);<br />
|-<br />
| 1<br />
| host<br />
|-<br />
| 2<br />
| servlen<<14 // IPC_Desc_StaticBuffer(servlen,0);<br />
|-<br />
| 3<br />
| serv<br />
|}<br />
<br />
=Response=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Header code<br />
|-<br />
| 1<br />
| Result code<br />
|-<br />
| 2<br />
| POSIX return value<br />
|}<br />
<br />
Notes : some of the 0x1C values could possibly be replaced by salen, but the module seems to accept only 0x1C.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15278
Socket Services
2016-01-13T00:10:01Z
<p>Lectem: </p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]] ? This resolves the IP address(es) for the specified host-name.<br />
|-<br />
| 0x00100102<br />
| [[SOCU:getnameinfo|getnameinfo]] ? The arguments match but couldn't get it to work yet.<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}<br />
<br />
<br />
=IPV6=<br />
<br />
It seems that Nintendo planned ahead and included IPv6 support to some extent in their code.<br />
Name resolution functions support IPv6 (such as [[SOCU:getnameinfo|getnameinfo]]), but [[SOCU:socket|socket]] doesn't.<br />
<br />
The ipv6 sockaddr size is 0x1C and is required for some IPC commands, even when using sockaddr_in which in reality is of size 8.<br />
The sockaddr_in6 struct is the following:<br />
<br />
struct in6_addr<br />
{<br />
uint8_t s6_addr[16];<br />
};<br />
<br />
struct sockaddr_in6<br />
{<br />
sa_family_t sin6_family;<br />
in_port_t sin6_port;<br />
struct in6_addr sin6_addr;<br />
u32 sin6_flowinfo; // Not confirmed<br />
u32 sin6_scope_id; // Not confirmed<br />
};</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15277
Socket Services
2016-01-12T18:09:57Z
<p>Lectem: fixed getnameinfo header</p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]] ? This resolves the IP address(es) for the specified host-name.<br />
|-<br />
| 0x00100102<br />
| [[SOCU:getnameinfo|getnameinfo]] ? The arguments match but couldn't get it to work yet.<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Socket_Services&diff=15276
Socket Services
2016-01-12T17:35:30Z
<p>Lectem: added static buffers usage and getaddrinfo/getnameinfo command headers</p>
<hr />
<div>[[Category:Services]]<br />
= Socket user service "soc:U" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010044<br />
| [[SOCU:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x000200C2<br />
| [[SOCU:socket|socket]]<br />
|-<br />
| 0x00030082<br />
| [[SOCU:listen|listen]]<br />
|-<br />
| 0x00040082<br />
| [[SOCU:accept|accept]]<br />
|-<br />
| 0x00050084<br />
| [[SOCU:bind|bind]]<br />
|-<br />
| 0x00060084<br />
| [[SOCU:connect|connect]]<br />
|-<br />
| 0x00070104<br />
| [[SOCU:recvfrom_other|recvfrom_other]]<br />
|-<br />
| 0x00080102<br />
| [[SOCU:recvfrom|recvfrom]]<br />
|-<br />
| 0x00090106<br />
| [[SOCU:sendto_other|sendto_other]]<br />
|-<br />
| 0x000A0106<br />
| [[SOCU:sendto|sendto]]<br />
|-<br />
| 0x000B0042<br />
| [[SOCU:close|close]]<br />
|-<br />
| 0x000C0082<br />
| [[SOCU:shutdown|shutdown]]<br />
|-<br />
| 0x000D0082<br />
| [[SOCU:gethostbyname|gethostbyname]]<br />
|-<br />
| 0x000E00C2<br />
| [[SOCU:gethostbyaddr|gethostbyaddr]]<br />
|-<br />
| 0x000F0106<br />
| [[SOCU:getaddrinfo|getaddrinfo]] ? This resolves the IP address(es) for the specified host-name.<br />
|-<br />
| 0x00120104<br />
| [[SOCU:getnameinfo|getnameinfo]] ? The arguments match but couldn't get it to work yet.<br />
|-<br />
| 0x00110102<br />
| [[SOCU:getsockopt|getsockopt]]<br />
|-<br />
| 0x00120104<br />
| [[SOCU:setsockopt|setsockopt]]<br />
|-<br />
| 0x001300C2<br />
| [[SOCU:fcntl|fcntl]]<br />
|-<br />
| 0x00140084<br />
| [[SOCU:poll|poll]]<br />
|-<br />
| 0x00150042<br />
| [[SOCU:sockatmark|sockatmark]]<br />
|-<br />
| 0x00160000<br />
| [[SOCU:gethostid|gethostid]]<br />
|-<br />
| 0x00170082<br />
| [[SOCU:getsockname|getsockname]]<br />
|-<br />
| 0x00180082<br />
| [[SOCU:getpeername|getpeername]]<br />
|-<br />
| 0x00190000<br />
| [[SOCU:ShutdownSockets|ShutdownSockets]]<br />
|-<br />
| 0x001A00C0<br />
| [[SOCU:GetNetworkOpt|GetNetworkOpt]]<br />
|-<br />
| 0x001B0040<br />
| [[SOCU:ICMPSocket|ICMPSocket]]<br />
|-<br />
| 0x001C0104<br />
| [[SOCU:ICMPPing|ICMPPing]]<br />
|-<br />
| 0x001D0040<br />
| [[SOCU:ICMPCancel|ICMPCancel]]<br />
|-<br />
| 0x001E0040<br />
| [[SOCU:ICMPClose|ICMPClose]]<br />
|-<br />
| 0x001F0040<br />
| [[SOCU:GetResolverInfo|GetResolverInfo]]<br />
|-<br />
| 0x00210002<br />
| [[SOCU:CloseSockets|CloseSockets]]<br />
|-<br />
| 0x100100C0<br />
| ?<br />
|-<br />
| 0x10030142<br />
| ?<br />
|-<br />
| 0x10050084<br />
| ?<br />
|-<br />
| 0x10070102<br />
| ?<br />
|-<br />
|}<br />
<br />
= Socket privileged service "soc:P" =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Command Header<br />
! Description<br />
|-<br />
| 0x00010084<br />
| [[SOCP:InitializeSockets|InitializeSockets]]<br />
|-<br />
| 0x00020000<br />
| [[SOCP:FinalizeSockets|FinalizeSockets]]<br />
|-<br />
| 0x000300C2<br />
| [[SOCP:SetNetworkOpt|SetNetworkOpt]]<br />
|-<br />
| 0x00040040<br />
| [[SOCP:CloseSocketsForProcess|CloseSocketsForProcess]]<br />
|-<br />
| 0x000500C0<br />
| <br />
|-<br />
| 0x00060000<br />
| [[SOCP:gethostid|gethostid]]<br />
|-<br />
| 0x00070000<br />
| <br />
|-<br />
| 0x00080000<br />
| <br />
|-<br />
| 0x00090000<br />
| [[SOCP:StopInitializeSockets|StopInitializeSockets]]<br />
|}<br />
<br />
= struct sockaddr =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| Total size of the entire sockaddr buffer.<br />
|-<br />
| 0x1<br />
| 0x1<br />
| u8 sa_family<br />
|-<br />
| 0x2<br />
| sockaddr_totalsize-0x2<br />
| sa_data[]<br />
|}<br />
<br />
The total buffer size is 0x8, for family AF_INET value 2. AF_INET6 seems to be value 23, the total sockaddr size for this is 0x1C. The max sockaddr buffer size which the socket module can handle is size 0x1C.<br />
<br />
These socket services(and defines/structures) seem to be based on the Wii sockets?<br />
<br />
=Socket module errors=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Error<br />
! Description<br />
|-<br />
| 0xC8A0700B<br />
| [[SOCU:InitializeSockets]] returns this when the specified PID was already used with [[SOCU:InitializeSockets]](since the PID was found in SOC module state table).<br />
|-<br />
| 0xD860700A<br />
| [[SOCU:InitializeSockets]] returns this when the PID table is already full(32 processes max).<br />
|}<br />
<br />
=Socket module static buffers=<br />
<br />
This is the list of the known thread static buffers in use for SOC:u and the commands using those.<br />
{| class="wikitable" border="1"<br />
|-<br />
! buffer ID<br />
! commands<br />
|-<br />
| 0<br />
| bind,connect<br />
|-<br />
| 1<br />
| sendto_other,sendto<br />
|-<br />
| 2<br />
| sendto<br />
|-<br />
| 8<br />
| getnameinfo<br />
|-<br />
| 9<br />
| setsockopt<br />
|-<br />
| 10<br />
| poll<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Internet_Browser&diff=14339
Internet Browser
2015-10-27T03:48:13Z
<p>Lectem: </p>
<hr />
<div>The 3DS Internet Browser was added in the June 2011 Update for JPN/EUR/USA.<br />
<br />
From the Internet Browser help section:<br />
In compliance with the LGPL, the source code of the OSS is available via the Nintendo website.<br />
This source code can be downloaded here:<br />
[http://mediacontent.nintendo-europe.com/NOE/images/service/OpenSources.zip] [http://www.nintendo.co.jp/support/oss/index.html]<br />
<br />
The 3DS Internet Browser is [http://en.wikipedia.org/wiki/Netfront Netfront] Browser NX v1.0 based on [http://en.wikipedia.org/wiki/WebKit WebKit] engine.<br />
<br />
The browser supports up to 64 bookmarks.<br />
<br />
The exheader name of this title is "spider".<br />
<br />
The only difference between the ExeFS .code for each region of the Old3DS/New3DS browser, is byte values for the title uniqueID/region, otherwise the binaries are identical.<br />
<br />
'''Note that both spider and SKATER have started being included in some CUPs (cart updates) beginning with Tri Force Heroes and potentially earlier.'''<br />
<br />
==[[New 3DS]] Internet Browser==<br />
New3DS has a separate browser title, the exheader name is "SKATER".<br />
<br />
Unlike the Old3DS browser, this New3DS browser has videos+HTML5 support. This browser also has a filter enabled by default(ExeFS codebin is same for all regions, this filter only applies for JPN region). Disabling it requires paying money with a credit-card, for [[NIM_Services|purchasing]] web-browser [[Title_list/DLC|DLC]].<br />
<br />
During startup the browser does various HTTPS comms. When visting an URL, the browser sends a plaintext HTTP POST to here: [http://ars.ifuser.jp:20080/ars2/rating]. The raw POST data begins with "ARS/2.0\r\n\x00", the rest appears to be encrypted. The server reply content also has this ARS header + encrypted data. This appears to use a fixed xorpad, likely from a fixed encryption CTR/IV. The server content responses for allowed sites, and blocked sites, are fixed. When the server returns that the site is blocked, the browser goes to this page: [http://ars.ifuser.jp/filter/44.html](the Referrer header value is set to the same URL it's actually requesting).<br />
<br />
The WebKit source was updated since the Old3DS browser.<br />
<br />
Unlike the Old3DS browser, the New3DS browser uses the following services: [[MVD_Services|mvd:STD]] and [[IR_Services|ir:rst]](DLC-related services are used too but those aren't New3DS specific).<br />
<br />
Video decoding is done with [[MVD_Services|mvd:STD]]. Audio decoding/playback is done with a browser-specific DSP binary. The Old3DS browser used CSND for audio playback, the New3DS browser doesn't have access to that at all since it uses DSP instead.<br />
<br />
The browser manual includes licenses for Android and PacketVideo. The browser uses libstagefright from Android.<br />
<br />
===User-Agent and Browser Versions===<br />
Normal user-agent format: <code style="font-size:larger;">Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/<WebKit version> (KHTML, like Gecko) NX/<Netfront version> Mobile NintendoBrowser/<Mobile NintendoBrowser version>.<region></code><br />
<br />
<region> can be one of the following: "JP", "US", or "EU".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Mobile NintendoBrowser version(displayed in browser settings)<br />
! Normal UA<br />
! Mobile UA<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.0.9934<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.8 Mobile NintendoBrowser/1.0.9934.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v10<br />
| [[9.0.0-20]]<br />
| Initial version.<br />
|-<br />
| 1.1.9996<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.10 Mobile NintendoBrowser/1.1.9996.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v1027<br />
| [[9.3.0-21]]<br />
| See below regarding OSS changes.<br />
|-<br />
| 1.2.10085<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.13 Mobile NintendoBrowser/1.2.10085.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v2051<br />
| [[9.6.0-24]]<br />
| See below.<br />
|-<br />
| 1.3.10126<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.US<br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v3077<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| 1.4.10138<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.17 Mobile NintendoBrowser/1.4.10138.US<br />
| ?<br />
| v4096<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
Note that the latest Old3DS browser WebKit version at the time the initial New3DS browser was released, was the following: 532.8.<br />
<br />
==== OSS 9.0 and 9.3 diff ====<br />
The following is a diff of the OSS archives from [http://www.nintendo.co.jp/support/oss/index.html here], for v9.0 and v9.3.<br />
<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp and NewNintendo3DS_OpenSources9.3.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp differ<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebKit/WKC/webkit/WKCVersion.h and NewNintendo3DS_OpenSources9.3.0-/WKC/WebKit/WKC/webkit/WKCVersion.h differ<br />
<br />
WKC_CUSTOMER_RELEASE_VERSION was changed from "0.5.8" to "0.5.10".<br />
<br />
The following code was added to ResourceHandleManager::doRedirect(): curl_easy_setopt(d->m_handle, CURLOPT_SHARE, 0);<br />
<br />
==== v9.6 ====<br />
WebKit/OSS code was actually updated.<br />
ExeFS .code was updated. The following files in RomFS were updated:<br />
* "/banner/CN/Skater.icn" and "/banner/KR/Skater.icn".<br />
* "/browser/rootca.pem"<br />
* "/build/buildinfo.dat"<br />
* "/cairo.cro.lex" and "/.crr/static.crr"<br />
* "/lyt/Button/ButtonSelectHSearch.arc"<br />
* "/lyt/Kbd/Swkbd.arc"<br />
* "lyt/Kbd.arc"<br />
* "skater.msbt" under all of the "/message/<region>_<language>/" directories.<br />
* "/oss.cro.lex", "/peer.cro.lex", "/static.crs", and "/webkit.cro.lex".<br />
<br />
The following was added to RomFS:<br />
* "/favicon/naver.dat"<br />
* A "KO" directory under "/iwnn".<br />
<br />
==== v9.9 ====<br />
ExeFS:/.code was updated.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem<br />
/build/buildinfo.dat<br />
/cairo.cro.lex<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/skater.msbt<br />
/message/EU_Dutch/skater.msbt<br />
/message/EU_English/skater.msbt<br />
/message/EU_French/skater.msbt<br />
/message/EU_German/skater.msbt<br />
/message/EU_Italian/skater.msbt<br />
/message/EU_Portuguese/skater.msbt<br />
/message/EU_Russian/skater.msbt<br />
/message/EU_Spanish/skater.msbt<br />
/message/JP_Japanese/skater.msbt<br />
/message/KR_Hangeul/skater.msbt<br />
/message/TW_English/skater.msbt<br />
/message/TW_Trad_Chinese/skater.msbt<br />
/message/US_English/skater.msbt<br />
/message/US_French/skater.msbt<br />
/message/US_Portuguese/skater.msbt<br />
/message/US_Spanish/skater.msbt<br />
/oss.cro.lex<br />
/peer.cro.lex<br />
/static.crs<br />
/webkit.cro.lex<br />
<br />
See [https://gist.github.com/yellows8/9fb509fde4112339f342 here] for a diff of the OSS(WebKitLibraries/ is not included due to the massive cairo library diff). An exploitable security vuln(which was already known in the context of 3DS webkit) was fixed. [[User:Yellows8|Yellows8]]' private(at the time of writing) exploit for it is based on the PoC from [http://pastebin.com/ufBCQKda here](see the pastebin for the actual pastebin author).<br />
<br />
==== v10.2 ====<br />
The libstagefright build in the main SKATER codebin was updated to a version which fixed libstagefright vuln(s): the vuln used in [[browserhax|browserhax_fright]] at the time of sysupdate release was fixed. The *only* code changed in the main codebin, was code related to libstagefright.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem differ<br />
/build/buildinfo.dat differ<br />
/.crr/static.crr differ<br />
/message/CN_Simp_Chinese/skater.msbt differ<br />
/message/EU_Dutch/skater.msbt differ<br />
/message/EU_English/skater.msbt differ<br />
/message/EU_French/skater.msbt differ<br />
/message/EU_German/skater.msbt differ<br />
/message/EU_Italian/skater.msbt differ<br />
/message/EU_Portuguese/skater.msbt differ<br />
/message/EU_Russian/skater.msbt differ<br />
/message/EU_Spanish/skater.msbt differ<br />
/message/JP_Japanese/skater.msbt differ<br />
/message/KR_Hangeul/skater.msbt differ<br />
/message/TW_English/skater.msbt differ<br />
/message/TW_Trad_Chinese/skater.msbt differ<br />
/message/US_English/skater.msbt differ<br />
/message/US_French/skater.msbt differ<br />
/message/US_Portuguese/skater.msbt differ<br />
/message/US_Spanish/skater.msbt differ<br />
/oss.cro.lex differ<br />
/static.crs differ<br />
/webkit.cro.lex differ<br />
<br />
=== New3DS Browser Specifications ===<br />
[http://www.nintendo.co.jp/3ds/new/features/modal_net.html]<br />
<br />
English version(Google translate):<br />
* "Browser engine: NetFront® Browser NX v3.0"<br />
* "User agent: Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.*.*.* Mobile NintendoBrowser/1.0.****.JP<br />
** The *** is described version information.<br />
** When you use the "mobile version of the request" function, which is different from those described above string."<br />
* "Supported protocols: HTTP1.0/HTTP1.1/SSL3.0/TLS1.0/TLS1.1/TLS1.2"<br />
* "Web standard: HTML4.01 / HTML5 / XHTML1.1 / Fullscreen / Gamepad / SVG / WebSocket / Video Subtitle / WOFF / Web Messaging / Server-Sent / Web Storage of part / XMLHttpRequest / canvas / Video / DOM1-3 / ECMAScript / CSS1 / CSS2.1 / CSS3 part of"<br />
* "Image format: bmp / ​​gif / ico / jpeg / png / svg (There are, however, it is not possible to display some image.)"<br />
* "Image preview: mpo / jpeg (There are, however, it is not possible to display some image.)"<br />
* "Video format: MP4, M3U8 + TS (HTTPLiveStreaming) (However, there are some you can not play the video.)"<br />
* "Video codec: H.264 - MPEG-4 AVC Video (max 854x480 level 3.2, 3D compatible) (However, there are some you can not play the video.)"<br />
* "Audio codec: AAC - ISO / IEC 14496-3 MPEG-4AAC, MP3 <br /> (However, there are some you can not play the video.)"<br />
* "Of 3D video at the time of upload format: .mkv (However, in order to play the video, you must format is converted in the upload to the site. In addition, even if it is converted you might not be able to play.)"<br />
* "It does not correspond to the plug-ins such as plug-in Adobe Flash."<br />
* "Use the Active Rating System of filtering function: Digital Arts, Inc. provides. At the time of access to Web content, and implementing the decision of whether access is permitted based on the category information. Feature that can limit access to Web content that may be inappropriate for viewing by the determination result."<br />
* "I will request the display of the mobile version page of the web page you are viewing request function the mobile version. (However, if the web page does not correspond to the mobile version of the page does not change the display.)"<br />
<br />
MJPEG + .avi is also supported.<br />
<br />
<br />
== Old3DS browser ==<br />
<br />
<br />
=== User-Agent and Browser Versions ===<br />
User-agent format: <code style="font-size:larger;">Mozilla/5.0 (Nintendo 3DS; U; ; <lang>) Version/<version>.<region></code>.<br />
<br />
<lang> is "en", "fr", etc. <region> is "US", "EU", etc. See below for <version>.<br />
{| class="wikitable" border="1"<br />
|-<br />
! Browser version<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.7412<br />
| v6<br />
| [[2.0.0-2|2.0.0-2]]<br />
| This was the initial version.<br />
|-<br />
| 1.7455<br />
| v1024<br />
| [[2.1.0-4]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too.<br />
|-<br />
| 1.7498<br />
| v2050<br />
| [[4.0.0-7]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3075<br />
| [[5.0.0-11]]<br />
| ExeFS .code and icon were updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3088<br />
| [[7.0.0-13]]<br />
| The main NCCH wasn't updated at all(same TMD contentID/content-hash as the previous version), only the manual CFA for this title was updated.<br />
|-<br />
| 1.7567<br />
| v4096<br />
| [[7.1.0-16]]<br />
| The CXI .code was updated, some data in the RomFS was updated(none of the CROs such as webkit.cro were updated). The manual CFA was updated too.<br />
|-<br />
| 1.7585<br />
| v5121<br />
| [[9.5.0-23]]<br />
| The CXI .code was updated, and the manual CFA was updated. RomFS changes:<br />
* "/browser/rootca.pem" updated<br />
* "/cro/oss.cro" updated<br />
* "/cro/static.crs" updated<br />
* "/cro/webkit.cro" updated<br />
* "/.crr/static.crr" updated<br />
* "/layout/dialogheader/WirelessSwitchOff.arc" was removed<br />
* "/layout/favorite/favicondata/KOR.arc" updated<br />
<br />
A vuln used in a public(at the time of this sysupdate) webkit exploit for spider was fixed, which also fixed the removewinframe exploit from [https://github.com/yellows8/3ds_webkithax here].<br />
|-<br />
| 1.7610<br />
| v6149<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| 1.7616<br />
| v7168<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
=== Old3DS v9.9 ===<br />
ExeFS:/.code was updated.<br />
<br />
The only changes in RomFS were file-updating, the following files were updated:<br />
/browser/rootca.pem<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/spider.msbt<br />
/message/EU_Dutch/spider.msbt<br />
/message/EU_English/spider.msbt<br />
/message/EU_French/spider.msbt<br />
/message/EU_German/spider.msbt<br />
/message/EU_Italian/spider.msbt<br />
/message/EU_Portuguese/spider.msbt<br />
/message/EU_Russian/spider.msbt<br />
/message/EU_Spanish/spider.msbt<br />
/message/JP_Japanese/spider.msbt<br />
/message/KR_Hangeul/spider.msbt<br />
/message/TW_English/spider.msbt<br />
/message/TW_Trad_Chinese/spider.msbt<br />
/message/US_English/spider.msbt<br />
/message/US_French/spider.msbt<br />
/message/US_Portuguese/spider.msbt<br />
/message/US_Spanish/spider.msbt<br />
<br />
OSS diff for v9.5 and v9.9, without the .dox changes:<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
index be5ff09..55a7274 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
@@ -29,7 +29,7 @@<br />
#define WKC_VERSION_CHECK(major, minor, micro) \<br />
(((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO))<br />
<br />
-#define WKC_CUSTOMER_RELEASE_VERSION "1.8.14"<br />
+#define WKC_CUSTOMER_RELEASE_VERSION "1.8.16"<br />
<br />
#define WKC_WEBKIT_VERSION "532.7"<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
index da4127e..d03403e 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
@@ -305,23 +305,23 @@ int RenderBox::scrollHeight() const<br />
<br />
int RenderBox::scrollLeft() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
}<br />
<br />
int RenderBox::scrollTop() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
}<br />
<br />
void RenderBox::setScrollLeft(int newLeft)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToXOffset(newLeft);<br />
}<br />
<br />
void RenderBox::setScrollTop(int newTop)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToYOffset(newTop);<br />
}<br />
<br />
=== Old3DS v10.2 ===<br />
The slider vuln from [https://github.com/yellows8/3ds_webkithax here] was fixed in the Old3DS browser it seems.<br />
<br />
The main codebin .text only increased by 0x10-bytes.<br />
<br />
The only changes in RomFS was that the following files were updated:<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
<br />
== Forced system-update ==<br />
The Old3DS/New3DS Internet Browser updated with [[9.9.0-26]] now includes the following message string:<br />
In order to use the Internet <br />
browser, a system update <br />
is required.<br />
To perform a system update, <br />
select System Update from Other<br />
Settings in System Settings.<br />
<br />
This wasn't enforced(web-browser displaying the above message when the installed browser isn't the latest version) until October 26, 2015. In some cases this message isn't displayed(as in some systems never displayed the message yet), the cause is unknown. It's unknown how exactly this is handled.<br />
<br />
This message only triggers when attempting to load a web-page.<br />
<br />
The browser codebins starting with v9.9 now contain the following URL strings:<br />
* Old3DS: <nowiki>"https://cbvc.cdn.nintendo.net/CTR/1/<region>"</nowiki><br />
* New3DS: <nowiki>"https://cbvc.cdn.nintendo.net/SNAKE/1/<region>"</nowiki><br />
<br />
The <region> string is one of the following:<br />
* "JPN"<br />
* "USA"<br />
* "EUR"<br />
* "KOR"<br />
<br />
Starting with the browser from [[10.2.0-28]], the "1" in the above URLs were changed to "2".<br />
<br />
It is still possible to guard against this update by blocking the previous URLs using a proxy. <br />
It is not possible to remove the update message by entering the [[Recovery Mode]].<br />
<br />
==Web Standards==<br />
*HTML 4.01<br />
*HTML 5 (120/400 score on [http://www.html5test.com HTML5Test.com])<br />
*XHTML 1.1<br />
*CSS 1<br />
*CSS 2.1<br />
*CSS 3 (some functionality is unavailable)<br />
*DOM Levels 1-3<br />
*ECMAScript (partial support for ECMA-262 5th Edition)<br />
*XMLHttpRequest Level 2<br />
*Canvas Element (some functionality is unavailable)<br />
<br />
==Protocols==<br />
*HTTP 1.0<br />
*HTTP 1.1<br />
*SSLv3<br />
*TLS 1.0<br />
<br />
==Image Formats==<br />
*[[File_Formats|MPO]]<br />
*GIF<br />
*JPEG<br />
*PNG<br />
*BMP<br />
*ICO (some files cannot be displayed)<br />
<br />
==Plug-Ins==<br />
<br />
Plug-ins (such as Adobe Flash) are not supported.<br />
<br />
==Other details==<br />
<br />
*It scored 90/100 on [http://acid3.acidtests.org/ Acid3] test<br />
*Images from the Internet can be saved to the [[SD Filesystem|SD Card]] and viewed using the [[Nintendo 3DS Camera]] application.<br />
*Images saved to an [[SD Filesystem|SD Card]] or to the Nintendo 3DS system memory can be uploaded to blogs or other sites that allow the uploading of photos using :<br />
<input type="file" /><br />
* HTML5Test.com say that Drag and drop is supported but it's not (code on WebKit is ready, but it's not implemented on interface of browser)<br />
<br />
==Tips==<br />
<br />
=== Detect User Agent ===<br />
<br />
To detect if the user agent is Nintendo 3DS Browser :<br />
<br />
<script type="text/javascript"><br />
if (navigator.userAgent.indexOf('Nintendo 3DS') == -1) { //If the UserAgent is not "Nintendo 3DS"<br />
location.replace('http://www.3dbrew.org'); //Redirect to an other page<br />
}<br />
</script><br />
<br />
* You can check <em>navigator.platform=="Nintendo 3DS"</em> as well.<br />
<br />
=== Scrolling ===<br />
<br />
Scrolling can be altered by modifying <em>document.body.scrollTop</em> and <em>document.body.scrollLeft</em>. However, there are drawbacks related to working with these properties:<br />
<br />
* Both properties return 0 when accessed<br />
* Setting one property resets the other property's scroll position<br />
<br />
In order to set both at the same time (without either resetting to 0), use <em>window.scrollTo</em>.<br />
<br />
=== Events ===<br />
==== Key Events ====<br />
The following buttons trigger the <em>onkeydown</em>, <em>onkeypress</em> and <em>onkeyup</em> events:<br />
<br />
{|class="wikitable" width="20%"<br />
! Code !! Button <br />
|-<br />
| 13 || A<br />
|-<br />
| 37 || Left<br />
|-<br />
| 38 || Up<br />
|-<br />
| 39 || Right<br />
|-<br />
| 40 || Down<br />
|}<br />
<br />
The events cannot have their default action cancelled. Other buttons do not trigger key events.<br />
<br />
==== Touch/Mouse Events ====<br />
<em>onmousedown</em>, <em>onmouseup</em> & <em>onclick</em> are all triggered by the browser. However, the <em>onmousedown</em> event doesn't trigger until you lift the stylus or you've held it on the screen for ~2 seconds—which is when text selection mode is activated—making it pretty much the same as <em>onmouseup</em>. The events cannot have their default action cancelled.<br />
<br />
The <em>onmousemove</em> and common touch/gesture events are not supported.<br />
<br />
== Screen Resolution ==<br />
<br />
The up screen resolution is 400×240. However, the viewable area in the browser is only <b>400×220</b>.<br />
<br />
The touch screen resolution is 320×240. However, the viewable area in the browser is only <b>320×212</b>.<br />
<br />
You can have a page span both screens. However, the browser will behave as if the bottom screen is the only active screen and the top screen is scrolled off. This is important when computing CSS coordinates. Items positioned from "bottom" will be positioned based on 220px and not the full 432px of both screens.<br />
<br />
== Using Both Screens ==<br />
<br />
Generally the easiest way to accomplish the correct layout is to create HTML elements that "contain" the top and bottom screens. Here's an example:<br />
<br />
<!DOCTYPE html><br />
<html><br />
<head><br />
<meta name="viewport" content="width=400"><br />
<style><br />
body{margin:0px;}<br />
#topscreen{width:400px;height:220px;overflow:hidden;}<br />
#bottomscreen{width:320px;height:212px;overflow:hidden;margin:0 auto;}<br />
</style><br />
</head><br />
<body><br />
&lt;div id="topscreen">Top Screen&lt;/div><br />
&lt;div id="bottomscreen">Bottom Screen&lt;/div><br />
</body><br />
</html><br />
<br />
This scheme allows the page to be easily manipulated through JavaScript. In order to have the window snap to the correct position, use the following JavaScript code:<br />
<br />
window.setInterval(function () {<br />
window.scrollTo(40, 220); <br />
}, 50);<br />
<br />
This automatically resets the position if the user accidentally scrolls the page.<br />
<br />
==Example Sites==<br />
<!-- If you have a website that demonstrates these techniques, place it here! --><br />
* [http://geekshadow.com/gaming/dev/weaponscolors/3DS/ Weapons and Colors] (Short URL: http://bit.ly/3DSwc)<br />
* [http://3ds.andysmith.co.uk/jFox.html jFox] (Short URL: http://bit.ly/iB7FqW)<br />
* [http://ditto3d.com/3ds Ditto3D] (Short URL: http://bit.ly/oVreWA)<br />
* [http://www.nintendo.com/3ds/internetbrowser/bookmarks Nintendo 3DS Bookmarks] - This is the first bookmark pre-installed in the browser.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Internet_Browser&diff=14337
Internet Browser
2015-10-27T03:43:47Z
<p>Lectem: </p>
<hr />
<div>The 3DS Internet Browser was added in the June 2011 Update for JPN/EUR/USA.<br />
<br />
From the Internet Browser help section:<br />
In compliance with the LGPL, the source code of the OSS is available via the Nintendo website.<br />
This source code can be downloaded here:<br />
[http://mediacontent.nintendo-europe.com/NOE/images/service/OpenSources.zip] [http://www.nintendo.co.jp/support/oss/index.html]<br />
<br />
The 3DS Internet Browser is [http://en.wikipedia.org/wiki/Netfront Netfront] Browser NX v1.0 based on [http://en.wikipedia.org/wiki/WebKit WebKit] engine.<br />
<br />
The browser supports up to 64 bookmarks.<br />
<br />
The exheader name of this title is "spider".<br />
<br />
The only difference between the ExeFS .code for each region of the Old3DS/New3DS browser, is byte values for the title uniqueID/region, otherwise the binaries are identical.<br />
<br />
'''Note that both spider and SKATER have started being included in some CUPs (cart updates) beginning with Tri Force Heroes and potentially earlier.'''<br />
<br />
==[[New 3DS]] Internet Browser==<br />
New3DS has a separate browser title, the exheader name is "SKATER".<br />
<br />
Unlike the Old3DS browser, this New3DS browser has videos+HTML5 support. This browser also has a filter enabled by default(ExeFS codebin is same for all regions, this filter only applies for JPN region). Disabling it requires paying money with a credit-card, for [[NIM_Services|purchasing]] web-browser [[Title_list/DLC|DLC]].<br />
<br />
During startup the browser does various HTTPS comms. When visting an URL, the browser sends a plaintext HTTP POST to here: [http://ars.ifuser.jp:20080/ars2/rating]. The raw POST data begins with "ARS/2.0\r\n\x00", the rest appears to be encrypted. The server reply content also has this ARS header + encrypted data. This appears to use a fixed xorpad, likely from a fixed encryption CTR/IV. The server content responses for allowed sites, and blocked sites, are fixed. When the server returns that the site is blocked, the browser goes to this page: [http://ars.ifuser.jp/filter/44.html](the Referrer header value is set to the same URL it's actually requesting).<br />
<br />
The WebKit source was updated since the Old3DS browser.<br />
<br />
Unlike the Old3DS browser, the New3DS browser uses the following services: [[MVD_Services|mvd:STD]] and [[IR_Services|ir:rst]](DLC-related services are used too but those aren't New3DS specific).<br />
<br />
Video decoding is done with [[MVD_Services|mvd:STD]]. Audio decoding/playback is done with a browser-specific DSP binary. The Old3DS browser used CSND for audio playback, the New3DS browser doesn't have access to that at all since it uses DSP instead.<br />
<br />
The browser manual includes licenses for Android and PacketVideo. The browser uses libstagefright from Android.<br />
<br />
===User-Agent and Browser Versions===<br />
Normal user-agent format: <code style="font-size:larger;">Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/<WebKit version> (KHTML, like Gecko) NX/<Netfront version> Mobile NintendoBrowser/<Mobile NintendoBrowser version>.<region></code><br />
<br />
<region> can be one of the following: "JP", "US", or "EU".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Mobile NintendoBrowser version(displayed in browser settings)<br />
! Normal UA<br />
! Mobile UA<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.0.9934<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.8 Mobile NintendoBrowser/1.0.9934.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v10<br />
| [[9.0.0-20]]<br />
| Initial version.<br />
|-<br />
| 1.1.9996<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.10 Mobile NintendoBrowser/1.1.9996.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v1027<br />
| [[9.3.0-21]]<br />
| See below regarding OSS changes.<br />
|-<br />
| 1.2.10085<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.13 Mobile NintendoBrowser/1.2.10085.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v2051<br />
| [[9.6.0-24]]<br />
| See below.<br />
|-<br />
| 1.3.10126<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.US<br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v3077<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| 1.4.10138<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.17 Mobile NintendoBrowser/1.4.10138.US<br />
| ?<br />
| v4096<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
Note that the latest Old3DS browser WebKit version at the time the initial New3DS browser was released, was the following: 532.8.<br />
<br />
==== OSS 9.0 and 9.3 diff ====<br />
The following is a diff of the OSS archives from [http://www.nintendo.co.jp/support/oss/index.html here], for v9.0 and v9.3.<br />
<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp and NewNintendo3DS_OpenSources9.3.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp differ<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebKit/WKC/webkit/WKCVersion.h and NewNintendo3DS_OpenSources9.3.0-/WKC/WebKit/WKC/webkit/WKCVersion.h differ<br />
<br />
WKC_CUSTOMER_RELEASE_VERSION was changed from "0.5.8" to "0.5.10".<br />
<br />
The following code was added to ResourceHandleManager::doRedirect(): curl_easy_setopt(d->m_handle, CURLOPT_SHARE, 0);<br />
<br />
==== v9.6 ====<br />
WebKit/OSS code was actually updated.<br />
ExeFS .code was updated. The following files in RomFS were updated:<br />
* "/banner/CN/Skater.icn" and "/banner/KR/Skater.icn".<br />
* "/browser/rootca.pem"<br />
* "/build/buildinfo.dat"<br />
* "/cairo.cro.lex" and "/.crr/static.crr"<br />
* "/lyt/Button/ButtonSelectHSearch.arc"<br />
* "/lyt/Kbd/Swkbd.arc"<br />
* "lyt/Kbd.arc"<br />
* "skater.msbt" under all of the "/message/<region>_<language>/" directories.<br />
* "/oss.cro.lex", "/peer.cro.lex", "/static.crs", and "/webkit.cro.lex".<br />
<br />
The following was added to RomFS:<br />
* "/favicon/naver.dat"<br />
* A "KO" directory under "/iwnn".<br />
<br />
==== v9.9 ====<br />
ExeFS:/.code was updated.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem<br />
/build/buildinfo.dat<br />
/cairo.cro.lex<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/skater.msbt<br />
/message/EU_Dutch/skater.msbt<br />
/message/EU_English/skater.msbt<br />
/message/EU_French/skater.msbt<br />
/message/EU_German/skater.msbt<br />
/message/EU_Italian/skater.msbt<br />
/message/EU_Portuguese/skater.msbt<br />
/message/EU_Russian/skater.msbt<br />
/message/EU_Spanish/skater.msbt<br />
/message/JP_Japanese/skater.msbt<br />
/message/KR_Hangeul/skater.msbt<br />
/message/TW_English/skater.msbt<br />
/message/TW_Trad_Chinese/skater.msbt<br />
/message/US_English/skater.msbt<br />
/message/US_French/skater.msbt<br />
/message/US_Portuguese/skater.msbt<br />
/message/US_Spanish/skater.msbt<br />
/oss.cro.lex<br />
/peer.cro.lex<br />
/static.crs<br />
/webkit.cro.lex<br />
<br />
See [https://gist.github.com/yellows8/9fb509fde4112339f342 here] for a diff of the OSS(WebKitLibraries/ is not included due to the massive cairo library diff). An exploitable security vuln(which was already known in the context of 3DS webkit) was fixed. [[User:Yellows8|Yellows8]]' private(at the time of writing) exploit for it is based on the PoC from [http://pastebin.com/ufBCQKda here](see the pastebin for the actual pastebin author).<br />
<br />
==== v10.2 ====<br />
The libstagefright build in the main SKATER codebin was updated to a version which fixed libstagefright vuln(s): the vuln used in [[browserhax|browserhax_fright]] at the time of sysupdate release was fixed. The *only* code changed in the main codebin, was code related to libstagefright.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem differ<br />
/build/buildinfo.dat differ<br />
/.crr/static.crr differ<br />
/message/CN_Simp_Chinese/skater.msbt differ<br />
/message/EU_Dutch/skater.msbt differ<br />
/message/EU_English/skater.msbt differ<br />
/message/EU_French/skater.msbt differ<br />
/message/EU_German/skater.msbt differ<br />
/message/EU_Italian/skater.msbt differ<br />
/message/EU_Portuguese/skater.msbt differ<br />
/message/EU_Russian/skater.msbt differ<br />
/message/EU_Spanish/skater.msbt differ<br />
/message/JP_Japanese/skater.msbt differ<br />
/message/KR_Hangeul/skater.msbt differ<br />
/message/TW_English/skater.msbt differ<br />
/message/TW_Trad_Chinese/skater.msbt differ<br />
/message/US_English/skater.msbt differ<br />
/message/US_French/skater.msbt differ<br />
/message/US_Portuguese/skater.msbt differ<br />
/message/US_Spanish/skater.msbt differ<br />
/oss.cro.lex differ<br />
/static.crs differ<br />
/webkit.cro.lex differ<br />
<br />
=== New3DS Browser Specifications ===<br />
[http://www.nintendo.co.jp/3ds/new/features/modal_net.html]<br />
<br />
English version(Google translate):<br />
* "Browser engine: NetFront® Browser NX v3.0"<br />
* "User agent: Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.*.*.* Mobile NintendoBrowser/1.0.****.JP<br />
** The *** is described version information.<br />
** When you use the "mobile version of the request" function, which is different from those described above string."<br />
* "Supported protocols: HTTP1.0/HTTP1.1/SSL3.0/TLS1.0/TLS1.1/TLS1.2"<br />
* "Web standard: HTML4.01 / HTML5 / XHTML1.1 / Fullscreen / Gamepad / SVG / WebSocket / Video Subtitle / WOFF / Web Messaging / Server-Sent / Web Storage of part / XMLHttpRequest / canvas / Video / DOM1-3 / ECMAScript / CSS1 / CSS2.1 / CSS3 part of"<br />
* "Image format: bmp / ​​gif / ico / jpeg / png / svg (There are, however, it is not possible to display some image.)"<br />
* "Image preview: mpo / jpeg (There are, however, it is not possible to display some image.)"<br />
* "Video format: MP4, M3U8 + TS (HTTPLiveStreaming) (However, there are some you can not play the video.)"<br />
* "Video codec: H.264 - MPEG-4 AVC Video (max 854x480 level 3.2, 3D compatible) (However, there are some you can not play the video.)"<br />
* "Audio codec: AAC - ISO / IEC 14496-3 MPEG-4AAC, MP3 <br /> (However, there are some you can not play the video.)"<br />
* "Of 3D video at the time of upload format: .mkv (However, in order to play the video, you must format is converted in the upload to the site. In addition, even if it is converted you might not be able to play.)"<br />
* "It does not correspond to the plug-ins such as plug-in Adobe Flash."<br />
* "Use the Active Rating System of filtering function: Digital Arts, Inc. provides. At the time of access to Web content, and implementing the decision of whether access is permitted based on the category information. Feature that can limit access to Web content that may be inappropriate for viewing by the determination result."<br />
* "I will request the display of the mobile version page of the web page you are viewing request function the mobile version. (However, if the web page does not correspond to the mobile version of the page does not change the display.)"<br />
<br />
MJPEG + .avi is also supported.<br />
<br />
<br />
== Old3DS browser ==<br />
<br />
<br />
=== User-Agent and Browser Versions ===<br />
User-agent format: <code style="font-size:larger;">Mozilla/5.0 (Nintendo 3DS; U; ; <lang>) Version/<version>.<region></code>.<br />
<br />
<lang> is "en", "fr", etc. <region> is "US", "EU", etc. See below for <version>.<br />
{| class="wikitable" border="1"<br />
|-<br />
! Browser version<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.7412<br />
| v6<br />
| [[2.0.0-2|2.0.0-2]]<br />
| This was the initial version.<br />
|-<br />
| 1.7455<br />
| v1024<br />
| [[2.1.0-4]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too.<br />
|-<br />
| 1.7498<br />
| v2050<br />
| [[4.0.0-7]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3075<br />
| [[5.0.0-11]]<br />
| ExeFS .code and icon were updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3088<br />
| [[7.0.0-13]]<br />
| The main NCCH wasn't updated at all(same TMD contentID/content-hash as the previous version), only the manual CFA for this title was updated.<br />
|-<br />
| 1.7567<br />
| v4096<br />
| [[7.1.0-16]]<br />
| The CXI .code was updated, some data in the RomFS was updated(none of the CROs such as webkit.cro were updated). The manual CFA was updated too.<br />
|-<br />
| 1.7585<br />
| v5121<br />
| [[9.5.0-23]]<br />
| The CXI .code was updated, and the manual CFA was updated. RomFS changes:<br />
* "/browser/rootca.pem" updated<br />
* "/cro/oss.cro" updated<br />
* "/cro/static.crs" updated<br />
* "/cro/webkit.cro" updated<br />
* "/.crr/static.crr" updated<br />
* "/layout/dialogheader/WirelessSwitchOff.arc" was removed<br />
* "/layout/favorite/favicondata/KOR.arc" updated<br />
<br />
A vuln used in a public(at the time of this sysupdate) webkit exploit for spider was fixed, which also fixed the removewinframe exploit from [https://github.com/yellows8/3ds_webkithax here].<br />
|-<br />
| 1.7610<br />
| v6149<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| ?<br />
| v7168<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
=== Old3DS v9.9 ===<br />
ExeFS:/.code was updated.<br />
<br />
The only changes in RomFS were file-updating, the following files were updated:<br />
/browser/rootca.pem<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/spider.msbt<br />
/message/EU_Dutch/spider.msbt<br />
/message/EU_English/spider.msbt<br />
/message/EU_French/spider.msbt<br />
/message/EU_German/spider.msbt<br />
/message/EU_Italian/spider.msbt<br />
/message/EU_Portuguese/spider.msbt<br />
/message/EU_Russian/spider.msbt<br />
/message/EU_Spanish/spider.msbt<br />
/message/JP_Japanese/spider.msbt<br />
/message/KR_Hangeul/spider.msbt<br />
/message/TW_English/spider.msbt<br />
/message/TW_Trad_Chinese/spider.msbt<br />
/message/US_English/spider.msbt<br />
/message/US_French/spider.msbt<br />
/message/US_Portuguese/spider.msbt<br />
/message/US_Spanish/spider.msbt<br />
<br />
OSS diff for v9.5 and v9.9, without the .dox changes:<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
index be5ff09..55a7274 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
@@ -29,7 +29,7 @@<br />
#define WKC_VERSION_CHECK(major, minor, micro) \<br />
(((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO))<br />
<br />
-#define WKC_CUSTOMER_RELEASE_VERSION "1.8.14"<br />
+#define WKC_CUSTOMER_RELEASE_VERSION "1.8.16"<br />
<br />
#define WKC_WEBKIT_VERSION "532.7"<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
index da4127e..d03403e 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
@@ -305,23 +305,23 @@ int RenderBox::scrollHeight() const<br />
<br />
int RenderBox::scrollLeft() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
}<br />
<br />
int RenderBox::scrollTop() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
}<br />
<br />
void RenderBox::setScrollLeft(int newLeft)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToXOffset(newLeft);<br />
}<br />
<br />
void RenderBox::setScrollTop(int newTop)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToYOffset(newTop);<br />
}<br />
<br />
=== Old3DS v10.2 ===<br />
The slider vuln from [https://github.com/yellows8/3ds_webkithax here] was fixed in the Old3DS browser it seems.<br />
<br />
The main codebin .text only increased by 0x10-bytes.<br />
<br />
The only changes in RomFS was that the following files were updated:<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
<br />
== Forced system-update ==<br />
The Old3DS/New3DS Internet Browser updated with [[9.9.0-26]] now includes the following message string:<br />
In order to use the Internet <br />
browser, a system update <br />
is required.<br />
To perform a system update, <br />
select System Update from Other<br />
Settings in System Settings.<br />
<br />
This wasn't enforced(web-browser displaying the above message when the installed browser isn't the latest version) until October 26, 2015. In some cases this message isn't displayed(as in some systems never displayed the message yet), the cause is unknown. It's unknown how exactly this is handled.<br />
<br />
This message only triggers when attempting to load a web-page.<br />
<br />
The browser codebins starting with v9.9 now contain the following URL strings:<br />
* Old3DS: <nowiki>"https://cbvc.cdn.nintendo.net/CTR/1/<region>"</nowiki><br />
* New3DS: <nowiki>"https://cbvc.cdn.nintendo.net/SNAKE/1/<region>"</nowiki><br />
<br />
The <region> string is one of the following:<br />
* "JPN"<br />
* "USA"<br />
* "EUR"<br />
* "KOR"<br />
<br />
Starting with the browser from [[10.2.0-28]], the "1" in the above URLs were changed to "2".<br />
<br />
It is still possible to guard against this update by blocking the previous URLs using a proxy. <br />
It is however possible to remove the update message by entering the [[Recovery Mode]].<br />
<br />
==Web Standards==<br />
*HTML 4.01<br />
*HTML 5 (120/400 score on [http://www.html5test.com HTML5Test.com])<br />
*XHTML 1.1<br />
*CSS 1<br />
*CSS 2.1<br />
*CSS 3 (some functionality is unavailable)<br />
*DOM Levels 1-3<br />
*ECMAScript (partial support for ECMA-262 5th Edition)<br />
*XMLHttpRequest Level 2<br />
*Canvas Element (some functionality is unavailable)<br />
<br />
==Protocols==<br />
*HTTP 1.0<br />
*HTTP 1.1<br />
*SSLv3<br />
*TLS 1.0<br />
<br />
==Image Formats==<br />
*[[File_Formats|MPO]]<br />
*GIF<br />
*JPEG<br />
*PNG<br />
*BMP<br />
*ICO (some files cannot be displayed)<br />
<br />
==Plug-Ins==<br />
<br />
Plug-ins (such as Adobe Flash) are not supported.<br />
<br />
==Other details==<br />
<br />
*It scored 90/100 on [http://acid3.acidtests.org/ Acid3] test<br />
*Images from the Internet can be saved to the [[SD Filesystem|SD Card]] and viewed using the [[Nintendo 3DS Camera]] application.<br />
*Images saved to an [[SD Filesystem|SD Card]] or to the Nintendo 3DS system memory can be uploaded to blogs or other sites that allow the uploading of photos using :<br />
<input type="file" /><br />
* HTML5Test.com say that Drag and drop is supported but it's not (code on WebKit is ready, but it's not implemented on interface of browser)<br />
<br />
==Tips==<br />
<br />
=== Detect User Agent ===<br />
<br />
To detect if the user agent is Nintendo 3DS Browser :<br />
<br />
<script type="text/javascript"><br />
if (navigator.userAgent.indexOf('Nintendo 3DS') == -1) { //If the UserAgent is not "Nintendo 3DS"<br />
location.replace('http://www.3dbrew.org'); //Redirect to an other page<br />
}<br />
</script><br />
<br />
* You can check <em>navigator.platform=="Nintendo 3DS"</em> as well.<br />
<br />
=== Scrolling ===<br />
<br />
Scrolling can be altered by modifying <em>document.body.scrollTop</em> and <em>document.body.scrollLeft</em>. However, there are drawbacks related to working with these properties:<br />
<br />
* Both properties return 0 when accessed<br />
* Setting one property resets the other property's scroll position<br />
<br />
In order to set both at the same time (without either resetting to 0), use <em>window.scrollTo</em>.<br />
<br />
=== Events ===<br />
==== Key Events ====<br />
The following buttons trigger the <em>onkeydown</em>, <em>onkeypress</em> and <em>onkeyup</em> events:<br />
<br />
{|class="wikitable" width="20%"<br />
! Code !! Button <br />
|-<br />
| 13 || A<br />
|-<br />
| 37 || Left<br />
|-<br />
| 38 || Up<br />
|-<br />
| 39 || Right<br />
|-<br />
| 40 || Down<br />
|}<br />
<br />
The events cannot have their default action cancelled. Other buttons do not trigger key events.<br />
<br />
==== Touch/Mouse Events ====<br />
<em>onmousedown</em>, <em>onmouseup</em> & <em>onclick</em> are all triggered by the browser. However, the <em>onmousedown</em> event doesn't trigger until you lift the stylus or you've held it on the screen for ~2 seconds—which is when text selection mode is activated—making it pretty much the same as <em>onmouseup</em>. The events cannot have their default action cancelled.<br />
<br />
The <em>onmousemove</em> and common touch/gesture events are not supported.<br />
<br />
== Screen Resolution ==<br />
<br />
The up screen resolution is 400×240. However, the viewable area in the browser is only <b>400×220</b>.<br />
<br />
The touch screen resolution is 320×240. However, the viewable area in the browser is only <b>320×212</b>.<br />
<br />
You can have a page span both screens. However, the browser will behave as if the bottom screen is the only active screen and the top screen is scrolled off. This is important when computing CSS coordinates. Items positioned from "bottom" will be positioned based on 220px and not the full 432px of both screens.<br />
<br />
== Using Both Screens ==<br />
<br />
Generally the easiest way to accomplish the correct layout is to create HTML elements that "contain" the top and bottom screens. Here's an example:<br />
<br />
<!DOCTYPE html><br />
<html><br />
<head><br />
<meta name="viewport" content="width=400"><br />
<style><br />
body{margin:0px;}<br />
#topscreen{width:400px;height:220px;overflow:hidden;}<br />
#bottomscreen{width:320px;height:212px;overflow:hidden;margin:0 auto;}<br />
</style><br />
</head><br />
<body><br />
&lt;div id="topscreen">Top Screen&lt;/div><br />
&lt;div id="bottomscreen">Bottom Screen&lt;/div><br />
</body><br />
</html><br />
<br />
This scheme allows the page to be easily manipulated through JavaScript. In order to have the window snap to the correct position, use the following JavaScript code:<br />
<br />
window.setInterval(function () {<br />
window.scrollTo(40, 220); <br />
}, 50);<br />
<br />
This automatically resets the position if the user accidentally scrolls the page.<br />
<br />
==Example Sites==<br />
<!-- If you have a website that demonstrates these techniques, place it here! --><br />
* [http://geekshadow.com/gaming/dev/weaponscolors/3DS/ Weapons and Colors] (Short URL: http://bit.ly/3DSwc)<br />
* [http://3ds.andysmith.co.uk/jFox.html jFox] (Short URL: http://bit.ly/iB7FqW)<br />
* [http://ditto3d.com/3ds Ditto3D] (Short URL: http://bit.ly/oVreWA)<br />
* [http://www.nintendo.com/3ds/internetbrowser/bookmarks Nintendo 3DS Bookmarks] - This is the first bookmark pre-installed in the browser.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Internet_Browser&diff=14336
Internet Browser
2015-10-27T03:43:30Z
<p>Lectem: </p>
<hr />
<div>The 3DS Internet Browser was added in the June 2011 Update for JPN/EUR/USA.<br />
<br />
From the Internet Browser help section:<br />
In compliance with the LGPL, the source code of the OSS is available via the Nintendo website.<br />
This source code can be downloaded here:<br />
[http://mediacontent.nintendo-europe.com/NOE/images/service/OpenSources.zip] [http://www.nintendo.co.jp/support/oss/index.html]<br />
<br />
The 3DS Internet Browser is [http://en.wikipedia.org/wiki/Netfront Netfront] Browser NX v1.0 based on [http://en.wikipedia.org/wiki/WebKit WebKit] engine.<br />
<br />
The browser supports up to 64 bookmarks.<br />
<br />
The exheader name of this title is "spider".<br />
<br />
The only difference between the ExeFS .code for each region of the Old3DS/New3DS browser, is byte values for the title uniqueID/region, otherwise the binaries are identical.<br />
<br />
'''Note that both spider and SKATER have started being included in some CUPs (cart updates) beginning with Tri Force Heroes and potentially earlier.'''<br />
<br />
==[[New 3DS]] Internet Browser==<br />
New3DS has a separate browser title, the exheader name is "SKATER".<br />
<br />
Unlike the Old3DS browser, this New3DS browser has videos+HTML5 support. This browser also has a filter enabled by default(ExeFS codebin is same for all regions, this filter only applies for JPN region). Disabling it requires paying money with a credit-card, for [[NIM_Services|purchasing]] web-browser [[Title_list/DLC|DLC]].<br />
<br />
During startup the browser does various HTTPS comms. When visting an URL, the browser sends a plaintext HTTP POST to here: [http://ars.ifuser.jp:20080/ars2/rating]. The raw POST data begins with "ARS/2.0\r\n\x00", the rest appears to be encrypted. The server reply content also has this ARS header + encrypted data. This appears to use a fixed xorpad, likely from a fixed encryption CTR/IV. The server content responses for allowed sites, and blocked sites, are fixed. When the server returns that the site is blocked, the browser goes to this page: [http://ars.ifuser.jp/filter/44.html](the Referrer header value is set to the same URL it's actually requesting).<br />
<br />
The WebKit source was updated since the Old3DS browser.<br />
<br />
Unlike the Old3DS browser, the New3DS browser uses the following services: [[MVD_Services|mvd:STD]] and [[IR_Services|ir:rst]](DLC-related services are used too but those aren't New3DS specific).<br />
<br />
Video decoding is done with [[MVD_Services|mvd:STD]]. Audio decoding/playback is done with a browser-specific DSP binary. The Old3DS browser used CSND for audio playback, the New3DS browser doesn't have access to that at all since it uses DSP instead.<br />
<br />
The browser manual includes licenses for Android and PacketVideo. The browser uses libstagefright from Android.<br />
<br />
===User-Agent and Browser Versions===<br />
Normal user-agent format: <code style="font-size:larger;">Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/<WebKit version> (KHTML, like Gecko) NX/<Netfront version> Mobile NintendoBrowser/<Mobile NintendoBrowser version>.<region></code><br />
<br />
<region> can be one of the following: "JP", "US", or "EU".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Mobile NintendoBrowser version(displayed in browser settings)<br />
! Normal UA<br />
! Mobile UA<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.0.9934<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.8 Mobile NintendoBrowser/1.0.9934.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v10<br />
| [[9.0.0-20]]<br />
| Initial version.<br />
|-<br />
| 1.1.9996<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.10 Mobile NintendoBrowser/1.1.9996.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v1027<br />
| [[9.3.0-21]]<br />
| See below regarding OSS changes.<br />
|-<br />
| 1.2.10085<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.13 Mobile NintendoBrowser/1.2.10085.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v2051<br />
| [[9.6.0-24]]<br />
| See below.<br />
|-<br />
| 1.3.10126<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.US<br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v3077<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| 1.4.10138<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.17 Mobile NintendoBrowser/1.4.10138.US<br />
| ?<br />
| v4096<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
Note that the latest Old3DS browser WebKit version at the time the initial New3DS browser was released, was the following: 532.8.<br />
<br />
==== OSS 9.0 and 9.3 diff ====<br />
The following is a diff of the OSS archives from [http://www.nintendo.co.jp/support/oss/index.html here], for v9.0 and v9.3.<br />
<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp and NewNintendo3DS_OpenSources9.3.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp differ<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebKit/WKC/webkit/WKCVersion.h and NewNintendo3DS_OpenSources9.3.0-/WKC/WebKit/WKC/webkit/WKCVersion.h differ<br />
<br />
WKC_CUSTOMER_RELEASE_VERSION was changed from "0.5.8" to "0.5.10".<br />
<br />
The following code was added to ResourceHandleManager::doRedirect(): curl_easy_setopt(d->m_handle, CURLOPT_SHARE, 0);<br />
<br />
==== v9.6 ====<br />
WebKit/OSS code was actually updated.<br />
ExeFS .code was updated. The following files in RomFS were updated:<br />
* "/banner/CN/Skater.icn" and "/banner/KR/Skater.icn".<br />
* "/browser/rootca.pem"<br />
* "/build/buildinfo.dat"<br />
* "/cairo.cro.lex" and "/.crr/static.crr"<br />
* "/lyt/Button/ButtonSelectHSearch.arc"<br />
* "/lyt/Kbd/Swkbd.arc"<br />
* "lyt/Kbd.arc"<br />
* "skater.msbt" under all of the "/message/<region>_<language>/" directories.<br />
* "/oss.cro.lex", "/peer.cro.lex", "/static.crs", and "/webkit.cro.lex".<br />
<br />
The following was added to RomFS:<br />
* "/favicon/naver.dat"<br />
* A "KO" directory under "/iwnn".<br />
<br />
==== v9.9 ====<br />
ExeFS:/.code was updated.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem<br />
/build/buildinfo.dat<br />
/cairo.cro.lex<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/skater.msbt<br />
/message/EU_Dutch/skater.msbt<br />
/message/EU_English/skater.msbt<br />
/message/EU_French/skater.msbt<br />
/message/EU_German/skater.msbt<br />
/message/EU_Italian/skater.msbt<br />
/message/EU_Portuguese/skater.msbt<br />
/message/EU_Russian/skater.msbt<br />
/message/EU_Spanish/skater.msbt<br />
/message/JP_Japanese/skater.msbt<br />
/message/KR_Hangeul/skater.msbt<br />
/message/TW_English/skater.msbt<br />
/message/TW_Trad_Chinese/skater.msbt<br />
/message/US_English/skater.msbt<br />
/message/US_French/skater.msbt<br />
/message/US_Portuguese/skater.msbt<br />
/message/US_Spanish/skater.msbt<br />
/oss.cro.lex<br />
/peer.cro.lex<br />
/static.crs<br />
/webkit.cro.lex<br />
<br />
See [https://gist.github.com/yellows8/9fb509fde4112339f342 here] for a diff of the OSS(WebKitLibraries/ is not included due to the massive cairo library diff). An exploitable security vuln(which was already known in the context of 3DS webkit) was fixed. [[User:Yellows8|Yellows8]]' private(at the time of writing) exploit for it is based on the PoC from [http://pastebin.com/ufBCQKda here](see the pastebin for the actual pastebin author).<br />
<br />
==== v10.2 ====<br />
The libstagefright build in the main SKATER codebin was updated to a version which fixed libstagefright vuln(s): the vuln used in [[browserhax|browserhax_fright]] at the time of sysupdate release was fixed. The *only* code changed in the main codebin, was code related to libstagefright.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem differ<br />
/build/buildinfo.dat differ<br />
/.crr/static.crr differ<br />
/message/CN_Simp_Chinese/skater.msbt differ<br />
/message/EU_Dutch/skater.msbt differ<br />
/message/EU_English/skater.msbt differ<br />
/message/EU_French/skater.msbt differ<br />
/message/EU_German/skater.msbt differ<br />
/message/EU_Italian/skater.msbt differ<br />
/message/EU_Portuguese/skater.msbt differ<br />
/message/EU_Russian/skater.msbt differ<br />
/message/EU_Spanish/skater.msbt differ<br />
/message/JP_Japanese/skater.msbt differ<br />
/message/KR_Hangeul/skater.msbt differ<br />
/message/TW_English/skater.msbt differ<br />
/message/TW_Trad_Chinese/skater.msbt differ<br />
/message/US_English/skater.msbt differ<br />
/message/US_French/skater.msbt differ<br />
/message/US_Portuguese/skater.msbt differ<br />
/message/US_Spanish/skater.msbt differ<br />
/oss.cro.lex differ<br />
/static.crs differ<br />
/webkit.cro.lex differ<br />
<br />
=== New3DS Browser Specifications ===<br />
[http://www.nintendo.co.jp/3ds/new/features/modal_net.html]<br />
<br />
English version(Google translate):<br />
* "Browser engine: NetFront® Browser NX v3.0"<br />
* "User agent: Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.*.*.* Mobile NintendoBrowser/1.0.****.JP<br />
** The *** is described version information.<br />
** When you use the "mobile version of the request" function, which is different from those described above string."<br />
* "Supported protocols: HTTP1.0/HTTP1.1/SSL3.0/TLS1.0/TLS1.1/TLS1.2"<br />
* "Web standard: HTML4.01 / HTML5 / XHTML1.1 / Fullscreen / Gamepad / SVG / WebSocket / Video Subtitle / WOFF / Web Messaging / Server-Sent / Web Storage of part / XMLHttpRequest / canvas / Video / DOM1-3 / ECMAScript / CSS1 / CSS2.1 / CSS3 part of"<br />
* "Image format: bmp / ​​gif / ico / jpeg / png / svg (There are, however, it is not possible to display some image.)"<br />
* "Image preview: mpo / jpeg (There are, however, it is not possible to display some image.)"<br />
* "Video format: MP4, M3U8 + TS (HTTPLiveStreaming) (However, there are some you can not play the video.)"<br />
* "Video codec: H.264 - MPEG-4 AVC Video (max 854x480 level 3.2, 3D compatible) (However, there are some you can not play the video.)"<br />
* "Audio codec: AAC - ISO / IEC 14496-3 MPEG-4AAC, MP3 <br /> (However, there are some you can not play the video.)"<br />
* "Of 3D video at the time of upload format: .mkv (However, in order to play the video, you must format is converted in the upload to the site. In addition, even if it is converted you might not be able to play.)"<br />
* "It does not correspond to the plug-ins such as plug-in Adobe Flash."<br />
* "Use the Active Rating System of filtering function: Digital Arts, Inc. provides. At the time of access to Web content, and implementing the decision of whether access is permitted based on the category information. Feature that can limit access to Web content that may be inappropriate for viewing by the determination result."<br />
* "I will request the display of the mobile version page of the web page you are viewing request function the mobile version. (However, if the web page does not correspond to the mobile version of the page does not change the display.)"<br />
<br />
MJPEG + .avi is also supported.<br />
<br />
<br />
== Old3DS browser ==<br />
<br />
<br />
=== User-Agent and Browser Versions ===<br />
User-agent format: <code style="font-size:larger;">Mozilla/5.0 (Nintendo 3DS; U; ; <lang>) Version/<version>.<region></code>.<br />
<br />
<lang> is "en", "fr", etc. <region> is "US", "EU", etc. See below for <version>.<br />
{| class="wikitable" border="1"<br />
|-<br />
! Browser version<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.7412<br />
| v6<br />
| [[2.0.0-2|2.0.0-2]]<br />
| This was the initial version.<br />
|-<br />
| 1.7455<br />
| v1024<br />
| [[2.1.0-4]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too.<br />
|-<br />
| 1.7498<br />
| v2050<br />
| [[4.0.0-7]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3075<br />
| [[5.0.0-11]]<br />
| ExeFS .code and icon were updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3088<br />
| [[7.0.0-13]]<br />
| The main NCCH wasn't updated at all(same TMD contentID/content-hash as the previous version), only the manual CFA for this title was updated.<br />
|-<br />
| 1.7567<br />
| v4096<br />
| [[7.1.0-16]]<br />
| The CXI .code was updated, some data in the RomFS was updated(none of the CROs such as webkit.cro were updated). The manual CFA was updated too.<br />
|-<br />
| 1.7585<br />
| v5121<br />
| [[9.5.0-23]]<br />
| The CXI .code was updated, and the manual CFA was updated. RomFS changes:<br />
* "/browser/rootca.pem" updated<br />
* "/cro/oss.cro" updated<br />
* "/cro/static.crs" updated<br />
* "/cro/webkit.cro" updated<br />
* "/.crr/static.crr" updated<br />
* "/layout/dialogheader/WirelessSwitchOff.arc" was removed<br />
* "/layout/favorite/favicondata/KOR.arc" updated<br />
<br />
A vuln used in a public(at the time of this sysupdate) webkit exploit for spider was fixed, which also fixed the removewinframe exploit from [https://github.com/yellows8/3ds_webkithax here].<br />
|-<br />
| 1.7610<br />
| v6149<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| ?<br />
| v7168<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
=== Old3DS v9.9 ===<br />
ExeFS:/.code was updated.<br />
<br />
The only changes in RomFS were file-updating, the following files were updated:<br />
/browser/rootca.pem<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/spider.msbt<br />
/message/EU_Dutch/spider.msbt<br />
/message/EU_English/spider.msbt<br />
/message/EU_French/spider.msbt<br />
/message/EU_German/spider.msbt<br />
/message/EU_Italian/spider.msbt<br />
/message/EU_Portuguese/spider.msbt<br />
/message/EU_Russian/spider.msbt<br />
/message/EU_Spanish/spider.msbt<br />
/message/JP_Japanese/spider.msbt<br />
/message/KR_Hangeul/spider.msbt<br />
/message/TW_English/spider.msbt<br />
/message/TW_Trad_Chinese/spider.msbt<br />
/message/US_English/spider.msbt<br />
/message/US_French/spider.msbt<br />
/message/US_Portuguese/spider.msbt<br />
/message/US_Spanish/spider.msbt<br />
<br />
OSS diff for v9.5 and v9.9, without the .dox changes:<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
index be5ff09..55a7274 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
@@ -29,7 +29,7 @@<br />
#define WKC_VERSION_CHECK(major, minor, micro) \<br />
(((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO))<br />
<br />
-#define WKC_CUSTOMER_RELEASE_VERSION "1.8.14"<br />
+#define WKC_CUSTOMER_RELEASE_VERSION "1.8.16"<br />
<br />
#define WKC_WEBKIT_VERSION "532.7"<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
index da4127e..d03403e 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
@@ -305,23 +305,23 @@ int RenderBox::scrollHeight() const<br />
<br />
int RenderBox::scrollLeft() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
}<br />
<br />
int RenderBox::scrollTop() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
}<br />
<br />
void RenderBox::setScrollLeft(int newLeft)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToXOffset(newLeft);<br />
}<br />
<br />
void RenderBox::setScrollTop(int newTop)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToYOffset(newTop);<br />
}<br />
<br />
=== Old3DS v10.2 ===<br />
The slider vuln from [https://github.com/yellows8/3ds_webkithax here] was fixed in the Old3DS browser it seems.<br />
<br />
The main codebin .text only increased by 0x10-bytes.<br />
<br />
The only changes in RomFS was that the following files were updated:<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
<br />
== Forced system-update ==<br />
The Old3DS/New3DS Internet Browser updated with [[9.9.0-26]] now includes the following message string:<br />
In order to use the Internet <br />
browser, a system update <br />
is required.<br />
To perform a system update, <br />
select System Update from Other<br />
Settings in System Settings.<br />
<br />
This wasn't enforced(web-browser displaying the above message when the installed browser isn't the latest version) until October 26, 2015. In some cases this message isn't displayed(as in some systems never displayed the message yet), the cause is unknown. It's unknown how exactly this is handled.<br />
<br />
This message only triggers when attempting to load a web-page.<br />
<br />
The browser codebins starting with v9.9 now contain the following URL strings:<br />
* Old3DS: <nowiki>"https://cbvc.cdn.nintendo.net/CTR/1/<region>"</nowiki><br />
* New3DS: <nowiki>"https://cbvc.cdn.nintendo.net/SNAKE/1/<region>"</nowiki><br />
<br />
The <region> string is one of the following:<br />
* "JPN"<br />
* "USA"<br />
* "EUR"<br />
* "KOR"<br />
<br />
Starting with the browser from [[10.2.0-28]], the "1" in the above URLs were changed to "2".<br />
<br />
It is still possible to guard against this update by blocking the previous URLs using a proxy. <br />
It is not possible to remove the update message by entering the [[Recovery Mode]].<br />
<br />
==Web Standards==<br />
*HTML 4.01<br />
*HTML 5 (120/400 score on [http://www.html5test.com HTML5Test.com])<br />
*XHTML 1.1<br />
*CSS 1<br />
*CSS 2.1<br />
*CSS 3 (some functionality is unavailable)<br />
*DOM Levels 1-3<br />
*ECMAScript (partial support for ECMA-262 5th Edition)<br />
*XMLHttpRequest Level 2<br />
*Canvas Element (some functionality is unavailable)<br />
<br />
==Protocols==<br />
*HTTP 1.0<br />
*HTTP 1.1<br />
*SSLv3<br />
*TLS 1.0<br />
<br />
==Image Formats==<br />
*[[File_Formats|MPO]]<br />
*GIF<br />
*JPEG<br />
*PNG<br />
*BMP<br />
*ICO (some files cannot be displayed)<br />
<br />
==Plug-Ins==<br />
<br />
Plug-ins (such as Adobe Flash) are not supported.<br />
<br />
==Other details==<br />
<br />
*It scored 90/100 on [http://acid3.acidtests.org/ Acid3] test<br />
*Images from the Internet can be saved to the [[SD Filesystem|SD Card]] and viewed using the [[Nintendo 3DS Camera]] application.<br />
*Images saved to an [[SD Filesystem|SD Card]] or to the Nintendo 3DS system memory can be uploaded to blogs or other sites that allow the uploading of photos using :<br />
<input type="file" /><br />
* HTML5Test.com say that Drag and drop is supported but it's not (code on WebKit is ready, but it's not implemented on interface of browser)<br />
<br />
==Tips==<br />
<br />
=== Detect User Agent ===<br />
<br />
To detect if the user agent is Nintendo 3DS Browser :<br />
<br />
<script type="text/javascript"><br />
if (navigator.userAgent.indexOf('Nintendo 3DS') == -1) { //If the UserAgent is not "Nintendo 3DS"<br />
location.replace('http://www.3dbrew.org'); //Redirect to an other page<br />
}<br />
</script><br />
<br />
* You can check <em>navigator.platform=="Nintendo 3DS"</em> as well.<br />
<br />
=== Scrolling ===<br />
<br />
Scrolling can be altered by modifying <em>document.body.scrollTop</em> and <em>document.body.scrollLeft</em>. However, there are drawbacks related to working with these properties:<br />
<br />
* Both properties return 0 when accessed<br />
* Setting one property resets the other property's scroll position<br />
<br />
In order to set both at the same time (without either resetting to 0), use <em>window.scrollTo</em>.<br />
<br />
=== Events ===<br />
==== Key Events ====<br />
The following buttons trigger the <em>onkeydown</em>, <em>onkeypress</em> and <em>onkeyup</em> events:<br />
<br />
{|class="wikitable" width="20%"<br />
! Code !! Button <br />
|-<br />
| 13 || A<br />
|-<br />
| 37 || Left<br />
|-<br />
| 38 || Up<br />
|-<br />
| 39 || Right<br />
|-<br />
| 40 || Down<br />
|}<br />
<br />
The events cannot have their default action cancelled. Other buttons do not trigger key events.<br />
<br />
==== Touch/Mouse Events ====<br />
<em>onmousedown</em>, <em>onmouseup</em> & <em>onclick</em> are all triggered by the browser. However, the <em>onmousedown</em> event doesn't trigger until you lift the stylus or you've held it on the screen for ~2 seconds—which is when text selection mode is activated—making it pretty much the same as <em>onmouseup</em>. The events cannot have their default action cancelled.<br />
<br />
The <em>onmousemove</em> and common touch/gesture events are not supported.<br />
<br />
== Screen Resolution ==<br />
<br />
The up screen resolution is 400×240. However, the viewable area in the browser is only <b>400×220</b>.<br />
<br />
The touch screen resolution is 320×240. However, the viewable area in the browser is only <b>320×212</b>.<br />
<br />
You can have a page span both screens. However, the browser will behave as if the bottom screen is the only active screen and the top screen is scrolled off. This is important when computing CSS coordinates. Items positioned from "bottom" will be positioned based on 220px and not the full 432px of both screens.<br />
<br />
== Using Both Screens ==<br />
<br />
Generally the easiest way to accomplish the correct layout is to create HTML elements that "contain" the top and bottom screens. Here's an example:<br />
<br />
<!DOCTYPE html><br />
<html><br />
<head><br />
<meta name="viewport" content="width=400"><br />
<style><br />
body{margin:0px;}<br />
#topscreen{width:400px;height:220px;overflow:hidden;}<br />
#bottomscreen{width:320px;height:212px;overflow:hidden;margin:0 auto;}<br />
</style><br />
</head><br />
<body><br />
&lt;div id="topscreen">Top Screen&lt;/div><br />
&lt;div id="bottomscreen">Bottom Screen&lt;/div><br />
</body><br />
</html><br />
<br />
This scheme allows the page to be easily manipulated through JavaScript. In order to have the window snap to the correct position, use the following JavaScript code:<br />
<br />
window.setInterval(function () {<br />
window.scrollTo(40, 220); <br />
}, 50);<br />
<br />
This automatically resets the position if the user accidentally scrolls the page.<br />
<br />
==Example Sites==<br />
<!-- If you have a website that demonstrates these techniques, place it here! --><br />
* [http://geekshadow.com/gaming/dev/weaponscolors/3DS/ Weapons and Colors] (Short URL: http://bit.ly/3DSwc)<br />
* [http://3ds.andysmith.co.uk/jFox.html jFox] (Short URL: http://bit.ly/iB7FqW)<br />
* [http://ditto3d.com/3ds Ditto3D] (Short URL: http://bit.ly/oVreWA)<br />
* [http://www.nintendo.com/3ds/internetbrowser/bookmarks Nintendo 3DS Bookmarks] - This is the first bookmark pre-installed in the browser.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Internet_Browser&diff=14335
Internet Browser
2015-10-27T03:40:20Z
<p>Lectem: </p>
<hr />
<div>The 3DS Internet Browser was added in the June 2011 Update for JPN/EUR/USA.<br />
<br />
From the Internet Browser help section:<br />
In compliance with the LGPL, the source code of the OSS is available via the Nintendo website.<br />
This source code can be downloaded here:<br />
[http://mediacontent.nintendo-europe.com/NOE/images/service/OpenSources.zip] [http://www.nintendo.co.jp/support/oss/index.html]<br />
<br />
The 3DS Internet Browser is [http://en.wikipedia.org/wiki/Netfront Netfront] Browser NX v1.0 based on [http://en.wikipedia.org/wiki/WebKit WebKit] engine.<br />
<br />
The browser supports up to 64 bookmarks.<br />
<br />
The exheader name of this title is "spider".<br />
<br />
The only difference between the ExeFS .code for each region of the Old3DS/New3DS browser, is byte values for the title uniqueID/region, otherwise the binaries are identical.<br />
<br />
'''Note that both spider and SKATER have started being included in some CUPs (cart updates) beginning with Tri Force Heroes and potentially earlier.'''<br />
<br />
==[[New 3DS]] Internet Browser==<br />
New3DS has a separate browser title, the exheader name is "SKATER".<br />
<br />
Unlike the Old3DS browser, this New3DS browser has videos+HTML5 support. This browser also has a filter enabled by default(ExeFS codebin is same for all regions, this filter only applies for JPN region). Disabling it requires paying money with a credit-card, for [[NIM_Services|purchasing]] web-browser [[Title_list/DLC|DLC]].<br />
<br />
During startup the browser does various HTTPS comms. When visting an URL, the browser sends a plaintext HTTP POST to here: [http://ars.ifuser.jp:20080/ars2/rating]. The raw POST data begins with "ARS/2.0\r\n\x00", the rest appears to be encrypted. The server reply content also has this ARS header + encrypted data. This appears to use a fixed xorpad, likely from a fixed encryption CTR/IV. The server content responses for allowed sites, and blocked sites, are fixed. When the server returns that the site is blocked, the browser goes to this page: [http://ars.ifuser.jp/filter/44.html](the Referrer header value is set to the same URL it's actually requesting).<br />
<br />
The WebKit source was updated since the Old3DS browser.<br />
<br />
Unlike the Old3DS browser, the New3DS browser uses the following services: [[MVD_Services|mvd:STD]] and [[IR_Services|ir:rst]](DLC-related services are used too but those aren't New3DS specific).<br />
<br />
Video decoding is done with [[MVD_Services|mvd:STD]]. Audio decoding/playback is done with a browser-specific DSP binary. The Old3DS browser used CSND for audio playback, the New3DS browser doesn't have access to that at all since it uses DSP instead.<br />
<br />
The browser manual includes licenses for Android and PacketVideo. The browser uses libstagefright from Android.<br />
<br />
===User-Agent and Browser Versions===<br />
Normal user-agent format: <code style="font-size:larger;">Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/<WebKit version> (KHTML, like Gecko) NX/<Netfront version> Mobile NintendoBrowser/<Mobile NintendoBrowser version>.<region></code><br />
<br />
<region> can be one of the following: "JP", "US", or "EU".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Mobile NintendoBrowser version(displayed in browser settings)<br />
! Normal UA<br />
! Mobile UA<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.0.9934<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.8 Mobile NintendoBrowser/1.0.9934.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v10<br />
| [[9.0.0-20]]<br />
| Initial version.<br />
|-<br />
| 1.1.9996<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.10 Mobile NintendoBrowser/1.1.9996.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v1027<br />
| [[9.3.0-21]]<br />
| See below regarding OSS changes.<br />
|-<br />
| 1.2.10085<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.13 Mobile NintendoBrowser/1.2.10085.<region><br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v2051<br />
| [[9.6.0-24]]<br />
| See below.<br />
|-<br />
| 1.3.10126<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.US<br />
| Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25<br />
| v3077<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| 1.4.10138<br />
| Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.17 Mobile NintendoBrowser/1.4.10138.US<br />
| ?<br />
| v4096<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
Note that the latest Old3DS browser WebKit version at the time the initial New3DS browser was released, was the following: 532.8.<br />
<br />
==== OSS 9.0 and 9.3 diff ====<br />
The following is a diff of the OSS archives from [http://www.nintendo.co.jp/support/oss/index.html here], for v9.0 and v9.3.<br />
<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp and NewNintendo3DS_OpenSources9.3.0-/WKC/WebCore/platform/network/WKC/ResourceHandleManagerWKC.cpp differ<br />
Files NewNintendo3DS_OpenSources9.0.0-/WKC/WebKit/WKC/webkit/WKCVersion.h and NewNintendo3DS_OpenSources9.3.0-/WKC/WebKit/WKC/webkit/WKCVersion.h differ<br />
<br />
WKC_CUSTOMER_RELEASE_VERSION was changed from "0.5.8" to "0.5.10".<br />
<br />
The following code was added to ResourceHandleManager::doRedirect(): curl_easy_setopt(d->m_handle, CURLOPT_SHARE, 0);<br />
<br />
==== v9.6 ====<br />
WebKit/OSS code was actually updated.<br />
ExeFS .code was updated. The following files in RomFS were updated:<br />
* "/banner/CN/Skater.icn" and "/banner/KR/Skater.icn".<br />
* "/browser/rootca.pem"<br />
* "/build/buildinfo.dat"<br />
* "/cairo.cro.lex" and "/.crr/static.crr"<br />
* "/lyt/Button/ButtonSelectHSearch.arc"<br />
* "/lyt/Kbd/Swkbd.arc"<br />
* "lyt/Kbd.arc"<br />
* "skater.msbt" under all of the "/message/<region>_<language>/" directories.<br />
* "/oss.cro.lex", "/peer.cro.lex", "/static.crs", and "/webkit.cro.lex".<br />
<br />
The following was added to RomFS:<br />
* "/favicon/naver.dat"<br />
* A "KO" directory under "/iwnn".<br />
<br />
==== v9.9 ====<br />
ExeFS:/.code was updated.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem<br />
/build/buildinfo.dat<br />
/cairo.cro.lex<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/skater.msbt<br />
/message/EU_Dutch/skater.msbt<br />
/message/EU_English/skater.msbt<br />
/message/EU_French/skater.msbt<br />
/message/EU_German/skater.msbt<br />
/message/EU_Italian/skater.msbt<br />
/message/EU_Portuguese/skater.msbt<br />
/message/EU_Russian/skater.msbt<br />
/message/EU_Spanish/skater.msbt<br />
/message/JP_Japanese/skater.msbt<br />
/message/KR_Hangeul/skater.msbt<br />
/message/TW_English/skater.msbt<br />
/message/TW_Trad_Chinese/skater.msbt<br />
/message/US_English/skater.msbt<br />
/message/US_French/skater.msbt<br />
/message/US_Portuguese/skater.msbt<br />
/message/US_Spanish/skater.msbt<br />
/oss.cro.lex<br />
/peer.cro.lex<br />
/static.crs<br />
/webkit.cro.lex<br />
<br />
See [https://gist.github.com/yellows8/9fb509fde4112339f342 here] for a diff of the OSS(WebKitLibraries/ is not included due to the massive cairo library diff). An exploitable security vuln(which was already known in the context of 3DS webkit) was fixed. [[User:Yellows8|Yellows8]]' private(at the time of writing) exploit for it is based on the PoC from [http://pastebin.com/ufBCQKda here](see the pastebin for the actual pastebin author).<br />
<br />
==== v10.2 ====<br />
The libstagefright build in the main SKATER codebin was updated to a version which fixed libstagefright vuln(s): the vuln used in [[browserhax|browserhax_fright]] at the time of sysupdate release was fixed. The *only* code changed in the main codebin, was code related to libstagefright.<br />
<br />
The only RomFS changes is file-updating, all of the following files were updated:<br />
/browser/rootca.pem differ<br />
/build/buildinfo.dat differ<br />
/.crr/static.crr differ<br />
/message/CN_Simp_Chinese/skater.msbt differ<br />
/message/EU_Dutch/skater.msbt differ<br />
/message/EU_English/skater.msbt differ<br />
/message/EU_French/skater.msbt differ<br />
/message/EU_German/skater.msbt differ<br />
/message/EU_Italian/skater.msbt differ<br />
/message/EU_Portuguese/skater.msbt differ<br />
/message/EU_Russian/skater.msbt differ<br />
/message/EU_Spanish/skater.msbt differ<br />
/message/JP_Japanese/skater.msbt differ<br />
/message/KR_Hangeul/skater.msbt differ<br />
/message/TW_English/skater.msbt differ<br />
/message/TW_Trad_Chinese/skater.msbt differ<br />
/message/US_English/skater.msbt differ<br />
/message/US_French/skater.msbt differ<br />
/message/US_Portuguese/skater.msbt differ<br />
/message/US_Spanish/skater.msbt differ<br />
/oss.cro.lex differ<br />
/static.crs differ<br />
/webkit.cro.lex differ<br />
<br />
=== New3DS Browser Specifications ===<br />
[http://www.nintendo.co.jp/3ds/new/features/modal_net.html]<br />
<br />
English version(Google translate):<br />
* "Browser engine: NetFront® Browser NX v3.0"<br />
* "User agent: Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.*.*.* Mobile NintendoBrowser/1.0.****.JP<br />
** The *** is described version information.<br />
** When you use the "mobile version of the request" function, which is different from those described above string."<br />
* "Supported protocols: HTTP1.0/HTTP1.1/SSL3.0/TLS1.0/TLS1.1/TLS1.2"<br />
* "Web standard: HTML4.01 / HTML5 / XHTML1.1 / Fullscreen / Gamepad / SVG / WebSocket / Video Subtitle / WOFF / Web Messaging / Server-Sent / Web Storage of part / XMLHttpRequest / canvas / Video / DOM1-3 / ECMAScript / CSS1 / CSS2.1 / CSS3 part of"<br />
* "Image format: bmp / ​​gif / ico / jpeg / png / svg (There are, however, it is not possible to display some image.)"<br />
* "Image preview: mpo / jpeg (There are, however, it is not possible to display some image.)"<br />
* "Video format: MP4, M3U8 + TS (HTTPLiveStreaming) (However, there are some you can not play the video.)"<br />
* "Video codec: H.264 - MPEG-4 AVC Video (max 854x480 level 3.2, 3D compatible) (However, there are some you can not play the video.)"<br />
* "Audio codec: AAC - ISO / IEC 14496-3 MPEG-4AAC, MP3 <br /> (However, there are some you can not play the video.)"<br />
* "Of 3D video at the time of upload format: .mkv (However, in order to play the video, you must format is converted in the upload to the site. In addition, even if it is converted you might not be able to play.)"<br />
* "It does not correspond to the plug-ins such as plug-in Adobe Flash."<br />
* "Use the Active Rating System of filtering function: Digital Arts, Inc. provides. At the time of access to Web content, and implementing the decision of whether access is permitted based on the category information. Feature that can limit access to Web content that may be inappropriate for viewing by the determination result."<br />
* "I will request the display of the mobile version page of the web page you are viewing request function the mobile version. (However, if the web page does not correspond to the mobile version of the page does not change the display.)"<br />
<br />
MJPEG + .avi is also supported.<br />
<br />
<br />
== Old3DS browser ==<br />
<br />
<br />
=== User-Agent and Browser Versions ===<br />
User-agent format: <code style="font-size:larger;">Mozilla/5.0 (Nintendo 3DS; U; ; <lang>) Version/<version>.<region></code>.<br />
<br />
<lang> is "en", "fr", etc. <region> is "US", "EU", etc. See below for <version>.<br />
{| class="wikitable" border="1"<br />
|-<br />
! Browser version<br />
! CDN Title-version<br />
! Network-only system-update version<br />
! Notes<br />
|-<br />
| 1.7412<br />
| v6<br />
| [[2.0.0-2|2.0.0-2]]<br />
| This was the initial version.<br />
|-<br />
| 1.7455<br />
| v1024<br />
| [[2.1.0-4]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too.<br />
|-<br />
| 1.7498<br />
| v2050<br />
| [[4.0.0-7]]<br />
| ExeFS .code was updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3075<br />
| [[5.0.0-11]]<br />
| ExeFS .code and icon were updated, both of the CROs(webkit/OSS) were updated too. The manual CFA was updated as well.<br />
|-<br />
| 1.7552<br />
| v3088<br />
| [[7.0.0-13]]<br />
| The main NCCH wasn't updated at all(same TMD contentID/content-hash as the previous version), only the manual CFA for this title was updated.<br />
|-<br />
| 1.7567<br />
| v4096<br />
| [[7.1.0-16]]<br />
| The CXI .code was updated, some data in the RomFS was updated(none of the CROs such as webkit.cro were updated). The manual CFA was updated too.<br />
|-<br />
| 1.7585<br />
| v5121<br />
| [[9.5.0-23]]<br />
| The CXI .code was updated, and the manual CFA was updated. RomFS changes:<br />
* "/browser/rootca.pem" updated<br />
* "/cro/oss.cro" updated<br />
* "/cro/static.crs" updated<br />
* "/cro/webkit.cro" updated<br />
* "/.crr/static.crr" updated<br />
* "/layout/dialogheader/WirelessSwitchOff.arc" was removed<br />
* "/layout/favorite/favicondata/KOR.arc" updated<br />
<br />
A vuln used in a public(at the time of this sysupdate) webkit exploit for spider was fixed, which also fixed the removewinframe exploit from [https://github.com/yellows8/3ds_webkithax here].<br />
|-<br />
| 1.7610<br />
| v6149<br />
| [[9.9.0-26]]<br />
| See below.<br />
|-<br />
| ?<br />
| v7168<br />
| [[10.2.0-28]]<br />
| See below.<br />
|}<br />
<br />
=== Old3DS v9.9 ===<br />
ExeFS:/.code was updated.<br />
<br />
The only changes in RomFS were file-updating, the following files were updated:<br />
/browser/rootca.pem<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
/message/CN_Simp_Chinese/spider.msbt<br />
/message/EU_Dutch/spider.msbt<br />
/message/EU_English/spider.msbt<br />
/message/EU_French/spider.msbt<br />
/message/EU_German/spider.msbt<br />
/message/EU_Italian/spider.msbt<br />
/message/EU_Portuguese/spider.msbt<br />
/message/EU_Russian/spider.msbt<br />
/message/EU_Spanish/spider.msbt<br />
/message/JP_Japanese/spider.msbt<br />
/message/KR_Hangeul/spider.msbt<br />
/message/TW_English/spider.msbt<br />
/message/TW_Trad_Chinese/spider.msbt<br />
/message/US_English/spider.msbt<br />
/message/US_French/spider.msbt<br />
/message/US_Portuguese/spider.msbt<br />
/message/US_Spanish/spider.msbt<br />
<br />
OSS diff for v9.5 and v9.9, without the .dox changes:<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
index be5ff09..55a7274 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/WKC/WebKit/WKC/webkit/WKCVersion.h<br />
@@ -29,7 +29,7 @@<br />
#define WKC_VERSION_CHECK(major, minor, micro) \<br />
(((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO))<br />
<br />
-#define WKC_CUSTOMER_RELEASE_VERSION "1.8.14"<br />
+#define WKC_CUSTOMER_RELEASE_VERSION "1.8.16"<br />
<br />
#define WKC_WEBKIT_VERSION "532.7"<br />
<br />
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
index da4127e..d03403e 100644<br />
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.5.0(23J_23U_23E_19K_18T_3C)/webkit/WebCore/rendering/RenderBox.cpp<br />
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_9.9.0/webkit/WebCore/rendering/RenderBox.cpp<br />
@@ -305,23 +305,23 @@ int RenderBox::scrollHeight() const<br />
<br />
int RenderBox::scrollLeft() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollXOffset() : 0;<br />
}<br />
<br />
int RenderBox::scrollTop() const<br />
{<br />
- return hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
+ return layer() && hasOverflowClip() ? layer()->scrollYOffset() : 0;<br />
}<br />
<br />
void RenderBox::setScrollLeft(int newLeft)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToXOffset(newLeft);<br />
}<br />
<br />
void RenderBox::setScrollTop(int newTop)<br />
{<br />
- if (hasOverflowClip())<br />
+ if (hasOverflowClip() && layer())<br />
layer()->scrollToYOffset(newTop);<br />
}<br />
<br />
=== Old3DS v10.2 ===<br />
The slider vuln from [https://github.com/yellows8/3ds_webkithax here] was fixed in the Old3DS browser it seems.<br />
<br />
The main codebin .text only increased by 0x10-bytes.<br />
<br />
The only changes in RomFS was that the following files were updated:<br />
/cro/oss.cro<br />
/cro/static.crs<br />
/cro/webkit.cro<br />
/.crr/static.crr<br />
<br />
== Forced system-update ==<br />
The Old3DS/New3DS Internet Browser updated with [[9.9.0-26]] now includes the following message string:<br />
In order to use the Internet <br />
browser, a system update <br />
is required.<br />
To perform a system update, <br />
select System Update from Other<br />
Settings in System Settings.<br />
<br />
This wasn't enforced(web-browser displaying the above message when the installed browser isn't the latest version) until October 26, 2015. In some cases this message isn't displayed(as in some systems never displayed the message yet), the cause is unknown. It's unknown how exactly this is handled.<br />
<br />
This message only triggers when attempting to load a web-page.<br />
<br />
The browser codebins starting with v9.9 now contain the following URL strings:<br />
* Old3DS: <nowiki>"https://cbvc.cdn.nintendo.net/CTR/1/<region>"</nowiki><br />
* New3DS: <nowiki>"https://cbvc.cdn.nintendo.net/SNAKE/1/<region>"</nowiki><br />
<br />
The <region> string is one of the following:<br />
* "JPN"<br />
* "USA"<br />
* "EUR"<br />
* "KOR"<br />
<br />
Starting with the browser from [[10.2.0-28]], the "1" in the above URLs were changed to "2".<br />
<br />
It is still possible to guard against this update by blocking the previous URLs using a proxy. However, it is not possible to make the message disappear or skip it if it appeared at least once.<br />
<br />
==Web Standards==<br />
*HTML 4.01<br />
*HTML 5 (120/400 score on [http://www.html5test.com HTML5Test.com])<br />
*XHTML 1.1<br />
*CSS 1<br />
*CSS 2.1<br />
*CSS 3 (some functionality is unavailable)<br />
*DOM Levels 1-3<br />
*ECMAScript (partial support for ECMA-262 5th Edition)<br />
*XMLHttpRequest Level 2<br />
*Canvas Element (some functionality is unavailable)<br />
<br />
==Protocols==<br />
*HTTP 1.0<br />
*HTTP 1.1<br />
*SSLv3<br />
*TLS 1.0<br />
<br />
==Image Formats==<br />
*[[File_Formats|MPO]]<br />
*GIF<br />
*JPEG<br />
*PNG<br />
*BMP<br />
*ICO (some files cannot be displayed)<br />
<br />
==Plug-Ins==<br />
<br />
Plug-ins (such as Adobe Flash) are not supported.<br />
<br />
==Other details==<br />
<br />
*It scored 90/100 on [http://acid3.acidtests.org/ Acid3] test<br />
*Images from the Internet can be saved to the [[SD Filesystem|SD Card]] and viewed using the [[Nintendo 3DS Camera]] application.<br />
*Images saved to an [[SD Filesystem|SD Card]] or to the Nintendo 3DS system memory can be uploaded to blogs or other sites that allow the uploading of photos using :<br />
<input type="file" /><br />
* HTML5Test.com say that Drag and drop is supported but it's not (code on WebKit is ready, but it's not implemented on interface of browser)<br />
<br />
==Tips==<br />
<br />
=== Detect User Agent ===<br />
<br />
To detect if the user agent is Nintendo 3DS Browser :<br />
<br />
<script type="text/javascript"><br />
if (navigator.userAgent.indexOf('Nintendo 3DS') == -1) { //If the UserAgent is not "Nintendo 3DS"<br />
location.replace('http://www.3dbrew.org'); //Redirect to an other page<br />
}<br />
</script><br />
<br />
* You can check <em>navigator.platform=="Nintendo 3DS"</em> as well.<br />
<br />
=== Scrolling ===<br />
<br />
Scrolling can be altered by modifying <em>document.body.scrollTop</em> and <em>document.body.scrollLeft</em>. However, there are drawbacks related to working with these properties:<br />
<br />
* Both properties return 0 when accessed<br />
* Setting one property resets the other property's scroll position<br />
<br />
In order to set both at the same time (without either resetting to 0), use <em>window.scrollTo</em>.<br />
<br />
=== Events ===<br />
==== Key Events ====<br />
The following buttons trigger the <em>onkeydown</em>, <em>onkeypress</em> and <em>onkeyup</em> events:<br />
<br />
{|class="wikitable" width="20%"<br />
! Code !! Button <br />
|-<br />
| 13 || A<br />
|-<br />
| 37 || Left<br />
|-<br />
| 38 || Up<br />
|-<br />
| 39 || Right<br />
|-<br />
| 40 || Down<br />
|}<br />
<br />
The events cannot have their default action cancelled. Other buttons do not trigger key events.<br />
<br />
==== Touch/Mouse Events ====<br />
<em>onmousedown</em>, <em>onmouseup</em> & <em>onclick</em> are all triggered by the browser. However, the <em>onmousedown</em> event doesn't trigger until you lift the stylus or you've held it on the screen for ~2 seconds—which is when text selection mode is activated—making it pretty much the same as <em>onmouseup</em>. The events cannot have their default action cancelled.<br />
<br />
The <em>onmousemove</em> and common touch/gesture events are not supported.<br />
<br />
== Screen Resolution ==<br />
<br />
The up screen resolution is 400×240. However, the viewable area in the browser is only <b>400×220</b>.<br />
<br />
The touch screen resolution is 320×240. However, the viewable area in the browser is only <b>320×212</b>.<br />
<br />
You can have a page span both screens. However, the browser will behave as if the bottom screen is the only active screen and the top screen is scrolled off. This is important when computing CSS coordinates. Items positioned from "bottom" will be positioned based on 220px and not the full 432px of both screens.<br />
<br />
== Using Both Screens ==<br />
<br />
Generally the easiest way to accomplish the correct layout is to create HTML elements that "contain" the top and bottom screens. Here's an example:<br />
<br />
<!DOCTYPE html><br />
<html><br />
<head><br />
<meta name="viewport" content="width=400"><br />
<style><br />
body{margin:0px;}<br />
#topscreen{width:400px;height:220px;overflow:hidden;}<br />
#bottomscreen{width:320px;height:212px;overflow:hidden;margin:0 auto;}<br />
</style><br />
</head><br />
<body><br />
&lt;div id="topscreen">Top Screen&lt;/div><br />
&lt;div id="bottomscreen">Bottom Screen&lt;/div><br />
</body><br />
</html><br />
<br />
This scheme allows the page to be easily manipulated through JavaScript. In order to have the window snap to the correct position, use the following JavaScript code:<br />
<br />
window.setInterval(function () {<br />
window.scrollTo(40, 220); <br />
}, 50);<br />
<br />
This automatically resets the position if the user accidentally scrolls the page.<br />
<br />
==Example Sites==<br />
<!-- If you have a website that demonstrates these techniques, place it here! --><br />
* [http://geekshadow.com/gaming/dev/weaponscolors/3DS/ Weapons and Colors] (Short URL: http://bit.ly/3DSwc)<br />
* [http://3ds.andysmith.co.uk/jFox.html jFox] (Short URL: http://bit.ly/iB7FqW)<br />
* [http://ditto3d.com/3ds Ditto3D] (Short URL: http://bit.ly/oVreWA)<br />
* [http://www.nintendo.com/3ds/internetbrowser/bookmarks Nintendo 3DS Bookmarks] - This is the first bookmark pre-installed in the browser.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=13378
Multi-threading
2015-09-26T21:53:58Z
<p>Lectem: fixed declaration/definition mistake</p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Declaration'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2(for the processorid validation check in the kernel).<br />
<br />
With the New3DS kernel: processorid must be less than or equal to <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>(for the processorid validation check in the kernel). When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range, otherwise error 0xE0E01BFD is returned: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Declaration'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Declaration'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Declaration'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Declaration'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Declaration'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Declaration'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Declaration'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
'''Details'''<br />
It seems that only the thread itself or one of its parent can get the ID. Calling this on the handle of a sibling or parent seems to always yield the ID 0.<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Declaration'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
''' Details '''<br />
This requests always return an error when called, it only checks if the handle is a thread or not. <br />
Hence, it will return 0xD8E007ED (BAD_ENUM) if the Handle is a Thread Handle, 0xD8E007F7 (BAD_HANDLE) if it isn't.<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Declaration'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
The cores are numbered from 0 to 1 for Old 3DS and 0 to 3 for the new 3DS.<br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Declaration'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Declaration'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Declaration'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
=== APT:SetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:SetApplicationCpuTimeLimit]].<br />
<br />
You are not able to use the system core (core1) by default. You have to first assign the amount of time dedicated to the system.<br />
The value is in percent, the higher it is, the more the system will be available for your application. <br />
<br />
For example if you set this value to 25%, it means that your application will be able to use 25% of the system core at most, even if you never issue system calls.<br />
<br />
If you set the value to a non-zero value, you will not be able to set it back to 0%.<br />
Keep in mind that if your application is heavily dependant on the system, setting a high value for your application might yield poorer performance than if you had set a low value.<br />
<br />
=== APT:GetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:GetApplicationCpuTimeLimit]].<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=CIA&diff=13204
CIA
2015-09-06T18:50:31Z
<p>Lectem: /* Tools */</p>
<hr />
<div>[[Category:File formats]]<br />
== Overview ==<br />
CIA stands for '''C'''TR '''I'''mportable '''A'''rchive. This format allows the installation titles to the 3DS. CIA files and titles on [[Title list|Nintendo's CDN]] contain identical data. As a consequence, valid CIA files can be generated from CDN content. This also means CIA files can contain anything that titles on Nintendo's CDN can contain. <br />
<br />
Under normal circumstances CIA files are used where downloading a title is impractical or not possible. Such as distributing a [[Download Play]] child, or installing forced Gamecard updates. Those CIA(s) are stored by the titles in question, in an auxiliary [[NCCH#CFA|CFA]] file.<br />
<br />
Development Units, are capable of manually installing CIA files via the [[3DS Development Unit Software#Dev Menu|Dev Menu]].<br />
<br />
== Format ==<br />
<br />
This is the current version of the CIA format, it was finalised in late 2010. (Older versions of the CIA format can be viewed on the [[Talk:CIA|Talk]] page)<br />
<br />
The CIA format has a similar structure to the [http://wiibrew.org/wiki/Wad WAD format].<br />
<br />
The file is represented in little-endian.<br />
<br />
The data is aligned in 64 byte blocks (if a content ends at the middle of the block, the next content will begin from a new block).<br />
<br />
=== CIA Header ===<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! START<br />
! SIZE<br />
! DESCRIPTION<br />
|-<br />
| 0x00<br />
| 0x04 <br />
| Archive Header Size (Usually = 0x2020 bytes)<br />
|-<br />
| 0x04<br />
| 0x02<br />
| Type<br />
|-<br />
| 0x06<br />
| 0x02<br />
| Version<br />
|- <br />
| 0x08 <br />
| 0x04<br />
| Certificate chain size <br />
|-<br />
| 0x0C <br />
| 0x04<br />
| [[Ticket]] size<br />
|-<br />
| 0x10 <br />
| 0x04<br />
| [[TMD]] file size<br />
|-<br />
| 0x14 <br />
| 0x04<br />
| Meta size (0 if no Meta data is present)<br />
|-<br />
| 0x18 <br />
| 0x08<br />
| Content size<br />
|-<br />
| 0x20<br />
| 0x2000<br />
| Content Index<br />
|}<br />
<br />
The order of the sections in the CIA file:<br />
* certificate chain<br />
* Ticket<br />
* TMD file data<br />
* Content file data<br />
* Meta file data (Not a necessary component) <br />
<br />
The contents (NCCH/SRL) are encrypted using 128-bit AES-CBC. The encryption uses the decrypted titlekey from the [[Ticket#Structure|ticket]], and the content index from the TMD padded with zeros as the IV.<br />
<br />
=== Certificate Chain ===<br />
<br />
There are three [[Certificates|certificates]] in this chain:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! CERTIFICATE<br />
! SIGNATURE TYPE<br />
! RETAIL CERT NAME<br />
! DEBUG CERT NAME<br />
! DESCRIPTION<br />
|-<br />
| CA<br />
| RSA-4096<br />
| CA00000003<br />
| CA00000004<br />
| Used to verify the Ticket/TMD Certificates<br />
|-<br />
| Ticket<br />
| RSA-2048<br />
| XS0000000c<br />
| XS00000009<br />
| Used to verify the Ticket signature<br />
|-<br />
| TMD<br />
| RSA-2048<br />
| CP0000000b<br />
| CP0000000a<br />
| Used to verify the TMD signature<br />
|}<br />
<br />
The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM.<br />
<br />
=== Meta ===<br />
<br />
The structure of this data is as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! START<br />
! SIZE<br />
! DESCRIPTION<br />
|-<br />
| 0x00<br />
| 0x180<br />
| Title ID dependency list - Taken from the application's [[NCCH#Extended Header|ExHeader]]<br />
|-<br />
| 0x180<br />
| 0x180<br />
| Reserved<br />
|-<br />
| 0x300<br />
| 0x4<br />
| Core Version<br />
|-<br />
| 0x304<br />
| 0xFC<br />
| Reserved<br />
|-<br />
| 0x400<br />
| 0x36C0<br />
| [[SMDH|Icon Data]](.ICN) - Taken from the application's [[ExeFS]]<br />
|}<br />
<br />
Obviously this section is not present in TWL CIA files, or any other CIA file which does not contain a [[NCCH#CXI|CXI]].<br />
<br />
== Tools ==<br />
<br />
* [https://github.com/3dshax/ctr/tree/master/ctrtool ctrtool] - Reading/Extraction of CIA files. This can only decrypt the title-key for development CIAs, since retail CIAs use the [[AES]] hardware key-scrambler for the common-key keyslot.<br />
<br />
* [https://github.com/ctrdev/ctrsdk/tree/master/tools/make_cia make_cia] - Generating CIA files. Requires CommonKey and ticket/TMD RSA-2048 private exponents.<br />
<br />
* [https://github.com/ctrdev/ctrsdk/tree/master/tools/make_cdn_cia make_cdn_cia] - (CMD)(Windows/Linux) Generates CIA files from CDN Content<br />
<br />
* [[makerom]] - Tool which can be used to create NCCH, CCI, and CIA files.<br />
<br />
== Title Key Encryption ==<br />
<br />
The unencrypted Title Key is used to encrypt the data in a CIA. The encrypted Title Key of a CIA can be found at offset 0x1BF in a CIA's Ticket.<br />
Each Title Key is encrypted with AES-CBC to get the encrypted Title Key.<br />
<br />
To encrypt an unencrypted title key, you need:<br />
<br />
* Common key (as byte array)<br />
* Title ID (as ulong)<br />
* (and of course the unencrypted title key you want to encrypt) (as byte array)<br />
<br />
The title key encryption process starts by converting the ulong (Title ID) into a byte array using by retrieving the bytes of the Title ID using BitConverter.GetBytes().<br />
If the converted bytes (title ID) are in Little Endian, reverse those bytes. (in C# it would be Array.Reverse(byte_array_from_bitconverter))<br />
This process makes the Title Key encryption IV.<br />
<br />
Next, after you've gotten your Title Key's IV, you can start your cryptography transformation. Using AESManaged, where:<br />
<br />
Key = Common Key<br />
<br />
IV = the byte array found in the conversion process above<br />
<br />
Mode = CipherMode.CBC<br />
<br />
Create the encryptor (AesManaged.CreateEncryptor(key, iv)) where the key and IV are both the same as above.<br />
<br />
Then, create a CryptoStream and a MemoryStream. The Crypto stream should start with the arguments (memorystream, aes_transform_from_above, CryptoStreamMode.Write).<br />
<br />
Write to the CryptoStream where buffer=unencrypted_titlekey, offset=0, and count=the length of the unencrypted title key.<br />
<br />
Use FlushFinalBlock() on the CryptoStream.<br />
<br />
Finally, then, the encrypted title key will be available from your memory <br />
stream. (to output the calculated encrypted title key as a byte array, you can use memorystream.ToArray(), for example)<br />
<br />
Example function: (C#)<br />
<br />
<pre><br />
public static byte[] EncryptMyTitleKey(byte[] commonKey, byte[] titleKey, ulong titleId)<br />
{<br />
// Make encryption IV<br />
byte[] titleidasbytes = new byte[0x10];<br />
for (int i = 0; i < 0x10; i++)<br />
{<br />
titleidasbytes[i] = 0;<br />
}<br />
byte[] bitBytes = BitConverter.GetBytes(titleId);<br />
if (BitConverter.IsLittleEndian)<br />
{<br />
Array.Reverse(bitBytes);<br />
}<br />
bitBytes.CopyTo(titleidasbytes, 0);<br />
// Encrypt<br />
ICryptoTransform transform = new AesManaged { Key = commonKey, IV = titleidasbytes, Mode = CipherMode.CBC }.CreateEncryptor(commonKey, titleidasbytes);<br />
MemoryStream memstream = new MemoryStream();<br />
CryptoStream cryptostream = new CryptoStream(memstream, transform, CryptoStreamMode.Write);<br />
cryptostream.Write(titleKey, 0, titleKey.Length);<br />
cryptostream.FlushFinalBlock();<br />
return memstream.ToArray();<br />
}<br />
</pre></div>
Lectem
https://www.3dbrew.org/w/index.php?title=Homebrew_Libraries_and_Tools&diff=13203
Homebrew Libraries and Tools
2015-09-06T18:48:20Z
<p>Lectem: Added makerom and bannertool</p>
<hr />
<div>This is a list of libraries and tools that can be used to develop 3DS Homebrew.<br />
<br />
==List==<br />
<br />
===Libraries===<br />
{| class="wikitable" border="1" width="100%"<br />
! width="20%" | Name<br />
! width="50%" | Description<br />
! width="10%" | Author<br />
! width="10%" | Download<br />
! width="10%" | Open-Source<br />
|-<br />
| [https://github.com/smealum/ctrulib ctrulib]<br />
| C library for writing user mode ARM11 code for the 3DS (CTR) <br />
| [https://twitter.com/smealum smea] et al.<br />
| [[Setting_up_Development_Environment|See here]]<br />
| Yes<br />
|-<br />
| [https://github.com/xerpi/sf2dlib sf2dlib]<br />
| Simple and Fast 2D library for the Nintendo 3DS (using ctrulib)<br />
| [https://github.com/xerpi xerpi]<br />
| [https://github.com/xerpi/sf2dlib/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/cpp3ds/gl3ds gl3ds]<br />
| OpenGL implementation for Nintendo 3DS using ctrulib<br />
| [https://github.com/Cruel Cruel] et al.<br />
| [https://github.com/cpp3ds/gl3ds/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/machinamentum/Caelina Caelina]<br />
| An OpenGL implementation for (N)3DS<br />
| [https://github.com/machinamentum machinamentum]<br />
| [https://github.com/machinamentum/Caelina/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/Myriachan/libkhax libkhax]<br />
| Library for modifying kernel memory on a certain handheld game console.<br />
| [https://github.com/Myriachan Myria] et al.<br />
| [https://github.com/Myriachan/libkhax/archive/master.zip Here]<br />
| Yes<br />
|}<br />
<br />
===Tools===<br />
{| class="wikitable" border="1" width="100%"<br />
! width="20%" | Name<br />
! width="50%" | Description<br />
! width="10%" | Author<br />
! width="10%" | Download<br />
! width="10%" | Open-Source<br />
|-<br />
| [http://devkitpro.org/ devkitARM]<br />
| GCC-based toolchain tuned for homebrew development for ARM-based consoles.<br />
| [https://github.com/WinterMute WinterMute] et al.<br />
| [[Setting_up_Development_Environment|See here]]<br />
| [https://github.com/devkitPro Yes]<br />
|-<br />
| [https://github.com/smealum/aemstro aemstro]<br />
| Set of tools used to disassemble and assemble shader code for DMP's MAESTRO shader extension used in the 3DS's PICA200 GPU<br />
| [https://twitter.com/smealum smea]<br />
| [https://github.com/smealum/aemstro/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/fincs/picasso picasso]<br />
| Homebrew PICA200 shader assembler<br />
| [https://github.com/fincs fincs]<br />
| [https://github.com/fincs/picasso/releases Here]<br />
| Yes<br />
|-<br />
| [http://4dsdev.org/thread.php?id=14 nihstro]<br />
| 3DS shader assembler and disassembler <br />
| [https://github.com/neobrain neobrain]<br />
| [http://4dsdev.org/thread.php?id=14 Here]<br />
| [https://github.com/neobrain/nihstro Yes]<br />
|-<br />
| [https://github.com/Lectem/3ds-cmake 3ds-cmake]<br />
| CMake files for devkitARM and 3DS homebrew development<br />
| [https://github.com/Lectem Lectem]<br />
| [https://github.com/Lectem/3ds-cmake/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/profi200/Project_CTR/archive/master.zip makerom]<br />
| Tool which can be used to create NCCH, CCI, and CIA files. <br />
| [http://3dbrew.org/wiki/User:3dsguy 3dsguy] maintained by [https://github.com/profi200 profi200]<br />
| [https://github.com/profi200/Project_CTR/archive/master.zip Here]<br />
| Yes<br />
|-<br />
| [https://github.com/Steveice10/bannertool bannertool]<br />
| Tool to create NCCH banners<br />
| [https://github.com/Steveice10 Steveice10]<br />
| [https://github.com/Steveice10/bannertool/archive/master.zip Here]<br />
| Yes<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU_Textures&diff=12916
GPU Textures
2015-07-07T20:25:51Z
<p>Lectem: /* Texture parameters */</p>
<hr />
<div>This page describes the [[GPU_Commands|GPU commands]] used for textures.<br />
<br />
== General information ==<br />
Individual texels in a texture are laid out in memory as a [http://en.wikipedia.org/wiki/Z-order_curve Z-order curve].<br />
<br />
== Texture unit setup: Register 0x80 ==<br />
Register 0x80 is used to enable individual texture units.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable texture unit 0.<br />
|-<br />
| 1<br />
| Enable texture unit 1.<br />
|-<br />
| 2<br />
| Enable texture unit 2.<br />
|}<br />
<br />
== Configuration of texture unit 0 ==<br />
{| class="wikitable" border="1"<br />
! Register ID<br />
! Description<br />
|-<br />
| 0x0081<br />
| Border color (unverified)<br />
|-<br />
| 0x0082<br />
| Bits 16-31 are the texture width. Bits 0-15 are the texture height. The maximum texture size in either direction is 1024.<br />
|-<br />
| 0x0083<br />
| Texture parameters (filtering, wrapping), see below.<br />
|-<br />
| 0x0084<br />
| LOD setup?<br />
|-<br />
| 0x0085<br />
| Physical address of texture data (divided by 8).<br />
|-<br />
| 0x0086<br />
| Physical address of texture data for cube mapping?<br />
|-<br />
| 0x0087<br />
| Physical address of texture data for cube mapping?<br />
|-<br />
| 0x0088<br />
| Physical address of texture data for cube mapping?<br />
|-<br />
| 0x0089<br />
| Physical address of texture data for cube mapping?<br />
|-<br />
| 0x008A<br />
| Physical address of texture data for cube mapping?<br />
|-<br />
| 0x008B<br />
| Shadow related?<br />
|-<br />
| 0x008E<br />
| Texture format (see below)<br />
|}<br />
<br />
== Configuration of texture units 1 and 2 ==<br />
Texture units 1 and 2 use a configuration block similar to the one of texture unit 0. They are based at registers 0x0091 and 0x0099.<br />
<br />
{| class="wikitable" border="1"<br />
! Index word<br />
! Description<br />
|-<br />
| 0-4<br />
| Same as for texture unit 0<br />
|-<br />
| 5<br />
| Texture format (see below)<br />
|}<br />
<br />
== Configuration of texture unit 3 ==<br />
The configuration block for texture unit 3 seems to be vastly different from the other texture units. Instead, registers 0x00A8 through 0x00B7 are used to configure procedural texturing features.<br />
<br />
== Texture parameters ==<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
! GL parameter name<br />
|-<br />
| 0<br />
| Normally this is value 0.<br />
| <br />
|-<br />
| 1<br />
| 0 = GL_NEAREST, 1 = GL_LINEAR.<br />
| GL_TEXTURE_MAG_FILTER<br />
|-<br />
| 2<br />
| 1 = GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, or GL_LINEAR_MIPMAP_LINEAR. Value zero otherwise.<br />
| GL_TEXTURE_MIN_FILTER<br />
|-<br />
| 3<br />
| Unused?<br />
| ?<br />
|-<br />
| 5-4<br />
| 2 = texture color type 0xC, 0 otherwise.(Enable/disable texture data compression?) 0 = unknown, 1 = unknown, 3 = same effect as value 2.<br />
| <br />
|-<br />
| 7-6<br />
| Unused<br />
|-<br />
| 11-8<br />
| 0 = GL_CLAMP_TO_EDGE, 1=GL_CLAMP_TO_BORDER, 2=GL_REPEAT, 3=GL_MIRRORED_REPEAT.<br />
| GL_TEXTURE_WRAP_S<br />
|-<br />
| 15-12<br />
| Same values as GL_TEXTURE_WRAP_S.<br />
| GL_TEXTURE_WRAP_T<br />
|-<br />
| 24<br />
| 1 = GL_NEAREST_MIPMAP_LINEAR, or GL_LINEAR_MIPMAP_LINEAR. Value zero otherwise.<br />
| GL_TEXTURE_MIN_FILTER<br />
|-<br />
| 27-25<br />
| Unused?<br />
|-<br />
| 30-28<br />
| When some flag=1: value1=GL_TEXTURE_2D, value0 when the input parameter is not GL_TEXTURE_2D. When some flag=0: 0=GL_TEXTURE_2D, 1-4=unknown.<br />
| ?<br />
|-<br />
| 31<br />
| Unused?<br />
| ?<br />
|}<br />
<br />
== Texture color types ==<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
! GL Format<br />
! GL Data Type<br />
|-<br />
| 0x0<br />
| RGBA8888<br />
| GL_RGBA<br />
| GL_UNSIGNED_BYTE<br />
|-<br />
| 0x1<br />
| RGB888<br />
| GL_RGB<br />
| GL_UNSIGNED_BYTE<br />
|-<br />
| 0x2<br />
| RGBA5551<br />
| GL_RGBA<br />
| GL_UNSIGNED_SHORT_5_5_5_1<br />
|-<br />
| 0x3<br />
| RGB565<br />
| GL_RGB<br />
| GL_UNSIGNED_SHORT_5_6_5<br />
|-<br />
| 0x4<br />
| RGBA4444<br />
| GL_RGBA<br />
| GL_UNSIGNED_SHORT_4_4_4_4<br />
|-<br />
| 0x5<br />
| IA8<br />
| GL_LUMINANCE_ALPHA<br />
| GL_UNSIGNED_BYTE<br />
|-<br />
| 0x6<br />
| HILO8<br />
| <br />
| <br />
|-<br />
| 0x7<br />
| I8<br />
| GL_LUMINANCE<br />
| GL_UNSIGNED_BYTE<br />
|-<br />
| 0x8<br />
| A8<br />
| GL_ALPHA<br />
| GL_UNSIGNED_BYTE<br />
|-<br />
| 0x9<br />
| IA44<br />
| GL_LUMINANCE_ALPHA<br />
| GL_UNSIGNED_BYTE_4_4_EXT<br />
|-<br />
| 0xA<br />
| I4<br />
| <br />
|<br />
|-<br />
| 0xB<br />
| A4<br />
| GL_ALPHA<br />
| GL_UNSIGNED_NIBBLE_EXT<br />
|-<br />
| 0xC<br />
| ETC1<br />
| GL_ETC1_RGB8_OES<br />
| <br />
|-<br />
| 0xD<br />
| ETC1A4<br />
|<br />
| <br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12880
Multi-threading
2015-06-27T22:32:19Z
<p>Lectem: /* CreateThread */</p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <2.<br />
<br />
With the New3DS kernel: processorid must be inferior to <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range, otherwise error 0xE0E01BFD is returned: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
'''Details'''<br />
It seems that only the thread itself or one of its parent can get the ID. Calling this on the handle of a sibling or parent seems to always yield the ID 0.<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
''' Details '''<br />
This requests always return an error when called, it only checks if the handle is a thread or not. <br />
Hence, it will return 0xD8E007ED (BAD_ENUM) if the Handle is a Thread Handle, 0xD8E007F7 (BAD_HANDLE) if it isn't.<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
The cores are numbered from 0 to 1 for Old 3DS and 0 to 3 for the new 3DS.<br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
=== APT:SetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:SetApplicationCpuTimeLimit]].<br />
<br />
You are not able to use the system core (core1) by default. You have to first assign the amount of time dedicated to the system.<br />
The value is in percent, the higher it is, the more the system will be available for your application. <br />
<br />
For example if you set this value to 25%, it means that your application will be able to use 25% of the system core at most, even if you never issue system calls.<br />
<br />
If you set the value to a non-zero value, you will not be able to set it back to 0%.<br />
Keep in mind that if your application is heavily dependant on the system, setting a high value for your application might yield poorer performance than if you had set a low value.<br />
<br />
=== APT:GetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:GetApplicationCpuTimeLimit]].<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12826
GPU/Commands
2015-06-14T00:21:46Z
<p>Lectem: </p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_FRAGMENT_PRIMARY_COLOR<br />
| Sum of ambient, emissive, and diffuse components of lightning stage<br />
|-<br />
| 0x2<br />
| GL_FRAGMENT_SECONDARY_COLOR<br />
| Specular component of the lightning stage + ?<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC_R<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC_G<br />
|-<br />
| 0x9<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC_B<br />
|-<br />
| 0xD<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
Note : GL_SRC_X and GL_ONE_MINUS_SRC_X where X=R|G|B are the same as GL_SRC_COLOR and GL_ONE_MINUS_SRC_COLOR but will use only the corresponding color component.<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC_R<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x4<br />
| GL_SRC_G<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0x6<br />
| GL_SRC_B<br />
|-<br />
| 0x7<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-18<br />
| Unused<br />
|-<br />
| 17-16<br />
| Alpha output scale factor<br />
|-<br />
| 15-2<br />
| Unused<br />
|-<br />
| 1-0<br />
| Color output scale factor<br />
|}<br />
<br />
{| class="wikitable" border="1"<br />
! Scale value<br />
! Corresponding factor<br />
|-<br />
| 0x0<br />
| 1.0<br />
|-<br />
| 0x1<br />
| 2.0<br />
|-<br />
| 0x2<br />
| 4.0<br />
|}<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12825
GPU/Commands
2015-06-13T23:47:18Z
<p>Lectem: /* Param4 format for command 0x00C0 */ output scale + texenv buffers?</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_FRAGMENT_PRIMARY_COLOR<br />
| Sum of ambient, emissive, and diffuse components of lightning stage<br />
|-<br />
| 0x2<br />
| GL_FRAGMENT_SECONDARY_COLOR<br />
| Specular component of the lightning stage + ?<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC_R<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC_G<br />
|-<br />
| 0x9<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC_B<br />
|-<br />
| 0xD<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
Note : GL_SRC_X and GL_ONE_MINUS_SRC_X where X=R|G|B are the same as GL_SRC_COLOR and GL_ONE_MINUS_SRC_COLOR but will use only the corresponding color component.<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC_R<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x4<br />
| GL_SRC_G<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0x6<br />
| GL_SRC_B<br />
|-<br />
| 0x7<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-18<br />
| To be determined.<br />
|-<br />
| 17-16<br />
| Alpha output scale factor<br />
|-<br />
| 15-2<br />
| To be determined<br />
|-<br />
| 1-0<br />
| Color output scale factor<br />
|}<br />
<br />
{| class="wikitable" border="1"<br />
! Scale value<br />
! Corresponding factor<br />
|-<br />
| 0x0<br />
| 1.0<br />
|-<br />
| 0x1<br />
| 2.0<br />
|-<br />
| 0x2<br />
| 4.0<br />
|}<br />
<br />
Probably also has something to do with Texenv buffer registers [[:GPU_Internal_Registers#GPUREG_00FD|PICA_REG_TEX_ENV_BUF_COLOR]] and [[GPU_Internal_Registers#GPUREG_00E0|PICA_REG_TEX_ENV_BUF_INPUT]].<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12824
GPU/Commands
2015-06-13T23:18:16Z
<p>Lectem: /* Param1 field1 values for command 0x00C0 */</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_FRAGMENT_PRIMARY_COLOR<br />
| Sum of ambient, emissive, and diffuse components of lightning stage<br />
|-<br />
| 0x2<br />
| GL_FRAGMENT_SECONDARY_COLOR<br />
| Specular component of the lightning stage + ?<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC_R<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC_G<br />
|-<br />
| 0x9<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC_B<br />
|-<br />
| 0xD<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
Note : GL_SRC_X and GL_ONE_MINUS_SRC_X where X=R|G|B are the same as GL_SRC_COLOR and GL_ONE_MINUS_SRC_COLOR but will use only the corresponding color component.<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC_R<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x4<br />
| GL_SRC_G<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0x6<br />
| GL_SRC_B<br />
|-<br />
| 0x7<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-0<br />
| To be determined<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12823
GPU/Commands
2015-06-13T23:16:28Z
<p>Lectem: /* Param1 field0 values for command 0x00C0 */ Added single component color sources</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_FRAGMENT_PRIMARY_COLOR<br />
| Sum of ambient, emissive, and diffuse components of lightning stage<br />
|-<br />
| 0x2<br />
| GL_FRAGMENT_SECONDARY_COLOR<br />
| Specular component of the lightning stage + ?<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC_R<br />
|-<br />
| 0x5<br />
| GL_ONE_MINUS_SRC_R<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC_G<br />
|-<br />
| 0x9<br />
| GL_ONE_MINUS_SRC_G<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC_B<br />
|-<br />
| 0xD<br />
| GL_ONE_MINUS_SRC_B<br />
|}<br />
Note : GL_SRC_X and GL_ONE_MINUS_SRC_X where X=R|G|B are the same as GL_SRC_COLOR and GL_ONE_MINUS_SRC_COLOR but will use only the corresponding color component.<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x4<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC2_RGB<br />
|-<br />
| 0x7<br />
| ?<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-0<br />
| To be determined<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12822
GPU/Commands
2015-06-13T22:59:27Z
<p>Lectem: Added lightning stage component sources</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_FRAGMENT_PRIMARY_COLOR<br />
| Sum of ambient, emissive, and diffuse components of lightning stage<br />
|-<br />
| 0x2<br />
| GL_FRAGMENT_SECONDARY_COLOR<br />
| Specular component of the lightning stage + ?<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x9<br />
| ?<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC2_RGB<br />
|-<br />
| 0xD<br />
| ?<br />
|}<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x4<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC2_RGB<br />
|-<br />
| 0x7<br />
| ?<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-0<br />
| To be determined<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12796
Multi-threading
2015-06-07T09:43:03Z
<p>Lectem: /* GetThreadInfo */</p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range, otherwise error 0xE0E01BFD is returned: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
'''Details'''<br />
It seems that only the thread itself or one of its parent can get the ID. Calling this on the handle of a sibling or parent seems to always yield the ID 0.<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
''' Details '''<br />
This requests always return an error when called, it only checks if the handle is a thread or not. <br />
Hence, it will return 0xD8E007ED (BAD_ENUM) if the Handle is a Thread Handle, 0xD8E007F7 (BAD_HANDLE) if it isn't.<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
The cores are numbered from 0 to 1 for Old 3DS and 0 to 3 for the new 3DS.<br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
=== APT:SetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:SetApplicationCpuTimeLimit]].<br />
<br />
You are not able to use the system core (core1) by default. You have to first assign the amount of time dedicated to the system.<br />
The value is in percent, the higher it is, the more the system will be available for your application. <br />
<br />
For example if you set this value to 25%, it means that your application will be able to use 25% of the system core at most, even if you never issue system calls.<br />
<br />
If you set the value to a non-zero value, you will not be able to set it back to 0%.<br />
Keep in mind that if your application is heavily dependant on the system, setting a high value for your application might yield poorer performance than if you had set a low value.<br />
<br />
=== APT:GetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:GetApplicationCpuTimeLimit]].<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GSP_Shared_Memory&diff=12751
GSP Shared Memory
2015-06-03T18:04:45Z
<p>Lectem: /* Trigger Memory Fill */ control bits</p>
<hr />
<div>This page describes the structure of the GSP [[GSPGPU:RegisterInterruptRelayQueue|shared]] memory. GX commands and framebuffer info is stored here, and other unknown data.<br />
<br />
<br />
=Interrupt info=<br />
The Interrupt info structure is located at sharedmemvadr + process_gsp_index*0x40.<br />
<br />
It is a list of interrupts (id's 0-6 exist).<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Byte<br />
! Description<br />
|-<br />
| 0x0<br />
| Index of the last processed data (field size is 0x33) (must be updated manually)<br />
|-<br />
| 0x1<br />
| To be processed datafields, (max 0x20 for PDC interrupts else the missed PDC filds are used,max 0x34 for all other if more interrupts happen and the Errorflag is 0 the Errorflag is set to 1)<br />
|-<br />
| 0x2<br />
| Errorflag (if the first bit of Errorflag is set future PDC interrupts are ignored)<br />
|-<br />
| 0x3<br />
| not used<br />
|-<br />
| 0x4-0x7<br />
| missed PDC0<br />
|-<br />
| 0x8-0xB<br />
| missed PDC1<br />
|-<br />
| 0xC-0x3F<br />
| u8 Interrupttypefield (0=PSC0, 1=PSC1, 2=PDC0/VBlankTop (sent to all threads), 3=PDC1/VBlankBottom (sent to all threads), 4=PPF, 5=P3D, 6=DMA)<br />
|}<br />
<br />
=Framebuffer info=<br />
The framebuffer info structure for the main LCD is located at sharedmemvadr + 0x200 + threadindex*0x80. The framebuffer info structure for the sub LCD is located at sharedmemvadr + 0x240 + threadindex*0x80.<br />
<br />
==Framebuffer info header==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Byte<br />
! Description<br />
|-<br />
| 0<br />
| Framebuffer info [[GSPGPU:SetBufferSwap|entry]] index<br />
|-<br />
| 1<br />
| Flag<br />
|-<br />
| 3-2<br />
| Padding<br />
|}<br />
<br />
When a process sets this framebuffer info, it sets index to <nowiki>(index+1) & 1</nowiki>. Then it writes the framebuffer info entry, and sets flag to value 1. The GSP module loads this framebuffer info entry data into GSP state once the [[GPU]] finishes processing GX commands 3 or 4. Once the GSP module finishes loading this framebuffer info, it sets flag to value 0, then it will not load the framebuffer info again until flag is value 1. After loading this entry data into GSP state, the GSP module then writes this framebuffer state to the [[LCD]] registers. GSP module automatically updates the LCD framebuffer registers each time GX commands 3 or 4 finish, even when this shared memory data was not updated by the application.(GSP module toggles the active framebuffer register when automatically updating LCD registers, when shared memory data is not used)<br />
<br />
The two 0x1C-byte framebuffer info entries are located at framebufferinfo+4.<br />
<br />
=3D Slider and 3D [[GSPGPU:SetLedForceOff|LED]]=<br />
See [[Configuration Memory]].<br />
<br />
=Command Buffer Header=<br />
<br />
The command buffer is located at sharedmem + 0x800 + [[GSPGPU:RegisterInterruptRelayQueue|threadindex]]*0x200. After writing the command data to shared memory, [[GSPGPU:TriggerCmdReqQueue|TriggerCmdReqQueue]] must be used to trigger GSP processing for the command when the total commands field is value 1.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Byte<br />
! Description<br />
|-<br />
| 0<br />
| Current command index. This index is updated by GSP module after loading the command data, right before the command is processed. When this index is updated by GSP module, the total commands field is decreased by one as well.<br />
|-<br />
| 1<br />
| Total commands to process, must not be value 0 when GSP module handles commands. This must be <=15 when writing a command to shared memory. This is incremented by the application when writing a command to shared memory, after increasing this value [[GSPGPU:TriggerCmdReqQueue|TriggerCmdReqQueue]] is only used if this field is value 1.<br />
|-<br />
| 2<br />
| Must not be value 1. When the error-code u32 is set, this u8 is set to value 0x80.<br />
|-<br />
| 3<br />
| Bit0 must not be set<br />
|-<br />
| 4<br />
| u32 Error code for the last GX command which failed<br />
|}<br />
<br />
=Command Header=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Byte<br />
! Description<br />
|-<br />
| 0<br />
| Command ID<br />
|-<br />
| 2-1<br />
| ?<br />
|-<br />
| 3<br />
| When non-zero GSP module may check flags for the specified cmdID, command handling is aborted when the flags are set. The corresponding flag for each CmdID is set once the command is handled by GSP module, this flag is likely cleared once the GPU finishes processing the command.<br />
|}<br />
<br />
The command is located at cmdbuf + 0x20 + cmdindex*0x20, the size of each command is 0x20-bytes. The command parameters are located at command+4. Addresses specified in parameters are application vaddrs, these are usually located in either the process GSP [[Memory_layout|heap]] or VRAM. For applications these addresses are normally located in the GSP heap, while for other processes these addresses are located in VRAM. Addresses/sizes specified in parameters except for cmd0 and cmd5 must be 8-byte [[GPU|aligned]].<br />
<br />
=Commands=<br />
<br />
== Trigger DMA Request ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x00<br />
|-<br />
| 1<br />
| Source address<br />
|-<br />
| 2<br />
| Destination address<br />
|-<br />
| 3<br />
| Size<br />
|-<br />
| 6-4<br />
| Unused<br />
|-<br />
| 7<br />
| Flag: when source buffer is not located in VRAM and this flag is non-zero, svcFlushProcessDataCache is used with the source buffer.<br />
|}<br />
<br />
This command is normally used to DMA data from the application GSP [[Memory_layout|heap]] to VRAM.<br />
<br />
== Trigger Command List Processing ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x01<br />
|-<br />
| 1<br />
| Buffer address<br />
|-<br />
| 2<br />
| Buffer size<br />
|-<br />
| 3<br />
| Flag, bit0 is written to GSP module state<br />
|-<br />
| 6-4<br />
| Unused<br />
|-<br />
| 7<br />
| When non-zero, call svcFlushProcessDataCache() with the specified buffer<br />
|}<br />
<br />
This command converts the specified address to a physical address, then writes the physical address and size to the [[GPU]] registers at 0x1EF018E0. This buffer contains [[GPU_Commands|GPU commands]].<br />
<br />
== Trigger Memory Fill ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x02<br />
|-<br />
| 1<br />
| Buf0 start address (0 = don't fill anything)<br />
|-<br />
| 2<br />
| Buf0 value<br />
|-<br />
| 3<br />
| Buf0 end address<br />
|-<br />
| 4<br />
| Buf1 start address (0 = don't fill anything)<br />
|-<br />
| 5<br />
| Buf1 value<br />
|-<br />
| 6<br />
| Buf1 end address<br />
|-<br />
| 7<br />
| The low u16 is control0, while the high u16 is control1<br />
|}<br />
<br />
This commands converts the specified addresses to physical addresses, then writes these addresses and the specified parameters to the [[GPU]] registers at 0x1EF00010 and 0x1EF00020. Doing so fills the specified buffers with the associated 4-byte value. This is used to clear GPU framebuffers.<br />
The associated buffer address must not be <= to the main buffer address, thus the associated buffer address must not be zero as well. When the bufX address is zero, processing for the bufX parameters is skipped.<br />
<br />
The values of control0 and control1 give information about the type of memory fill and if it has to be triggered. By default the fill pattern is set to 16bits.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| trigger<br />
|-<br />
| 8<br />
| Fill pattern of 24bits<br />
|-<br />
| 9<br />
| Fill pattern of 32bits<br />
|}<br />
<br />
== Trigger Display Transfer ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x03<br />
|-<br />
| 1<br />
| Input framebuffer address<br />
|-<br />
| 2<br />
| Output framebuffer address<br />
|-<br />
| 3<br />
| Input framebuffer [[GPU|dimensions]]<br />
|-<br />
| 4<br />
| Output framebuffer dimensions<br />
|-<br />
| 5<br />
| [[GPU|Flags]], for applications this is 0x1001000 for the main screen, and 0x1000 for the sub screen.<br />
|-<br />
| 7-6<br />
| Unused<br />
|}<br />
<br />
This command converts the specified addresses to physical addresses, then writes these physical addresses and parameters to the [[GPU]] registers at 0x1EF00C00. This GPU command copies the already rendered framebuffer data from the input GPU framebuffer address to the specified output LCD framebuffer. The input framebuffer is normally located in VRAM.<br />
<br />
The GPU color buffer is stored in the same Z-curve (tiled) format as textures. By default, SetDisplayTransfer converts the given buffer from the tiled format to a linear format adapted to the LCD framebuffers.<br />
<br />
Display transfers are performed asynchronously, so after requesting a display transfer you should wait for the PPF interrupt to fire before reading the output data.<br />
<br />
Some color formats seem to require specific input / output sizes when performing a display transfer, doing an RGB5A1->RGBA4 display transfer would never fire the PPF interrupt with a 32x32 buffer, increasing the buffer to 128x128 made it fire correctly.<br />
<br />
== Trigger Texture Copy ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x04<br />
|-<br />
| 1<br />
| Input buffer address<br />
|-<br />
| 2<br />
| Output buffer address<br />
|-<br />
| 3<br />
| Size<br />
|-<br />
| 4<br />
| Input [[GPU|dimensions]]?<br />
|-<br />
| 5<br />
| Output dimensions?<br />
|-<br />
| 6<br />
| Flags, normally this is 0x8, with bit2 optionally set when either of the dimensions fields are set.<br />
|-<br />
| 7<br />
| Unused<br />
|}<br />
<br />
This command is similar to cmd3. It also writes to the [[GPU]] registers at 0x1EF00C00. It's unknown where the difference is.<br />
<br />
== Prepare Command List Processing ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| u8 CommandID is 0x05<br />
|-<br />
| 1<br />
| Buf0 address<br />
|-<br />
| 2<br />
| Buf0 size<br />
|-<br />
| 3<br />
| Buf1 address<br />
|-<br />
| 4<br />
| Buf1 size<br />
|-<br />
| 5<br />
| Buf2 address<br />
|-<br />
| 6<br />
| Buf2 size<br />
|-<br />
| 7<br />
| Unused<br />
|}<br />
<br />
The application buffer addresses specified in the parameters are used with [[SVC|svcFlushProcessDataCache]]. The input buf0 size must not be zero. When buf1 size is zero, svcFlushProcessDataCache() for buf1 and buf2 are skipped. When buf2 size is zero, svcFlushProcessDataCache() for buf2 is skipped.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12731
Multi-threading
2015-06-01T16:33:15Z
<p>Lectem: </p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range, otherwise error 0xE0E01BFD is returned: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
'''Details'''<br />
It seems that only the thread itself or one of its parent can get the ID. Calling this on the handle of a sibling or parent seems to always yield the ID 0.<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
{| class="wikitable" border="1"<br />
! ThreadInfoType value<br />
! Description<br />
|-<br />
| ?<br />
| ?<br />
|}<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
The cores are numbered from 0 to 1 for Old 3DS and 0 to 3 for the new 3DS.<br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
=== APT:SetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:SetApplicationCpuTimeLimit]].<br />
<br />
You are not able to use the system core (core1) by default. You have to first assign the amount of time dedicated to the system.<br />
The value is in percent, the higher it is, the more the system will be available for your application. <br />
<br />
For example if you set this value to 25%, it means that your application will be able to use 25% of the system core at most, even if you never issue system calls.<br />
<br />
If you set the value to a non-zero value, you will not be able to set it back to 0%.<br />
Keep in mind that if your application is heavily dependant on the system, setting a high value for your application might yield poorer performance than if you had set a low value.<br />
<br />
=== APT:GetApplicationCpuTimeLimit ===<br />
<br />
See [[APT:GetApplicationCpuTimeLimit]].<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Ninjhax&diff=12713
Ninjhax
2015-05-28T19:26:46Z
<p>Lectem: /* Service access */</p>
<hr />
<div>ninjhax is an exploit by smea for the game Cubic Ninja. It was released on November 20th, 2014. It can be used on all 3DS firmware versions from 4.0 up to and including 9.2.0-20. It was partially patched in [[9.3.0-21|9.3.0-X]] (only system flaws used by ninjhax were fixed, the game haxx itself was not affected).<br />
<br />
When triggered, it will boot a [[3DSX_Format | 3dsx-file]] from the sdcard root called "boot.3dsx". This file is usually the [[Homebrew Launcher]], which in turn can be used to launch other games/apps from the (micro)SD card.<br />
<br />
==Installation==<br />
<br />
Visit [http://smealum.net/ninjhax/ here] for instructions on how to install Ninjhax!<br />
<br />
==Service access==<br />
<br />
ninjhax gives developers access to a number of services. These include :<br />
<br />
* ac:u<br />
* APT:U<br />
* boss:U<br />
* cam:u<br />
* cecd:u<br />
* cfg:u<br />
* dlp:FKCL<br />
* dlp:SRVR<br />
* dsp::DSP<br />
* frd:u<br />
* fs:USER<br />
* gsp::Gpu<br />
* hid:USER<br />
* http:C<br />
* ir:u<br />
* mic:u<br />
* ndm:u<br />
* <nowiki>news:u</nowiki><br />
* nwm::UDS<br />
* ptm:u<br />
* pxi:dev<br />
* soc:U<br />
* ssl:C<br />
* y2r:u<br />
<br />
Additionally, Old 3DS models (3DS, 3DS XL and 2DS) are given access to the following :<br />
<br />
* csnd:SND<br />
<br />
In contrast, New 3DS models (New 3DS, New 3DS XL) get access to :<br />
<br />
* am:app<br />
* ir:rst<br />
* l2b2:u<br />
* l2b:u<br />
* mvd:STD<br />
* nim:aoc<br />
* y2r2:u<br />
<br />
<br />
The normal service used for accessing [[Circle Pad Pro]] is not accessible: [[IR_Services|ir:USER]].<br />
<br />
The codes of the allowed [[SVC]]s are : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2A 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D<br />
<br />
==Limitations==<br />
<br />
At the moment, ninjhax only allows users to access 64MB of RAM, including on the New 3DS. This may change in the future.<br />
<br />
As there is currently no good way to use the DSP from homebrew, sound output is not yet possible on the New 3DS. At the moment, there is also no known way of running code on the New 3DS's extra CPU cores under ninjhax, though it is possible to use 80% of the system core's time using [[APT:SetApplicationCpuTimeLimit]] rather than 30% as was the case on the Old 3DS.<br />
<br />
==Capabilities==<br />
* All SD and NAND [[extdata]] is accessible via the main extdata [[FS:OpenArchive|archive]](R/W). Note that the [[FS:OpenArchive|ExtSaveData-for-BOSS]] archive is not accessible.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12707
Multi-threading
2015-05-26T00:02:35Z
<p>Lectem: /* GetThreadId */</p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
'''Details'''<br />
It seems that only the thread itself or one of its parent can get the ID. Calling this on the handle of a sibling or parent seems to always yield the ID 0.<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
{| class="wikitable" border="1"<br />
! ThreadInfoType value<br />
! Description<br />
|-<br />
| ?<br />
| ?<br />
|}<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=SVC&diff=12704
SVC
2015-05-25T20:44:56Z
<p>Lectem: moved thread related stuff to Multi-threading page</p>
<hr />
<div>= System calls =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Id<br />
! NF ARM11<br />
! NF ARM9<br />
! TF ARM11<br />
! Description<br />
! scope="col" width="200" | Notes<br />
|-<br />
| 0x01 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ControlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions)<br />
| Outaddr is usually the same as the input addr0.<br />
|-<br />
| 0x02 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryMemory(MemoryInfo* info, PageInfo* out, u32 Addr)<br />
|<br />
|-<br />
| 0x03 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| void ExitProcess(void)<br />
|<br />
|-<br />
| 0x04 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessAffinityMask(u8* affinitymask, Handle process, s32 processorcount)<br />
|<br />
|-<br />
| 0x05 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessAffinityMask(Handle process, u8* affinitymask, s32 processorcount)<br />
|<br />
|-<br />
| 0x06 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessIdealProcessor(s32 *idealprocessor, Handle process)<br />
|<br />
|-<br />
| 0x07 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessIdealProcessor(Handle process, s32 idealprocessor)<br />
|<br />
|-<br />
| 0x08 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#CreateThread|CreateThread]](Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid)<br />
|<br />
|-<br />
| 0x09 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| void [[Multi-threading#ExitThread|ExitThread]](void)<br />
|<br />
|-<br />
| 0x0A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| void [[Multi-threading#SleepThread|SleepThread]](s64 nanoseconds)<br />
|<br />
|-<br />
| 0x0B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#GetThreadPriority|GetThreadPriority]](s32* priority, Handle thread)<br />
|<br />
|-<br />
| 0x0C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#SetThreadPriority|SetThreadPriority]](Handle thread, s32 priority)<br />
|<br />
|-<br />
| 0x0D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#GetThreadAffinityMask|GetThreadAffinityMask]](u8* affinitymask, Handle thread, s32 processorcount)<br />
|<br />
|-<br />
| 0x0E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#SetThreadAffinityMask|SetThreadAffinityMask]](Handle thread, u8* affinitymask, s32 processorcount)<br />
| Replaced with a stub in ARM11 NATIVE_FIRM kernel beginning with [[8.0.0-18]].<br />
|-<br />
| 0x0F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#GetThreadIdealProcessor|GetThreadIdealProcessor]](s32* processorid, Handle thread)<br />
|<br />
|-<br />
| 0x10 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#SetThreadIdealProcessor|SetThreadIdealProcessor]](Handle thread, s32 processorid)<br />
| Replaced with a stub in ARM11 NATIVE_FIRM kernel beginning with [[8.0.0-18]].<br />
|-<br />
| 0x11 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| s32 GetCurrentProcessorNumber(void)<br />
|<br />
|-<br />
| 0x12 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result Run(Handle process, StartupInfo* info)<br />
| This starts the main() thread. Buf+0 is main-thread priority, Buf+4 is main-thread stack-size.<br />
|-<br />
| 0x13 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#CreateMutex|CreateMutex]](Handle* mutex, bool initialLocked)<br />
|<br />
|-<br />
| 0x14 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#ReleaseMutex|ReleaseMutex]](Handle mutex)<br />
|<br />
|-<br />
| 0x15 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#CreateSemaphore|CreateSemaphore]](Handle* semaphore, s32 initialCount, s32 maxCount)<br />
|<br />
|-<br />
| 0x16 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#ReleaseSemaphore|ReleaseSemaphore]](s32* count, Handle semaphore, s32 releaseCount)<br />
|<br />
|-<br />
| 0x17 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#CreateEvent|CreateEvent]](Handle* event, ResetType resettype)<br />
|<br />
|-<br />
| 0x18 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#SignalEvent|SignalEvent]](Handle event)<br />
|<br />
|-<br />
| 0x19 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#ClearEvent|ClearEvent]](Handle event)<br />
|<br />
|-<br />
| 0x1A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateTimer(Handle* timer, ResetType resettype)<br />
|<br />
|-<br />
| 0x1B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result SetTimer(Handle timer, s64 initial, s64 interval)<br />
|<br />
|-<br />
| 0x1C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CancelTimer(Handle timer)<br />
|<br />
|-<br />
| 0x1D <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ClearTimer(Handle timer)<br />
|<br />
|-<br />
| 0x1E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 mypermission, u32 otherpermission)<br />
|<br />
|-<br />
| 0x1F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission)<br />
|<br />
|-<br />
| 0x20 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result UnmapMemoryBlock(Handle memblock, u32 addr)<br />
|<br />
|-<br />
| 0x21 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateAddressArbiter(Handle* arbiter)<br />
|<br />
|-<br />
| 0x22 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x23 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CloseHandle(Handle handle)<br />
|<br />
|-<br />
| 0x24 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result WaitSynchronization1(Handle handle, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x25 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result WaitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x26 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SignalAndWait(s32* out, Handle signal, Handle* handles, s32 handleCount, bool waitAll, s64 nanoseconds)<br />
| Stubbed<br />
|-<br />
| 0x27 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result DuplicateHandle(Handle* out, Handle original)<br />
|<br />
|-<br />
| 0x28 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| s64 GetSystemTick(void) (This returns the total CPU ticks elapsed since the CPU was powered-on)<br />
|<br />
|-<br />
| 0x29 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetHandleInfo(s64* out, Handle handle, HandleInfoType type)<br />
|<br />
|-<br />
| 0x2A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetSystemInfo(s64* out, SystemInfoType type, s32 param)<br />
|<br />
|-<br />
| 0x2B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetProcessInfo(s64* out, Handle process, ProcessInfoType type)<br />
|<br />
|-<br />
| 0x2C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#GetThreadInfo|GetThreadInfo]](s64* out, Handle thread, ThreadInfoType type)<br />
|<br />
|-<br />
| 0x2D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ConnectToPort(Handle* out, const char* portName)<br />
|<br />
|-<br />
| 0x2E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest1(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x2F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest2(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x30 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest3(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x31 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest4(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x32 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest(Handle session)<br />
|<br />
|-<br />
| 0x33 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result OpenProcess(Handle* process, u32 processId)<br />
|<br />
|-<br />
| 0x34 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#OpenThread|OpenThread]](Handle* thread, Handle process, u32 threadId)<br />
|<br />
|-<br />
| 0x35 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: green" | Yes<br />
| Result GetProcessId(u32* processId, Handle process)<br />
|<br />
|-<br />
| 0x36 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#GetProcessIdOfThread|GetProcessIdOfThread]](u32* processId, Handle thread)<br />
|<br />
|-<br />
| 0x37 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[Multi-threading#GetThreadId|GetThreadId]](u32* threadId, Handle thread)<br />
|<br />
|-<br />
| 0x38 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimit(Handle* resourceLimit, Handle process)<br />
|<br />
|-<br />
| 0x39 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimitLimitValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)<br />
|<br />
|-<br />
| 0x3A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimitCurrentValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)<br />
|<br />
|-<br />
| 0x3B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result [[Multi-threading#GetThreadContext|GetThreadContext]](ThreadContext* context, Handle thread)<br />
| Stubbed<br />
|-<br />
| 0x3C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Break(BreakReason)<br />
|<br />
|-<br />
| 0x3D <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| OutputDebugString(void const, int)<br />
| Does nothing on non-debug units.<br />
|-<br />
| 0x3E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| ControlPerformanceCounter(unsigned long long, int, unsigned int, unsigned long long)<br />
|<br />
|- style="border-top: double"<br />
| 0x47 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions)<br />
| Setting name=NULL creates a private port not accessible from svcConnectToPort.<br />
|-<br />
| 0x48 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateSessionToPort(Handle* session, Handle port)<br />
|<br />
|-<br />
| 0x49 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateSession(Handle* sessionServer, Handle* sessionClient)<br />
|<br />
|-<br />
| 0x4A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result AcceptSession(Handle* session, Handle port)<br />
|<br />
|-<br />
| 0x4B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive1(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4C <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive2(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive3(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive4(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
|<br />
|-<br />
| 0x50 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result BindInterrupt(Interrupt name, Handle syncObject, s32 priority, bool isManualClear)<br />
|<br />
|-<br />
| 0x51 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result UnbindInterrupt(Interrupt name, Handle syncObject)<br />
|<br />
|-<br />
| 0x52 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result InvalidateProcessDataCache(Handle process, void* addr, u32 size)<br />
|<br />
|-<br />
| 0x53 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StoreProcessDataCache(Handle process, void const* addr, u32 size)<br />
|<br />
|-<br />
| 0x54 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result FlushProcessDataCache(Handle process, void const* addr, u32 size)<br />
|<br />
|-<br />
| 0x55 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StartInterProcessDma(Handle* dma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, const DmaConfig& config)<br />
|<br />
|-<br />
| 0x56 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StopDma(Handle dma)<br />
|<br />
|-<br />
| 0x57 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetDmaState(DmaState* state, Handle dma)<br />
|<br />
|-<br />
| 0x58<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| RestartDma(nn::Handle, void *, void const*, unsigned int, signed char)<br />
|<br />
|- style="border-top: double"<br />
| 0x60 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result DebugActiveProcess(Handle* debug, u32 processID)<br />
|<br />
|-<br />
| 0x61 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result BreakDebugProcess(Handle debug)<br />
|<br />
|-<br />
| 0x62 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result TerminateDebugProcess(Handle debug)<br />
|<br />
|-<br />
| 0x63 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessDebugEvent(DebugEventInfo* info, Handle debug)<br />
|<br />
|-<br />
| 0x64 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ContinueDebugEvent(Handle debug, u32 flags)<br />
|<br />
|-<br />
| 0x65 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount)<br />
|<br />
|-<br />
| 0x66 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetThreadList(s32* threadCount, u32* threadIds, s32 threadIdMaxCount, Handle domain)<br />
|<br />
|-<br />
| 0x67 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, u32 controlFlags)<br />
|<br />
|-<br />
| 0x68 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, u32 controlFlags)<br />
|<br />
|-<br />
| 0x69 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryDebugProcessMemory(MemoryInfo* blockInfo, PageInfo* pageInfo, Handle process, u32 addr)<br />
|<br />
|-<br />
| 0x6A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size)<br />
|<br />
|-<br />
| 0x6B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result WriteProcessMemory(Handle debug, void const* buffer, u32 addr, u32 size)<br />
|<br />
|-<br />
| 0x6C <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetHardwareBreakPoint(s32 registerId, u32 control, u32 value)<br />
|<br />
|-<br />
| 0x6D<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| [[Multi-threading#GetDebugThreadParam|GetDebugThreadParam]](long long *, int *, nn::Handle, unsigned int, nn::dmnt::DebugThreadParam)<br />
| Disabled on regular kernel.<br />
|- style="border-top: double"<br />
| 0x70<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ControlProcessMemory(Handle KProcess, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int Type, unsigned int Permissions)<br />
|<br />
|-<br />
| 0x71<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result MapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr)<br />
|<br />
|-<br />
| 0x72<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result UnmapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr)<br />
|<br />
|-<br />
| 0x73<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateCodeSet(Handle* handle_out, struct CodeSetInfo, u32 code_ptr, u32 ro_ptr, u32 data_ptr)<br />
|<br />
|-<br />
| 0x74<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result RandomStub()<br />
| Stubbed<br />
|-<br />
| 0x75<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateProcess(Handle* handle_out, Handle codeset_handle, u32 arm11kernelcaps_ptr, u32 arm11kernelcaps_num)<br />
|<br />
|-<br />
| 0x76<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| TerminateProcess(Handle)<br />
|<br />
|-<br />
| 0x77<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessResourceLimits(Handle KProcess, Handle KResourceLimit)<br />
| <br />
|-<br />
| 0x78<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateResourceLimit(Handle *KResourceLimit)<br />
|<br />
|-<br />
| 0x79<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetResourceLimitValues(Handle res_limit, LimitableResource* resource_type_list, s64* resource_list, u32 count)<br />
|<br />
|-<br />
| 0x7A<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: green" | Yes<br />
| AddCodeSegment (unsigned int Addr, unsigned int Size)<br />
| Stubbed on NATIVE_FIRM beginning with [[2.0.0-2]]. Used during TWL_FIRM boot.<br />
|-<br />
| 0x7B<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| Backdoor(unsigned int CodeAddress)<br />
| This is used on ARM9 NATIVE_FIRM. No ARM11 processes have access to it without some form of kernelhax.<br />
|-<br />
| 0x7C<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| KernelSetState(unsigned int Type, unsigned int Param0, unsigned int Param1, unsigned int Param2)<br />
| The type determines the meaning of each param<br />
|-<br />
| 0x7D<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryProcessMemory(MemInfo *Info, unsigned int *Out, Handle KProcess, unsigned int Addr)<br />
|<br />
|- style="border-top: double"<br />
| 0xFF<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| ???<br />
| Debug related? The svcaccesscontrol mask doesn't apply for this SVC. Stubbed on ARM9 NATIVE_FIRM.<br />
|}<br />
NF: NATIVE_FIRM. TF: TWL_FIRM.<br />
<br />
Note that "stubbed" here means that the SVC only returns an error, as in the following snippet:<br />
<br />
<pre>ROM:FFF04D98 LDR R0, =0xF8C007F4<br />
ROM:FFF04D9C BX LR</pre><br />
= Types and structures =<br />
<br />
== enum MemoryState ==<br />
{| class="wikitable" border="1"<br />
! Memory state flags<br />
! Value<br />
|-<br />
| FREE<br />
| 0<br />
|-<br />
| RESERVED<br />
| 1<br />
|-<br />
| IO<br />
| 2<br />
|-<br />
| STATIC<br />
| 3<br />
|-<br />
| CODE<br />
| 4<br />
|-<br />
| PRIVATE<br />
| 5<br />
|-<br />
| SHARED<br />
| 6<br />
|-<br />
| CONTINUOUS<br />
| 7<br />
|-<br />
| ALIASED<br />
| 8<br />
|-<br />
| ALIAS<br />
| 9<br />
|-<br />
| ALIAS CODE<br />
| 10<br />
|-<br />
| LOCKED<br />
| 11<br />
|}<br />
<br />
== enum PageFlags ==<br />
{| class="wikitable" border="1"<br />
! Page flags<br />
! Bit<br />
|-<br />
| LOCKED<br />
| 0<br />
|-<br />
| CHANGED<br />
| 1<br />
|}<br />
<br />
== enum MemoryOperation ==<br />
<br />
{| class="wikitable" border="1"<br />
! Memory operation<br />
! Id<br />
|-<br />
| FREE<br />
| 1<br />
|-<br />
| RESERVE<br />
| 2<br />
|-<br />
| COMMIT<br />
| 3<br />
|-<br />
| MAP<br />
| 4<br />
|-<br />
| UNMAP<br />
| 5<br />
|-<br />
| PROTECT<br />
| 6<br />
|-<br />
| REGION APP<br />
| 0x100<br />
|-<br />
| REGION SYSTEM<br />
| 0x200<br />
|-<br />
| REGION BASE<br />
| 0x300<br />
|-<br />
| LINEAR<br />
| 0x10000<br />
|}<br />
<br />
The LINEAR memory-operation indicates that the mapped physical address is always MappedVAddr+0x0C000000, thus this memory can be used for hardware devices' DMA(such as the [[GPU]]). Addr0+size for this must be within the 0x14000000-0x1C000000 range when Addr0 is non-zero(Addr1 must be zero), Addr0 isn't actually used by svcControlMemory for mapping memory: Addr0 is not used by the kernel after doing address-range checks. The kernel determines what physical-address to use by allocating memory from FCRAM(about the same way as other memory), which is then used to determine the virtual-address.<br />
<br />
[[8.0.0-18]] added a new memory mapping(0x30000000-0x38000000) for LINEAR memory, this replaces the original mapping for newer titles. The kernel uses the new mapping when the process memory-region is BASE, or when the process kernel-release-version field is >=0x022c(2.44 / system-version [[8.0.0-18]]).<br />
<br />
The input mem-region value for svcControlMemory is only used(when non-zero) when the PID is value 1, for the [[FIRM]] ARM11 "loader" module.<br />
<br />
== enum MemoryPermission ==<br />
<br />
{| class="wikitable" border="1"<br />
! Memory permission<br />
! Id<br />
|-<br />
| NONE<br />
| 0<br />
|-<br />
| R<br />
| 1<br />
|-<br />
| W<br />
| 2<br />
|-<br />
| RW<br />
| 3<br />
|-<br />
| X<br />
| 4<br />
|-<br />
| RX<br />
| 5<br />
|-<br />
| WX<br />
| 6<br />
|-<br />
| RWX<br />
| 7<br />
|-<br />
| DONTCARE<br />
| 0x10000000<br />
|}<br />
<br />
== enum ResetType ==<br />
<br />
{| class="wikitable" border="1"<br />
! Reset type<br />
! Id<br />
|-<br />
| ONESHOT<br />
| 0<br />
|-<br />
| STICKY<br />
| 1<br />
|-<br />
| PULSE<br />
| 2<br />
|}<br />
<br />
== struct MemoryInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Base process virtual address<br />
|-<br />
| u32<br />
| Size<br />
|-<br />
| u32<br />
| Permission<br />
|-<br />
| enum MemoryState<br />
| State<br />
|}<br />
<br />
== struct PageInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Flags<br />
|}<br />
<br />
== struct StartupInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| s32<br />
| Priority<br />
|-<br />
| u32<br />
| Stack size<br />
|-<br />
| s32<br />
| argc<br />
|-<br />
| s16*<br />
| argv<br />
|-<br />
| s16*<br />
| envp<br />
|}<br />
<br />
== enum ArbitrationType ==<br />
{| class="wikitable" border="1"<br />
! Address arbitration type<br />
! Value<br />
|-<br />
| FREE<br />
| 0<br />
|-<br />
| AQUIRE<br />
| 1<br />
|-<br />
| KERNEL2<br />
| 2<br />
|-<br />
| AQUIRE_TIMEOUT<br />
| 3<br />
|-<br />
| KERNEL4<br />
| 4<br />
|}<br />
<br />
== enum BreakReason ==<br />
{| class="wikitable" border="1"<br />
! Break Reason<br />
! Value<br />
|-<br />
| PANIC<br />
| 0<br />
|-<br />
| ASSERT<br />
| 1<br />
|-<br />
| USER<br />
| 2<br />
|}<br />
<br />
== struct CodeSetInfo ==<br />
All addresses are given virtual for the process to be created.<br />
All sizes are given in 0x1000-pages.<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u8[8]<br />
| Codeset Name<br />
|-<br />
| u16<br />
| Unknown, this is written to field 0x5A of KCodeSet<br />
|-<br />
| u16<br />
| Unknown/padding<br />
|-<br />
| u32<br />
| Unknown/padding<br />
|-<br />
| u32<br />
| .text addr<br />
|-<br />
| u32<br />
| .text size<br />
|-<br />
| u32<br />
| .rodata start<br />
|-<br />
| u32<br />
| .rodata size<br />
|-<br />
| u32<br />
| RW addr (.data + .bss)<br />
|-<br />
| u32<br />
| RW size (.data + .bss)<br />
|-<br />
| u32<br />
| Total .text pages<br />
|-<br />
| u32<br />
| Total .rodata pages<br />
|-<br />
| u32<br />
| Total RW pages (.data + .bss)<br />
|-<br />
| u32<br />
| Unknown/padding<br />
|-<br />
| u8[8]<br />
| Program ID<br />
|}<br />
<br />
== struct DebugEventInfo ==<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Event type<br />
|-<br />
| u32<br />
| Thread ID (not used in all events)<br />
|-<br />
| u32[2]<br />
| Unknown/padding<br />
|-<br />
| u32[6]<br />
| Event-specific data (see below)<br />
|}<br />
<br />
{| class="wikitable" border="1"<br />
! Event type<br />
! Id<br />
|-<br />
| PROCESS<br />
| 0<br />
|-<br />
| CREATE THREAD<br />
| 1<br />
|-<br />
| EXIT THREAD<br />
| 2<br />
|-<br />
| EXIT PROCESS<br />
| 3<br />
|-<br />
| EXCEPTION<br />
| 4<br />
|-<br />
| DLL LOAD<br />
| 5<br />
|-<br />
| DLL UNLOAD<br />
| 6<br />
|-<br />
| SCHEDULE IN<br />
| 7<br />
|-<br />
| SCHEDULE OUT<br />
| 8<br />
|-<br />
| SYSCALL IN<br />
| 9<br />
|-<br />
| SYSCALL OUT<br />
| 10<br />
|-<br />
| OUTPUT STRING<br />
| 11<br />
|-<br />
| MAP<br />
| 12<br />
|}<br />
<br />
=== PROCESS event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u64<br />
| Program ID<br />
|-<br />
| char[8]<br />
| Process name<br />
|-<br />
| u32<br />
| Process ID<br />
|-<br />
| u32<br />
| 0 = newly created process, 1 = attached process<br />
|}<br />
<br />
=== CREATE THREAD event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Creator thread ID<br />
|-<br />
| u32<br />
| Base address (?)<br />
|-<br />
| u32<br />
| Entrypoint<br />
|}<br />
<br />
=== EXIT THREAD/PROCESS events ===<br />
<br />
A single u32 reason field is used.<br />
<br />
Thread exit reasons:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| (None)<br />
| 0<br />
|-<br />
| TERMINATE<br />
| 1<br />
|-<br />
| EXIT PROCESS<br />
| 2<br />
|-<br />
| TERMINATE PROCESS<br />
| 3<br />
|}<br />
<br />
Process exit reasons:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| (None)<br />
| 0<br />
|-<br />
| TERMINATE<br />
| 1<br />
|-<br />
| UNHANDLED EXCEPTION<br />
| 2<br />
|}<br />
<br />
=== EXCEPTION event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Exception type<br />
|-<br />
| u32<br />
| Exception address<br />
|-<br />
| u32<br />
| Argument (type-specific)<br />
|}<br />
<br />
Exception types:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
! Argument<br />
|-<br />
| UNDEFINED INSTRUCTION<br />
| 0<br />
| (None)<br />
|-<br />
| (Unknown)<br />
| 1<br />
| (None)<br />
|-<br />
| (Unknown, mem-related)<br />
| 2<br />
| Address<br />
|-<br />
| (Unknown, mem-related)<br />
| 3<br />
| Address<br />
|-<br />
| ATTACH BREAK<br />
| 4<br />
| (None)<br />
|-<br />
| BREAKPOINT<br />
| 5<br />
| (None)<br />
|-<br />
| USER BREAK<br />
| 6<br />
| User break type<br />
|-<br />
| DEBUGGER BREAK<br />
| 7<br />
| (None)<br />
|-<br />
| UNDEFINED SYSCALL<br />
| 8<br />
| Attempted syscall ID<br />
|}<br />
<br />
User break types:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| PANIC<br />
| 0<br />
|-<br />
| ASSERT<br />
| 1<br />
|-<br />
| USER<br />
| 2<br />
|}<br />
<br />
=== SCHEDULER/SYSCALL IN/OUT events ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u64<br />
| Clock tick<br />
|-<br />
| u32<br />
| Syscall (only for SYSCALL events)<br />
|}<br />
<br />
=== OUTPUT STRING event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| String address<br />
|-<br />
| u32<br />
| String size<br />
|}<br />
<br />
=== MAP event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Mapped address<br />
|-<br />
| u32<br />
| Mapped size<br />
|-<br />
| u32<br />
| MemoryPermission<br />
|-<br />
| u32<br />
| MemoryState<br />
|}<br />
<br />
= Processes =<br />
Each process can only use SVCs which are enabled in the [[NCCH#CXI|exheader]] for this process. The ARM11 kernel SVC handler checks whether the SVC is enabled in the syscall access control mask stored on the SVC-mode stack, when the SVC isn't enabled a kernelpanic() is triggered. Each process has a separate SVC-mode stack, this stack and the syscall access mask stored here is initialized when the process is started. Applications normally only have access to SVCs <=0x3D, however not all SVCs <=0x3D are accessible to the application. The majority of the SVCs accessible to applications are unused by the application.<br />
<br />
Each process has a separate handle-table, the size of this table is stored in the exheader. The handles in a handle-table can't be used in the context of other processes, since those handles don't exist in other handle-tables.<br />
<br />
0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for the current KThread.<br />
<br />
Calling svcBreak on retail will only terminate the process which called this SVC.<br />
<br />
= Threads =<br />
For svcCreateThread the input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread, only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
= Memory Mapping =<br />
ControlMemory and MapMemoryBlock can be used to map memory pages, these two SVCs only support mapping execute-never R/W pages. The input permissions parameter for these SVCs must therefore be <=3, where value zero is used when un-mapping memory. Furthermore it appears that only regular heap pages can be mirrored (it won't work for TLS, stack, .data, .text, for example).<br />
<br />
Bitmask 0xF00 for ControlMemory parameter MemoryType is the memory-type, when this is zero the memory-type is loaded from the kernel flags stored in the exheader ARM11 kernel descriptors, for the process using the SVC.<br />
<br />
ControlMemory parameter MemoryType with value 0x10003 is used for mapping the GSP [[Memory_layout|heap]]. The low 8-bits are the type: 1 is for un-mapping memory, 3 for mapping memory. Type4 is used to mirror the RW memory at Addr1, to Addr0. Type4 will return an error if Addr1 is located in read-only memory. Addr1 is not used for type1 and type3.<br />
<br />
The ARM11 kernel does not allow processes to create shared memory blocks via svcCreateMemoryBlock, when the process memorytype(from the kernel flags stored in the exheader kernel descriptor) is the application memorytype, and when addr=0. It's unknown how the kernel handles addr=0 when the memorytype is not the application memorytype. When addr is non-zero, it must be located in memory which is already mapped. Furthermore, it appears that only regular heap pages (allocated using svcControlMemory op=COMMIT) are accepted as valid addrs.<br />
<br />
ControlProcessMemory maps memory in the specified process, this is the only SVC which allows mapping executable memory. Format of the permissions field for memory mapping SVCs: bit0=R, bit1=W, bit2=X. Type6 sets the Addr0 memory permissions to the input permissions, for already mapped memory. Type is the MemoryOperation enum, without the memory-type/memory-region. ControlProcessMemory only supports type4, type5, and type6. ControlProcessMemory does not support using the current KProcess handle alias.<br />
<br />
MapProcessMemory maps RW memory starting at address 0x00100000 in the specified KProcess, at the specified StartAddr in the current process. MapProcessMemory then maps 0x08000000 in the specified process, to StartAddr+0x7f00000 in the current process. UnmapProcessMemory unmaps the memory which was mapped by MapProcessMemory.<br />
<br />
Note that with the MAP MemoryOperation, the kernel will refuse to MAP memory for the specified addr1, when addr1 was already used with another MAP operation as addr1. The kernel also doesn't allow memory to be freed via the FREE MemoryOperation, when other virtual-memory is mapped to this same memory(when the MAP MemoryOperation was used with this memory with addr1).<br />
<br />
= DMA =<br />
The CTRSDK code for using svcStartInterProcessDma will execute svcBreak when svcStartInterProcessDma returns an error(except for certain error value(s)). Therefore on retail, triggering a svcStartInterProcessDma via a system-module which results in an error from svcStartInterProcessDma will result in the system-module terminating.<br />
<br />
==DmaConfig==<br />
Size of struct is 24 bytes.<br />
<br />
struct DmaConfig {<br />
sint8_t channel_sel; // @0 Selects which DMA channel to use: 0-7, -1 = don't care.<br />
uint8_t unk1; // @1 Accepted values: 0,2,4,8.<br />
uint8_t flags; // @2 bit0: DST_CFG, bit1: SRC_CFG, bit2: SHALL_BLOCK, bit3: ???, bit6: DST_ALT_CFG, bit7: SRC_ALT_CFG<br />
uint8_t unk2;<br />
uint8_t dst_cfg[10];<br />
// @5 Accepted values (u8): 4, 8, 12, 15.<br />
// @15 Accepted values (u8): 4, 8, 12, 15.<br />
uint8_t src_cfg[10]; // @14<br />
}<br />
<br />
If SRC_CFG/DST_CFG is set in the flags field, the configuration for src/dst is loaded from src_cfg/dst_cfg respectively. If the *_ALT_CFG flag is set same thing goes, except byte0 of each cfg is forced to 0xFF. ALT_CFG has priority over CFG.<br />
<br />
If CFG or ALT_CFG is not set, default configuration is loaded:<br />
FF 0F 80 00 00 00 80 00 00 00<br />
<br />
If SHALL_BLOCK is set, the thread will sleep until the DMA engine is ready. If not set, the SVC will return 0xD04007F0 if the DMA channel is busy.<br />
<br />
The format of src_cfg/dst_cfg is unknown, but both have the same format. Checks suggest that the second byte of cfg equalling 4 means NO_INCREMENT (don't increment after read/write).<br />
<br />
= Debugging =<br />
DebugActiveProcess is used to attach to a process for debugging. This SVC can only be used when the target process' ARM11 descriptors stored in the exheader have the kernel flag for "Enable debug" set. Otherwise when that flag is clear, the kernel flags for the process using this SVC must have the "Force debug" flag set.<br />
<br />
= KernelSetState =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Type<br />
! Enabled for the NATIVE_FIRM ARM11 kernel<br />
! Enabled for the TWL_FIRM ARM11 kernel<br />
! Description<br />
|-<br />
| 0<br />
| Yes<br />
| No<br />
| This initializes the programID for launching [[FIRM]], then triggers launching [[FIRM]]. Param0 is unused. Param1 is the programID-low, and the programID-high is 0x00040138. Param2 is used only with the [[New_3DS]] kernel, pm-module uses value 0 with this. With New3DS kernel, it forces the programIDlow to be the New3DS NATIVE_FIRM, when the input programIDlow is for the Old3DS NATIVE_FIRM and Param2==0.<br />
|-<br />
| 1<br />
| Yes<br />
| Yes<br />
| Unknown, does nothing with the TWL_FIRM ARM11 kernel.<br />
|-<br />
| 2<br />
| Yes<br />
| Yes<br />
| ?<br />
|-<br />
| 3<br />
| Yes<br />
| No<br />
| This used for initializing the 0x1000-byte buffer used by the launched [[FIRM]]. Param2 is unused. When Param0 is value 1, this buffer is copied to the beginning of FCRAM at 0xF0000000, and Param1 is unused. When Param0 is value 0, this kernel buffer is mapped to process address Param1.<br />
|-<br />
| 4<br />
| No<br />
| Yes<br />
| Param0-Param3 are unused. This unmaps(?) the following virtual memory by writing value physaddr(where physaddr base is 0x80000000) to the L1 MMU table entries: 0x00300000..0x04300000, 0x08000000..0x0FE00000, and 0x10000000..0xF8000000.<br />
|-<br />
| 5<br />
| Yes<br />
| Yes<br />
| ?<br />
|-<br />
| 6<br />
| Yes<br />
| No<br />
| Debug related?<br />
|-<br />
| 7<br />
| Yes<br />
| No<br />
| This triggers ARM11 kernel [[I2C]] code, Param0-Param3 are unused. This ARM11 kernel I2C code will never return. Device address 0x4a via the second I2C bus is used here. This triggers a hardware system reboot via poking an I2C MCU register: register address 0x20 is written to with value 4.<br />
|-<br />
| 8<br />
| Yes<br />
| No<br />
| Alternate unused FIRM launch code-path, with different [[PXI]] FIFO word constants.<br />
|-<br />
| 9<br />
| Yes, implemented at some point after system-version v4.5.<br />
| ?<br />
| Unknown<br />
|-<br />
| 10<br />
| Yes<br />
| ?<br />
| Only available for the [[New_3DS]] kernel. It's unknown what this is used for.<br />
|}<br />
<br />
= GetSystemInfo =<br />
{| class="wikitable" border="1"<br />
! SystemInfoType value<br />
! s32 param<br />
! Description<br />
|-<br />
| 0<br />
| 0<br />
| This writes the total used memory size in the following memory regions to out: APPLICATION, SYSTEM, and BASE.<br />
|-<br />
| 0<br />
| 1<br />
| This writes the total used memory size in the APPLICATION memory region to out.<br />
|-<br />
| 0<br />
| 2<br />
| This writes the total used memory size in the SYSTEM memory region to out.<br />
|-<br />
| 0<br />
| 3<br />
| This writes the total used memory size in the BASE memory region to out.<br />
|-<br />
| 25<br />
| Unused<br />
| This writes the total number of threads which were directly launched by the kernel, to out.<br />
|-<br />
| 26<br />
| Unused<br />
| This writes the total number of processes which were directly launched by the kernel, to out. For the NATIVE_FIRM/SAFE_MODE_FIRM ARM11 kernel, this is normally 5, for processes sm, fs, pm, loader, and pxi.<br />
|}<br />
<br />
= GetProcessInfo =<br />
Input:<br />
R0 = unused<br />
R1 = Handle process<br />
R2 = ProcessInfoType type<br />
<br />
Output:<br />
R0 = Result<br />
R1 = output value lower word<br />
R2 = output value upper word<br />
<br />
{| class="wikitable" border="1"<br />
! ProcessInfoType value<br />
! Available since system version<br />
! Description<br />
|-<br />
| 9-19<br />
| [[8.0.0-18]]<br />
| This only returns error 0xD8E007ED.<br />
|-<br />
| 20<br />
| [[8.0.0-18]]<br />
| low u32 = (0x20000000 - <LINEAR virtual-memory base for this process>). That is, the output value is the value which can be added to LINEAR memory vaddrs for converting to physical-memory addrs.<br />
|-<br />
| 21-23<br />
| [[8.0.0-18]]<br />
| This only returns error 0xE0E01BF4.<br />
|}<br />
<br />
= GetHandleInfo =<br />
{| class="wikitable" border="1"<br />
! HandleInfoType value<br />
! Description<br />
|-<br />
| 0<br />
| This writes back two (unknown) u32 fields from the KProcess object. If not a KProcess handle is given, it will write whatever was in r5, r7 when the svc was called.<br />
|-<br />
| 1<br />
| Get internal refcount-1 for kernel object (u32), and also a boolean if the refcount-1 is negative (u32).<br />
|-<br />
| 0x32107<br />
| Returns (u64) 0.<br />
|}<br />
<br />
= svc7B Backdoor =<br />
This saves SVC-mode SP+LR on the user-mode stack, then sets the SVC-mode SP to the user-mode SP. This then calls the specified code in SVC-mode. Once the called code returns, this pops the saved SP+LR off the stack for restoring the SVC-mode SP, then returns from the svc7b handler. Note that this svc7b handler does not disable IRQs, if any IRQs/context-switches occur while the SVC-mode SP is set to the user-mode one here, the ARM11-kernel will crash(which hangs the whole ARM11-side system).<br />
<br />
= Kernel error-codes =<br />
See [[Error codes]].<br />
<br />
{| class="wikitable" border="1"<br />
! Error-code value<br />
! Description<br />
|-<br />
| 0xC8601801<br />
| No more unused/free synchronization objects left to use in a given object's linked list. (KEvent, KMutex, KTimer, KSemaphore, KAddressArbiter, KThread)<br />
|-<br />
| 0xC8601802<br />
| No more unused/free KSharedMemory objects left to use in the KSharedMemory linked list - out of blocks<br />
|-<br />
| 0xC8601809<br />
| No more unused/free KSessions left to use in the KSession linked list - out of sessions<br />
|-<br />
| 0xC860180A<br />
| Not enough free memory available for memory allocation.<br />
|-<br />
| 0xC920181A<br />
| The session was closed by the other process..<br />
|-<br />
| 0xD0401834<br />
| Max connections to port have been exceeded<br />
|-<br />
| 0xD88007FA<br />
| Returned if no KObjectName object in the linked list of such objects matches the port name provided to the svc. <br />
|-<br />
| 0xD8E007ED<br />
| This indicates that a value is outside of the enum being used.<br />
|-<br />
| 0xD8E007F1<br />
| This error indicates Misaligned address.<br />
|-<br />
| 0xD8E007F7<br />
| This error indicates that the input handle used with the SVC does not exist in the process handle-table, or that the handle kernel object type does not match the type used by the SVC.<br />
|-<br />
| 0xD9000402<br />
| Invalid memory permissions for input/output buffers, for svcStartInterProcessDma.<br />
|-<br />
| 0xD9001814<br />
| Failed unprivileged load or store - wrong permissions on memory<br />
|-<br />
| 0xD9001BF7<br />
| This error is returned when the kernel retrieves a pointer to a kernel object, but the object type doesn't match the desired one.<br />
|-<br />
| 0xD92007EA<br />
| This error is returned when a process attempts to use svcCreateMemoryBlock when the process memorytype is the application memorytype, and when addr=0.<br />
|-<br />
| 0xE0E01BF5<br />
| This indicates an invalid address was used.<br />
|-<br />
| 0xF8C007F4<br />
| Invalid type/param0-param3 input for svcKernelSetState. This is also returned for those syscalls marked as stubs.<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12703
Multi-threading
2015-05-25T20:34:34Z
<p>Lectem: </p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread, only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
'''svc''' : 0x08<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread ===<br />
'''svc''' : 0x09<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread ===<br />
'''svc''' : 0x0A<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority ===<br />
'''svc''' : 0x0B<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority ===<br />
'''svc''' : 0x0C<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
'''svc''' : 0x34<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
'''svc''' : 0x36<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
'''svc''' : 0x37<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
=== GetThreadInfo ===<br />
'''svc''' : 0x2C<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
{| class="wikitable" border="1"<br />
! ThreadInfoType value<br />
! Description<br />
|-<br />
| ?<br />
| ?<br />
|}<br />
<br />
=== GetThreadContext ===<br />
'''svc''' : 0x3B<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
=== GetThreadAffinityMask ===<br />
'''svc''' : 0x0D<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
'''svc''' : 0x0E<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
'''svc''' : 0x0F<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
'''svc''' : 0x10<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12702
Multi-threading
2015-05-25T19:23:18Z
<p>Lectem: </p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread, only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread (svc 0x08) ===<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread (svc 0x09)===<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread (svc 0x0A)===<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority (svc 0x0B) ===<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority (svc 0x0C) ===<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread (svc 0x34) ===<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread (svc 0x36) ===<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId (svc 0x37) ===<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
=== GetThreadInfo (svc 0x2C) ===<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
{| class="wikitable" border="1"<br />
! ThreadInfoType value<br />
! Description<br />
|-<br />
| ?<br />
| ?<br />
|}<br />
<br />
=== GetThreadContext (svc 0x3B) ===<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
=== GetThreadAffinityMask (svc 0x0D) ===<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask (svc 0x0E) ===<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor (svc 0x0F) ===<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor (svc 0x10) ===<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12701
Multi-threading
2015-05-25T19:20:29Z
<p>Lectem: </p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread, only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread (svc 0x08) ===<br />
<br />
'''Definition'''<br />
Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid);<br />
<br />
'''Configuration'''<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
'''Details'''<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
The input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
=== ExitThread (svc 0x09)===<br />
<br />
'''Definition'''<br />
void ExitThread(void);<br />
<br />
=== SleepThread (svc 0x0A)===<br />
<br />
'''Definition'''<br />
void SleepThread(s64 nanoseconds);<br />
<br />
=== GetThreadPriority (svc 0x0B) ===<br />
<br />
'''Definition'''<br />
Result GetThreadPriority(s32* priority, Handle thread);<br />
<br />
'''asm'''<br />
.global svcGetThreadPriority<br />
.type svcGetThreadPriority, %function<br />
svcGetThreadPriority:<br />
str r0, [sp, #-0x4]!<br />
svc 0x0B<br />
ldr r3, [sp], #4<br />
str r1, [r3]<br />
bx lr<br />
<br />
=== SetThreadPriority (svc 0x0C) ===<br />
<br />
'''Definition'''<br />
Result SetThreadPriority(Handle thread, s32 priority);<br />
<br />
=== OpenThread ===<br />
<br />
'''Definition'''<br />
Result OpenThread(Handle* thread, Handle process, u32 threadId);<br />
<br />
=== GetProcessIdOfThread ===<br />
<br />
'''Definition'''<br />
Result GetProcessIdOfThread(u32* processId, Handle thread);<br />
<br />
=== GetThreadId ===<br />
<br />
'''Definition'''<br />
Result GetThreadId(u32* threadId, Handle thread);<br />
<br />
=== GetThreadInfo ===<br />
<br />
'''Definition'''<br />
Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type);<br />
<br />
{| class="wikitable" border="1"<br />
! ThreadInfoType value<br />
! Description<br />
|-<br />
| ?<br />
| ?<br />
|}<br />
<br />
=== GetThreadContext ===<br />
<br />
'''Definition'''<br />
Result GetThreadContext(ThreadContext* context, Handle thread);<br />
<br />
'''Details'''<br />
Stubbed?<br />
<br />
== Core affinity == <br />
<br />
=== GetThreadAffinityMask ===<br />
<br />
'''Definition'''<br />
Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);<br />
<br />
=== SetThreadAffinityMask ===<br />
<br />
'''Definition'''<br />
Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);<br />
<br />
=== GetThreadIdealProcessor ===<br />
<br />
'''Definition'''<br />
Result GetThreadIdealProcessor(s32* processorid, Handle thread);<br />
<br />
=== SetThreadIdealProcessor ===<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
For Kernel implementation details, see [[KMutex]]<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=SVC&diff=12700
SVC
2015-05-25T18:27:07Z
<p>Lectem: /* GetSystemInfo */</p>
<hr />
<div>= System calls =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Id<br />
! NF ARM11<br />
! NF ARM9<br />
! TF ARM11<br />
! Description<br />
! scope="col" width="200" | Notes<br />
|-<br />
| 0x01 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ControlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions)<br />
| Outaddr is usually the same as the input addr0.<br />
|-<br />
| 0x02 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryMemory(MemoryInfo* info, PageInfo* out, u32 Addr)<br />
|<br />
|-<br />
| 0x03 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| void ExitProcess(void)<br />
|<br />
|-<br />
| 0x04 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessAffinityMask(u8* affinitymask, Handle process, s32 processorcount)<br />
|<br />
|-<br />
| 0x05 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessAffinityMask(Handle process, u8* affinitymask, s32 processorcount)<br />
|<br />
|-<br />
| 0x06 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessIdealProcessor(s32 *idealprocessor, Handle process)<br />
|<br />
|-<br />
| 0x07 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessIdealProcessor(Handle process, s32 idealprocessor)<br />
|<br />
|-<br />
| 0x08 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result [[#CreateThread|CreateThread]](Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid)<br />
|<br />
|-<br />
| 0x09 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| void ExitThread(void)<br />
|<br />
|-<br />
| 0x0A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| void SleepThread(s64 nanoseconds)<br />
|<br />
|-<br />
| 0x0B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetThreadPriority(s32* priority, Handle thread)<br />
|<br />
|-<br />
| 0x0C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result SetThreadPriority(Handle thread, s32 priority)<br />
|<br />
|-<br />
| 0x0D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount)<br />
|<br />
|-<br />
| 0x0E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount)<br />
| Replaced with a stub in ARM11 NATIVE_FIRM kernel beginning with [[8.0.0-18]].<br />
|-<br />
| 0x0F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetThreadIdealProcessor(s32* processorid, Handle thread)<br />
|<br />
|-<br />
| 0x10 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetThreadIdealProcessor(Handle thread, s32 processorid)<br />
| Replaced with a stub in ARM11 NATIVE_FIRM kernel beginning with [[8.0.0-18]].<br />
|-<br />
| 0x11 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| s32 GetCurrentProcessorNumber(void)<br />
|<br />
|-<br />
| 0x12 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result Run(Handle process, StartupInfo* info)<br />
| This starts the main() thread. Buf+0 is main-thread priority, Buf+4 is main-thread stack-size.<br />
|-<br />
| 0x13 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateMutex(Handle* mutex, bool initialLocked)<br />
|<br />
|-<br />
| 0x14 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ReleaseMutex(Handle mutex)<br />
|<br />
|-<br />
| 0x15 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateSemaphore(Handle* semaphore, s32 initialCount, s32 maxCount)<br />
|<br />
|-<br />
| 0x16 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ReleaseSemaphore(s32* count, Handle semaphore, s32 releaseCount)<br />
|<br />
|-<br />
| 0x17 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateEvent(Handle* event, ResetType resettype)<br />
|<br />
|-<br />
| 0x18 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result SignalEvent(Handle event)<br />
|<br />
|-<br />
| 0x19 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ClearEvent(Handle event)<br />
|<br />
|-<br />
| 0x1A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateTimer(Handle* timer, ResetType resettype)<br />
|<br />
|-<br />
| 0x1B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result SetTimer(Handle timer, s64 initial, s64 interval)<br />
|<br />
|-<br />
| 0x1C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CancelTimer(Handle timer)<br />
|<br />
|-<br />
| 0x1D <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ClearTimer(Handle timer)<br />
|<br />
|-<br />
| 0x1E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 mypermission, u32 otherpermission)<br />
|<br />
|-<br />
| 0x1F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission)<br />
|<br />
|-<br />
| 0x20 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result UnmapMemoryBlock(Handle memblock, u32 addr)<br />
|<br />
|-<br />
| 0x21 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CreateAddressArbiter(Handle* arbiter)<br />
|<br />
|-<br />
| 0x22 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x23 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result CloseHandle(Handle handle)<br />
|<br />
|-<br />
| 0x24 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result WaitSynchronization1(Handle handle, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x25 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result WaitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds)<br />
|<br />
|-<br />
| 0x26 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SignalAndWait(s32* out, Handle signal, Handle* handles, s32 handleCount, bool waitAll, s64 nanoseconds)<br />
| Stubbed<br />
|-<br />
| 0x27 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result DuplicateHandle(Handle* out, Handle original)<br />
|<br />
|-<br />
| 0x28 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| s64 GetSystemTick(void) (This returns the total CPU ticks elapsed since the CPU was powered-on)<br />
|<br />
|-<br />
| 0x29 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetHandleInfo(s64* out, Handle handle, HandleInfoType type)<br />
|<br />
|-<br />
| 0x2A <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetSystemInfo(s64* out, SystemInfoType type, s32 param)<br />
|<br />
|-<br />
| 0x2B <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetProcessInfo(s64* out, Handle process, ProcessInfoType type)<br />
|<br />
|-<br />
| 0x2C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type)<br />
|<br />
|-<br />
| 0x2D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ConnectToPort(Handle* out, const char* portName)<br />
|<br />
|-<br />
| 0x2E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest1(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x2F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest2(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x30 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest3(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x31 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest4(Handle session)<br />
| Stubbed<br />
|<br />
|-<br />
| 0x32 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SendSyncRequest(Handle session)<br />
|<br />
|-<br />
| 0x33 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result OpenProcess(Handle* process, u32 processId)<br />
|<br />
|-<br />
| 0x34 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result OpenThread(Handle* thread, Handle process, u32 threadId)<br />
|<br />
|-<br />
| 0x35 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: green" | Yes<br />
| Result GetProcessId(u32* processId, Handle process)<br />
|<br />
|-<br />
| 0x36 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessIdOfThread(u32* processId, Handle thread)<br />
|<br />
|-<br />
| 0x37 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetThreadId(u32* threadId, Handle thread)<br />
|<br />
|-<br />
| 0x38 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimit(Handle* resourceLimit, Handle process)<br />
|<br />
|-<br />
| 0x39 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimitLimitValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)<br />
|<br />
|-<br />
| 0x3A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetResourceLimitCurrentValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)<br />
|<br />
|-<br />
| 0x3B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetThreadContext(ThreadContext* context, Handle thread)<br />
| Stubbed<br />
|-<br />
| 0x3C <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Break(BreakReason)<br />
|<br />
|-<br />
| 0x3D <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| OutputDebugString(void const, int)<br />
| Does nothing on non-debug units.<br />
|-<br />
| 0x3E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| ControlPerformanceCounter(unsigned long long, int, unsigned int, unsigned long long)<br />
|<br />
|- style="border-top: double"<br />
| 0x47 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions)<br />
| Setting name=NULL creates a private port not accessible from svcConnectToPort.<br />
|-<br />
| 0x48 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateSessionToPort(Handle* session, Handle port)<br />
|<br />
|-<br />
| 0x49 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateSession(Handle* sessionServer, Handle* sessionClient)<br />
|<br />
|-<br />
| 0x4A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result AcceptSession(Handle* session, Handle port)<br />
|<br />
|-<br />
| 0x4B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive1(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4C <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive2(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4D <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive3(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4E <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive4(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
| Stubbed.<br />
|-<br />
| 0x4F <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)<br />
|<br />
|-<br />
| 0x50 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result BindInterrupt(Interrupt name, Handle syncObject, s32 priority, bool isManualClear)<br />
|<br />
|-<br />
| 0x51 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result UnbindInterrupt(Interrupt name, Handle syncObject)<br />
|<br />
|-<br />
| 0x52 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result InvalidateProcessDataCache(Handle process, void* addr, u32 size)<br />
|<br />
|-<br />
| 0x53 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StoreProcessDataCache(Handle process, void const* addr, u32 size)<br />
|<br />
|-<br />
| 0x54 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result FlushProcessDataCache(Handle process, void const* addr, u32 size)<br />
|<br />
|-<br />
| 0x55 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StartInterProcessDma(Handle* dma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, const DmaConfig& config)<br />
|<br />
|-<br />
| 0x56 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result StopDma(Handle dma)<br />
|<br />
|-<br />
| 0x57 <br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| Result GetDmaState(DmaState* state, Handle dma)<br />
|<br />
|-<br />
| 0x58<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| RestartDma(nn::Handle, void *, void const*, unsigned int, signed char)<br />
|<br />
|- style="border-top: double"<br />
| 0x60 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result DebugActiveProcess(Handle* debug, u32 processID)<br />
|<br />
|-<br />
| 0x61 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result BreakDebugProcess(Handle debug)<br />
|<br />
|-<br />
| 0x62 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result TerminateDebugProcess(Handle debug)<br />
|<br />
|-<br />
| 0x63 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessDebugEvent(DebugEventInfo* info, Handle debug)<br />
|<br />
|-<br />
| 0x64 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ContinueDebugEvent(Handle debug, u32 flags)<br />
|<br />
|-<br />
| 0x65 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount)<br />
|<br />
|-<br />
| 0x66 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetThreadList(s32* threadCount, u32* threadIds, s32 threadIdMaxCount, Handle domain)<br />
|<br />
|-<br />
| 0x67 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result GetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, u32 controlFlags)<br />
|<br />
|-<br />
| 0x68 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, u32 controlFlags)<br />
|<br />
|-<br />
| 0x69 <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryDebugProcessMemory(MemoryInfo* blockInfo, PageInfo* pageInfo, Handle process, u32 addr)<br />
|<br />
|-<br />
| 0x6A <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size)<br />
|<br />
|-<br />
| 0x6B <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result WriteProcessMemory(Handle debug, void const* buffer, u32 addr, u32 size)<br />
|<br />
|-<br />
| 0x6C <br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetHardwareBreakPoint(s32 registerId, u32 control, u32 value)<br />
|<br />
|-<br />
| 0x6D<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| GetDebugThreadParam(long long *, int *, nn::Handle, unsigned int, nn::dmnt::DebugThreadParam)<br />
| Disabled on regular kernel.<br />
|- style="border-top: double"<br />
| 0x70<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result ControlProcessMemory(Handle KProcess, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int Type, unsigned int Permissions)<br />
|<br />
|-<br />
| 0x71<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result MapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr)<br />
|<br />
|-<br />
| 0x72<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result UnmapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr)<br />
|<br />
|-<br />
| 0x73<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateCodeSet(Handle* handle_out, struct CodeSetInfo, u32 code_ptr, u32 ro_ptr, u32 data_ptr)<br />
|<br />
|-<br />
| 0x74<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result RandomStub()<br />
| Stubbed<br />
|-<br />
| 0x75<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateProcess(Handle* handle_out, Handle codeset_handle, u32 arm11kernelcaps_ptr, u32 arm11kernelcaps_num)<br />
|<br />
|-<br />
| 0x76<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| TerminateProcess(Handle)<br />
|<br />
|-<br />
| 0x77<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetProcessResourceLimits(Handle KProcess, Handle KResourceLimit)<br />
| <br />
|-<br />
| 0x78<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result CreateResourceLimit(Handle *KResourceLimit)<br />
|<br />
|-<br />
| 0x79<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result SetResourceLimitValues(Handle res_limit, LimitableResource* resource_type_list, s64* resource_list, u32 count)<br />
|<br />
|-<br />
| 0x7A<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: green" | Yes<br />
| AddCodeSegment (unsigned int Addr, unsigned int Size)<br />
| Stubbed on NATIVE_FIRM beginning with [[2.0.0-2]]. Used during TWL_FIRM boot.<br />
|-<br />
| 0x7B<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| Backdoor(unsigned int CodeAddress)<br />
| This is used on ARM9 NATIVE_FIRM. No ARM11 processes have access to it without some form of kernelhax.<br />
|-<br />
| 0x7C<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| KernelSetState(unsigned int Type, unsigned int Param0, unsigned int Param1, unsigned int Param2)<br />
| The type determines the meaning of each param<br />
|-<br />
| 0x7D<br />
| style="background: green" | Yes<br />
| style="background: red" | No<br />
| style="background: red" | No<br />
| Result QueryProcessMemory(MemInfo *Info, unsigned int *Out, Handle KProcess, unsigned int Addr)<br />
|<br />
|- style="border-top: double"<br />
| 0xFF<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| style="background: green" | Yes<br />
| ???<br />
| Debug related? The svcaccesscontrol mask doesn't apply for this SVC. Stubbed on ARM9 NATIVE_FIRM.<br />
|}<br />
NF: NATIVE_FIRM. TF: TWL_FIRM.<br />
<br />
Note that "stubbed" here means that the SVC only returns an error, as in the following snippet:<br />
<br />
<pre>ROM:FFF04D98 LDR R0, =0xF8C007F4<br />
ROM:FFF04D9C BX LR</pre><br />
<br />
== CreateThread ==<br />
R0=s32 threadpriority<br />
R1=func entrypoint<br />
R2=u32 arg<br />
R3=u32 stacktop<br />
R4=s32 processorid<br />
<br />
Result result=R0<br />
Handle* thread=R1<br />
<br />
The processorid parameter specifies which processor the thread can run on. Non-negative values correspond to a specific CPU. (e.g. 0 for the Appcore and 1 for the Syscore on Old3DS) Special value -1 means all CPUs, and -2 means the default CPU for the process (Read from the [[NCCH/Extended Header|Exheader]], usually 0 for applications, 1 for system services). Games usually create threads using -2.<br />
<br />
With the Old3DS kernel, the s32 processorid must be <=2.<br />
<br />
With the New3DS kernel: processorid must be <= <total cores(MPCore "SCU Configuration Register" CPU number value + 1)>. When processorid==0x2 and the process is not an APPLICATION mem-region process, exheader kernel-flags bitmask 0x2000 must be set otherwise error 0xD9001BEA is returned. When processorid==0x3 and the process is not an APPLICATION mem-region process, error 0xD9001BEA is returned. These are the only restriction checks done by the kernel for processorid.<br />
<br />
The thread priority value must be in the following range: 0x0..0x3F.<br />
<br />
The stacktop must be aligned to 0x8-bytes, otherwise when not aligned to 0x8-bytes the ARM11 kernel clears the low 3-bits of the stacktop address.<br />
<br />
= Types and structures =<br />
<br />
== enum MemoryState ==<br />
{| class="wikitable" border="1"<br />
! Memory state flags<br />
! Value<br />
|-<br />
| FREE<br />
| 0<br />
|-<br />
| RESERVED<br />
| 1<br />
|-<br />
| IO<br />
| 2<br />
|-<br />
| STATIC<br />
| 3<br />
|-<br />
| CODE<br />
| 4<br />
|-<br />
| PRIVATE<br />
| 5<br />
|-<br />
| SHARED<br />
| 6<br />
|-<br />
| CONTINUOUS<br />
| 7<br />
|-<br />
| ALIASED<br />
| 8<br />
|-<br />
| ALIAS<br />
| 9<br />
|-<br />
| ALIAS CODE<br />
| 10<br />
|-<br />
| LOCKED<br />
| 11<br />
|}<br />
<br />
== enum PageFlags ==<br />
{| class="wikitable" border="1"<br />
! Page flags<br />
! Bit<br />
|-<br />
| LOCKED<br />
| 0<br />
|-<br />
| CHANGED<br />
| 1<br />
|}<br />
<br />
== enum MemoryOperation ==<br />
<br />
{| class="wikitable" border="1"<br />
! Memory operation<br />
! Id<br />
|-<br />
| FREE<br />
| 1<br />
|-<br />
| RESERVE<br />
| 2<br />
|-<br />
| COMMIT<br />
| 3<br />
|-<br />
| MAP<br />
| 4<br />
|-<br />
| UNMAP<br />
| 5<br />
|-<br />
| PROTECT<br />
| 6<br />
|-<br />
| REGION APP<br />
| 0x100<br />
|-<br />
| REGION SYSTEM<br />
| 0x200<br />
|-<br />
| REGION BASE<br />
| 0x300<br />
|-<br />
| LINEAR<br />
| 0x10000<br />
|}<br />
<br />
The LINEAR memory-operation indicates that the mapped physical address is always MappedVAddr+0x0C000000, thus this memory can be used for hardware devices' DMA(such as the [[GPU]]). Addr0+size for this must be within the 0x14000000-0x1C000000 range when Addr0 is non-zero(Addr1 must be zero), Addr0 isn't actually used by svcControlMemory for mapping memory: Addr0 is not used by the kernel after doing address-range checks. The kernel determines what physical-address to use by allocating memory from FCRAM(about the same way as other memory), which is then used to determine the virtual-address.<br />
<br />
[[8.0.0-18]] added a new memory mapping(0x30000000-0x38000000) for LINEAR memory, this replaces the original mapping for newer titles. The kernel uses the new mapping when the process memory-region is BASE, or when the process kernel-release-version field is >=0x022c(2.44 / system-version [[8.0.0-18]]).<br />
<br />
The input mem-region value for svcControlMemory is only used(when non-zero) when the PID is value 1, for the [[FIRM]] ARM11 "loader" module.<br />
<br />
== enum MemoryPermission ==<br />
<br />
{| class="wikitable" border="1"<br />
! Memory permission<br />
! Id<br />
|-<br />
| NONE<br />
| 0<br />
|-<br />
| R<br />
| 1<br />
|-<br />
| W<br />
| 2<br />
|-<br />
| RW<br />
| 3<br />
|-<br />
| X<br />
| 4<br />
|-<br />
| RX<br />
| 5<br />
|-<br />
| WX<br />
| 6<br />
|-<br />
| RWX<br />
| 7<br />
|-<br />
| DONTCARE<br />
| 0x10000000<br />
|}<br />
<br />
== enum ResetType ==<br />
<br />
{| class="wikitable" border="1"<br />
! Reset type<br />
! Id<br />
|-<br />
| ONESHOT<br />
| 0<br />
|-<br />
| STICKY<br />
| 1<br />
|-<br />
| PULSE<br />
| 2<br />
|}<br />
<br />
== struct MemoryInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Base process virtual address<br />
|-<br />
| u32<br />
| Size<br />
|-<br />
| u32<br />
| Permission<br />
|-<br />
| enum MemoryState<br />
| State<br />
|}<br />
<br />
== struct PageInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Flags<br />
|}<br />
<br />
== struct StartupInfo ==<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| s32<br />
| Priority<br />
|-<br />
| u32<br />
| Stack size<br />
|-<br />
| s32<br />
| argc<br />
|-<br />
| s16*<br />
| argv<br />
|-<br />
| s16*<br />
| envp<br />
|}<br />
<br />
== enum ArbitrationType ==<br />
{| class="wikitable" border="1"<br />
! Address arbitration type<br />
! Value<br />
|-<br />
| FREE<br />
| 0<br />
|-<br />
| AQUIRE<br />
| 1<br />
|-<br />
| KERNEL2<br />
| 2<br />
|-<br />
| AQUIRE_TIMEOUT<br />
| 3<br />
|-<br />
| KERNEL4<br />
| 4<br />
|}<br />
<br />
== enum BreakReason ==<br />
{| class="wikitable" border="1"<br />
! Break Reason<br />
! Value<br />
|-<br />
| PANIC<br />
| 0<br />
|-<br />
| ASSERT<br />
| 1<br />
|-<br />
| USER<br />
| 2<br />
|}<br />
<br />
== struct CodeSetInfo ==<br />
All addresses are given virtual for the process to be created.<br />
All sizes are given in 0x1000-pages.<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u8[8]<br />
| Codeset Name<br />
|-<br />
| u16<br />
| Unknown, this is written to field 0x5A of KCodeSet<br />
|-<br />
| u16<br />
| Unknown/padding<br />
|-<br />
| u32<br />
| Unknown/padding<br />
|-<br />
| u32<br />
| .text addr<br />
|-<br />
| u32<br />
| .text size<br />
|-<br />
| u32<br />
| .rodata start<br />
|-<br />
| u32<br />
| .rodata size<br />
|-<br />
| u32<br />
| RW addr (.data + .bss)<br />
|-<br />
| u32<br />
| RW size (.data + .bss)<br />
|-<br />
| u32<br />
| Total .text pages<br />
|-<br />
| u32<br />
| Total .rodata pages<br />
|-<br />
| u32<br />
| Total RW pages (.data + .bss)<br />
|-<br />
| u32<br />
| Unknown/padding<br />
|-<br />
| u8[8]<br />
| Program ID<br />
|}<br />
<br />
== struct DebugEventInfo ==<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Event type<br />
|-<br />
| u32<br />
| Thread ID (not used in all events)<br />
|-<br />
| u32[2]<br />
| Unknown/padding<br />
|-<br />
| u32[6]<br />
| Event-specific data (see below)<br />
|}<br />
<br />
{| class="wikitable" border="1"<br />
! Event type<br />
! Id<br />
|-<br />
| PROCESS<br />
| 0<br />
|-<br />
| CREATE THREAD<br />
| 1<br />
|-<br />
| EXIT THREAD<br />
| 2<br />
|-<br />
| EXIT PROCESS<br />
| 3<br />
|-<br />
| EXCEPTION<br />
| 4<br />
|-<br />
| DLL LOAD<br />
| 5<br />
|-<br />
| DLL UNLOAD<br />
| 6<br />
|-<br />
| SCHEDULE IN<br />
| 7<br />
|-<br />
| SCHEDULE OUT<br />
| 8<br />
|-<br />
| SYSCALL IN<br />
| 9<br />
|-<br />
| SYSCALL OUT<br />
| 10<br />
|-<br />
| OUTPUT STRING<br />
| 11<br />
|-<br />
| MAP<br />
| 12<br />
|}<br />
<br />
=== PROCESS event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u64<br />
| Program ID<br />
|-<br />
| char[8]<br />
| Process name<br />
|-<br />
| u32<br />
| Process ID<br />
|-<br />
| u32<br />
| 0 = newly created process, 1 = attached process<br />
|}<br />
<br />
=== CREATE THREAD event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Creator thread ID<br />
|-<br />
| u32<br />
| Base address (?)<br />
|-<br />
| u32<br />
| Entrypoint<br />
|}<br />
<br />
=== EXIT THREAD/PROCESS events ===<br />
<br />
A single u32 reason field is used.<br />
<br />
Thread exit reasons:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| (None)<br />
| 0<br />
|-<br />
| TERMINATE<br />
| 1<br />
|-<br />
| EXIT PROCESS<br />
| 2<br />
|-<br />
| TERMINATE PROCESS<br />
| 3<br />
|}<br />
<br />
Process exit reasons:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| (None)<br />
| 0<br />
|-<br />
| TERMINATE<br />
| 1<br />
|-<br />
| UNHANDLED EXCEPTION<br />
| 2<br />
|}<br />
<br />
=== EXCEPTION event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Exception type<br />
|-<br />
| u32<br />
| Exception address<br />
|-<br />
| u32<br />
| Argument (type-specific)<br />
|}<br />
<br />
Exception types:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
! Argument<br />
|-<br />
| UNDEFINED INSTRUCTION<br />
| 0<br />
| (None)<br />
|-<br />
| (Unknown)<br />
| 1<br />
| (None)<br />
|-<br />
| (Unknown, mem-related)<br />
| 2<br />
| Address<br />
|-<br />
| (Unknown, mem-related)<br />
| 3<br />
| Address<br />
|-<br />
| ATTACH BREAK<br />
| 4<br />
| (None)<br />
|-<br />
| BREAKPOINT<br />
| 5<br />
| (None)<br />
|-<br />
| USER BREAK<br />
| 6<br />
| User break type<br />
|-<br />
| DEBUGGER BREAK<br />
| 7<br />
| (None)<br />
|-<br />
| UNDEFINED SYSCALL<br />
| 8<br />
| Attempted syscall ID<br />
|}<br />
<br />
User break types:<br />
{| class="wikitable" border="1"<br />
! Reason<br />
! Id<br />
|-<br />
| PANIC<br />
| 0<br />
|-<br />
| ASSERT<br />
| 1<br />
|-<br />
| USER<br />
| 2<br />
|}<br />
<br />
=== SCHEDULER/SYSCALL IN/OUT events ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u64<br />
| Clock tick<br />
|-<br />
| u32<br />
| Syscall (only for SYSCALL events)<br />
|}<br />
<br />
=== OUTPUT STRING event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| String address<br />
|-<br />
| u32<br />
| String size<br />
|}<br />
<br />
=== MAP event ===<br />
<br />
{| class="wikitable" border="1"<br />
! Type<br />
! Field<br />
|-<br />
| u32<br />
| Mapped address<br />
|-<br />
| u32<br />
| Mapped size<br />
|-<br />
| u32<br />
| MemoryPermission<br />
|-<br />
| u32<br />
| MemoryState<br />
|}<br />
<br />
= Processes =<br />
Each process can only use SVCs which are enabled in the [[NCCH#CXI|exheader]] for this process. The ARM11 kernel SVC handler checks whether the SVC is enabled in the syscall access control mask stored on the SVC-mode stack, when the SVC isn't enabled a kernelpanic() is triggered. Each process has a separate SVC-mode stack, this stack and the syscall access mask stored here is initialized when the process is started. Applications normally only have access to SVCs <=0x3D, however not all SVCs <=0x3D are accessible to the application. The majority of the SVCs accessible to applications are unused by the application.<br />
<br />
Each process has a separate handle-table, the size of this table is stored in the exheader. The handles in a handle-table can't be used in the context of other processes, since those handles don't exist in other handle-tables.<br />
<br />
0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for the current KThread.<br />
<br />
Calling svcBreak on retail will only terminate the process which called this SVC.<br />
<br />
= Threads =<br />
For svcCreateThread the input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.<br />
<br />
Using CloseHandle() with a KThread handle will terminate the specified thread, only if the reference count reaches 0.<br />
<br />
Lower priority values give the thread higher priority. For userland apps, priorities between 0x18 and 0x3F are allowed. The priority of the app's main thread seems to be 0x30.<br />
<br />
The thread scheduler is cooperative, therefore if a thread takes up all the CPU time (for example if it enters an endless loop), all the other threads that run on the same CPU core won't get a chance to run. The main way of yielding another thread is using an address arbiter.<br />
<br />
= Memory Mapping =<br />
ControlMemory and MapMemoryBlock can be used to map memory pages, these two SVCs only support mapping execute-never R/W pages. The input permissions parameter for these SVCs must therefore be <=3, where value zero is used when un-mapping memory. Furthermore it appears that only regular heap pages can be mirrored (it won't work for TLS, stack, .data, .text, for example).<br />
<br />
Bitmask 0xF00 for ControlMemory parameter MemoryType is the memory-type, when this is zero the memory-type is loaded from the kernel flags stored in the exheader ARM11 kernel descriptors, for the process using the SVC.<br />
<br />
ControlMemory parameter MemoryType with value 0x10003 is used for mapping the GSP [[Memory_layout|heap]]. The low 8-bits are the type: 1 is for un-mapping memory, 3 for mapping memory. Type4 is used to mirror the RW memory at Addr1, to Addr0. Type4 will return an error if Addr1 is located in read-only memory. Addr1 is not used for type1 and type3.<br />
<br />
The ARM11 kernel does not allow processes to create shared memory blocks via svcCreateMemoryBlock, when the process memorytype(from the kernel flags stored in the exheader kernel descriptor) is the application memorytype, and when addr=0. It's unknown how the kernel handles addr=0 when the memorytype is not the application memorytype. When addr is non-zero, it must be located in memory which is already mapped. Furthermore, it appears that only regular heap pages (allocated using svcControlMemory op=COMMIT) are accepted as valid addrs.<br />
<br />
ControlProcessMemory maps memory in the specified process, this is the only SVC which allows mapping executable memory. Format of the permissions field for memory mapping SVCs: bit0=R, bit1=W, bit2=X. Type6 sets the Addr0 memory permissions to the input permissions, for already mapped memory. Type is the MemoryOperation enum, without the memory-type/memory-region. ControlProcessMemory only supports type4, type5, and type6. ControlProcessMemory does not support using the current KProcess handle alias.<br />
<br />
MapProcessMemory maps RW memory starting at address 0x00100000 in the specified KProcess, at the specified StartAddr in the current process. MapProcessMemory then maps 0x08000000 in the specified process, to StartAddr+0x7f00000 in the current process. UnmapProcessMemory unmaps the memory which was mapped by MapProcessMemory.<br />
<br />
Note that with the MAP MemoryOperation, the kernel will refuse to MAP memory for the specified addr1, when addr1 was already used with another MAP operation as addr1. The kernel also doesn't allow memory to be freed via the FREE MemoryOperation, when other virtual-memory is mapped to this same memory(when the MAP MemoryOperation was used with this memory with addr1).<br />
<br />
= DMA =<br />
The CTRSDK code for using svcStartInterProcessDma will execute svcBreak when svcStartInterProcessDma returns an error(except for certain error value(s)). Therefore on retail, triggering a svcStartInterProcessDma via a system-module which results in an error from svcStartInterProcessDma will result in the system-module terminating.<br />
<br />
==DmaConfig==<br />
Size of struct is 24 bytes.<br />
<br />
struct DmaConfig {<br />
sint8_t channel_sel; // @0 Selects which DMA channel to use: 0-7, -1 = don't care.<br />
uint8_t unk1; // @1 Accepted values: 0,2,4,8.<br />
uint8_t flags; // @2 bit0: DST_CFG, bit1: SRC_CFG, bit2: SHALL_BLOCK, bit3: ???, bit6: DST_ALT_CFG, bit7: SRC_ALT_CFG<br />
uint8_t unk2;<br />
uint8_t dst_cfg[10];<br />
// @5 Accepted values (u8): 4, 8, 12, 15.<br />
// @15 Accepted values (u8): 4, 8, 12, 15.<br />
uint8_t src_cfg[10]; // @14<br />
}<br />
<br />
If SRC_CFG/DST_CFG is set in the flags field, the configuration for src/dst is loaded from src_cfg/dst_cfg respectively. If the *_ALT_CFG flag is set same thing goes, except byte0 of each cfg is forced to 0xFF. ALT_CFG has priority over CFG.<br />
<br />
If CFG or ALT_CFG is not set, default configuration is loaded:<br />
FF 0F 80 00 00 00 80 00 00 00<br />
<br />
If SHALL_BLOCK is set, the thread will sleep until the DMA engine is ready. If not set, the SVC will return 0xD04007F0 if the DMA channel is busy.<br />
<br />
The format of src_cfg/dst_cfg is unknown, but both have the same format. Checks suggest that the second byte of cfg equalling 4 means NO_INCREMENT (don't increment after read/write).<br />
<br />
= Debugging =<br />
DebugActiveProcess is used to attach to a process for debugging. This SVC can only be used when the target process' ARM11 descriptors stored in the exheader have the kernel flag for "Enable debug" set. Otherwise when that flag is clear, the kernel flags for the process using this SVC must have the "Force debug" flag set.<br />
<br />
= KernelSetState =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Type<br />
! Enabled for the NATIVE_FIRM ARM11 kernel<br />
! Enabled for the TWL_FIRM ARM11 kernel<br />
! Description<br />
|-<br />
| 0<br />
| Yes<br />
| No<br />
| This initializes the programID for launching [[FIRM]], then triggers launching [[FIRM]]. Param0 is unused. Param1 is the programID-low, and the programID-high is 0x00040138. Param2 is used only with the [[New_3DS]] kernel, pm-module uses value 0 with this. With New3DS kernel, it forces the programIDlow to be the New3DS NATIVE_FIRM, when the input programIDlow is for the Old3DS NATIVE_FIRM and Param2==0.<br />
|-<br />
| 1<br />
| Yes<br />
| Yes<br />
| Unknown, does nothing with the TWL_FIRM ARM11 kernel.<br />
|-<br />
| 2<br />
| Yes<br />
| Yes<br />
| ?<br />
|-<br />
| 3<br />
| Yes<br />
| No<br />
| This used for initializing the 0x1000-byte buffer used by the launched [[FIRM]]. Param2 is unused. When Param0 is value 1, this buffer is copied to the beginning of FCRAM at 0xF0000000, and Param1 is unused. When Param0 is value 0, this kernel buffer is mapped to process address Param1.<br />
|-<br />
| 4<br />
| No<br />
| Yes<br />
| Param0-Param3 are unused. This unmaps(?) the following virtual memory by writing value physaddr(where physaddr base is 0x80000000) to the L1 MMU table entries: 0x00300000..0x04300000, 0x08000000..0x0FE00000, and 0x10000000..0xF8000000.<br />
|-<br />
| 5<br />
| Yes<br />
| Yes<br />
| ?<br />
|-<br />
| 6<br />
| Yes<br />
| No<br />
| Debug related?<br />
|-<br />
| 7<br />
| Yes<br />
| No<br />
| This triggers ARM11 kernel [[I2C]] code, Param0-Param3 are unused. This ARM11 kernel I2C code will never return. Device address 0x4a via the second I2C bus is used here. This triggers a hardware system reboot via poking an I2C MCU register: register address 0x20 is written to with value 4.<br />
|-<br />
| 8<br />
| Yes<br />
| No<br />
| Alternate unused FIRM launch code-path, with different [[PXI]] FIFO word constants.<br />
|-<br />
| 9<br />
| Yes, implemented at some point after system-version v4.5.<br />
| ?<br />
| Unknown<br />
|-<br />
| 10<br />
| Yes<br />
| ?<br />
| Only available for the [[New_3DS]] kernel. It's unknown what this is used for.<br />
|}<br />
<br />
= GetSystemInfo =<br />
{| class="wikitable" border="1"<br />
! SystemInfoType value<br />
! s32 param<br />
! Description<br />
|-<br />
| 0<br />
| 0<br />
| This writes the total used memory size in the following memory regions to out: APPLICATION, SYSTEM, and BASE.<br />
|-<br />
| 0<br />
| 1<br />
| This writes the total used memory size in the APPLICATION memory region to out.<br />
|-<br />
| 0<br />
| 2<br />
| This writes the total used memory size in the SYSTEM memory region to out.<br />
|-<br />
| 0<br />
| 3<br />
| This writes the total used memory size in the BASE memory region to out.<br />
|-<br />
| 25<br />
| Unused<br />
| This writes the total number of threads which were directly launched by the kernel, to out.<br />
|-<br />
| 26<br />
| Unused<br />
| This writes the total number of processes which were directly launched by the kernel, to out. For the NATIVE_FIRM/SAFE_MODE_FIRM ARM11 kernel, this is normally 5, for processes sm, fs, pm, loader, and pxi.<br />
|}<br />
<br />
= GetProcessInfo =<br />
Input:<br />
R0 = unused<br />
R1 = Handle process<br />
R2 = ProcessInfoType type<br />
<br />
Output:<br />
R0 = Result<br />
R1 = output value lower word<br />
R2 = output value upper word<br />
<br />
{| class="wikitable" border="1"<br />
! ProcessInfoType value<br />
! Available since system version<br />
! Description<br />
|-<br />
| 9-19<br />
| [[8.0.0-18]]<br />
| This only returns error 0xD8E007ED.<br />
|-<br />
| 20<br />
| [[8.0.0-18]]<br />
| low u32 = (0x20000000 - <LINEAR virtual-memory base for this process>). That is, the output value is the value which can be added to LINEAR memory vaddrs for converting to physical-memory addrs.<br />
|-<br />
| 21-23<br />
| [[8.0.0-18]]<br />
| This only returns error 0xE0E01BF4.<br />
|}<br />
<br />
= GetHandleInfo =<br />
{| class="wikitable" border="1"<br />
! HandleInfoType value<br />
! Description<br />
|-<br />
| 0<br />
| This writes back two (unknown) u32 fields from the KProcess object. If not a KProcess handle is given, it will write whatever was in r5, r7 when the svc was called.<br />
|-<br />
| 1<br />
| Get internal refcount-1 for kernel object (u32), and also a boolean if the refcount-1 is negative (u32).<br />
|-<br />
| 0x32107<br />
| Returns (u64) 0.<br />
|}<br />
<br />
= svc7B Backdoor =<br />
This saves SVC-mode SP+LR on the user-mode stack, then sets the SVC-mode SP to the user-mode SP. This then calls the specified code in SVC-mode. Once the called code returns, this pops the saved SP+LR off the stack for restoring the SVC-mode SP, then returns from the svc7b handler. Note that this svc7b handler does not disable IRQs, if any IRQs/context-switches occur while the SVC-mode SP is set to the user-mode one here, the ARM11-kernel will crash(which hangs the whole ARM11-side system).<br />
<br />
= Kernel error-codes =<br />
See [[Error codes]].<br />
<br />
{| class="wikitable" border="1"<br />
! Error-code value<br />
! Description<br />
|-<br />
| 0xC8601801<br />
| No more unused/free synchronization objects left to use in a given object's linked list. (KEvent, KMutex, KTimer, KSemaphore, KAddressArbiter, KThread)<br />
|-<br />
| 0xC8601802<br />
| No more unused/free KSharedMemory objects left to use in the KSharedMemory linked list - out of blocks<br />
|-<br />
| 0xC8601809<br />
| No more unused/free KSessions left to use in the KSession linked list - out of sessions<br />
|-<br />
| 0xC860180A<br />
| Not enough free memory available for memory allocation.<br />
|-<br />
| 0xC920181A<br />
| The session was closed by the other process..<br />
|-<br />
| 0xD0401834<br />
| Max connections to port have been exceeded<br />
|-<br />
| 0xD88007FA<br />
| Returned if no KObjectName object in the linked list of such objects matches the port name provided to the svc. <br />
|-<br />
| 0xD8E007ED<br />
| This indicates that a value is outside of the enum being used.<br />
|-<br />
| 0xD8E007F1<br />
| This error indicates Misaligned address.<br />
|-<br />
| 0xD8E007F7<br />
| This error indicates that the input handle used with the SVC does not exist in the process handle-table, or that the handle kernel object type does not match the type used by the SVC.<br />
|-<br />
| 0xD9000402<br />
| Invalid memory permissions for input/output buffers, for svcStartInterProcessDma.<br />
|-<br />
| 0xD9001814<br />
| Failed unprivileged load or store - wrong permissions on memory<br />
|-<br />
| 0xD9001BF7<br />
| This error is returned when the kernel retrieves a pointer to a kernel object, but the object type doesn't match the desired one.<br />
|-<br />
| 0xD92007EA<br />
| This error is returned when a process attempts to use svcCreateMemoryBlock when the process memorytype is the application memorytype, and when addr=0.<br />
|-<br />
| 0xE0E01BF5<br />
| This indicates an invalid address was used.<br />
|-<br />
| 0xF8C007F4<br />
| Invalid type/param0-param3 input for svcKernelSetState. This is also returned for those syscalls marked as stubs.<br />
|}</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Multi-threading&diff=12699
Multi-threading
2015-05-25T15:49:22Z
<p>Lectem: Created page with "This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc. The Nintendo 3DS offers support for threading..."</p>
<hr />
<div>This page is a work in progress. Put everything related to multi-threading here, threads, synchronization, multi-core support, etc.<br />
<br />
The Nintendo 3DS offers support for threading through use of [[SVC]] calls.<br />
<br />
= Threads =<br />
<br />
For Kernel implementation details, see [[KThread]].<br />
<br />
Though it is possible to run multi-threaded programs, running those on different cores is not possible "as-is". One core is always dedicated to the OS, hence you will never get 100% of both cores.<br />
<br />
== Usage ==<br />
<br />
=== CreateThread ===<br />
<br />
=== ExitThread ===<br />
<br />
=== SleepThread ===<br />
<br />
=== GetThreadPriority ===<br />
<br />
=== SetThreadPriority ===<br />
<br />
=== OpenThread ===<br />
<br />
=== GetProcessIdOfThread ===<br />
<br />
=== GetThreadId ===<br />
<br />
=== GetThreadInfo ===<br />
<br />
=== GetThreadContext ===<br />
<br />
== Core affinity == <br />
<br />
=== GetThreadAffinityMask ===<br />
<br />
=== SetThreadAffinityMask ===<br />
<br />
=== GetThreadIdealProcessor ===<br />
<br />
=== SetThreadIdealProcessor ===<br />
<br />
== Debug == <br />
<br />
=== GetThreadList ===<br />
<br />
=== GetDebugThreadContext ===<br />
<br />
=== SetDebugThreadContext ===<br />
<br />
=== GetDebugThreadParam ===<br />
<br />
= Synchronization =<br />
<br />
Most synchronization systems seem to have both a "normal" and "light-weight" version<br />
<br />
== Mutex (normal) ==<br />
<br />
=== CreateMutex ===<br />
<br />
/!\ It seems that the mutex will not be available once the thread that created it is destroyed <br />
<br />
=== ReleaseMutex ===<br />
<br />
== Ciritical Section (light-weight mutex) ==<br />
<br />
== CriticalSection::Initialize ==<br />
<br />
Same thread ownership as a mutex ?<br />
<br />
=== CriticalSection::Enter ===<br />
<br />
=== CriticalSection::Leave ===<br />
<br />
== Semaphore ==<br />
<br />
== Light Semaphore ? ==<br />
<br />
Does it exist ?<br />
<br />
== Event ==<br />
<br />
== Light Event ==</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Memory_layout&diff=12696
Memory layout
2015-05-25T06:18:25Z
<p>Lectem: /* ARM9 Physical memory regions */</p>
<hr />
<div>=ARM11 Physical memory regions =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00000000<br />
| 0x00010000<br />
| Bootrom (super secret code/data @ 0x8000)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00010000<br />
| 0x00010000<br />
| Bootrom mirror<br />
|-<br />
| style="background: green" | Yes<br />
| 0x10000000<br />
|?<br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x17E00000<br />
| 0x00002000<br />
| MPCore private memory region<br />
<br />
|-<br />
| style="background: red" | No<br />
| 0x17E10000<br />
| 0x00001000<br />
| ?<br />
|-<br />
| style="background: green" | Yes<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM (divided in two banks, VRAM and VRAMB)<br />
|-<br />
| style="background: red" | No<br />
| 0x1F000000<br />
| 0x00400000<br />
| [[New_3DS]] additional memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF00000<br />
| 0x00080000<br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF80000<br />
| 0x00080000<br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| 0x20000000<br />
| 0x08000000<br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| 0x28000000<br />
| 0x08000000<br />
| [[New_3DS]] FCRAM extension<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFFF0000<br />
| 0x00010000<br />
| Bootrom mirror<br />
|}<br />
<br />
=ARM9 Physical memory regions =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00000000<br />
| 0x08000000<br />
| Instruction TCM, repeating each 0x8000 bytes.<br />
|-<br />
| style="background: green" | Yes<br />
| 0x01FF8000<br />
| 0x00008000<br />
| Instruction TCM (Accessed by the kernel and process by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x07FF8000<br />
| 0x00008000<br />
| Instruction TCM (Accessed by bootrom by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x08000000<br />
| 0x00100000<br />
| ARM9-only internal memory (ARM7's internal regions are mapped here as well)<br />
|-<br />
| style="background: red" | No<br />
| 0x08100000<br />
| 0x00080000<br />
| [[New_3DS]] ARM9-only extension, only enabled when a certain [[CONFIG_Registers|CONFIG]] register is set.<br />
|-<br />
| style="background: green" | Yes<br />
| 0x10000000<br />
| 0x08000000<br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM (divided in two banks, VRAM and VRAMB) <br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF00000<br />
| 0x00080000<br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF80000<br />
| 0x00080000<br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| 0x20000000<br />
| 0x08000000<br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| 0x28000000<br />
| 0x08000000<br />
| [[New_3DS]] FCRAM extension<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFF00000<br />
| 0x00004000<br />
| Data TCM (Mapped during bootrom)<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFFF0000<br />
| 0x00010000<br />
| Bootrom, the main region is at +0x8000, which is disabled during system boot.<br />
|}<br />
<br />
==ARM9 MPU regions==<br />
For the below instruction permissions: RO = memory is executable, while None = not-executable.<br />
<br />
===NATIVE_FIRM/SAFE_MODE_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. >=[[8.0.0-18|8.0.0-X]]: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x10100000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. >=[[8.0.0-18|8.0.0-X]]: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08020000<br />
| <[[3.0.0-5]]: 64KB/0x10000. >=[[3.0.0-5]]: 32KB/0x8000.<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|}<br />
<br />
The above is the MPU region settings setup by the ARM9-kernel in the crt0.<br />
<br />
The New3DS ARM9-kernel MPU region settings are the same as the Old3DS MPU region settings for >=[[8.0.0-18|8.0.0-X]].<br />
<br />
At the start of the Process9 function executed in kernel-mode via svc7b during firm-launching, it changes some MPU region settings. At the end of that function, before it uses the ARM9/ARM11 entrypoint fields, it disables MPU.<br />
<br />
===New3DS [[FIRM|ARM9-loader]]===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 2MB/0x200000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| None<br />
| None<br />
|}<br />
<br />
MPU regions 4-7 are disabled. Note that the entire ARM9-loader runs in SVC-mode.<br />
<br />
===TWL_FIRM/AGB_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. New3DS: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 2MB/0x200000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x1FF00000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. New3DS: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| <[[3.0.0-5|3.0.0-X]]: 256KB/0x40000. >=[[3.0.0-5|3.0.0-X]]: 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08080000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|}<br />
<br />
==ARM9 ITCM==<br />
{| class="wikitable" border="1"<br />
|-<br />
! ITCM mirror address<br />
! ITCM bootrom mirror address<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x01FF8000<br />
| <br />
| 0x0<br />
| 0x3700<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFB700<br />
| 0x07FFB700<br />
| 0x3700<br />
| 0x100<br />
| The unprotected ARM9-bootrom code copies code from unprotected bootrom to 0x07FFB700(ITCM mirror) size 0x100, then calls the code at 0x07FFB700. The code located here is the code used for disabling access to the bootroms.<br />
|-<br />
| 0x01FFB800<br />
| <br />
| 0x3800<br />
| 0x4<br />
| This is always 0xDEADB00F.<br />
|-<br />
| 0x01FFB804<br />
| <br />
| 0x3804<br />
| 0x4<br />
| This is the u32 DeviceId.<br />
|-<br />
| 0x01FFB808<br />
| <br />
| 0x3808<br />
| 0x10<br />
| This is the fall-back keyY used for movable.sed keyY when movable.sed doesn't exist in NAND(the last two words here are used on retail for generating console-unique TWL keydata/etc). This is also used for "LocalFriendCodeSeed", etc.<br />
|-<br />
| 0x01FFB818<br />
| <br />
| 0x3818<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x01FFB819<br />
| <br />
| 0x3819<br />
| 0x1<br />
| This is the [[CTCert]] issuer type: 0 = retail "Nintendo CA - G3_NintendoCTR2prod", non-zero = dev "Nintendo CA - G3_NintendoCTR2dev".<br />
|-<br />
| 0x01FFB81A<br />
| <br />
| 0x381A<br />
| 0x6<br />
| ?<br />
|-<br />
| 0x01FFB820<br />
| <br />
| 0x3820<br />
| 0x4<br />
| This is the CTCert ECDSA exponent, this is byte-swapped when *((u8*)(0x01FFB800+0x18)) is >=5.<br />
|-<br />
| 0x01FFB824<br />
| <br />
| 0x3824<br />
| 0x2<br />
| ?<br />
|-<br />
| 0x01FFB826<br />
| <br />
| 0x3826<br />
| 0x1E<br />
| This is the CTCert ECDSA privk.<br />
|-<br />
| 0x01FFB844<br />
| <br />
| 0x3844<br />
| 0x3C<br />
| This is the CTCert ECDSA signature.<br />
|-<br />
| 0x01FFB880<br />
| <br />
| 0x3880<br />
| 0x80<br />
| This is all-zero.<br />
|-<br />
| 0x01FFB900<br />
| <br />
| 0x3900<br />
| 0x200<br />
| This is the 0x200-bytes from NAND sector0.<br />
|-<br />
| 0x01FFBB00<br />
| <br />
| 0x3B00<br />
| 0x200<br />
| This is the 0x200-bytes from the plaintext NAND firm partition FIRM header, read by bootrom.<br />
|-<br />
| 0x01FFBD00<br />
| <br />
| 0x3D00<br />
| 0x200<br />
| Unknown, not used by [[FIRM]]. Probably RSA related going by the data right after this? These are not console-unique.<br />
|-<br />
| 0x01FFBF00<br />
| <br />
| 0x3F00<br />
| 0x100<br />
| This is the RSA-2048 modulo for [[RSA_Registers|RSA]]-engine slot2.<br />
|-<br />
| 0x01FFC000<br />
| <br />
| 0x4000<br />
| 0x100<br />
| This is the RSA-2048 modulo for RSA-engine slot3.<br />
|-<br />
| 0x01FFC100<br />
| <br />
| 0x4100<br />
| 0x800<br />
| Unknown, not console-unique.<br />
|-<br />
| 0x01FFC900<br />
| 0x07FFC900<br />
| 0x4900<br />
| 0x400<br />
| The unprotected ARM9-bootrom copies data to 0x07FFC900(mirror of 0x01FFC900) size 0x400. This data is copied from AXI WRAM, initialized by ARM11-bootrom(the addr used for the src is determined by [[CONFIG_Registers|REG_UNITINFO]]). These are RSA modulus: retailsrcptr = 0x1FFFD000, devsrvptr = 0x1FFFD400.<br />
* The first 0x100-bytes here is the RSA-2048 modulo for the CFA NCCH header, and for the gamecard NCSD header.<br />
* 0x01FFCA00 is the RSA-2048 modulo for the CXI accessdesc signature, written to rsaengine keyslot1 by NATIVE_FIRM.<br />
* 0x01FFCB00 size 0x200 is unknown, probably RSA related, these aren't used by [[FIRM]](these are not console-unique).<br />
|-<br />
| 0x01FFCD00<br />
| <br />
| 0x4D00<br />
| 0x80<br />
| Unknown, not used by [[FIRM]]. This isn't console-unique.<br />
The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function, when non-zero it clears this block and continues to do the key generation. Otherwise when this block was already all-zero, it immediately returns.<br />
|-<br />
| 0x01FFCD80<br />
| <br />
| 0x4D80<br />
| 0x64<br />
| 0x01FFCD84 size 0x10-bytes is the NAND CID(the 0x64-byte region at 0x01FFCD80 is initialized by Process9 + ARM9-bootrom). The u32 at 0x01FFCDC4 is the total number of NAND sectors, read from a MMC command.<br />
|-<br />
| 0x01FFCDE4<br />
| <br />
| 0x4DE4<br />
| 0x21C<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFD000<br />
| 0x07FFD000<br />
| 0x5000<br />
| 0x2470<br />
| The unprotected ARM9-bootrom copies 0x1FFFA000(AXIWRAM mem initialized by ARM11-bootrom) size 0x2470 to 0x07FFD000(mirror of 0x01FFD000). This block contains DSi keys.<br />
|-<br />
| 0x01FFF470<br />
| <br />
| 0x7470<br />
| 0xB90<br />
| Uninitialized memory.<br />
0x01FFFC00 size 0x100-bytes starting with [[9.5.0-22|9.5.0-X]] is the FIRM header used during FIRM-launching.<br />
|}<br />
<br />
=[[New_3DS]] physical 0x1F000000 memory=<br />
This area is used by [[QTM Services]](starting at offset 0x200000, size 0x180000). This area is not accessible to the GPU on the old 3DS. The old 3DS and New 3DS GSP module has vaddr->physaddr conversion code for this entire region. On the New 3DS, only the first 0x200000-bytes (half of this memory) are accessible to the GPU.<br />
<br />
=Memory map by firmware=<br />
* [[Virtual address mapping FW0B]]<br />
* [[Virtual address mapping FW1F]]<br />
* [[Virtual address mapping FW25]]<br />
* [[Virtual address mapping FW2E]]<br />
* [[Virtual address mapping FW37]]<br />
* [[Virtual address mapping FW38‎]]<br />
* [[Virtual address mapping FW3F]]<br />
* FW49([[9.6.0-24|9.6.0-X]]) ARM11-kernel vmem mapping is identical to FW40([[9.5.0-22|9.5.0-X]]).<br />
<br />
<br />
* [[Virtual address mapping TWLFIRM04]]<br />
<br />
<br />
* [[Virtual address mapping New3DS v8.1]]<br />
* [[Virtual address mapping New3DS v9.0]]<br />
* [[Virtual address mapping New3DS v9.2]]<br />
<br />
=ARM11 Detailed physical memory map=<br />
18000000 - 18600000: VRAM<br />
<br />
1FF80000 - 1FFAB000: Kernel code<br />
1FFAB000 - 1FFF0000: SlabHeap [temporarily contains boot processes]<br />
1FFF0000 - 1FFF1000: ?<br />
1FFF1000 - 1FFF2000: ?<br />
1FFF2000 - 1FFF3000: ?<br />
1FFF3000 - 1FFF4000: ?<br />
1FFF4000 - 1FFF5000: Exception vectors<br />
1FFF5000 - 1FFF5800: Unused?<br />
1FFF5800 - 1FFF5C00: 256-entry L2 MMU table for VA FF4xx000<br />
1FFF5C00 - 1FFF6000: 256-entry L2 MMU table for VA FF5xx000<br />
1FFF6000 - 1FFF6400: 256-entry L2 MMU table for VA FF6xx000<br />
1FFF6400 - 1FFF6800: 256-entry L2 MMU table for VA FF7xx000<br />
1FFF6800 - 1FFF6C00: 256-entry L2 MMU table for VA FF8xx000<br />
1FFF6C00 - 1FFF7000: 256-entry L2 MMU table for VA FF9xx000<br />
1FFF7000 - 1FFF7400: 256-entry L2 MMU table for VA FFAxx000<br />
1FFF7400 - 1FFF7800: 256-entry L2 MMU table for VA FFBxx000<br />
1FFF7800 - 1FFF7C00: MMU table but unused?<br />
1FFF7C00 - 1FFF8000: 256-entry L2 MMU table for VA FFFxx000 <br />
1FFF8000 - 1FFFC000: 4096-entry L1 MMU table for VA xxx00000 (CPU 0)<br />
1FFFC000 - 20000000: 4096-entry L1 MMU table for VA xxx00000 (CPU 1)<br />
20000000 - 28000000: Main memory<br />
<br />
The entire FCRAM is cleared during NATIVE_FIRM boot. This is probably done by the ARM11 kernel(after loading [[FIRM]] launch parameters from FCRAM)?<br />
<br />
== FCRAM memory-regions layout ==<br />
{| class="wikitable" border="1"<br />
! [[Configuration_Memory#APPMEMTYPE|Configmem-APPMEMTYPE]] Value<br />
! Base address relative to FCRAM+0, for APPLICATION mem-region<br />
! Region size, for APPLICATION mem-region<br />
! Base address relative to FCRAM+0, for SYSTEM mem-region<br />
! Region size, for SYSTEM mem-region<br />
! Base address relative to FCRAM+0, for BASE mem-region<br />
! Region size, for BASE mem-region<br />
|-<br />
| 0 (default with regular 3DS kernel, used when the type is not 2-5)<br />
| 0x0<br />
| 0x04000000(64MB)<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 2<br />
| 0x0<br />
| 0x06000000(96MB)<br />
| 0x06000000<br />
| 0x00C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 3<br />
| 0x0<br />
| 0x05000000(80MB)<br />
| 0x05000000<br />
| 0x01C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 4<br />
| 0x0<br />
| 0x04800000(72MB)<br />
| 0x04800000<br />
| 0x02400000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 5<br />
| 0x0<br />
| 0x02000000(32MB)<br />
| 0x02000000<br />
| 0x04C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 6 (This is the default on New3DS. With [[New_3DS]] kernel this is the type used when the value is not 7)<br />
| 0x0<br />
| 0x07C00000(124MB)<br />
| 0x07C00000<br />
| 0x06400000<br />
| 0x0E000000<br />
| 0x02000000<br />
|-<br />
| 7<br />
| 0x0<br />
| 0x0B200000(178MB)<br />
| 0x0B200000<br />
| 0x02E00000<br />
| 0x0E000000<br />
| 0x02000000<br />
|}<br />
<br />
The SYSTEM mem-region size is calculated with: size = FCRAMTOTALSIZE - (APPLICATION_MEMREGIONSIZE + BASE_MEMREGIONSIZE).<br />
<br />
Support for type6/7 was [[NCCH/Extended Header|implemented]] in [[NS]] with [[8.0.0-18]], these are only supported in the [[New_3DS]] ARM11-kernel not the regular 3DS kernel. These two types are the only ones supported by the New3DS kernel.<br />
<br />
All memory allocated by the kernel itself for kernel use is located under BASE. Most system-modules run under the BASE memregion too.<br />
<br />
Free/used memory on [[4.5.0-10]] with Home Menu / Internet Browser, with the default APPMEMTYPE on retail:<br />
{| class="wikitable" border="1"<br />
! Region<br />
! Base address relative to FCRAM+0<br />
! Region size<br />
! Used memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Used memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
! Free memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Free memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
|-<br />
| APPLICATION<br />
| 0x0<br />
| 0x04000000<br />
| 0x0<br />
| <br />
| 0x04000000<br />
| <br />
|-<br />
| SYSTEM<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x01488000<br />
| 0x02A50000<br />
| 0x01778000<br />
| 0x001B0000<br />
|-<br />
| BASE<br />
| 0x06C00000<br />
| 0x01400000<br />
| 0x01202000<br />
| 0x01236000<br />
| 0x001FE000<br />
| 0x001CA000<br />
|}<br />
<br />
=ARM11 Detailed virtual memory map=<br />
(valid only for FW0B, see [[#Memory map by firmware|Memory map by firmware]] for subsequent versions)<br />
<br />
E8000000 - E8600000: mapped VRAM (18000000 - 18600000)<br />
<br />
EFF00000 - F0000000: mapped Internal memory (1FF00000 - 20000000)<br />
F0000000 - F8000000: mapped Main memory<br />
<br />
FF401000 - FF402000: mapped ? (27FC7000 - 27FC8000)<br />
<br />
FF403000 - FF404000: mapped ? (27FC2000 - 27FC3000)<br />
<br />
FF405000 - FF406000: mapped ? (27FBB000 - 27FBC000)<br />
<br />
FF407000 - FF408000: mapped ? (27FB3000 - 27FB4000)<br />
<br />
FF409000 - FF40A000: mapped ? (27F8E000 - 27F8F000)<br />
<br />
FFF00000 - FFF45000: mapped SlabHeap <br />
<br />
FFF60000 - FFF8B000: mapped Kernel code<br />
<br />
FFFCC000 - FFFCD000: mapped IO [[I2C|I2C]] second bus (10144000 - 10145000)<br />
<br />
FFFCE000 - FFFCF000: mapped IO PDC([[LCD]]) (10400000 - 10401000)<br />
<br />
FFFD0000 - FFFD1000: mapped IO PDN (10141000 - 10142000)<br />
<br />
FFFD2000 - FFFD3000: mapped IO PXI (10163000 - 10164000)<br />
<br />
FFFD4000 - FFFD5000: mapped IO PAD (10146000 - 10147000)<br />
<br />
FFFD6000 - FFFD7000: mapped IO LCD (10202000 - 10203000)<br />
<br />
FFFD8000 - FFFD9000: mapped IO DSP (10140000 - 10141000)<br />
<br />
FFFDA000 - FFFDB000: mapped IO XDMA (10200000 - 10201000)<br />
<br />
FFFDC000 - FFFE0000: mapped ? (1FFF8000 - 1FFFC000)<br />
<br />
FFFE1000 - FFFE2000: mapped ? (1FFF0000 - 1FFF1000)<br />
<br />
FFFE3000 - FFFE4000: mapped ? (1FFF2000 - 1FFF3000)<br />
<br />
FFFE5000 - FFFE9000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFEA000 - FFFEB000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFEC000 - FFFED000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFEE000 - FFFF0000: mapped IO IRQ (17E00000 - 17E02000)<br />
<br />
FFFF0000 - FFFF1000: mapped Exception vectors<br />
<br />
FFFF2000 - FFFF6000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFF7000 - FFFF8000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFF9000 - FFFFA000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFFB000 - FFFFE000: mapped L2 MMU tables (1FFF5000 - 1FFF8000)<br />
<br />
==0xFF4XX000==<br />
Each [[KThread|thread]] is allocated a 0x1000-byte page in this region: the first page at 0xFF401000 is for the first created thread, 0xFF403000 for the second thread. This region is used to store the SVC-mode stack for the thread, and thread context data used for context switching. When the IRQ handler, prefetch/data abort handlers, and undefined instruction handler are entered where the SPSR-mode=user, these handlers then store LR+SPSR for the current mode on the SVC-mode stack, then these handlers switch to SVC-mode.<br />
<br />
This page does not contain a dedicated block for storing R0-PC(etc). For user-mode, the user-mode regs are instead saved on the SVC-mode stack when IRQs such as timers for context switching are triggered.<br />
<br />
Structure of this page, relative to page_endaddr-0xC8:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| <br />
| SVC-mode stack-top. The 0x10-byte SVC-access-control for this thread is also located here, which is checked by the SVC-handler.<br />
|-<br />
| 0x18<br />
| 0x28<br />
| SVC-mode saved registers, stored/loaded during context switches: R4-R9, SL, FP, SP, LR. After loading these registers, the context switch code will jump to the loaded LR.<br />
|-<br />
| 0xC0<br />
| 4<br />
| fpexc from vmrs, used during context switches with the above saved registers.<br />
|}<br />
<br />
For NATIVE_FIRM the memory pages for this region are located in FCRAM, however for TWL_FIRM these are located in AXI WRAM. For TWL_FIRM v6704 the first thread's page for this region is located at physical address 0x1FF93000, the next one at 0x1FF92000, etc.<br />
<br />
=ARM11 User-land memory regions=<br />
==NATIVE_FIRM/SAFE_MODE_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Region Max Size<br />
! Address-range available for svcMapMemoryBlock<br />
! Description<br />
|-<br />
| 0x00100000 / 0x14000000<br />
| <br />
| 0x03F00000<br />
| No<br />
| The [[ExeFS]]:/.code is loaded here, executables must be loaded to the 0x00100000 region when the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only applies when this flag is clear. Executables are usually loaded to 0x14000000 when the exheader "special memory" flag is set, however this address can be arbitrary.<br />
|-<br />
| 0x04000000<br />
| ?<br />
| ?<br />
| No<br />
| Used for mapping buffers during IPC, see [[IPC Command Structure]].<br />
|-<br />
| 0x08000000<br />
| Main stack physaddr - <heap size for the allocated vaddr 0x08000000 memory><br />
| 0x08000000<br />
| Yes<br />
| Heap mapped by [[SVC|ControlMemory]]<br />
|-<br />
| 0x10000000-StackSize<br />
| .bss physical address - total stack pages<br />
| StackSize from process exheader<br />
| <br />
| Stack for the main-thread, initialized by the ARM11 kernel. The StackSize from the exheader is usually 0x4000, therefore the stack-bottom is usually 0x0FFFC000. The stack for the other threads is normally located in the process .data section however this can be arbitrary.<br />
|-<br />
| 0x10000000<br />
| <br />
| 0x04000000<br />
| Yes<br />
| [[SVC|Shared]] memory<br />
|-<br />
| 0x14000000<br />
| FCRAM+0<br />
| 0x08000000<br />
| No<br />
| Can be mapped by [[SVC|ControlMemory]], this is used for processes' [[SVC|LINEAR]]/GSP heap.<br />
|-<br />
| 0x1E800000<br />
| 0x1F000000<br />
| 0x00400000<br />
| No<br />
| [[New_3DS]] additional memory, access to this is specified by the exheader. Added with [[8.0.0-18]], see above section regarding this memory.<br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x01000000<br />
| No<br />
| [[IO]] registers, the mapped IO pages which each process can access is specified in the [[NCCH#CXI|CXI]] exheader.(Applications normally don't have access to registers in this range)<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| No<br />
| VRAM, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| No<br />
| DSP memory, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF80000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory]], all processes have read-only access to this.<br />
|-<br />
| 0x1FF81000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory|Shared]] page, all processes have read-access to this. Write access to this is specified by the exheader "Shared page writing" kernel flag.<br />
|-<br />
| 0x1FF82000<br />
| ?<br />
| ?<br />
| No<br />
| [[Thread Local Storage]]<br />
|-<br />
| 0x30000000<br />
| FCRAM+0<br />
| 0x08000000(Old3DS) / 0x10000000([[New_3DS]])<br />
| No<br />
| This LINEAR memory mapping was added with [[8.0.0-18]], see [[SVC#enum_MemoryOperation|here]]. This replaces the original 0x14000000 mapping, for system(memory-region=BASE)/newer titles. The Old3DS kernel uses size 0x08000000 for LINEAR-memory address range checks, while the New3DS kernel uses size 0x10000000 for those range checks. Old3DS/New3DS system-module code doing vaddr->phys-addr conversion uses size 0x10000000.<br />
|-<br />
| 0x20000000 / 0x40000000<br />
| <br />
| <br />
| <br />
| This is the end-address of userland memory, memory under this address is process-unique. Memory starting at this address is only accessible in privileged-mode. This address was changed from 0x20000000 to 0x40000000 with [[8.0.0-18]].<br />
|}<br />
<br />
All executable pages are read-only, and data pages have the execute-never permission set. Normally .text from the loaded ExeFS:/.code is the only mapped executable memory. Executable [[RO Services|CROs]] can be loaded into memory, once loaded the CRO .text section memory page permissions are changed via [[SVC|ControlProcessMemory]] from RW- to R-X. The address and size of each ExeFS:/.code section is stored in the exheader, the permissions for each section is: .text R-X, .rodata R--, .data RW-, and .bss RW-. The loaded .code is mapped to the addresses specified in the exheader by the ARM11 kernel. The stack permissions is initialized by the ARM11 kernel: RW-. The heap permissions is normally RW-.<br />
<br />
All userland memory is mapped with RW permissions for privileged-mode. However, normally the ARM11 kernel only uses userland read/write instructions(or checks that the memory can be written from userland first) for accessing memory specified by [[SVC|SVCs]].<br />
<br />
Processes can't directly access memory for other processes. When service [[Services API|commands]] are used, the kernel maps memory in the destination process for input/output buffers, where the addresses in the command received by the process is replaced by this mapped memory. When this is an input buffer, the buffer data is copied to the mapped memory. When this is an output buffer, the data stored in the mapped memory is copied to the destination buffer specified in the command.<br />
<br />
The physical address which memory for the application memory-type is mapped to begins at FCRAM+0, the total memory allocated for this memory-type is stored in [[Configuration_Memory]]. Applications' .text + .rodata + .data under the application memory-type is mapped at FCRAM + APPMEMALLOC - (aligned page-size for .text + .rodata + .data). The application .bss is mapped at CODEADDR - .bss size aligned down to the page size.<br />
<br />
==TWL_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Size<br />
! Description<br />
|-<br />
| 0x00100000<br />
| 0x1FFAB000 (with newer TWL_FIRM such as v6704 this is located at 0x1FFAC000)<br />
| 0x00055000<br />
| Code + .(ro)data copied from the process 0x00300000 region is located here(.bss is located here as well).<br />
|-<br />
| 0x00155000<br />
| 0x18555000<br />
| 0x000AB000<br />
| <br />
|-<br />
| 0x00200000<br />
| 0x18500000<br />
| 0x00100000<br />
| <br />
|-<br />
| 0x00300000<br />
| 0x24000000<br />
| 0x04000000<br />
| The beginning of the ARM11 process .text is located here.<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x07E00000<br />
| <br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x00400000<br />
| [[IO]]<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| This is mapped to the DSP memory.<br />
|}<br />
<br />
The above regions are mapped by the ARM11 kernel. Later when the ARM11 process uses [[SVC|svcKernelSetState]] with type4, the kernel unmaps(?) the following regions: 0x00300000..0x04300000, 0x08000000..0x0FE00000, and 0x10000000..0xF8000000.<br />
<br />
=== Detailed TWL_FIRM ARM11 Memory ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Process Virtual Address<br />
! Physical Address<br />
! Size<br />
! Description<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x01000000*4<br />
| DS(i) 0x02000000 RAM. Vaddr = (DSRAMOffset*4) + 0x08000000, where DSRAMOffset is DSRAMAddr-0x02000000.<br />
|-<br />
| 0x0FC00000<br />
| 0x27C00000<br />
| <br />
| Loaded SRL binary, initially the dev DSi launcher SRL is located here(copied here by the ARM11 process).<br />
|-<br />
| 0x0FD00000<br />
| 0x27D00000<br />
| <br />
| The data located here is copied to here by the ARM11 process. The data located here is a TWL NAND [http://dsibrew.org/wiki/Bootloader bootloader] image, using the same format+encryption/verification methods as the DSi NAND bootloader(stage2). The keyX for this bootloader keyslot is initially set to the retail DSi key-data, however when TWL_FIRM is launched this keyX key-data is replaced with a separate keyX. TWL_FIRM can use either the retail DSi bootloader RSA-1024 modulo, or a seperate modulo: normally only the latter is used(the former is only used when loading the image from FS instead of FCRAM). When using the image from FCRAM(default code-path), TWL_FIRM will not calculate+check the hashes for the bootloader code binaries(this is done when loading from FS however).<br />
|-<br />
| 0x0FDF7000<br />
| 0x27DF7000<br />
| 0x1000<br />
| SRL header<br />
|}<br />
<br />
= System memory details =<br />
0xFFFF9000 Pointer to the current KThread instance<br />
0xFFFF9004 Pointer to the current KProcess instance<br />
0xFFFF9010 Pointer to the last KThread to encounter an exception<br />
<br />
0x8000040 Pointer to the current KThread instance on the ARM9<br />
0x8000044 Pointer to the current KProcess instance on the ARM9<br />
<br />
= Handles =<br />
The handle 0xFFFF8001 is a reference to the current KProcess.<br />
The handle 0xFFFF8000 is a reference to the current KThread.<br />
<br />
= IO Process/Kernel virtual addressing equivalence = <br />
It seems an IO register's process virtual address can be calculated by adding 0xEB00000 to its physical address.<br />
<br />
= VRAM Map While Running System Applets =<br />
*0x1E6000-0x22C500 -- top screen 3D left framebuffer 0(240x400x3) (The "3D right first-framebuf" addr stored in the LCD register is set to this, when the 3D is set to "off")<br />
*0x22C800-0x272D00 -- top screen 3D left framebuffer 1(240x400x3)<br />
*0x273000-0x2B9500 -- top screen 3D right framebuffer 0(240x400x3)<br />
*0x2B9800-0x2FFD00 -- top screen 3D right framebuffer 1(240x400x3)<br />
*0x48F000-0x4C7400 -- bottom screen framebuffer 0(240x320x3)<br />
*0x4C7800-0x4FF800 -- bottom screen framebuffer 1(240x320x3)<br />
<br />
These LCD framebuffer addresses are not changed by the system when launching regular applications, the application itself handles that if needed. These VRAM framebuffers are cleared when launching regular applications.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Memory_layout&diff=12695
Memory layout
2015-05-25T06:17:45Z
<p>Lectem: /* ARM11 Physical memory regions */</p>
<hr />
<div>=ARM11 Physical memory regions =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00000000<br />
| 0x00010000<br />
| Bootrom (super secret code/data @ 0x8000)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00010000<br />
| 0x00010000<br />
| Bootrom mirror<br />
|-<br />
| style="background: green" | Yes<br />
| 0x10000000<br />
|?<br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x17E00000<br />
| 0x00002000<br />
| MPCore private memory region<br />
<br />
|-<br />
| style="background: red" | No<br />
| 0x17E10000<br />
| 0x00001000<br />
| ?<br />
|-<br />
| style="background: green" | Yes<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM (divided in two banks, VRAM and VRAMB)<br />
|-<br />
| style="background: red" | No<br />
| 0x1F000000<br />
| 0x00400000<br />
| [[New_3DS]] additional memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF00000<br />
| 0x00080000<br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF80000<br />
| 0x00080000<br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| 0x20000000<br />
| 0x08000000<br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| 0x28000000<br />
| 0x08000000<br />
| [[New_3DS]] FCRAM extension<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFFF0000<br />
| 0x00010000<br />
| Bootrom mirror<br />
|}<br />
<br />
=ARM9 Physical memory regions =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| 0x00000000<br />
| 0x08000000<br />
| Instruction TCM, repeating each 0x8000 bytes.<br />
|-<br />
| style="background: green" | Yes<br />
| 0x01FF8000<br />
| 0x00008000<br />
| Instruction TCM (Accessed by the kernel and process by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x07FF8000<br />
| 0x00008000<br />
| Instruction TCM (Accessed by bootrom by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| 0x08000000<br />
| 0x00100000<br />
| ARM9-only internal memory (ARM7's internal regions are mapped here as well)<br />
|-<br />
| style="background: red" | No<br />
| 0x08100000<br />
| 0x00080000<br />
| [[New_3DS]] ARM9-only extension, only enabled when a certain [[CONFIG_Registers|CONFIG]] register is set.<br />
|-<br />
| style="background: green" | Yes<br />
| 0x10000000<br />
| 0x08000000<br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF00000<br />
| 0x00080000<br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| 0x1FF80000<br />
| 0x00080000<br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| 0x20000000<br />
| 0x08000000<br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| 0x28000000<br />
| 0x08000000<br />
| [[New_3DS]] FCRAM extension<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFF00000<br />
| 0x00004000<br />
| Data TCM (Mapped during bootrom)<br />
|-<br />
| style="background: green" | Yes<br />
| 0xFFFF0000<br />
| 0x00010000<br />
| Bootrom, the main region is at +0x8000, which is disabled during system boot.<br />
|}<br />
<br />
==ARM9 MPU regions==<br />
For the below instruction permissions: RO = memory is executable, while None = not-executable.<br />
<br />
===NATIVE_FIRM/SAFE_MODE_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. >=[[8.0.0-18|8.0.0-X]]: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x10100000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. >=[[8.0.0-18|8.0.0-X]]: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08020000<br />
| <[[3.0.0-5]]: 64KB/0x10000. >=[[3.0.0-5]]: 32KB/0x8000.<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|}<br />
<br />
The above is the MPU region settings setup by the ARM9-kernel in the crt0.<br />
<br />
The New3DS ARM9-kernel MPU region settings are the same as the Old3DS MPU region settings for >=[[8.0.0-18|8.0.0-X]].<br />
<br />
At the start of the Process9 function executed in kernel-mode via svc7b during firm-launching, it changes some MPU region settings. At the end of that function, before it uses the ARM9/ARM11 entrypoint fields, it disables MPU.<br />
<br />
===New3DS [[FIRM|ARM9-loader]]===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 2MB/0x200000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| None<br />
| None<br />
|}<br />
<br />
MPU regions 4-7 are disabled. Note that the entire ARM9-loader runs in SVC-mode.<br />
<br />
===TWL_FIRM/AGB_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. New3DS: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 2MB/0x200000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x1FF00000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. New3DS: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| <[[3.0.0-5|3.0.0-X]]: 256KB/0x40000. >=[[3.0.0-5|3.0.0-X]]: 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08080000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|}<br />
<br />
==ARM9 ITCM==<br />
{| class="wikitable" border="1"<br />
|-<br />
! ITCM mirror address<br />
! ITCM bootrom mirror address<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x01FF8000<br />
| <br />
| 0x0<br />
| 0x3700<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFB700<br />
| 0x07FFB700<br />
| 0x3700<br />
| 0x100<br />
| The unprotected ARM9-bootrom code copies code from unprotected bootrom to 0x07FFB700(ITCM mirror) size 0x100, then calls the code at 0x07FFB700. The code located here is the code used for disabling access to the bootroms.<br />
|-<br />
| 0x01FFB800<br />
| <br />
| 0x3800<br />
| 0x4<br />
| This is always 0xDEADB00F.<br />
|-<br />
| 0x01FFB804<br />
| <br />
| 0x3804<br />
| 0x4<br />
| This is the u32 DeviceId.<br />
|-<br />
| 0x01FFB808<br />
| <br />
| 0x3808<br />
| 0x10<br />
| This is the fall-back keyY used for movable.sed keyY when movable.sed doesn't exist in NAND(the last two words here are used on retail for generating console-unique TWL keydata/etc). This is also used for "LocalFriendCodeSeed", etc.<br />
|-<br />
| 0x01FFB818<br />
| <br />
| 0x3818<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x01FFB819<br />
| <br />
| 0x3819<br />
| 0x1<br />
| This is the [[CTCert]] issuer type: 0 = retail "Nintendo CA - G3_NintendoCTR2prod", non-zero = dev "Nintendo CA - G3_NintendoCTR2dev".<br />
|-<br />
| 0x01FFB81A<br />
| <br />
| 0x381A<br />
| 0x6<br />
| ?<br />
|-<br />
| 0x01FFB820<br />
| <br />
| 0x3820<br />
| 0x4<br />
| This is the CTCert ECDSA exponent, this is byte-swapped when *((u8*)(0x01FFB800+0x18)) is >=5.<br />
|-<br />
| 0x01FFB824<br />
| <br />
| 0x3824<br />
| 0x2<br />
| ?<br />
|-<br />
| 0x01FFB826<br />
| <br />
| 0x3826<br />
| 0x1E<br />
| This is the CTCert ECDSA privk.<br />
|-<br />
| 0x01FFB844<br />
| <br />
| 0x3844<br />
| 0x3C<br />
| This is the CTCert ECDSA signature.<br />
|-<br />
| 0x01FFB880<br />
| <br />
| 0x3880<br />
| 0x80<br />
| This is all-zero.<br />
|-<br />
| 0x01FFB900<br />
| <br />
| 0x3900<br />
| 0x200<br />
| This is the 0x200-bytes from NAND sector0.<br />
|-<br />
| 0x01FFBB00<br />
| <br />
| 0x3B00<br />
| 0x200<br />
| This is the 0x200-bytes from the plaintext NAND firm partition FIRM header, read by bootrom.<br />
|-<br />
| 0x01FFBD00<br />
| <br />
| 0x3D00<br />
| 0x200<br />
| Unknown, not used by [[FIRM]]. Probably RSA related going by the data right after this? These are not console-unique.<br />
|-<br />
| 0x01FFBF00<br />
| <br />
| 0x3F00<br />
| 0x100<br />
| This is the RSA-2048 modulo for [[RSA_Registers|RSA]]-engine slot2.<br />
|-<br />
| 0x01FFC000<br />
| <br />
| 0x4000<br />
| 0x100<br />
| This is the RSA-2048 modulo for RSA-engine slot3.<br />
|-<br />
| 0x01FFC100<br />
| <br />
| 0x4100<br />
| 0x800<br />
| Unknown, not console-unique.<br />
|-<br />
| 0x01FFC900<br />
| 0x07FFC900<br />
| 0x4900<br />
| 0x400<br />
| The unprotected ARM9-bootrom copies data to 0x07FFC900(mirror of 0x01FFC900) size 0x400. This data is copied from AXI WRAM, initialized by ARM11-bootrom(the addr used for the src is determined by [[CONFIG_Registers|REG_UNITINFO]]). These are RSA modulus: retailsrcptr = 0x1FFFD000, devsrvptr = 0x1FFFD400.<br />
* The first 0x100-bytes here is the RSA-2048 modulo for the CFA NCCH header, and for the gamecard NCSD header.<br />
* 0x01FFCA00 is the RSA-2048 modulo for the CXI accessdesc signature, written to rsaengine keyslot1 by NATIVE_FIRM.<br />
* 0x01FFCB00 size 0x200 is unknown, probably RSA related, these aren't used by [[FIRM]](these are not console-unique).<br />
|-<br />
| 0x01FFCD00<br />
| <br />
| 0x4D00<br />
| 0x80<br />
| Unknown, not used by [[FIRM]]. This isn't console-unique.<br />
The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function, when non-zero it clears this block and continues to do the key generation. Otherwise when this block was already all-zero, it immediately returns.<br />
|-<br />
| 0x01FFCD80<br />
| <br />
| 0x4D80<br />
| 0x64<br />
| 0x01FFCD84 size 0x10-bytes is the NAND CID(the 0x64-byte region at 0x01FFCD80 is initialized by Process9 + ARM9-bootrom). The u32 at 0x01FFCDC4 is the total number of NAND sectors, read from a MMC command.<br />
|-<br />
| 0x01FFCDE4<br />
| <br />
| 0x4DE4<br />
| 0x21C<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFD000<br />
| 0x07FFD000<br />
| 0x5000<br />
| 0x2470<br />
| The unprotected ARM9-bootrom copies 0x1FFFA000(AXIWRAM mem initialized by ARM11-bootrom) size 0x2470 to 0x07FFD000(mirror of 0x01FFD000). This block contains DSi keys.<br />
|-<br />
| 0x01FFF470<br />
| <br />
| 0x7470<br />
| 0xB90<br />
| Uninitialized memory.<br />
0x01FFFC00 size 0x100-bytes starting with [[9.5.0-22|9.5.0-X]] is the FIRM header used during FIRM-launching.<br />
|}<br />
<br />
=[[New_3DS]] physical 0x1F000000 memory=<br />
This area is used by [[QTM Services]](starting at offset 0x200000, size 0x180000). This area is not accessible to the GPU on the old 3DS. The old 3DS and New 3DS GSP module has vaddr->physaddr conversion code for this entire region. On the New 3DS, only the first 0x200000-bytes (half of this memory) are accessible to the GPU.<br />
<br />
=Memory map by firmware=<br />
* [[Virtual address mapping FW0B]]<br />
* [[Virtual address mapping FW1F]]<br />
* [[Virtual address mapping FW25]]<br />
* [[Virtual address mapping FW2E]]<br />
* [[Virtual address mapping FW37]]<br />
* [[Virtual address mapping FW38‎]]<br />
* [[Virtual address mapping FW3F]]<br />
* FW49([[9.6.0-24|9.6.0-X]]) ARM11-kernel vmem mapping is identical to FW40([[9.5.0-22|9.5.0-X]]).<br />
<br />
<br />
* [[Virtual address mapping TWLFIRM04]]<br />
<br />
<br />
* [[Virtual address mapping New3DS v8.1]]<br />
* [[Virtual address mapping New3DS v9.0]]<br />
* [[Virtual address mapping New3DS v9.2]]<br />
<br />
=ARM11 Detailed physical memory map=<br />
18000000 - 18600000: VRAM<br />
<br />
1FF80000 - 1FFAB000: Kernel code<br />
1FFAB000 - 1FFF0000: SlabHeap [temporarily contains boot processes]<br />
1FFF0000 - 1FFF1000: ?<br />
1FFF1000 - 1FFF2000: ?<br />
1FFF2000 - 1FFF3000: ?<br />
1FFF3000 - 1FFF4000: ?<br />
1FFF4000 - 1FFF5000: Exception vectors<br />
1FFF5000 - 1FFF5800: Unused?<br />
1FFF5800 - 1FFF5C00: 256-entry L2 MMU table for VA FF4xx000<br />
1FFF5C00 - 1FFF6000: 256-entry L2 MMU table for VA FF5xx000<br />
1FFF6000 - 1FFF6400: 256-entry L2 MMU table for VA FF6xx000<br />
1FFF6400 - 1FFF6800: 256-entry L2 MMU table for VA FF7xx000<br />
1FFF6800 - 1FFF6C00: 256-entry L2 MMU table for VA FF8xx000<br />
1FFF6C00 - 1FFF7000: 256-entry L2 MMU table for VA FF9xx000<br />
1FFF7000 - 1FFF7400: 256-entry L2 MMU table for VA FFAxx000<br />
1FFF7400 - 1FFF7800: 256-entry L2 MMU table for VA FFBxx000<br />
1FFF7800 - 1FFF7C00: MMU table but unused?<br />
1FFF7C00 - 1FFF8000: 256-entry L2 MMU table for VA FFFxx000 <br />
1FFF8000 - 1FFFC000: 4096-entry L1 MMU table for VA xxx00000 (CPU 0)<br />
1FFFC000 - 20000000: 4096-entry L1 MMU table for VA xxx00000 (CPU 1)<br />
20000000 - 28000000: Main memory<br />
<br />
The entire FCRAM is cleared during NATIVE_FIRM boot. This is probably done by the ARM11 kernel(after loading [[FIRM]] launch parameters from FCRAM)?<br />
<br />
== FCRAM memory-regions layout ==<br />
{| class="wikitable" border="1"<br />
! [[Configuration_Memory#APPMEMTYPE|Configmem-APPMEMTYPE]] Value<br />
! Base address relative to FCRAM+0, for APPLICATION mem-region<br />
! Region size, for APPLICATION mem-region<br />
! Base address relative to FCRAM+0, for SYSTEM mem-region<br />
! Region size, for SYSTEM mem-region<br />
! Base address relative to FCRAM+0, for BASE mem-region<br />
! Region size, for BASE mem-region<br />
|-<br />
| 0 (default with regular 3DS kernel, used when the type is not 2-5)<br />
| 0x0<br />
| 0x04000000(64MB)<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 2<br />
| 0x0<br />
| 0x06000000(96MB)<br />
| 0x06000000<br />
| 0x00C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 3<br />
| 0x0<br />
| 0x05000000(80MB)<br />
| 0x05000000<br />
| 0x01C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 4<br />
| 0x0<br />
| 0x04800000(72MB)<br />
| 0x04800000<br />
| 0x02400000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 5<br />
| 0x0<br />
| 0x02000000(32MB)<br />
| 0x02000000<br />
| 0x04C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 6 (This is the default on New3DS. With [[New_3DS]] kernel this is the type used when the value is not 7)<br />
| 0x0<br />
| 0x07C00000(124MB)<br />
| 0x07C00000<br />
| 0x06400000<br />
| 0x0E000000<br />
| 0x02000000<br />
|-<br />
| 7<br />
| 0x0<br />
| 0x0B200000(178MB)<br />
| 0x0B200000<br />
| 0x02E00000<br />
| 0x0E000000<br />
| 0x02000000<br />
|}<br />
<br />
The SYSTEM mem-region size is calculated with: size = FCRAMTOTALSIZE - (APPLICATION_MEMREGIONSIZE + BASE_MEMREGIONSIZE).<br />
<br />
Support for type6/7 was [[NCCH/Extended Header|implemented]] in [[NS]] with [[8.0.0-18]], these are only supported in the [[New_3DS]] ARM11-kernel not the regular 3DS kernel. These two types are the only ones supported by the New3DS kernel.<br />
<br />
All memory allocated by the kernel itself for kernel use is located under BASE. Most system-modules run under the BASE memregion too.<br />
<br />
Free/used memory on [[4.5.0-10]] with Home Menu / Internet Browser, with the default APPMEMTYPE on retail:<br />
{| class="wikitable" border="1"<br />
! Region<br />
! Base address relative to FCRAM+0<br />
! Region size<br />
! Used memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Used memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
! Free memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Free memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
|-<br />
| APPLICATION<br />
| 0x0<br />
| 0x04000000<br />
| 0x0<br />
| <br />
| 0x04000000<br />
| <br />
|-<br />
| SYSTEM<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x01488000<br />
| 0x02A50000<br />
| 0x01778000<br />
| 0x001B0000<br />
|-<br />
| BASE<br />
| 0x06C00000<br />
| 0x01400000<br />
| 0x01202000<br />
| 0x01236000<br />
| 0x001FE000<br />
| 0x001CA000<br />
|}<br />
<br />
=ARM11 Detailed virtual memory map=<br />
(valid only for FW0B, see [[#Memory map by firmware|Memory map by firmware]] for subsequent versions)<br />
<br />
E8000000 - E8600000: mapped VRAM (18000000 - 18600000)<br />
<br />
EFF00000 - F0000000: mapped Internal memory (1FF00000 - 20000000)<br />
F0000000 - F8000000: mapped Main memory<br />
<br />
FF401000 - FF402000: mapped ? (27FC7000 - 27FC8000)<br />
<br />
FF403000 - FF404000: mapped ? (27FC2000 - 27FC3000)<br />
<br />
FF405000 - FF406000: mapped ? (27FBB000 - 27FBC000)<br />
<br />
FF407000 - FF408000: mapped ? (27FB3000 - 27FB4000)<br />
<br />
FF409000 - FF40A000: mapped ? (27F8E000 - 27F8F000)<br />
<br />
FFF00000 - FFF45000: mapped SlabHeap <br />
<br />
FFF60000 - FFF8B000: mapped Kernel code<br />
<br />
FFFCC000 - FFFCD000: mapped IO [[I2C|I2C]] second bus (10144000 - 10145000)<br />
<br />
FFFCE000 - FFFCF000: mapped IO PDC([[LCD]]) (10400000 - 10401000)<br />
<br />
FFFD0000 - FFFD1000: mapped IO PDN (10141000 - 10142000)<br />
<br />
FFFD2000 - FFFD3000: mapped IO PXI (10163000 - 10164000)<br />
<br />
FFFD4000 - FFFD5000: mapped IO PAD (10146000 - 10147000)<br />
<br />
FFFD6000 - FFFD7000: mapped IO LCD (10202000 - 10203000)<br />
<br />
FFFD8000 - FFFD9000: mapped IO DSP (10140000 - 10141000)<br />
<br />
FFFDA000 - FFFDB000: mapped IO XDMA (10200000 - 10201000)<br />
<br />
FFFDC000 - FFFE0000: mapped ? (1FFF8000 - 1FFFC000)<br />
<br />
FFFE1000 - FFFE2000: mapped ? (1FFF0000 - 1FFF1000)<br />
<br />
FFFE3000 - FFFE4000: mapped ? (1FFF2000 - 1FFF3000)<br />
<br />
FFFE5000 - FFFE9000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFEA000 - FFFEB000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFEC000 - FFFED000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFEE000 - FFFF0000: mapped IO IRQ (17E00000 - 17E02000)<br />
<br />
FFFF0000 - FFFF1000: mapped Exception vectors<br />
<br />
FFFF2000 - FFFF6000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFF7000 - FFFF8000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFF9000 - FFFFA000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFFB000 - FFFFE000: mapped L2 MMU tables (1FFF5000 - 1FFF8000)<br />
<br />
==0xFF4XX000==<br />
Each [[KThread|thread]] is allocated a 0x1000-byte page in this region: the first page at 0xFF401000 is for the first created thread, 0xFF403000 for the second thread. This region is used to store the SVC-mode stack for the thread, and thread context data used for context switching. When the IRQ handler, prefetch/data abort handlers, and undefined instruction handler are entered where the SPSR-mode=user, these handlers then store LR+SPSR for the current mode on the SVC-mode stack, then these handlers switch to SVC-mode.<br />
<br />
This page does not contain a dedicated block for storing R0-PC(etc). For user-mode, the user-mode regs are instead saved on the SVC-mode stack when IRQs such as timers for context switching are triggered.<br />
<br />
Structure of this page, relative to page_endaddr-0xC8:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| <br />
| SVC-mode stack-top. The 0x10-byte SVC-access-control for this thread is also located here, which is checked by the SVC-handler.<br />
|-<br />
| 0x18<br />
| 0x28<br />
| SVC-mode saved registers, stored/loaded during context switches: R4-R9, SL, FP, SP, LR. After loading these registers, the context switch code will jump to the loaded LR.<br />
|-<br />
| 0xC0<br />
| 4<br />
| fpexc from vmrs, used during context switches with the above saved registers.<br />
|}<br />
<br />
For NATIVE_FIRM the memory pages for this region are located in FCRAM, however for TWL_FIRM these are located in AXI WRAM. For TWL_FIRM v6704 the first thread's page for this region is located at physical address 0x1FF93000, the next one at 0x1FF92000, etc.<br />
<br />
=ARM11 User-land memory regions=<br />
==NATIVE_FIRM/SAFE_MODE_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Region Max Size<br />
! Address-range available for svcMapMemoryBlock<br />
! Description<br />
|-<br />
| 0x00100000 / 0x14000000<br />
| <br />
| 0x03F00000<br />
| No<br />
| The [[ExeFS]]:/.code is loaded here, executables must be loaded to the 0x00100000 region when the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only applies when this flag is clear. Executables are usually loaded to 0x14000000 when the exheader "special memory" flag is set, however this address can be arbitrary.<br />
|-<br />
| 0x04000000<br />
| ?<br />
| ?<br />
| No<br />
| Used for mapping buffers during IPC, see [[IPC Command Structure]].<br />
|-<br />
| 0x08000000<br />
| Main stack physaddr - <heap size for the allocated vaddr 0x08000000 memory><br />
| 0x08000000<br />
| Yes<br />
| Heap mapped by [[SVC|ControlMemory]]<br />
|-<br />
| 0x10000000-StackSize<br />
| .bss physical address - total stack pages<br />
| StackSize from process exheader<br />
| <br />
| Stack for the main-thread, initialized by the ARM11 kernel. The StackSize from the exheader is usually 0x4000, therefore the stack-bottom is usually 0x0FFFC000. The stack for the other threads is normally located in the process .data section however this can be arbitrary.<br />
|-<br />
| 0x10000000<br />
| <br />
| 0x04000000<br />
| Yes<br />
| [[SVC|Shared]] memory<br />
|-<br />
| 0x14000000<br />
| FCRAM+0<br />
| 0x08000000<br />
| No<br />
| Can be mapped by [[SVC|ControlMemory]], this is used for processes' [[SVC|LINEAR]]/GSP heap.<br />
|-<br />
| 0x1E800000<br />
| 0x1F000000<br />
| 0x00400000<br />
| No<br />
| [[New_3DS]] additional memory, access to this is specified by the exheader. Added with [[8.0.0-18]], see above section regarding this memory.<br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x01000000<br />
| No<br />
| [[IO]] registers, the mapped IO pages which each process can access is specified in the [[NCCH#CXI|CXI]] exheader.(Applications normally don't have access to registers in this range)<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| No<br />
| VRAM, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| No<br />
| DSP memory, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF80000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory]], all processes have read-only access to this.<br />
|-<br />
| 0x1FF81000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory|Shared]] page, all processes have read-access to this. Write access to this is specified by the exheader "Shared page writing" kernel flag.<br />
|-<br />
| 0x1FF82000<br />
| ?<br />
| ?<br />
| No<br />
| [[Thread Local Storage]]<br />
|-<br />
| 0x30000000<br />
| FCRAM+0<br />
| 0x08000000(Old3DS) / 0x10000000([[New_3DS]])<br />
| No<br />
| This LINEAR memory mapping was added with [[8.0.0-18]], see [[SVC#enum_MemoryOperation|here]]. This replaces the original 0x14000000 mapping, for system(memory-region=BASE)/newer titles. The Old3DS kernel uses size 0x08000000 for LINEAR-memory address range checks, while the New3DS kernel uses size 0x10000000 for those range checks. Old3DS/New3DS system-module code doing vaddr->phys-addr conversion uses size 0x10000000.<br />
|-<br />
| 0x20000000 / 0x40000000<br />
| <br />
| <br />
| <br />
| This is the end-address of userland memory, memory under this address is process-unique. Memory starting at this address is only accessible in privileged-mode. This address was changed from 0x20000000 to 0x40000000 with [[8.0.0-18]].<br />
|}<br />
<br />
All executable pages are read-only, and data pages have the execute-never permission set. Normally .text from the loaded ExeFS:/.code is the only mapped executable memory. Executable [[RO Services|CROs]] can be loaded into memory, once loaded the CRO .text section memory page permissions are changed via [[SVC|ControlProcessMemory]] from RW- to R-X. The address and size of each ExeFS:/.code section is stored in the exheader, the permissions for each section is: .text R-X, .rodata R--, .data RW-, and .bss RW-. The loaded .code is mapped to the addresses specified in the exheader by the ARM11 kernel. The stack permissions is initialized by the ARM11 kernel: RW-. The heap permissions is normally RW-.<br />
<br />
All userland memory is mapped with RW permissions for privileged-mode. However, normally the ARM11 kernel only uses userland read/write instructions(or checks that the memory can be written from userland first) for accessing memory specified by [[SVC|SVCs]].<br />
<br />
Processes can't directly access memory for other processes. When service [[Services API|commands]] are used, the kernel maps memory in the destination process for input/output buffers, where the addresses in the command received by the process is replaced by this mapped memory. When this is an input buffer, the buffer data is copied to the mapped memory. When this is an output buffer, the data stored in the mapped memory is copied to the destination buffer specified in the command.<br />
<br />
The physical address which memory for the application memory-type is mapped to begins at FCRAM+0, the total memory allocated for this memory-type is stored in [[Configuration_Memory]]. Applications' .text + .rodata + .data under the application memory-type is mapped at FCRAM + APPMEMALLOC - (aligned page-size for .text + .rodata + .data). The application .bss is mapped at CODEADDR - .bss size aligned down to the page size.<br />
<br />
==TWL_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Size<br />
! Description<br />
|-<br />
| 0x00100000<br />
| 0x1FFAB000 (with newer TWL_FIRM such as v6704 this is located at 0x1FFAC000)<br />
| 0x00055000<br />
| Code + .(ro)data copied from the process 0x00300000 region is located here(.bss is located here as well).<br />
|-<br />
| 0x00155000<br />
| 0x18555000<br />
| 0x000AB000<br />
| <br />
|-<br />
| 0x00200000<br />
| 0x18500000<br />
| 0x00100000<br />
| <br />
|-<br />
| 0x00300000<br />
| 0x24000000<br />
| 0x04000000<br />
| The beginning of the ARM11 process .text is located here.<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x07E00000<br />
| <br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x00400000<br />
| [[IO]]<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| This is mapped to the DSP memory.<br />
|}<br />
<br />
The above regions are mapped by the ARM11 kernel. Later when the ARM11 process uses [[SVC|svcKernelSetState]] with type4, the kernel unmaps(?) the following regions: 0x00300000..0x04300000, 0x08000000..0x0FE00000, and 0x10000000..0xF8000000.<br />
<br />
=== Detailed TWL_FIRM ARM11 Memory ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Process Virtual Address<br />
! Physical Address<br />
! Size<br />
! Description<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x01000000*4<br />
| DS(i) 0x02000000 RAM. Vaddr = (DSRAMOffset*4) + 0x08000000, where DSRAMOffset is DSRAMAddr-0x02000000.<br />
|-<br />
| 0x0FC00000<br />
| 0x27C00000<br />
| <br />
| Loaded SRL binary, initially the dev DSi launcher SRL is located here(copied here by the ARM11 process).<br />
|-<br />
| 0x0FD00000<br />
| 0x27D00000<br />
| <br />
| The data located here is copied to here by the ARM11 process. The data located here is a TWL NAND [http://dsibrew.org/wiki/Bootloader bootloader] image, using the same format+encryption/verification methods as the DSi NAND bootloader(stage2). The keyX for this bootloader keyslot is initially set to the retail DSi key-data, however when TWL_FIRM is launched this keyX key-data is replaced with a separate keyX. TWL_FIRM can use either the retail DSi bootloader RSA-1024 modulo, or a seperate modulo: normally only the latter is used(the former is only used when loading the image from FS instead of FCRAM). When using the image from FCRAM(default code-path), TWL_FIRM will not calculate+check the hashes for the bootloader code binaries(this is done when loading from FS however).<br />
|-<br />
| 0x0FDF7000<br />
| 0x27DF7000<br />
| 0x1000<br />
| SRL header<br />
|}<br />
<br />
= System memory details =<br />
0xFFFF9000 Pointer to the current KThread instance<br />
0xFFFF9004 Pointer to the current KProcess instance<br />
0xFFFF9010 Pointer to the last KThread to encounter an exception<br />
<br />
0x8000040 Pointer to the current KThread instance on the ARM9<br />
0x8000044 Pointer to the current KProcess instance on the ARM9<br />
<br />
= Handles =<br />
The handle 0xFFFF8001 is a reference to the current KProcess.<br />
The handle 0xFFFF8000 is a reference to the current KThread.<br />
<br />
= IO Process/Kernel virtual addressing equivalence = <br />
It seems an IO register's process virtual address can be calculated by adding 0xEB00000 to its physical address.<br />
<br />
= VRAM Map While Running System Applets =<br />
*0x1E6000-0x22C500 -- top screen 3D left framebuffer 0(240x400x3) (The "3D right first-framebuf" addr stored in the LCD register is set to this, when the 3D is set to "off")<br />
*0x22C800-0x272D00 -- top screen 3D left framebuffer 1(240x400x3)<br />
*0x273000-0x2B9500 -- top screen 3D right framebuffer 0(240x400x3)<br />
*0x2B9800-0x2FFD00 -- top screen 3D right framebuffer 1(240x400x3)<br />
*0x48F000-0x4C7400 -- bottom screen framebuffer 0(240x320x3)<br />
*0x4C7800-0x4FF800 -- bottom screen framebuffer 1(240x320x3)<br />
<br />
These LCD framebuffer addresses are not changed by the system when launching regular applications, the application itself handles that if needed. These VRAM framebuffers are cleared when launching regular applications.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12644
GPU/Commands
2015-05-17T19:08:35Z
<p>Lectem: /* Parameter structure for command 0x00C0 */</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|-<br />
| 3<br />
| Constant. 0xAABBBGGRR format (or same as the color buffer ?)<br />
|-<br />
| 4<br />
| Param4<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_PRIMARY_FRAGMENT_COLOR<br />
|The color that comes from lightning<br />
|-<br />
| 0x2<br />
| ?<br />
|<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x9<br />
| ?<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC2_RGB<br />
|-<br />
| 0xD<br />
| ?<br />
|}<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x4<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC2_RGB<br />
|-<br />
| 0x7<br />
| ?<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param4 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 31-0<br />
| To be determined<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Commands&diff=12643
GPU/Commands
2015-05-17T14:22:42Z
<p>Lectem: /* Param0 values for command 0x00C0 */</p>
<hr />
<div>This page describes the structure of the buffer submitted via the registers at [[GPU|0x1EF018E0]] (or equivalently via [[GSP_Shared_Memory|GX command]] 1). This buffer is used for GPU commands including functionality equivalent to OpenGL commands.<br />
<br />
[[GPU Internal Registers]] provides a more structured overview for the available commands but is still work in progress, and hence should be used as a complementary source of information.<br />
<br />
=== Overview ===<br />
Each command is at least 8 bytes wide. The first word is the command parameter and the second word constitutes the command header. Optionally, more parameter words may follow (potentially including a padding word to align commands to multiples of 8 bytes).<br />
<br />
In the simplest case, a command is exactly 8 bytes wide. You can think of such a command as writing the parameter word to an internal register (the index of which is given in the command header). The more general case where more than one parameter word is given is equivalent to multiple simple commands (one for each parameter word). If consecutive writing mode is enabled in the command header, the current command index will be incremented after each parameter write. Otherwise, the parameters will be consecutively written to the same register.<br />
<br />
For example, the sequence "0xAAAAAAAA 0x802F011C 0xBBBBBBBB 0xCCCCCCCC" is equivalent to a call to commands 0xF011C with parameter 0xAAAAAAAA, 0xF011D with parameter 0xBBBBBBBB and 0xF011E with parameter 0xCCCCCCCC. If consecutive writing mode were disabled, the command would be equivalent to three consecutive calls to 0xF011C (once with parameter 0xAAAAAAAA, once with 0xBBBBBBBB, and finally with 0xCCCCCCCC).<br />
<br />
Invalid GPU command parameters including NaN floats can cause the GPU to hang, which then causes the GSP module to hang as well.<br />
<br />
The size of GPU command buffers must be 0x10-byte aligned; the lower 3 bits of the size are cleared. A common pitfall is having the finalization command (write to register 0x0010) not executed because it was the last 8 bytes of a non-0x10 byte aligned command buffer, and having the GPU hang as a result.<br />
<br />
=== Command Header ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Command ID<br />
|-<br />
| 19-16<br />
| Parameter mask<br />
|-<br />
| 30-20<br />
| Number of extra parameters (may be zero)<br />
|-<br />
| 31<br />
| Consecutive writing mode<br />
|}<br />
<br />
=== Parameter masking ===<br />
<br />
Using a value other than 0xF, parts of a word in internal GPU memory can be updated without touching the other bits of it. For example, setting bit 16 to zero indicates that the least significant byte of the parameter will not be overwritten, setting bit 17 to zero indicates that the parameter's second LSB will not be overwritten, etc. This means that for instance commands 0x00010107 and 0x00020107 refer to the same thing but write different parts of the parameter.<br />
<br />
=== Command IDs ===<br />
{| class="wikitable" border="1"<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0x0010<br />
| Value is 0x12345678<br />
| This command is always the last command in the buffer.<br />
|-<br />
| 0x0110<br />
| Value 0x1<br />
| This command is immediately before command 0x0010, this is also used elsewhere for beginning rendering of mesh(es) as well.<br />
|-<br />
| 0x0111<br />
| Value 0x1<br />
| This command is immediately before command 0x0110, however command 0x0110 doesn't always follow this command.<br />
|-<br />
| 0x0040<br />
| u32, valid values are 0x1 and 0x2, values 0x0 and 0x3 have the same effect as value 0x2. Only bits 1-0 are used.<br />
| Value 2 = GL_FRONT/GL_CW or GL_BACK/GL_CCW. Value 1 = GL_FRONT/GL_CCW or GL_BACK/GL_CW.<br />
|-<br />
| 0x0041<br />
| float24<br />
| VIEWPORT_WIDTH. See command set 0x0041.<br />
|-<br />
| 0x0042<br />
| float32<br />
| VIEWPORT_WIDTH_INV. See command set 0x0041.<br />
|-<br />
| 0x0043<br />
| float24<br />
| VIEWPORT_HEIGHT. See command set 0x0041.<br />
|-<br />
| 0x0044<br />
| float32<br />
| VIEWPORT_HEIGHT_INV. See command set 0x0041.<br />
|-<br />
| 0x004D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x0065<br />
| <br />
| Scissor test. See command set 0x0065.<br />
|-<br />
| 0x0068<br />
| u32<br />
| VIEWPORT Y/X. See command set 0x0041.<br />
|-<br />
| 0x006D<br />
| <br />
| See command set 0x004D.<br />
|-<br />
| 0x006E<br />
| u32<br />
| See command set 0x0111.<br />
|-<br />
| 0x006F<br />
| u32<br />
| See command set 0x006F.<br />
|-<br />
| 0x0080<br />
| u32<br />
| See command set 0x0080.<br />
|-<br />
| 0x0081<br />
| <br />
| This is used to set the current texture info used for rendering, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x008E<br />
| u32 color type<br />
| This command sets the texture color type, see command set [[GPU_Textures|0x0081]].<br />
|-<br />
| 0x0091<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0091]].<br />
|-<br />
| 0x0099<br />
| <br />
| This sets current texture info, see command [[GPU_Textures|0x0099]].<br />
|-<br />
| 0x00C3<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00CB<br />
| val<<24<br />
| Val is usually 0xFF or 0x00, however 0x00-0xFF is valid as well. This is alpha-blending related?<br />
|-<br />
| 0x00C0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00C8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00CC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00D8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00DC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F0<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F4<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00F8<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00FC<br />
| <br />
| See command set 0x00C0.<br />
|-<br />
| 0x00E0<br />
| Normally value zero.<br />
| Unknown, fragment related?<br />
|-<br />
| 0x00E0<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E1<br />
| <br />
| See command set 0x00E0.<br />
|-<br />
| 0x00E6<br />
| Value zero<br />
| See command set 0x00E6.<br />
|-<br />
| 0x00E8<br />
| <br />
| See command set 0x00E6.<br />
|-<br />
| 0x0100<br />
| u32, value is 0x00E40100<br />
| See command set 0x0100.<br />
|-<br />
| 0x0100<br />
| <nowiki>0x00E40000 | val</nowiki>.<br />
| See command set 0x0100.<br />
|-<br />
| 0x0101<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0102<br />
| u32<br />
| See command set 0x0100.<br />
|-<br />
| 0x0103<br />
| <br />
| See command set 0x0100.<br />
|-<br />
| 0x0104<br />
| u32<br />
| glAlphaFunc()<br />
|-<br />
| 0x0105<br />
| u32<br />
| Stencil test settings<br />
|-<br />
| 0x0106<br />
| u32<br />
| Stencil replacement operators<br />
|-<br />
| 0x0107<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0116<br />
| u32<br />
| DEPTHBUFFER FORMAT. See command set 0x0111.<br />
|-<br />
| 0x0117<br />
| u32<br />
| COLORBUFFER FORMAT/PIXEL. See command set 0x0111.<br />
|-<br />
| 0x011C<br />
| Physical address>>3<br />
| DEPTHBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011D<br />
| Physical address>>3<br />
| COLORBUFFER ADDRESS. See command set 0x0111.<br />
|-<br />
| 0x011E<br />
| u32<br />
| COLORBUFFER HEIGHT/WIDTH. See command set 0x0111.<br />
|-<br />
| 0x0112<br />
| <br />
| ?<br />
|-<br />
| 0x01C5<br />
| <nowiki>(dmp_FragmentLightSource ID)<<8 | (sampler ID)<<11</nowiki> ?<br />
| This command is in conjunction with 0x01C8 used to send fragment 1D samplers. (LUTs) sampler ID 1 for sampler samplerSP and 2 for samplerDA<br />
|-<br />
| 0x01C8<br />
| LUT as parameter<br />
| Used to send fragment LUT data.<br />
|-<br />
| 0x0200<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0126<br />
| <br />
| See command set command 0x0107.<br />
|-<br />
| 0x0227<br />
| u32<br />
| This specifies the address of an array containing vertex array indices, and the data-type of the indices, used for rendering primitives. See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0228<br />
| u32 total elements in the array to use for rendering.<br />
| See command set [[GPU_GL_Arrays|glDrawElements()]].<br />
|-<br />
| 0x0232<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0244<br />
| bool ?<br />
| Set geo shader enabled/disabled ?<br />
|-<br />
| 0x025E<br />
| u32, val<<8.<br />
| This sets the GL rendering mode, see command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x0280<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set geo shader boolean uniforms. ((val>>i)&1 = !b_i) value (b0 = False => val&1 == 1)<br />
|-<br />
| 0x0281<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (geo shader)<br />
|-<br />
| 0x0282<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (geo shader)<br />
|-<br />
| 0x0283<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (geo shader)<br />
|-<br />
| 0x0284<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (geo shader)<br />
|-<br />
| 0x028A<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the geometry shader program<br />
|-<br />
| 0x0290<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| Geometry shader equivalent of 0x02C0<br />
|-<br />
| 0x02B0<br />
| u32, value is <nowiki>0x7FFF0000 | val</nowiki>.<br />
| Used to set the 16 vertex shader boolean uniforms. (b_i = (val>>i)&1)<br />
|-<br />
| 0x02B1<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i0 (vertex shader)<br />
|-<br />
| 0x02B2<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i1 (vertex shader)<br />
|-<br />
| 0x02B3<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i2 (vertex shader)<br />
|-<br />
| 0x02B4<br />
| u32, value is <nowiki>(x&0xff)|((y&0xff)<<8)|((z&0xff)<<16)|((w&0xff)<<24)</nowiki>.<br />
| Used to set i3 (vertex shader)<br />
|-<br />
| 0x02BB<br />
| <br />
| See command set [[GPU_GL_Arrays|0x0200]].<br />
|-<br />
| 0x02BA<br />
| <nowiki>0x7FFF0000 | entrypoint offset</nowiki><br />
| Sets the entrypoint offset for the vertex shader program<br />
|-<br />
| 0x02C0<br />
| <nowiki>0x80000000 | Type</nowiki><br />
| This is used immediately before command 0x02C1. This type field controls the command parameter buffer type. This command can also be used to send over (float24 only ?) data directly, without using 0x02C1. In that case, the first parameter is still Type but with bit 31 not set; the actual data follows.<br />
|-<br />
| 0x02C1<br />
| First word in the first entry<br />
| A list of entries follow this command.<br />
|-<br />
| 0x02C2<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C3<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C4<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C5<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C6<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C7<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x02C8<br />
| First word in the first entry<br />
| Alias for 0x02C1<br />
|-<br />
| 0x029B<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x029C. It is used to indicate that geometry shader program data will follow.<br />
|-<br />
| 0x029C<br />
| First word of geometry shader program data chunk.<br />
| This command is used to transfer geometry shader program data (as the parameter data). It can be called multiple times in a row if the shader program is too big to fit into a single call.<br />
|-<br />
| 0x028F<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x029C. It is used to indicate that geometry shader program data transfer is complete.<br />
|-<br />
| 0x02A5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02A6<br />
| First entry.<br />
| This is used to send over the geometry shader program operand descriptor table.<br />
|-<br />
| 0x02CB<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02CC. It is used to indicate that shader program data will follow.<br />
|-<br />
| 0x02CC<br />
| First word of vertex shader program data chunk.<br />
| This command is used to transfer vertex shader program data (as the parameter data). It can be called multiple times in a row if the vertex shader program is too big to fit into a single call.<br />
|-<br />
| 0x02BF<br />
| Value 0x1 ?<br />
| This is used immediately after a set of command 0x02CC. It is used to indicate that vertex shader program data transfer is complete.<br />
|-<br />
| 0x02D5<br />
| Value 0x0 ?<br />
| This is used immediately before command 0x02A6.<br />
|-<br />
| 0x02D6<br />
| First entry.<br />
| This is used to send over the vertex shader program operand descriptor table.<br />
|-<br />
| 0x004F<br />
| Number of vertex shader output attributes<br />
| Sets number of vertex shader output attributes<br />
|-<br />
| 0x0050<br />
| First entry<br />
| This command is used to setup vertex shader output registers. The n-th word-long entry is a map of the (n*2)-th output register's components. Each byte of each entry corresponds to where a component is mapped. Value 0x1F indicates that the corresponding component is unused.<br />
|}<br />
<br />
==== Command Sets ====<br />
<br />
===== glDrawElements() =====<br />
See [[GPU_GL_Arrays|GPU GL Arrays]].<br />
<br />
===== glClear() / glClearColor() =====<br />
The GPU does not have dedicated commands for clearing the color buffer, therefore applications implement color buffer clearing by rendering a quad. Applications normally store this vertex and color [[GPU_GL_Arrays|array]] in the GSP application heap.<br />
<br />
===== Command 0x0081 =====<br />
This sets current texture info, see [[GPU Textures|GPU textures]].<br />
<br />
===== Command 0x0065 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0065<br />
| Scissor test enable<br />
| 0 = disabled, 1 = inverted (pixels within the scissor box are excluded), 2 = disabled, 3 = normal (pixels outside of the scissor box are excluded)<br />
|-<br />
| 1<br />
| 0x0066<br />
| Scissor box X/Y<br />
| Bit 0-15: X, bit 16-31: Y<br />
|-<br />
| 2<br />
| 0x0067<br />
| Scissor box width/height<br />
| Bit 0-15: width-1, bit 16-31: height-1<br />
|}<br />
<br />
===== Command 0x006F =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x006F<br />
| Typically only bit8-10 are used.<br />
| Bit8 enables texture coordinate output for texture unit 0, bit9 enables texcoords for texture unit 1, and bit2 enables texcoords for texture unit 2.<br />
|}<br />
<br />
===== Command 0x0080 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0080<br />
| <nowiki>0x11000 | val</nowiki>, where only bits 2-0 are used in val.<br />
| bit0-2 enables/disables texture units 0-2 respectively<br />
|}<br />
Note that bit0-2 in this command only enable texture processing. For texturing to work fully, the corresponding texture coordinate outputs must be enabled as well via command 0x006F.<br />
<br />
===== Command 0x00C0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| <nowiki>SlotCmdID</nowiki><br />
| <br />
| <br />
|-<br />
| 1<br />
| <nowiki>SlotCmdID + 4</nowiki><br />
| <br />
| <br />
|}<br />
<br />
This is used for glTexEnv(), for the slot indicated by the command id. There's a total of 6 slots, where each slot corresponds to the following u16 command ids: 0xC0, 0xC8, 0xD0, 0xD8, 0xF0, 0xF8.<br />
<br />
===== Command 0x00E0 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E0<br />
| <nowiki>5 | val<<16</nowiki>, where val is 0 or 1.<br />
| Val0 = enable, val1 = disable.<br />
|-<br />
| 1<br />
| 0x00E1<br />
| <br />
| This specifies a color.<br />
|}<br />
<br />
This is usually used immediately after command set glDrawElements(). This is used to specify a color used for blending?<br />
<br />
===== Command 0x00E6 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x00E6<br />
| Value 0<br />
| ?<br />
|-<br />
| 1<br />
| 0x00E8<br />
| <br />
| <br />
|}<br />
<br />
This is usually the last command set used for rendering a mesh, when command set 0x00E0 was used. This command set is used immediately after command set 0x00E0.<br />
<br />
===== Command 0x0100 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0100<br />
| Value 0x00E40100<br />
| Controls color compositing<br />
|-<br />
| 1<br />
| 0x0101<br />
| 0x01010000 when disabled<br />
| Alphablending equations and factors<br />
|-<br />
| 2<br />
| 0x0103<br />
| This is set to zero when the command 0x0101 parameter is value 0x01010000.<br />
| Constant color for alphablending<br />
|}<br />
<br />
This is fragment related?<br />
<br />
===== Command 0x004D =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x004D<br />
| <br />
| glDepthRange()<br />
|-<br />
| 1<br />
| 0x006D<br />
| 0 = unknown, 1 = unknown.<br />
| Value zero causes the mesh to not be rendered.<br />
|}<br />
<br />
===== Command 0x0041 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0041<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 1<br />
| 0x0043<br />
| float<br />
| This parameter value is calculated the same way as the command 0x0041 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 2<br />
| 0x0042<br />
| float<br />
| This corresponds to the framebuffer width.<br />
|-<br />
| 3<br />
| 0x0044<br />
| float<br />
| This parameter value value is calculated the same way as the command 0x0042 parameter, except the framebuffer height is used instead.<br />
|-<br />
| 4<br />
| 0x0068<br />
| u32<br />
| This sets the X/Y coordinates used for glViewport().<br />
|}<br />
<br />
This command set initializes the projection matrix. This command set is used twice when beginning rendering for each screen. The framebuffer width used here for the main screen is 240, however this is 480 with stereoscopy enabled for the second time this command set is used.<br />
<br />
===== Command 0x0111 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0111<br />
| Value 1<br />
| <br />
|-<br />
| 1<br />
| 0x0110<br />
| Value 1<br />
| <br />
|-<br />
| 2<br />
| 0x0117<br />
| Framebuffer color format descriptor<br />
| See [[GPU_Internal_Registers#GPUREG_COLORBUFFER_FORMAT]]<br />
|-<br />
| 3<br />
| 0x011D<br />
| Physical address>>3<br />
| This initializes the framebuffer address used for rendering, this framebuffer is used for the input framebuffer with [[GSP_Shared_Memory|GX command]] 3 and 4. This command is used immediately after command 0x0117.<br />
|-<br />
| 4<br />
| 0x0116<br />
| <br />
| ?<br />
|-<br />
| 5<br />
| 0x011C<br />
| Physical address>>3<br />
| Unknown, normally this address is located in VRAM.<br />
|-<br />
| 6<br />
| 0x011E<br />
| u32, 0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF)<br />
| This sets the width and height for the framebuffer used for rendering. Therefore this is glViewport(), x/y are specified by command 0x0068.<br />
|-<br />
| 7<br />
| 0x006E<br />
| Same input parameter value as command 0x011E.<br />
| <br />
|}<br />
<br />
This command set is normally used after the two 0x0041 command sets.<br />
<br />
===== Command 0x0107 =====<br />
{| class="wikitable" border="1"<br />
! Command Index<br />
! CommandID<br />
! Parameter<br />
! Description<br />
|-<br />
| 0<br />
| 0x0107<br />
| <br />
| <br />
|-<br />
| 1<br />
| 0x0126<br />
| type<<24<br />
| <br />
|}<br />
<br />
This command set is used for disabling the alpha-blending info set by command set 0x0107? The GL AlphaFunction used here is normally GL_ALWAYS.<br />
<br />
=== Parameter format for command 0x0107 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_DEPTH_TEST, 1 = enable GL_DEPTH_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Depth test function<br />
|-<br />
| 8<br />
| Enable color writing for red component<br />
|-<br />
| 9<br />
| Enable color writing for green component<br />
|-<br />
| 10<br />
| Enable color writing for blue component<br />
|-<br />
| 11<br />
| Enable color writing for alpha component<br />
|-<br />
| 12<br />
| Enable depth writing (doesn't affect stencil writing)<br />
|-<br />
| 31-13<br />
| Unused<br />
|}<br />
<br />
==== Alpha function values ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_EQUAL<br />
|-<br />
| 3<br />
| GL_NOTEQUAL<br />
|-<br />
| 4<br />
| GL_LESS<br />
|-<br />
| 5<br />
| GL_LEQUAL<br />
|-<br />
| 6<br />
| GL_GREATER<br />
|-<br />
| 7<br />
| GL_GEQUAL<br />
|}<br />
<br />
=== Alpha types for command 0x0126 ===<br />
{| class="wikitable" border="1"<br />
! Type<br />
! GL AlphaFunction<br />
|-<br />
| 0<br />
| GL_NEVER<br />
|-<br />
| 1<br />
| GL_ALWAYS<br />
|-<br />
| 2<br />
| GL_GREATER/GL_GEQUAL<br />
|-<br />
| 3<br />
| The remaining GL alpha functions.<br />
|}<br />
<br />
=== Parameter value format for command 0x0104 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| 0 = disable GL_ALPHA_TEST, 1 = enable GL_ALPHA_TEST<br />
|-<br />
| 3-1<br />
| Unused?<br />
|-<br />
| 7-4<br />
| Alpha function<br />
|-<br />
| 15-8<br />
| u8 ref, range is 0-255<br />
|-<br />
| 31-16<br />
| Unused?<br />
|}<br />
<br />
This is glAlphaFunc().<br />
<br />
=== Parameter value format for command 0x011E ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 11-0<br />
| Framebuffer/viewport width<br />
|-<br />
| 23-12<br />
| Framebuffer/viewport height - 1<br />
|-<br />
| 24<br />
| Must be set<br />
|-<br />
| 31-25<br />
| Unused?<br />
|}<br />
<br />
This specifies the width/height for glViewport(). Normally the framebuffer width and height is set to the same [[GPU|dimensions]] used with GX [[GSP_Shared_Memory|command]] 3 and 4.<br />
<br />
=== Parameter value format for command 0x0068 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| X<br />
|-<br />
| 31-16<br />
| Y<br />
|}<br />
<br />
This specifies the X/Y coordinates for glViewport().<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Value 0xFFF0FFF / 0x0<br />
|-<br />
| 1<br />
| Value 0x0<br />
|-<br />
| 2<br />
| Value 0x0<br />
|-<br />
| 3<br />
| Value 0xFFFFFFFF<br />
|-<br />
| 4<br />
| Value 0x0<br />
|}<br />
<br />
This individual command is used instead of the 0x80XF00C0 command set when none of the associated rendering parameters for this slot are set.<br />
<br />
=== Parameter structure for command 0x00C0 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Param0<br />
|-<br />
| 1<br />
| Param1<br />
|-<br />
| 2<br />
| Param2<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
==== Param0 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values.(Field0 index0)<br />
|-<br />
| 7-4<br />
| See below values.(Field0 index1)<br />
|-<br />
| 11-8<br />
| See below values.(Field0 index2)<br />
|-<br />
| 15-12<br />
| Unused<br />
|-<br />
| 19-16<br />
| See below values.(Field1 index0)<br />
|-<br />
| 23-20<br />
| See below values.(Field1 index1)<br />
|-<br />
| 27-24<br />
| See below values.(Field1 index2)<br />
|-<br />
| 31-28<br />
| Unused<br />
|}<br />
<br />
==== Param0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
! Comment<br />
|-<br />
| 0x0<br />
| GL_PRIMARY_COLOR<br />
|The color that comes from the upper shader<br />
|-<br />
| 0x1<br />
| GL_PRIMARY_FRAGMENT_COLOR<br />
|The color that comes from lightning<br />
|-<br />
| 0x2<br />
| ?<br />
|<br />
|-<br />
| 0x3<br />
| GL_TEXTURE0<br />
|<br />
|-<br />
| 0x4<br />
| GL_TEXTURE1<br />
|<br />
|-<br />
| 0x5<br />
| GL_TEXTURE2<br />
|<br />
|-<br />
| 0x6<br />
| GL_TEXTURE3<br />
|<br />
|-<br />
| 0xC-0x7<br />
|(GL_PRIMARY_COLOR)No?<br />
| Please detail. Gives 0 on TexEnv0<br />
|-<br />
| 0xD<br />
| ?<br />
|<br />
|-<br />
| 0xE<br />
| GL_CONSTANT<br />
|<br />
|-<br />
| 0xF<br />
| GL_PREVIOUS<br />
| Color that comes from the previous texture stage<br />
|}<br />
<br />
==== Param1 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| See below values for field0.(Index0)<br />
|-<br />
| 7-4<br />
| See below values for field0.(Index1)<br />
|-<br />
| 11-8<br />
| See below values for field0.(Index2)<br />
|-<br />
| 15-12<br />
| See below values for field1.(Index0)<br />
|-<br />
| 19-16<br />
| See below values for field1.(Index1)<br />
|-<br />
| 23-20<br />
| See below values for field1.(Index2)<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
This specifies the pname for glTexEnv().<br />
<br />
==== Param1 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 0x2<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x3<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x4<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x7<br />
| GL_SRC_COLOR<br />
|-<br />
| 0x8<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x9<br />
| ?<br />
|-<br />
| 0xA<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xB<br />
| GL_SRC_COLOR<br />
|-<br />
| 0xC<br />
| GL_SRC2_RGB<br />
|-<br />
| 0xD<br />
| ?<br />
|}<br />
<br />
==== Param1 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_SRC_ALPHA<br />
|-<br />
| 0x1<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 0x2<br />
| GL_SRC0_RGB<br />
|-<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x4<br />
| GL_SRC1_RGB<br />
|-<br />
| 0x5<br />
| ?<br />
|-<br />
| 0x6<br />
| GL_SRC2_RGB<br />
|-<br />
| 0x7<br />
| ?<br />
|}<br />
<br />
==== Param2 format for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| See below field0 values.<br />
|-<br />
| 31-16<br />
| See below field1 values.<br />
|}<br />
<br />
This is used to specify the param for glTexEnv(..., ..., param).<br />
<br />
==== Param2 field0 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGBA<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
==== Param2 field1 values for command 0x00C0 ====<br />
{| class="wikitable" border="1"<br />
! Value<br />
! GL type<br />
|-<br />
| 0x0<br />
| GL_REPLACE<br />
|-<br />
| 0x1<br />
| GL_MODULATE<br />
|-<br />
| 0x2<br />
| GL_ADD<br />
|-<br />
| 0x3<br />
| GL_ADD_SIGNED<br />
|-<br />
| 0x4<br />
| GL_INTERPOLATE<br />
|-<br />
| 0x5<br />
| GL_SUBTRACT<br />
|-<br />
| 0x6<br />
| GL_REPLACE<br />
|-<br />
| 0x7<br />
| GL_DOT3_RGB<br />
|-<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x9<br />
| ?<br />
|}<br />
<br />
=== Parameter value format for command 0x00C4 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 15-0<br />
| Valid values: 0=unknown, 1=unknown, 2=unknown.<br />
|-<br />
| 31-16<br />
| Same format as bits15-0.<br />
|}<br />
<br />
See command set 0x80XF00C0.<br />
<br />
=== Parameter value format for command 0x00E1 ===<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Red component<br />
|-<br />
| 15-8<br />
| Green component<br />
|-<br />
| 23-16<br />
| Blue component<br />
|-<br />
| 31-24<br />
| Unused<br />
|}<br />
<br />
=== Parameter value format for command 0x0100 ===<br />
This command controls color compositing. It is typically used right after commands 0x0101 or 0x0102 to select the appropriate blending mode.<br />
<br />
Alphablending and color logic op can't be used together. Attempting to issue commands 0x0101 and 0x0102 at the same time can freeze the GPU.<br />
<br />
For blending to work correctly, color buffer reading needs to be enabled (see command set 0x0112). Otherwise zero values will be used as destination color/alpha.<br />
<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Weird mode (see below)<br />
|-<br />
| 1<br />
| When set, nothing is drawn to the color, depth and stencil buffers. This bit can cause a noisy picture when used with bit 0 (this seems to also cause the depth buffer's endianness to be reversed, and forces stencil values to 0xFF).<br />
|-<br />
| 8<br />
| Selects blending mode. 0 = color logic op, 1 = alphablending<br />
|-<br />
| 23-16<br />
| Unknown, typically set to 0xE4. No observed effect when changing this.<br />
|-<br />
| 25-24<br />
| 0 = normal, 1-3 = apply dithering (3 = 0% source)<br />
|}<br />
<br />
When "weird mode" is enabled, the source color/alpha values are ignored. Instead, each 16-bit value in the destination color buffer is converted according to its bits 14-8, as follows:<br />
* if bits 14-8 are between 0x00 and 0x03, the value is replaced with 0x0000<br />
* if bits 14-8 are between 0x7D and 0x7F, the value is replaced with 0x7FFF<br />
* in all other cases, the value is left unchanged<br />
<br />
=== Parameter value format for command 0x0101 ===<br />
This command controls alphablending. To disable alphablending, the value is set to 0x01010000.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 7-0<br />
| Color blend equation<br />
|-<br />
| 15-8<br />
| Alpha blend equation<br />
|-<br />
| 19-16<br />
| Color source factor<br />
|-<br />
| 23-20<br />
| Color destination factor<br />
|-<br />
| 27-24<br />
| Alpha source factor<br />
|-<br />
| 31-28<br />
| Alpha destination factor<br />
|}<br />
<br />
Blend equation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_FUNC_ADD<br />
|-<br />
| 1<br />
| GL_FUNC_SUBTRACT<br />
|-<br />
| 2<br />
| GL_FUNC_REVERSE_SUBTRACT<br />
|-<br />
| 3<br />
| GL_MIN<br />
|-<br />
| 4<br />
| GL_MAX<br />
|}<br />
<br />
Source/destination factor values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_ZERO<br />
|-<br />
| 1<br />
| GL_ONE<br />
|-<br />
| 2<br />
| GL_SRC_COLOR<br />
|-<br />
| 3<br />
| GL_ONE_MINUS_SRC_COLOR<br />
|-<br />
| 4<br />
| GL_DST_COLOR<br />
|-<br />
| 5<br />
| GL_ONE_MINUS_DST_COLOR<br />
|-<br />
| 6<br />
| GL_SRC_ALPHA<br />
|-<br />
| 7<br />
| GL_ONE_MINUS_SRC_ALPHA<br />
|-<br />
| 8<br />
| GL_DST_ALPHA<br />
|-<br />
| 9<br />
| GL_ONE_MINUS_DST_ALPHA<br />
|-<br />
| 10<br />
| GL_CONSTANT_COLOR<br />
|-<br />
| 11<br />
| GL_ONE_MINUS_CONSTANT_COLOR<br />
|-<br />
| 12<br />
| GL_CONSTANT_ALPHA<br />
|-<br />
| 13<br />
| GL_ONE_MINUS_CONSTANT_ALPHA<br />
|-<br />
| 14<br />
| GL_SRC_ALPHA_SATURATE<br />
|}<br />
<br />
=== Parameter value format for command 0x0102 ===<br />
This command controls color logic op.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 3-0<br />
| Logic operation<br />
|}<br />
<br />
Logic operation values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| GL_CLEAR<br />
|-<br />
| 1<br />
| GL_AND<br />
|-<br />
| 2<br />
| GL_AND_REVERSE<br />
|-<br />
| 3<br />
| GL_COPY<br />
|-<br />
| 4<br />
| GL_SET<br />
|-<br />
| 5<br />
| GL_COPY_INVERTED<br />
|-<br />
| 6<br />
| GL_NOOP<br />
|-<br />
| 7<br />
| GL_INVERT<br />
|-<br />
| 8<br />
| GL_NAND<br />
|-<br />
| 9<br />
| GL_OR<br />
|-<br />
| 10<br />
| GL_NOR<br />
|-<br />
| 11<br />
| GL_XOR<br />
|-<br />
| 12<br />
| GL_EQUIV<br />
|-<br />
| 13<br />
| GL_AND_INVERTED<br />
|-<br />
| 14<br />
| GL_OR_REVERSE<br />
|-<br />
| 15<br />
| GL_OR_INVERTED<br />
|}<br />
<br />
=== Parameter value format for command 0x0105 ===<br />
This command controls stencil testing.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 0<br />
| Enable stencil test<br />
|-<br />
| 7-4<br />
| Stencil test function (values same as for alpha and depth tests)<br />
|-<br />
| 15-8<br />
| Replacement value, used as specified by command 0x0106<br />
|-<br />
| 23-16<br />
| Reference value for the stencil test. Note that the test does "reference FUNC value".<br />
|-<br />
| 31-24<br />
| Mask for the stencil test.<br />
|}<br />
<br />
=== Parameter value format for command 0x0106 ===<br />
This command controls stencil buffer replacement.<br />
{| class="wikitable" border="1"<br />
! Bit<br />
! Description<br />
|-<br />
| 2-0<br />
| Action when the stencil test fails<br />
|-<br />
| 6-4<br />
| Action when the stencil test passes but the depth test fails<br />
|-<br />
| 10-8<br />
| Action when both stencil test and depth test pass<br />
|}<br />
<br />
Action values:<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Final stencil value<br />
|-<br />
| 0<br />
| destination<br />
|-<br />
| 1<br />
| destination & ~source<br />
|-<br />
| 2<br />
| same as 1<br />
|-<br />
| 3<br />
| Weird operation.<br />
|-<br />
| 4<br />
| Weird operation. TODO: find out what it is exactly.<br />
|-<br />
| 5<br />
| destination ^ source<br />
|-<br />
| 6<br />
| Another weird operation.<br />
|-<br />
| 7<br />
| same as 4<br />
|}<br />
'destination' is the value present in the stencil buffer, 'source' is the replacement value specified in command 0x0105.<br />
<br />
=== Parameter structure for command 0x004D ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float far<br />
|-<br />
| 1<br />
| float near<br />
|}<br />
<br />
This is glDepthRange().<br />
<br />
=== Parameter structure for command 0x00E8 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0x7D-0x00<br />
| Usually value 0x00FFE000.<br />
|-<br />
| 0x7E<br />
| Usually value 0x00FFFEE6?<br />
|-<br />
| 0x7F<br />
| Usually value 0x00DCD919?<br />
|}<br />
<br />
=== Parameter structure for command 0x0112 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| Setting bits 3-0 to a nonzero value allows the GPU to read from the color buffer.<br />
|-<br />
| 1<br />
| Setting bits 3-0 to a nonzero value allows the GPU to write to the color buffer.<br />
|-<br />
| 2<br />
| Setting bits 1-0 to a nonzero value allows the GPU to read from the depth/stencil buffer.<br />
|-<br />
| 3<br />
| Setting bits 1-0 to a nonzero value allows the GPU to write to the depth/stencil buffer.<br />
|}<br />
<br />
=== Entries for command 0x02C1 ===<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float, the GPU handles this as the 4th word.<br />
|-<br />
| 1<br />
| float, the GPU handles this as the 3rd word.<br />
|-<br />
| 2<br />
| float, the GPU handles this as the 2nd word.<br />
|-<br />
| 3<br />
| float, the GPU handles this as the 1st word.<br />
|}<br />
<br />
The below entry structure info is in the raw order used for the command, not the order used by the GPU.<br />
<br />
==== Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Red component<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Alpha<br />
|}<br />
<br />
==== Lighting Color Entry ====<br />
{| class="wikitable" border="1"<br />
! Index Word<br />
! Description<br />
|-<br />
| 0<br />
| float Alpha<br />
|-<br />
| 1<br />
| float Blue component<br />
|-<br />
| 2<br />
| float Green component<br />
|-<br />
| 3<br />
| float Red component<br />
|}<br />
<br />
=== Types for command 0x02C0 ===<br />
<br />
The 0x02C0/0x02C1 is actually used as a generic way to set uniforms, regardless of what they represent. 0x02C0's parameter represents the ID of the destination GPU register (0x0 is c0, 0x1 is c1 etc). As such, the meaning of the data being sent over is entirely dependant on the shader currently in use.<br />
The values below may be "default" values used by Nintendo's openGL implementation.<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Entries per chunk<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| This specifies 16-floats for a 4x4 matrix, used for glLoadMatrix() for the projection matrix.<br />
|-<br />
| 0x04<br />
| 4<br />
| This specifies a 4x4 matrix, used for glLoadMatrix() for the model-view matrix. This is usually an identity matrix.<br />
|-<br />
| 0x08<br />
| 2<br />
| Sets the color.<br />
|-<br />
| 0x0A<br />
| 4<br />
| Specifies a 4x4 matrix, used for glLoadMatrix() for the texture matrix.(Index0)<br />
|-<br />
| 0x0E<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index1)<br />
|-<br />
| 0x11<br />
| 3<br />
| Specifies a 4x3 texture matrix.(Index2)<br />
|-<br />
| 0x14<br />
| <=30<br />
| Used to specify a 4xN matrix, where N is the total command 0x02C1 entries. This is glMultMatrix() for the model-view matrix, except the input matrix is 4xN instead of 4x4.<br />
|-<br />
| 0x4C<br />
| 4<br />
| This specifies a 4x4 float matrix.<br />
|-<br />
| 0x50, 0x53, and 0x56<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_AMBIENT?<br />
|-<br />
| 0x51, 0x54, and 0x57<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_DIFFUSE?<br />
|-<br />
| 0x52, 0x55, and 0x58<br />
| 1<br />
| This specifies the GL_LIGHT0-2 color for GL_SPECULAR?<br />
|-<br />
| 0x59<br />
| 1<br />
| Unknown, the entry data is floats converted from s32s. Usually each entry word is zeros.<br />
|-<br />
| 0x5A<br />
| 2<br />
| Color related?<br />
|-<br />
| 0x5C<br />
| 1<br />
| ?<br />
|}<br />
<br />
The matrices for types 0x00 and 0x04 use row-major order, instead of column-major order.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Internal_Registers&diff=12291
GPU/Internal Registers
2015-04-12T07:46:39Z
<p>Lectem: fixed formatting of reg 0163</p>
<hr />
<div>[[Category:GFX]]<br />
(this page is hugely WIP)<br />
<br />
== Overview ==<br />
<br />
GPU internal registers are written to through GPU commands. They are used to control the GPU's behavior, that is to say tell it to draw stuff and how we want it drawn.<br />
<br />
== Types ==<br />
<br />
There are three main types of registers :<br />
* configuration registers, which directly map to various rendering properties (for example : [[#GPUREG_FACECULLING_CONFIG|GPUREG_FACECULLING_CONFIG]])<br />
* data transfer registers, which can be seen as FIFOs that let us send sequential chunks of data to the GPU, such as shader code or 1D samplers (for example : [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]])<br />
* action triggering registers, which tell the GPU to do something, like draw a primitive (for example : [[#GPUREG_DRAWARRAYS|GPUREG_DRAWARRAYS]])<br />
<br />
== Aliases ==<br />
<br />
It is possible for multiple register (sequential) IDs to correspond to the same register. This is done to leverage the consecutive writing mode for [[GPU Commands]], which makes it possible for a single command to write data to multiple sequential register IDs. For example, register IDs 02C1 through 02C8 all correspond to [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]] so that a consecutively writing command based at 02C0 will write its first parameter to [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]] and ever subsequent ones to [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
<br />
== Register list ==<br />
<br />
{| class="wikitable" border="1"<br />
! Register ID<br />
! Register name<br />
! Notes<br />
! Official Name<br />
|-<br />
| 0000<br />
| [[#GPUREG_0000|GPUREG_0000]]<br />
| <br />
|<br />
|-<br />
| 0001<br />
| [[#GPUREG_0001|GPUREG_0001]]<br />
| <br />
|<br />
|-<br />
| 0002<br />
| [[#GPUREG_0002|GPUREG_0002]]<br />
| <br />
|<br />
|-<br />
| 0003<br />
| [[#GPUREG_0003|GPUREG_0003]]<br />
| <br />
|<br />
|-<br />
| 0004<br />
| [[#GPUREG_0004|GPUREG_0004]]<br />
| <br />
|<br />
|-<br />
| 0005<br />
| [[#GPUREG_0005|GPUREG_0005]]<br />
| <br />
|<br />
|-<br />
| 0006<br />
| [[#GPUREG_0006|GPUREG_0006]]<br />
| <br />
|<br />
|-<br />
| 0007<br />
| [[#GPUREG_0007|GPUREG_0007]]<br />
| <br />
|<br />
|-<br />
| 0008<br />
| [[#GPUREG_0008|GPUREG_0008]]<br />
| <br />
|<br />
|-<br />
| 0009<br />
| [[#GPUREG_0009|GPUREG_0009]]<br />
| <br />
|<br />
|-<br />
| 000A<br />
| [[#GPUREG_000A|GPUREG_000A]]<br />
| <br />
|<br />
|-<br />
| 000B<br />
| [[#GPUREG_000B|GPUREG_000B]]<br />
| <br />
|<br />
|-<br />
| 000C<br />
| [[#GPUREG_000C|GPUREG_000C]]<br />
| <br />
|<br />
|-<br />
| 000D<br />
| [[#GPUREG_000D|GPUREG_000D]]<br />
| <br />
|<br />
|-<br />
| 000E<br />
| [[#GPUREG_000E|GPUREG_000E]]<br />
| <br />
|<br />
|-<br />
| 000F<br />
| [[#GPUREG_000F|GPUREG_000F]]<br />
| <br />
|<br />
|-<br />
| 0010<br />
| [[#GPUREG_FINALIZE|GPUREG_FINALIZE]]<br />
| <br />
|<br />
|-<br />
| 0011<br />
| [[#GPUREG_0011|GPUREG_0011]]<br />
| <br />
|<br />
|-<br />
| 0012<br />
| [[#GPUREG_0012|GPUREG_0012]]<br />
| <br />
|<br />
|-<br />
| 0013<br />
| [[#GPUREG_0013|GPUREG_0013]]<br />
| <br />
|<br />
|-<br />
| 0014<br />
| [[#GPUREG_0014|GPUREG_0014]]<br />
| <br />
|<br />
|-<br />
| 0015<br />
| [[#GPUREG_0015|GPUREG_0015]]<br />
| <br />
|<br />
|-<br />
| 0016<br />
| [[#GPUREG_0016|GPUREG_0016]]<br />
| <br />
|<br />
|-<br />
| 0017<br />
| [[#GPUREG_0017|GPUREG_0017]]<br />
| <br />
|<br />
|-<br />
| 0018<br />
| [[#GPUREG_0018|GPUREG_0018]]<br />
| <br />
|<br />
|-<br />
| 0019<br />
| [[#GPUREG_0019|GPUREG_0019]]<br />
| <br />
|<br />
|-<br />
| 001A<br />
| [[#GPUREG_001A|GPUREG_001A]]<br />
| <br />
|<br />
|-<br />
| 001B<br />
| [[#GPUREG_001B|GPUREG_001B]]<br />
| <br />
|<br />
|-<br />
| 001C<br />
| [[#GPUREG_001C|GPUREG_001C]]<br />
| <br />
|<br />
|-<br />
| 001D<br />
| [[#GPUREG_001D|GPUREG_001D]]<br />
| <br />
|<br />
|-<br />
| 001E<br />
| [[#GPUREG_001E|GPUREG_001E]]<br />
| <br />
|<br />
|-<br />
| 001F<br />
| [[#GPUREG_001F|GPUREG_001F]]<br />
| <br />
|<br />
|-<br />
| 0020<br />
| [[#GPUREG_0020|GPUREG_0020]]<br />
| <br />
|<br />
|-<br />
| 0021<br />
| [[#GPUREG_0021|GPUREG_0021]]<br />
| <br />
|<br />
|-<br />
| 0022<br />
| [[#GPUREG_0022|GPUREG_0022]]<br />
| <br />
|<br />
|-<br />
| 0023<br />
| [[#GPUREG_0023|GPUREG_0023]]<br />
| <br />
|<br />
|-<br />
| 0024<br />
| [[#GPUREG_0024|GPUREG_0024]]<br />
| <br />
|<br />
|-<br />
| 0025<br />
| [[#GPUREG_0025|GPUREG_0025]]<br />
| <br />
|<br />
|-<br />
| 0026<br />
| [[#GPUREG_0026|GPUREG_0026]]<br />
| <br />
|<br />
|-<br />
| 0027<br />
| [[#GPUREG_0027|GPUREG_0027]]<br />
| <br />
|<br />
|-<br />
| 0028<br />
| [[#GPUREG_0028|GPUREG_0028]]<br />
| <br />
|<br />
|-<br />
| 0029<br />
| [[#GPUREG_0029|GPUREG_0029]]<br />
| <br />
|<br />
|-<br />
| 002A<br />
| [[#GPUREG_002A|GPUREG_002A]]<br />
| <br />
|<br />
|-<br />
| 002B<br />
| [[#GPUREG_002B|GPUREG_002B]]<br />
| <br />
|<br />
|-<br />
| 002C<br />
| [[#GPUREG_002C|GPUREG_002C]]<br />
| <br />
|<br />
|-<br />
| 002D<br />
| [[#GPUREG_002D|GPUREG_002D]]<br />
| <br />
|<br />
|-<br />
| 002E<br />
| [[#GPUREG_002E|GPUREG_002E]]<br />
| <br />
|<br />
|-<br />
| 002F<br />
| [[#GPUREG_002F|GPUREG_002F]]<br />
| <br />
|<br />
|-<br />
| 0030<br />
| [[#GPUREG_0030|GPUREG_0030]]<br />
| <br />
|<br />
|-<br />
| 0031<br />
| [[#GPUREG_0031|GPUREG_0031]]<br />
| <br />
|<br />
|-<br />
| 0032<br />
| [[#GPUREG_0032|GPUREG_0032]]<br />
| <br />
|<br />
|-<br />
| 0033<br />
| [[#GPUREG_0033|GPUREG_0033]]<br />
| <br />
|<br />
|-<br />
| 0034<br />
| [[#GPUREG_0034|GPUREG_0034]]<br />
| <br />
|<br />
|-<br />
| 0035<br />
| [[#GPUREG_0035|GPUREG_0035]]<br />
| <br />
|<br />
|-<br />
| 0036<br />
| [[#GPUREG_0036|GPUREG_0036]]<br />
| <br />
|<br />
|-<br />
| 0037<br />
| [[#GPUREG_0037|GPUREG_0037]]<br />
| <br />
|<br />
|-<br />
| 0038<br />
| [[#GPUREG_0038|GPUREG_0038]]<br />
| <br />
|<br />
|-<br />
| 0039<br />
| [[#GPUREG_0039|GPUREG_0039]]<br />
| <br />
|<br />
|-<br />
| 003A<br />
| [[#GPUREG_003A|GPUREG_003A]]<br />
| <br />
|<br />
|-<br />
| 003B<br />
| [[#GPUREG_003B|GPUREG_003B]]<br />
| <br />
|<br />
|-<br />
| 003C<br />
| [[#GPUREG_003C|GPUREG_003C]]<br />
| <br />
|<br />
|-<br />
| 003D<br />
| [[#GPUREG_003D|GPUREG_003D]]<br />
| <br />
|<br />
|-<br />
| 003E<br />
| [[#GPUREG_003E|GPUREG_003E]]<br />
| <br />
|<br />
|-<br />
| 003F<br />
| [[#GPUREG_003F|GPUREG_003F]]<br />
| <br />
|<br />
|-<br />
| 0040<br />
| [[#GPUREG_FACECULLING_CONFIG|GPUREG_FACECULLING_CONFIG]]<br />
| <br />
|PICA_REG_CULL_FACE<br />
|-<br />
| 0041<br />
| [[#GPUREG_0041|GPUREG_0041]]<br />
|?<br />
|PICA_REG_VIEWPORT_WIDTH1<br />
|-<br />
| 0042<br />
| [[#GPUREG_0042|GPUREG_0042]]<br />
|?<br />
|PICA_REG_VIEWPORT_WIDTH2<br />
|-<br />
| 0043<br />
| [[#GPUREG_0043|GPUREG_0043]]<br />
|?<br />
|PICA_REG_VIEWPORT_HEIGHT1<br />
|-<br />
| 0044<br />
| [[#GPUREG_0044|GPUREG_0044]]<br />
| ?<br />
|PICA_REG_VIEWPORT_HEIGHT2<br />
|-<br />
| 0045<br />
| [[#GPUREG_0045|GPUREG_0045]]<br />
| <br />
|<br />
|-<br />
| 0046<br />
| [[#GPUREG_0046|GPUREG_0046]]<br />
| <br />
|<br />
|-<br />
| 0047<br />
| [[#GPUREG_0047|GPUREG_0047]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP<br />
|-<br />
| 0048<br />
| [[#GPUREG_0048|GPUREG_0048]]<br />
|? <br />
|PICA_REG_FRAG_OP_CLIP_DATA1<br />
|-<br />
| 0049<br />
| [[#GPUREG_0049|GPUREG_0049]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA2<br />
|-<br />
| 004A<br />
| [[#GPUREG_004A|GPUREG_004A]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA3<br />
|-<br />
| 004B<br />
| [[#GPUREG_004B|GPUREG_004B]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA4<br />
|-<br />
| 004C<br />
| [[#GPUREG_004C|GPUREG_004C]]<br />
| <br />
|<br />
|-<br />
| 004D<br />
| [[#GPUREG_DEPTHMAP_SCALE|GPUREG_DEPTHMAP_SCALE]]<br />
| <br />
|PICA_REG_FRAG_OP_WSCALE_DATA1<br />
|-<br />
| 004E<br />
| [[#GPUREG_DEPTHMAP_OFFSET|GPUREG_DEPTHMAP_OFFSET]]<br />
| <br />
|PICA_REG_FRAG_OP_WSCALE_DATA2<br />
|-<br />
| 004F<br />
| [[#GPUREG_SH_OUTMAP_TOTAL|GPUREG_SH_OUTMAP_TOTAL]]<br />
| <br />
|PICA_REG_GS_OUT_REG_NUM0 / PICA_REG_VS_OUT_REG_NUM0<br />
|-<br />
| 0050<br />
| [[#GPUREG_SH_OUTMAP_O0|GPUREG_SH_OUTMAP_O0]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR0 / PICA_REG_VS_OUT_ATTR0<br />
|-<br />
| 0051<br />
| [[#GPUREG_SH_OUTMAP_O1|GPUREG_SH_OUTMAP_O1]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR1 / PICA_REG_VS_OUT_ATTR1<br />
|-<br />
| 0052<br />
| [[#GPUREG_SH_OUTMAP_O2|GPUREG_SH_OUTMAP_O2]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR2 / PICA_REG_VS_OUT_ATTR2<br />
|-<br />
| 0053<br />
| [[#GPUREG_SH_OUTMAP_O3|GPUREG_SH_OUTMAP_O3]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR3 / PICA_REG_VS_OUT_ATTR3<br />
|-<br />
| 0054<br />
| [[#GPUREG_SH_OUTMAP_O4|GPUREG_SH_OUTMAP_O4]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR4 / PICA_REG_VS_OUT_ATTR4<br />
|-<br />
| 0055<br />
| [[#GPUREG_SH_OUTMAP_O5|GPUREG_SH_OUTMAP_O5]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR5 / PICA_REG_VS_OUT_ATTR5<br />
|-<br />
| 0056<br />
| [[#GPUREG_SH_OUTMAP_O6|GPUREG_SH_OUTMAP_O6]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR6 / PICA_REG_VS_OUT_ATTR6<br />
|-<br />
| 0057<br />
| [[#GPUREG_0057|GPUREG_0057]]<br />
| <br />
|<br />
|-<br />
| 0058<br />
| [[#GPUREG_0058|GPUREG_0058]]<br />
| <br />
|<br />
|-<br />
| 0059<br />
| [[#GPUREG_0059|GPUREG_0059]]<br />
| <br />
|<br />
|-<br />
| 005A<br />
| [[#GPUREG_005A|GPUREG_005A]]<br />
| <br />
|<br />
|-<br />
| 005B<br />
| [[#GPUREG_005B|GPUREG_005B]]<br />
| <br />
|<br />
|-<br />
| 005C<br />
| [[#GPUREG_005C|GPUREG_005C]]<br />
| <br />
|<br />
|-<br />
| 005D<br />
| [[#GPUREG_005D|GPUREG_005D]]<br />
| <br />
|<br />
|-<br />
| 005E<br />
| [[#GPUREG_005E|GPUREG_005E]]<br />
| <br />
|<br />
|-<br />
| 005F<br />
| [[#GPUREG_005F|GPUREG_005F]]<br />
| <br />
|<br />
|-<br />
| 0060<br />
| [[#GPUREG_0060|GPUREG_0060]]<br />
| <br />
|<br />
|-<br />
| 0061<br />
| [[#GPUREG_0061|GPUREG_0061]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_FUNC<br />
|-<br />
| 0062<br />
| [[#GPUREG_0062|GPUREG_0062]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_TEST1<br />
|-<br />
| 0063<br />
| [[#GPUREG_0063|GPUREG_0063]]<br />
| <br />
|<br />
|-<br />
| 0064<br />
| [[#GPUREG_0064|GPUREG_0064]]<br />
|?<br />
|PICA_REG_GS_OUT_ATTR_MODE / PICA_REG_VS_OUT_ATTR_MODE<br />
|-<br />
| 0065<br />
| [[#GPUREG_SCISSORTEST_MODE|GPUREG_SCISSORTEST_MODE]]<br />
| <br />
|PICA_REG_SCISSOR<br />
|-<br />
| 0066<br />
| [[#GPUREG_SCISSORTEST_POS|GPUREG_SCISSORTEST_POS]]<br />
| <br />
|PICA_REG_SCISSOR_XY<br />
|-<br />
| 0067<br />
| [[#GPUREG_SCISSORTEST_DIM|GPUREG_SCISSORTEST_DIM]]<br />
| <br />
|PICA_REG_SCISSOR_SIZE<br />
|-<br />
| 0068<br />
| [[#GPUREG_0068|GPUREG_0068]]<br />
| <br />
|PICA_REG_VIEWPORT_XY<br />
|-<br />
| 0069<br />
| [[#GPUREG_0069|GPUREG_0069]]<br />
| <br />
|<br />
|-<br />
| 006A<br />
| [[#GPUREG_006A|GPUREG_006A]]<br />
|<br />
|PICA_REG_EARLY_DEPTH_DATA<br />
|-<br />
| 006B<br />
| [[#GPUREG_006B|GPUREG_006B]]<br />
| <br />
|<br />
|-<br />
| 006C<br />
| [[#GPUREG_006C|GPUREG_006C]]<br />
| <br />
|<br />
|-<br />
| 006D<br />
| [[#GPUREG_006D|GPUREG_006D]]<br />
|?<br />
|PICA_REG_FRAG_OP_WSCALE<br />
|-<br />
| 006E<br />
| [[#GPUREG_006E|GPUREG_006E]]<br />
|?<br />
|PICA_REG_RENDER_BUF_RESOLUTION1<br />
|-<br />
| 006F<br />
| [[#GPUREG_006F|GPUREG_006F]]<br />
|?<br />
|PICA_REG_GS_OUT_ATTR_CLK / PICA_REG_VS_OUT_ATTR_CLK<br />
|-<br />
| 0070<br />
| [[#GPUREG_0070|GPUREG_0070]]<br />
| <br />
|<br />
|-<br />
| 0071<br />
| [[#GPUREG_0071|GPUREG_0071]]<br />
| <br />
|<br />
|-<br />
| 0072<br />
| [[#GPUREG_0072|GPUREG_0072]]<br />
| <br />
|<br />
|-<br />
| 0073<br />
| [[#GPUREG_0073|GPUREG_0073]]<br />
| <br />
|<br />
|-<br />
| 0074<br />
| [[#GPUREG_0074|GPUREG_0074]]<br />
| <br />
|<br />
|-<br />
| 0075<br />
| [[#GPUREG_0075|GPUREG_0075]]<br />
| <br />
|<br />
|-<br />
| 0076<br />
| [[#GPUREG_0076|GPUREG_0076]]<br />
| <br />
|<br />
|-<br />
| 0077<br />
| [[#GPUREG_0077|GPUREG_0077]]<br />
| <br />
|<br />
|-<br />
| 0078<br />
| [[#GPUREG_0078|GPUREG_0078]]<br />
| <br />
|<br />
|-<br />
| 0079<br />
| [[#GPUREG_0079|GPUREG_0079]]<br />
| <br />
|<br />
|-<br />
| 007A<br />
| [[#GPUREG_007A|GPUREG_007A]]<br />
| <br />
|<br />
|-<br />
| 007B<br />
| [[#GPUREG_007B|GPUREG_007B]]<br />
| <br />
|<br />
|-<br />
| 007C<br />
| [[#GPUREG_007C|GPUREG_007C]]<br />
| <br />
|<br />
|-<br />
| 007D<br />
| [[#GPUREG_007D|GPUREG_007D]]<br />
| <br />
|<br />
|-<br />
| 007E<br />
| [[#GPUREG_007E|GPUREG_007E]]<br />
| <br />
|<br />
|-<br />
| 007F<br />
| [[#GPUREG_007F|GPUREG_007F]]<br />
| <br />
|<br />
|-<br />
| 0080<br />
| [[#GPUREG_TEXUNITS_CONFIG|GPUREG_TEXUNITS_CONFIG]]<br />
| <br />
|PICA_REG_TEXTURE_FUNC<br />
|-<br />
| 0081<br />
| [[#GPUREG_0081|GPUREG_0081]]<br />
|?<br />
|PICA_REG_TEXTURE0_BORDER_COLOR<br />
|-<br />
| 0082<br />
| [[#GPUREG_TEXUNIT0_DIM|GPUREG_TEXUNIT0_DIM]]<br />
|<br />
|PICA_REG_TEXTURE0_SIZE<br />
|-<br />
| 0083<br />
| [[#GPUREG_TEXUNIT0_PARAM|GPUREG_TEXUNIT0_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE0_WRAP_FILTER<br />
|-<br />
| 0084<br />
| [[#GPUREG_0084|GPUREG_0084]]<br />
|?<br />
|PICA_REG_TEXTURE0_LOD<br />
|-<br />
| 0085<br />
| [[#GPUREG_TEXUNIT0_LOC|GPUREG_TEXUNIT0_LOC]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR1<br />
|-<br />
| 0086<br />
| [[#GPUREG_0086|GPUREG_0086]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR2<br />
|-<br />
| 0087<br />
| [[#GPUREG_0087|GPUREG_0087]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR3<br />
|-<br />
| 0088<br />
| [[#GPUREG_0088|GPUREG_0088]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR4<br />
|-<br />
| 0089<br />
| [[#GPUREG_0089|GPUREG_0089]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR5<br />
|-<br />
| 008A<br />
| [[#GPUREG_008A|GPUREG_008A]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR6<br />
|-<br />
| 008B<br />
| [[#GPUREG_008B|GPUREG_008B]]<br />
|?<br />
|PICA_REG_TEXTURE0_SHADOW<br />
|-<br />
| 008C<br />
| [[#GPUREG_008C|GPUREG_008C]]<br />
|<br />
|<br />
|-<br />
| 008D<br />
| [[#GPUREG_008D|GPUREG_008D]]<br />
|<br />
|<br />
|-<br />
| 008E<br />
| [[#GPUREG_TEXUNIT0_TYPE|GPUREG_TEXUNIT0_TYPE]]<br />
|?<br />
|PICA_REG_TEXTURE0_FORMAT<br />
|-<br />
| 008F<br />
| [[#GPUREG_008F|GPUREG_008F]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_EN0<br />
|-<br />
| 0090<br />
| [[#GPUREG_0090|GPUREG_0090]]<br />
| <br />
|<br />
|-<br />
| 0091<br />
| [[#GPUREG_0091|GPUREG_0091]]<br />
|?<br />
|PICA_REG_TEXTURE1_BORDER_COLOR<br />
|-<br />
| 0092<br />
| [[#GPUREG_TEXUNIT1_DIM|GPUREG_TEXUNIT1_DIM]]<br />
| <br />
|PICA_REG_TEXTURE1_SIZE<br />
|-<br />
| 0093<br />
| [[#GPUREG_TEXUNIT1_PARAM|GPUREG_TEXUNIT1_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE1_WRAP_FILTER<br />
|-<br />
| 0094<br />
| [[#GPUREG_0094|GPUREG_0094]]<br />
|?<br />
|PICA_REG_TEXTURE1_LOD<br />
|-<br />
| 0095<br />
| [[#GPUREG_TEXUNIT1_LOC|GPUREG_TEXUNIT1_LOC]]<br />
| <br />
|PICA_REG_TEXTURE1_ADDR<br />
|-<br />
| 0096<br />
| [[#GPUREG_TEXUNIT1_TYPE|GPUREG_TEXUNIT1_TYPE]]<br />
| <br />
|PICA_REG_TEXTURE1_FORMAT<br />
|-<br />
| 0097<br />
| [[#GPUREG_0097|GPUREG_0097]]<br />
| <br />
|<br />
|-<br />
| 0098<br />
| [[#GPUREG_0098|GPUREG_0098]]<br />
| <br />
|<br />
|-<br />
| 0099<br />
| [[#GPUREG_0099|GPUREG_0099]]<br />
|?<br />
|PICA_REG_TEXTURE2_BORDER_COLOR<br />
|-<br />
| 009A<br />
| [[#GPUREG_TEXUNIT2_DIM|GPUREG_TEXUNIT2_DIM]]<br />
| <br />
|PICA_REG_TEXTURE2_SIZE<br />
|-<br />
| 009B<br />
| [[#GPUREG_TEXUNIT2_PARAM|GPUREG_TEXUNIT2_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE2_WRAP_FILTER<br />
|-<br />
| 009C<br />
| [[#GPUREG_009C|GPUREG_009C]]<br />
|?<br />
|PICA_REG_TEXTURE2_LOD<br />
|-<br />
| 009D<br />
| [[#GPUREG_TEXUNIT2_LOC|GPUREG_TEXUNIT2_LOC]]<br />
|<br />
|PICA_REG_TEXTURE2_ADDR<br />
|-<br />
| 009E<br />
| [[#GPUREG_TEXUNIT2_TYPE|GPUREG_TEXUNIT2_TYPE]]<br />
| <br />
|PICA_REG_TEXTURE2_FORMAT<br />
|-<br />
| 009F<br />
| [[#GPUREG_009F|GPUREG_009F]]<br />
| <br />
|<br />
|-<br />
| 00A0<br />
| [[#GPUREG_00A0|GPUREG_00A0]]<br />
| <br />
|<br />
|-<br />
| 00A1<br />
| [[#GPUREG_00A1|GPUREG_00A1]]<br />
| <br />
|<br />
|-<br />
| 00A2<br />
| [[#GPUREG_00A2|GPUREG_00A2]]<br />
| <br />
|<br />
|-<br />
| 00A3<br />
| [[#GPUREG_00A3|GPUREG_00A3]]<br />
| <br />
|<br />
|-<br />
| 00A4<br />
| [[#GPUREG_00A4|GPUREG_00A4]]<br />
| <br />
|<br />
|-<br />
| 00A5<br />
| [[#GPUREG_00A5|GPUREG_00A5]]<br />
| <br />
|<br />
|-<br />
| 00A6<br />
| [[#GPUREG_00A6|GPUREG_00A6]]<br />
| <br />
|<br />
|-<br />
| 00A7<br />
| [[#GPUREG_00A7|GPUREG_00A7]]<br />
| <br />
|<br />
|-<br />
| 00A8<br />
| [[#GPUREG_00A8|GPUREG_00A8]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX0<br />
|-<br />
| 00A9<br />
| [[#GPUREG_00A9|GPUREG_00A9]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX1<br />
|-<br />
| 00AA<br />
| [[#GPUREG_00AA|GPUREG_00AA]]<br />
|? <br />
|PICA_REG_TEXTURE3_PROTEX2<br />
|-<br />
| 00AB<br />
| [[#GPUREG_00AB|GPUREG_00AB]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX3<br />
|-<br />
| 00AC<br />
| [[#GPUREG_00AC|GPUREG_00AC]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX4<br />
|-<br />
| 00AD<br />
| [[#GPUREG_00AD|GPUREG_00AD]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX5<br />
|-<br />
| 00AE<br />
| [[#GPUREG_00AE|GPUREG_00AE]]<br />
| <br />
|<br />
|-<br />
| 00AF<br />
| [[#GPUREG_00AF|GPUREG_00AF]]<br />
|?<br />
|PICA_REG_PROTEX_LUT<br />
|-<br />
| 00B0<br />
| [[#GPUREG_00B0|GPUREG_00B0]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA0<br />
|-<br />
| 00B1<br />
| [[#GPUREG_00B1|GPUREG_00B1]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA1<br />
|-<br />
| 00B2<br />
| [[#GPUREG_00B2|GPUREG_00B2]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA2<br />
|-<br />
| 00B3<br />
| [[#GPUREG_00B3|GPUREG_00B3]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA3<br />
|-<br />
| 00B4<br />
| [[#GPUREG_00B4|GPUREG_00B4]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA4<br />
|-<br />
| 00B5<br />
| [[#GPUREG_00B5|GPUREG_00B5]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA5<br />
|-<br />
| 00B6<br />
| [[#GPUREG_00B6|GPUREG_00B6]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA6<br />
|-<br />
| 00B7<br />
| [[#GPUREG_00B7|GPUREG_00B7]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA7<br />
|-<br />
| 00B8<br />
| [[#GPUREG_00B8|GPUREG_00B8]]<br />
| <br />
|<br />
|-<br />
| 00B9<br />
| [[#GPUREG_00B9|GPUREG_00B9]]<br />
| <br />
|<br />
|-<br />
| 00BA<br />
| [[#GPUREG_00BA|GPUREG_00BA]]<br />
| <br />
|<br />
|-<br />
| 00BB<br />
| [[#GPUREG_00BB|GPUREG_00BB]]<br />
| <br />
|<br />
|-<br />
| 00BC<br />
| [[#GPUREG_00BC|GPUREG_00BC]]<br />
| <br />
|<br />
|-<br />
| 00BD<br />
| [[#GPUREG_00BD|GPUREG_00BD]]<br />
| <br />
|<br />
|-<br />
| 00BE<br />
| [[#GPUREG_00BE|GPUREG_00BE]]<br />
| <br />
|<br />
|-<br />
| 00BF<br />
| [[#GPUREG_00BF|GPUREG_00BF]]<br />
| <br />
|<br />
|-<br />
| 00C0<br />
| [[#GPUREG_TEXENV0_CONFIG0|GPUREG_TEXENV0_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_0<br />
|-<br />
| 00C1<br />
| [[#GPUREG_TEXENV0_CONFIG1|GPUREG_TEXENV0_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_0_OPERAND<br />
|-<br />
| 00C2<br />
| [[#GPUREG_TEXENV0_CONFIG2|GPUREG_TEXENV0_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_0_COMBINE<br />
|-<br />
| 00C3<br />
| [[#GPUREG_TEXENV0_CONFIG3|GPUREG_TEXENV0_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_0_COLOR<br />
|-<br />
| 00C4<br />
| [[#GPUREG_TEXENV0_CONFIG4|GPUREG_TEXENV0_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_0_SCALE<br />
|-<br />
| 00C5<br />
| [[#GPUREG_00C5|GPUREG_00C5]]<br />
| <br />
|<br />
|-<br />
| 00C6<br />
| [[#GPUREG_00C6|GPUREG_00C6]]<br />
| <br />
|<br />
|-<br />
| 00C7<br />
| [[#GPUREG_00C7|GPUREG_00C7]]<br />
| <br />
|<br />
|-<br />
| 00C8<br />
| [[#GPUREG_TEXENV1_CONFIG0|GPUREG_TEXENV1_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_1<br />
|-<br />
| 00C9<br />
| [[#GPUREG_TEXENV1_CONFIG1|GPUREG_TEXENV1_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_1_OPERAND<br />
|-<br />
| 00CA<br />
| [[#GPUREG_TEXENV1_CONFIG2|GPUREG_TEXENV1_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_1_COMBINE<br />
|-<br />
| 00CB<br />
| [[#GPUREG_TEXENV1_CONFIG3|GPUREG_TEXENV1_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_1_COLOR<br />
|-<br />
| 00CC<br />
| [[#GPUREG_TEXENV1_CONFIG4|GPUREG_TEXENV1_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_1_SCALE<br />
|-<br />
| 00CD<br />
| [[#GPUREG_00CD|GPUREG_00CD]]<br />
| <br />
|<br />
|-<br />
| 00CE<br />
| [[#GPUREG_00CE|GPUREG_00CE]]<br />
| <br />
|<br />
|-<br />
| 00CF<br />
| [[#GPUREG_00CF|GPUREG_00CF]]<br />
| <br />
|<br />
|-<br />
| 00D0<br />
| [[#GPUREG_TEXENV2_CONFIG0|GPUREG_TEXENV2_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_2<br />
|-<br />
| 00D1<br />
| [[#GPUREG_TEXENV2_CONFIG1|GPUREG_TEXENV2_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_2_OPERAND<br />
|-<br />
| 00D2<br />
| [[#GPUREG_TEXENV2_CONFIG2|GPUREG_TEXENV2_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_2_COMBINE<br />
|-<br />
| 00D3<br />
| [[#GPUREG_TEXENV2_CONFIG3|GPUREG_TEXENV2_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_2_COLOR<br />
|-<br />
| 00D4<br />
| [[#GPUREG_TEXENV2_CONFIG4|GPUREG_TEXENV2_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_2_SCALE<br />
|-<br />
| 00D5<br />
| [[#GPUREG_00D5|GPUREG_00D5]]<br />
| <br />
|<br />
|-<br />
| 00D6<br />
| [[#GPUREG_00D6|GPUREG_00D6]]<br />
| <br />
|<br />
|-<br />
| 00D7<br />
| [[#GPUREG_00D7|GPUREG_00D7]]<br />
| <br />
|<br />
|-<br />
| 00D8<br />
| [[#GPUREG_TEXENV3_CONFIG0|GPUREG_TEXENV3_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_3<br />
|-<br />
| 00D9<br />
| [[#GPUREG_TEXENV3_CONFIG1|GPUREG_TEXENV3_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_3_OPERAND<br />
|-<br />
| 00DA<br />
| [[#GPUREG_TEXENV3_CONFIG2|GPUREG_TEXENV3_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_3_COMBINE<br />
|-<br />
| 00DB<br />
| [[#GPUREG_TEXENV3_CONFIG3|GPUREG_TEXENV3_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_3_COLOR<br />
|-<br />
| 00DC<br />
| [[#GPUREG_TEXENV3_CONFIG4|GPUREG_TEXENV3_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_3_SCALE<br />
|-<br />
| 00DD<br />
| [[#GPUREG_00DD|GPUREG_00DD]]<br />
| <br />
|<br />
|-<br />
| 00DE<br />
| [[#GPUREG_00DE|GPUREG_00DE]]<br />
| <br />
|<br />
|-<br />
| 00DF<br />
| [[#GPUREG_00DF|GPUREG_00DF]]<br />
| <br />
|<br />
|-<br />
| 00E0<br />
| [[#GPUREG_00E0|GPUREG_00E0]]<br />
|?<br />
|PICA_REG_GAS_FOG_MODE / PICA_REG_TEX_ENV_BUF_INPUT<br />
|-<br />
| 00E1<br />
| [[#GPUREG_00E1|GPUREG_00E1]]<br />
|?<br />
|PICA_REG_FOG_COLOR<br />
|-<br />
| 00E2<br />
| [[#GPUREG_00E2|GPUREG_00E2]]<br />
| <br />
|<br />
|-<br />
| 00E3<br />
| [[#GPUREG_00E3|GPUREG_00E3]]<br />
| <br />
|<br />
|-<br />
| 00E4<br />
| [[#GPUREG_00E4|GPUREG_00E4]]<br />
|?<br />
|PICA_REG_GAS_ATTENUATION<br />
|-<br />
| 00E5<br />
| [[#GPUREG_00E5|GPUREG_00E5]]<br />
|?<br />
|PICA_REG_GAS_ACCMAX<br />
|-<br />
| 00E6<br />
| [[#GPUREG_00E6|GPUREG_00E6]]<br />
|?<br />
|PICA_REG_FOG_LUT_INDEX<br />
|-<br />
| 00E7<br />
| [[#GPUREG_00E7|GPUREG_00E7]]<br />
| <br />
|<br />
|-<br />
| 00E8<br />
| [[#GPUREG_00E8|GPUREG_00E8]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA0<br />
|-<br />
| 00E9<br />
| [[#GPUREG_00E9|GPUREG_00E9]]<br />
|? <br />
|PICA_REG_FOG_LUT_DATA1<br />
|-<br />
| 00EA<br />
| [[#GPUREG_00EA|GPUREG_00EA]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA2<br />
|-<br />
| 00EB<br />
| [[#GPUREG_00EB|GPUREG_00EB]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA3<br />
|-<br />
| 00EC<br />
| [[#GPUREG_00EC|GPUREG_00EC]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA4<br />
|-<br />
| 00ED<br />
| [[#GPUREG_00ED|GPUREG_00ED]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA5<br />
|-<br />
| 00EE<br />
| [[#GPUREG_00EE|GPUREG_00EE]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA6<br />
|-<br />
| 00EF<br />
| [[#GPUREG_00EF|GPUREG_00EF]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA7<br />
|-<br />
| 00F0<br />
| [[#GPUREG_TEXENV4_CONFIG0|GPUREG_TEXENV4_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_4<br />
|-<br />
| 00F1<br />
| [[#GPUREG_TEXENV4_CONFIG1|GPUREG_TEXENV4_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_4_OPERAND<br />
|-<br />
| 00F2<br />
| [[#GPUREG_TEXENV4_CONFIG2|GPUREG_TEXENV4_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_4_COMBINE<br />
|-<br />
| 00F3<br />
| [[#GPUREG_TEXENV4_CONFIG3|GPUREG_TEXENV4_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_4_COLOR<br />
|-<br />
| 00F4<br />
| [[#GPUREG_TEXENV4_CONFIG4|GPUREG_TEXENV4_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_4_SCALE<br />
|-<br />
| 00F5<br />
| [[#GPUREG_00F5|GPUREG_00F5]]<br />
| <br />
|<br />
|-<br />
| 00F6<br />
| [[#GPUREG_00F6|GPUREG_00F6]]<br />
| <br />
|<br />
|-<br />
| 00F7<br />
| [[#GPUREG_00F7|GPUREG_00F7]]<br />
| <br />
|<br />
|-<br />
| 00F8<br />
| [[#GPUREG_TEXENV5_CONFIG0|GPUREG_TEXENV5_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_5<br />
|-<br />
| 00F9<br />
| [[#GPUREG_TEXENV5_CONFIG1|GPUREG_TEXENV5_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_5_OPERAND<br />
|-<br />
| 00FA<br />
| [[#GPUREG_TEXENV5_CONFIG2|GPUREG_TEXENV5_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_5_COMBINE<br />
|-<br />
| 00FB<br />
| [[#GPUREG_TEXENV5_CONFIG3|GPUREG_TEXENV5_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_5_COLOR<br />
|-<br />
| 00FC<br />
| [[#GPUREG_TEXENV5_CONFIG4|GPUREG_TEXENV5_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_5_SCALE<br />
|-<br />
| 00FD<br />
| [[#GPUREG_00FD|GPUREG_00FD]]<br />
|?<br />
|PICA_REG_TEX_ENV_BUF_COLOR<br />
|-<br />
| 00FE<br />
| [[#GPUREG_00FE|GPUREG_00FE]]<br />
| <br />
|<br />
|-<br />
| 00FF<br />
| [[#GPUREG_00FF|GPUREG_00FF]]<br />
| <br />
|<br />
|-<br />
| 0100<br />
| [[#GPUREG_COLOROUTPUT_CONFIG|GPUREG_COLOROUTPUT_CONFIG]]<br />
| ?<br />
|PICA_REG_COLOR_OPERATION<br />
|-<br />
| 0101<br />
| [[#GPUREG_BLEND_CONFIG|GPUREG_BLEND_CONFIG]]<br />
| <br />
|PICA_REG_BLEND_FUNC<br />
|-<br />
| 0102<br />
| [[#GPUREG_COLORLOGICOP_CONFIG|GPUREG_COLORLOGICOP_CONFIG]]<br />
| <br />
|PICA_REG_LOGIC_OP<br />
|-<br />
| 0103<br />
| [[#GPUREG_BLEND_COLOR|GPUREG_BLEND_COLOR]]<br />
| <br />
|PICA_REG_BLEND_COLOR<br />
|-<br />
| 0104<br />
| [[#GPUREG_ALPHATEST_CONFIG|GPUREG_ALPHATEST_CONFIG]]<br />
| <br />
|PICA_REG_FRAG_OP_ALPHA_TEST<br />
|-<br />
| 0105<br />
| [[#GPUREG_STENCILTEST_CONFIG|GPUREG_STENCILTEST_CONFIG]]<br />
| <br />
|PICA_REG_STENCIL_TEST<br />
|-<br />
| 0106<br />
| [[#GPUREG_STENCILOP_CONFIG|GPUREG_STENCILOP_CONFIG]]<br />
| <br />
|PICA_REG_STENCIL_OP<br />
|-<br />
| 0107<br />
| [[#GPUREG_DEPTHTEST_CONFIG|GPUREG_DEPTHTEST_CONFIG]]<br />
| <br />
|PICA_REG_DEPTH_COLOR_MASK<br />
|-<br />
| 0108<br />
| [[#GPUREG_0108|GPUREG_0108]]<br />
| <br />
|<br />
|-<br />
| 0109<br />
| [[#GPUREG_0109|GPUREG_0109]]<br />
| <br />
|<br />
|-<br />
| 010A<br />
| [[#GPUREG_010A|GPUREG_010A]]<br />
| <br />
|<br />
|-<br />
| 010B<br />
| [[#GPUREG_010B|GPUREG_010B]]<br />
| <br />
|<br />
|-<br />
| 010C<br />
| [[#GPUREG_010C|GPUREG_010C]]<br />
| <br />
|<br />
|-<br />
| 010D<br />
| [[#GPUREG_010D|GPUREG_010D]]<br />
| <br />
|<br />
|-<br />
| 010E<br />
| [[#GPUREG_010E|GPUREG_010E]]<br />
| <br />
|<br />
|-<br />
| 010F<br />
| [[#GPUREG_010F|GPUREG_010F]]<br />
| <br />
|<br />
|-<br />
| 0110<br />
| [[#GPUREG_0110|GPUREG_0110]]<br />
|?<br />
|PICA_REG_COLOR_BUFFER_CLEAR0<br />
|-<br />
| 0111<br />
| [[#GPUREG_0111|GPUREG_0111]]<br />
|?<br />
|PICA_REG_COLOR_BUFFER_CLEAR1<br />
|-<br />
| 0112<br />
| [[#GPUREG_COLORBUFFER_READ|GPUREG_COLORBUFFER_READ]]<br />
| <br />
|PICA_REG_COLOR_BUFFER_READ<br />
|-<br />
| 0113<br />
| [[#GPUREG_COLORBUFFER_WRITE|GPUREG_COLORBUFFER_WRITE]]<br />
| <br />
|PICA_REG_COLOR_BUFFER_WRITE<br />
|-<br />
| 0114<br />
| [[#GPUREG_DEPTHBUFFER_READ|GPUREG_DEPTHBUFFER_READ]]<br />
| <br />
|PICA_REG_DEPTH_STENCIL_READ<br />
|-<br />
| 0115<br />
| [[#GPUREG_DEPTHBUFFER_WRITE|GPUREG_DEPTHBUFFER_WRITE]]<br />
| <br />
|PICA_REG_DEPTH_STENCIL_WRITE<br />
|-<br />
| 0116<br />
| [[#GPUREG_DEPTHBUFFER_FORMAT|GPUREG_DEPTHBUFFER_FORMAT]]<br />
| <br />
|PICA_REG_RENDER_BUF_DEPTH_MODE<br />
|-<br />
| 0117<br />
| [[#GPUREG_COLORBUFFER_FORMAT|GPUREG_COLORBUFFER_FORMAT]]<br />
| <br />
|PICA_REG_RENDER_BUF_COLOR_MODE<br />
|-<br />
| 0118<br />
| [[#GPUREG_0118|GPUREG_0118]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_TEST2<br />
|-<br />
| 0119<br />
| [[#GPUREG_0119|GPUREG_0119]]<br />
| <br />
|<br />
|-<br />
| 011A<br />
| [[#GPUREG_011A|GPUREG_011A]]<br />
| <br />
|<br />
|-<br />
| 011B<br />
| [[#GPUREG_011B|GPUREG_011B]]<br />
|?<br />
|PICA_REG_RENDER_BLOCK_FORMAT<br />
|-<br />
| 011C<br />
| [[#GPUREG_DEPTHBUFFER_LOC|GPUREG_DEPTHBUFFER_LOC]]<br />
|<br />
|PICA_REG_RENDER_BUF_DEPTH_ADDR<br />
|-<br />
| 011D<br />
| [[#GPUREG_COLORBUFFER_LOC|GPUREG_COLORBUFFER_LOC]]<br />
| <br />
|PICA_REG_RENDER_BUF_COLOR_ADDR<br />
|-<br />
| 011E<br />
| [[#GPUREG_OUTBUFFER_DIM|GPUREG_OUTBUFFER_DIM]]<br />
| <br />
|PICA_REG_RENDER_BUF_RESOLUTION0<br />
|-<br />
| 011F<br />
| [[#GPUREG_011F|GPUREG_011F]]<br />
| <br />
|<br />
|-<br />
| 0120<br />
| [[#GPUREG_0120|GPUREG_0120]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_XY<br />
|-<br />
| 0121<br />
| [[#GPUREG_0121|GPUREG_0121]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_Z<br />
|-<br />
| 0122<br />
| [[#GPUREG_0122|GPUREG_0122]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_Z_COLOR<br />
|-<br />
| 0123<br />
| [[#GPUREG_0123|GPUREG_0123]]<br />
|?<br />
|PICA_REG_GAS_LUT_INDEX<br />
|-<br />
| 0124<br />
| [[#GPUREG_0124|GPUREG_0124]]<br />
|?<br />
|PICA_REG_GAS_LUT_DATA<br />
|-<br />
| 0125<br />
| [[#GPUREG_0125|GPUREG_0125]]<br />
| <br />
|<br />
|-<br />
| 0126<br />
| [[#GPUREG_0126|GPUREG_0126]]<br />
|?<br />
|PICA_REG_GAS_DELTAZ_DEPTH<br />
|-<br />
| 0127<br />
| [[#GPUREG_0127|GPUREG_0127]]<br />
| <br />
|<br />
|-<br />
| 0128<br />
| [[#GPUREG_0128|GPUREG_0128]]<br />
| <br />
|<br />
|-<br />
| 0129<br />
| [[#GPUREG_0129|GPUREG_0129]]<br />
| <br />
|<br />
|-<br />
| 012A<br />
| [[#GPUREG_012A|GPUREG_012A]]<br />
| <br />
|<br />
|-<br />
| 012B<br />
| [[#GPUREG_012B|GPUREG_012B]]<br />
| <br />
|<br />
|-<br />
| 012C<br />
| [[#GPUREG_012C|GPUREG_012C]]<br />
| <br />
|<br />
|-<br />
| 012D<br />
| [[#GPUREG_012D|GPUREG_012D]]<br />
| <br />
|<br />
|-<br />
| 012E<br />
| [[#GPUREG_012E|GPUREG_012E]]<br />
| <br />
|<br />
|-<br />
| 012F<br />
| [[#GPUREG_012F|GPUREG_012F]]<br />
| <br />
|<br />
|-<br />
| 0130<br />
| [[#GPUREG_0130|GPUREG_0130]]<br />
|?<br />
|PICA_REG_FRAG_OP_SHADOW<br />
|-<br />
| 0131<br />
| [[#GPUREG_0131|GPUREG_0131]]<br />
| <br />
|<br />
|-<br />
| 0132<br />
| [[#GPUREG_0132|GPUREG_0132]]<br />
| <br />
|<br />
|-<br />
| 0133<br />
| [[#GPUREG_0133|GPUREG_0133]]<br />
| <br />
|<br />
|-<br />
| 0134<br />
| [[#GPUREG_0134|GPUREG_0134]]<br />
| <br />
|<br />
|-<br />
| 0135<br />
| [[#GPUREG_0135|GPUREG_0135]]<br />
| <br />
|<br />
|-<br />
| 0136<br />
| [[#GPUREG_0136|GPUREG_0136]]<br />
| <br />
|<br />
|-<br />
| 0137<br />
| [[#GPUREG_0137|GPUREG_0137]]<br />
| <br />
|<br />
|-<br />
| 0138<br />
| [[#GPUREG_0138|GPUREG_0138]]<br />
| <br />
|<br />
|-<br />
| 0139<br />
| [[#GPUREG_0139|GPUREG_0139]]<br />
| <br />
|<br />
|-<br />
| 013A<br />
| [[#GPUREG_013A|GPUREG_013A]]<br />
| <br />
|<br />
|-<br />
| 013B<br />
| [[#GPUREG_013B|GPUREG_013B]]<br />
| <br />
|<br />
|-<br />
| 013C<br />
| [[#GPUREG_013C|GPUREG_013C]]<br />
| <br />
|<br />
|-<br />
| 013D<br />
| [[#GPUREG_013D|GPUREG_013D]]<br />
| <br />
|<br />
|-<br />
| 013E<br />
| [[#GPUREG_013E|GPUREG_013E]]<br />
| <br />
|<br />
|-<br />
| 013F<br />
| [[#GPUREG_013F|GPUREG_013F]]<br />
| <br />
|<br />
|-<br />
| 0140<br />
| [[#GPUREG_0140|GPUREG_0140]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPECULAR0 / PICA_REG_FRAG_LIGHT_START<br />
|-<br />
| 0141<br />
| [[#GPUREG_0141|GPUREG_0141]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPECULAR1<br />
|-<br />
| 0142<br />
| [[#GPUREG_0142|GPUREG_0142]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIFFUSE<br />
|-<br />
| 0143<br />
| [[#GPUREG_0143|GPUREG_0143]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_AMBIENT<br />
|-<br />
| 0144<br />
| [[#GPUREG_0144|GPUREG_0144]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_POSITION_XY<br />
|-<br />
| 0145<br />
| [[#GPUREG_0145|GPUREG_0145]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_POSITION_Z<br />
|-<br />
| 0146<br />
| [[#GPUREG_0146|GPUREG_0146]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPOT_XY<br />
|-<br />
| 0147<br />
| [[#GPUREG_0147|GPUREG_0147]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPOT_Z<br />
|-<br />
| 0148<br />
| [[#GPUREG_0148|GPUREG_0148]]<br />
| <br />
|<br />
|-<br />
| 0149<br />
| [[#GPUREG_0149|GPUREG_0149]]<br />
| <br />
|PICA_REG_FRAG_LIGHT0_TYPE<br />
|-<br />
| 014A<br />
| [[#GPUREG_014A|GPUREG_014A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIST_ATTN_BIAS<br />
|-<br />
| 014B<br />
| [[#GPUREG_014B|GPUREG_014B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIST_ATTN_SCALE<br />
|-<br />
| 014C<br />
| [[#GPUREG_014C|GPUREG_014C]]<br />
| <br />
|<br />
|-<br />
| 014D<br />
| [[#GPUREG_014D|GPUREG_014D]]<br />
| <br />
|<br />
|-<br />
| 014E<br />
| [[#GPUREG_014E|GPUREG_014E]]<br />
| <br />
|<br />
|-<br />
| 014F<br />
| [[#GPUREG_014F|GPUREG_014F]]<br />
| <br />
|<br />
|-<br />
| 0150<br />
| [[#GPUREG_0150|GPUREG_0150]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPECULAR0<br />
|-<br />
| 0151<br />
| [[#GPUREG_0151|GPUREG_0151]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPECULAR1<br />
|-<br />
| 0152<br />
| [[#GPUREG_0152|GPUREG_0152]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIFFUSE<br />
|-<br />
| 0153<br />
| [[#GPUREG_0153|GPUREG_0153]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_AMBIENT<br />
|-<br />
| 0154<br />
| [[#GPUREG_0154|GPUREG_0154]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_POSITION_XY<br />
|-<br />
| 0155<br />
| [[#GPUREG_0155|GPUREG_0155]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_POSITION_Z<br />
|-<br />
| 0156<br />
| [[#GPUREG_0156|GPUREG_0156]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPOT_XY<br />
|-<br />
| 0157<br />
| [[#GPUREG_0157|GPUREG_0157]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPOT_Z<br />
|-<br />
| 0158<br />
| [[#GPUREG_0158|GPUREG_0158]]<br />
| <br />
|<br />
|-<br />
| 0159<br />
| [[#GPUREG_0159|GPUREG_0159]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_TYPE<br />
|-<br />
| 015A<br />
| [[#GPUREG_015A|GPUREG_015A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIST_ATTN_BIAS<br />
|-<br />
| 015B<br />
| [[#GPUREG_015B|GPUREG_015B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIST_ATTN_SCALE<br />
|-<br />
| 015C<br />
| [[#GPUREG_015C|GPUREG_015C]]<br />
| <br />
|<br />
|-<br />
| 015D<br />
| [[#GPUREG_015D|GPUREG_015D]]<br />
| <br />
|<br />
|-<br />
| 015E<br />
| [[#GPUREG_015E|GPUREG_015E]]<br />
| <br />
|<br />
|-<br />
| 015F<br />
| [[#GPUREG_015F|GPUREG_015F]]<br />
| <br />
|<br />
|-<br />
| 0160<br />
| [[#GPUREG_0160|GPUREG_0160]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPECULAR0<br />
|-<br />
| 0161<br />
| [[#GPUREG_0161|GPUREG_0161]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPECULAR1<br />
|-<br />
| 0162<br />
| [[#GPUREG_0162|GPUREG_0162]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIFFUSE<br />
|-<br />
| 0163<br />
| [[#GPUREG_0163|GPUREG_0163]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_AMBIENT<br />
|-<br />
| 0164<br />
| [[#GPUREG_0164|GPUREG_0164]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_POSITION_XY<br />
|-<br />
| 0165<br />
| [[#GPUREG_0165|GPUREG_0165]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_POSITION_Z<br />
|-<br />
| 0166<br />
| [[#GPUREG_0166|GPUREG_0166]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPOT_XY<br />
|-<br />
| 0167<br />
| [[#GPUREG_0167|GPUREG_0167]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPOT_Z<br />
|-<br />
| 0168<br />
| [[#GPUREG_0168|GPUREG_0168]]<br />
| <br />
|<br />
|-<br />
| 0169<br />
| [[#GPUREG_0169|GPUREG_0169]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_TYPE<br />
|-<br />
| 016A<br />
| [[#GPUREG_016A|GPUREG_016A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIST_ATTN_BIAS<br />
|-<br />
| 016B<br />
| [[#GPUREG_016B|GPUREG_016B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIST_ATTN_SCALE<br />
|-<br />
| 016C<br />
| [[#GPUREG_016C|GPUREG_016C]]<br />
| <br />
|<br />
|-<br />
| 016D<br />
| [[#GPUREG_016D|GPUREG_016D]]<br />
| <br />
|<br />
|-<br />
| 016E<br />
| [[#GPUREG_016E|GPUREG_016E]]<br />
| <br />
|<br />
|-<br />
| 016F<br />
| [[#GPUREG_016F|GPUREG_016F]]<br />
| <br />
|<br />
|-<br />
| 0170<br />
| [[#GPUREG_0170|GPUREG_0170]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPECULAR0<br />
|-<br />
| 0171<br />
| [[#GPUREG_0171|GPUREG_0171]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPECULAR1<br />
|-<br />
| 0172<br />
| [[#GPUREG_0172|GPUREG_0172]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIFFUSE<br />
|-<br />
| 0173<br />
| [[#GPUREG_0173|GPUREG_0173]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_AMBIENT<br />
|-<br />
| 0174<br />
| [[#GPUREG_0174|GPUREG_0174]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_POSITION_XY<br />
|-<br />
| 0175<br />
| [[#GPUREG_0175|GPUREG_0175]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_POSITION_Z<br />
|-<br />
| 0176<br />
| [[#GPUREG_0176|GPUREG_0176]]<br />
|? <br />
|PICA_REG_FRAG_LIGHT3_SPOT_XY<br />
|-<br />
| 0177<br />
| [[#GPUREG_0177|GPUREG_0177]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPOT_Z<br />
|-<br />
| 0178<br />
| [[#GPUREG_0178|GPUREG_0178]]<br />
| <br />
|<br />
|-<br />
| 0179<br />
| [[#GPUREG_0179|GPUREG_0179]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_TYPE<br />
|-<br />
| 017A<br />
| [[#GPUREG_017A|GPUREG_017A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIST_ATTN_BIAS<br />
|-<br />
| 017B<br />
| [[#GPUREG_017B|GPUREG_017B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIST_ATTN_SCALE<br />
|-<br />
| 017C<br />
| [[#GPUREG_017C|GPUREG_017C]]<br />
| <br />
|<br />
|-<br />
| 017D<br />
| [[#GPUREG_017D|GPUREG_017D]]<br />
| <br />
|<br />
|-<br />
| 017E<br />
| [[#GPUREG_017E|GPUREG_017E]]<br />
| <br />
|<br />
|-<br />
| 017F<br />
| [[#GPUREG_017F|GPUREG_017F]]<br />
| <br />
|<br />
|-<br />
| 0180<br />
| [[#GPUREG_0180|GPUREG_0180]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPECULAR0<br />
|-<br />
| 0181<br />
| [[#GPUREG_0181|GPUREG_0181]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPECULAR1<br />
|-<br />
| 0182<br />
| [[#GPUREG_0182|GPUREG_0182]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIFFUSE<br />
|-<br />
| 0183<br />
| [[#GPUREG_0183|GPUREG_0183]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_AMBIENT<br />
|-<br />
| 0184<br />
| [[#GPUREG_0184|GPUREG_0184]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_POSITION_XY<br />
|-<br />
| 0185<br />
| [[#GPUREG_0185|GPUREG_0185]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_POSITION_Z<br />
|-<br />
| 0186<br />
| [[#GPUREG_0186|GPUREG_0186]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPOT_XY<br />
|-<br />
| 0187<br />
| [[#GPUREG_0187|GPUREG_0187]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPOT_Z<br />
|-<br />
| 0188<br />
| [[#GPUREG_0188|GPUREG_0188]]<br />
| <br />
|<br />
|-<br />
| 0189<br />
| [[#GPUREG_0189|GPUREG_0189]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_TYPE<br />
|-<br />
| 018A<br />
| [[#GPUREG_018A|GPUREG_018A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIST_ATTN_BIAS<br />
|-<br />
| 018B<br />
| [[#GPUREG_018B|GPUREG_018B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIST_ATTN_SCALE<br />
|-<br />
| 018C<br />
| [[#GPUREG_018C|GPUREG_018C]]<br />
| <br />
|<br />
|-<br />
| 018D<br />
| [[#GPUREG_018D|GPUREG_018D]]<br />
| <br />
|<br />
|-<br />
| 018E<br />
| [[#GPUREG_018E|GPUREG_018E]]<br />
| <br />
|<br />
|-<br />
| 018F<br />
| [[#GPUREG_018F|GPUREG_018F]]<br />
| <br />
|<br />
|-<br />
| 0190<br />
| [[#GPUREG_0190|GPUREG_0190]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPECULAR0<br />
|-<br />
| 0191<br />
| [[#GPUREG_0191|GPUREG_0191]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPECULAR1<br />
|-<br />
| 0192<br />
| [[#GPUREG_0192|GPUREG_0192]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_DIFFUSE<br />
|-<br />
| 0193<br />
| [[#GPUREG_0193|GPUREG_0193]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_AMBIENT<br />
|-<br />
| 0194<br />
| [[#GPUREG_0194|GPUREG_0194]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_POSITION_XY<br />
|-<br />
| 0195<br />
| [[#GPUREG_0195|GPUREG_0195]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_POSITION_Z<br />
|-<br />
| 0196<br />
| [[#GPUREG_0196|GPUREG_0196]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPOT_XY<br />
|-<br />
| 0197<br />
| [[#GPUREG_0197|GPUREG_0197]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPOT_Z<br />
|-<br />
| 0198<br />
| [[#GPUREG_0198|GPUREG_0198]]<br />
| <br />
|<br />
|-<br />
| 0199<br />
| [[#GPUREG_0199|GPUREG_0199]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_TYPE<br />
|-<br />
| 019A<br />
| [[#GPUREG_019A|GPUREG_019A]]<br />
| <br />
|<br />
|-<br />
| 019B<br />
| [[#GPUREG_019B|GPUREG_019B]]<br />
| <br />
|<br />
|-<br />
| 019C<br />
| [[#GPUREG_019C|GPUREG_019C]]<br />
| <br />
|<br />
|-<br />
| 019D<br />
| [[#GPUREG_019D|GPUREG_019D]]<br />
| <br />
|<br />
|-<br />
| 019E<br />
| [[#GPUREG_019E|GPUREG_019E]]<br />
| <br />
|<br />
|-<br />
| 019F<br />
| [[#GPUREG_019F|GPUREG_019F]]<br />
| <br />
|<br />
|-<br />
| 01A0<br />
| [[#GPUREG_01A0|GPUREG_01A0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPECULAR0<br />
|-<br />
| 01A1<br />
| [[#GPUREG_01A1|GPUREG_01A1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPECULAR1<br />
|-<br />
| 01A2<br />
| [[#GPUREG_01A2|GPUREG_01A2]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_DIFFUSE<br />
|-<br />
| 01A3<br />
| [[#GPUREG_01A3|GPUREG_01A3]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_AMBIENT<br />
|-<br />
| 01A4<br />
| [[#GPUREG_01A4|GPUREG_01A4]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_POSITION_XY<br />
|-<br />
| 01A5<br />
| [[#GPUREG_01A5|GPUREG_01A5]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_POSITION_Z<br />
|-<br />
| 01A6<br />
| [[#GPUREG_01A6|GPUREG_01A6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPOT_XY<br />
|-<br />
| 01A7<br />
| [[#GPUREG_01A7|GPUREG_01A7]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPOT_Z<br />
|-<br />
| 01A8<br />
| [[#GPUREG_01A8|GPUREG_01A8]]<br />
| <br />
|<br />
|-<br />
| 01A9<br />
| [[#GPUREG_01A9|GPUREG_01A9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_TYPE<br />
|-<br />
| 01AA<br />
| [[#GPUREG_01AA|GPUREG_01AA]]<br />
| <br />
|<br />
|-<br />
| 01AB<br />
| [[#GPUREG_01AB|GPUREG_01AB]]<br />
| <br />
|<br />
|-<br />
| 01AC<br />
| [[#GPUREG_01AC|GPUREG_01AC]]<br />
| <br />
|<br />
|-<br />
| 01AD<br />
| [[#GPUREG_01AD|GPUREG_01AD]]<br />
| <br />
|<br />
|-<br />
| 01AE<br />
| [[#GPUREG_01AE|GPUREG_01AE]]<br />
| <br />
|<br />
|-<br />
| 01AF<br />
| [[#GPUREG_01AF|GPUREG_01AF]]<br />
| <br />
|<br />
|-<br />
| 01B0<br />
| [[#GPUREG_01B0|GPUREG_01B0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPECULAR0<br />
|-<br />
| 01B1<br />
| [[#GPUREG_01B1|GPUREG_01B1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPECULAR1<br />
|-<br />
| 01B2<br />
| [[#GPUREG_01B2|GPUREG_01B2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_DIFFUSE<br />
|-<br />
| 01B3<br />
| [[#GPUREG_01B3|GPUREG_01B3]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_AMBIENT<br />
|-<br />
| 01B4<br />
| [[#GPUREG_01B4|GPUREG_01B4]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_POSITION_XY<br />
|-<br />
| 01B5<br />
| [[#GPUREG_01B5|GPUREG_01B5]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_POSITION_Z<br />
|-<br />
| 01B6<br />
| [[#GPUREG_01B6|GPUREG_01B6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPOT_XY<br />
|-<br />
| 01B7<br />
| [[#GPUREG_01B7|GPUREG_01B7]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPOT_Z<br />
|-<br />
| 01B8<br />
| [[#GPUREG_01B8|GPUREG_01B8]]<br />
| <br />
|<br />
|-<br />
| 01B9<br />
| [[#GPUREG_01B9|GPUREG_01B9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_TYPE<br />
|-<br />
| 01BA<br />
| [[#GPUREG_01BA|GPUREG_01BA]]<br />
| <br />
|<br />
|-<br />
| 01BB<br />
| [[#GPUREG_01BB|GPUREG_01BB]]<br />
| <br />
|<br />
|-<br />
| 01BC<br />
| [[#GPUREG_01BC|GPUREG_01BC]]<br />
| <br />
|<br />
|-<br />
| 01BD<br />
| [[#GPUREG_01BD|GPUREG_01BD]]<br />
| <br />
|<br />
|-<br />
| 01BE<br />
| [[#GPUREG_01BE|GPUREG_01BE]]<br />
| <br />
|<br />
|-<br />
| 01BF<br />
| [[#GPUREG_01BF|GPUREG_01BF]]<br />
| <br />
|<br />
|-<br />
| 01C0<br />
| [[#GPUREG_01C0|GPUREG_01C0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_AMBIENT<br />
|-<br />
| 01C1<br />
| [[#GPUREG_01C1|GPUREG_01C1]]<br />
| <br />
|<br />
|-<br />
| 01C2<br />
| [[#GPUREG_01C2|GPUREG_01C2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_SRC_NUM<br />
|-<br />
| 01C3<br />
| [[#GPUREG_01C3|GPUREG_01C3]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_FUNC_MODE0<br />
|-<br />
| 01C4<br />
| [[#GPUREG_01C4|GPUREG_01C4]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_FUNC_MODE1<br />
|-<br />
| 01C5<br />
| [[#GPUREG_01C5|GPUREG_01C5]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT<br />
|-<br />
| 01C6<br />
| [[#GPUREG_01C6|GPUREG_01C6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_EN1<br />
|-<br />
| 01C7<br />
| [[#GPUREG_01C7|GPUREG_01C7]]<br />
| <br />
|<br />
|-<br />
| 01C8<br />
| [[#GPUREG_01C8|GPUREG_01C8]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA0<br />
|-<br />
| 01C9<br />
| [[#GPUREG_01C9|GPUREG_01C9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA1<br />
|-<br />
| 01CA<br />
| [[#GPUREG_01CA|GPUREG_01CA]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA2<br />
|-<br />
| 01CB<br />
| [[#GPUREG_01CB|GPUREG_01CB]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA3<br />
|-<br />
| 01CC<br />
| [[#GPUREG_01CC|GPUREG_01CC]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA4<br />
|-<br />
| 01CD<br />
| [[#GPUREG_01CD|GPUREG_01CD]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA8<br />
|-<br />
| 01CE<br />
| [[#GPUREG_01CE|GPUREG_01CE]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA6<br />
|-<br />
| 01CF<br />
| [[#GPUREG_01CF|GPUREG_01CF]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA7<br />
|-<br />
| 01D0<br />
| [[#GPUREG_01D0|GPUREG_01D0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_ABSLUTINPUT<br />
|-<br />
| 01D1<br />
| [[#GPUREG_01D1|GPUREG_01D1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUTINPUT<br />
|-<br />
| 01D2<br />
| [[#GPUREG_01D2|GPUREG_01D2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUTSCALE<br />
|-<br />
| 01D3<br />
| [[#GPUREG_01D3|GPUREG_01D3]]<br />
| <br />
|<br />
|-<br />
| 01D4<br />
| [[#GPUREG_01D4|GPUREG_01D4]]<br />
| <br />
|<br />
|-<br />
| 01D5<br />
| [[#GPUREG_01D5|GPUREG_01D5]]<br />
| <br />
|<br />
|-<br />
| 01D6<br />
| [[#GPUREG_01D6|GPUREG_01D6]]<br />
| <br />
|<br />
|-<br />
| 01D7<br />
| [[#GPUREG_01D7|GPUREG_01D7]]<br />
| <br />
|<br />
|-<br />
| 01D8<br />
| [[#GPUREG_01D8|GPUREG_01D8]]<br />
| <br />
|<br />
|-<br />
| 01D9<br />
| [[#GPUREG_01D9|GPUREG_01D9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_SRC_EN_ID<br />
|-<br />
| 01DA<br />
| [[#GPUREG_01DA|GPUREG_01DA]]<br />
| <br />
|<br />
|-<br />
| 01DB<br />
| [[#GPUREG_01DB|GPUREG_01DB]]<br />
| <br />
|<br />
|-<br />
| 01DC<br />
| [[#GPUREG_01DC|GPUREG_01DC]]<br />
| <br />
|<br />
|-<br />
| 01DD<br />
| [[#GPUREG_01DD|GPUREG_01DD]]<br />
| <br />
|<br />
|-<br />
| 01DE<br />
| [[#GPUREG_01DE|GPUREG_01DE]]<br />
| <br />
|<br />
|-<br />
| 01DF<br />
| [[#GPUREG_01DF|GPUREG_01DF]]<br />
| <br />
|<br />
|-<br />
| 01E0<br />
| [[#GPUREG_01E0|GPUREG_01E0]]<br />
| <br />
|<br />
|-<br />
| 01E1<br />
| [[#GPUREG_01E1|GPUREG_01E1]]<br />
| <br />
|<br />
|-<br />
| 01E2<br />
| [[#GPUREG_01E2|GPUREG_01E2]]<br />
| <br />
|<br />
|-<br />
| 01E3<br />
| [[#GPUREG_01E3|GPUREG_01E3]]<br />
| <br />
|<br />
|-<br />
| 01E4<br />
| [[#GPUREG_01E4|GPUREG_01E4]]<br />
| <br />
|<br />
|-<br />
| 01E5<br />
| [[#GPUREG_01E5|GPUREG_01E5]]<br />
| <br />
|<br />
|-<br />
| 01E6<br />
| [[#GPUREG_01E6|GPUREG_01E6]]<br />
| <br />
|<br />
|-<br />
| 01E7<br />
| [[#GPUREG_01E7|GPUREG_01E7]]<br />
| <br />
|<br />
|-<br />
| 01E8<br />
| [[#GPUREG_01E8|GPUREG_01E8]]<br />
| <br />
|<br />
|-<br />
| 01E9<br />
| [[#GPUREG_01E9|GPUREG_01E9]]<br />
| <br />
|<br />
|-<br />
| 01EA<br />
| [[#GPUREG_01EA|GPUREG_01EA]]<br />
| <br />
|<br />
|-<br />
| 01EB<br />
| [[#GPUREG_01EB|GPUREG_01EB]]<br />
| <br />
|<br />
|-<br />
| 01EC<br />
| [[#GPUREG_01EC|GPUREG_01EC]]<br />
| <br />
|<br />
|-<br />
| 01ED<br />
| [[#GPUREG_01ED|GPUREG_01ED]]<br />
| <br />
|<br />
|-<br />
| 01EE<br />
| [[#GPUREG_01EE|GPUREG_01EE]]<br />
| <br />
|<br />
|-<br />
| 01EF<br />
| [[#GPUREG_01EF|GPUREG_01EF]]<br />
| <br />
|<br />
|-<br />
| 01F0<br />
| [[#GPUREG_01F0|GPUREG_01F0]]<br />
| <br />
|<br />
|-<br />
| 01F1<br />
| [[#GPUREG_01F1|GPUREG_01F1]]<br />
| <br />
|<br />
|-<br />
| 01F2<br />
| [[#GPUREG_01F2|GPUREG_01F2]]<br />
| <br />
|<br />
|-<br />
| 01F3<br />
| [[#GPUREG_01F3|GPUREG_01F3]]<br />
| <br />
|<br />
|-<br />
| 01F4<br />
| [[#GPUREG_01F4|GPUREG_01F4]]<br />
| <br />
|<br />
|-<br />
| 01F5<br />
| [[#GPUREG_01F5|GPUREG_01F5]]<br />
| <br />
|<br />
|-<br />
| 01F6<br />
| [[#GPUREG_01F6|GPUREG_01F6]]<br />
| <br />
|<br />
|-<br />
| 01F7<br />
| [[#GPUREG_01F7|GPUREG_01F7]]<br />
| <br />
|<br />
|-<br />
| 01F8<br />
| [[#GPUREG_01F8|GPUREG_01F8]]<br />
| <br />
|<br />
|-<br />
| 01F9<br />
| [[#GPUREG_01F9|GPUREG_01F9]]<br />
| <br />
|<br />
|-<br />
| 01FA<br />
| [[#GPUREG_01FA|GPUREG_01FA]]<br />
| <br />
|<br />
|-<br />
| 01FB<br />
| [[#GPUREG_01FB|GPUREG_01FB]]<br />
| <br />
|<br />
|-<br />
| 01FC<br />
| [[#GPUREG_01FC|GPUREG_01FC]]<br />
| <br />
|<br />
|-<br />
| 01FD<br />
| [[#GPUREG_01FD|GPUREG_01FD]]<br />
| <br />
|<br />
|-<br />
| 01FE<br />
| [[#GPUREG_01FE|GPUREG_01FE]]<br />
| <br />
|<br />
|-<br />
| 01FF<br />
| [[#GPUREG_01FF|GPUREG_01FF]]<br />
| <br />
|<br />
|-<br />
! colspan=3 | Geometry pipeline registers<br />
|<br />
|-<br />
| 0200<br />
| [[#GPUREG_ATTRIBBUFFERS_LOC|GPUREG_ATTRIBBUFFERS_LOC]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS_BASE_ADDR<br />
|-<br />
| 0201<br />
| [[#GPUREG_ATTRIBBUFFERS_FORMAT_LOW|GPUREG_ATTRIBBUFFERS_FORMAT_LOW]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS0<br />
|-<br />
| 0202<br />
| [[#GPUREG_ATTRIBBUFFERS_FORMAT_HIGH|GPUREG_ATTRIBBUFFERS_FORMAT_HIGH]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS1<br />
|-<br />
| 0203<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG0|GPUREG_ATTRIBBUFFER0_CONFIG0]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ATTR_OFFSET<br />
|-<br />
| 0204<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG1|GPUREG_ATTRIBBUFFER0_CONFIG1]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ELEMENT0<br />
|-<br />
| 0205<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG2|GPUREG_ATTRIBBUFFER0_CONFIG2]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ELEMENT1<br />
|-<br />
| 0206<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG0|GPUREG_ATTRIBBUFFER1_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0207<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG1|GPUREG_ATTRIBBUFFER1_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0208<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG2|GPUREG_ATTRIBBUFFER1_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0209<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG0|GPUREG_ATTRIBBUFFER2_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 020A<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG1|GPUREG_ATTRIBBUFFER2_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 020B<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG2|GPUREG_ATTRIBBUFFER2_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 020C<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG0|GPUREG_ATTRIBBUFFER3_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 020D<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG1|GPUREG_ATTRIBBUFFER3_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 020E<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG2|GPUREG_ATTRIBBUFFER3_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 020F<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG0|GPUREG_ATTRIBBUFFER4_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0210<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG1|GPUREG_ATTRIBBUFFER4_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0211<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG2|GPUREG_ATTRIBBUFFER4_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0212<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG0|GPUREG_ATTRIBBUFFER5_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0213<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG1|GPUREG_ATTRIBBUFFER5_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0214<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG2|GPUREG_ATTRIBBUFFER5_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0215<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG0|GPUREG_ATTRIBBUFFER6_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0216<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG1|GPUREG_ATTRIBBUFFER6_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0217<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG2|GPUREG_ATTRIBBUFFER6_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0218<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG0|GPUREG_ATTRIBBUFFER7_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0219<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG1|GPUREG_ATTRIBBUFFER7_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 021A<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG2|GPUREG_ATTRIBBUFFER7_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 021B<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG0|GPUREG_ATTRIBBUFFER8_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 021C<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG1|GPUREG_ATTRIBBUFFER8_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 021D<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG2|GPUREG_ATTRIBBUFFER8_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 021E<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG0|GPUREG_ATTRIBBUFFER9_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 021F<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG1|GPUREG_ATTRIBBUFFER9_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0220<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG2|GPUREG_ATTRIBBUFFER9_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0221<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG0|GPUREG_ATTRIBBUFFERA_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0222<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG1|GPUREG_ATTRIBBUFFERA_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0223<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG2|GPUREG_ATTRIBBUFFERA_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0224<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG0|GPUREG_ATTRIBBUFFERB_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0225<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG1|GPUREG_ATTRIBBUFFERB_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0226<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG2|GPUREG_ATTRIBBUFFERB_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0227<br />
| [[#GPUREG_INDEXBUFFER_CONFIG|GPUREG_INDEXBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_INDEX_ARRAY_ADDR_OFFSET<br />
|-<br />
| 0228<br />
| [[#GPUREG_NUMVERTICES|GPUREG_NUMVERTICES]]<br />
| <br />
|PICA_REG_DRAW_VERTEX_NUM<br />
|-<br />
| 0229<br />
| [[#GPUREG_GEOSTAGE_CONFIG|GPUREG_GEOSTAGE_CONFIG]]<br />
| ?<br />
|PICA_REG_DRAW_MODE0<br />
|-<br />
| 022A<br />
| [[#GPUREG_022A|GPUREG_022A]]<br />
|?<br />
|PICA_REG_DRAW_VERTEX_OFFSET<br />
|-<br />
| 022B<br />
| [[#GPUREG_022B|GPUREG_022B]]<br />
| <br />
|<br />
|-<br />
| 022C<br />
| [[#GPUREG_022C|GPUREG_022C]]<br />
| <br />
|<br />
|-<br />
| 022D<br />
| [[#GPUREG_022D|GPUREG_022D]]<br />
| <br />
|<br />
|-<br />
| 022E<br />
| [[#GPUREG_DRAWARRAYS|GPUREG_DRAWARRAYS]]<br />
|<br />
|PICA_REG_START_DRAW_ARRAY<br />
|-<br />
| 022F<br />
| [[#GPUREG_DRAWELEMENTS|GPUREG_DRAWELEMENTS]]<br />
|<br />
|PICA_REG_START_DRAW_ELEMENT<br />
|-<br />
| 0230<br />
| [[#GPUREG_0230|GPUREG_0230]]<br />
| <br />
|<br />
|-<br />
| 0231<br />
| [[#GPUREG_0231|GPUREG_0231]]<br />
|?<br />
|PICA_REG_VTX_FUNC<br />
|-<br />
| 0232<br />
| [[#GPUREG_0232|GPUREG_0232]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR<br />
|-<br />
| 0233<br />
| [[#GPUREG_0233|GPUREG_0233]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA0<br />
|-<br />
| 0234<br />
| [[#GPUREG_0234|GPUREG_0234]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA1<br />
|-<br />
| 0235<br />
| [[#GPUREG_0235|GPUREG_0235]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA2<br />
|-<br />
| 0236<br />
| [[#GPUREG_0236|GPUREG_0236]]<br />
| <br />
|<br />
|-<br />
| 0237<br />
| [[#GPUREG_0237|GPUREG_0237]]<br />
| <br />
|<br />
|-<br />
| 0238<br />
| [[#GPUREG_0238|GPUREG_0238]]<br />
| <br />
|<br />
|-<br />
| 0239<br />
| [[#GPUREG_0239|GPUREG_0239]]<br />
| <br />
|<br />
|-<br />
| 023A<br />
| [[#GPUREG_023A|GPUREG_023A]]<br />
| <br />
|<br />
|-<br />
| 023B<br />
| [[#GPUREG_023B|GPUREG_023B]]<br />
| <br />
|<br />
|-<br />
| 023C<br />
| [[#GPUREG_023C|GPUREG_023C]]<br />
| <br />
|<br />
|-<br />
| 023D<br />
| [[#GPUREG_023D|GPUREG_023D]]<br />
| <br />
|<br />
|-<br />
| 023E<br />
| [[#GPUREG_023E|GPUREG_023E]]<br />
| <br />
|<br />
|-<br />
| 023F<br />
| [[#GPUREG_023F|GPUREG_023F]]<br />
| <br />
|<br />
|-<br />
| 0240<br />
| [[#GPUREG_0240|GPUREG_0240]]<br />
| <br />
|<br />
|-<br />
| 0241<br />
| [[#GPUREG_0241|GPUREG_0241]]<br />
| <br />
|<br />
|-<br />
| 0242<br />
| [[#GPUREG_0242|GPUREG_0242]]<br />
|?<br />
|PICA_REG_VS_ATTR_NUM1<br />
|-<br />
| 0243<br />
| [[#GPUREG_0243|GPUREG_0243]]<br />
| <br />
|<br />
|-<br />
| 0244<br />
| [[#GPUREG_0244|GPUREG_0244]]<br />
|?<br />
|PICA_REG_VS_COM_MODE<br />
|-<br />
| 0245<br />
| [[#GPUREG_0245|GPUREG_0245]]<br />
|?<br />
|PICA_REG_START_DRAW_FUNC0<br />
|-<br />
| 0246<br />
| [[#GPUREG_0246|GPUREG_0246]]<br />
| <br />
|<br />
|-<br />
| 0247<br />
| [[#GPUREG_0247|GPUREG_0247]]<br />
| <br />
|<br />
|-<br />
| 0248<br />
| [[#GPUREG_0248|GPUREG_0248]]<br />
| <br />
|<br />
|-<br />
| 0249<br />
| [[#GPUREG_0249|GPUREG_0249]]<br />
| <br />
|<br />
|-<br />
| 024A<br />
| [[#GPUREG_024A|GPUREG_024A]]<br />
|?<br />
|PICA_REG_VS_OUT_REG_NUM1<br />
|-<br />
| 024B<br />
| [[#GPUREG_024B|GPUREG_024B]]<br />
|<br />
|<br />
|-<br />
| 024C<br />
| [[#GPUREG_024C|GPUREG_024C]]<br />
| <br />
|<br />
|-<br />
| 024D<br />
| [[#GPUREG_024D|GPUREG_024D]]<br />
| <br />
|<br />
|-<br />
| 024E<br />
| [[#GPUREG_024E|GPUREG_024E]]<br />
| <br />
|<br />
|-<br />
| 024F<br />
| [[#GPUREG_024F|GPUREG_024F]]<br />
| <br />
|<br />
|-<br />
| 0250<br />
| [[#GPUREG_0250|GPUREG_0250]]<br />
| <br />
|<br />
|-<br />
| 0251<br />
| [[#GPUREG_0251|GPUREG_0251]]<br />
|?<br />
|PICA_REG_VS_OUT_REG_NUM2<br />
|-<br />
| 0252<br />
| [[#GPUREG_0252|GPUREG_0252]]<br />
|?<br />
|PICA_REG_GS_MISC_REG0<br />
|-<br />
| 0253<br />
| [[#GPUREG_0253|GPUREG_0253]]<br />
|?<br />
|PICA_REG_DRAW_MODE1<br />
|-<br />
| 0254<br />
| [[#GPUREG_0254|GPUREG_0254]]<br />
|?<br />
|PICA_REG_GS_MISC_REG1<br />
|-<br />
| 0255<br />
| [[#GPUREG_0255|GPUREG_0255]]<br />
| <br />
|<br />
|-<br />
| 0256<br />
| [[#GPUREG_0256|GPUREG_0256]]<br />
| <br />
|<br />
|-<br />
| 0257<br />
| [[#GPUREG_0257|GPUREG_0257]]<br />
| <br />
|<br />
|-<br />
| 0258<br />
| [[#GPUREG_0258|GPUREG_0258]]<br />
| <br />
|<br />
|-<br />
| 0259<br />
| [[#GPUREG_0259|GPUREG_0259]]<br />
| <br />
|<br />
|-<br />
| 025A<br />
| [[#GPUREG_025A|GPUREG_025A]]<br />
| <br />
|<br />
|-<br />
| 025B<br />
| [[#GPUREG_025B|GPUREG_025B]]<br />
| <br />
|<br />
|-<br />
| 025C<br />
| [[#GPUREG_025C|GPUREG_025C]]<br />
| <br />
|<br />
|-<br />
| 025D<br />
| [[#GPUREG_025D|GPUREG_025D]]<br />
| <br />
|<br />
|-<br />
| 025E<br />
| [[#GPUREG_PRIMITIVE_CONFIG|GPUREG_PRIMITIVE_CONFIG]]<br />
| ?<br />
|PICA_REG_GS_OUT_REG_NUM3 / PICA_REG_VS_OUT_REG_NUM3<br />
|-<br />
| 025F<br />
| [[#GPUREG_025F|GPUREG_025F]]<br />
|?<br />
|PICA_REG_START_DRAW_FUNC1<br />
|-<br />
| 0260<br />
| [[#GPUREG_0260|GPUREG_0260]]<br />
| <br />
|<br />
|-<br />
| 0261<br />
| [[#GPUREG_0261|GPUREG_0261]]<br />
| <br />
|<br />
|-<br />
| 0262<br />
| [[#GPUREG_0262|GPUREG_0262]]<br />
| <br />
|<br />
|-<br />
| 0263<br />
| [[#GPUREG_0263|GPUREG_0263]]<br />
| <br />
|<br />
|-<br />
| 0264<br />
| [[#GPUREG_0264|GPUREG_0264]]<br />
| <br />
|<br />
|-<br />
| 0265<br />
| [[#GPUREG_0265|GPUREG_0265]]<br />
| <br />
|<br />
|-<br />
| 0266<br />
| [[#GPUREG_0266|GPUREG_0266]]<br />
| <br />
|<br />
|-<br />
| 0267<br />
| [[#GPUREG_0267|GPUREG_0267]]<br />
| <br />
|<br />
|-<br />
| 0268<br />
| [[#GPUREG_0268|GPUREG_0268]]<br />
| <br />
|<br />
|-<br />
| 0269<br />
| [[#GPUREG_0269|GPUREG_0269]]<br />
| <br />
|<br />
|-<br />
| 026A<br />
| [[#GPUREG_026A|GPUREG_026A]]<br />
| <br />
|<br />
|-<br />
| 026B<br />
| [[#GPUREG_026B|GPUREG_026B]]<br />
| <br />
|<br />
|-<br />
| 026C<br />
| [[#GPUREG_026C|GPUREG_026C]]<br />
| <br />
|<br />
|-<br />
| 026D<br />
| [[#GPUREG_026D|GPUREG_026D]]<br />
| <br />
|<br />
|-<br />
| 026E<br />
| [[#GPUREG_026E|GPUREG_026E]]<br />
| <br />
|<br />
|-<br />
| 026F<br />
| [[#GPUREG_026F|GPUREG_026F]]<br />
| <br />
|<br />
|-<br />
| 0270<br />
| [[#GPUREG_0270|GPUREG_0270]]<br />
| <br />
|<br />
|-<br />
| 0271<br />
| [[#GPUREG_0271|GPUREG_0271]]<br />
| <br />
|<br />
|-<br />
| 0272<br />
| [[#GPUREG_0272|GPUREG_0272]]<br />
| <br />
|<br />
|-<br />
| 0273<br />
| [[#GPUREG_0273|GPUREG_0273]]<br />
| <br />
|<br />
|-<br />
| 0274<br />
| [[#GPUREG_0274|GPUREG_0274]]<br />
| <br />
|<br />
|-<br />
| 0275<br />
| [[#GPUREG_0275|GPUREG_0275]]<br />
| <br />
|<br />
|-<br />
| 0276<br />
| [[#GPUREG_0276|GPUREG_0276]]<br />
| <br />
|<br />
|-<br />
| 0277<br />
| [[#GPUREG_0277|GPUREG_0277]]<br />
| <br />
|<br />
|-<br />
| 0278<br />
| [[#GPUREG_0278|GPUREG_0278]]<br />
| <br />
|<br />
|-<br />
| 0279<br />
| [[#GPUREG_0279|GPUREG_0279]]<br />
| <br />
|<br />
|-<br />
| 027A<br />
| [[#GPUREG_027A|GPUREG_027A]]<br />
| <br />
|<br />
|-<br />
| 027B<br />
| [[#GPUREG_027B|GPUREG_027B]]<br />
| <br />
|<br />
|-<br />
| 027C<br />
| [[#GPUREG_027C|GPUREG_027C]]<br />
| <br />
|<br />
|-<br />
| 027D<br />
| [[#GPUREG_027D|GPUREG_027D]]<br />
| <br />
|<br />
|-<br />
| 027E<br />
| [[#GPUREG_027E|GPUREG_027E]]<br />
| <br />
|<br />
|-<br />
| 027F<br />
| [[#GPUREG_027F|GPUREG_027F]]<br />
| <br />
|<br />
|-<br />
! colspan=4 | Geometry shader registers<br />
|-<br />
| 0280<br />
| [[#GPUREG_GSH_BOOLUNIFORM|GPUREG_GSH_BOOLUNIFORM]]<br />
| <br />
|PICA_REG_GS_BOOL<br />
|-<br />
| 0281<br />
| [[#GPUREG_GSH_INTUNIFORM_I0|GPUREG_GSH_INTUNIFORM_I0]]<br />
| <br />
|PICA_REG_GS_INT0<br />
|-<br />
| 0282<br />
| [[#GPUREG_GSH_INTUNIFORM_I1|GPUREG_GSH_INTUNIFORM_I1]]<br />
| <br />
|PICA_REG_GS_INT1<br />
|-<br />
| 0283<br />
| [[#GPUREG_GSH_INTUNIFORM_I2|GPUREG_GSH_INTUNIFORM_I2]]<br />
| <br />
|PICA_REG_GS_INT2<br />
|-<br />
| 0284<br />
| [[#GPUREG_GSH_INTUNIFORM_I3|GPUREG_GSH_INTUNIFORM_I3]]<br />
| <br />
|PICA_REG_GS_INT3<br />
|-<br />
| 0285<br />
| [[#GPUREG_0285|GPUREG_0285]]<br />
| <br />
|<br />
|-<br />
| 0286<br />
| [[#GPUREG_0286|GPUREG_0286]]<br />
| <br />
|<br />
|-<br />
| 0287<br />
| [[#GPUREG_0287|GPUREG_0287]]<br />
| <br />
|<br />
|-<br />
| 0288<br />
| [[#GPUREG_0288|GPUREG_0288]]<br />
| <br />
|<br />
|-<br />
| 0289<br />
| [[#GPUREG_GSH_INPUTBUFFER_CONFIG|GPUREG_GSH_INPUTBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_GS_ATTR_NUM<br />
|-<br />
| 028A<br />
| [[#GPUREG_GSH_ENTRYPOINT|GPUREG_GSH_ENTRYPOINT]]<br />
| <br />
|PICA_REG_GS_START_ADDR<br />
|-<br />
| 028B<br />
| [[#GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW|GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW]]<br />
| <br />
|PICA_REG_GS_ATTR_IN_REG_MAP0<br />
|-<br />
| 028C<br />
| [[#GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH|GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH]]<br />
| <br />
|PICA_REG_GS_ATTR_IN_REG_MAP1<br />
|-<br />
| 028D<br />
| [[#GPUREG_GSH_OUTMAP_MASK|GPUREG_GSH_OUTMAP_MASK]]<br />
| <br />
|PICA_REG_GS_OUT_REG_MASK<br />
|-<br />
| 028E<br />
| [[#GPUREG_028E|GPUREG_028E]]<br />
| <br />
|<br />
|-<br />
| 028F<br />
| [[#GPUREG_GSH_CODETRANSFER_END|GPUREG_GSH_CODETRANSFER_END]]<br />
| <br />
|PICA_REG_GS_PROG_RENEWAL_END<br />
|-<br />
| 0290<br />
| [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]]<br />
| <br />
|PICA_REG_GS_FLOAT_ADDR<br />
|-<br />
| 0291<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA1<br />
|-<br />
| 0292<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA2<br />
|-<br />
| 0293<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA3<br />
|-<br />
| 0294<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA4<br />
|-<br />
| 0295<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA5<br />
|-<br />
| 0296<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA6<br />
|-<br />
| 0297<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA7<br />
|-<br />
| 0298<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA8<br />
|-<br />
| 0299<br />
| [[#GPUREG_0299|GPUREG_0299]]<br />
| <br />
|<br />
|-<br />
| 029A<br />
| [[#GPUREG_029A|GPUREG_029A]]<br />
| <br />
|<br />
|-<br />
| 029B<br />
| [[#GPUREG_GSH_CODETRANSFER_CONFIG|GPUREG_GSH_CODETRANSFER_CONFIG]]<br />
| ?<br />
|PICA_REG_GS_PROG_ADDR<br />
|-<br />
| 029C<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA0<br />
|-<br />
| 029D<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA1<br />
|-<br />
| 029E<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA2<br />
|-<br />
| 029F<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA3<br />
|-<br />
| 02A0<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA4<br />
|-<br />
| 02A1<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA5<br />
|-<br />
| 02A2<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA6<br />
|-<br />
| 02A3<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA7<br />
|-<br />
| 02A4<br />
| [[#GPUREG_02A4|GPUREG_02A4]]<br />
| <br />
|<br />
|-<br />
| 02A5<br />
| [[#GPUREG_GSH_OPDESCS_CONFIG|GPUREG_GSH_OPDESCS_CONFIG]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_ADDR<br />
|-<br />
| 02A6<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA0<br />
|-<br />
| 02A7<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA1<br />
|-<br />
| 02A8<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA2<br />
|-<br />
| 02A9<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA3<br />
|-<br />
| 02AA<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA4<br />
|-<br />
| 02AB<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA5<br />
|-<br />
| 02AC<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA6<br />
|-<br />
| 02AD<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA7<br />
|-<br />
| 02AE<br />
| [[#GPUREG_02AE|GPUREG_02AE]]<br />
| <br />
|<br />
|-<br />
| 02AF<br />
| [[#GPUREG_02AF|GPUREG_02AF]]<br />
| <br />
|<br />
|-<br />
! colspan=4 | Vertex shader registers<br />
|-<br />
| 02B0<br />
| [[#GPUREG_VSH_BOOLUNIFORM|GPUREG_VSH_BOOLUNIFORM]]<br />
| <br />
|PICA_REG_VS_BOOL<br />
|-<br />
| 02B1<br />
| [[#GPUREG_VSH_INTUNIFORM_I0|GPUREG_VSH_INTUNIFORM_I0]]<br />
| <br />
|PICA_REG_VS_INT0<br />
|-<br />
| 02B2<br />
| [[#GPUREG_VSH_INTUNIFORM_I1|GPUREG_VSH_INTUNIFORM_I1]]<br />
| <br />
|PICA_REG_VS_INT1<br />
|-<br />
| 02B3<br />
| [[#GPUREG_VSH_INTUNIFORM_I2|GPUREG_VSH_INTUNIFORM_I2]]<br />
| <br />
|PICA_REG_VS_INT2<br />
|-<br />
| 02B4<br />
| [[#GPUREG_VSH_INTUNIFORM_I3|GPUREG_VSH_INTUNIFORM_I3]]<br />
| <br />
|PICA_REG_VS_INT3<br />
|-<br />
| 02B5<br />
| [[#GPUREG_02B5|GPUREG_02B5]]<br />
| <br />
|<br />
|-<br />
| 02B6<br />
| [[#GPUREG_02B6|GPUREG_02B6]]<br />
| <br />
|<br />
|-<br />
| 02B7<br />
| [[#GPUREG_02B7|GPUREG_02B7]]<br />
| <br />
|<br />
|-<br />
| 02B8<br />
| [[#GPUREG_02B8|GPUREG_02B8]]<br />
| <br />
|<br />
|-<br />
| 02B9<br />
| [[#GPUREG_VSH_INPUTBUFFER_CONFIG|GPUREG_VSH_INPUTBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_VS_ATTR_NUM0<br />
|-<br />
| 02BA<br />
| [[#GPUREG_VSH_ENTRYPOINT|GPUREG_VSH_ENTRYPOINT]]<br />
| <br />
|PICA_REG_VS_START_ADDR<br />
|-<br />
| 02BB<br />
| [[#GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW|GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW]]<br />
| <br />
|PICA_REG_VS_ATTR_IN_REG_MAP0<br />
|-<br />
| 02BC<br />
| [[#GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH|GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH]]<br />
| <br />
|PICA_REG_VS_ATTR_IN_REG_MAP1<br />
|-<br />
| 02BD<br />
| [[#GPUREG_VSH_OUTMAP_MASK|GPUREG_VSH_OUTMAP_MASK]]<br />
| <br />
|PICA_REG_VS_OUT_REG_MASK<br />
|-<br />
| 02BE<br />
| [[#GPUREG_02BE|GPUREG_02BE]]<br />
| <br />
|<br />
|-<br />
| 02BF<br />
| [[#GPUREG_VSH_CODETRANSFER_END|GPUREG_VSH_CODETRANSFER_END]]<br />
| <br />
|PICA_REG_VS_PROG_RENEWAL_END<br />
|-<br />
| 02C0<br />
| [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]]<br />
| <br />
|PICA_REG_VS_FLOAT_ADDR<br />
|-<br />
| 02C1<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA1<br />
|-<br />
| 02C2<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA2<br />
|-<br />
| 02C3<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA3<br />
|-<br />
| 02C4<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA4<br />
|-<br />
| 02C5<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA5<br />
|-<br />
| 02C6<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA6<br />
|-<br />
| 02C7<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA7<br />
|-<br />
| 02C8<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA8<br />
|-<br />
| 02C9<br />
| [[#GPUREG_02C9|GPUREG_02C9]]<br />
| <br />
|<br />
|-<br />
| 02CA<br />
| [[#GPUREG_02CA|GPUREG_02CA]]<br />
| <br />
|<br />
|-<br />
| 02CB<br />
| [[#GPUREG_VSH_CODETRANSFER_CONFIG|GPUREG_VSH_CODETRANSFER_CONFIG]]<br />
| ?<br />
|PICA_REG_VS_PROG_ADDR<br />
|-<br />
| 02CC<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA0<br />
|-<br />
| 02CD<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA1<br />
|-<br />
| 02CE<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA2<br />
|-<br />
| 02CF<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA3<br />
|-<br />
| 02D0<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA4<br />
|-<br />
| 02D1<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA5<br />
|-<br />
| 02D2<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA6<br />
|-<br />
| 02D3<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA7<br />
|-<br />
| 02D4<br />
| [[#GPUREG_02D4|GPUREG_02D4]]<br />
| <br />
|<br />
|-<br />
| 02D5<br />
| [[#GPUREG_VSH_OPDESCS_CONFIG|GPUREG_VSH_OPDESCS_CONFIG]]<br />
| ?<br />
|PICA_REG_VS_PROG_SWIZZLE_ADDR<br />
|-<br />
| 02D6<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA0<br />
|-<br />
| 02D7<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA1<br />
|-<br />
| 02D8<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA2<br />
|-<br />
| 02D9<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA3<br />
|-<br />
| 02DA<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA4<br />
|-<br />
| 02DB<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA5<br />
|-<br />
| 02DC<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA6<br />
|-<br />
| 02DD<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA7<br />
|-<br />
! colspan=4 | Unknown registers<br />
|-<br />
| 02DE<br />
| [[#GPUREG_02DE|GPUREG_02DE]]<br />
| <br />
|<br />
|-<br />
| 02DF<br />
| [[#GPUREG_02DF|GPUREG_02DF]]<br />
| <br />
|<br />
|-<br />
| 02E0<br />
| [[#GPUREG_02E0|GPUREG_02E0]]<br />
| <br />
|<br />
|-<br />
| 02E1<br />
| [[#GPUREG_02E1|GPUREG_02E1]]<br />
| <br />
|<br />
|-<br />
| 02E2<br />
| [[#GPUREG_02E2|GPUREG_02E2]]<br />
| <br />
|<br />
|-<br />
| 02E3<br />
| [[#GPUREG_02E3|GPUREG_02E3]]<br />
| <br />
|<br />
|-<br />
| 02E4<br />
| [[#GPUREG_02E4|GPUREG_02E4]]<br />
| <br />
|<br />
|-<br />
| 02E5<br />
| [[#GPUREG_02E5|GPUREG_02E5]]<br />
| <br />
|<br />
|-<br />
| 02E6<br />
| [[#GPUREG_02E6|GPUREG_02E6]]<br />
| <br />
|<br />
|-<br />
| 02E7<br />
| [[#GPUREG_02E7|GPUREG_02E7]]<br />
| <br />
|<br />
|-<br />
| 02E8<br />
| [[#GPUREG_02E8|GPUREG_02E8]]<br />
| <br />
|<br />
|-<br />
| 02E9<br />
| [[#GPUREG_02E9|GPUREG_02E9]]<br />
| <br />
|<br />
|-<br />
| 02EA<br />
| [[#GPUREG_02EA|GPUREG_02EA]]<br />
| <br />
|<br />
|-<br />
| 02EB<br />
| [[#GPUREG_02EB|GPUREG_02EB]]<br />
| <br />
|<br />
|-<br />
| 02EC<br />
| [[#GPUREG_02EC|GPUREG_02EC]]<br />
| <br />
|<br />
|-<br />
| 02ED<br />
| [[#GPUREG_02ED|GPUREG_02ED]]<br />
| <br />
|<br />
|-<br />
| 02EE<br />
| [[#GPUREG_02EE|GPUREG_02EE]]<br />
| <br />
|<br />
|-<br />
| 02EF<br />
| [[#GPUREG_02EF|GPUREG_02EF]]<br />
| <br />
|<br />
|-<br />
| 02F0<br />
| [[#GPUREG_02F0|GPUREG_02F0]]<br />
| <br />
|<br />
|-<br />
| 02F1<br />
| [[#GPUREG_02F1|GPUREG_02F1]]<br />
| <br />
|<br />
|-<br />
| 02F2<br />
| [[#GPUREG_02F2|GPUREG_02F2]]<br />
| <br />
|<br />
|-<br />
| 02F3<br />
| [[#GPUREG_02F3|GPUREG_02F3]]<br />
| <br />
|<br />
|-<br />
| 02F4<br />
| [[#GPUREG_02F4|GPUREG_02F4]]<br />
| <br />
|<br />
|-<br />
| 02F5<br />
| [[#GPUREG_02F5|GPUREG_02F5]]<br />
| <br />
|<br />
|-<br />
| 02F6<br />
| [[#GPUREG_02F6|GPUREG_02F6]]<br />
| <br />
|<br />
|-<br />
| 02F7<br />
| [[#GPUREG_02F7|GPUREG_02F7]]<br />
| <br />
|<br />
|-<br />
| 02F8<br />
| [[#GPUREG_02F8|GPUREG_02F8]]<br />
| <br />
|<br />
|-<br />
| 02F9<br />
| [[#GPUREG_02F9|GPUREG_02F9]]<br />
| <br />
|<br />
|-<br />
| 02FA<br />
| [[#GPUREG_02FA|GPUREG_02FA]]<br />
| <br />
|<br />
|-<br />
| 02FB<br />
| [[#GPUREG_02FB|GPUREG_02FB]]<br />
| <br />
|<br />
|-<br />
| 02FC<br />
| [[#GPUREG_02FC|GPUREG_02FC]]<br />
| <br />
|<br />
|-<br />
| 02FD<br />
| [[#GPUREG_02FD|GPUREG_02FD]]<br />
| <br />
|<br />
|-<br />
| 02FE<br />
| [[#GPUREG_02FE|GPUREG_02FE]]<br />
| <br />
|<br />
|-<br />
| 02FF<br />
| [[#GPUREG_02FF|GPUREG_02FF]]<br />
| <br />
|<br />
|}<br />
<br />
=== GPUREG_FINALIZE ===<br />
<br />
Writing to this register seems to signal the GPU to stop processing GPU commands from the current buffer; any command following a write to this register will be ignored. The value written to this register does not appear to matter, although 0x12345678 is the value typically written by commercial software.<br />
Failure to write to this register in any command buffer will result in the GPU hanging.<br />
<br />
=== GPUREG_DEPTHBUFFER_FORMAT ===<br />
<br />
The format the current depth buffer should be written into. Following values are possible:<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| 16-bit depth<br />
|-<br />
| 1<br />
| ?? seems to freeze the GPU<br />
|-<br />
| 2<br />
| 24-bit depth<br />
|-<br />
| 3<br />
| 24-bit depth + 8-bit stencil (stencil is within bit 24-31)<br />
|}<br />
<br />
=== GPUREG_COLORBUFFER_FORMAT ===<br />
<br />
Describes the format of the current color buffer used for 3D rendering.<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Pixel size (0=16-bit, 1=24-bit, 2=32-bit, 3=64-bit?)<br />
|-<br />
| 16-23<br />
| Framebuffer Format (0=GL_RGBA8, 1=GL_RGB8, 2=GL_RGB5_A1, 3=GL_R5_G6_B5, 4=GL_RGBA4).<br />
Note that these values are slightly different from those in [[GPU#Framebuffer_color_formats]].<br />
<br />
Color components are laid out in reverse byte order, with the most significant bits used first.<br />
|}<br />
<br />
=== GPUREG_GEOSTAGE_CONFIG ===<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Geometry stage mode. (0=Vertex shader only, 2=Vertex shader + geometry shader)<br />
|-<br />
| 0-7<br />
| Unknown. Often set to 1.<br />
|-<br />
| 0-7<br />
| Unknown.<br />
|-<br />
| 0-7<br />
| Unknown. Often set to 0.<br />
|}<br />
<br />
This register configures the geometry stage of the GPU pipeline.<br />
<br />
=== Geometry shader registers ===<br />
<br />
==== GPUREG_GSH_BOOLUNIFORM ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Value of geometry shader unit's b0 boolean register. (0=true, 1=false)<br />
|-<br />
| 1<br />
| Value of geometry shader unit's b1 boolean register. (0=true, 1=false)<br />
|-<br />
| 2<br />
| Value of geometry shader unit's b2 boolean register. (0=true, 1=false)<br />
|-<br />
| 3<br />
| Value of geometry shader unit's b3 boolean register. (0=true, 1=false)<br />
|-<br />
| 4<br />
| Value of geometry shader unit's b4 boolean register. (0=true, 1=false)<br />
|-<br />
| 5<br />
| Value of geometry shader unit's b5 boolean register. (0=true, 1=false)<br />
|-<br />
| 6<br />
| Value of geometry shader unit's b6 boolean register. (0=true, 1=false)<br />
|-<br />
| 7<br />
| Value of geometry shader unit's b7 boolean register. (0=true, 1=false)<br />
|-<br />
| 8<br />
| Value of geometry shader unit's b8 boolean register. (0=true, 1=false)<br />
|-<br />
| 9<br />
| Value of geometry shader unit's b9 boolean register. (0=true, 1=false)<br />
|-<br />
| 10<br />
| Value of geometry shader unit's b10 boolean register. (0=true, 1=false)<br />
|-<br />
| 11<br />
| Value of geometry shader unit's b11 boolean register. (0=true, 1=false)<br />
|-<br />
| 12<br />
| Value of geometry shader unit's b12 boolean register. (0=true, 1=false)<br />
|-<br />
| 13<br />
| Value of geometry shader unit's b13 boolean register. (0=true, 1=false)<br />
|-<br />
| 14<br />
| Value of geometry shader unit's b14 boolean register. (0=true, 1=false)<br />
|-<br />
| 15<br />
| Value of geometry shader unit's b15 boolean register. (0=true, 1=false)<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This register is used to set the geometry shader unit's boolean registers.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I0 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i0.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i0.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i0.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i0.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i0 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I1 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i1.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i1.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i1.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i1.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i1 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I2 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i2.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i2.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i2.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i2.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i2 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I3 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i3.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i3.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i3.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i3.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i3 integer register.<br />
<br />
==== GPUREG_GSH_INPUTBUFFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Input buffer stride minus 1, in float vec4 registers. (value 0 means a stride of 1 float vec4 register)<br />
|-<br />
| 8-23<br />
| Unknown. These bits typically aren't updated by games.<br />
|-<br />
| 24-31<br />
| Unknown. This is typically set to 8 for geometry shaders.<br />
|}<br />
<br />
This register is used to configure the geometry shader's input buffer. In the context of a geometry shader, the stride parameter can be interpreted as the input primitive size in registers, though it is not a limit on the number of input registers which can be accessed from the geometry shader.<br />
<br />
<br />
==== GPUREG_GSH_ENTRYPOINT ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-15<br />
| Geometry shader unit entrypoint, in words.<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This sets the entrypoint for the program running on the single shader unit which can be dedicated to running geometry shaders, regardless of the current geometry stage mode. This is means that while this register is normally used to set the geometry shader entrypoint, it can also be used to set this single shader unit to run from a different entrypoint than the other three even when running a vertex shader.<br />
<br />
==== GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of geometry shader input register which the 1st attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of geometry shader input register which the 2nd attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of geometry shader input register which the 3rd attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of geometry shader input register which the 4th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of geometry shader input register which the 5th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of geometry shader input register which the 6th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of geometry shader input register which the 7th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of geometry shader input register which the 8th attribute will be stored in.<br />
|}<br />
<br />
This register sets the geometry shader input register index which will correspond to each attribute contained by the input buffer (which in the case of geometry shaders is the vertex shader output buffer) for the first 8 attributes.<br />
For example, having bits 0-3 set to 5 means that, in the geometry shader program, v5 will contain the input buffer's 1st attribute.<br />
<br />
==== GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of geometry shader input register which the 9th attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of geometry shader input register which the 10th attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of geometry shader input register which the 11th attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of geometry shader input register which the 12th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of geometry shader input register which the 13th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of geometry shader input register which the 14th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of geometry shader input register which the 15th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of geometry shader input register which the 16th attribute will be stored in.<br />
|}<br />
<br />
This register sets the geometry shader input register index which will correspond to each attribute contained by the input buffer (which in the case of geometry shaders is the vertex shader output buffer) for attributes 8 through 15.<br />
For example, having bits 0-3 set to 5 means that, in the geometry shader program, v5 will contain the input buffer's 9th attribute.<br />
<br />
==== GPUREG_GSH_OUTMAP_MASK ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Enable bit for geometry shader's o0 output register. (1 = o0 enabled, 0 = o0 disabled)<br />
|-<br />
| 1<br />
| Enable bit for geometry shader's o1 output register. (1 = o1 enabled, 0 = o1 disabled)<br />
|-<br />
| 2<br />
| Enable bit for geometry shader's o2 output register. (1 = o2 enabled, 0 = o2 disabled)<br />
|-<br />
| 3<br />
| Enable bit for geometry shader's o3 output register. (1 = o3 enabled, 0 = o3 disabled)<br />
|-<br />
| 4<br />
| Enable bit for geometry shader's o4 output register. (1 = o4 enabled, 0 = o4 disabled)<br />
|-<br />
| 5<br />
| Enable bit for geometry shader's o5 output register. (1 = o5 enabled, 0 = o5 disabled)<br />
|-<br />
| 6<br />
| Enable bit for geometry shader's o6 output register. (1 = o6 enabled, 0 = o6 disabled)<br />
|}<br />
<br />
This register toggles the geometry shader unit's output registers.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_END ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Code data transfer end signal bit.<br />
|}<br />
<br />
This register's value should be set to 1 in order to finalize the transfer of geometry shader code. It is unknown whether this register is used for other functions.<br />
<br />
==== GPUREG_GSH_FLOATUNIFORM_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target float vec4 geometry shader uniform ID for transfer. (range 0-95, where 0 = c0 and 95 = c95)<br />
|-<br />
| 31<br />
| Float vec4 geometry shader uniform data transfer mode. (0 = float24, 1 = float32)<br />
|}<br />
<br />
This register sets the target float vec4 geometry shader uniform ID and transfer mode for the data transfer system. As such it is typically used right before [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]], though writing to one register does not make writing to the other mandatory.<br />
<br />
==== GPUREG_GSH_FLOATUNIFORM_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Float vec4 geometry shader uniform data. (format depends on transfer mode, see below for details)<br />
|}<br />
<br />
This register is used to set the value of float vec4 geometry shader uniform registers. The data format which should be written to it depends on the transfer mode set with [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]]. This register functions as a FIFO queue : after each time a uniform register is successfully set, the target uniform ID value is incremented, meaning that groups of uniforms with contiguous register IDs can be set with only one initial write to [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]].<br />
<br />
* In the case of float24 transfer mode, data should be sent by writing three words which are the concatenation of the float24 value of the uniform register's 4 components, in the reverse order. Assuming each letter corresponds to 4 bits, the format becomes :<br />
** first word : ZZWWWWWW<br />
** second word : YYYYZZZZ<br />
** third word : XXXXXXYY<br />
* In the case of float32 transfer mode, data should be sent by writing four words which are each the float32 value of the uniform register's 4 components, in the reverse order.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-11<br />
| Target geometry shader code offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming geometry shader code data transferred through [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]] should be written.<br />
<br />
NOTE : as we do not yet know what a shader program's maximum size is yet, we also do not know how many bits the code offset parameter holds. The biggest shader binary observed so far was 2422 instructions long. The [[Shader_Instruction_Set#Instruction_formats|shader control flow instructions]] only have room to address 12 bits though, so it's likely that the maximum is 4095.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Geometry shader instruction data.<br />
|}<br />
<br />
This register is used to transfer geometry shader code data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU geometry shader code memory bank at the offset initially set by [[#GPUREG_GSH_CODETRANSFER_CONFIG|GPUREG_GSH_CODETRANSFER_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
==== GPUREG_GSH_OPDESCS_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target geometry shader operand descriptor offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming geometry shader operand descriptor data transferred through [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]] should be written.<br />
<br />
==== GPUREG_GSH_OPDESCS_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Geometry shader operand descriptor data.<br />
|}<br />
<br />
This register is used to transfer geometry shader operand descriptor data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU geometry shader operand descriptor memory bank at the offset initially set by [[#GPUREG_GSH_OPDESCS_CONFIG|GPUREG_GSH_OPDESCS_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
=== Vertex shader registers ===<br />
<br />
==== GPUREG_VSH_BOOLUNIFORM ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Value of vertex shader unit's b0 boolean register. (0=true, 1=false)<br />
|-<br />
| 1<br />
| Value of vertex shader unit's b1 boolean register. (0=true, 1=false)<br />
|-<br />
| 2<br />
| Value of vertex shader unit's b2 boolean register. (0=true, 1=false)<br />
|-<br />
| 3<br />
| Value of vertex shader unit's b3 boolean register. (0=true, 1=false)<br />
|-<br />
| 4<br />
| Value of vertex shader unit's b4 boolean register. (0=true, 1=false)<br />
|-<br />
| 5<br />
| Value of vertex shader unit's b5 boolean register. (0=true, 1=false)<br />
|-<br />
| 6<br />
| Value of vertex shader unit's b6 boolean register. (0=true, 1=false)<br />
|-<br />
| 7<br />
| Value of vertex shader unit's b7 boolean register. (0=true, 1=false)<br />
|-<br />
| 8<br />
| Value of vertex shader unit's b8 boolean register. (0=true, 1=false)<br />
|-<br />
| 9<br />
| Value of vertex shader unit's b9 boolean register. (0=true, 1=false)<br />
|-<br />
| 10<br />
| Value of vertex shader unit's b10 boolean register. (0=true, 1=false)<br />
|-<br />
| 11<br />
| Value of vertex shader unit's b11 boolean register. (0=true, 1=false)<br />
|-<br />
| 12<br />
| Value of vertex shader unit's b12 boolean register. (0=true, 1=false)<br />
|-<br />
| 13<br />
| Value of vertex shader unit's b13 boolean register. (0=true, 1=false)<br />
|-<br />
| 14<br />
| Value of vertex shader unit's b14 boolean register. (0=true, 1=false)<br />
|-<br />
| 15<br />
| Value of vertex shader unit's b15 boolean register. (0=true, 1=false)<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This register is used to set the vertex shader unit's boolean registers.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I0 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i0.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i0.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i0.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i0.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i0 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I1 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i1.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i1.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i1.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i1.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i1 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I2 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i2.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i2.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i2.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i2.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i2 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I3 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i3.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i3.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i3.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i3.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i3 integer register.<br />
<br />
==== GPUREG_VSH_INPUTBUFFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Input buffer stride minus 1, in float vec4 registers. (value 0 means a stride of 1 float vec4 register)<br />
|-<br />
| 8-23<br />
| Unknown. These bits typically aren't updated by games.<br />
|-<br />
| 24-31<br />
| Unknown. This is typically set to 0xA for vertex shaders.<br />
|}<br />
<br />
This register is used to configure the vertex shader's input buffer. In the context of a geometry shader, the stride parameter can be interpreted as the number of attributes per vertex.<br />
<br />
==== GPUREG_VSH_ENTRYPOINT ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-15<br />
| Vertex shader entrypoint, in words.<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This sets the entrypoint for the program running on shader units set to vertex shader mode. Depending on the current geometry stage mode this can include either all 4 shader units or just 3 of them.<br />
<br />
==== GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of vertex shader input register which the 1st attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of vertex shader input register which the 2nd attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of vertex shader input register which the 3rd attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of vertex shader input register which the 4th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of vertex shader input register which the 5th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of vertex shader input register which the 6th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of vertex shader input register which the 7th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of vertex shader input register which the 8th attribute will be stored in.<br />
|}<br />
<br />
This register sets the vertex shader input register index which will correspond to each attribute contained by the input buffer for the first 8 attributes.<br />
For example, having bits 0-3 set to 5 means that, in the vertex shader program, v5 will contain the input buffer's 1st attribute.<br />
<br />
==== GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of vertex shader input register which the 9th attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of vertex shader input register which the 10th attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of vertex shader input register which the 11th attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of vertex shader input register which the 12th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of vertex shader input register which the 13th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of vertex shader input register which the 14th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of vertex shader input register which the 15th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of vertex shader input register which the 16th attribute will be stored in.<br />
|}<br />
<br />
This register sets the vertex shader input register index which will correspond to each attribute contained by the input buffer for attributes 8 through 15.<br />
For example, having bits 0-3 set to 5 means that, in the vertex shader program, v5 will contain the input buffer's 9th attribute.<br />
<br />
==== GPUREG_VSH_OUTMAP_MASK ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Enable bit for vertex shader's o0 output register. (1 = o0 enabled, 0 = o0 disabled)<br />
|-<br />
| 1<br />
| Enable bit for vertex shader's o1 output register. (1 = o1 enabled, 0 = o1 disabled)<br />
|-<br />
| 2<br />
| Enable bit for vertex shader's o2 output register. (1 = o2 enabled, 0 = o2 disabled)<br />
|-<br />
| 3<br />
| Enable bit for vertex shader's o3 output register. (1 = o3 enabled, 0 = o3 disabled)<br />
|-<br />
| 4<br />
| Enable bit for vertex shader's o4 output register. (1 = o4 enabled, 0 = o4 disabled)<br />
|-<br />
| 5<br />
| Enable bit for vertex shader's o5 output register. (1 = o5 enabled, 0 = o5 disabled)<br />
|-<br />
| 6<br />
| Enable bit for vertex shader's o6 output register. (1 = o6 enabled, 0 = o6 disabled)<br />
|-<br />
| 7<br />
| Enable bit for vertex shader's o7 output register. (1 = o7 enabled, 0 = o7 disabled)<br />
|-<br />
| 8<br />
| Enable bit for vertex shader's o8 output register. (1 = o8 enabled, 0 = o8 disabled)<br />
|-<br />
| 9<br />
| Enable bit for vertex shader's o9 output register. (1 = o9 enabled, 0 = o9 disabled)<br />
|-<br />
| 10<br />
| Enable bit for vertex shader's o10 output register. (1 = o10 enabled, 0 = o10 disabled)<br />
|-<br />
| 11<br />
| Enable bit for vertex shader's o11 output register. (1 = o11 enabled, 0 = o11 disabled)<br />
|-<br />
| 12<br />
| Enable bit for vertex shader's o12 output register. (1 = o12 enabled, 0 = o12 disabled)<br />
|-<br />
| 13<br />
| Enable bit for vertex shader's o13 output register. (1 = o13 enabled, 0 = o13 disabled)<br />
|-<br />
| 14<br />
| Enable bit for vertex shader's o14 output register. (1 = o14 enabled, 0 = o14 disabled)<br />
|-<br />
| 15<br />
| Enable bit for vertex shader's o15 output register. (1 = o15 enabled, 0 = o15 disabled)<br />
|}<br />
<br />
This register toggles the vertex shader units' output registers.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_END ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Code data transfer end signal bit.<br />
|}<br />
<br />
This register's value should be set to 1 in order to finalize the transfer of vertex shader code. It is unknown whether this register is used for other functions.<br />
<br />
==== GPUREG_VSH_FLOATUNIFORM_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target float vec4 vertex shader uniform ID for transfer. (range 0-95, where 0 = c0 and 95 = c95)<br />
|-<br />
| 31<br />
| Float vec4 vertex shader uniform data transfer mode. (0 = float24, 1 = float32)<br />
|}<br />
<br />
This register sets the target float vec4 vertex shader uniform ID and transfer mode for the data transfer system. As such it is typically used right before [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]], though writing to one register does not make writing to the other mandatory.<br />
<br />
==== GPUREG_VSH_FLOATUNIFORM_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Float vec4 vertex shader uniform data. (format depends on transfer mode, see below for details)<br />
|}<br />
<br />
This register is used to set the value of float vec4 vertex shader uniform registers. The data format which should be written to it depends on the transfer mode set with [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]]. This register functions as a FIFO queue : after each time a uniform register is successfully set, the target uniform ID value is incremented, meaning that groups of uniforms with contiguous register IDs can be set with only one initial write to [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]].<br />
<br />
* In the case of float24 transfer mode, data should be sent by writing three words which are the concatenation of the float24 value of the uniform register's 4 components, in the reverse order. Assuming each letter corresponds to 4 bits, the format becomes :<br />
** first word : ZZWWWWWW<br />
** second word : YYYYZZZZ<br />
** third word : XXXXXXYY<br />
* In the case of float32 transfer mode, data should be sent by writing four words which are each the float32 value of the uniform register's 4 components, in the reverse order.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-11<br />
| Target vertex shader code offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming vertex shader code data transferred through [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]] should be written.<br />
<br />
NOTE : as we do not yet know what a shader program's maximum size is yet, we also do not know how many bits the code offset parameter holds. The biggest shader binary observed so far was 2422 instructions long. The [[Shader_Instruction_Set#Instruction_formats|shader control flow instructions]] only have room to address 12 bits though, so it's likely that the maximum is 4095.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Vertex shader instruction data.<br />
|}<br />
<br />
This register is used to transfer vertex shader code data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU vertex shader code memory bank at the offset initially set by [[#GPUREG_VSH_CODETRANSFER_CONFIG|GPUREG_VSH_CODETRANSFER_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
==== GPUREG_VSH_OPDESCS_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target vertex shader operand descriptor offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming vertex shader operand descriptor data transferred through [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]] should be written.<br />
<br />
==== GPUREG_VSH_OPDESCS_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Vertex shader operand descriptor data.<br />
|}<br />
<br />
This register is used to transfer vertex shader operand descriptor data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU vertex shader operand descriptor memory bank at the offset initially set by [[#GPUREG_VSH_OPDESCS_CONFIG|GPUREG_VSH_OPDESCS_CONFIG]]. The offset in question is incremented after each write to this register.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=GPU/Internal_Registers&diff=12282
GPU/Internal Registers
2015-04-11T22:58:25Z
<p>Lectem: Added register names extracted from game</p>
<hr />
<div>[[Category:GFX]]<br />
(this page is hugely WIP)<br />
<br />
== Overview ==<br />
<br />
GPU internal registers are written to through GPU commands. They are used to control the GPU's behavior, that is to say tell it to draw stuff and how we want it drawn.<br />
<br />
== Types ==<br />
<br />
There are three main types of registers :<br />
* configuration registers, which directly map to various rendering properties (for example : [[#GPUREG_FACECULLING_CONFIG|GPUREG_FACECULLING_CONFIG]])<br />
* data transfer registers, which can be seen as FIFOs that let us send sequential chunks of data to the GPU, such as shader code or 1D samplers (for example : [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]])<br />
* action triggering registers, which tell the GPU to do something, like draw a primitive (for example : [[#GPUREG_DRAWARRAYS|GPUREG_DRAWARRAYS]])<br />
<br />
== Aliases ==<br />
<br />
It is possible for multiple register (sequential) IDs to correspond to the same register. This is done to leverage the consecutive writing mode for [[GPU Commands]], which makes it possible for a single command to write data to multiple sequential register IDs. For example, register IDs 02C1 through 02C8 all correspond to [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]] so that a consecutively writing command based at 02C0 will write its first parameter to [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]] and ever subsequent ones to [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
<br />
== Register list ==<br />
<br />
{| class="wikitable" border="1"<br />
! Register ID<br />
! Register name<br />
! Notes<br />
! Official Name<br />
|-<br />
| 0000<br />
| [[#GPUREG_0000|GPUREG_0000]]<br />
| <br />
|<br />
|-<br />
| 0001<br />
| [[#GPUREG_0001|GPUREG_0001]]<br />
| <br />
|<br />
|-<br />
| 0002<br />
| [[#GPUREG_0002|GPUREG_0002]]<br />
| <br />
|<br />
|-<br />
| 0003<br />
| [[#GPUREG_0003|GPUREG_0003]]<br />
| <br />
|<br />
|-<br />
| 0004<br />
| [[#GPUREG_0004|GPUREG_0004]]<br />
| <br />
|<br />
|-<br />
| 0005<br />
| [[#GPUREG_0005|GPUREG_0005]]<br />
| <br />
|<br />
|-<br />
| 0006<br />
| [[#GPUREG_0006|GPUREG_0006]]<br />
| <br />
|<br />
|-<br />
| 0007<br />
| [[#GPUREG_0007|GPUREG_0007]]<br />
| <br />
|<br />
|-<br />
| 0008<br />
| [[#GPUREG_0008|GPUREG_0008]]<br />
| <br />
|<br />
|-<br />
| 0009<br />
| [[#GPUREG_0009|GPUREG_0009]]<br />
| <br />
|<br />
|-<br />
| 000A<br />
| [[#GPUREG_000A|GPUREG_000A]]<br />
| <br />
|<br />
|-<br />
| 000B<br />
| [[#GPUREG_000B|GPUREG_000B]]<br />
| <br />
|<br />
|-<br />
| 000C<br />
| [[#GPUREG_000C|GPUREG_000C]]<br />
| <br />
|<br />
|-<br />
| 000D<br />
| [[#GPUREG_000D|GPUREG_000D]]<br />
| <br />
|<br />
|-<br />
| 000E<br />
| [[#GPUREG_000E|GPUREG_000E]]<br />
| <br />
|<br />
|-<br />
| 000F<br />
| [[#GPUREG_000F|GPUREG_000F]]<br />
| <br />
|<br />
|-<br />
| 0010<br />
| [[#GPUREG_FINALIZE|GPUREG_FINALIZE]]<br />
| <br />
|<br />
|-<br />
| 0011<br />
| [[#GPUREG_0011|GPUREG_0011]]<br />
| <br />
|<br />
|-<br />
| 0012<br />
| [[#GPUREG_0012|GPUREG_0012]]<br />
| <br />
|<br />
|-<br />
| 0013<br />
| [[#GPUREG_0013|GPUREG_0013]]<br />
| <br />
|<br />
|-<br />
| 0014<br />
| [[#GPUREG_0014|GPUREG_0014]]<br />
| <br />
|<br />
|-<br />
| 0015<br />
| [[#GPUREG_0015|GPUREG_0015]]<br />
| <br />
|<br />
|-<br />
| 0016<br />
| [[#GPUREG_0016|GPUREG_0016]]<br />
| <br />
|<br />
|-<br />
| 0017<br />
| [[#GPUREG_0017|GPUREG_0017]]<br />
| <br />
|<br />
|-<br />
| 0018<br />
| [[#GPUREG_0018|GPUREG_0018]]<br />
| <br />
|<br />
|-<br />
| 0019<br />
| [[#GPUREG_0019|GPUREG_0019]]<br />
| <br />
|<br />
|-<br />
| 001A<br />
| [[#GPUREG_001A|GPUREG_001A]]<br />
| <br />
|<br />
|-<br />
| 001B<br />
| [[#GPUREG_001B|GPUREG_001B]]<br />
| <br />
|<br />
|-<br />
| 001C<br />
| [[#GPUREG_001C|GPUREG_001C]]<br />
| <br />
|<br />
|-<br />
| 001D<br />
| [[#GPUREG_001D|GPUREG_001D]]<br />
| <br />
|<br />
|-<br />
| 001E<br />
| [[#GPUREG_001E|GPUREG_001E]]<br />
| <br />
|<br />
|-<br />
| 001F<br />
| [[#GPUREG_001F|GPUREG_001F]]<br />
| <br />
|<br />
|-<br />
| 0020<br />
| [[#GPUREG_0020|GPUREG_0020]]<br />
| <br />
|<br />
|-<br />
| 0021<br />
| [[#GPUREG_0021|GPUREG_0021]]<br />
| <br />
|<br />
|-<br />
| 0022<br />
| [[#GPUREG_0022|GPUREG_0022]]<br />
| <br />
|<br />
|-<br />
| 0023<br />
| [[#GPUREG_0023|GPUREG_0023]]<br />
| <br />
|<br />
|-<br />
| 0024<br />
| [[#GPUREG_0024|GPUREG_0024]]<br />
| <br />
|<br />
|-<br />
| 0025<br />
| [[#GPUREG_0025|GPUREG_0025]]<br />
| <br />
|<br />
|-<br />
| 0026<br />
| [[#GPUREG_0026|GPUREG_0026]]<br />
| <br />
|<br />
|-<br />
| 0027<br />
| [[#GPUREG_0027|GPUREG_0027]]<br />
| <br />
|<br />
|-<br />
| 0028<br />
| [[#GPUREG_0028|GPUREG_0028]]<br />
| <br />
|<br />
|-<br />
| 0029<br />
| [[#GPUREG_0029|GPUREG_0029]]<br />
| <br />
|<br />
|-<br />
| 002A<br />
| [[#GPUREG_002A|GPUREG_002A]]<br />
| <br />
|<br />
|-<br />
| 002B<br />
| [[#GPUREG_002B|GPUREG_002B]]<br />
| <br />
|<br />
|-<br />
| 002C<br />
| [[#GPUREG_002C|GPUREG_002C]]<br />
| <br />
|<br />
|-<br />
| 002D<br />
| [[#GPUREG_002D|GPUREG_002D]]<br />
| <br />
|<br />
|-<br />
| 002E<br />
| [[#GPUREG_002E|GPUREG_002E]]<br />
| <br />
|<br />
|-<br />
| 002F<br />
| [[#GPUREG_002F|GPUREG_002F]]<br />
| <br />
|<br />
|-<br />
| 0030<br />
| [[#GPUREG_0030|GPUREG_0030]]<br />
| <br />
|<br />
|-<br />
| 0031<br />
| [[#GPUREG_0031|GPUREG_0031]]<br />
| <br />
|<br />
|-<br />
| 0032<br />
| [[#GPUREG_0032|GPUREG_0032]]<br />
| <br />
|<br />
|-<br />
| 0033<br />
| [[#GPUREG_0033|GPUREG_0033]]<br />
| <br />
|<br />
|-<br />
| 0034<br />
| [[#GPUREG_0034|GPUREG_0034]]<br />
| <br />
|<br />
|-<br />
| 0035<br />
| [[#GPUREG_0035|GPUREG_0035]]<br />
| <br />
|<br />
|-<br />
| 0036<br />
| [[#GPUREG_0036|GPUREG_0036]]<br />
| <br />
|<br />
|-<br />
| 0037<br />
| [[#GPUREG_0037|GPUREG_0037]]<br />
| <br />
|<br />
|-<br />
| 0038<br />
| [[#GPUREG_0038|GPUREG_0038]]<br />
| <br />
|<br />
|-<br />
| 0039<br />
| [[#GPUREG_0039|GPUREG_0039]]<br />
| <br />
|<br />
|-<br />
| 003A<br />
| [[#GPUREG_003A|GPUREG_003A]]<br />
| <br />
|<br />
|-<br />
| 003B<br />
| [[#GPUREG_003B|GPUREG_003B]]<br />
| <br />
|<br />
|-<br />
| 003C<br />
| [[#GPUREG_003C|GPUREG_003C]]<br />
| <br />
|<br />
|-<br />
| 003D<br />
| [[#GPUREG_003D|GPUREG_003D]]<br />
| <br />
|<br />
|-<br />
| 003E<br />
| [[#GPUREG_003E|GPUREG_003E]]<br />
| <br />
|<br />
|-<br />
| 003F<br />
| [[#GPUREG_003F|GPUREG_003F]]<br />
| <br />
|<br />
|-<br />
| 0040<br />
| [[#GPUREG_FACECULLING_CONFIG|GPUREG_FACECULLING_CONFIG]]<br />
| <br />
|PICA_REG_CULL_FACE<br />
|-<br />
| 0041<br />
| [[#GPUREG_0041|GPUREG_0041]]<br />
|?<br />
|PICA_REG_VIEWPORT_WIDTH1<br />
|-<br />
| 0042<br />
| [[#GPUREG_0042|GPUREG_0042]]<br />
|?<br />
|PICA_REG_VIEWPORT_WIDTH2<br />
|-<br />
| 0043<br />
| [[#GPUREG_0043|GPUREG_0043]]<br />
|?<br />
|PICA_REG_VIEWPORT_HEIGHT1<br />
|-<br />
| 0044<br />
| [[#GPUREG_0044|GPUREG_0044]]<br />
| ?<br />
|PICA_REG_VIEWPORT_HEIGHT2<br />
|-<br />
| 0045<br />
| [[#GPUREG_0045|GPUREG_0045]]<br />
| <br />
|<br />
|-<br />
| 0046<br />
| [[#GPUREG_0046|GPUREG_0046]]<br />
| <br />
|<br />
|-<br />
| 0047<br />
| [[#GPUREG_0047|GPUREG_0047]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP<br />
|-<br />
| 0048<br />
| [[#GPUREG_0048|GPUREG_0048]]<br />
|? <br />
|PICA_REG_FRAG_OP_CLIP_DATA1<br />
|-<br />
| 0049<br />
| [[#GPUREG_0049|GPUREG_0049]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA2<br />
|-<br />
| 004A<br />
| [[#GPUREG_004A|GPUREG_004A]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA3<br />
|-<br />
| 004B<br />
| [[#GPUREG_004B|GPUREG_004B]]<br />
|?<br />
|PICA_REG_FRAG_OP_CLIP_DATA4<br />
|-<br />
| 004C<br />
| [[#GPUREG_004C|GPUREG_004C]]<br />
| <br />
|<br />
|-<br />
| 004D<br />
| [[#GPUREG_DEPTHMAP_SCALE|GPUREG_DEPTHMAP_SCALE]]<br />
| <br />
|PICA_REG_FRAG_OP_WSCALE_DATA1<br />
|-<br />
| 004E<br />
| [[#GPUREG_DEPTHMAP_OFFSET|GPUREG_DEPTHMAP_OFFSET]]<br />
| <br />
|PICA_REG_FRAG_OP_WSCALE_DATA2<br />
|-<br />
| 004F<br />
| [[#GPUREG_SH_OUTMAP_TOTAL|GPUREG_SH_OUTMAP_TOTAL]]<br />
| <br />
|PICA_REG_GS_OUT_REG_NUM0 / PICA_REG_VS_OUT_REG_NUM0<br />
|-<br />
| 0050<br />
| [[#GPUREG_SH_OUTMAP_O0|GPUREG_SH_OUTMAP_O0]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR0 / PICA_REG_VS_OUT_ATTR0<br />
|-<br />
| 0051<br />
| [[#GPUREG_SH_OUTMAP_O1|GPUREG_SH_OUTMAP_O1]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR1 / PICA_REG_VS_OUT_ATTR1<br />
|-<br />
| 0052<br />
| [[#GPUREG_SH_OUTMAP_O2|GPUREG_SH_OUTMAP_O2]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR2 / PICA_REG_VS_OUT_ATTR2<br />
|-<br />
| 0053<br />
| [[#GPUREG_SH_OUTMAP_O3|GPUREG_SH_OUTMAP_O3]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR3 / PICA_REG_VS_OUT_ATTR3<br />
|-<br />
| 0054<br />
| [[#GPUREG_SH_OUTMAP_O4|GPUREG_SH_OUTMAP_O4]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR4 / PICA_REG_VS_OUT_ATTR4<br />
|-<br />
| 0055<br />
| [[#GPUREG_SH_OUTMAP_O5|GPUREG_SH_OUTMAP_O5]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR5 / PICA_REG_VS_OUT_ATTR5<br />
|-<br />
| 0056<br />
| [[#GPUREG_SH_OUTMAP_O6|GPUREG_SH_OUTMAP_O6]]<br />
| <br />
|PICA_REG_GS_OUT_ATTR6 / PICA_REG_VS_OUT_ATTR6<br />
|-<br />
| 0057<br />
| [[#GPUREG_0057|GPUREG_0057]]<br />
| <br />
|<br />
|-<br />
| 0058<br />
| [[#GPUREG_0058|GPUREG_0058]]<br />
| <br />
|<br />
|-<br />
| 0059<br />
| [[#GPUREG_0059|GPUREG_0059]]<br />
| <br />
|<br />
|-<br />
| 005A<br />
| [[#GPUREG_005A|GPUREG_005A]]<br />
| <br />
|<br />
|-<br />
| 005B<br />
| [[#GPUREG_005B|GPUREG_005B]]<br />
| <br />
|<br />
|-<br />
| 005C<br />
| [[#GPUREG_005C|GPUREG_005C]]<br />
| <br />
|<br />
|-<br />
| 005D<br />
| [[#GPUREG_005D|GPUREG_005D]]<br />
| <br />
|<br />
|-<br />
| 005E<br />
| [[#GPUREG_005E|GPUREG_005E]]<br />
| <br />
|<br />
|-<br />
| 005F<br />
| [[#GPUREG_005F|GPUREG_005F]]<br />
| <br />
|<br />
|-<br />
| 0060<br />
| [[#GPUREG_0060|GPUREG_0060]]<br />
| <br />
|<br />
|-<br />
| 0061<br />
| [[#GPUREG_0061|GPUREG_0061]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_FUNC<br />
|-<br />
| 0062<br />
| [[#GPUREG_0062|GPUREG_0062]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_TEST1<br />
|-<br />
| 0063<br />
| [[#GPUREG_0063|GPUREG_0063]]<br />
| <br />
|<br />
|-<br />
| 0064<br />
| [[#GPUREG_0064|GPUREG_0064]]<br />
|?<br />
|PICA_REG_GS_OUT_ATTR_MODE / PICA_REG_VS_OUT_ATTR_MODE<br />
|-<br />
| 0065<br />
| [[#GPUREG_SCISSORTEST_MODE|GPUREG_SCISSORTEST_MODE]]<br />
| <br />
|PICA_REG_SCISSOR<br />
|-<br />
| 0066<br />
| [[#GPUREG_SCISSORTEST_POS|GPUREG_SCISSORTEST_POS]]<br />
| <br />
|PICA_REG_SCISSOR_XY<br />
|-<br />
| 0067<br />
| [[#GPUREG_SCISSORTEST_DIM|GPUREG_SCISSORTEST_DIM]]<br />
| <br />
|PICA_REG_SCISSOR_SIZE<br />
|-<br />
| 0068<br />
| [[#GPUREG_0068|GPUREG_0068]]<br />
| <br />
|PICA_REG_VIEWPORT_XY<br />
|-<br />
| 0069<br />
| [[#GPUREG_0069|GPUREG_0069]]<br />
| <br />
|<br />
|-<br />
| 006A<br />
| [[#GPUREG_006A|GPUREG_006A]]<br />
|<br />
|PICA_REG_EARLY_DEPTH_DATA<br />
|-<br />
| 006B<br />
| [[#GPUREG_006B|GPUREG_006B]]<br />
| <br />
|<br />
|-<br />
| 006C<br />
| [[#GPUREG_006C|GPUREG_006C]]<br />
| <br />
|<br />
|-<br />
| 006D<br />
| [[#GPUREG_006D|GPUREG_006D]]<br />
|?<br />
|PICA_REG_FRAG_OP_WSCALE<br />
|-<br />
| 006E<br />
| [[#GPUREG_006E|GPUREG_006E]]<br />
|?<br />
|PICA_REG_RENDER_BUF_RESOLUTION1<br />
|-<br />
| 006F<br />
| [[#GPUREG_006F|GPUREG_006F]]<br />
|?<br />
|PICA_REG_GS_OUT_ATTR_CLK / PICA_REG_VS_OUT_ATTR_CLK<br />
|-<br />
| 0070<br />
| [[#GPUREG_0070|GPUREG_0070]]<br />
| <br />
|<br />
|-<br />
| 0071<br />
| [[#GPUREG_0071|GPUREG_0071]]<br />
| <br />
|<br />
|-<br />
| 0072<br />
| [[#GPUREG_0072|GPUREG_0072]]<br />
| <br />
|<br />
|-<br />
| 0073<br />
| [[#GPUREG_0073|GPUREG_0073]]<br />
| <br />
|<br />
|-<br />
| 0074<br />
| [[#GPUREG_0074|GPUREG_0074]]<br />
| <br />
|<br />
|-<br />
| 0075<br />
| [[#GPUREG_0075|GPUREG_0075]]<br />
| <br />
|<br />
|-<br />
| 0076<br />
| [[#GPUREG_0076|GPUREG_0076]]<br />
| <br />
|<br />
|-<br />
| 0077<br />
| [[#GPUREG_0077|GPUREG_0077]]<br />
| <br />
|<br />
|-<br />
| 0078<br />
| [[#GPUREG_0078|GPUREG_0078]]<br />
| <br />
|<br />
|-<br />
| 0079<br />
| [[#GPUREG_0079|GPUREG_0079]]<br />
| <br />
|<br />
|-<br />
| 007A<br />
| [[#GPUREG_007A|GPUREG_007A]]<br />
| <br />
|<br />
|-<br />
| 007B<br />
| [[#GPUREG_007B|GPUREG_007B]]<br />
| <br />
|<br />
|-<br />
| 007C<br />
| [[#GPUREG_007C|GPUREG_007C]]<br />
| <br />
|<br />
|-<br />
| 007D<br />
| [[#GPUREG_007D|GPUREG_007D]]<br />
| <br />
|<br />
|-<br />
| 007E<br />
| [[#GPUREG_007E|GPUREG_007E]]<br />
| <br />
|<br />
|-<br />
| 007F<br />
| [[#GPUREG_007F|GPUREG_007F]]<br />
| <br />
|<br />
|-<br />
| 0080<br />
| [[#GPUREG_TEXUNITS_CONFIG|GPUREG_TEXUNITS_CONFIG]]<br />
| <br />
|PICA_REG_TEXTURE_FUNC<br />
|-<br />
| 0081<br />
| [[#GPUREG_0081|GPUREG_0081]]<br />
|?<br />
|PICA_REG_TEXTURE0_BORDER_COLOR<br />
|-<br />
| 0082<br />
| [[#GPUREG_TEXUNIT0_DIM|GPUREG_TEXUNIT0_DIM]]<br />
|<br />
|PICA_REG_TEXTURE0_SIZE<br />
|-<br />
| 0083<br />
| [[#GPUREG_TEXUNIT0_PARAM|GPUREG_TEXUNIT0_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE0_WRAP_FILTER<br />
|-<br />
| 0084<br />
| [[#GPUREG_0084|GPUREG_0084]]<br />
|?<br />
|PICA_REG_TEXTURE0_LOD<br />
|-<br />
| 0085<br />
| [[#GPUREG_TEXUNIT0_LOC|GPUREG_TEXUNIT0_LOC]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR1<br />
|-<br />
| 0086<br />
| [[#GPUREG_0086|GPUREG_0086]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR2<br />
|-<br />
| 0087<br />
| [[#GPUREG_0087|GPUREG_0087]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR3<br />
|-<br />
| 0088<br />
| [[#GPUREG_0088|GPUREG_0088]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR4<br />
|-<br />
| 0089<br />
| [[#GPUREG_0089|GPUREG_0089]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR5<br />
|-<br />
| 008A<br />
| [[#GPUREG_008A|GPUREG_008A]]<br />
| <br />
|PICA_REG_TEXTURE0_ADDR6<br />
|-<br />
| 008B<br />
| [[#GPUREG_008B|GPUREG_008B]]<br />
|?<br />
|PICA_REG_TEXTURE0_SHADOW<br />
|-<br />
| 008C<br />
| [[#GPUREG_008C|GPUREG_008C]]<br />
|<br />
|<br />
|-<br />
| 008D<br />
| [[#GPUREG_008D|GPUREG_008D]]<br />
|<br />
|<br />
|-<br />
| 008E<br />
| [[#GPUREG_TEXUNIT0_TYPE|GPUREG_TEXUNIT0_TYPE]]<br />
|?<br />
|PICA_REG_TEXTURE0_FORMAT<br />
|-<br />
| 008F<br />
| [[#GPUREG_008F|GPUREG_008F]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_EN0<br />
|-<br />
| 0090<br />
| [[#GPUREG_0090|GPUREG_0090]]<br />
| <br />
|<br />
|-<br />
| 0091<br />
| [[#GPUREG_0091|GPUREG_0091]]<br />
|?<br />
|PICA_REG_TEXTURE1_BORDER_COLOR<br />
|-<br />
| 0092<br />
| [[#GPUREG_TEXUNIT1_DIM|GPUREG_TEXUNIT1_DIM]]<br />
| <br />
|PICA_REG_TEXTURE1_SIZE<br />
|-<br />
| 0093<br />
| [[#GPUREG_TEXUNIT1_PARAM|GPUREG_TEXUNIT1_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE1_WRAP_FILTER<br />
|-<br />
| 0094<br />
| [[#GPUREG_0094|GPUREG_0094]]<br />
|?<br />
|PICA_REG_TEXTURE1_LOD<br />
|-<br />
| 0095<br />
| [[#GPUREG_TEXUNIT1_LOC|GPUREG_TEXUNIT1_LOC]]<br />
| <br />
|PICA_REG_TEXTURE1_ADDR<br />
|-<br />
| 0096<br />
| [[#GPUREG_TEXUNIT1_TYPE|GPUREG_TEXUNIT1_TYPE]]<br />
| <br />
|PICA_REG_TEXTURE1_FORMAT<br />
|-<br />
| 0097<br />
| [[#GPUREG_0097|GPUREG_0097]]<br />
| <br />
|<br />
|-<br />
| 0098<br />
| [[#GPUREG_0098|GPUREG_0098]]<br />
| <br />
|<br />
|-<br />
| 0099<br />
| [[#GPUREG_0099|GPUREG_0099]]<br />
|?<br />
|PICA_REG_TEXTURE2_BORDER_COLOR<br />
|-<br />
| 009A<br />
| [[#GPUREG_TEXUNIT2_DIM|GPUREG_TEXUNIT2_DIM]]<br />
| <br />
|PICA_REG_TEXTURE2_SIZE<br />
|-<br />
| 009B<br />
| [[#GPUREG_TEXUNIT2_PARAM|GPUREG_TEXUNIT2_PARAM]]<br />
| <br />
|PICA_REG_TEXTURE2_WRAP_FILTER<br />
|-<br />
| 009C<br />
| [[#GPUREG_009C|GPUREG_009C]]<br />
|?<br />
|PICA_REG_TEXTURE2_LOD<br />
|-<br />
| 009D<br />
| [[#GPUREG_TEXUNIT2_LOC|GPUREG_TEXUNIT2_LOC]]<br />
|<br />
|PICA_REG_TEXTURE2_ADDR<br />
|-<br />
| 009E<br />
| [[#GPUREG_TEXUNIT2_TYPE|GPUREG_TEXUNIT2_TYPE]]<br />
| <br />
|PICA_REG_TEXTURE2_FORMAT<br />
|-<br />
| 009F<br />
| [[#GPUREG_009F|GPUREG_009F]]<br />
| <br />
|<br />
|-<br />
| 00A0<br />
| [[#GPUREG_00A0|GPUREG_00A0]]<br />
| <br />
|<br />
|-<br />
| 00A1<br />
| [[#GPUREG_00A1|GPUREG_00A1]]<br />
| <br />
|<br />
|-<br />
| 00A2<br />
| [[#GPUREG_00A2|GPUREG_00A2]]<br />
| <br />
|<br />
|-<br />
| 00A3<br />
| [[#GPUREG_00A3|GPUREG_00A3]]<br />
| <br />
|<br />
|-<br />
| 00A4<br />
| [[#GPUREG_00A4|GPUREG_00A4]]<br />
| <br />
|<br />
|-<br />
| 00A5<br />
| [[#GPUREG_00A5|GPUREG_00A5]]<br />
| <br />
|<br />
|-<br />
| 00A6<br />
| [[#GPUREG_00A6|GPUREG_00A6]]<br />
| <br />
|<br />
|-<br />
| 00A7<br />
| [[#GPUREG_00A7|GPUREG_00A7]]<br />
| <br />
|<br />
|-<br />
| 00A8<br />
| [[#GPUREG_00A8|GPUREG_00A8]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX0<br />
|-<br />
| 00A9<br />
| [[#GPUREG_00A9|GPUREG_00A9]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX1<br />
|-<br />
| 00AA<br />
| [[#GPUREG_00AA|GPUREG_00AA]]<br />
|? <br />
|PICA_REG_TEXTURE3_PROTEX2<br />
|-<br />
| 00AB<br />
| [[#GPUREG_00AB|GPUREG_00AB]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX3<br />
|-<br />
| 00AC<br />
| [[#GPUREG_00AC|GPUREG_00AC]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX4<br />
|-<br />
| 00AD<br />
| [[#GPUREG_00AD|GPUREG_00AD]]<br />
|?<br />
|PICA_REG_TEXTURE3_PROTEX5<br />
|-<br />
| 00AE<br />
| [[#GPUREG_00AE|GPUREG_00AE]]<br />
| <br />
|<br />
|-<br />
| 00AF<br />
| [[#GPUREG_00AF|GPUREG_00AF]]<br />
|?<br />
|PICA_REG_PROTEX_LUT<br />
|-<br />
| 00B0<br />
| [[#GPUREG_00B0|GPUREG_00B0]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA0<br />
|-<br />
| 00B1<br />
| [[#GPUREG_00B1|GPUREG_00B1]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA1<br />
|-<br />
| 00B2<br />
| [[#GPUREG_00B2|GPUREG_00B2]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA2<br />
|-<br />
| 00B3<br />
| [[#GPUREG_00B3|GPUREG_00B3]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA3<br />
|-<br />
| 00B4<br />
| [[#GPUREG_00B4|GPUREG_00B4]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA4<br />
|-<br />
| 00B5<br />
| [[#GPUREG_00B5|GPUREG_00B5]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA5<br />
|-<br />
| 00B6<br />
| [[#GPUREG_00B6|GPUREG_00B6]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA6<br />
|-<br />
| 00B7<br />
| [[#GPUREG_00B7|GPUREG_00B7]]<br />
| ?<br />
|PICA_REG_PROTEX_LUT_DATA7<br />
|-<br />
| 00B8<br />
| [[#GPUREG_00B8|GPUREG_00B8]]<br />
| <br />
|<br />
|-<br />
| 00B9<br />
| [[#GPUREG_00B9|GPUREG_00B9]]<br />
| <br />
|<br />
|-<br />
| 00BA<br />
| [[#GPUREG_00BA|GPUREG_00BA]]<br />
| <br />
|<br />
|-<br />
| 00BB<br />
| [[#GPUREG_00BB|GPUREG_00BB]]<br />
| <br />
|<br />
|-<br />
| 00BC<br />
| [[#GPUREG_00BC|GPUREG_00BC]]<br />
| <br />
|<br />
|-<br />
| 00BD<br />
| [[#GPUREG_00BD|GPUREG_00BD]]<br />
| <br />
|<br />
|-<br />
| 00BE<br />
| [[#GPUREG_00BE|GPUREG_00BE]]<br />
| <br />
|<br />
|-<br />
| 00BF<br />
| [[#GPUREG_00BF|GPUREG_00BF]]<br />
| <br />
|<br />
|-<br />
| 00C0<br />
| [[#GPUREG_TEXENV0_CONFIG0|GPUREG_TEXENV0_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_0<br />
|-<br />
| 00C1<br />
| [[#GPUREG_TEXENV0_CONFIG1|GPUREG_TEXENV0_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_0_OPERAND<br />
|-<br />
| 00C2<br />
| [[#GPUREG_TEXENV0_CONFIG2|GPUREG_TEXENV0_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_0_COMBINE<br />
|-<br />
| 00C3<br />
| [[#GPUREG_TEXENV0_CONFIG3|GPUREG_TEXENV0_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_0_COLOR<br />
|-<br />
| 00C4<br />
| [[#GPUREG_TEXENV0_CONFIG4|GPUREG_TEXENV0_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_0_SCALE<br />
|-<br />
| 00C5<br />
| [[#GPUREG_00C5|GPUREG_00C5]]<br />
| <br />
|<br />
|-<br />
| 00C6<br />
| [[#GPUREG_00C6|GPUREG_00C6]]<br />
| <br />
|<br />
|-<br />
| 00C7<br />
| [[#GPUREG_00C7|GPUREG_00C7]]<br />
| <br />
|<br />
|-<br />
| 00C8<br />
| [[#GPUREG_TEXENV1_CONFIG0|GPUREG_TEXENV1_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_1<br />
|-<br />
| 00C9<br />
| [[#GPUREG_TEXENV1_CONFIG1|GPUREG_TEXENV1_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_1_OPERAND<br />
|-<br />
| 00CA<br />
| [[#GPUREG_TEXENV1_CONFIG2|GPUREG_TEXENV1_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_1_COMBINE<br />
|-<br />
| 00CB<br />
| [[#GPUREG_TEXENV1_CONFIG3|GPUREG_TEXENV1_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_1_COLOR<br />
|-<br />
| 00CC<br />
| [[#GPUREG_TEXENV1_CONFIG4|GPUREG_TEXENV1_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_1_SCALE<br />
|-<br />
| 00CD<br />
| [[#GPUREG_00CD|GPUREG_00CD]]<br />
| <br />
|<br />
|-<br />
| 00CE<br />
| [[#GPUREG_00CE|GPUREG_00CE]]<br />
| <br />
|<br />
|-<br />
| 00CF<br />
| [[#GPUREG_00CF|GPUREG_00CF]]<br />
| <br />
|<br />
|-<br />
| 00D0<br />
| [[#GPUREG_TEXENV2_CONFIG0|GPUREG_TEXENV2_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_2<br />
|-<br />
| 00D1<br />
| [[#GPUREG_TEXENV2_CONFIG1|GPUREG_TEXENV2_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_2_OPERAND<br />
|-<br />
| 00D2<br />
| [[#GPUREG_TEXENV2_CONFIG2|GPUREG_TEXENV2_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_2_COMBINE<br />
|-<br />
| 00D3<br />
| [[#GPUREG_TEXENV2_CONFIG3|GPUREG_TEXENV2_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_2_COLOR<br />
|-<br />
| 00D4<br />
| [[#GPUREG_TEXENV2_CONFIG4|GPUREG_TEXENV2_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_2_SCALE<br />
|-<br />
| 00D5<br />
| [[#GPUREG_00D5|GPUREG_00D5]]<br />
| <br />
|<br />
|-<br />
| 00D6<br />
| [[#GPUREG_00D6|GPUREG_00D6]]<br />
| <br />
|<br />
|-<br />
| 00D7<br />
| [[#GPUREG_00D7|GPUREG_00D7]]<br />
| <br />
|<br />
|-<br />
| 00D8<br />
| [[#GPUREG_TEXENV3_CONFIG0|GPUREG_TEXENV3_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_3<br />
|-<br />
| 00D9<br />
| [[#GPUREG_TEXENV3_CONFIG1|GPUREG_TEXENV3_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_3_OPERAND<br />
|-<br />
| 00DA<br />
| [[#GPUREG_TEXENV3_CONFIG2|GPUREG_TEXENV3_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_3_COMBINE<br />
|-<br />
| 00DB<br />
| [[#GPUREG_TEXENV3_CONFIG3|GPUREG_TEXENV3_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_3_COLOR<br />
|-<br />
| 00DC<br />
| [[#GPUREG_TEXENV3_CONFIG4|GPUREG_TEXENV3_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_3_SCALE<br />
|-<br />
| 00DD<br />
| [[#GPUREG_00DD|GPUREG_00DD]]<br />
| <br />
|<br />
|-<br />
| 00DE<br />
| [[#GPUREG_00DE|GPUREG_00DE]]<br />
| <br />
|<br />
|-<br />
| 00DF<br />
| [[#GPUREG_00DF|GPUREG_00DF]]<br />
| <br />
|<br />
|-<br />
| 00E0<br />
| [[#GPUREG_00E0|GPUREG_00E0]]<br />
|?<br />
|PICA_REG_GAS_FOG_MODE / PICA_REG_TEX_ENV_BUF_INPUT<br />
|-<br />
| 00E1<br />
| [[#GPUREG_00E1|GPUREG_00E1]]<br />
|?<br />
|PICA_REG_FOG_COLOR<br />
|-<br />
| 00E2<br />
| [[#GPUREG_00E2|GPUREG_00E2]]<br />
| <br />
|<br />
|-<br />
| 00E3<br />
| [[#GPUREG_00E3|GPUREG_00E3]]<br />
| <br />
|<br />
|-<br />
| 00E4<br />
| [[#GPUREG_00E4|GPUREG_00E4]]<br />
|?<br />
|PICA_REG_GAS_ATTENUATION<br />
|-<br />
| 00E5<br />
| [[#GPUREG_00E5|GPUREG_00E5]]<br />
|?<br />
|PICA_REG_GAS_ACCMAX<br />
|-<br />
| 00E6<br />
| [[#GPUREG_00E6|GPUREG_00E6]]<br />
|?<br />
|PICA_REG_FOG_LUT_INDEX<br />
|-<br />
| 00E7<br />
| [[#GPUREG_00E7|GPUREG_00E7]]<br />
| <br />
|<br />
|-<br />
| 00E8<br />
| [[#GPUREG_00E8|GPUREG_00E8]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA0<br />
|-<br />
| 00E9<br />
| [[#GPUREG_00E9|GPUREG_00E9]]<br />
|? <br />
|PICA_REG_FOG_LUT_DATA1<br />
|-<br />
| 00EA<br />
| [[#GPUREG_00EA|GPUREG_00EA]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA2<br />
|-<br />
| 00EB<br />
| [[#GPUREG_00EB|GPUREG_00EB]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA3<br />
|-<br />
| 00EC<br />
| [[#GPUREG_00EC|GPUREG_00EC]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA4<br />
|-<br />
| 00ED<br />
| [[#GPUREG_00ED|GPUREG_00ED]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA5<br />
|-<br />
| 00EE<br />
| [[#GPUREG_00EE|GPUREG_00EE]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA6<br />
|-<br />
| 00EF<br />
| [[#GPUREG_00EF|GPUREG_00EF]]<br />
|?<br />
|PICA_REG_FOG_LUT_DATA7<br />
|-<br />
| 00F0<br />
| [[#GPUREG_TEXENV4_CONFIG0|GPUREG_TEXENV4_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_4<br />
|-<br />
| 00F1<br />
| [[#GPUREG_TEXENV4_CONFIG1|GPUREG_TEXENV4_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_4_OPERAND<br />
|-<br />
| 00F2<br />
| [[#GPUREG_TEXENV4_CONFIG2|GPUREG_TEXENV4_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_4_COMBINE<br />
|-<br />
| 00F3<br />
| [[#GPUREG_TEXENV4_CONFIG3|GPUREG_TEXENV4_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_4_COLOR<br />
|-<br />
| 00F4<br />
| [[#GPUREG_TEXENV4_CONFIG4|GPUREG_TEXENV4_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_4_SCALE<br />
|-<br />
| 00F5<br />
| [[#GPUREG_00F5|GPUREG_00F5]]<br />
| <br />
|<br />
|-<br />
| 00F6<br />
| [[#GPUREG_00F6|GPUREG_00F6]]<br />
| <br />
|<br />
|-<br />
| 00F7<br />
| [[#GPUREG_00F7|GPUREG_00F7]]<br />
| <br />
|<br />
|-<br />
| 00F8<br />
| [[#GPUREG_TEXENV5_CONFIG0|GPUREG_TEXENV5_CONFIG0]]<br />
| <br />
|PICA_REG_TEX_ENV_5<br />
|-<br />
| 00F9<br />
| [[#GPUREG_TEXENV5_CONFIG1|GPUREG_TEXENV5_CONFIG1]]<br />
| <br />
|PICA_REG_TEX_ENV_5_OPERAND<br />
|-<br />
| 00FA<br />
| [[#GPUREG_TEXENV5_CONFIG2|GPUREG_TEXENV5_CONFIG2]]<br />
| <br />
|PICA_REG_TEX_ENV_5_COMBINE<br />
|-<br />
| 00FB<br />
| [[#GPUREG_TEXENV5_CONFIG3|GPUREG_TEXENV5_CONFIG3]]<br />
| <br />
|PICA_REG_TEX_ENV_5_COLOR<br />
|-<br />
| 00FC<br />
| [[#GPUREG_TEXENV5_CONFIG4|GPUREG_TEXENV5_CONFIG4]]<br />
| <br />
|PICA_REG_TEX_ENV_5_SCALE<br />
|-<br />
| 00FD<br />
| [[#GPUREG_00FD|GPUREG_00FD]]<br />
|?<br />
|PICA_REG_TEX_ENV_BUF_COLOR<br />
|-<br />
| 00FE<br />
| [[#GPUREG_00FE|GPUREG_00FE]]<br />
| <br />
|<br />
|-<br />
| 00FF<br />
| [[#GPUREG_00FF|GPUREG_00FF]]<br />
| <br />
|<br />
|-<br />
| 0100<br />
| [[#GPUREG_COLOROUTPUT_CONFIG|GPUREG_COLOROUTPUT_CONFIG]]<br />
| ?<br />
|PICA_REG_COLOR_OPERATION<br />
|-<br />
| 0101<br />
| [[#GPUREG_BLEND_CONFIG|GPUREG_BLEND_CONFIG]]<br />
| <br />
|PICA_REG_BLEND_FUNC<br />
|-<br />
| 0102<br />
| [[#GPUREG_COLORLOGICOP_CONFIG|GPUREG_COLORLOGICOP_CONFIG]]<br />
| <br />
|PICA_REG_LOGIC_OP<br />
|-<br />
| 0103<br />
| [[#GPUREG_BLEND_COLOR|GPUREG_BLEND_COLOR]]<br />
| <br />
|PICA_REG_BLEND_COLOR<br />
|-<br />
| 0104<br />
| [[#GPUREG_ALPHATEST_CONFIG|GPUREG_ALPHATEST_CONFIG]]<br />
| <br />
|PICA_REG_FRAG_OP_ALPHA_TEST<br />
|-<br />
| 0105<br />
| [[#GPUREG_STENCILTEST_CONFIG|GPUREG_STENCILTEST_CONFIG]]<br />
| <br />
|PICA_REG_STENCIL_TEST<br />
|-<br />
| 0106<br />
| [[#GPUREG_STENCILOP_CONFIG|GPUREG_STENCILOP_CONFIG]]<br />
| <br />
|PICA_REG_STENCIL_OP<br />
|-<br />
| 0107<br />
| [[#GPUREG_DEPTHTEST_CONFIG|GPUREG_DEPTHTEST_CONFIG]]<br />
| <br />
|PICA_REG_DEPTH_COLOR_MASK<br />
|-<br />
| 0108<br />
| [[#GPUREG_0108|GPUREG_0108]]<br />
| <br />
|<br />
|-<br />
| 0109<br />
| [[#GPUREG_0109|GPUREG_0109]]<br />
| <br />
|<br />
|-<br />
| 010A<br />
| [[#GPUREG_010A|GPUREG_010A]]<br />
| <br />
|<br />
|-<br />
| 010B<br />
| [[#GPUREG_010B|GPUREG_010B]]<br />
| <br />
|<br />
|-<br />
| 010C<br />
| [[#GPUREG_010C|GPUREG_010C]]<br />
| <br />
|<br />
|-<br />
| 010D<br />
| [[#GPUREG_010D|GPUREG_010D]]<br />
| <br />
|<br />
|-<br />
| 010E<br />
| [[#GPUREG_010E|GPUREG_010E]]<br />
| <br />
|<br />
|-<br />
| 010F<br />
| [[#GPUREG_010F|GPUREG_010F]]<br />
| <br />
|<br />
|-<br />
| 0110<br />
| [[#GPUREG_0110|GPUREG_0110]]<br />
|?<br />
|PICA_REG_COLOR_BUFFER_CLEAR0<br />
|-<br />
| 0111<br />
| [[#GPUREG_0111|GPUREG_0111]]<br />
|?<br />
|PICA_REG_COLOR_BUFFER_CLEAR1<br />
|-<br />
| 0112<br />
| [[#GPUREG_COLORBUFFER_READ|GPUREG_COLORBUFFER_READ]]<br />
| <br />
|PICA_REG_COLOR_BUFFER_READ<br />
|-<br />
| 0113<br />
| [[#GPUREG_COLORBUFFER_WRITE|GPUREG_COLORBUFFER_WRITE]]<br />
| <br />
|PICA_REG_COLOR_BUFFER_WRITE<br />
|-<br />
| 0114<br />
| [[#GPUREG_DEPTHBUFFER_READ|GPUREG_DEPTHBUFFER_READ]]<br />
| <br />
|PICA_REG_DEPTH_STENCIL_READ<br />
|-<br />
| 0115<br />
| [[#GPUREG_DEPTHBUFFER_WRITE|GPUREG_DEPTHBUFFER_WRITE]]<br />
| <br />
|PICA_REG_DEPTH_STENCIL_WRITE<br />
|-<br />
| 0116<br />
| [[#GPUREG_DEPTHBUFFER_FORMAT|GPUREG_DEPTHBUFFER_FORMAT]]<br />
| <br />
|PICA_REG_RENDER_BUF_DEPTH_MODE<br />
|-<br />
| 0117<br />
| [[#GPUREG_COLORBUFFER_FORMAT|GPUREG_COLORBUFFER_FORMAT]]<br />
| <br />
|PICA_REG_RENDER_BUF_COLOR_MODE<br />
|-<br />
| 0118<br />
| [[#GPUREG_0118|GPUREG_0118]]<br />
|?<br />
|PICA_REG_EARLY_DEPTH_TEST2<br />
|-<br />
| 0119<br />
| [[#GPUREG_0119|GPUREG_0119]]<br />
| <br />
|<br />
|-<br />
| 011A<br />
| [[#GPUREG_011A|GPUREG_011A]]<br />
| <br />
|<br />
|-<br />
| 011B<br />
| [[#GPUREG_011B|GPUREG_011B]]<br />
|?<br />
|PICA_REG_RENDER_BLOCK_FORMAT<br />
|-<br />
| 011C<br />
| [[#GPUREG_DEPTHBUFFER_LOC|GPUREG_DEPTHBUFFER_LOC]]<br />
|<br />
|PICA_REG_RENDER_BUF_DEPTH_ADDR<br />
|-<br />
| 011D<br />
| [[#GPUREG_COLORBUFFER_LOC|GPUREG_COLORBUFFER_LOC]]<br />
| <br />
|PICA_REG_RENDER_BUF_COLOR_ADDR<br />
|-<br />
| 011E<br />
| [[#GPUREG_OUTBUFFER_DIM|GPUREG_OUTBUFFER_DIM]]<br />
| <br />
|PICA_REG_RENDER_BUF_RESOLUTION0<br />
|-<br />
| 011F<br />
| [[#GPUREG_011F|GPUREG_011F]]<br />
| <br />
|<br />
|-<br />
| 0120<br />
| [[#GPUREG_0120|GPUREG_0120]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_XY<br />
|-<br />
| 0121<br />
| [[#GPUREG_0121|GPUREG_0121]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_Z<br />
|-<br />
| 0122<br />
| [[#GPUREG_0122|GPUREG_0122]]<br />
|?<br />
|PICA_REG_GAS_LIGHT_Z_COLOR<br />
|-<br />
| 0123<br />
| [[#GPUREG_0123|GPUREG_0123]]<br />
|?<br />
|PICA_REG_GAS_LUT_INDEX<br />
|-<br />
| 0124<br />
| [[#GPUREG_0124|GPUREG_0124]]<br />
|?<br />
|PICA_REG_GAS_LUT_DATA<br />
|-<br />
| 0125<br />
| [[#GPUREG_0125|GPUREG_0125]]<br />
| <br />
|<br />
|-<br />
| 0126<br />
| [[#GPUREG_0126|GPUREG_0126]]<br />
|?<br />
|PICA_REG_GAS_DELTAZ_DEPTH<br />
|-<br />
| 0127<br />
| [[#GPUREG_0127|GPUREG_0127]]<br />
| <br />
|<br />
|-<br />
| 0128<br />
| [[#GPUREG_0128|GPUREG_0128]]<br />
| <br />
|<br />
|-<br />
| 0129<br />
| [[#GPUREG_0129|GPUREG_0129]]<br />
| <br />
|<br />
|-<br />
| 012A<br />
| [[#GPUREG_012A|GPUREG_012A]]<br />
| <br />
|<br />
|-<br />
| 012B<br />
| [[#GPUREG_012B|GPUREG_012B]]<br />
| <br />
|<br />
|-<br />
| 012C<br />
| [[#GPUREG_012C|GPUREG_012C]]<br />
| <br />
|<br />
|-<br />
| 012D<br />
| [[#GPUREG_012D|GPUREG_012D]]<br />
| <br />
|<br />
|-<br />
| 012E<br />
| [[#GPUREG_012E|GPUREG_012E]]<br />
| <br />
|<br />
|-<br />
| 012F<br />
| [[#GPUREG_012F|GPUREG_012F]]<br />
| <br />
|<br />
|-<br />
| 0130<br />
| [[#GPUREG_0130|GPUREG_0130]]<br />
|?<br />
|PICA_REG_FRAG_OP_SHADOW<br />
|-<br />
| 0131<br />
| [[#GPUREG_0131|GPUREG_0131]]<br />
| <br />
|<br />
|-<br />
| 0132<br />
| [[#GPUREG_0132|GPUREG_0132]]<br />
| <br />
|<br />
|-<br />
| 0133<br />
| [[#GPUREG_0133|GPUREG_0133]]<br />
| <br />
|<br />
|-<br />
| 0134<br />
| [[#GPUREG_0134|GPUREG_0134]]<br />
| <br />
|<br />
|-<br />
| 0135<br />
| [[#GPUREG_0135|GPUREG_0135]]<br />
| <br />
|<br />
|-<br />
| 0136<br />
| [[#GPUREG_0136|GPUREG_0136]]<br />
| <br />
|<br />
|-<br />
| 0137<br />
| [[#GPUREG_0137|GPUREG_0137]]<br />
| <br />
|<br />
|-<br />
| 0138<br />
| [[#GPUREG_0138|GPUREG_0138]]<br />
| <br />
|<br />
|-<br />
| 0139<br />
| [[#GPUREG_0139|GPUREG_0139]]<br />
| <br />
|<br />
|-<br />
| 013A<br />
| [[#GPUREG_013A|GPUREG_013A]]<br />
| <br />
|<br />
|-<br />
| 013B<br />
| [[#GPUREG_013B|GPUREG_013B]]<br />
| <br />
|<br />
|-<br />
| 013C<br />
| [[#GPUREG_013C|GPUREG_013C]]<br />
| <br />
|<br />
|-<br />
| 013D<br />
| [[#GPUREG_013D|GPUREG_013D]]<br />
| <br />
|<br />
|-<br />
| 013E<br />
| [[#GPUREG_013E|GPUREG_013E]]<br />
| <br />
|<br />
|-<br />
| 013F<br />
| [[#GPUREG_013F|GPUREG_013F]]<br />
| <br />
|<br />
|-<br />
| 0140<br />
| [[#GPUREG_0140|GPUREG_0140]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPECULAR0 / PICA_REG_FRAG_LIGHT_START<br />
|-<br />
| 0141<br />
| [[#GPUREG_0141|GPUREG_0141]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPECULAR1<br />
|-<br />
| 0142<br />
| [[#GPUREG_0142|GPUREG_0142]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIFFUSE<br />
|-<br />
| 0143<br />
| [[#GPUREG_0143|GPUREG_0143]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_AMBIENT<br />
|-<br />
| 0144<br />
| [[#GPUREG_0144|GPUREG_0144]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_POSITION_XY<br />
|-<br />
| 0145<br />
| [[#GPUREG_0145|GPUREG_0145]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_POSITION_Z<br />
|-<br />
| 0146<br />
| [[#GPUREG_0146|GPUREG_0146]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPOT_XY<br />
|-<br />
| 0147<br />
| [[#GPUREG_0147|GPUREG_0147]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_SPOT_Z<br />
|-<br />
| 0148<br />
| [[#GPUREG_0148|GPUREG_0148]]<br />
| <br />
|<br />
|-<br />
| 0149<br />
| [[#GPUREG_0149|GPUREG_0149]]<br />
| <br />
|PICA_REG_FRAG_LIGHT0_TYPE<br />
|-<br />
| 014A<br />
| [[#GPUREG_014A|GPUREG_014A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIST_ATTN_BIAS<br />
|-<br />
| 014B<br />
| [[#GPUREG_014B|GPUREG_014B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT0_DIST_ATTN_SCALE<br />
|-<br />
| 014C<br />
| [[#GPUREG_014C|GPUREG_014C]]<br />
| <br />
|<br />
|-<br />
| 014D<br />
| [[#GPUREG_014D|GPUREG_014D]]<br />
| <br />
|<br />
|-<br />
| 014E<br />
| [[#GPUREG_014E|GPUREG_014E]]<br />
| <br />
|<br />
|-<br />
| 014F<br />
| [[#GPUREG_014F|GPUREG_014F]]<br />
| <br />
|<br />
|-<br />
| 0150<br />
| [[#GPUREG_0150|GPUREG_0150]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPECULAR0<br />
|-<br />
| 0151<br />
| [[#GPUREG_0151|GPUREG_0151]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPECULAR1<br />
|-<br />
| 0152<br />
| [[#GPUREG_0152|GPUREG_0152]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIFFUSE<br />
|-<br />
| 0153<br />
| [[#GPUREG_0153|GPUREG_0153]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_AMBIENT<br />
|-<br />
| 0154<br />
| [[#GPUREG_0154|GPUREG_0154]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_POSITION_XY<br />
|-<br />
| 0155<br />
| [[#GPUREG_0155|GPUREG_0155]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_POSITION_Z<br />
|-<br />
| 0156<br />
| [[#GPUREG_0156|GPUREG_0156]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPOT_XY<br />
|-<br />
| 0157<br />
| [[#GPUREG_0157|GPUREG_0157]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_SPOT_Z<br />
|-<br />
| 0158<br />
| [[#GPUREG_0158|GPUREG_0158]]<br />
| <br />
|<br />
|-<br />
| 0159<br />
| [[#GPUREG_0159|GPUREG_0159]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_TYPE<br />
|-<br />
| 015A<br />
| [[#GPUREG_015A|GPUREG_015A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIST_ATTN_BIAS<br />
|-<br />
| 015B<br />
| [[#GPUREG_015B|GPUREG_015B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT1_DIST_ATTN_SCALE<br />
|-<br />
| 015C<br />
| [[#GPUREG_015C|GPUREG_015C]]<br />
| <br />
|<br />
|-<br />
| 015D<br />
| [[#GPUREG_015D|GPUREG_015D]]<br />
| <br />
|<br />
|-<br />
| 015E<br />
| [[#GPUREG_015E|GPUREG_015E]]<br />
| <br />
|<br />
|-<br />
| 015F<br />
| [[#GPUREG_015F|GPUREG_015F]]<br />
| <br />
|<br />
|-<br />
| 0160<br />
| [[#GPUREG_0160|GPUREG_0160]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPECULAR0<br />
|-<br />
| 0161<br />
| [[#GPUREG_0161|GPUREG_0161]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPECULAR1<br />
|-<br />
| 0162<br />
| [[#GPUREG_0162|GPUREG_0162]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIFFUSE<br />
|-<br />
| 0163<br />
| [[#GPUREG_0163|GPUREG_0163]]<br />
|?<br />
PICA_REG_FRAG_LIGHT2_AMBIENT<br />
|-<br />
| 0164<br />
| [[#GPUREG_0164|GPUREG_0164]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_POSITION_XY<br />
|-<br />
| 0165<br />
| [[#GPUREG_0165|GPUREG_0165]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_POSITION_Z<br />
|-<br />
| 0166<br />
| [[#GPUREG_0166|GPUREG_0166]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPOT_XY<br />
|-<br />
| 0167<br />
| [[#GPUREG_0167|GPUREG_0167]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_SPOT_Z<br />
|-<br />
| 0168<br />
| [[#GPUREG_0168|GPUREG_0168]]<br />
| <br />
|<br />
|-<br />
| 0169<br />
| [[#GPUREG_0169|GPUREG_0169]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_TYPE<br />
|-<br />
| 016A<br />
| [[#GPUREG_016A|GPUREG_016A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIST_ATTN_BIAS<br />
|-<br />
| 016B<br />
| [[#GPUREG_016B|GPUREG_016B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT2_DIST_ATTN_SCALE<br />
|-<br />
| 016C<br />
| [[#GPUREG_016C|GPUREG_016C]]<br />
| <br />
|<br />
|-<br />
| 016D<br />
| [[#GPUREG_016D|GPUREG_016D]]<br />
| <br />
|<br />
|-<br />
| 016E<br />
| [[#GPUREG_016E|GPUREG_016E]]<br />
| <br />
|<br />
|-<br />
| 016F<br />
| [[#GPUREG_016F|GPUREG_016F]]<br />
| <br />
|<br />
|-<br />
| 0170<br />
| [[#GPUREG_0170|GPUREG_0170]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPECULAR0<br />
|-<br />
| 0171<br />
| [[#GPUREG_0171|GPUREG_0171]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPECULAR1<br />
|-<br />
| 0172<br />
| [[#GPUREG_0172|GPUREG_0172]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIFFUSE<br />
|-<br />
| 0173<br />
| [[#GPUREG_0173|GPUREG_0173]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_AMBIENT<br />
|-<br />
| 0174<br />
| [[#GPUREG_0174|GPUREG_0174]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_POSITION_XY<br />
|-<br />
| 0175<br />
| [[#GPUREG_0175|GPUREG_0175]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_POSITION_Z<br />
|-<br />
| 0176<br />
| [[#GPUREG_0176|GPUREG_0176]]<br />
|? <br />
|PICA_REG_FRAG_LIGHT3_SPOT_XY<br />
|-<br />
| 0177<br />
| [[#GPUREG_0177|GPUREG_0177]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_SPOT_Z<br />
|-<br />
| 0178<br />
| [[#GPUREG_0178|GPUREG_0178]]<br />
| <br />
|<br />
|-<br />
| 0179<br />
| [[#GPUREG_0179|GPUREG_0179]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_TYPE<br />
|-<br />
| 017A<br />
| [[#GPUREG_017A|GPUREG_017A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIST_ATTN_BIAS<br />
|-<br />
| 017B<br />
| [[#GPUREG_017B|GPUREG_017B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT3_DIST_ATTN_SCALE<br />
|-<br />
| 017C<br />
| [[#GPUREG_017C|GPUREG_017C]]<br />
| <br />
|<br />
|-<br />
| 017D<br />
| [[#GPUREG_017D|GPUREG_017D]]<br />
| <br />
|<br />
|-<br />
| 017E<br />
| [[#GPUREG_017E|GPUREG_017E]]<br />
| <br />
|<br />
|-<br />
| 017F<br />
| [[#GPUREG_017F|GPUREG_017F]]<br />
| <br />
|<br />
|-<br />
| 0180<br />
| [[#GPUREG_0180|GPUREG_0180]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPECULAR0<br />
|-<br />
| 0181<br />
| [[#GPUREG_0181|GPUREG_0181]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPECULAR1<br />
|-<br />
| 0182<br />
| [[#GPUREG_0182|GPUREG_0182]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIFFUSE<br />
|-<br />
| 0183<br />
| [[#GPUREG_0183|GPUREG_0183]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_AMBIENT<br />
|-<br />
| 0184<br />
| [[#GPUREG_0184|GPUREG_0184]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_POSITION_XY<br />
|-<br />
| 0185<br />
| [[#GPUREG_0185|GPUREG_0185]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_POSITION_Z<br />
|-<br />
| 0186<br />
| [[#GPUREG_0186|GPUREG_0186]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPOT_XY<br />
|-<br />
| 0187<br />
| [[#GPUREG_0187|GPUREG_0187]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_SPOT_Z<br />
|-<br />
| 0188<br />
| [[#GPUREG_0188|GPUREG_0188]]<br />
| <br />
|<br />
|-<br />
| 0189<br />
| [[#GPUREG_0189|GPUREG_0189]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_TYPE<br />
|-<br />
| 018A<br />
| [[#GPUREG_018A|GPUREG_018A]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIST_ATTN_BIAS<br />
|-<br />
| 018B<br />
| [[#GPUREG_018B|GPUREG_018B]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT4_DIST_ATTN_SCALE<br />
|-<br />
| 018C<br />
| [[#GPUREG_018C|GPUREG_018C]]<br />
| <br />
|<br />
|-<br />
| 018D<br />
| [[#GPUREG_018D|GPUREG_018D]]<br />
| <br />
|<br />
|-<br />
| 018E<br />
| [[#GPUREG_018E|GPUREG_018E]]<br />
| <br />
|<br />
|-<br />
| 018F<br />
| [[#GPUREG_018F|GPUREG_018F]]<br />
| <br />
|<br />
|-<br />
| 0190<br />
| [[#GPUREG_0190|GPUREG_0190]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPECULAR0<br />
|-<br />
| 0191<br />
| [[#GPUREG_0191|GPUREG_0191]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPECULAR1<br />
|-<br />
| 0192<br />
| [[#GPUREG_0192|GPUREG_0192]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_DIFFUSE<br />
|-<br />
| 0193<br />
| [[#GPUREG_0193|GPUREG_0193]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_AMBIENT<br />
|-<br />
| 0194<br />
| [[#GPUREG_0194|GPUREG_0194]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_POSITION_XY<br />
|-<br />
| 0195<br />
| [[#GPUREG_0195|GPUREG_0195]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_POSITION_Z<br />
|-<br />
| 0196<br />
| [[#GPUREG_0196|GPUREG_0196]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPOT_XY<br />
|-<br />
| 0197<br />
| [[#GPUREG_0197|GPUREG_0197]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_SPOT_Z<br />
|-<br />
| 0198<br />
| [[#GPUREG_0198|GPUREG_0198]]<br />
| <br />
|<br />
|-<br />
| 0199<br />
| [[#GPUREG_0199|GPUREG_0199]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT5_TYPE<br />
|-<br />
| 019A<br />
| [[#GPUREG_019A|GPUREG_019A]]<br />
| <br />
|<br />
|-<br />
| 019B<br />
| [[#GPUREG_019B|GPUREG_019B]]<br />
| <br />
|<br />
|-<br />
| 019C<br />
| [[#GPUREG_019C|GPUREG_019C]]<br />
| <br />
|<br />
|-<br />
| 019D<br />
| [[#GPUREG_019D|GPUREG_019D]]<br />
| <br />
|<br />
|-<br />
| 019E<br />
| [[#GPUREG_019E|GPUREG_019E]]<br />
| <br />
|<br />
|-<br />
| 019F<br />
| [[#GPUREG_019F|GPUREG_019F]]<br />
| <br />
|<br />
|-<br />
| 01A0<br />
| [[#GPUREG_01A0|GPUREG_01A0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPECULAR0<br />
|-<br />
| 01A1<br />
| [[#GPUREG_01A1|GPUREG_01A1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPECULAR1<br />
|-<br />
| 01A2<br />
| [[#GPUREG_01A2|GPUREG_01A2]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_DIFFUSE<br />
|-<br />
| 01A3<br />
| [[#GPUREG_01A3|GPUREG_01A3]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_AMBIENT<br />
|-<br />
| 01A4<br />
| [[#GPUREG_01A4|GPUREG_01A4]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_POSITION_XY<br />
|-<br />
| 01A5<br />
| [[#GPUREG_01A5|GPUREG_01A5]]<br />
| <br />
|PICA_REG_FRAG_LIGHT6_POSITION_Z<br />
|-<br />
| 01A6<br />
| [[#GPUREG_01A6|GPUREG_01A6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPOT_XY<br />
|-<br />
| 01A7<br />
| [[#GPUREG_01A7|GPUREG_01A7]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_SPOT_Z<br />
|-<br />
| 01A8<br />
| [[#GPUREG_01A8|GPUREG_01A8]]<br />
| <br />
|<br />
|-<br />
| 01A9<br />
| [[#GPUREG_01A9|GPUREG_01A9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT6_TYPE<br />
|-<br />
| 01AA<br />
| [[#GPUREG_01AA|GPUREG_01AA]]<br />
| <br />
|<br />
|-<br />
| 01AB<br />
| [[#GPUREG_01AB|GPUREG_01AB]]<br />
| <br />
|<br />
|-<br />
| 01AC<br />
| [[#GPUREG_01AC|GPUREG_01AC]]<br />
| <br />
|<br />
|-<br />
| 01AD<br />
| [[#GPUREG_01AD|GPUREG_01AD]]<br />
| <br />
|<br />
|-<br />
| 01AE<br />
| [[#GPUREG_01AE|GPUREG_01AE]]<br />
| <br />
|<br />
|-<br />
| 01AF<br />
| [[#GPUREG_01AF|GPUREG_01AF]]<br />
| <br />
|<br />
|-<br />
| 01B0<br />
| [[#GPUREG_01B0|GPUREG_01B0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPECULAR0<br />
|-<br />
| 01B1<br />
| [[#GPUREG_01B1|GPUREG_01B1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPECULAR1<br />
|-<br />
| 01B2<br />
| [[#GPUREG_01B2|GPUREG_01B2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_DIFFUSE<br />
|-<br />
| 01B3<br />
| [[#GPUREG_01B3|GPUREG_01B3]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_AMBIENT<br />
|-<br />
| 01B4<br />
| [[#GPUREG_01B4|GPUREG_01B4]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_POSITION_XY<br />
|-<br />
| 01B5<br />
| [[#GPUREG_01B5|GPUREG_01B5]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_POSITION_Z<br />
|-<br />
| 01B6<br />
| [[#GPUREG_01B6|GPUREG_01B6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPOT_XY<br />
|-<br />
| 01B7<br />
| [[#GPUREG_01B7|GPUREG_01B7]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_SPOT_Z<br />
|-<br />
| 01B8<br />
| [[#GPUREG_01B8|GPUREG_01B8]]<br />
| <br />
|<br />
|-<br />
| 01B9<br />
| [[#GPUREG_01B9|GPUREG_01B9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT7_TYPE<br />
|-<br />
| 01BA<br />
| [[#GPUREG_01BA|GPUREG_01BA]]<br />
| <br />
|<br />
|-<br />
| 01BB<br />
| [[#GPUREG_01BB|GPUREG_01BB]]<br />
| <br />
|<br />
|-<br />
| 01BC<br />
| [[#GPUREG_01BC|GPUREG_01BC]]<br />
| <br />
|<br />
|-<br />
| 01BD<br />
| [[#GPUREG_01BD|GPUREG_01BD]]<br />
| <br />
|<br />
|-<br />
| 01BE<br />
| [[#GPUREG_01BE|GPUREG_01BE]]<br />
| <br />
|<br />
|-<br />
| 01BF<br />
| [[#GPUREG_01BF|GPUREG_01BF]]<br />
| <br />
|<br />
|-<br />
| 01C0<br />
| [[#GPUREG_01C0|GPUREG_01C0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_AMBIENT<br />
|-<br />
| 01C1<br />
| [[#GPUREG_01C1|GPUREG_01C1]]<br />
| <br />
|<br />
|-<br />
| 01C2<br />
| [[#GPUREG_01C2|GPUREG_01C2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_SRC_NUM<br />
|-<br />
| 01C3<br />
| [[#GPUREG_01C3|GPUREG_01C3]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_FUNC_MODE0<br />
|-<br />
| 01C4<br />
| [[#GPUREG_01C4|GPUREG_01C4]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_FUNC_MODE1<br />
|-<br />
| 01C5<br />
| [[#GPUREG_01C5|GPUREG_01C5]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT<br />
|-<br />
| 01C6<br />
| [[#GPUREG_01C6|GPUREG_01C6]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_EN1<br />
|-<br />
| 01C7<br />
| [[#GPUREG_01C7|GPUREG_01C7]]<br />
| <br />
|<br />
|-<br />
| 01C8<br />
| [[#GPUREG_01C8|GPUREG_01C8]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA0<br />
|-<br />
| 01C9<br />
| [[#GPUREG_01C9|GPUREG_01C9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA1<br />
|-<br />
| 01CA<br />
| [[#GPUREG_01CA|GPUREG_01CA]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA2<br />
|-<br />
| 01CB<br />
| [[#GPUREG_01CB|GPUREG_01CB]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA3<br />
|-<br />
| 01CC<br />
| [[#GPUREG_01CC|GPUREG_01CC]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA4<br />
|-<br />
| 01CD<br />
| [[#GPUREG_01CD|GPUREG_01CD]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA8<br />
|-<br />
| 01CE<br />
| [[#GPUREG_01CE|GPUREG_01CE]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA6<br />
|-<br />
| 01CF<br />
| [[#GPUREG_01CF|GPUREG_01CF]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUT_DATA7<br />
|-<br />
| 01D0<br />
| [[#GPUREG_01D0|GPUREG_01D0]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_ABSLUTINPUT<br />
|-<br />
| 01D1<br />
| [[#GPUREG_01D1|GPUREG_01D1]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUTINPUT<br />
|-<br />
| 01D2<br />
| [[#GPUREG_01D2|GPUREG_01D2]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_LUTSCALE<br />
|-<br />
| 01D3<br />
| [[#GPUREG_01D3|GPUREG_01D3]]<br />
| <br />
|<br />
|-<br />
| 01D4<br />
| [[#GPUREG_01D4|GPUREG_01D4]]<br />
| <br />
|<br />
|-<br />
| 01D5<br />
| [[#GPUREG_01D5|GPUREG_01D5]]<br />
| <br />
|<br />
|-<br />
| 01D6<br />
| [[#GPUREG_01D6|GPUREG_01D6]]<br />
| <br />
|<br />
|-<br />
| 01D7<br />
| [[#GPUREG_01D7|GPUREG_01D7]]<br />
| <br />
|<br />
|-<br />
| 01D8<br />
| [[#GPUREG_01D8|GPUREG_01D8]]<br />
| <br />
|<br />
|-<br />
| 01D9<br />
| [[#GPUREG_01D9|GPUREG_01D9]]<br />
|?<br />
|PICA_REG_FRAG_LIGHT_SRC_EN_ID<br />
|-<br />
| 01DA<br />
| [[#GPUREG_01DA|GPUREG_01DA]]<br />
| <br />
|<br />
|-<br />
| 01DB<br />
| [[#GPUREG_01DB|GPUREG_01DB]]<br />
| <br />
|<br />
|-<br />
| 01DC<br />
| [[#GPUREG_01DC|GPUREG_01DC]]<br />
| <br />
|<br />
|-<br />
| 01DD<br />
| [[#GPUREG_01DD|GPUREG_01DD]]<br />
| <br />
|<br />
|-<br />
| 01DE<br />
| [[#GPUREG_01DE|GPUREG_01DE]]<br />
| <br />
|<br />
|-<br />
| 01DF<br />
| [[#GPUREG_01DF|GPUREG_01DF]]<br />
| <br />
|<br />
|-<br />
| 01E0<br />
| [[#GPUREG_01E0|GPUREG_01E0]]<br />
| <br />
|<br />
|-<br />
| 01E1<br />
| [[#GPUREG_01E1|GPUREG_01E1]]<br />
| <br />
|<br />
|-<br />
| 01E2<br />
| [[#GPUREG_01E2|GPUREG_01E2]]<br />
| <br />
|<br />
|-<br />
| 01E3<br />
| [[#GPUREG_01E3|GPUREG_01E3]]<br />
| <br />
|<br />
|-<br />
| 01E4<br />
| [[#GPUREG_01E4|GPUREG_01E4]]<br />
| <br />
|<br />
|-<br />
| 01E5<br />
| [[#GPUREG_01E5|GPUREG_01E5]]<br />
| <br />
|<br />
|-<br />
| 01E6<br />
| [[#GPUREG_01E6|GPUREG_01E6]]<br />
| <br />
|<br />
|-<br />
| 01E7<br />
| [[#GPUREG_01E7|GPUREG_01E7]]<br />
| <br />
|<br />
|-<br />
| 01E8<br />
| [[#GPUREG_01E8|GPUREG_01E8]]<br />
| <br />
|<br />
|-<br />
| 01E9<br />
| [[#GPUREG_01E9|GPUREG_01E9]]<br />
| <br />
|<br />
|-<br />
| 01EA<br />
| [[#GPUREG_01EA|GPUREG_01EA]]<br />
| <br />
|<br />
|-<br />
| 01EB<br />
| [[#GPUREG_01EB|GPUREG_01EB]]<br />
| <br />
|<br />
|-<br />
| 01EC<br />
| [[#GPUREG_01EC|GPUREG_01EC]]<br />
| <br />
|<br />
|-<br />
| 01ED<br />
| [[#GPUREG_01ED|GPUREG_01ED]]<br />
| <br />
|<br />
|-<br />
| 01EE<br />
| [[#GPUREG_01EE|GPUREG_01EE]]<br />
| <br />
|<br />
|-<br />
| 01EF<br />
| [[#GPUREG_01EF|GPUREG_01EF]]<br />
| <br />
|<br />
|-<br />
| 01F0<br />
| [[#GPUREG_01F0|GPUREG_01F0]]<br />
| <br />
|<br />
|-<br />
| 01F1<br />
| [[#GPUREG_01F1|GPUREG_01F1]]<br />
| <br />
|<br />
|-<br />
| 01F2<br />
| [[#GPUREG_01F2|GPUREG_01F2]]<br />
| <br />
|<br />
|-<br />
| 01F3<br />
| [[#GPUREG_01F3|GPUREG_01F3]]<br />
| <br />
|<br />
|-<br />
| 01F4<br />
| [[#GPUREG_01F4|GPUREG_01F4]]<br />
| <br />
|<br />
|-<br />
| 01F5<br />
| [[#GPUREG_01F5|GPUREG_01F5]]<br />
| <br />
|<br />
|-<br />
| 01F6<br />
| [[#GPUREG_01F6|GPUREG_01F6]]<br />
| <br />
|<br />
|-<br />
| 01F7<br />
| [[#GPUREG_01F7|GPUREG_01F7]]<br />
| <br />
|<br />
|-<br />
| 01F8<br />
| [[#GPUREG_01F8|GPUREG_01F8]]<br />
| <br />
|<br />
|-<br />
| 01F9<br />
| [[#GPUREG_01F9|GPUREG_01F9]]<br />
| <br />
|<br />
|-<br />
| 01FA<br />
| [[#GPUREG_01FA|GPUREG_01FA]]<br />
| <br />
|<br />
|-<br />
| 01FB<br />
| [[#GPUREG_01FB|GPUREG_01FB]]<br />
| <br />
|<br />
|-<br />
| 01FC<br />
| [[#GPUREG_01FC|GPUREG_01FC]]<br />
| <br />
|<br />
|-<br />
| 01FD<br />
| [[#GPUREG_01FD|GPUREG_01FD]]<br />
| <br />
|<br />
|-<br />
| 01FE<br />
| [[#GPUREG_01FE|GPUREG_01FE]]<br />
| <br />
|<br />
|-<br />
| 01FF<br />
| [[#GPUREG_01FF|GPUREG_01FF]]<br />
| <br />
|<br />
|-<br />
! colspan=3 | Geometry pipeline registers<br />
|<br />
|-<br />
| 0200<br />
| [[#GPUREG_ATTRIBBUFFERS_LOC|GPUREG_ATTRIBBUFFERS_LOC]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS_BASE_ADDR<br />
|-<br />
| 0201<br />
| [[#GPUREG_ATTRIBBUFFERS_FORMAT_LOW|GPUREG_ATTRIBBUFFERS_FORMAT_LOW]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS0<br />
|-<br />
| 0202<br />
| [[#GPUREG_ATTRIBBUFFERS_FORMAT_HIGH|GPUREG_ATTRIBBUFFERS_FORMAT_HIGH]]<br />
| <br />
|PICA_REG_VTX_ATTR_ARRAYS1<br />
|-<br />
| 0203<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG0|GPUREG_ATTRIBBUFFER0_CONFIG0]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ATTR_OFFSET<br />
|-<br />
| 0204<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG1|GPUREG_ATTRIBBUFFER0_CONFIG1]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ELEMENT0<br />
|-<br />
| 0205<br />
| [[#GPUREG_ATTRIBBUFFER0_CONFIG2|GPUREG_ATTRIBBUFFER0_CONFIG2]]<br />
| <br />
|PICA_REG_LOAD_ARRAY0_ELEMENT1<br />
|-<br />
| 0206<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG0|GPUREG_ATTRIBBUFFER1_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0207<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG1|GPUREG_ATTRIBBUFFER1_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0208<br />
| [[#GPUREG_ATTRIBBUFFER1_CONFIG2|GPUREG_ATTRIBBUFFER1_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0209<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG0|GPUREG_ATTRIBBUFFER2_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 020A<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG1|GPUREG_ATTRIBBUFFER2_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 020B<br />
| [[#GPUREG_ATTRIBBUFFER2_CONFIG2|GPUREG_ATTRIBBUFFER2_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 020C<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG0|GPUREG_ATTRIBBUFFER3_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 020D<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG1|GPUREG_ATTRIBBUFFER3_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 020E<br />
| [[#GPUREG_ATTRIBBUFFER3_CONFIG2|GPUREG_ATTRIBBUFFER3_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 020F<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG0|GPUREG_ATTRIBBUFFER4_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0210<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG1|GPUREG_ATTRIBBUFFER4_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0211<br />
| [[#GPUREG_ATTRIBBUFFER4_CONFIG2|GPUREG_ATTRIBBUFFER4_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0212<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG0|GPUREG_ATTRIBBUFFER5_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0213<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG1|GPUREG_ATTRIBBUFFER5_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0214<br />
| [[#GPUREG_ATTRIBBUFFER5_CONFIG2|GPUREG_ATTRIBBUFFER5_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0215<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG0|GPUREG_ATTRIBBUFFER6_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0216<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG1|GPUREG_ATTRIBBUFFER6_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0217<br />
| [[#GPUREG_ATTRIBBUFFER6_CONFIG2|GPUREG_ATTRIBBUFFER6_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0218<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG0|GPUREG_ATTRIBBUFFER7_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0219<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG1|GPUREG_ATTRIBBUFFER7_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 021A<br />
| [[#GPUREG_ATTRIBBUFFER7_CONFIG2|GPUREG_ATTRIBBUFFER7_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 021B<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG0|GPUREG_ATTRIBBUFFER8_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 021C<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG1|GPUREG_ATTRIBBUFFER8_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 021D<br />
| [[#GPUREG_ATTRIBBUFFER8_CONFIG2|GPUREG_ATTRIBBUFFER8_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 021E<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG0|GPUREG_ATTRIBBUFFER9_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 021F<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG1|GPUREG_ATTRIBBUFFER9_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0220<br />
| [[#GPUREG_ATTRIBBUFFER9_CONFIG2|GPUREG_ATTRIBBUFFER9_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0221<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG0|GPUREG_ATTRIBBUFFERA_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0222<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG1|GPUREG_ATTRIBBUFFERA_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0223<br />
| [[#GPUREG_ATTRIBBUFFERA_CONFIG2|GPUREG_ATTRIBBUFFERA_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0224<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG0|GPUREG_ATTRIBBUFFERB_CONFIG0]]<br />
| <br />
|<br />
|-<br />
| 0225<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG1|GPUREG_ATTRIBBUFFERB_CONFIG1]]<br />
| <br />
|<br />
|-<br />
| 0226<br />
| [[#GPUREG_ATTRIBBUFFERB_CONFIG2|GPUREG_ATTRIBBUFFERB_CONFIG2]]<br />
| <br />
|<br />
|-<br />
| 0227<br />
| [[#GPUREG_INDEXBUFFER_CONFIG|GPUREG_INDEXBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_INDEX_ARRAY_ADDR_OFFSET<br />
|-<br />
| 0228<br />
| [[#GPUREG_NUMVERTICES|GPUREG_NUMVERTICES]]<br />
| <br />
|PICA_REG_DRAW_VERTEX_NUM<br />
|-<br />
| 0229<br />
| [[#GPUREG_GEOSTAGE_CONFIG|GPUREG_GEOSTAGE_CONFIG]]<br />
| ?<br />
|PICA_REG_DRAW_MODE0<br />
|-<br />
| 022A<br />
| [[#GPUREG_022A|GPUREG_022A]]<br />
|?<br />
|PICA_REG_DRAW_VERTEX_OFFSET<br />
|-<br />
| 022B<br />
| [[#GPUREG_022B|GPUREG_022B]]<br />
| <br />
|<br />
|-<br />
| 022C<br />
| [[#GPUREG_022C|GPUREG_022C]]<br />
| <br />
|<br />
|-<br />
| 022D<br />
| [[#GPUREG_022D|GPUREG_022D]]<br />
| <br />
|<br />
|-<br />
| 022E<br />
| [[#GPUREG_DRAWARRAYS|GPUREG_DRAWARRAYS]]<br />
|<br />
|PICA_REG_START_DRAW_ARRAY<br />
|-<br />
| 022F<br />
| [[#GPUREG_DRAWELEMENTS|GPUREG_DRAWELEMENTS]]<br />
|<br />
|PICA_REG_START_DRAW_ELEMENT<br />
|-<br />
| 0230<br />
| [[#GPUREG_0230|GPUREG_0230]]<br />
| <br />
|<br />
|-<br />
| 0231<br />
| [[#GPUREG_0231|GPUREG_0231]]<br />
|?<br />
|PICA_REG_VTX_FUNC<br />
|-<br />
| 0232<br />
| [[#GPUREG_0232|GPUREG_0232]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR<br />
|-<br />
| 0233<br />
| [[#GPUREG_0233|GPUREG_0233]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA0<br />
|-<br />
| 0234<br />
| [[#GPUREG_0234|GPUREG_0234]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA1<br />
|-<br />
| 0235<br />
| [[#GPUREG_0235|GPUREG_0235]]<br />
|?<br />
|PICA_REG_VS_FIXED_ATTR_DATA2<br />
|-<br />
| 0236<br />
| [[#GPUREG_0236|GPUREG_0236]]<br />
| <br />
|<br />
|-<br />
| 0237<br />
| [[#GPUREG_0237|GPUREG_0237]]<br />
| <br />
|<br />
|-<br />
| 0238<br />
| [[#GPUREG_0238|GPUREG_0238]]<br />
| <br />
|<br />
|-<br />
| 0239<br />
| [[#GPUREG_0239|GPUREG_0239]]<br />
| <br />
|<br />
|-<br />
| 023A<br />
| [[#GPUREG_023A|GPUREG_023A]]<br />
| <br />
|<br />
|-<br />
| 023B<br />
| [[#GPUREG_023B|GPUREG_023B]]<br />
| <br />
|<br />
|-<br />
| 023C<br />
| [[#GPUREG_023C|GPUREG_023C]]<br />
| <br />
|<br />
|-<br />
| 023D<br />
| [[#GPUREG_023D|GPUREG_023D]]<br />
| <br />
|<br />
|-<br />
| 023E<br />
| [[#GPUREG_023E|GPUREG_023E]]<br />
| <br />
|<br />
|-<br />
| 023F<br />
| [[#GPUREG_023F|GPUREG_023F]]<br />
| <br />
|<br />
|-<br />
| 0240<br />
| [[#GPUREG_0240|GPUREG_0240]]<br />
| <br />
|<br />
|-<br />
| 0241<br />
| [[#GPUREG_0241|GPUREG_0241]]<br />
| <br />
|<br />
|-<br />
| 0242<br />
| [[#GPUREG_0242|GPUREG_0242]]<br />
|?<br />
|PICA_REG_VS_ATTR_NUM1<br />
|-<br />
| 0243<br />
| [[#GPUREG_0243|GPUREG_0243]]<br />
| <br />
|<br />
|-<br />
| 0244<br />
| [[#GPUREG_0244|GPUREG_0244]]<br />
|?<br />
|PICA_REG_VS_COM_MODE<br />
|-<br />
| 0245<br />
| [[#GPUREG_0245|GPUREG_0245]]<br />
|?<br />
|PICA_REG_START_DRAW_FUNC0<br />
|-<br />
| 0246<br />
| [[#GPUREG_0246|GPUREG_0246]]<br />
| <br />
|<br />
|-<br />
| 0247<br />
| [[#GPUREG_0247|GPUREG_0247]]<br />
| <br />
|<br />
|-<br />
| 0248<br />
| [[#GPUREG_0248|GPUREG_0248]]<br />
| <br />
|<br />
|-<br />
| 0249<br />
| [[#GPUREG_0249|GPUREG_0249]]<br />
| <br />
|<br />
|-<br />
| 024A<br />
| [[#GPUREG_024A|GPUREG_024A]]<br />
|?<br />
|PICA_REG_VS_OUT_REG_NUM1<br />
|-<br />
| 024B<br />
| [[#GPUREG_024B|GPUREG_024B]]<br />
|<br />
|<br />
|-<br />
| 024C<br />
| [[#GPUREG_024C|GPUREG_024C]]<br />
| <br />
|<br />
|-<br />
| 024D<br />
| [[#GPUREG_024D|GPUREG_024D]]<br />
| <br />
|<br />
|-<br />
| 024E<br />
| [[#GPUREG_024E|GPUREG_024E]]<br />
| <br />
|<br />
|-<br />
| 024F<br />
| [[#GPUREG_024F|GPUREG_024F]]<br />
| <br />
|<br />
|-<br />
| 0250<br />
| [[#GPUREG_0250|GPUREG_0250]]<br />
| <br />
|<br />
|-<br />
| 0251<br />
| [[#GPUREG_0251|GPUREG_0251]]<br />
|?<br />
|PICA_REG_VS_OUT_REG_NUM2<br />
|-<br />
| 0252<br />
| [[#GPUREG_0252|GPUREG_0252]]<br />
|?<br />
|PICA_REG_GS_MISC_REG0<br />
|-<br />
| 0253<br />
| [[#GPUREG_0253|GPUREG_0253]]<br />
|?<br />
|PICA_REG_DRAW_MODE1<br />
|-<br />
| 0254<br />
| [[#GPUREG_0254|GPUREG_0254]]<br />
|?<br />
|PICA_REG_GS_MISC_REG1<br />
|-<br />
| 0255<br />
| [[#GPUREG_0255|GPUREG_0255]]<br />
| <br />
|<br />
|-<br />
| 0256<br />
| [[#GPUREG_0256|GPUREG_0256]]<br />
| <br />
|<br />
|-<br />
| 0257<br />
| [[#GPUREG_0257|GPUREG_0257]]<br />
| <br />
|<br />
|-<br />
| 0258<br />
| [[#GPUREG_0258|GPUREG_0258]]<br />
| <br />
|<br />
|-<br />
| 0259<br />
| [[#GPUREG_0259|GPUREG_0259]]<br />
| <br />
|<br />
|-<br />
| 025A<br />
| [[#GPUREG_025A|GPUREG_025A]]<br />
| <br />
|<br />
|-<br />
| 025B<br />
| [[#GPUREG_025B|GPUREG_025B]]<br />
| <br />
|<br />
|-<br />
| 025C<br />
| [[#GPUREG_025C|GPUREG_025C]]<br />
| <br />
|<br />
|-<br />
| 025D<br />
| [[#GPUREG_025D|GPUREG_025D]]<br />
| <br />
|<br />
|-<br />
| 025E<br />
| [[#GPUREG_PRIMITIVE_CONFIG|GPUREG_PRIMITIVE_CONFIG]]<br />
| ?<br />
|PICA_REG_GS_OUT_REG_NUM3 / PICA_REG_VS_OUT_REG_NUM3<br />
|-<br />
| 025F<br />
| [[#GPUREG_025F|GPUREG_025F]]<br />
|?<br />
|PICA_REG_START_DRAW_FUNC1<br />
|-<br />
| 0260<br />
| [[#GPUREG_0260|GPUREG_0260]]<br />
| <br />
|<br />
|-<br />
| 0261<br />
| [[#GPUREG_0261|GPUREG_0261]]<br />
| <br />
|<br />
|-<br />
| 0262<br />
| [[#GPUREG_0262|GPUREG_0262]]<br />
| <br />
|<br />
|-<br />
| 0263<br />
| [[#GPUREG_0263|GPUREG_0263]]<br />
| <br />
|<br />
|-<br />
| 0264<br />
| [[#GPUREG_0264|GPUREG_0264]]<br />
| <br />
|<br />
|-<br />
| 0265<br />
| [[#GPUREG_0265|GPUREG_0265]]<br />
| <br />
|<br />
|-<br />
| 0266<br />
| [[#GPUREG_0266|GPUREG_0266]]<br />
| <br />
|<br />
|-<br />
| 0267<br />
| [[#GPUREG_0267|GPUREG_0267]]<br />
| <br />
|<br />
|-<br />
| 0268<br />
| [[#GPUREG_0268|GPUREG_0268]]<br />
| <br />
|<br />
|-<br />
| 0269<br />
| [[#GPUREG_0269|GPUREG_0269]]<br />
| <br />
|<br />
|-<br />
| 026A<br />
| [[#GPUREG_026A|GPUREG_026A]]<br />
| <br />
|<br />
|-<br />
| 026B<br />
| [[#GPUREG_026B|GPUREG_026B]]<br />
| <br />
|<br />
|-<br />
| 026C<br />
| [[#GPUREG_026C|GPUREG_026C]]<br />
| <br />
|<br />
|-<br />
| 026D<br />
| [[#GPUREG_026D|GPUREG_026D]]<br />
| <br />
|<br />
|-<br />
| 026E<br />
| [[#GPUREG_026E|GPUREG_026E]]<br />
| <br />
|<br />
|-<br />
| 026F<br />
| [[#GPUREG_026F|GPUREG_026F]]<br />
| <br />
|<br />
|-<br />
| 0270<br />
| [[#GPUREG_0270|GPUREG_0270]]<br />
| <br />
|<br />
|-<br />
| 0271<br />
| [[#GPUREG_0271|GPUREG_0271]]<br />
| <br />
|<br />
|-<br />
| 0272<br />
| [[#GPUREG_0272|GPUREG_0272]]<br />
| <br />
|<br />
|-<br />
| 0273<br />
| [[#GPUREG_0273|GPUREG_0273]]<br />
| <br />
|<br />
|-<br />
| 0274<br />
| [[#GPUREG_0274|GPUREG_0274]]<br />
| <br />
|<br />
|-<br />
| 0275<br />
| [[#GPUREG_0275|GPUREG_0275]]<br />
| <br />
|<br />
|-<br />
| 0276<br />
| [[#GPUREG_0276|GPUREG_0276]]<br />
| <br />
|<br />
|-<br />
| 0277<br />
| [[#GPUREG_0277|GPUREG_0277]]<br />
| <br />
|<br />
|-<br />
| 0278<br />
| [[#GPUREG_0278|GPUREG_0278]]<br />
| <br />
|<br />
|-<br />
| 0279<br />
| [[#GPUREG_0279|GPUREG_0279]]<br />
| <br />
|<br />
|-<br />
| 027A<br />
| [[#GPUREG_027A|GPUREG_027A]]<br />
| <br />
|<br />
|-<br />
| 027B<br />
| [[#GPUREG_027B|GPUREG_027B]]<br />
| <br />
|<br />
|-<br />
| 027C<br />
| [[#GPUREG_027C|GPUREG_027C]]<br />
| <br />
|<br />
|-<br />
| 027D<br />
| [[#GPUREG_027D|GPUREG_027D]]<br />
| <br />
|<br />
|-<br />
| 027E<br />
| [[#GPUREG_027E|GPUREG_027E]]<br />
| <br />
|<br />
|-<br />
| 027F<br />
| [[#GPUREG_027F|GPUREG_027F]]<br />
| <br />
|<br />
|-<br />
! colspan=4 | Geometry shader registers<br />
|-<br />
| 0280<br />
| [[#GPUREG_GSH_BOOLUNIFORM|GPUREG_GSH_BOOLUNIFORM]]<br />
| <br />
|PICA_REG_GS_BOOL<br />
|-<br />
| 0281<br />
| [[#GPUREG_GSH_INTUNIFORM_I0|GPUREG_GSH_INTUNIFORM_I0]]<br />
| <br />
|PICA_REG_GS_INT0<br />
|-<br />
| 0282<br />
| [[#GPUREG_GSH_INTUNIFORM_I1|GPUREG_GSH_INTUNIFORM_I1]]<br />
| <br />
|PICA_REG_GS_INT1<br />
|-<br />
| 0283<br />
| [[#GPUREG_GSH_INTUNIFORM_I2|GPUREG_GSH_INTUNIFORM_I2]]<br />
| <br />
|PICA_REG_GS_INT2<br />
|-<br />
| 0284<br />
| [[#GPUREG_GSH_INTUNIFORM_I3|GPUREG_GSH_INTUNIFORM_I3]]<br />
| <br />
|PICA_REG_GS_INT3<br />
|-<br />
| 0285<br />
| [[#GPUREG_0285|GPUREG_0285]]<br />
| <br />
|<br />
|-<br />
| 0286<br />
| [[#GPUREG_0286|GPUREG_0286]]<br />
| <br />
|<br />
|-<br />
| 0287<br />
| [[#GPUREG_0287|GPUREG_0287]]<br />
| <br />
|<br />
|-<br />
| 0288<br />
| [[#GPUREG_0288|GPUREG_0288]]<br />
| <br />
|<br />
|-<br />
| 0289<br />
| [[#GPUREG_GSH_INPUTBUFFER_CONFIG|GPUREG_GSH_INPUTBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_GS_ATTR_NUM<br />
|-<br />
| 028A<br />
| [[#GPUREG_GSH_ENTRYPOINT|GPUREG_GSH_ENTRYPOINT]]<br />
| <br />
|PICA_REG_GS_START_ADDR<br />
|-<br />
| 028B<br />
| [[#GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW|GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW]]<br />
| <br />
|PICA_REG_GS_ATTR_IN_REG_MAP0<br />
|-<br />
| 028C<br />
| [[#GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH|GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH]]<br />
| <br />
|PICA_REG_GS_ATTR_IN_REG_MAP1<br />
|-<br />
| 028D<br />
| [[#GPUREG_GSH_OUTMAP_MASK|GPUREG_GSH_OUTMAP_MASK]]<br />
| <br />
|PICA_REG_GS_OUT_REG_MASK<br />
|-<br />
| 028E<br />
| [[#GPUREG_028E|GPUREG_028E]]<br />
| <br />
|<br />
|-<br />
| 028F<br />
| [[#GPUREG_GSH_CODETRANSFER_END|GPUREG_GSH_CODETRANSFER_END]]<br />
| <br />
|PICA_REG_GS_PROG_RENEWAL_END<br />
|-<br />
| 0290<br />
| [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]]<br />
| <br />
|PICA_REG_GS_FLOAT_ADDR<br />
|-<br />
| 0291<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA1<br />
|-<br />
| 0292<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA2<br />
|-<br />
| 0293<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA3<br />
|-<br />
| 0294<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA4<br />
|-<br />
| 0295<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA5<br />
|-<br />
| 0296<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA6<br />
|-<br />
| 0297<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA7<br />
|-<br />
| 0298<br />
| [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_GS_FLOAT_DATA8<br />
|-<br />
| 0299<br />
| [[#GPUREG_0299|GPUREG_0299]]<br />
| <br />
|<br />
|-<br />
| 029A<br />
| [[#GPUREG_029A|GPUREG_029A]]<br />
| <br />
|<br />
|-<br />
| 029B<br />
| [[#GPUREG_GSH_CODETRANSFER_CONFIG|GPUREG_GSH_CODETRANSFER_CONFIG]]<br />
| ?<br />
|PICA_REG_GS_PROG_ADDR<br />
|-<br />
| 029C<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA0<br />
|-<br />
| 029D<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA1<br />
|-<br />
| 029E<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA2<br />
|-<br />
| 029F<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA3<br />
|-<br />
| 02A0<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA4<br />
|-<br />
| 02A1<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA5<br />
|-<br />
| 02A2<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA6<br />
|-<br />
| 02A3<br />
| [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_DATA7<br />
|-<br />
| 02A4<br />
| [[#GPUREG_02A4|GPUREG_02A4]]<br />
| <br />
|<br />
|-<br />
| 02A5<br />
| [[#GPUREG_GSH_OPDESCS_CONFIG|GPUREG_GSH_OPDESCS_CONFIG]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_ADDR<br />
|-<br />
| 02A6<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA0<br />
|-<br />
| 02A7<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA1<br />
|-<br />
| 02A8<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA2<br />
|-<br />
| 02A9<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA3<br />
|-<br />
| 02AA<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA4<br />
|-<br />
| 02AB<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA5<br />
|-<br />
| 02AC<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA6<br />
|-<br />
| 02AD<br />
| [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_GS_PROG_SWIZZLE_DATA7<br />
|-<br />
| 02AE<br />
| [[#GPUREG_02AE|GPUREG_02AE]]<br />
| <br />
|<br />
|-<br />
| 02AF<br />
| [[#GPUREG_02AF|GPUREG_02AF]]<br />
| <br />
|<br />
|-<br />
! colspan=4 | Vertex shader registers<br />
|-<br />
| 02B0<br />
| [[#GPUREG_VSH_BOOLUNIFORM|GPUREG_VSH_BOOLUNIFORM]]<br />
| <br />
|PICA_REG_VS_BOOL<br />
|-<br />
| 02B1<br />
| [[#GPUREG_VSH_INTUNIFORM_I0|GPUREG_VSH_INTUNIFORM_I0]]<br />
| <br />
|PICA_REG_VS_INT0<br />
|-<br />
| 02B2<br />
| [[#GPUREG_VSH_INTUNIFORM_I1|GPUREG_VSH_INTUNIFORM_I1]]<br />
| <br />
|PICA_REG_VS_INT1<br />
|-<br />
| 02B3<br />
| [[#GPUREG_VSH_INTUNIFORM_I2|GPUREG_VSH_INTUNIFORM_I2]]<br />
| <br />
|PICA_REG_VS_INT2<br />
|-<br />
| 02B4<br />
| [[#GPUREG_VSH_INTUNIFORM_I3|GPUREG_VSH_INTUNIFORM_I3]]<br />
| <br />
|PICA_REG_VS_INT3<br />
|-<br />
| 02B5<br />
| [[#GPUREG_02B5|GPUREG_02B5]]<br />
| <br />
|<br />
|-<br />
| 02B6<br />
| [[#GPUREG_02B6|GPUREG_02B6]]<br />
| <br />
|<br />
|-<br />
| 02B7<br />
| [[#GPUREG_02B7|GPUREG_02B7]]<br />
| <br />
|<br />
|-<br />
| 02B8<br />
| [[#GPUREG_02B8|GPUREG_02B8]]<br />
| <br />
|<br />
|-<br />
| 02B9<br />
| [[#GPUREG_VSH_INPUTBUFFER_CONFIG|GPUREG_VSH_INPUTBUFFER_CONFIG]]<br />
| <br />
|PICA_REG_VS_ATTR_NUM0<br />
|-<br />
| 02BA<br />
| [[#GPUREG_VSH_ENTRYPOINT|GPUREG_VSH_ENTRYPOINT]]<br />
| <br />
|PICA_REG_VS_START_ADDR<br />
|-<br />
| 02BB<br />
| [[#GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW|GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW]]<br />
| <br />
|PICA_REG_VS_ATTR_IN_REG_MAP0<br />
|-<br />
| 02BC<br />
| [[#GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH|GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH]]<br />
| <br />
|PICA_REG_VS_ATTR_IN_REG_MAP1<br />
|-<br />
| 02BD<br />
| [[#GPUREG_VSH_OUTMAP_MASK|GPUREG_VSH_OUTMAP_MASK]]<br />
| <br />
|PICA_REG_VS_OUT_REG_MASK<br />
|-<br />
| 02BE<br />
| [[#GPUREG_02BE|GPUREG_02BE]]<br />
| <br />
|<br />
|-<br />
| 02BF<br />
| [[#GPUREG_VSH_CODETRANSFER_END|GPUREG_VSH_CODETRANSFER_END]]<br />
| <br />
|PICA_REG_VS_PROG_RENEWAL_END<br />
|-<br />
| 02C0<br />
| [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]]<br />
| <br />
|PICA_REG_VS_FLOAT_ADDR<br />
|-<br />
| 02C1<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA1<br />
|-<br />
| 02C2<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA2<br />
|-<br />
| 02C3<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA3<br />
|-<br />
| 02C4<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA4<br />
|-<br />
| 02C5<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA5<br />
|-<br />
| 02C6<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA6<br />
|-<br />
| 02C7<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA7<br />
|-<br />
| 02C8<br />
| [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]]<br />
| <br />
|PICA_REG_VS_FLOAT_DATA8<br />
|-<br />
| 02C9<br />
| [[#GPUREG_02C9|GPUREG_02C9]]<br />
| <br />
|<br />
|-<br />
| 02CA<br />
| [[#GPUREG_02CA|GPUREG_02CA]]<br />
| <br />
|<br />
|-<br />
| 02CB<br />
| [[#GPUREG_VSH_CODETRANSFER_CONFIG|GPUREG_VSH_CODETRANSFER_CONFIG]]<br />
| ?<br />
|PICA_REG_VS_PROG_ADDR<br />
|-<br />
| 02CC<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA0<br />
|-<br />
| 02CD<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA1<br />
|-<br />
| 02CE<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA2<br />
|-<br />
| 02CF<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA3<br />
|-<br />
| 02D0<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA4<br />
|-<br />
| 02D1<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA5<br />
|-<br />
| 02D2<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA6<br />
|-<br />
| 02D3<br />
| [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_DATA7<br />
|-<br />
| 02D4<br />
| [[#GPUREG_02D4|GPUREG_02D4]]<br />
| <br />
|<br />
|-<br />
| 02D5<br />
| [[#GPUREG_VSH_OPDESCS_CONFIG|GPUREG_VSH_OPDESCS_CONFIG]]<br />
| ?<br />
|PICA_REG_VS_PROG_SWIZZLE_ADDR<br />
|-<br />
| 02D6<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA0<br />
|-<br />
| 02D7<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA1<br />
|-<br />
| 02D8<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA2<br />
|-<br />
| 02D9<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA3<br />
|-<br />
| 02DA<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA4<br />
|-<br />
| 02DB<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA5<br />
|-<br />
| 02DC<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA6<br />
|-<br />
| 02DD<br />
| [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]]<br />
| <br />
|PICA_REG_VS_PROG_SWIZZLE_DATA7<br />
|-<br />
! colspan=4 | Unknown registers<br />
|-<br />
| 02DE<br />
| [[#GPUREG_02DE|GPUREG_02DE]]<br />
| <br />
|<br />
|-<br />
| 02DF<br />
| [[#GPUREG_02DF|GPUREG_02DF]]<br />
| <br />
|<br />
|-<br />
| 02E0<br />
| [[#GPUREG_02E0|GPUREG_02E0]]<br />
| <br />
|<br />
|-<br />
| 02E1<br />
| [[#GPUREG_02E1|GPUREG_02E1]]<br />
| <br />
|<br />
|-<br />
| 02E2<br />
| [[#GPUREG_02E2|GPUREG_02E2]]<br />
| <br />
|<br />
|-<br />
| 02E3<br />
| [[#GPUREG_02E3|GPUREG_02E3]]<br />
| <br />
|<br />
|-<br />
| 02E4<br />
| [[#GPUREG_02E4|GPUREG_02E4]]<br />
| <br />
|<br />
|-<br />
| 02E5<br />
| [[#GPUREG_02E5|GPUREG_02E5]]<br />
| <br />
|<br />
|-<br />
| 02E6<br />
| [[#GPUREG_02E6|GPUREG_02E6]]<br />
| <br />
|<br />
|-<br />
| 02E7<br />
| [[#GPUREG_02E7|GPUREG_02E7]]<br />
| <br />
|<br />
|-<br />
| 02E8<br />
| [[#GPUREG_02E8|GPUREG_02E8]]<br />
| <br />
|<br />
|-<br />
| 02E9<br />
| [[#GPUREG_02E9|GPUREG_02E9]]<br />
| <br />
|<br />
|-<br />
| 02EA<br />
| [[#GPUREG_02EA|GPUREG_02EA]]<br />
| <br />
|<br />
|-<br />
| 02EB<br />
| [[#GPUREG_02EB|GPUREG_02EB]]<br />
| <br />
|<br />
|-<br />
| 02EC<br />
| [[#GPUREG_02EC|GPUREG_02EC]]<br />
| <br />
|<br />
|-<br />
| 02ED<br />
| [[#GPUREG_02ED|GPUREG_02ED]]<br />
| <br />
|<br />
|-<br />
| 02EE<br />
| [[#GPUREG_02EE|GPUREG_02EE]]<br />
| <br />
|<br />
|-<br />
| 02EF<br />
| [[#GPUREG_02EF|GPUREG_02EF]]<br />
| <br />
|<br />
|-<br />
| 02F0<br />
| [[#GPUREG_02F0|GPUREG_02F0]]<br />
| <br />
|<br />
|-<br />
| 02F1<br />
| [[#GPUREG_02F1|GPUREG_02F1]]<br />
| <br />
|<br />
|-<br />
| 02F2<br />
| [[#GPUREG_02F2|GPUREG_02F2]]<br />
| <br />
|<br />
|-<br />
| 02F3<br />
| [[#GPUREG_02F3|GPUREG_02F3]]<br />
| <br />
|<br />
|-<br />
| 02F4<br />
| [[#GPUREG_02F4|GPUREG_02F4]]<br />
| <br />
|<br />
|-<br />
| 02F5<br />
| [[#GPUREG_02F5|GPUREG_02F5]]<br />
| <br />
|<br />
|-<br />
| 02F6<br />
| [[#GPUREG_02F6|GPUREG_02F6]]<br />
| <br />
|<br />
|-<br />
| 02F7<br />
| [[#GPUREG_02F7|GPUREG_02F7]]<br />
| <br />
|<br />
|-<br />
| 02F8<br />
| [[#GPUREG_02F8|GPUREG_02F8]]<br />
| <br />
|<br />
|-<br />
| 02F9<br />
| [[#GPUREG_02F9|GPUREG_02F9]]<br />
| <br />
|<br />
|-<br />
| 02FA<br />
| [[#GPUREG_02FA|GPUREG_02FA]]<br />
| <br />
|<br />
|-<br />
| 02FB<br />
| [[#GPUREG_02FB|GPUREG_02FB]]<br />
| <br />
|<br />
|-<br />
| 02FC<br />
| [[#GPUREG_02FC|GPUREG_02FC]]<br />
| <br />
|<br />
|-<br />
| 02FD<br />
| [[#GPUREG_02FD|GPUREG_02FD]]<br />
| <br />
|<br />
|-<br />
| 02FE<br />
| [[#GPUREG_02FE|GPUREG_02FE]]<br />
| <br />
|<br />
|-<br />
| 02FF<br />
| [[#GPUREG_02FF|GPUREG_02FF]]<br />
| <br />
|<br />
|}<br />
<br />
=== GPUREG_FINALIZE ===<br />
<br />
Writing to this register seems to signal the GPU to stop processing GPU commands from the current buffer; any command following a write to this register will be ignored. The value written to this register does not appear to matter, although 0x12345678 is the value typically written by commercial software.<br />
Failure to write to this register in any command buffer will result in the GPU hanging.<br />
<br />
=== GPUREG_DEPTHBUFFER_FORMAT ===<br />
<br />
The format the current depth buffer should be written into. Following values are possible:<br />
<br />
{| class="wikitable" border="1"<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| 16-bit depth<br />
|-<br />
| 1<br />
| ?? seems to freeze the GPU<br />
|-<br />
| 2<br />
| 24-bit depth<br />
|-<br />
| 3<br />
| 24-bit depth + 8-bit stencil (stencil is within bit 24-31)<br />
|}<br />
<br />
=== GPUREG_COLORBUFFER_FORMAT ===<br />
<br />
Describes the format of the current color buffer used for 3D rendering.<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Pixel size (0=16-bit, 1=24-bit, 2=32-bit, 3=64-bit?)<br />
|-<br />
| 16-23<br />
| Framebuffer Format (0=GL_RGBA8, 1=GL_RGB8, 2=GL_RGB5_A1, 3=GL_R5_G6_B5, 4=GL_RGBA4).<br />
Note that these values are slightly different from those in [[GPU#Framebuffer_color_formats]].<br />
<br />
Color components are laid out in reverse byte order, with the most significant bits used first.<br />
|}<br />
<br />
=== GPUREG_GEOSTAGE_CONFIG ===<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Geometry stage mode. (0=Vertex shader only, 2=Vertex shader + geometry shader)<br />
|-<br />
| 0-7<br />
| Unknown. Often set to 1.<br />
|-<br />
| 0-7<br />
| Unknown.<br />
|-<br />
| 0-7<br />
| Unknown. Often set to 0.<br />
|}<br />
<br />
This register configures the geometry stage of the GPU pipeline.<br />
<br />
=== Geometry shader registers ===<br />
<br />
==== GPUREG_GSH_BOOLUNIFORM ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Value of geometry shader unit's b0 boolean register. (0=true, 1=false)<br />
|-<br />
| 1<br />
| Value of geometry shader unit's b1 boolean register. (0=true, 1=false)<br />
|-<br />
| 2<br />
| Value of geometry shader unit's b2 boolean register. (0=true, 1=false)<br />
|-<br />
| 3<br />
| Value of geometry shader unit's b3 boolean register. (0=true, 1=false)<br />
|-<br />
| 4<br />
| Value of geometry shader unit's b4 boolean register. (0=true, 1=false)<br />
|-<br />
| 5<br />
| Value of geometry shader unit's b5 boolean register. (0=true, 1=false)<br />
|-<br />
| 6<br />
| Value of geometry shader unit's b6 boolean register. (0=true, 1=false)<br />
|-<br />
| 7<br />
| Value of geometry shader unit's b7 boolean register. (0=true, 1=false)<br />
|-<br />
| 8<br />
| Value of geometry shader unit's b8 boolean register. (0=true, 1=false)<br />
|-<br />
| 9<br />
| Value of geometry shader unit's b9 boolean register. (0=true, 1=false)<br />
|-<br />
| 10<br />
| Value of geometry shader unit's b10 boolean register. (0=true, 1=false)<br />
|-<br />
| 11<br />
| Value of geometry shader unit's b11 boolean register. (0=true, 1=false)<br />
|-<br />
| 12<br />
| Value of geometry shader unit's b12 boolean register. (0=true, 1=false)<br />
|-<br />
| 13<br />
| Value of geometry shader unit's b13 boolean register. (0=true, 1=false)<br />
|-<br />
| 14<br />
| Value of geometry shader unit's b14 boolean register. (0=true, 1=false)<br />
|-<br />
| 15<br />
| Value of geometry shader unit's b15 boolean register. (0=true, 1=false)<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This register is used to set the geometry shader unit's boolean registers.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I0 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i0.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i0.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i0.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i0.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i0 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I1 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i1.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i1.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i1.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i1.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i1 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I2 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i2.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i2.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i2.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i2.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i2 integer register.<br />
<br />
==== GPUREG_GSH_INTUNIFORM_I3 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for geometry shader's i3.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for geometry shader's i3.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for geometry shader's i3.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for geometry shader's i3.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the geometry shader's i3 integer register.<br />
<br />
==== GPUREG_GSH_INPUTBUFFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Input buffer stride minus 1, in float vec4 registers. (value 0 means a stride of 1 float vec4 register)<br />
|-<br />
| 8-23<br />
| Unknown. These bits typically aren't updated by games.<br />
|-<br />
| 24-31<br />
| Unknown. This is typically set to 8 for geometry shaders.<br />
|}<br />
<br />
This register is used to configure the geometry shader's input buffer. In the context of a geometry shader, the stride parameter can be interpreted as the input primitive size in registers, though it is not a limit on the number of input registers which can be accessed from the geometry shader.<br />
<br />
<br />
==== GPUREG_GSH_ENTRYPOINT ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-15<br />
| Geometry shader unit entrypoint, in words.<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This sets the entrypoint for the program running on the single shader unit which can be dedicated to running geometry shaders, regardless of the current geometry stage mode. This is means that while this register is normally used to set the geometry shader entrypoint, it can also be used to set this single shader unit to run from a different entrypoint than the other three even when running a vertex shader.<br />
<br />
==== GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of geometry shader input register which the 1st attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of geometry shader input register which the 2nd attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of geometry shader input register which the 3rd attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of geometry shader input register which the 4th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of geometry shader input register which the 5th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of geometry shader input register which the 6th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of geometry shader input register which the 7th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of geometry shader input register which the 8th attribute will be stored in.<br />
|}<br />
<br />
This register sets the geometry shader input register index which will correspond to each attribute contained by the input buffer (which in the case of geometry shaders is the vertex shader output buffer) for the first 8 attributes.<br />
For example, having bits 0-3 set to 5 means that, in the geometry shader program, v5 will contain the input buffer's 1st attribute.<br />
<br />
==== GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of geometry shader input register which the 9th attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of geometry shader input register which the 10th attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of geometry shader input register which the 11th attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of geometry shader input register which the 12th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of geometry shader input register which the 13th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of geometry shader input register which the 14th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of geometry shader input register which the 15th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of geometry shader input register which the 16th attribute will be stored in.<br />
|}<br />
<br />
This register sets the geometry shader input register index which will correspond to each attribute contained by the input buffer (which in the case of geometry shaders is the vertex shader output buffer) for attributes 8 through 15.<br />
For example, having bits 0-3 set to 5 means that, in the geometry shader program, v5 will contain the input buffer's 9th attribute.<br />
<br />
==== GPUREG_GSH_OUTMAP_MASK ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Enable bit for geometry shader's o0 output register. (1 = o0 enabled, 0 = o0 disabled)<br />
|-<br />
| 1<br />
| Enable bit for geometry shader's o1 output register. (1 = o1 enabled, 0 = o1 disabled)<br />
|-<br />
| 2<br />
| Enable bit for geometry shader's o2 output register. (1 = o2 enabled, 0 = o2 disabled)<br />
|-<br />
| 3<br />
| Enable bit for geometry shader's o3 output register. (1 = o3 enabled, 0 = o3 disabled)<br />
|-<br />
| 4<br />
| Enable bit for geometry shader's o4 output register. (1 = o4 enabled, 0 = o4 disabled)<br />
|-<br />
| 5<br />
| Enable bit for geometry shader's o5 output register. (1 = o5 enabled, 0 = o5 disabled)<br />
|-<br />
| 6<br />
| Enable bit for geometry shader's o6 output register. (1 = o6 enabled, 0 = o6 disabled)<br />
|}<br />
<br />
This register toggles the geometry shader unit's output registers.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_END ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Code data transfer end signal bit.<br />
|}<br />
<br />
This register's value should be set to 1 in order to finalize the transfer of geometry shader code. It is unknown whether this register is used for other functions.<br />
<br />
==== GPUREG_GSH_FLOATUNIFORM_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target float vec4 geometry shader uniform ID for transfer. (range 0-95, where 0 = c0 and 95 = c95)<br />
|-<br />
| 31<br />
| Float vec4 geometry shader uniform data transfer mode. (0 = float24, 1 = float32)<br />
|}<br />
<br />
This register sets the target float vec4 geometry shader uniform ID and transfer mode for the data transfer system. As such it is typically used right before [[#GPUREG_GSH_FLOATUNIFORM_DATA|GPUREG_GSH_FLOATUNIFORM_DATA]], though writing to one register does not make writing to the other mandatory.<br />
<br />
==== GPUREG_GSH_FLOATUNIFORM_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Float vec4 geometry shader uniform data. (format depends on transfer mode, see below for details)<br />
|}<br />
<br />
This register is used to set the value of float vec4 geometry shader uniform registers. The data format which should be written to it depends on the transfer mode set with [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]]. This register functions as a FIFO queue : after each time a uniform register is successfully set, the target uniform ID value is incremented, meaning that groups of uniforms with contiguous register IDs can be set with only one initial write to [[#GPUREG_GSH_FLOATUNIFORM_CONFIG|GPUREG_GSH_FLOATUNIFORM_CONFIG]].<br />
<br />
* In the case of float24 transfer mode, data should be sent by writing three words which are the concatenation of the float24 value of the uniform register's 4 components, in the reverse order. Assuming each letter corresponds to 4 bits, the format becomes :<br />
** first word : ZZWWWWWW<br />
** second word : YYYYZZZZ<br />
** third word : XXXXXXYY<br />
* In the case of float32 transfer mode, data should be sent by writing four words which are each the float32 value of the uniform register's 4 components, in the reverse order.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-11<br />
| Target geometry shader code offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming geometry shader code data transferred through [[#GPUREG_GSH_CODETRANSFER_DATA|GPUREG_GSH_CODETRANSFER_DATA]] should be written.<br />
<br />
NOTE : as we do not yet know what a shader program's maximum size is yet, we also do not know how many bits the code offset parameter holds. The biggest shader binary observed so far was 2422 instructions long. The [[Shader_Instruction_Set#Instruction_formats|shader control flow instructions]] only have room to address 12 bits though, so it's likely that the maximum is 4095.<br />
<br />
==== GPUREG_GSH_CODETRANSFER_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Geometry shader instruction data.<br />
|}<br />
<br />
This register is used to transfer geometry shader code data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU geometry shader code memory bank at the offset initially set by [[#GPUREG_GSH_CODETRANSFER_CONFIG|GPUREG_GSH_CODETRANSFER_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
==== GPUREG_GSH_OPDESCS_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target geometry shader operand descriptor offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming geometry shader operand descriptor data transferred through [[#GPUREG_GSH_OPDESCS_DATA|GPUREG_GSH_OPDESCS_DATA]] should be written.<br />
<br />
==== GPUREG_GSH_OPDESCS_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Geometry shader operand descriptor data.<br />
|}<br />
<br />
This register is used to transfer geometry shader operand descriptor data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU geometry shader operand descriptor memory bank at the offset initially set by [[#GPUREG_GSH_OPDESCS_CONFIG|GPUREG_GSH_OPDESCS_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
=== Vertex shader registers ===<br />
<br />
==== GPUREG_VSH_BOOLUNIFORM ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Value of vertex shader unit's b0 boolean register. (0=true, 1=false)<br />
|-<br />
| 1<br />
| Value of vertex shader unit's b1 boolean register. (0=true, 1=false)<br />
|-<br />
| 2<br />
| Value of vertex shader unit's b2 boolean register. (0=true, 1=false)<br />
|-<br />
| 3<br />
| Value of vertex shader unit's b3 boolean register. (0=true, 1=false)<br />
|-<br />
| 4<br />
| Value of vertex shader unit's b4 boolean register. (0=true, 1=false)<br />
|-<br />
| 5<br />
| Value of vertex shader unit's b5 boolean register. (0=true, 1=false)<br />
|-<br />
| 6<br />
| Value of vertex shader unit's b6 boolean register. (0=true, 1=false)<br />
|-<br />
| 7<br />
| Value of vertex shader unit's b7 boolean register. (0=true, 1=false)<br />
|-<br />
| 8<br />
| Value of vertex shader unit's b8 boolean register. (0=true, 1=false)<br />
|-<br />
| 9<br />
| Value of vertex shader unit's b9 boolean register. (0=true, 1=false)<br />
|-<br />
| 10<br />
| Value of vertex shader unit's b10 boolean register. (0=true, 1=false)<br />
|-<br />
| 11<br />
| Value of vertex shader unit's b11 boolean register. (0=true, 1=false)<br />
|-<br />
| 12<br />
| Value of vertex shader unit's b12 boolean register. (0=true, 1=false)<br />
|-<br />
| 13<br />
| Value of vertex shader unit's b13 boolean register. (0=true, 1=false)<br />
|-<br />
| 14<br />
| Value of vertex shader unit's b14 boolean register. (0=true, 1=false)<br />
|-<br />
| 15<br />
| Value of vertex shader unit's b15 boolean register. (0=true, 1=false)<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This register is used to set the vertex shader unit's boolean registers.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I0 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i0.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i0.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i0.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i0.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i0 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I1 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i1.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i1.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i1.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i1.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i1 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I2 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i2.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i2.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i2.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i2.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i2 integer register.<br />
<br />
==== GPUREG_VSH_INTUNIFORM_I3 ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Value for vertex shader's i3.x (u8, 0-255)<br />
|-<br />
| 8-15<br />
| Value for vertex shader's i3.y (u8, 0-255)<br />
|-<br />
| 16-23<br />
| Value for vertex shader's i3.z (u8, 0-255)<br />
|-<br />
| 24-31<br />
| Value for vertex shader's i3.w (u8, 0-255)<br />
|}<br />
<br />
This register is used to set the vertex shader's i3 integer register.<br />
<br />
==== GPUREG_VSH_INPUTBUFFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-7<br />
| Input buffer stride minus 1, in float vec4 registers. (value 0 means a stride of 1 float vec4 register)<br />
|-<br />
| 8-23<br />
| Unknown. These bits typically aren't updated by games.<br />
|-<br />
| 24-31<br />
| Unknown. This is typically set to 0xA for vertex shaders.<br />
|}<br />
<br />
This register is used to configure the vertex shader's input buffer. In the context of a geometry shader, the stride parameter can be interpreted as the number of attributes per vertex.<br />
<br />
==== GPUREG_VSH_ENTRYPOINT ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-15<br />
| Vertex shader entrypoint, in words.<br />
|-<br />
| 16-31<br />
| Unknown. This seems to always be set to 0x7FFF, and other values may cause the GPU to hang<br />
|}<br />
<br />
This sets the entrypoint for the program running on shader units set to vertex shader mode. Depending on the current geometry stage mode this can include either all 4 shader units or just 3 of them.<br />
<br />
==== GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of vertex shader input register which the 1st attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of vertex shader input register which the 2nd attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of vertex shader input register which the 3rd attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of vertex shader input register which the 4th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of vertex shader input register which the 5th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of vertex shader input register which the 6th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of vertex shader input register which the 7th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of vertex shader input register which the 8th attribute will be stored in.<br />
|}<br />
<br />
This register sets the vertex shader input register index which will correspond to each attribute contained by the input buffer for the first 8 attributes.<br />
For example, having bits 0-3 set to 5 means that, in the vertex shader program, v5 will contain the input buffer's 1st attribute.<br />
<br />
==== GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-3<br />
| Index of vertex shader input register which the 9th attribute will be stored in.<br />
|-<br />
| 4-7<br />
| Index of vertex shader input register which the 10th attribute will be stored in.<br />
|-<br />
| 8-11<br />
| Index of vertex shader input register which the 11th attribute will be stored in.<br />
|-<br />
| 12-15<br />
| Index of vertex shader input register which the 12th attribute will be stored in.<br />
|-<br />
| 16-19<br />
| Index of vertex shader input register which the 13th attribute will be stored in.<br />
|-<br />
| 20-23<br />
| Index of vertex shader input register which the 14th attribute will be stored in.<br />
|-<br />
| 24-27<br />
| Index of vertex shader input register which the 15th attribute will be stored in.<br />
|-<br />
| 28-31<br />
| Index of vertex shader input register which the 16th attribute will be stored in.<br />
|}<br />
<br />
This register sets the vertex shader input register index which will correspond to each attribute contained by the input buffer for attributes 8 through 15.<br />
For example, having bits 0-3 set to 5 means that, in the vertex shader program, v5 will contain the input buffer's 9th attribute.<br />
<br />
==== GPUREG_VSH_OUTMAP_MASK ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Enable bit for vertex shader's o0 output register. (1 = o0 enabled, 0 = o0 disabled)<br />
|-<br />
| 1<br />
| Enable bit for vertex shader's o1 output register. (1 = o1 enabled, 0 = o1 disabled)<br />
|-<br />
| 2<br />
| Enable bit for vertex shader's o2 output register. (1 = o2 enabled, 0 = o2 disabled)<br />
|-<br />
| 3<br />
| Enable bit for vertex shader's o3 output register. (1 = o3 enabled, 0 = o3 disabled)<br />
|-<br />
| 4<br />
| Enable bit for vertex shader's o4 output register. (1 = o4 enabled, 0 = o4 disabled)<br />
|-<br />
| 5<br />
| Enable bit for vertex shader's o5 output register. (1 = o5 enabled, 0 = o5 disabled)<br />
|-<br />
| 6<br />
| Enable bit for vertex shader's o6 output register. (1 = o6 enabled, 0 = o6 disabled)<br />
|-<br />
| 7<br />
| Enable bit for vertex shader's o7 output register. (1 = o7 enabled, 0 = o7 disabled)<br />
|-<br />
| 8<br />
| Enable bit for vertex shader's o8 output register. (1 = o8 enabled, 0 = o8 disabled)<br />
|-<br />
| 9<br />
| Enable bit for vertex shader's o9 output register. (1 = o9 enabled, 0 = o9 disabled)<br />
|-<br />
| 10<br />
| Enable bit for vertex shader's o10 output register. (1 = o10 enabled, 0 = o10 disabled)<br />
|-<br />
| 11<br />
| Enable bit for vertex shader's o11 output register. (1 = o11 enabled, 0 = o11 disabled)<br />
|-<br />
| 12<br />
| Enable bit for vertex shader's o12 output register. (1 = o12 enabled, 0 = o12 disabled)<br />
|-<br />
| 13<br />
| Enable bit for vertex shader's o13 output register. (1 = o13 enabled, 0 = o13 disabled)<br />
|-<br />
| 14<br />
| Enable bit for vertex shader's o14 output register. (1 = o14 enabled, 0 = o14 disabled)<br />
|-<br />
| 15<br />
| Enable bit for vertex shader's o15 output register. (1 = o15 enabled, 0 = o15 disabled)<br />
|}<br />
<br />
This register toggles the vertex shader units' output registers.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_END ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0<br />
| Code data transfer end signal bit.<br />
|}<br />
<br />
This register's value should be set to 1 in order to finalize the transfer of vertex shader code. It is unknown whether this register is used for other functions.<br />
<br />
==== GPUREG_VSH_FLOATUNIFORM_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target float vec4 vertex shader uniform ID for transfer. (range 0-95, where 0 = c0 and 95 = c95)<br />
|-<br />
| 31<br />
| Float vec4 vertex shader uniform data transfer mode. (0 = float24, 1 = float32)<br />
|}<br />
<br />
This register sets the target float vec4 vertex shader uniform ID and transfer mode for the data transfer system. As such it is typically used right before [[#GPUREG_VSH_FLOATUNIFORM_DATA|GPUREG_VSH_FLOATUNIFORM_DATA]], though writing to one register does not make writing to the other mandatory.<br />
<br />
==== GPUREG_VSH_FLOATUNIFORM_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Float vec4 vertex shader uniform data. (format depends on transfer mode, see below for details)<br />
|}<br />
<br />
This register is used to set the value of float vec4 vertex shader uniform registers. The data format which should be written to it depends on the transfer mode set with [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]]. This register functions as a FIFO queue : after each time a uniform register is successfully set, the target uniform ID value is incremented, meaning that groups of uniforms with contiguous register IDs can be set with only one initial write to [[#GPUREG_VSH_FLOATUNIFORM_CONFIG|GPUREG_VSH_FLOATUNIFORM_CONFIG]].<br />
<br />
* In the case of float24 transfer mode, data should be sent by writing three words which are the concatenation of the float24 value of the uniform register's 4 components, in the reverse order. Assuming each letter corresponds to 4 bits, the format becomes :<br />
** first word : ZZWWWWWW<br />
** second word : YYYYZZZZ<br />
** third word : XXXXXXYY<br />
* In the case of float32 transfer mode, data should be sent by writing four words which are each the float32 value of the uniform register's 4 components, in the reverse order.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-11<br />
| Target vertex shader code offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming vertex shader code data transferred through [[#GPUREG_VSH_CODETRANSFER_DATA|GPUREG_VSH_CODETRANSFER_DATA]] should be written.<br />
<br />
NOTE : as we do not yet know what a shader program's maximum size is yet, we also do not know how many bits the code offset parameter holds. The biggest shader binary observed so far was 2422 instructions long. The [[Shader_Instruction_Set#Instruction_formats|shader control flow instructions]] only have room to address 12 bits though, so it's likely that the maximum is 4095.<br />
<br />
==== GPUREG_VSH_CODETRANSFER_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Vertex shader instruction data.<br />
|}<br />
<br />
This register is used to transfer vertex shader code data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU vertex shader code memory bank at the offset initially set by [[#GPUREG_VSH_CODETRANSFER_CONFIG|GPUREG_VSH_CODETRANSFER_CONFIG]]. The offset in question is incremented after each write to this register.<br />
<br />
==== GPUREG_VSH_OPDESCS_CONFIG ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-6<br />
| Target vertex shader operand descriptor offset for data transfer.<br />
|}<br />
<br />
This register is used to set the offset at which upcoming vertex shader operand descriptor data transferred through [[#GPUREG_VSH_OPDESCS_DATA|GPUREG_VSH_OPDESCS_DATA]] should be written.<br />
<br />
==== GPUREG_VSH_OPDESCS_DATA ====<br />
<br />
{| class="wikitable" border="1"<br />
! Bits<br />
! Description<br />
|-<br />
| 0-31<br />
| Vertex shader operand descriptor data.<br />
|}<br />
<br />
This register is used to transfer vertex shader operand descriptor data. This register behaves as a FIFO queue : each write to this register writes the provided value to the GPU vertex shader operand descriptor memory bank at the offset initially set by [[#GPUREG_VSH_OPDESCS_CONFIG|GPUREG_VSH_OPDESCS_CONFIG]]. The offset in question is incremented after each write to this register.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Automatic_System_Update_Download&diff=11827
Automatic System Update Download
2015-03-04T22:10:15Z
<p>Lectem: </p>
<hr />
<div>Beginning with the [[2.0.0-2]] update, system updates are automatically downloaded via the [[NIM_Services|NIM]] module. The system only downloads updates, Home Menu will only [[NIMU:FinishTitlesInstall|finalize]] update installation once the user gives permission for that(via the "Install system update" dialog). Each time the event handle from [[NIM_Services|NIMU]] command 0x00050000 is signaled, Home Menu uses [[NIM_Services|NIMU:GetState]] and [[NIMU:CheckSysupdateAvailable]] to check whether a system update is available. When an update is available Home Menu will then set some Home Menu state flags, which likely indicate that the "Install system update" dialog should be shown.<br />
<br />
The system checks for updates every 24 hours, then downloads all updated titles if an update is available. This is the same as doing a system update via [[System Settings]], except with this the update installation will not be finalized until [[Home Menu]] uses the [[NIMU:FinishTitlesInstall]] command.<br />
<br />
It is possible to erase this update data by entering the [[Recovery Mode]].</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Recovery_Mode&diff=11826
Recovery Mode
2015-03-04T22:02:09Z
<p>Lectem: Created page with "The recovery mode (also known as Safe Mode Boot) can be accessed when turning up the Nintendo 3DS while holding A+R+L+Up(DPad). This menu is made to update your Nintendo 3DS thro..."</p>
<hr />
<div>The recovery mode (also known as Safe Mode Boot) can be accessed when turning up the Nintendo 3DS while holding A+R+L+Up(DPad).<br />
This menu is made to update your Nintendo 3DS through internet, if an update previously failed.<br />
<br />
However it is possible to use this menu to delete the nagging update message if your console downloaded an update while in sleep mode. It is believed that this menu simply erases all update data, as it should normally be accessed when the update files are corrupted.</div>
Lectem
https://www.3dbrew.org/w/index.php?title=Homebrew_Applications&diff=11222
Homebrew Applications
2014-12-21T10:08:54Z
<p>Lectem: /* List */</p>
<hr />
<div>==Installing==<br />
Applications are installed by copying the necessary files to the 3ds/ folder in the root of the SD-card. Most applications come with two files:<br />
* boot.3dsx: The executable.<br />
* icon.bin: The icon/metadata.<br />
<br />
The [[Homebrew Launcher]] will scan the sdcard for all .3dsx files, but will only display an icon for those who have one according to the format described above.<br />
<br />
==List==<br />
{| class="wikitable" border="1"<br />
! Category<br />
! Name<br />
! Description<br />
! Author<br />
! Download<br />
! Open-Source<br />
|-<br />
| Launcher<br />
| [https://github.com/smealum/3ds_hb_menu The Homebrew Launcher]<br />
| The ninjhax homebrew launcher.<br />
| [[User:smea|smea]] et al.<br />
| [http://smealum.net/ninjhax/dl/hbmenu/boot.3dsx Here]<br />
| Yes<br />
|-<br />
| Demo<br />
| cubedemo<br />
| A short demo of Homebrew on 3ds with working sound.<br />
| [[User:plutoo|plutoo]]<br />
| [https://mega.co.nz/#!KUQFiQYA!pv8HDEyrmuX6Eyw2hW0opL7gf9Ztmjd9J5pPsvs_rD4 Here]<br />
| No<br />
|-<br />
| Game<br />
| [https://github.com/smealum/yeti3DS Yeti3DS]<br />
| A quick and dirty port of Derek Evans' Yeti3D software rendering engine.<br />
| [[User:smea|smea]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Game<br />
| [https://github.com/smealum/3dscraft 3DSCraft]<br />
| Minecraft clone.<br />
| [[User:smea|smea]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Game<br />
| [https://github.com/Steveice10/WorldOf3DSand World of 3DSand]<br />
| World of Sand clone.<br />
| [[User:Steveice10|Steveice10]]<br />
| [https://www.dropbox.com/s/91tqtydxpny9p1g/WorldOf3DSand.zip?dl=0 Here]<br />
| Yes<br />
|-<br />
| Emulator<br />
| [https://github.com/StapleButter/blargSnes blargSnes]<br />
| A Super Nintendo emulator.<br />
| StapleButter<br />
| [http://blargsnes.kuribo64.net/download/blargSnes_1.2.zip Here]<br />
| Yes<br />
|-<br />
| Emulator<br />
| [https://github.com/Drenn1/GameYob/tree/master/platform/3ds GameYob]<br />
| A Game Boy (Color) emulator.<br />
| Drenn<br />
| [https://dl.dropboxusercontent.com/u/100702766/gameyob/gameyob_3ds.zip Here]<br />
| Yes<br />
|-<br />
| Emulator<br />
| [https://github.com/st4rk/3DNES 3DNES]<br />
| An NES emulator.<br />
| St4rk<br />
| N/A<br />
| Yes<br />
|-<br />
| Emulator<br />
| [https://github.com/Steveice10/3DSGBA 3DSGBA]<br />
| A GBA emulator.<br />
| Steveice10<br />
| [https://www.dropbox.com/s/fraixj1fn9ql3w4/3DSGBA.zip?dl=0 Here]<br />
| Yes<br />
|-<br />
| Emulator<br />
| [https://github.com/xerpi/CHIP-3DS CHIP-3DS]<br />
| A simple and slow CHIP-8 emulator.<br />
| xerpi<br />
| [https://www.mediafire.com/?y94yjhzf70fsfsi Here]<br />
| Yes<br />
|-<br />
| Application<br />
| [https://github.com/smealum/ftPONY ftPONY]<br />
| A basic FTP server, useful for testing new homebrew versions without swapping the SD card.<br />
| [[User:smea|smea]]<br />
| [https://mega.co.nz/#!nchBkL7B!T3vXnX4q8Uwp6APYYTDSZi2bkm25la-Qyz6j4CjsllI Here]<br />
| Yes<br />
|-<br />
| Application<br />
| [https://github.com/mtheall/ftbrony ftBRONY]<br />
| An FTP server.<br />
| [[User:mtheall|mtheall]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Application<br />
| [https://github.com/plutooo/ctrrpc ctrrpc]<br />
| A small and easily extensible RPC server/client written in C/Python. Allows you to quickly poke service-commands and syscalls over wifi from a Python shell on your PC. Useful during reverse-engineering.<br />
| [[User:plutooo|plutoo]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Application<br />
| [https://github.com/yellows8/ctr-streaming-server ctr-streaming-server]<br />
| This is a server which runs on a 3DS, which receives audio/video for playback. This can also send [[HID_Shared_Memory|HID]] state to the client (see the README) when enabled. The included parse_hidstream tool can be used to parse that HID data to simulate keyboard/mouse input events, via Linux uinput.<br />
| [[User:yellows8|yellows8]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Application<br />
| [https://github.com/DownloadMii/DownloadMii DownloadMii]<br />
| This is a WIP homebrew online store.<br />
| [[User:filfat|filfat]]<br />
| N/A<br />
| Yes<br />
|-<br />
| Application<br />
| vid3o<br />
| A real video player for 3ds with support for many codecs.<br />
| [[User:ILOVEPIE|ILOVEPIE]]<br />
| N/A<br />
| Maybe<br />
|}</div>
Lectem