MechaCon

From PS2 Developer wiki
Jump to navigation Jump to search

MechaCon is short for Mechanics Controller. Its main function is to control the drive mechanism. However, this chip also handles security in the PlayStation 2 and implements game disc security, Magic Gate and KELF file decryption.

There are two known main variants of it.

The earlier one is based on the 16-bit SPC970 CPU core and was used till GH-022. Chip name starts with "CXP10". GH-016/014 and earlier motherboards come with a 100-pin qfp package. GH-015/017 and later motherboards come with a 136-ball BGA package.

The newer one is ARM-based (Sony SR11 core, 32-bit, ARM7TDMI), codenamed "Dragon", and used from GH-023 (SCPH-500xx/5500x) onwards. Chip name starts with "CXR7". Comes in a 164-ball BGA package.

The "Dragon" variant also fulfills the functions that were undertaken by the separate SysCon chip on earlier boards up to GH-022, as well as the RTC+EEPROM chip, which was separate on earlier boards (or dedicated EEPROM and RTC chips on even earlier boards).

Both have access to a 1 KB / 512 words EEPROM. The EEPROM content is different between the SPC970-based MechaCon and Dragon.

For the SPC970 MechaCon, the EEPROM is an external chip; either a dedicated EEPROM chip on early GH-015 and earlier boards including GH-016 board, or a combined Rohm RTC+EEPROM chip on late GH-015 and later boards except GH-016.

Dragon has the die of the combined Rohm RTC+EEPROM chip inside its own chip package, however, the EEPROM pins are exposed on the package, and the connection between Dragon and the RTC+EEPROM is done externally on the motherboard.

Every MechaCon has a 3.3 V TTL UART interface exposed on test pads that was used by service centers for example to readjust the drive and write calibration data etc. Today it can be used with tools like PMAP (currently only supports consoles with SPC970 MechaCon, support for Dragon is highly experimental) to readjust the drive mechanism after fitting a replacement laser assembly etc. See Test points/MechaCon UART.

Additionaly, at least the SPC970-based MechaCon (both, QFP and BGA revisions) provides an I²C interface with SDA and SCL being exposed on test pads next to the MechaCon.

SPC970

Hardware revisions

  • CXP101064 (only used on early A-chassis/GH-001 boards)
    • KUUiF6v.jpg
  • CXP102064 (used from later A-chassis to D/D'-chassis boards)
    • Ent320h.jpg DWB8SQQ.jpg
  • CXP103049 (BGA case, used in F and G-chassis)
    • requires a working battery to function properly.
    • VbJMIXr.jpg

Firmware revisions

Firmware comes in an OTP or mask ROM inside MechaCon. The major version number for SPC970 MechaCon firmware is always <= 3. PS3 emulated mechacon reports itself as 3.9 version. As of 2022, the SPC970 mechacon's firmware has not yet been dumped, unlike Dragon's firmware.

Unlike the later Dragon-MechaCons, which retrieve region parameters from EEPROM and have identical firmware across all regions, the SPC970-MechaCons have region-dependent firmware builds, hence many different chip labels exist for each firmware.

Unlike the later Dragon-MechaCons, the firmware (code) can not be patched/updated via patches stored in EEPROM. Instead, the "update" mentioned in official service tool for SPC970-MechaCons refers to changing some constants stored in EEPROM.

The list might be incomplete. Source

The number behind the underscore denotes the region. See below for a list of region numbers.

There is some ambiguity about which versions of CXP102064 were used in which consoles.

   version_region    |   chip label    |                              remarks
    (cfd output)     |                 |
---------------------|-----------------|---------------------------------------------------------------------
1.02_0    (0x020100) | CXP101064-605R  | A-chassis SCPH-10000 (Japan)
1.03_0    (0x030100) | CXP101064-602R  | A-chassis DTL-T10000, DTL-H10000
---------------------|-----------------|---------------------------------------------------------------------
unknown   (0x020027) | CXP102064-651R  | All Namco System 246 and 256 arcade systems
1.06_0    (0x060100) | CXP102064-001R  |
1.07_0    (0x070100) | CXP102064-003R  | A-chassis DTL-T10000
1.08_0    (0x080100) | CXP102064-002R  | A-chassis SCPH-15000
1.09_0    (0x090100) | CXP102064-751R  | A-chassis DTL-T10000H
2.00_0    (0x000200) | CXP102064-004R  |
2.02_0    (0x020200) | CXP102064-005R  | A+ chassis (GH-003) SCPH-18000 (Japan), AB-chassis (GH-008) SCPH-18000 (Japan)
2.04_1    (0x040201) | CXP102064-101R  | B and C chassis SCPH-30001 (US)
2.04_2    (0x040202) | CXP102064-201R  | C-chassis SCPH-30002/3/4 (AU/NZ/UK/Europe)
2.04_3    (0x040203) | CXP102064-301R  |
2.05_0    (0x050200) | CXP102064-702R  | B-chassis DTL-H30001, DTL-H30002
2.06_1    (0x060201) | CXP102064-102R  | B/C/D-chassis SCPH-30001 (US)
2.06_2    (0x060202) | CXP102064-202R  | C/D-chassis SCPH-30003/4 (UK + Europe)
2.06_3    (0x060203) | CXP102064-302R  | C-chassis SCPH-30002 (AU/NZ)
2.07_0    (0x070200) | CXP102064-703R  | B-chassis DTL-H30001, DTL-H30002
2.08_0    (0x080200) | CXP102064-006R  |
2.09_0    (0x090200) | CXP102064-704R  |
2.12_0    (0x0c0200) | CXP102064-007R  | D-chassis (with single ROM?) SCPH-30000/SCPH-35000 (Japan)
2.12_1    (0x0c0201) | CXP102064-103R  | D-chassis SCPH-30001/SCPH-35001 (US)
2.12_2    (0x0c0202) | CXP102064-203R  | D-chassis SCPH-30003/4 and SCPH-35003/4 (UK/Europe)
2.12_3    (0x0c0203) | CXP102064-303R  | C/D-chassis SCPH-30002/SCPH-35002 (AU/NZ)
2.13_0    (0x0d0200) | CXP102064-705R  | also -752R, D-chassis DTL-H30000 (Japan), D-chassis DTL-H30101 (US)
2.13_0    (0x0d0200) | CXP102064-752R  | also -705R, D-chassis DTL-H30000 (Japan), D-chassis DTL-H30101 (US)
2.14_0    (0x0e0200) | CXP102064-008R  | D-chassis SCPH-30000/SCPH-35000 (Japan)
2.14_1    (0x0e0201) | CXP102064-104R  | D-chassis SCPH-30001/SCPH-35001 (US)
2.14_2    (0x0e0202) | CXP102064-204R  |
2.14_3    (0x0e0203) | CXP102064-304R  | D-chassis SCPH-30002/SCPH-35002 (AU/NZ)
---------------------|-----------------|---------------------------------------------------------------------
3.00_1    (0x000301) | CXP103049-101GG | F-chassis SCPH-30001 R (US) with separate EEPROM and RTC
3.00_2    (0x000302) | CXP103049-201GG | F-chassis SCPH-30003/4 R (UK + Europe) with separate EEPROM and RTC
3.00_3    (0x000303) | CXP103049-301GG | F-chassis SCPH-30002 R (AU/NZ) with separate EEPROM and RTC
3.02_0    (0x020300) | CXP103049-001GG | F-chassis SCPH-30000 (Japan) with combined EEPROM+RTC
3.02_1    (0x020301) | CXP103049-102GG | F-chassis SCPH-30001 R (US) with combined EEPROM+RTC
3.02_2    (0x020302) | CXP103049-202GG | F-chassis SCPH-30003/4 R (UK + Europe) with combined EEPROM+RTC
3.02_3    (0x020303) | CXP103049-302GG | F-chassis SCPH-30002 R (AU/NZ) with combined EEPROM+RTC
3.04_4    (0x040304) | CXP103049-401GG | F-chassis SCPH-30005/6/7 R (Asia) with combined EEPROM+RTC
3.06_0    (0x060300) | CXP103049-002GG | G-chassis SCPH-37000/SCPH-39000 (Japan)
3.06_1    (0x060301) | CXP103049-103GG | G-chassis SCPH-39001 (US)
3.06_2    (0x060302) | CXP103049-203GG | G-chassis SCPH-39003/4 (UK + Europe)
3.06_3    (0x060303) | CXP103049-303GG | G-chassis SCPH-39002 (AU/NZ)
3.06_4    (0x060304) | CXP103049-402GG | G-chassis SCPH-39005/6/7 (Asia)
3.06_5    (0x060305) | CXP103049-501GG | G-chassis SCPH-39008 (Russia)
3.08_0    (0x080300) | CXP103049-003GG |
3.08_4    (0x080304) | CXP103049-403GG |
---------------------|-----------------|---------------------------------------------------------------------

Last number represents region (more information in the table)

EEPROM layout

Start (word) End (word) Size (byte) Offset in file Description
0x000 ????? ???? 0x000 DVD-ROM Disc Detect
0x010 ????? ???? 0x020 DVD-ROM Servo
0x0C0 0x0C6 0x0C 0x180 DVD-ROM Tilt (not present on mechacon 1.x)
0x0D0 0x0C9 0x12 0x1A0 Model Name (not present on mechacon 1.2, 1.3)
0x0E0 0x0E8 0x10 0x1C0 PS2 ID (i.Link id + Console id)
0x0F0 0x0FD 0x20 0x1E0 DVD-ROM Tray
0x100 0x138 0x70 0x200 config 2(DVD Video Player)
0x140 0x160 0x40 0x280 config 0 (EEGS)
0x180 0x1B8 0x70 0x300 config 1 (OSD (User data))

???? - means that area size is variable and depends on mechacon version

Model number

Offset Size Description
0x1B0 0x12 Model number string. Type char. Zero padded.
Model number 0x1A0 1-16 Model name string. Max 15 or 16 characters. Zero padded. If started with "DTL-H" then OSD will block DVD player from work.
0x1B0 1 Null.
0x1B1 1 uint8_t sum = 0xFF - sum(0x1B0:0x1BF)

PS2 ID

i.Link ID

Offset Size Description
0x1C0 0x8 i.Link ID
Console id 0x1C0 1 07 - Sony Company Code (SCE), fixed value.
0x1C1 3 Model ID. Also known as Sony Model Id. Can be calculated from Console Model ID via formula: (0x1C1-0x1C3) = (Console Model ID - 0xd200) + 0x1a0001.
The only exception is SCPH-10000/SCPH-15000, it uses fixed value: 0x1A0000.
0x1E4 4 i.Link ID. Divided into Category and i.Link number, where category is some hex value based on Console Model ID and i.Link number is decimal number based on Console Serial Number. Can be calculated from Console Serial Number and Console Model ID via difficult decimal offset tables. There exist big text tables that contains information about serial ranges and applicable decimal offsets depending on console model and serial range. Full tables still unknown and not published publicly.

Console id

Offset Size Description
0x1C8 0x8 Console ID
0x1C8 2 Console Model ID. Unique per model number, color and edition. Can be restored from the console sticker.
0xd200 - 0xd22d all known ids for pre-dragon models. Total 45 ids, currently only few of them are missing. Most likely there are no more than 45 ids (but it is still unknown). Actually, Sony used only 1 byte to represent Console Model ID, but it is easier to use 2-byte value to be in sync with Dragon models. This 1 byte value is called SCE Model Id (similar field in i.Link id area is called Sony Model Id).
0x1CA 2 0x0111 - always. Known as SDMI Company ID. Actually these 2 ids by Sony are splitted differently. Not 2+2 bytes, but 1+3 bytes. So SDMI Company ID: 01-11-D2 (fixed value) and Console Model ID - 1 byte value.
0x1CC 3 Console Serial Number (in dec). Can be restored from the console sticker.
0x1CF 1 EMCS ID. Id of plant, where the console was manufactured. Can be restored from the console sticker.
0x00 - Japan (generic plant)
0x01 - FOXC (Foxconn, China)
0x02 - SZMT (SuZhou MainTek, China)
0x03 - SKZ (SONY KISARAZU, Japan).
00 - doesnt represent any plant, when there is 00 that only means that it is made in Japan but it can be any plant actually (non Foxconn). It seems that 02 and 03 EMCS ids appeared very late (at the end of 39k production).

Dragon

Hardware revisions

  • CXR706F080 (has a flash ROM for firmware; used for engineering, not used in retail consoles)
  • CXR706080 (used in H, I and J chassis SCPH-500xx/5500x consoles as well as in PSX)
    • 0BM8yj1.jpg
  • CXR716080 (used in K, L and M slim chassis SCPH-70xxx, SCPH-75xxx and SCPH-77xxx consoles)
    • AYJx9aD.jpg
  • CXR726080 (used in N, P and R slim chassis SCPH-79xxx and SCPH-90xxx consoles and in the Bravia PX300)
    • Has a smaller case than previous versions of Dragon (still has 164 balls, though)
    • VGATjwM.jpg

Firmware revisions

Firmware comes in an OTP or mask ROM inside MechaCon, except in CXR706F080, which has a reprogrammable flash ROM. It is however possible to apply patches to it via EEPROM.

Dumps: https://mega.nz/folder/MNpAQDzJ#bZpyfb7aGrhGDMR_ZGA8ig

Some version(s) of the DSP's firmware have a tendency to crash MechaCon by sheer bad luck or on badly readable discs (e.g. badly burned/low-quality DVD-R discs or scratched original discs), overvolting the focus/tracking coils of the laser and killing them and also the driver IC in the process. While the problematic DSP has already been used since the G-chassis, its SPC970-based MechaCon seems less susceptible to fully crashing for reasons not entirely known as of early 2023. This leads to the issue being mostly prevalent beginning with the GH-023 board/H-chassis and thus with the ARM-based Dragon MechaCon. Several hardware-based mitigations/"fixes" have been developed by the community to address this issue with varying degrees of success. The most well known of these fixes have been the "Romeo-mod"/"LA-fix" for SCPH-500xx/5500x consoles and "summ0ne's fix" for some SCPH-700xx consoles; however, these do not reliably prevent damage and can have side effects like reading issues and a slow tray. The most reliable fix is the Matrix PIC fix which monitors communication between DSP and MechaCon and turns off the console when a crash occurs.

PSX uses MechaCon v5.10 (CXR706080-702GG) (for DESR-x000 and DESR-x100) and v5.14 (CXR706080-703GG) (for DESR-x500 and DESR-x700).

Major version number for Dragon MechaCon firmware is always >= 5.

The list might be incomplete. Source

     version     |   chip label    |                              remarks
-----------------|-----------------|---------------------------------------------------------------------
5.00    (0x0500) | CXR706080-101GG | very early H-chassis, GH-023
5.01    (0x0501) | CXR706080-???GG | H-chassis Debug Station (DTL-H5000x)
5.02    (0x0502) | CXR706080-102GG |      early H-chassis, GH-023
5.04    (0x0504) | CXR706080-103GG | H-chassis and I-chassis, GH-023 and GH-026
5.05    (0x0505) | CXR706080-???GG | H-chassis Debug Station (DTL-H5000x)
5.06    (0x0506) | CXR706080-???GG | (Not confirmed)
5.06mx  (0x0506) | CXR706080-???GG | different from other v5.6 MechaCons, only sold in Mexico
5.08    (0x0508) | CXR706080-???GG | (Not confirmed)
5.10    (0x050a) | CXR706080-702GG | PSX v1 (DESR-x000 and DESR-x100), XPD-001
5.12    (0x050c) | CXR706080-105GG | J-chassis, GH-029, has also been found on a CXR706F080-1GG
5.14    (0x050e) | CXR706080-703GG | PSX v2 (DESR-x500 and DESR-x700), XPD-005
-----------------|-----------------|---------------------------------------------------------------------
6.00    (0x0600) | CXR716080-101GG | very early K-chassis, GH-032, GH-035
6.02    (0x0602) | CXR716080-102GG |      early K-chassis, GH-032, GH-035
6.04    (0x0604) | CXR716080-103GG |            K-chassis, GH-032, GH-035
6.06    (0x0606) | CXR716080-104GG | L-chassis, GH-040, GH-041
6.08    (0x0608) | CXR716080-???GG | (Not confirmed)
6.10    (0x060a) | CXR716080-106GG | M-chassis, GH-051, GH-052
-----------------|-----------------|---------------------------------------------------------------------
6.12    (0x060c) | CXR726080-301GB | all N, P, R chassis consoles, GH-061, GH-062, GH-070, GH-071, GH-072

EEPROM layout

Start (word) End (word) Size (byte) Offset in file Description
0x000 0x030 0x60 0x000
0x030 ????? 0x50 on mecha v5
0x54 - on v6.00-v6.10
0x56 on v6.12
0x060
0x060 ????? 0x40 all except DESR
0x28 on DESR
0x0C0 Thermal (Fan)
0x080 ????? 0x2e on v5.00-v6.02
0x2c on v6.04-v6.12
0x100
0x0A0 ????? 0x10 on DESR
0x24 on v6.00
0x32 on v6.02
0x3C on v6.04-v6.12
0x140 not present on fats
0x0B0 0x0C0 0x20 0x160 present only on DESR
0x0C0 0x0C6 0x0C 0x180 Region params (only slim)
0x0CC 0x0D0 0x08 0x198 MAC address (only slim)
0x0D3 0x0D8 0x0A 0x1A6 wake up time (???), not presented on desr, always filled with 0xFF
0x0D8 0x0E1 0x12 0x1B0 Model Name
0x0E3 0x0E8 0x0A 0x1C6 Region code key seed
0x0E8 0x0ED 0x0A 0x1D0 Region code ciphertext
0x0F0 0x0F5 0x0A 0x1E0 i.Link id
0x0F5 0x0F8 0x06 0x1EA ?? (used by scmd 3, subcmd 48 and 49)
0x0F8 0x0FD 0x0A 0x1F0 Console id
0x0FD 0x100 0x06 0x1FA ?? (used by scmd 3, subcmd 48 and 49)
0x100 0x138 0x70 0x200 config 2 (DVD Video Player)
0x138 0x158 0x40 0x270 config 0 (EEGS)
0x158 0x190 0x70 0x2B0 config 1 (OSD (User data))
0x190 0x200 0xE0 0x320 Rom patches ciphertext

Region params

Offset Size Description
0x180 0xF Various region parameters. Type char. Zero padded. On dragon FATs (mechacon v5) filled with FF. Does not have checksum. Normally write-protected by mechacon.
Region params 0x180 1 On 70k exists but has no effect. On Deckard will patch rom0:ROMVER (4th byte 0220HD20060905) and rom0. Possible values:
"J" - for Japan,
"A" - for America and Mexico,
"E" - for Europe, Oceania and Russia,
"H" - for region Asia, Taiwan, Korea,
"C" - for region Mainland China.
Each region checks license data in the PS2 titles. "A" region has this check disabled. "H" region untested.
0x181 4 On all slims will patch rom0:OSDVER (5-8th byte) ("0190Csch"). This mostly controls OSD language sets, and other changes are not tested. Possible values:
"Jjpn" - for Japan,
"Aeng" - for America,
"Eeng" - for Europe and Oceania,
"Heng" - for Asia,
"Reng" - for Russia,
"Csch" - for mainland China,
"Kkor" - for Korea,
"Htch" - for Taiwan,
"Aspa" - for Mexico.
"Csch" will crash cause rom2 (containing Simplified Chinese font) is missing on slims.
0x185 1 On 70k exists but has no effect. On Deckard will patch rom0:VERSTR (0x22 byte: "System ROM Version 5.0 06/23/03 J") and rom0. Possible values:
"J" - for Japan, Asia, Taiwan, Korea, China,
"A" - for America, Mexico,
"E" - for Europe, Oceania and Russia.
Each region checks license data in the PS1 titles. "A" region has this check disabled.
0x186 1 On all slims will patch rom1:DVDID (5th byte) ("3.11A"). This change DVD player region. Possible values: "JUEAORCM".
0x187-0x18B 5 Zero filled.

MAC address

Offset Size Description
0x198 0x8 48-bit MAC address. On dragon FATs (mechacon v5) filled with FF. On 70k exists but has no effect.
MAC address 0x198 3 Organizationally unique identifier (OUI). On 70k always 00:04:1F and has no effect. On Deckard units can be 00:13:15, 00:15:C1, 00:19:C5, 00:1D:0D, 00:1F:A7, 00:24:8D, 28:0D:FC, A8:E3:EE. Full list unknown. By OUI registration date, console manufacture date can be partially evaluated.
0x19B 3 Random part of MAC address. On 70k always 00:00:00 and has no effect. Assignment unknown: probably is somehow calculated from data on the sticker.
0x19E 1 checksum of even bytes uint8_t sum = 0x199 + 0x19B + 0x19D
0x19E 1 checksum of odd bytes uint8_t sum = 0x198 + 0x19A + 0x19C

Model number

Offset Size Description
0x1B0 0x12 Model number string. Type char. Zero padded.
Model number 0x1B0 1-16 Model name string. Max 15 or 16 characters. Zero padded. If started with "DTL-H" then OSD will block DVD player from work.
0x1C0 1 Null.
0x1C1 1 uint8_t sum = 0xFF - sum(0x1B0:0x1BF)

Region code

Decryption

int getRegionFlags()
{
	// read kek
	uint8_t key508[8];
	ksGetKey(key508, 508);
	
	// read saved seed from eeprom
	uint8_t keyseed[10];
	eepromRead(227, sizeof(keyseed), keyseed);
	
	// read encrypted region from eeprom
	uint8_t ciphertext[10];
	eepromRead(232, sizeof(ciphertext), ciphertext);
	
	// generate key
	uint8_t key[8];
	desEncrypt(key508, keyseed, key);
	
	// decrypt ciphertext
	uint8_t plaintext[8];
	desDecrypt(key, ciphertext, plaintext);
	
	uint16_t crc = *(uint16_t *) plaintext;
	crc += *(uint16_t *) &plaintext[2];
	crc += *(uint16_t *) &plaintext[4];
	
	// check checksum
	if (crc  == *(uint16_t *) &plaintext[6])
		return *(uint32_t *) plaintext;
	
	return 0;
}

Bits

Bit Description
0 Japan
1 USA
2 Europe
3 Oceania
4 Asia
5 Russia
6 China
7 Mexico
16 Development (changes MagicGate keys)
17 Retail MagicGate keys on Development, bypass BootCertify
18 Arcade (changes MagicGate keys; not actually used by existing arcade systems)
19 Prototype? (changes MagicGate keys)
20 ? (dvd related)

i.Link ID

Offset Size Description
0x1E0 0xA i.Link ID
Console id 0x1E0 1 EMCS ID. Id of plant, where the console was manufactured. Can be restored from the console sticker.
0x10 - SKZ (SONY KISARAZU, Japan)
0x11 SKD (SONY KOHDA, Japan)
0x18 - S.EMCS (Japan) only seen for PSX DESR
0x20 - FOXC (Foxconn, China)
0x21 - FOXC (Foxconn, China)
0x30 - SZMT (SuZhou MainTek)
0x40 - S WUXI, only seen for SCPH-50009.
Difference between 0x21 and 0x20 is unknown, 0x21 appeared in 2007. "FOXC" EMCS ID (0x20-0x21) changed somewhere in 77k era, earlier 77k units were still with 0x20, while later 77k units already have 0x21. EMCS ID almost always is printed on sticker - this is first 2-digits in the barcode.
0x1E1 3 Model ID. Can be calculated from Console Model ID (0x1F0-0x1F1) = ConsoleModelID + 0x200001
0x1E4 3 i.Link ID. Can be calculated from Console Serial Number (0x1F4-0x1F6) = 0xFFFFFF - SerialNumber
0x1E7 1 Unknown. 0xB0 on PSX DESR units, 0x80 on all other units. In pre-dragon models called Category.
0x1E8 1 Null.
0x1E9 1 uint8_t sum = 0xFF - sum(0x1E0:0x1E7)

Console id

Offset Size Description
0x1F0 0xA Console ID
0x1F0 2 Console Model ID. Unique per model number, color and edition. Can be restored from the console sticker.
0xd301 - 0xd37f reserved for DTL/TEST units,
0xd380 - 0xd400 reserved for PSX DESR units,
0xd401 - 0xd48f reserved for retail units.
Full list isn't yet collected, currently it contains more than 100 collected IDs.
0x1F2 2 0x0111 - always. In pre-Dragon units known as SDMI Company ID.
0x1F4 3 Console Serial Number (in dec). Can be restored from the console sticker.
0x1F7 1 EMCS ID. Id of plant, where the console was manufactured. Can be restored from the console sticker.
0x10 - SKZ (SONY KISARAZU, Japan)
0x11 - SKD (SONY KOHDA, Japan)
0x18 - S.EMCS (Japan) only seen for PSX DESR
0x20 - FOXC (Foxconn, China)
0x21 - FOXC (Foxconn, China)
0x30 - SZMT (SuZhou MainTek)
0x40 - S WUXI, only seen for SCPH-50009.
Difference between 0x21 and 0x20 is unknown, 0x21 appeared in 2007. "FOXC" EMCS ID (0x20-0x21) changed somewhere in 77k era, earlier 77k units were still with 0x20, while later 77k units already have 0x21. EMCS ID almost always is printed on sticker - this is first 2-digits in the barcode.
0x1F8 1 Null.
0x1F9 1 uint8_t sum = 0xFF - sum(0x1F0:0x1F7)

Config 0 (EEGS)

Offset Size Description
0x270 0x40 Config 0 (EEGS)
EEGS 0x270 1 Unknown, 0x00 or 0x01 or 0x02, looks like it controls HDD
0x271 1 Unknown, 0x03 or 0x00
0x272 13 Unknown, always zero
0x27F 1 uint8_t sum = sum(0x270-0x27E)
0x280 1 bit 7, enable/disable networking features, always = 1, if cleared will show all network devices as disabled
0x281 3 Unknown, always zero
0x284 1 Unknown, always zero. In elec tool, March 2003, 0xC0 bitmask is compared to check if console is PAL,

but no real console were found with that bitmask

0x285 1 bit 5, 1=pal, 0=ntsc, 0x10 bitmask is compared to check if console is PAL
0x286 9 Unknown, always zero
0x28F 1 uint8_t sum = sum(0x280-0x28E)
0x290 15 Unknown
0x29F 1 uint8_t sum = sum(0x290-0x29E)
0x2A0 15 Unknown
0x2AF 1 uint8_t sum = sum(0x2A0-0x2AE)
0x2B0 15 Unknown
0x2BF 1 uint8_t sum = sum(0x2B0-0x2BE)

Config 1 (OSD)

Offset Size Description
0x2B0 0x70 Config 1 (OSD)
Config 1 (OSD) 0x2B0 1 PS1 (ps1drv settings) Unknown, mostly zero
0x2B1 14 Unused, the rest of PS1 block, always zero
0x2BF 1 uint8_t sum = sum(0x2B0-0x2BE)
0x2C0 15 PS2
0x2C0 bit 0 spdif:
0=enabled
1=disabled
handled by OSD
bit 1-2 Aspct: Aspect Ration
0=4:3
1=fullscreen
2=16:9
3=unused
handled by OSD
bit 3 Video: 0=rgb(scart), 1=component, handled by OSD
bit 4 oldLang: always set to 1. Leftover from older OSD configuration block, left for compatibility.
bit 5 currentVersion: 0-standard languages, 1-extended languages: Simplified Chinese, Russian, Korean, Traditional Chinese
bit 6-7 unused: 0-always zero
0x2C1 bit 0-4 newLang, handled by OSD
Japanese=0
English=1
French=2
Spanish=3
German=4
Italian=5
Dutch=6
Portugese=7
Russian=8
Korean=9
Traditional Chinese=10
Simplified Chinese=11
12-31 unused
bit 5-7 maxVersion:
2=Dragon
1=Pre-Dragon (not used)
0 Unknown
3-7 unused
0x2C2 bit 0-2 TimeZoneH: Timezone minutes offset from GMT, higher 3 bits, total 11 bit, handled by OSD
bit 3 SummerTime: 0=standard(winter), 1=daylight savings(summer), handled by OSD
bit 4 TimeNotation: 0=24 hour, 1=12 hour, handled by OSD
bit 5-6 DateNotation:
0=YYYYMMDD
1=MMDDYYYY
2=DDMMYYYY
3-Unused
handled by OSD
bit 7 Init: 0=OOBE, 1=normal, 0 - will start OSD Initialization on next boot
0x2C3 1 TimeZoneL: Timezone minutes offset from GMT, lower 5 bits, total 11 bit, handled by OSD
0x2C4 bit 0 TimeZoneCityH: Timezone ID, higher 1 bit, total 9 bit, handled by OSD
bit 1-3 Unknown, Value is carried over
bit 4 dvdpProgressive: 0=disabled, 1=enabled Whether the DVD player should have progressive scanning enabled, handled by DVD Player
bit 5 rcSupported: always 1=enabled, Whether the Remote Control is supported by the PlayStation 2. Unknown how 0=disabled will affect.
bit 6 rcGameFunction: 0=disabled, 1=enabled, Remote Control Game Function On/Of, handled by OSD
bit 7 rcEnabled: 0=disabled, 1=enabled, Remote Control On/Off option, handled by OSD
0x2C5 1 TimeZoneCityL: Timezone ID, lower 8 bits, total 9 bit, handled by OSD
0x2C6 9 Unused, always zero
0x2CF 1 uint8_t sum = sum(0x2C0-0x2CE)
0x2D0 15 Unknown
0x2DF 1 int8_t sum = sum(0x2D0-0x2DE)
0x2E0 15 Unknown
0x2EF 1 uint8_t sum = sum(0x2E0-0x2EE)
0x2F0 15 Unknown
0x2FF 1 uint8_t sum = sum(0x2F0-0x2FE)
0x300 15 Unknown
0x30F 1 uint8_t sum = sum(0x300-0x30E)
0x310 15 Unknown
0x31F 1 uint8_t sum = sum(0x310-0x31E)

Rom patch

Decryption

bool readAndDecryptRomPatch()
{
	// read the patch's first half
	uint8_t patches[0xDE];
	eepromRead(400, 0x70, patches);
	
	// check if the -1th byte is 0 (sum is not checked)
	if (patches[0x6E])
		return false;

	// read the patch's second half
	eepromRead(456, 0x70, &patches[0x6E]);
	
	// check if the -1th byte is 0 (sum is not checked)
	if (patches[0xDC])
		return false;

	// read encryption key
	uint8_t key504[8];
	ksGetKey(key504, 504);
	
	// decrypt the patch using DES-ECB
	for (int i = 0; i < 0xD8; i += 8)
		desDecrypt(key504, &patches[i], &patches[i]);

	// check sum
	uint32_t sum = *(uint32_t *)patches;
	sum += *(uint32_t *)&patches[4];
	sum += *(uint32_t *)&patches[8];
	sum += *(uint32_t *)&patches[12];

	if (*(uint32_t *) &patches[0xD8] == ~sum)
		return false;
		
	return true;
}

Content

The patch can contain up to 4 patches.

addressX = The address where to apply the patch

valueX = The data that's written there

svc_addressX = The address where SVC X instruction jumps to.

payload = Arbitrary, could be code or data as well.

Offset Size Name
0x00 0x04 address0
0x04 0x04 address1
0x08 0x04 address2
0x0C 0x04 address3
0x10 0x04 value0
0x14 0x04 value1
0x18 0x04 value2
0x1C 0x04 value3
0x20 0x04 svc_address0
0x24 0x04 svc_address1
0x28 0x04 svc_address2
0x2C 0x04 svc_address3
0x30 0xA8 payload
0xD8 0x04 crc