<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://xboxdevwiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Prehistoricman</id>
		<title>xboxdevwiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://xboxdevwiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Prehistoricman"/>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/Special:Contributions/Prehistoricman"/>
		<updated>2026-04-26T11:43:02Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.28.0</generator>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7425</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7425"/>
				<updated>2025-12-28T21:11:25Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: /* Internal registers */ Add reg 0xAA&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|AA||Audio (AC97 and I2S) enable. 1 = enabled. 0 = disabled.&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D1||Fan PWM duty cycle or fan DAC level. 0xFF = fan off. 0 = fan full speed.&lt;br /&gt;
|-&lt;br /&gt;
|D2 - D5||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|-&lt;br /&gt;
|D6 - D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D6 - D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|-&lt;br /&gt;
|EF||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|-&lt;br /&gt;
|F1 - F4||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GPIO mapping ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!GPIO port.pin!!Pin number!!GPIO pin name!!Notes&lt;br /&gt;
|-&lt;br /&gt;
|P0.0 || 59 || AUD_CLAMP ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.1 || 7 ||  EJTSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.2 || 6 ||  POWSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.3 || 28 ||  PSUON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.4 || 13 ||  VREGON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.5 || 26 ||  VPLLON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.6 || 32 ||  GPIO/FANOUT || FANOUT does not operate unless P0.6 is set high (regardless of open-drain/tri-state mode).&lt;br /&gt;
|-&lt;br /&gt;
|P0.7 || 33 ||  RTCACTIVE ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.0 || 5 ||  DVDEJECT ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.1 || 40 ||  XCALRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.2 || 35 ||  SCL ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.3 || 34 ||  SDA ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.4 || 65 ||  SMI* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.5 || 41 ||  SYSRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.6 || 11 ||  LEDGRN* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.7 || 12 ||  LEDRED* ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.0 || 14 ||  PSUGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.1 || 27 ||  VREGGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.2 || 42 ||  VMODE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.3 || 43 ||  VMODE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.4 || 44 ||  VMODE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.5 || 62 ||  TRAYSTATE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.6 || 61 ||  TRAYSTATE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.7 || 60 ||  TRAYSTATE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7424</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7424"/>
				<updated>2025-12-28T18:18:52Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D1||Fan PWM duty cycle or fan DAC level. 0xFF = fan off. 0 = fan full speed.&lt;br /&gt;
|-&lt;br /&gt;
|D2 - D5||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|-&lt;br /&gt;
|D6 - D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D6 - D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|-&lt;br /&gt;
|EF||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|-&lt;br /&gt;
|F1 - F4||Scratch spaced used by the serial debug ROM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GPIO mapping ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!GPIO port.pin!!Pin number!!GPIO pin name!!Notes&lt;br /&gt;
|-&lt;br /&gt;
|P0.0 || 59 || AUD_CLAMP ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.1 || 7 ||  EJTSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.2 || 6 ||  POWSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.3 || 28 ||  PSUON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.4 || 13 ||  VREGON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.5 || 26 ||  VPLLON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.6 || 32 ||  GPIO/FANOUT || FANOUT does not operate unless P0.6 is set high (regardless of open-drain/tri-state mode).&lt;br /&gt;
|-&lt;br /&gt;
|P0.7 || 33 ||  RTCACTIVE ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.0 || 5 ||  DVDEJECT ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.1 || 40 ||  XCALRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.2 || 35 ||  SCL ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.3 || 34 ||  SDA ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.4 || 65 ||  SMI* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.5 || 41 ||  SYSRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.6 || 11 ||  LEDGRN* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.7 || 12 ||  LEDRED* ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.0 || 14 ||  PSUGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.1 || 27 ||  VREGGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.2 || 42 ||  VMODE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.3 || 43 ||  VMODE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.4 || 44 ||  VMODE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.5 || 62 ||  TRAYSTATE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.6 || 61 ||  TRAYSTATE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.7 || 60 ||  TRAYSTATE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Memory&amp;diff=7416</id>
		<title>Memory</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Memory&amp;diff=7416"/>
				<updated>2025-08-12T15:43:34Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: /* I/O port map */ Add modchip IO port information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Xbox has 64MB Memory. This could be expanded to 128MB of memory on boards of revision 1.0-1.4 (Boards of revision 1.0-1.4 have empty spots for the extra memory, but they were later removed on 1.6 boards) but no games took advantage of it. The debug Xbox and the Chihiro both contained 128MB Memory.&lt;br /&gt;
&lt;br /&gt;
The memory was shared between the CPU and GPU. On the retail Xbox, the [[Flash ROM]] and [[MCPX ROM]] are also mapped to memory at the top 16 MiB and the top 512 Bytes respectively. However on Debug Xboxes and Chihiro, only the Flash is mapped as they don't contain an MCPX ROM.&lt;br /&gt;
&lt;br /&gt;
= Memory map =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Memory Type&lt;br /&gt;
! Retail Xbox Range&lt;br /&gt;
! Debug/Chihiro Range&lt;br /&gt;
|-&lt;br /&gt;
|Main Memory&lt;br /&gt;
|0x00000000 - 0x03FFFFFF&lt;br /&gt;
|0x00000000 - 0x07FFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|Shadow RAM&lt;br /&gt;
|0xF0000000 - 0xF3FFFFFF&lt;br /&gt;
|0xF0000000 - 0xF7FFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[GPU|GPU (NV2A) Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFD000000 - 0xFDFFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[APU|APU Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFE800000 - 0xFE87FFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[ACI|ACI (AC97) Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFEC00000 - 0xFEC00FFF&lt;br /&gt;
|-&lt;br /&gt;
|USB 0 Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFED00000 - 0xFED00FFF&lt;br /&gt;
|-&lt;br /&gt;
|USB 1 Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFED08000 - 0xFED08FFF&lt;br /&gt;
|-&lt;br /&gt;
|NIC (NVNet) Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFEF00000 - 0xFEF003FF&lt;br /&gt;
|-&lt;br /&gt;
|[[Flash ROM]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFF000000 - 0xFFFFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[MCPX ROM]]&lt;br /&gt;
|0xFFFFFE00 - 0xFFFFFFFF&lt;br /&gt;
|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= I/O port map =&lt;br /&gt;
{{FIXME|reason=Taken from the KVMBOX memorymap.txt, not confirmed}}&lt;br /&gt;
&lt;br /&gt;
Modchips often place control registers for LCD, bank selection, and other features in the range of 0xF000 - 0xF800 such as [https://bitbucket.org/prehistoricman/lpcmod_os/src/c6c5ceb04ad6c583b01522e58308f83254dbedb5/include/lpcmod_v1.h#lines-81:96 Xblast] and [https://github.com/Kekule-OXC/R3DUX/blob/main/Research/io%20registers.png Xecuter X3].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Device&lt;br /&gt;
! Retail Xbox Range&lt;br /&gt;
! Debug/Chihiro Range&lt;br /&gt;
|-&lt;br /&gt;
|DMA Channels 0-3&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0000 - 0x000F&lt;br /&gt;
|-&lt;br /&gt;
|Master PIC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0020 - 0x0021&lt;br /&gt;
|-&lt;br /&gt;
|[[Super I/O|Super I/O Configuration]]&lt;br /&gt;
|N/A&lt;br /&gt;
|0x002E - 0x002F&lt;br /&gt;
|-&lt;br /&gt;
|[[Porting an Operating System to the Xbox HOWTO #Timer Frequency|PIT]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0040 - 0x0043&lt;br /&gt;
|-&lt;br /&gt;
|[[17 Mistakes Microsoft Made in the Xbox Security System #The Xbox Hardware|A20 Gate]] / [[MCPX #Pin L21: PC Speaker|Speaker]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0060 - 0x006F&lt;br /&gt;
|-&lt;br /&gt;
|CMOS / RTC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0070 - 0x0073&lt;br /&gt;
|-&lt;br /&gt;
|DMA Page Address&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0080 - 0x008F&lt;br /&gt;
|-&lt;br /&gt;
|Slave PIC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00A0 - 0x00A1&lt;br /&gt;
|-&lt;br /&gt;
|DMA Channels 4-7&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00C0 - 0x00DF&lt;br /&gt;
|-&lt;br /&gt;
|FPU Error Control&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00F0 - 0x00F1&lt;br /&gt;
|-&lt;br /&gt;
|IDE&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x01F0 - 0x01F7&lt;br /&gt;
|-&lt;br /&gt;
|vesafb {{FIXME|reason=Does XGPU expose I/O ports?}}&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x03C0 - 0x03DF&lt;br /&gt;
|-&lt;br /&gt;
|IDE {{FIXME|reason=Really? This is rather one of FDC ports}}&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x03F6 - 0x03F6&lt;br /&gt;
|-&lt;br /&gt;
|[[Super I/O|Super I/O Serial]]&lt;br /&gt;
|N/A&lt;br /&gt;
|0x03F8 - 0x03FF&lt;br /&gt;
|-&lt;br /&gt;
|[[PCI|PCI Configuration]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0CF8 - 0x0CFF&lt;br /&gt;
|-&lt;br /&gt;
|[[SMBus|SMBus (I2C)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1000 - 0x100F&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|Modem (MC97)&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1080 - 0x10FF&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1400 - 0x14FF&lt;br /&gt;
|-&lt;br /&gt;
|[[PCI #00.01:0 - ISA Bridge|LPC PM]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x8000 - 0x80FF&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|[[SMBus|SMBus (I2C)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xC000 - 0xC00F&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xC200 - 0xC21F&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|[[ACI|ACI (AC97)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xD000 - 0xD0FF&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xD200 - 0xD27F&lt;br /&gt;
|-&lt;br /&gt;
|NIC (NVNet)&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xE000 - 0xE007&lt;br /&gt;
|-&lt;br /&gt;
|IDE&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFF60 - 0xFF6F&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Emulation =&lt;br /&gt;
Code for emulating the memory might consist of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef DEBUG || CHIHIRO&lt;br /&gt;
#define MEMORY_SIZE 128 * 1024 * 1024&lt;br /&gt;
int mcpx_active = 0;&lt;br /&gt;
#else&lt;br /&gt;
#define MEMORY_SIZE 64 * 1024 * 1024&lt;br /&gt;
int mcpx_active = 1;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#define FLASH_SIZE 256 * 1024&lt;br /&gt;
#define FLASH_MAP_SIZE 16 * 1024 * 1024&lt;br /&gt;
#define FLASH_MAP_ADDRESS (0xFFFFFFFF - FLASH_MAP_SIZE + 1)&lt;br /&gt;
&lt;br /&gt;
#define MCPX_SIZE   0x200&lt;br /&gt;
#define MCPX_MAP_ADDRESS (0xFFFFFFFF - MCPX_MAP_SIZE + 1)&lt;br /&gt;
&lt;br /&gt;
uint8_t memory[MEMORY_SIZE] = {0};&lt;br /&gt;
uint8_t flash[FLASH_SIZE] = {0};&lt;br /&gt;
uint8_t mcpx[MCPX_SIZE] = {0};&lt;br /&gt;
&lt;br /&gt;
uint8_t get_memory_byte(uint32_t location) {&lt;br /&gt;
    if (location &amp;lt; MEMORY_SIZE) {&lt;br /&gt;
        return memory[location];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mcpx_active &amp;amp;&amp;amp; location &amp;gt;= MCPX_MAP_ADDRESS) {&lt;br /&gt;
        return mcpx[location - MCPX_MAP_ADDRESS];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (location &amp;gt;= FLASH_MAP_ADDRESS) {&lt;br /&gt;
        return flash[(location - FLASH_MAP_ADDRESS) % FLASH_SIZE];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Memory in unspecified range: %08X\n&amp;quot;, location);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t get_memory_word(uint32_t location) {&lt;br /&gt;
    return get_memory_byte(location + 1) &amp;lt;&amp;lt; 8 | get_memory_byte(location);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t get_memory_dword(uint32_t location) {&lt;br /&gt;
    return get_memory_word(location + 2) &amp;lt;&amp;lt; 16 | get_memory_word(location);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void deactivate_mcpx() {&lt;br /&gt;
    mcpx_active = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7413</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7413"/>
				<updated>2025-07-10T00:27:36Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: /* GPIO mapping */ Add GPIO pin numbers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GPIO mapping ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!GPIO port.pin!!Pin number!!GPIO pin name!!Notes&lt;br /&gt;
|-&lt;br /&gt;
|P0.0 || 59 || AUD_CLAMP ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.1 || 7 ||  EJTSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.2 || 6 ||  POWSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.3 || 28 ||  PSUON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.4 || 13 ||  VREGON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.5 || 26 ||  VPLLON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.6 || 32 ||  GPIO/FANOUT || FANOUT does not operate unless P0.6 is set high (regardless of open-drain/tri-state mode).&lt;br /&gt;
|-&lt;br /&gt;
|P0.7 || 33 ||  RTCACTIVE ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.0 || 5 ||  DVDEJECT ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.1 || 40 ||  XCALRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.2 || 35 ||  SCL ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.3 || 34 ||  SDA ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.4 || 65 ||  SMI* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.5 || 41 ||  SYSRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.6 || 11 ||  LEDGRN* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.7 || 12 ||  LEDRED* ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.0 || 14 ||  PSUGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.1 || 27 ||  VREGGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.2 || 42 ||  VMODE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.3 || 43 ||  VMODE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.4 || 44 ||  VMODE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.5 || 62 ||  TRAYSTATE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.6 || 61 ||  TRAYSTATE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.7 || 60 ||  TRAYSTATE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7411</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7411"/>
				<updated>2025-06-20T13:20:14Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add GPIO mapping table&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GPIO mapping ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!GPIO port.pin!!GPIO pin name!!Notes&lt;br /&gt;
|-&lt;br /&gt;
|P0.0 || AUD_CLAMP ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.1 || EJTSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.2 || POWSW ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.3 || PSUON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.4 || VREGON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.5 || VPLLON ||&lt;br /&gt;
|-&lt;br /&gt;
|P0.6 || GPIO/FANOUT || FANOUT does not operate unless P0.6 is set high (regardless of open-drain/tri-state mode).&lt;br /&gt;
|-&lt;br /&gt;
|P0.7 || RTCACTIVE ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.0 || DVDEJECT ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.1 || XCALRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.2 || SCL ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.3 || SDA ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.4 || SMI* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.5 || SYSRESET* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.6 || LEDGRN* ||&lt;br /&gt;
|-&lt;br /&gt;
|P1.7 || LEDRED* ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.0 || PSUGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.1 || VREGGD ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.2 || VMODE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.3 || VMODE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.4 || VMODE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.5 || TRAYSTATE&amp;lt;0&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.6 || TRAYSTATE&amp;lt;1&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
|P2.7 || TRAYSTATE&amp;lt;2&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7410</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7410"/>
				<updated>2025-06-20T12:46:09Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Amending last edit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7409</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7409"/>
				<updated>2025-06-20T01:03:11Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add port registers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|80||Port 0 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|90||Port 1 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|9D||Port 0 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9E||Port 1 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|9F||Port 2 open drain mode. 0 = normal GPIO. 1 = open drain mode (pin is floating when output value == 1).&lt;br /&gt;
|-&lt;br /&gt;
|A0||Port 2 output value (write) and input value (read)&lt;br /&gt;
|-&lt;br /&gt;
|B0||Port 0 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|C0||Port 1 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||Port 2 tristate. 0 = output on. 1 = floating.&lt;br /&gt;
|-&lt;br /&gt;
|D8||GPIO port 2 related (seemingly related to reading pin states)&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7408</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7408"/>
				<updated>2025-05-28T18:22:40Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add some registers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|D7||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|D8||GPIO port 2 related (seemingly related to reading pin states)&lt;br /&gt;
|-&lt;br /&gt;
|D9 - DE||SMBus related&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|-&lt;br /&gt;
|EC||Flash program/erase control. Bits 3:0 determine the flash region to target. Bits 7:5 control the kind of operation. Bit 4 starts the operation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7407</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7407"/>
				<updated>2025-05-28T14:57:06Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Update spare sector sizes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 2KiB or 0.5KiB memory space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x80 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 512-byte spare sector 0&lt;br /&gt;
* 128-byte spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7406</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7406"/>
				<updated>2025-05-28T14:01:40Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Opcode 1E and 1F&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 1KiB or 0.5KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||67||2||Program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x400 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 1KiB spare sector 0&lt;br /&gt;
* 0.5KiB spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7405</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7405"/>
				<updated>2025-05-27T13:01:05Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 1KiB or 0.5KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Assumed to be program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x400 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB SMC debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 1KiB spare sector 0&lt;br /&gt;
* 0.5KiB spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7403</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7403"/>
				<updated>2025-05-27T13:00:14Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add info about spare sectors&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||4||2||Program 1 byte of spare sector 0 or 1. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 1KiB or 0.5KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes from spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Assumed to be program 64 bytes of spare sector 0 or 1&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F|| - || - ||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|88||4||2||Erase spare sector 0 (0x400 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|89||4||2||Erase spare sector 1 (0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|8C||4||2||Erase spare sector 0&lt;br /&gt;
|-&lt;br /&gt;
|8D||4||2||Erase spare sector 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* 1KiB spare sector 0&lt;br /&gt;
* 0.5KiB spare sector 1&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7402</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7402"/>
				<updated>2025-05-27T11:53:54Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add SMC sector erase command&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||?||?||Untested&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Possible write to unknown areas. Untested.&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||?||?||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F||?||?||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appears to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Sector erase BIOS flash. Sectors are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||4||2||Sector erase SMC flash. Sectors are 0x200 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* Unknown 512 and 1024 byte spaces&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7401</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7401"/>
				<updated>2025-05-27T02:55:08Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Commands table updates and corrections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Read 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Read 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43. Addresses are aliased within the 16KiB flash space.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||?||?||Untested&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Possible write to unknown areas. Untested.&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||?||?||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|22 and 23||4||2||Write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 1 byte of RAM/SFRs 64 times&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Possibly broken write of 64 bytes to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Duplicate of 20 and 21&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Duplicate of 22 and 23&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24 and 25&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F||?||?||Similar to 10 - 1F, but the data read is always 00. Write attempts with opcode 0x32 are always rejected.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appear to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80||4||2||Block erase BIOS flash. Blocks are 0x800 bytes.&lt;br /&gt;
|-&lt;br /&gt;
|81||?||?||Assumed to block erase SMC flash.&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash. Takes about 350ms.&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Mass erase SMC flash. Takes about 350ms.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 16KiB SMC flash&lt;br /&gt;
* 1KiB debug ROM (at address 0xFC00 in the SMC flash space)&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* Unknown 512 and 1024 byte spaces&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7400</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7400"/>
				<updated>2025-05-21T13:52:39Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add Revisions and Processor core sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Processor core ==&lt;br /&gt;
The embedded microcontroller that supports SMC functions is an 8051 core.&lt;br /&gt;
&lt;br /&gt;
== Debug serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Dump 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Dump 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash (untested). Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash (untested). Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||?||?||Untested&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Possible write to unknown areas. Untested.&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||?||?||Assumed to read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 64 bytes of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Assumed to write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Write 1 byte to RAM/SFRs. TODO: verify that 2A works in the same way&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F||?||?||Similar to 10 - 1F, but the data read is always 00. TODO: test if 32 is unlocked by opcode 0x43. TODO: dump whole area&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appear to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80 and 81||?||?||Could be another kind of erase, such as block or sector erase&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Assumed to mass erase SMC flash. Danger: might also erase the command handler code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 64KiB SMC flash&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* Unknown 512 and 1024 byte spaces&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
Known revisions are:&lt;br /&gt;
* Unlabelled - prototypes&lt;br /&gt;
* A-A02 - flashable&lt;br /&gt;
* A-B01 - not flashable&lt;br /&gt;
&lt;br /&gt;
The die and bonding of A-B01 looks identical to A-A02, so it is not currently understood what prevents it from being flashed. The program and erase commands still execute successfully but don't produce any change in memory contents.&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7399</id>
		<title>System Management Controller</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7399"/>
				<updated>2025-05-21T13:41:34Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The System Management Controller (SMC) is a PIC16LC63A-04/SO microcontroller which handles a variety of tasks on the Xbox.&lt;br /&gt;
This includes rebooting the system, returning the connected kind of video cable, the DVD tray state, controlling the fan, LED control and sensing temperature.&lt;br /&gt;
It is also the hardware which is connected to the Power and Eject buttons.&lt;br /&gt;
The PIC is running at 10 MHz and has an internal ROM and RAM.&lt;br /&gt;
&lt;br /&gt;
The PIC is always running, even if the Xbox is turned off. When the power cable is unplugged, it gets its energy from a capacitor for some hours. &lt;br /&gt;
&lt;br /&gt;
It is connected via I²C and located on address 0x10.&lt;br /&gt;
&lt;br /&gt;
== Xyclops ==&lt;br /&gt;
&lt;br /&gt;
The SMC on v1.6 Xboxes is a custom chip called [[Xyclops]]. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
Go to [[Xyclops]] for more details.&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
The chip is also marked with a revision.&lt;br /&gt;
Known revisions include:&lt;br /&gt;
&lt;br /&gt;
* P01 (v1.0)&lt;br /&gt;
* P05 (v1.1)&lt;br /&gt;
* P11 (v1.2 - 1.4)&lt;br /&gt;
* P2L (v1.6)&lt;br /&gt;
* D01 (Seen in a debug kit)&lt;br /&gt;
* D05 (seen in a earlier model chihiro)&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7398</id>
		<title>System Management Controller</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7398"/>
				<updated>2025-05-21T13:39:23Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The System Management Controller (SMC) is a PIC16LC63A-04/SO microcontroller which handles a variety of tasks on the Xbox.&lt;br /&gt;
This includes rebooting the system, returning the connected kind of video cable, the DVD tray state, controlling the fan, LED control and sensing temperature.&lt;br /&gt;
It is also the hardware which is connected to the Power and Eject buttons.&lt;br /&gt;
The PIC is running at 10 MHz and has an internal ROM and RAM.&lt;br /&gt;
&lt;br /&gt;
The PIC is always running, even if the Xbox is turned off. When the power cable is unplugged, it gets its energy from a capacitor for some hours. &lt;br /&gt;
&lt;br /&gt;
It is connected via I²C and located on address 0x10.&lt;br /&gt;
&lt;br /&gt;
== Xyclops ==&lt;br /&gt;
&lt;br /&gt;
The SMC on v1.6 Xboxes is a custom chip called [[Xyclops]]. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
Go to [[Xyclops]] for details on the debug UART interface.&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
The chip is also marked with a revision.&lt;br /&gt;
Known revisions include:&lt;br /&gt;
&lt;br /&gt;
* P01 (v1.0)&lt;br /&gt;
* P05 (v1.1)&lt;br /&gt;
* P11 (v1.2 - 1.4)&lt;br /&gt;
* P2L (v1.6)&lt;br /&gt;
* D01 (Seen in a debug kit)&lt;br /&gt;
* D05 (seen in a earlier model chihiro)&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7397</id>
		<title>Xyclops</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Xyclops&amp;diff=7397"/>
				<updated>2025-05-21T13:36:27Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Created page with &amp;quot;The SMC on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SMC]] on v1.6 Xboxes is a custom chip called Xyclops. It has a debug UART interface on pins 63 (RXD) and 64 (TXD) which can be used to read/write the BIOS flash, and the SMC's RAM, registers and flash.&lt;br /&gt;
&lt;br /&gt;
== Xyclops serial protocol ==&lt;br /&gt;
&lt;br /&gt;
9600 baud UART, enabled by setting the DEBUG pin (pin 29) high. Baud can be changed by writing to a register. The very first byte sent will cause Xyclops to enter debug mode where normal SMC operations are paused.&lt;br /&gt;
&lt;br /&gt;
The protocol is based on 4-byte or 67-byte commands. &lt;br /&gt;
# Byte 0 is the opcode. Bit 0 is often controlling a destination.&lt;br /&gt;
# Bytes 1 - 2 are the address. The most significant byte is sent first. Commands that don't address memory will ignore this.&lt;br /&gt;
# Byte 3 is the payload byte, or the first byte of the 64-byte payload for some commands.&lt;br /&gt;
&lt;br /&gt;
Each command will produce a response of at least 2 bytes.&lt;br /&gt;
# Byte 0 is the echo of the command byte, or 0x4B if the command is not accepted.&lt;br /&gt;
# Byte 1 is the response payload&lt;br /&gt;
# Bytes 2 - 64 are the rest of the payload for commands that respond with 64 bytes of data.&lt;br /&gt;
&lt;br /&gt;
=== Opcodes ===&lt;br /&gt;
&lt;br /&gt;
SFR = Special Function Register&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Opcode (hex)!!Length!!Response length!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|00 and 01||4||2||Read 1 byte of RAM&lt;br /&gt;
|-&lt;br /&gt;
|02 and 03||4||2||Write 1 byte to RAM&lt;br /&gt;
|-&lt;br /&gt;
|04 and 05||4||65||Read 1 byte of RAM 64 times (yes, really)&lt;br /&gt;
|-&lt;br /&gt;
|06 and 07||67||2||64-byte to something, possibly RAM.&lt;br /&gt;
|-&lt;br /&gt;
|08 and 09||4||2||Duplicate of 00&lt;br /&gt;
|-&lt;br /&gt;
|0A and 0B||4||2||Duplicate of 02&lt;br /&gt;
|-&lt;br /&gt;
|0C and 0D||4||65||Duplicate of 04&lt;br /&gt;
|-&lt;br /&gt;
|0E and 0F||67||2||Duplicate of 06&lt;br /&gt;
|-&lt;br /&gt;
|10||4||2||Dump 1 byte from the BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|11||4||2||Dump 1 byte from the SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|12||4||2||Program 1 byte of BIOS flash (untested). Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|13||4||2||Program 1 byte of SMC flash (untested). Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|14||4||65||Read 64 bytes of BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|15||4||65||Read 64 bytes of SMC flash&lt;br /&gt;
|-&lt;br /&gt;
|16||67||2||Program 64 bytes of BIOS flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|17||67||2||Program 64 bytes of SMC flash. Needs to be unlocked by opcode 0x43.&lt;br /&gt;
|-&lt;br /&gt;
|18 and 19||4||2||Read 1 byte of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1A and 1B||?||?||Untested&lt;br /&gt;
|-&lt;br /&gt;
|1C and 1D||4||65||Read 64 bytes of some unknown areas&lt;br /&gt;
|-&lt;br /&gt;
|1E and 1F||?||?||Possible write to unknown areas. Untested.&lt;br /&gt;
|-&lt;br /&gt;
|20 and 21||?||?||Assumed to read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|24 and 25||4||65||Read 64 bytes of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|26 and 27||?||?||Assumed to write 1 byte to RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|28 and 29||4||2||Read 1 byte of RAM/SFRs&lt;br /&gt;
|-&lt;br /&gt;
|2A and 2B||4||2||Write 1 byte to RAM/SFRs. TODO: verify that 2A works in the same way&lt;br /&gt;
|-&lt;br /&gt;
|2C and 2D||4||65||Duplicate of 24&lt;br /&gt;
|-&lt;br /&gt;
|2E and 2F||?||?||Assumed to be duplicate of 26&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || ---&lt;br /&gt;
|-&lt;br /&gt;
|30 to 3F||?||?||Similar to 10 - 1F, but the data read is always 00. TODO: test if 32 is unlocked by opcode 0x43. TODO: dump whole area&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|40||4||4 or 6||Exits and re-enters debug mode&lt;br /&gt;
|-&lt;br /&gt;
|41||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|42||4||2||Exits debug mode and locks programming&lt;br /&gt;
|-&lt;br /&gt;
|43||4||2||Unlocks programming and erasing flash&lt;br /&gt;
|-&lt;br /&gt;
|48 - 4A||4||2||Not sure, appear to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| --- || --- || --- || --- &lt;br /&gt;
|-&lt;br /&gt;
|80 and 81||?||?||Could be another kind of erase, such as block or sector erase&lt;br /&gt;
|-&lt;br /&gt;
|84||4||2||Mass erase BIOS flash&lt;br /&gt;
|-&lt;br /&gt;
|85||4||2||Assumed to mass erase SMC flash. Danger: might also erase the command handler code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xyclops memory spaces ==&lt;br /&gt;
&lt;br /&gt;
* 128-byte RAM (could be 256)&lt;br /&gt;
** Upper 128 bytes read out as semi-random values. The 8051 core would need a bank select to naturally access them.&lt;br /&gt;
* 64KiB SMC flash&lt;br /&gt;
* 256KiB BIOS flash (4 banks)&lt;br /&gt;
** Bank selected by register 0x91&lt;br /&gt;
* Unknown 512 and 1024 byte spaces&lt;br /&gt;
* 256-byte mixed RAM+SFR space (first 128 is RAM, second 128 is SFRs)&lt;br /&gt;
&lt;br /&gt;
== Xyclops internal registers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Address (hex)!!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|91||BIOS flash bank select. 0 - 3 for 256KiB.&lt;br /&gt;
|-&lt;br /&gt;
|E9||Debug serial baud control. Higher value = faster serial. 0xB0 = 9600. 0xEC = 38400 baud&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7393</id>
		<title>System Management Controller</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7393"/>
				<updated>2025-04-23T13:05:20Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Associate Xbox version with SMC version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The System Management Controller (SMC) is a PIC16LC63A-04/SO microcontroller which handles a variety of tasks on the Xbox.&lt;br /&gt;
This includes rebooting the system, returning the connected kind of video cable, the DVD tray state, controlling the fan, LED control and sensing temperature.&lt;br /&gt;
It is also the hardware which is connected to the Power and Eject buttons.&lt;br /&gt;
The PIC is running at 10 MHz and has an internal ROM and RAM.&lt;br /&gt;
&lt;br /&gt;
The PIC is always running, even if the Xbox is turned off. When the power cable is unplugged, it gets its energy from a capacitor for some hours. &lt;br /&gt;
&lt;br /&gt;
It is connected via I²C and located on address 0x10.&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
The chip is also marked with a revision.&lt;br /&gt;
Known revisions include:&lt;br /&gt;
&lt;br /&gt;
* P01 (v1.0)&lt;br /&gt;
* P05 (v1.1)&lt;br /&gt;
* P11 (v1.2 - 1.4)&lt;br /&gt;
* P2L (v1.6)&lt;br /&gt;
* D01 (Seen in a debug kit)&lt;br /&gt;
* D05 (seen in a earlier model chihiro)&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7391</id>
		<title>System Management Controller</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=System_Management_Controller&amp;diff=7391"/>
				<updated>2025-03-25T03:47:28Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Fix PIC clock speed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The System Management Controller (SMC) is a PIC16LC63A-04/SO microcontroller which handles a variety of tasks on the Xbox.&lt;br /&gt;
This includes rebooting the system, returning the connected kind of video cable, the DVD tray state, controlling the fan, LED control and sensing temperature.&lt;br /&gt;
It is also the hardware which is connected to the Power and Eject buttons.&lt;br /&gt;
The PIC is running at 10 MHz and has an internal ROM and RAM.&lt;br /&gt;
&lt;br /&gt;
The PIC is always running, even if the Xbox is turned off. When the power cable is unplugged, it gets its energy from a capacitor for some hours. &lt;br /&gt;
&lt;br /&gt;
It is connected via I²C and located on address 0x10.&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
The chip is also marked with a revision.&lt;br /&gt;
Known revisions include:&lt;br /&gt;
&lt;br /&gt;
* P01&lt;br /&gt;
* P05&lt;br /&gt;
* P11&lt;br /&gt;
* P2L{{citation needed}}&lt;br /&gt;
* D01 (Seen in a debug kit)&lt;br /&gt;
* D05 (seen in a earlier model chihiro)&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Flash_ROM&amp;diff=7361</id>
		<title>Flash ROM</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Flash_ROM&amp;diff=7361"/>
				<updated>2024-02-21T04:43:26Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add details about the addressing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Flash is a 256 kiB or 1 MiB [[Wikipedia:Flash_memory|non-volatile &amp;lt;abbr title=&amp;quot;Thin Small Outline Package&amp;quot;&amp;gt;TSOP&amp;lt;/abbr&amp;gt; ROM chip]] and connected to the [[MCPX]] via a parallel bus on [[hardware revisions]] 1.0 to 1.4. The 256 kiB ROM on revision 1.6 is stored in the Xcalibur chip, not a flash chip, and is connected to the [[MCPX]] via the [[Wikipedia:Low Pin Count|&amp;lt;abbr title=&amp;quot;Low Pin Count&amp;quot;&amp;gt;LPC&amp;lt;/abbr&amp;gt;]] bus (Xbox revision 1.6).&lt;br /&gt;
&lt;br /&gt;
The Flash ROM is mapped at physical addresses 0xFF000000 to 0xFFFFFFFF (revision 1.0) or 0xFFFFFDFF (revisions 1.1 - 1.6). The 256 kiB or 1 MiB ROM is [[Wikipedia:Aliasing (computing)#Hardware aliasing|aliased]] throughout this 16 MiB address range.&lt;br /&gt;
The ROM is commonly based in software at either 0xFFF00000 or 0xFFFC0000 as these are the addresses of the last alias for 1 MiB and 256 kiB respectively.&lt;br /&gt;
Due to [[Exploits#MIST hack|the MIST hack]], Microsoft blocked the use of flash ROM in the range of the [[MCPX ROM]] (0xFFFFFE00 - 0xFFFFFFFF) for revisions 1.1 to 1.6. Once the MCPX ROM is hidden, accessing this memory range will freeze the system.&lt;br /&gt;
&lt;br /&gt;
For the content of the Microsoft flash images see [[BIOS]].&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Flash_ROM&amp;diff=7360</id>
		<title>Flash ROM</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Flash_ROM&amp;diff=7360"/>
				<updated>2024-02-21T04:15:35Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Fix information about MCPX connection&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Flash is a 256 kiB or 1 MiB [[Wikipedia:Flash_memory|non-volatile &amp;lt;abbr title=&amp;quot;Thin Small Outline Package&amp;quot;&amp;gt;TSOP&amp;lt;/abbr&amp;gt; ROM chip]] and connected to the [[MCPX]] via a parallel bus on [[hardware revisions]] 1.0 to 1.4. The ROM on revision 1.6 is stored in the Xcalibur chip, not a flash chip, and is connected to the [[MCPX]] via the [[Wikipedia:Low Pin Count|&amp;lt;abbr title=&amp;quot;Low Pin Count&amp;quot;&amp;gt;LPC&amp;lt;/abbr&amp;gt;]] bus (Xbox revision 1.6).&lt;br /&gt;
&lt;br /&gt;
The Flash ROM is mapped at 0xFFF00000 (if the ROM is 1 MiB; 0xFFFC0000, if the ROM is 256 kiB) in the Xbox kernel. &lt;br /&gt;
&lt;br /&gt;
For the content of the Microsoft flash images see [[BIOS]].&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=Memory&amp;diff=7359</id>
		<title>Memory</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=Memory&amp;diff=7359"/>
				<updated>2024-02-20T23:59:31Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: Add shadow RAM to memory map&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Xbox has 64MB Memory. This could be expanded to 128MB of memory on boards of revision 1.0-1.4 (Boards of revision 1.0-1.4 have empty spots for the extra memory, but they were later removed on 1.6 boards) but no games took advantage of it. The debug Xbox and the Chihiro both contained 128MB Memory.&lt;br /&gt;
&lt;br /&gt;
The memory was shared between the CPU and GPU. On the retail Xbox, the [[Flash ROM]] and [[MCPX ROM]] are also mapped to memory at the top 16 MiB and the top 512 Bytes respectively. However on Debug Xboxes and Chihiro, only the Flash is mapped as they don't contain an MCPX ROM.&lt;br /&gt;
&lt;br /&gt;
= Memory map =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Memory Type&lt;br /&gt;
! Retail Xbox Range&lt;br /&gt;
! Debug/Chihiro Range&lt;br /&gt;
|-&lt;br /&gt;
|Main Memory&lt;br /&gt;
|0x00000000 - 0x03FFFFFF&lt;br /&gt;
|0x00000000 - 0x07FFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|Shadow RAM&lt;br /&gt;
|0xF0000000 - 0xF3FFFFFF&lt;br /&gt;
|0xF0000000 - 0xF7FFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[GPU|GPU (NV2A) Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFD000000 - 0xFDFFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[APU|APU Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFE800000 - 0xFE87FFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[ACI|ACI (AC97) Registers]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFEC00000 - 0xFEC00FFF&lt;br /&gt;
|-&lt;br /&gt;
|USB 0 Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFED00000 - 0xFED00FFF&lt;br /&gt;
|-&lt;br /&gt;
|USB 1 Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFED08000 - 0xFED08FFF&lt;br /&gt;
|-&lt;br /&gt;
|NIC (NVNet) Registers&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFEF00000 - 0xFEF003FF&lt;br /&gt;
|-&lt;br /&gt;
|[[Flash ROM]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFF000000 - 0xFFFFFFFF&lt;br /&gt;
|-&lt;br /&gt;
|[[MCPX ROM]]&lt;br /&gt;
|0xFFFFFE00 - 0xFFFFFFFF&lt;br /&gt;
|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= I/O port map =&lt;br /&gt;
{{FIXME|reason=Taken from the KVMBOX memorymap.txt, not confirmed}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Device&lt;br /&gt;
! Retail Xbox Range&lt;br /&gt;
! Debug/Chihiro Range&lt;br /&gt;
|-&lt;br /&gt;
|DMA Channels 0-3&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0000 - 0x000F&lt;br /&gt;
|-&lt;br /&gt;
|Master PIC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0020 - 0x0021&lt;br /&gt;
|-&lt;br /&gt;
|[[Super I/O|Super I/O Configuration]]&lt;br /&gt;
|N/A&lt;br /&gt;
|0x002E - 0x002F&lt;br /&gt;
|-&lt;br /&gt;
|[[Porting an Operating System to the Xbox HOWTO #Timer Frequency|PIT]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0040 - 0x0043&lt;br /&gt;
|-&lt;br /&gt;
|[[17 Mistakes Microsoft Made in the Xbox Security System #The Xbox Hardware|A20 Gate]] / [[MCPX #Pin L21: PC Speaker|Speaker]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0060 - 0x006F&lt;br /&gt;
|-&lt;br /&gt;
|CMOS / RTC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0070 - 0x0073&lt;br /&gt;
|-&lt;br /&gt;
|DMA Page Address&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0080 - 0x008F&lt;br /&gt;
|-&lt;br /&gt;
|Slave PIC&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00A0 - 0x00A1&lt;br /&gt;
|-&lt;br /&gt;
|DMA Channels 4-7&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00C0 - 0x00DF&lt;br /&gt;
|-&lt;br /&gt;
|FPU Error Control&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x00F0 - 0x00F1&lt;br /&gt;
|-&lt;br /&gt;
|IDE&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x01F0 - 0x01F7&lt;br /&gt;
|-&lt;br /&gt;
|vesafb {{FIXME|reason=Does XGPU expose I/O ports?}}&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x03C0 - 0x03DF&lt;br /&gt;
|-&lt;br /&gt;
|IDE {{FIXME|reason=Really? This is rather one of FDC ports}}&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x03F6 - 0x03F6&lt;br /&gt;
|-&lt;br /&gt;
|[[Super I/O|Super I/O Serial]]&lt;br /&gt;
|N/A&lt;br /&gt;
|0x03F8 - 0x03FF&lt;br /&gt;
|-&lt;br /&gt;
|[[PCI|PCI Configuration]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x0CF8 - 0x0CFF&lt;br /&gt;
|-&lt;br /&gt;
|[[SMBus|SMBus (I2C)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1000 - 0x100F&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|Modem (MC97)&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1080 - 0x10FF&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x1400 - 0x14FF&lt;br /&gt;
|-&lt;br /&gt;
|[[PCI #00.01:0 - ISA Bridge|LPC PM]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0x8000 - 0x80FF&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|[[SMBus|SMBus (I2C)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xC000 - 0xC00F&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xC200 - 0xC21F&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|[[ACI|ACI (AC97)]]&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xD000 - 0xD0FF&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xD200 - 0xD27F&lt;br /&gt;
|-&lt;br /&gt;
|NIC (NVNet)&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xE000 - 0xE007&lt;br /&gt;
|-&lt;br /&gt;
|IDE&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|0xFF60 - 0xFF6F&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Emulation =&lt;br /&gt;
Code for emulating the memory might consist of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef DEBUG || CHIHIRO&lt;br /&gt;
#define MEMORY_SIZE 128 * 1024 * 1024&lt;br /&gt;
int mcpx_active = 0;&lt;br /&gt;
#else&lt;br /&gt;
#define MEMORY_SIZE 64 * 1024 * 1024&lt;br /&gt;
int mcpx_active = 1;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#define FLASH_SIZE 256 * 1024&lt;br /&gt;
#define FLASH_MAP_SIZE 16 * 1024 * 1024&lt;br /&gt;
#define FLASH_MAP_ADDRESS (0xFFFFFFFF - FLASH_MAP_SIZE + 1)&lt;br /&gt;
&lt;br /&gt;
#define MCPX_SIZE   0x200&lt;br /&gt;
#define MCPX_MAP_ADDRESS (0xFFFFFFFF - MCPX_MAP_SIZE + 1)&lt;br /&gt;
&lt;br /&gt;
uint8_t memory[MEMORY_SIZE] = {0};&lt;br /&gt;
uint8_t flash[FLASH_SIZE] = {0};&lt;br /&gt;
uint8_t mcpx[MCPX_SIZE] = {0};&lt;br /&gt;
&lt;br /&gt;
uint8_t get_memory_byte(uint32_t location) {&lt;br /&gt;
    if (location &amp;lt; MEMORY_SIZE) {&lt;br /&gt;
        return memory[location];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mcpx_active &amp;amp;&amp;amp; location &amp;gt;= MCPX_MAP_ADDRESS) {&lt;br /&gt;
        return mcpx[location - MCPX_MAP_ADDRESS];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (location &amp;gt;= FLASH_MAP_ADDRESS) {&lt;br /&gt;
        return flash[(location - FLASH_MAP_ADDRESS) % FLASH_SIZE];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Memory in unspecified range: %08X\n&amp;quot;, location);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t get_memory_word(uint32_t location) {&lt;br /&gt;
    return get_memory_byte(location + 1) &amp;lt;&amp;lt; 8 | get_memory_byte(location);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t get_memory_dword(uint32_t location) {&lt;br /&gt;
    return get_memory_word(location + 2) &amp;lt;&amp;lt; 16 | get_memory_word(location);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void deactivate_mcpx() {&lt;br /&gt;
    mcpx_active = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	<entry>
		<id>https://xboxdevwiki.net/index.php?title=The_Hidden_Boot_Code_of_the_Xbox&amp;diff=7358</id>
		<title>The Hidden Boot Code of the Xbox</title>
		<link rel="alternate" type="text/html" href="https://xboxdevwiki.net/index.php?title=The_Hidden_Boot_Code_of_the_Xbox&amp;diff=7358"/>
				<updated>2024-02-20T23:05:20Z</updated>
		
		<summary type="html">&lt;p&gt;Prehistoricman: MIST hack is fixed on 1.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{retrieved|https://web.archive.org/web/20100617012156/http://www.xbox-linux.org/wiki/The_Hidden_Boot_Code_of_the_Xbox|ours=MCPX ROM}}&lt;br /&gt;
&lt;br /&gt;
or '''&amp;quot;How to fit three bugs in 512 bytes of security code&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
by [https://web.archive.org/web/20100617012156/http://www.xbox-linux.org/wiki/User:Michael_Steil Michael Steil]&lt;br /&gt;
&lt;br /&gt;
Note: This article is partially incomplete. It is superseded by the more detailed article [https://web.archive.org/web/20100617012156/http://www.xbox-linux.org/wiki/The_Hidden_Boot_Code_of_the_Xbox 17 Mistakes Microsoft Made in the Xbox Security System]&lt;br /&gt;
&lt;br /&gt;
In order to lock out both copied games as well as homebrew software, including the GNU/Linux operating system, Microsoft built a chain of trust on the Xbox reaching from the hardware to the execution of game code, in order to avoid the infiltration of code that has not been authorized by Microsoft. The link between hardware and software in this chain of trust is the hidden &amp;quot;MCPX&amp;quot; boot ROM. The principles, the implementations and the security vulnerabilities of this 512 bytes ROM will be discussed in this article.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot;&amp;gt;'''Missing image'''&amp;lt;br /&amp;gt;''Chain_Of_Trust.png'' &amp;lt;br /&amp;gt;Image:Chain Of Trust.png&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In short: The memory limitations in the hidden ROM made the system vulnerable in principle. A terribly wrong design and three bugs in the implementation opened three independent backdoors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Why a Hidden ROM is Needed ==&lt;br /&gt;
&lt;br /&gt;
The Xbox is an IBM PC, i.e. it has an x86 CPU. When the machine is turned on, it starts execution 16 bytes from the top of its address space, at the address FFFF_FFF0 (F000:FFF0 in 8086 segment:offset notation). On an IBM PC, the upper 64 KB (or more) of the address space are occupied by the BIOS ROM, so the CPU starts execution in this ROM.&lt;br /&gt;
&lt;br /&gt;
The Xbox, having an external (reprogrammable) 1 MB Flash ROM chip (models since 2003 have only 256 KB), would normally start running code there as well, since this megabyte is also mapped into the uppermost area of the address space. But this would make it too easy for someone who wants to either replace the ROM image with a self-written one or patch it to break the chain of trust (&amp;quot;modchips&amp;quot;). If the ROM image could be fully accessed, it would be easy to reverse-engineer the code; encryption and obfuscation would only slow down the hacking process a bit.&lt;br /&gt;
&lt;br /&gt;
A common idea to make the code inaccessible is not to put it into an external chip, but integrate it into one of the other chips. Then there is no standard way to extract the data, and none to replace the chip with one with different contents. But this way, it is a lot more expensive, both the design of a chip that includes both ROM and additional logic, and updating the ROM in a new version of the Xbox if there is a flaw in the ROM.&lt;br /&gt;
&lt;br /&gt;
A good compromise is to store only a small amount of code in one of the other chips, and store the bulk of it in the external Flash chip. This small ROM can not be extracted easily, and it cannot be changed or replaced. The code in there just has to make sure that an attacker can neither understand nor successfully patch the bulk of the code he has access to, which is stored in Flash ROM.&lt;br /&gt;
&lt;br /&gt;
Microsoft decided to go this way, and they stored 512 bytes of code in the Xbox' Southbridge, the MCPX (Media and Communications Processor for Xbox), which is manufactured by nVidia. This code is supposed to be mapped into the uppermost 512 bytes of the address space, overriding the Flash ROM at this position, so that the CPU starts execution there. It includes x86 code for a decryption function with a secret key that makes the CPU decipher (parts of the) &amp;quot;unsafe&amp;quot; code in the Flash ROM into RAM and run it. Without knowing the key, it is practically impossible to understand or even patch the encrypted code in Flash ROM.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Code in the Hidden ROM ==&lt;br /&gt;
&lt;br /&gt;
ROM in a multifunction IC is expensive, therefore it has to be small. Microsoft decided it to be only 512 bytes. Microsoft's implementation of the RC4 decryption algorithm fits well in about 150 bytes, so, at first inspection, this should be no problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The 512 Bytes problem ===&lt;br /&gt;
&lt;br /&gt;
But it is. When the CPU starts up, we cannot simply start decrypting data from flash ROM into RAM. We have to&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* initialize the CPU (32 bit mode, caching, segmenting)&lt;br /&gt;
* initialize the chipset and RAM so that the machine is in a stable state&lt;br /&gt;
&lt;br /&gt;
While the CPU initialization can be done in less than 150 bytes, the initialization of the chipset and RAM, if done completely, will require more than 1000 bytes of assembly code. Even at a minimum, Microsoft probably did not see a way to fit all this into these 512 bytes.&lt;br /&gt;
&lt;br /&gt;
Therefore it was decided to store some initialization tables in Flash ROM. The Southbridge was modified to read these tables even before the CPU starts running, and to pass these values to the Northbridge and Southbridge components. These tables are fetched from the very beginning of Flash ROM (FFF0_0000) and are 52 bytes long.&lt;br /&gt;
&lt;br /&gt;
But these tables are not enough for full hardware initialization. Tables are just not powerful enough - for memory initialization, memory stability tests have to be made. Putting some x86 code to do this into Flash ROM would pervert the security system, because a hacker could then easily put his own code there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Xcodes ===&lt;br /&gt;
&lt;br /&gt;
Microsoft decided to create a simple virtual machine that was well-suited for running hardware initialization code, but not much else. They created a tiny interpreter that understands 12 statements, but is not supposed to be powerful enough to take over the machine. As it is secure, this bytecode, called Xcode by the hackers that discovered it, can then be stored in Flash ROM. So the hidden ROM initializes the CPU, interprets the Xcodes stored in Flash ROM to set up the machine and then decrypts and runs x86 code from Flash ROM.&lt;br /&gt;
&lt;br /&gt;
The Xcodes start at FFF0_0080 (at 128 bytes) in Flash ROM. As the Flash can be easily updated in newer revisions of the Xbox, their size needn't be constant; they are typically about 3000 bytes in size, which is about 330 statements.&lt;br /&gt;
&lt;br /&gt;
An Xcode consists of an 8 bit statement, always followed by two 32 bit operands. The virtual machine has a 32 bit accumulator. The following table summarizes possible instructions; all other codes are treated as NOP:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  0x02&lt;br /&gt;
|  PEEK&lt;br /&gt;
|  ACC&amp;amp;nbsp;:= MEM[OP1]&lt;br /&gt;
|-&lt;br /&gt;
|  0x03&lt;br /&gt;
|  POKE&lt;br /&gt;
|  MEM[OP1]&amp;amp;nbsp;:= OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x04&lt;br /&gt;
|  POKEPCI&lt;br /&gt;
|  PCICONF[OP1]	:= OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x05&lt;br /&gt;
|  PEEKPCI&lt;br /&gt;
|  ACC&amp;amp;nbsp;:= PCICONF[OP1]&lt;br /&gt;
|-&lt;br /&gt;
|  0x06&lt;br /&gt;
|  AND/OR&lt;br /&gt;
|  ACC&amp;amp;nbsp;:= (ACC &amp;amp;amp; OP1) 	OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x07&lt;br /&gt;
|  (prefix)&lt;br /&gt;
|  execute the instruction code in OP1 with OP1&amp;amp;nbsp;:= OP2, OP2&amp;amp;nbsp;:= ACC&lt;br /&gt;
|-&lt;br /&gt;
|  0x08&lt;br /&gt;
|  BNE&lt;br /&gt;
|  IF ACC = OP1	THEN PC	:= PC +	OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x09&lt;br /&gt;
|  BRA&lt;br /&gt;
|  PC&amp;amp;nbsp;:= PC + OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x10&lt;br /&gt;
|  AND/OR ACC2&lt;br /&gt;
|  ''(unused/defunct)'' ACC2&amp;amp;nbsp;:= (ACC2 &amp;amp;amp; OP1)  OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x11&lt;br /&gt;
|  OUTB&lt;br /&gt;
|  PORT[OP1]&amp;amp;nbsp;:=	OP2&lt;br /&gt;
|-&lt;br /&gt;
|  0x12&lt;br /&gt;
|  INB&lt;br /&gt;
|  ACC&amp;amp;nbsp;:= PORT(OP1)&lt;br /&gt;
|-&lt;br /&gt;
|  0xEE&lt;br /&gt;
|  END&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
So the interpreter, rewritten in C, looks roughly like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;struct {&lt;br /&gt;
    char opcode;&lt;br /&gt;
    int op1;&lt;br /&gt;
    int op2;&lt;br /&gt;
} *p;&lt;br /&gt;
int acc;&lt;br /&gt;
&lt;br /&gt;
p = 0xFFF00080;&lt;br /&gt;
&lt;br /&gt;
while(1) {&lt;br /&gt;
    switch(p-&amp;amp;gt;opcode) {&lt;br /&gt;
        case 2:&lt;br /&gt;
            acc = *((int*)p-&amp;amp;gt;op1);&lt;br /&gt;
            break;&lt;br /&gt;
        case 3:&lt;br /&gt;
            *((int*)p-&amp;amp;gt;op1) = p-&amp;amp;gt;op2;&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            outl(p-&amp;amp;gt;op1, 0x0CF8);&lt;br /&gt;
            outl(p-&amp;amp;gt;op2, 0x0CFC);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            ...&lt;br /&gt;
        case 0xEE:&lt;br /&gt;
            goto end;&lt;br /&gt;
    }&lt;br /&gt;
    p++;&lt;br /&gt;
}&lt;br /&gt;
end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PEEK and POKE read from and write constants to main memory. OUTB and INB do the same with 8 bit I/O ports. (I/O ports are another address space, 16 bit wide, next to the 32 bit memory address space. While most other CPU architectures control hardware by accessing their registers as if they were memory, the Intel architecture can access some older components through specialized in/out assembly instructions.) POKEPCI and PEEKPCI access the PCI configuration area, by sending the PCI config address to 32 bit I/O port 0xCF8 and accessing the value at 32 bit I/O port 0xCFC. (On PCI-equipped computers, every PCI device has at least 64 bytes of PCI config registers. On a PC, the BIOS or a Plug-and-Play operating system communicates through these registers to find out what resources (memory, I/O ports, interrupts) a device needs and then maps these resources. The I/O ports 0xCF8/0xCFC are the communication mechanism for the PCI config space on PCs.)&lt;br /&gt;
&lt;br /&gt;
The AND/OR instruction can do a 32 bit AND or OR or both at the same time with the accumulator. BNE branches if the accumulator is equal to a constant, BRA branches always. The prefix 0x07 can be used to execute any of the other statements with the accumulator as the second operand. This way, &amp;quot;POKE addr, ACC&amp;quot;, &amp;quot;POKEPCI addr, ACC&amp;quot;, &amp;quot;BNE PC+ACC&amp;quot;, &amp;quot;BRA PC+ACC&amp;quot; and &amp;quot;OUT addr, ACC&amp;quot; are possible. The code 0x07 is handled by the interpreter, and uses a second accumulator, but this code is never used by the Xcodes. The code 0xEE ends the interpreter and makes the hidden ROM go on with the RC4 decryption.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== RC4 decryption, validity check and panic code ===&lt;br /&gt;
&lt;br /&gt;
After the Xcodes have completed the hardware setup, the machine is in a stable state, so that it is possible to decrypt parts of the Flash ROM directly into RAM and run it there. As mentioned earlier, the RC4 code including the key is about 150 bytes in size. The Xcode interpreter is about 175 bytes, and CPU init about 145 bytes. This leaves only about 40 bytes for a check whether decryption was successful and halt the machine otherwise.&lt;br /&gt;
&lt;br /&gt;
This seems not to have been enough space for Microsoft's engineers to implement a small checksum routine, so they only checked for one 32 bit constant (0x7854794A) at the end of the decrypted data in RAM (0x0009_5FE4). If this is successful, the CPU jumps to 0x9_0000 in RAM, where the new code has been written. This code, the &amp;quot;second bootloader&amp;quot; (&amp;quot;2bl&amp;quot;) is about 25 KB in size. It continues initializing the hardware and decompresses the kernel from Flash ROM.&lt;br /&gt;
&lt;br /&gt;
If the decrypted value is not correct, the CPU is supposed to halt. Simply using the &amp;quot;hlt&amp;quot; opcode would mean that the machine would remain turned on and idle with the hidden ROM visible in the address space. A hacker could then use some hardware attached to the chipset that extracts the data from ROM from a running machine. The designers therefore decided to always turn off the hidden ROM as soon as possible in both branches, when decryption was successful (then it is turned off as one of the first instructions in the &amp;quot;2bl&amp;quot; code), and if it wasn't.&lt;br /&gt;
&lt;br /&gt;
But making the CPU crash and turning off the ROM it is running in is a challenge. If we halt the CPU, we cannot turn off the ROM afterwards. If we turn off the ROM, we turn off the code that gets run and we cannot halt the CPU - even worse, the CPU would continue fetching its opcodes from the underlying Flash ROM as soon as the hidden ROM is deactivated.&lt;br /&gt;
&lt;br /&gt;
Microsoft's developers came up with a very interesting trick: They led execution to the absolute top of the address space, and as the very last instruction, they turn off the hidden ROM. Then the instruction pointer is supposed to overflow from FFFF_FFFF to 0000_0000 and an exception is supposed to be generated which in turn is supposed to halt the CPU because no exception handler is registered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;https://web.archive.org/web/20100617012156im_/http://www.xbox-linux.org/pic/memorymap.png&amp;quot; alt=&amp;quot;memorymap.png&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Issues ==&lt;br /&gt;
&lt;br /&gt;
This system looks pretty secure. If we don't know what's going on, it is a lot of work to find out that there is a hidden boot ROM (but it's easy to prove because the Xbox still boots if you overwrite the upper 512 bytes of Flash ROM since they never get used). If we don't have access to the boot ROM, we cannot decrypt and thus cannot understand the code in Flash ROM. Because we don't know how to reencrypt, we cannot patch the code in Flash.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Importance of the Secret Key ===&lt;br /&gt;
&lt;br /&gt;
But what happens if someone finds out the hidden 512 bytes? [https://web.archive.org/web/20100617012156/http://www.xenatera.com/bunnie/proj/anatak/xboxmod.html Bunnie] did, Christmas 2001. He tapped the bus between the Southbridge (where the secret MCPX code is stored) and the Northbridge (the CPU's memory interface) where all secret data gets transmitted. The compromise to store the secret ROM in the MCPX instead of the CPU, so that data would travel over a bus, finally broke the system. Knowing the algorithm and the secret key, he could easily disassemble the whole code in Flash ROM, and he could have even patched and reencrypted the code - the decryption code won't notice the difference, as the Flash ROM is not hashed: Only a single 32 bit value is checked. Modchip makers, who used similar tricks to get hold of the hidden ROM, used this knowledge to create patched versions of the Flash ROM image and distributed them on boards that, soldered to the Xbox motherboard, overrode the onboard Flash ROM.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Security Measures in the Hidden ROM ===&lt;br /&gt;
&lt;br /&gt;
So as soon as the encryption algorithm and the key are known, everything is possible? Not quite. In order to create a working Flash ROM image, you have to use Microsoft's secret key, which is considered illegal under certain jurisdictions. So for a completely legal replacement Flash ROM image that takes over the machine to be free to run any homebrew software or alternative operating systems, a complete security analysis had to be made.&lt;br /&gt;
&lt;br /&gt;
Since the hidden code depends in some way on external data, stored in Flash ROM, which can be quite easily changed by the user, it may be attackable through certain data stored there. Microsoft understood this danger and added some precautions so that the Xcodes could not be abused - supposedly - in case the secret ROM was known.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== PEEK ====&lt;br /&gt;
&lt;br /&gt;
The Xcode language is powerful enough to easily read and write memory, the PCI configuration space as well as I/O ports. The user could easily add Xcodes that read the hidden MCPX ROM and send the data to some I/O ports, e.g. the I2C bus. Therefore all memory reads are limited to the lower 256 MB:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    and ebx, 0FFFFFFFh &amp;amp;nbsp;; clear	upper 4 bits&lt;br /&gt;
    mov edi, [ebx]      &amp;amp;nbsp;; read from memory location op1 into di&lt;br /&gt;
    jmp next_instruction&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== POKEPCI ====&lt;br /&gt;
&lt;br /&gt;
Turning off the hidden ROM is done by the following statements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    mov eax, 80000880h&lt;br /&gt;
    mov dx, 0CF8h&lt;br /&gt;
    out dx, eax&lt;br /&gt;
    add dl, 4&lt;br /&gt;
    mov al, 2&lt;br /&gt;
    out dx, al&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code sets bit #1 in the PCI config space, device 0:1:0, register offset 0x80 (coded in 0x80000880).&lt;br /&gt;
&lt;br /&gt;
Using the POKEPCI instruction, it would be possible to disable the hidden ROM prematurely, so that the underlying Flash ROM, which is normally overlapped by the secret ROM, would be visible, and CPU would continue running there, where the hacker could simly store his code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    POKEPCI 0x80000880, 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Therefore the interpreter always clears bit 1 if the Xcode wants to write to 0x80000880:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cmp ebx, 80000880h        &amp;amp;nbsp;; ISA Bridge, MCPX disable?&lt;br /&gt;
    jnz short not_mcpx_disable&amp;amp;nbsp;; no&lt;br /&gt;
    and ecx, not 2            &amp;amp;nbsp;; clear	bit 1&lt;br /&gt;
not_mcpx_disable:&lt;br /&gt;
    mov eax, ebx&lt;br /&gt;
    mov dx, 0CF8h&lt;br /&gt;
    out dx, eax               &amp;amp;nbsp;; PCI configuration address&lt;br /&gt;
    add dl, 4&lt;br /&gt;
    mov eax, ecx&lt;br /&gt;
    out dx, eax               &amp;amp;nbsp;; PCI configuration data&lt;br /&gt;
    jmp short next_instruction&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Halt ====&lt;br /&gt;
&lt;br /&gt;
As described earlier, if the hidden ROM detects that decryption was unsuccessful, it halts the CPU and turns off the hidden ROM by turning it off as the very last statement in the CPU's address space, causing an address overflow exception and thus a CPU halt in the very next cycle. This is supposed to make it impossible for a hacker to extract the hidden ROM contents, because the hidden ROM is always turned off very quickly, even if the machine does not boot correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    mov eax, ds:95FE4h&lt;br /&gt;
    cmp eax, 7854794Ah&lt;br /&gt;
    jnz short bad_checkcode&lt;br /&gt;
    mov eax, ds:90000h&lt;br /&gt;
    jmp eax                 &amp;amp;nbsp;; jump to decrypted second bootloader in RAM&lt;br /&gt;
bad_checkcode:&lt;br /&gt;
    mov eax, 80000880h	     &amp;amp;nbsp;; prepare MCPX ROM disable&lt;br /&gt;
    mov dx, 0CF8h&lt;br /&gt;
    out dx, eax&lt;br /&gt;
    jmp far ptr 8:0FFFFFFFAh&amp;amp;nbsp;; jump to end of ROM, wraparound&lt;br /&gt;
[...]&lt;br /&gt;
FFFA:&amp;amp;nbsp;; this is address FFFFFFFA&lt;br /&gt;
    add	dl, 4&lt;br /&gt;
    mov	al, 2&lt;br /&gt;
    out	dx, al&lt;br /&gt;
; ------ this is address 00000000 ------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Security Flaws in the Hidden ROM ===&lt;br /&gt;
&lt;br /&gt;
While these three security precautions that have just been described are indeed vital, two of them are faulty. The POKEPCI check is incorrectly implemented, and the somewhat clever &amp;quot;Halt&amp;quot; trick, which was supposed to lock out hardware sniffers, opened a software backdoor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== The Visor Trick ====&lt;br /&gt;
&lt;br /&gt;
The roll over of the instruction pointer from FFFF_FFFF to 0000_0000 is supposed to generate an exception. Since no exception handlers are installed, this is supposed to halt the machine. But in reality, no exception is generated. Execution just happily continues at 0000_0000 - in RAM! Apparently the i386 CPU family throws no exception in this case, Microsoft's engineers only assumed it or misread the documentation and never tested it.&lt;br /&gt;
&lt;br /&gt;
By adding Xcodes to write a jump to some Flash ROM address, like FFF0_0000, into memory at location 0, and causing the decryption check to fail by just not including the 32 bit check value into the Flash ROM, one's own code will be run right after the RC4 decryption:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    POKE 0x00000000, 0x001000B8&amp;amp;nbsp;; store &amp;quot;mov eax, 0xFF001000; jmp eax&amp;quot;&lt;br /&gt;
    POKE 0x00000004, 0x90E0FFFF&amp;amp;nbsp;; at 0x00000000 in memory&lt;br /&gt;
    END&lt;br /&gt;
   &amp;amp;nbsp;; now we can place our code at 0x1000 in Flash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The MIST Trick ====&lt;br /&gt;
&lt;br /&gt;
POKEPCI's check for 0x80000880, the address of the configuration register to turn off the hidden ROM, is incorrect. The Southbridge, which decodes the 32 bit value into &amp;quot;bus&amp;quot;, &amp;quot;device&amp;quot;, &amp;quot;function&amp;quot; and &amp;quot;register&amp;quot; and sends the funcion and register numbers to the specific device on the specific bus, simply ignores the unused bits of that 32 bit value, so 0x88000880 or 0xF0000880 behave exactly the same as 0x80000880 - but POKEPCI's check does not detect them. So this check even gives the attacker a hint how to circumvent it.&lt;br /&gt;
&lt;br /&gt;
By adding the statement POKEPCI 0x88000880, 2 to the Xcodes, the interpreter will turn off the hidden ROM - where it is running itself! As soon as the CPU cache has run empty, execution will continue somewhere between FFFF_FE00 and FFFF_FFFF in Flash ROM. You can simply fill everything with NOPs and add a JMP to your own code at the very top.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== More Attacks? ====&lt;br /&gt;
&lt;br /&gt;
Since two methods to circumvent the Xbox hidden ROM security without touching any crypto both work equally well, there has been little need for further research, but there might very well be more than two security issues in these 512 bytes. There are two more approaches for attacks that we do not want to disclose yet, as Microsoft may still offer updated Xboxes in the future.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Microsoft's Fixes ==&lt;br /&gt;
&lt;br /&gt;
In August 2002, Microsoft started manufacturing V1.1 Xboxes, which had been improved in many ways. In concerns of security, the hidden ROM and the MCPX' PCI config behavior had been updated (the MCPX revision is &amp;quot;C3&amp;quot; instead of &amp;quot;B2&amp;quot;): They now squeezed a TEA hash into the 512 bytes, replacing the old 32 bit test. The &amp;quot;2bl&amp;quot; code now couldn't be altered easily. And they changed the RC4 secret key.&lt;br /&gt;
&lt;br /&gt;
But although they had the possibility to patch their design, Microsoft again failed to make the Xbox secure this time:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* They left the Visor backdoor wide open.&lt;br /&gt;
* The TEA hash has been a bad choice. If they had even read Schneier's &amp;quot;Applied Cryptography&amp;quot; (''the'' book on crypto), they would have known that TEA is insecure if used as a hash. This can be easily exploited so that 2bl changes remain undetected, leading to the third bug in the second implementation.&lt;br /&gt;
&lt;br /&gt;
It is pretty obvious that the changes had been made in reaction to Bunnie's hack, who retrieved the secret key for the RC4 decryption, and before the Visor or MIST bugs had been found.&lt;br /&gt;
&lt;br /&gt;
In May 2004, Microsoft started shipping Xboxes that had the ROM image, the video encoder and the security chip (SMC) integrated into a single package, so that it was no longer possible to overwrite the firmware. The secret ROM in the MCPX was still the same though. But as of November 2005, it is still possible to attach a replacement ROM to the LPC bus (&amp;quot;modchip&amp;quot;) of new Xboxes, as the verification weakness is still there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Microsoft's Strategy ==&lt;br /&gt;
&lt;br /&gt;
Microsoft's engineers first seem to have thought that the secret key would never be revealed: security by obscurity. This explains why the decrypted code did not get hashed. Once the secret key was known, anyone could decrypt, patch and reencrypt the flash contents.&lt;br /&gt;
&lt;br /&gt;
So when the secret key had been extracted, Microsoft understood that it could be done again with another key very easily, so they added a hash function over the decrypted code. If the new secret key was to be found out again, attackers should at least not have had the possibility to change the code. Changing the key introduced no security, but was easy to do and at least required attackers to repeat the ROM extraction process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
The design of the first MCPX was very wrong, and the implementation was catastrophic. The design of the second version was a lot better, but the implementation was not.&lt;br /&gt;
&lt;br /&gt;
Without the various security holes (Visor and MIST bugs as well as possibly more) and with a working hash function, the system would have been pretty secure. Encrypting the ROM contents with a secret key, i.e. security by obscurity, simply does not work if the key travels over a bus that can be sniffed.&lt;br /&gt;
&lt;br /&gt;
So with the first version of the MCPX, Microsoft was too naive and apparently did not understand basic security concepts. After they had learnt their lesson, they designed a pretty good system with the second version of the MCPX - but the implementation still contained at least three security holes (Visor, MIST, TEA). They were too fast releasing a new version of the MCPX, spending a lot of money in trashing tons of already manufactured MCPX chips and manufacturing updated ones, apparently without any further code audit which should have revealed the security holes.&lt;br /&gt;
&lt;br /&gt;
512 bytes is a very small amount of code (it fits on a single sheet of paper!), compared to the megabytes of code contained in software like Windows, Internet Explorer or Internet Information Server. Three bugs within these 512 bytes compromised the security completely - a bunch of hackers found them within days after first looking at the code. Why hasn't Microsoft Corp. been able to do the same? Why?&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
&lt;br /&gt;
* [https://web.archive.org/web/20100617012156/http://www.xbox-linux.org/ The Xbox Linux Project]&lt;br /&gt;
* [https://web.archive.org/web/20100617012156/http://hackingthexbox.com/ Hacking the Xbox]&lt;br /&gt;
* [https://web.archive.org/web/20100617012156/http://www.xenatera.com/bunnie/proj/anatak/xboxmod.html bunnie's adventures hacking the Xbox]&lt;br /&gt;
* [https://web.archive.org/web/20100617012156/http://web.archive.org/web/20021208233956/http://65.108.63.67/visor/ visor's aXventure]&lt;/div&gt;</summary>
		<author><name>Prehistoricman</name></author>	</entry>

	</feed>