Related RTSAUTO reading
- How Bosch Motronic M1.1/M1.3 manages fuel and ignition in the BMW E30
- E30 ECU variant programming: manual and automatic applications
- BMW Motronic Tuning, specifically Motronic 1.3, 1.1 and 1.0
https://github.com/theodorechapman/grokathon
https://github.com/dimecho/E30-BMW-Motronics-ECU-Checksum
Summary
This article compares a verified stock Bosch Motronic 1.3 0261200173 / software 1267355705 binary with a 0261200525 / software 1267356304 binary for the BMW M20B25. The full-load fuel, ignition, AFM and engine-RPM-limit calibrations are effectively the same after correcting for a four-byte layout relocation. The important differences are in application selection, cranking, idle control, low-RPM transient filtering and the later package’s road-speed-governor behavior.
- No additional full-load power should be expected.
- The stock 525 application code
CA5Ealways selects its revised five-point cranking-fuel descriptor. - The retained three-point descriptor is not a warm/cold fallback. It is selected by first-byte bit-5 application families such as A*, B* and F*. The
C85E173,CA5E525 andCA9E524 paths all select the revised five-point record in the later 6303/6304 package. - The 525 selects the E30-automatic closed-loop idle surface; the 173 selects the E30-manual surface.
- Changing the 525 coding from
CA5EtoC85Eselects manual application records but still uses the five-point cranking descriptor. - The manual selector adds a strong fuel-command smoothing notch between 640 and 840 RPM; it changes transient response, not the final steady-state fuel target.
- Static analysis indicates a roughly 200 km/h / 125 mph road-speed governor in the later 6304 package. Recoding to
C85Eis not proven to remove it. - The earlier broad near-freezing coolant-enrichment prediction has been corrected: that conspicuous curve belongs to the 524/
CA9Eselector branch, not the stock 525/CA5Ebranch.
The values below come directly from the two 32 KiB EPROM images and the recovered selector mechanism. Raw values remain labelled raw where their final engineering conversion has not been proven.
ECUs and software compared
| Item | 173 baseline | 525 comparison |
|---|---|---|
| Bosch DME | 0261200173 | 0261200525 |
| Bosch software | 1267355705 | 1267356304 |
| EPROM size | 32,768 bytes / 27C256 | 32,768 bytes / 27C256 |
| Checksum | Valid | Valid: 0x3FAA |
| Relevant application association | C85E: later E30 325i manual | Coding block includes CA5E: later E30 325i automatic, plus C89E and an unassigned FFFF slot |
The 525 and the separately examined 524 are code/calibration twins: only 29 identity and application-coding bytes differ. Their executable code and complete calibration regions are otherwise byte-identical. Consequently, the 525 has the same cold-start and idle data discussed here for the 524.
How Motronic 1.3 selects calibration records
Motronic does not access every table by one fixed address. At initialization it majority-votes the triplicated coding block and installs a pointer-directory base and selector-list base. Control routines request logical slots; the active selector list translates each slot into a physical descriptor.
| Coding | Application represented here | Selector effect |
|---|---|---|
| C85E | E30 manual / 173 | Manual E30 fuel and idle records |
| CA5E | E30 automatic / 525 | Automatic E30 fuel and idle records |
| C89E | E34 manual | Manual E34 application records |
| CA9E | E34 automatic / 524 | Automatic E34 records; crank slots 22 and 24 still select the five-point record in the 6303/6304 package |
This is why one binary can contain apparently duplicate maps: many are application banks selected at initialization, not temperature-dependent fallbacks.
Coolant-related enrichment: corrected interpretation
The community XDF exposes two six-value coolant-enrichment curves near records 39 and 40. Earlier byte comparison made one appear to be an active 173-to-525 change near 0°C. Selector tracing shows those records are selected by the negative-BB CA9E application branch used by the 524. The C85E 173 and CA5E 525 instead select corresponding records 20 and 22, which are unchanged after relocation.
Stored CA9E coolant-enrichment curve 1 – raw values
| Coolant temperature | 173 image copy | 524/525 shared image copy |
|---|---|---|
| -20°C | 126 | 126 |
| -10°C | 92 | 93 |
| 0°C | 64 | 58 |
| 30°C | 39 | 39 |
| 80°C | 5 | 5 |
| 110°C | 0 | 0 |
Stored CA9E coolant-enrichment curve 2 – raw values
| Coolant temperature | 173 image copy | 524/525 shared image copy |
|---|---|---|
| -20°C | 124 | 124 |
| -10°C | 99 | 99 |
| 0°C | 31 | 31 |
| 30°C | 12 | 12 |
| 80°C | 4 | 4 |
| 110°C | 0 | 0 |
These curves document the shared calibration package but should not be used to predict a stock CA5E 525 versus C85E 173 cold-start difference.
Confirmed active temperature-related record
Descriptor index 24 is selected by the 173, 525 and 524 paths and is revised in the later package. Its exact breakpoints and scaling remain unresolved.
| Image | Complete descriptor bytes | Output-like six-byte portion |
|---|---|---|
| 173 | 38 06 1F 1F 1F 2F 2F 41 6D 43 2C 20 10 06 |
6D 43 2C 20 10 06 |
| 525/524 | 38 06 1F 10 2E 2F 2F 41 6D 43 37 1A 10 06 |
6D 43 37 1A 10 06 |
The defensible conclusion is narrower than the original draft: an active temperature-related correction changes, but the large near-freezing difference in the XDF-labelled CA9E curve is not active under stock CA5E coding.
Cranking fuel: why there are two descriptors
The cranking-fuel calculation uses logical lookup slots 22 and 24. Within any one application both slots share the same selected RPM descriptor. What changes between applications is which physical descriptor those slots resolve to.
| Image/application path | Code condition | Main selector list | Slots 22 and 24 | Descriptor | Result |
|---|---|---|---|---|---|
| 173 path in the 5705 image | C85E | 0x403C | 0x2E / 0x2E | 0x4DDA in that image | Three points because the 5705 data stored there is three-point |
| 525 path in the 6304 image | CA5E | 0x4056 | 0x2E / 0x2E | 0x4DDA | Five points |
| 524 path in the shared 6303/6304 calibration | CA9E | 0x40F2 | 0x2E / 0x2E | 0x4DDA | Five points |
| Alternate application families | First coding byte bit 5 set, such as A*/B*/F* | 0x410C or 0x4126 | 0x7A / 0x7A | 0x5075 | Retained three-point record |
The selector value is the important part. The 173 and 525 both request 0x2E, but the physical bytes at descriptor address 0x4DDA changed between software 5705 and 6304. The stock 525, a C85E-recoded 525 and the shared CA9E 524 application all use the revised five-point record in the later package. Temperature and RPM interpolate within whichever descriptor was selected; they do not choose between descriptors 0x4DDA and 0x5075.
Changed descriptor: three points to five
The 173 descriptor at EPROM 0x4DDA is 3B 03 05 0B EC FF 9A 73. The 525 record at the same address is 3B 05 05 04 02 04 ED FE B3 CD CD A7. The second byte is the point count: 03 versus 05.
173 three-point record
| Point | Cranking speed | Raw output | Hex |
|---|---|---|---|
| 1 | 160 RPM | 255 | FF |
| 2 | 360 RPM | 154 | 9A |
| 3 | 800 RPM | 115 | 73 |
525 five-point record
| Point | Cranking speed | Raw output | Hex |
|---|---|---|---|
| 1 | 160 RPM | 254 | FE |
| 2 | 360 RPM | 179 | B3 |
| 3 | 520 RPM | 205 | CD |
| 4 | 600 RPM | 205 | CD |
| 5 | 760 RPM | 167 | A7 |
The 525 RPM breakpoints are inferred from the same 160-RPM anchor and the established 40-RPM interval encoding. Its interval bytes are 05, 04, 02 and 04, corresponding to 200, 160, 80 and 160 RPM steps. The five outputs are raw lookup values; they are not yet decoded as injector milliseconds, AFR or a direct percentage. The non-monotonic shape is one reason not to label the 525 automatically richer or leaner from these numbers alone.
Retained three-point descriptor selected by bit-5 application families
| Cranking speed | Raw output | Hex |
|---|---|---|
| 160 RPM | 255 | FF |
| 360 RPM | 154 | 9A |
| 800 RPM | 115 | 73 |
The full later-image descriptor at 0x5075 is 3B 03 05 0B EC FF 9A 73. It is selected by main selector lists 0x410C and 0x4126 when the first coding byte has bit 5 set. It is not selected by stock C85E, CA5E or CA9E. Its presence is another application bank inside the shared software, not an unreachable historical leftover.
Cranking ignition timing
Cranking ignition uses a separate selector family. The 173 C85E, 525 CA5E and 524 CA9E all select descriptor index 114. The alternate descriptor index 135 is selected by coding families whose first application byte has bit 5 set, commonly the A*, B* and F* groups in the available coding list.
| Coding condition | Selector at logical slot 1 | Descriptor used |
|---|---|---|
| C85E, CA5E or CA9E | 0x04 | Index 114 |
| BA bit 5 set, such as A*/B*/F* | 0x2E | Index 135 |
One three-point cranking-ignition curve changes both its timing values and its upper RPM breakpoint. It does not expand to five points.
Changed cranking-ignition curve
| Point | 173 RPM | 173 raw hex | 173 timing | 525 RPM | 525 raw hex | 525 timing |
|---|---|---|---|---|---|---|
| 1 | 160 | 22 | 3.0° BTDC | 160 | 1E | 0.0° BTDC |
| 2 | 320 | 25 | 5.25° BTDC | 320 | 2C | 10.5° BTDC |
| 3 | 680 | 42 | 27.0° BTDC | 760 | 3F | 24.75° BTDC |
The raw timing conversion is (raw x 0.75) - 22.5 degrees. The full descriptors are:
- 173:
3B 03 04 09 EF 22 25 42 - 525:
3B 03 04 0B EE 1E 2C 3F
At a common speed of 680 RPM, standard linear interpolation would put the 525 at approximately 22.2° BTDC, versus the 173’s 27.0°. The 525 is not simply more advanced or more retarded across the whole curve: it is three degrees less advanced at 160 RPM, 5.25 degrees more advanced at 320 RPM, then less advanced near the upper endpoint.
Alternate index-135 cranking-ignition curve
| Cranking speed | Raw hex in both | Timing in both |
|---|---|---|
| 160 RPM | 25 | 5.25° BTDC |
| 320 RPM | 29 | 8.25° BTDC |
| 680 RPM | 42 | 27.0° BTDC |
The practical effect could be a subtly different catch and transition from starter speed to running speed. Index 135 is stored in both images but is not selected by C85E or CA5E. Changing a 525 from CA5E to C85E therefore does not change its cranking-ignition curve.
Closed-loop idle control and application selection
Here, closed loop means engine-speed feedback. The five XDF-labelled surfaces are not all used together: Surface 1 is common, while Surfaces 2 through 5 are application alternatives.
| Coding | Application | Selector list | Selected surface |
|---|---|---|---|
| C85E | E30 manual / 173 | 0x425E | Surface 2 |
| CA5E | E30 automatic / 525 | 0x4264 | Surface 3 |
| C89E | E34 manual | 0x426A | Surface 4 |
| CA9E | E34 automatic / 524 | 0x4270 | Surface 5 |
The cells below show 173-package raw value → later 524/525-package raw value. The exact controller direction remains a bench-validation item.
Common closed-loop idle surface 1
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 760 | 130 → 150 | 100 → 120 | 90 → 105 | 85 → 85 | 72 → 72 | 58 → 58 |
| 1160 | 130 → 150 | 100 → 120 | 95 → 105 | 87 → 87 | 74 → 74 | 59 → 59 |
| 1560 | 130 → 152 | 120 → 124 | 110 → 120 | 99 → 102 | 80 → 80 | 62 → 62 |
| 2560 | 148 → 165 | 138 → 143 | 128 → 135 | 115 → 120 | 95 → 95 | 75 → 75 |
| 3560 | 162 → 176 | 152 → 152 | 142 → 142 | 131 → 131 | 112 → 112 | 96 → 96 |
| 4960 | 182 → 182 | 172 → 172 | 162 → 162 | 151 → 151 | 132 → 132 | 116 → 116 |
Surface 2 – C85E / E30 manual branch
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 1160 | 130 → 152 | 102 → 122 | 92 → 103 | 85 → 85 | 74 → 74 | 60 → 59 |
| 1560 | 132 → 152 | 122 → 122 | 114 → 118 | 102 → 102 | 82 → 82 | 60 → 60 |
| 3560 | 164 → 164 | 154 → 154 | 146 → 144 | 135 → 133 | 115 → 114 | 97 → 98 |
| 4960 | 184 → 184 | 174 → 174 | 166 → 164 | 155 → 153 | 135 → 134 | 117 → 118 |
Surface 3 – CA5E / E30 automatic branch
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 1160 | 130 → 152 | 102 → 122 | 92 → 103 | 85 → 85 | 74 → 74 | 60 → 59 |
| 1560 | 132 → 152 | 122 → 122 | 114 → 114 | 102 → 102 | 82 → 82 | 60 → 60 |
| 3560 | 164 → 178 | 154 → 154 | 146 → 144 | 135 → 133 | 115 → 114 | 97 → 98 |
| 4960 | 184 → 184 | 174 → 174 | 166 → 164 | 155 → 153 | 135 → 134 | 117 → 118 |
Surface 4 – C89E / E34 manual branch
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 1160 | 130 → 152 | 102 → 122 | 92 → 103 | 85 → 85 | 74 → 74 | 60 → 59 |
| 1560 | 132 → 152 | 122 → 122 | 114 → 118 | 102 → 102 | 82 → 82 | 60 → 60 |
| 3560 | 164 → 178 | 154 → 154 | 146 → 144 | 135 → 133 | 115 → 114 | 97 → 98 |
| 4960 | 184 → 184 | 174 → 174 | 166 → 164 | 155 → 153 | 135 → 134 | 117 → 118 |
Surface 5 – CA9E / E34 automatic branch
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 1160 | 130 → 152 | 102 → 122 | 92 → 103 | 85 → 85 | 74 → 74 | 60 → 59 |
| 1560 | 132 → 152 | 122 → 122 | 114 → 118 | 102 → 102 | 82 → 82 | 60 → 60 |
| 3560 | 164 → 178 | 154 → 154 | 146 → 144 | 135 → 133 | 115 → 114 | 97 → 98 |
| 4960 | 184 → 184 | 174 → 174 | 166 → 164 | 155 → 153 | 135 → 134 | 117 → 118 |
Direct active comparison: stock 173 versus stock 525
The 173 uses Surface 2 while the stock 525 uses the later package’s Surface 3.
| RPM | 100°C | 80°C | 40°C | 0°C | -20°C | -40°C |
|---|---|---|---|---|---|---|
| 1160 | 130 → 152 | 102 → 122 | 92 → 103 | 85 → 85 | 74 → 74 | 60 → 59 |
| 1560 | 132 → 152 | 122 → 122 | 114 → 114 | 102 → 102 | 82 → 82 | 60 → 60 |
| 3560 | 164 → 178 | 154 → 154 | 146 → 144 | 135 → 133 | 115 → 114 | 97 → 98 |
| 4960 | 184 → 184 | 174 → 174 | 166 → 164 | 155 → 153 | 135 → 134 | 117 → 118 |
Idle-speed target records – unchanged
These records are identical after relocation. The target values are raw because their exact RPM conversion has not yet been recovered.
| Condition | 4°C | 35°C | 99°C | 144°C |
|---|---|---|---|---|
| Automatic D/R, A/C off – both ECUs | 100 | 93 | 80 | 72 |
| Automatic D/R, A/C on – both ECUs | 100 | 88 | 80 | 72 |
| Automatic P/N, A/C on or off – both ECUs | 105 | 91 | 82 | 76 |
Idle ignition timing – unchanged
| RPM | Raw hex in both | Timing in both |
|---|---|---|
| 600 | 32 | 15.0° BTDC |
| 760 | 2B | 9.75° BTDC |
| 840 | 2B | 9.75° BTDC |
| 960 | 2B | 9.75° BTDC |
| 1080 | 2B | 9.75° BTDC |
| 1600 | 2B | 9.75° BTDC |
| 2000 | 36 | 18.0° BTDC |
| 3000 | 36 | 18.0° BTDC |
Idle-valve voltage compensation – unchanged
| System voltage | 173 raw | 525 raw |
|---|---|---|
| 7.72 V | 128 | 128 |
| 11.03 V | 128 | 128 |
| 13.20 V | 128 | 128 |
| 15.45 V | 128 | 128 |
| 17.63 V | 128 | 128 |
Additional RPM-indexed records in the idle-control cluster
These two six-point records also change. Their location and axes associate them with the idle/deceleration cluster, but their exact function and output scaling remain unconfirmed.
Record A
| RPM | 173 raw | 525 raw |
|---|---|---|
| 920 | 0 | 0 |
| 1000 | 21 | 52 |
| 1480 | 53 | 79 |
| 2000 | 72 | 110 |
| 2600 | 87 | 134 |
| 3000 | 172 | 159 |
Record B
| RPM | 173 raw | 525 raw |
|---|---|---|
| 920 | 0 | 0 |
| 1000 | 41 | 52 |
| 1480 | 82 | 79 |
| 2000 | 105 | 110 |
| 2600 | 123 | 134 |
| 3000 | 205 | 159 |
What if the 525 is recoded from CA5E to C85E?
Changing the active application word clears the transmission/application selector bit. It changes several selector lists but does not replace 525 calibration data with 173 data.
| Function | Stock 525 CA5E | Recoded 525 C85E | Effect |
|---|---|---|---|
| Main fuel selector | 0x4056 | 0x403C | Four logical selector entries change; one is now decoded as a low-RPM fuel-command smoothing gain |
| Cranking slots 22/24 | Descriptor 31 | Descriptor 31 | Still the five-point 525 curve |
| Cranking ignition | Index 114 | Index 114 | No change |
| Closed-loop idle | Surface 3 | Surface 2 | Changes to E30-manual branch |
| Software/calibration | 1267356304 | 1267356304 | Does not become a 173 |
Other main-fuel selector records changed
| Logical slot | C85E record | CA5E record |
|---|---|---|
| 3 | 0x4C6E | 0x4DFA |
| 5 | 0x4E38 | 0x4E5E |
| 8 | 0x4CDE | 0x4E12 |
| 12 | 0x4D35 | 0x4E1C |
Decoded selector difference: low-RPM fuel-command smoothing
Logical main-fuel slot 3 is no longer an unnamed fuel curve. Disassembly shows that its interpolated value is stored in internal RAM at 0x62 and used as a fractional gain while the main fueling routine moves a current calculated quantity toward a desired calculated quantity:
new quantity ≈ previous quantity + (desired quantity - previous quantity) × gain / 256
| Engine speed | Stock 525 CA5E automatic | 525 recoded C85E manual | Approximate fraction of remaining change applied per update |
|---|---|---|---|
| 560 RPM | 255 | 255 | 99.6% in either coding |
| 640 RPM | 255 | 27 | 99.6% automatic; 10.5% manual |
| 840 RPM | 255 | 27 | 99.6% automatic; 10.5% manual |
| 1000 RPM | 255 | 255 | 99.6% in either coding |
| 2000 RPM | 255 | 255 | 99.6% in either coding |
| 2480 RPM | 255 | 255 | 99.6% in either coding |
The curve is linearly interpolated. In the manual branch it falls from 255 to 27 between 560 and 640 RPM, stays at 27 through 840 RPM, then rises back to 255 by 1000 RPM. If the desired quantity changes by 40 internal counts, gain 255 applies about 39.8 counts on the first update while gain 27 applies about 4.2 counts, then continues approaching the same target on subsequent updates.
This is transient filtering, not extra or reduced steady-state fuel. The best provisional name is manual-transmission low-RPM fuel-command smoothing gain. The likely purpose is to suppress low-speed driveline shuffle, hunting or torque oscillation during clutch engagement. That purpose is an engineering inference; the official Bosch name and control-loop period remain unknown.
Other main-fuel selector differences still awaiting names
| Logical slot | C85E manual record | CA5E automatic record | Current result |
|---|---|---|---|
| 5 | 0x4E38: 38 04 46 37 28 47 6E 5A 50 0E |
0x4E5E: 38 04 46 44 1B 47 6E 50 4A 0E |
Active temperature-indexed correction differs; final engineering scaling/name unresolved |
| 8 | 0x4CDE: 38 04 37 37 28 47 6C 60 4C 00 |
0x4E12: 38 04 37 37 28 47 6C 60 4C 00 |
Different pointer, byte-identical descriptor in the supplied 6304 ROM; no functional change from this slot |
| 12 | 0x4D35: 3B 04 09 0A 0A C4 40 04 14 14 14 9C FF FF FF F0 B0 B0 B0 C0 90 90 90 A0 80 80 90 A0 |
0x4E1C: 3B 04 04 0F 0A C4 40 04 14 14 14 9C D0 D0 E0 F0 B0 B0 B0 C0 90 90 90 A0 80 80 90 A0 |
Application-dependent 4×4 surface in the fueling path; exact Bosch function/scaling unresolved |
A recoded unit is best described as the later 525/6304 calibration package operating through its E30-manual selector paths. It retains the revised five-point cranking fuel and later cranking ignition.
Exact CA5E to C85E EPROM patch in the supplied 525 image
The variant-coding block is 30 bytes long, from EPROM 0x1F42 through 0x1F5F. The record scanner begins at 0x1F48, so the leading 80 80 80 7D 7D 7D word is not an application-list entry. In this specific 6304 image, C89E occupies 0x1F48-0x1F4D and CA5E occupies 0x1F4E-0x1F53.
| EPROM offset | Original | Recoded | Action |
|---|---|---|---|
| 0x1F4E | CA | C8 | Change |
| 0x1F4F | CA | C8 | Change |
| 0x1F50 | CA | C8 | Change |
| 0x1F51-0x1F53 | 5E 5E 5E | 5E 5E 5E | Leave unchanged |
| 0x1F5A-0x1F5F | FF FF FF FF FF FF | FF FF FF FF FF FF | Preserve the list terminator |
This is a clear-only three-byte patch: CA → C8 in all three majority-voted copies. It does not require changing the stored 0x3FAA checksum because the checksum covers combined CPU CODE 0x0000-0x9EFF, while this external-EPROM block maps to CODE 0x9F42-0x9F5F and lies outside that range. The checksum is stored big-endian at CODE 0x9F00 / EPROM 0x1F00-0x1F01.
Remove the original 27C256-family EPROM, make and compare multiple reads, keep the original untouched, program a known-genuine compatible replacement and use blank-check and verify. Do not assume every ECU has a socket. Recoding a 526 from CA3E to C85E is not this same operation: that changes both transmission and all-wheel-drive application bits and must be traced against the exact 526 ROM.
- Do not use
CA9Eto chase the three-point crank record; it selects E34 automatic fuel, coolant and idle records but still uses the later five-point crank record. - Do not write into 0x1F5A-0x1F5F. Those 0xFF bytes terminate the application-record scan.
Road-speed governor and vehicle-speed input
Static comparison indicates that software 1267356304 in the 525 has road-speed-governor behavior at approximately 200 km/h / 125 mph, whereas no corresponding active road-speed limit has been established in the supplied 173/5705 baseline. This is separate from the identical 6250-RPM engine-speed limiter.
The governor depends on the vehicle-speed signal entering the DME at connector pin 29 from the instrument cluster. If that wire or source fails, the engine can still start and run because crankshaft speed and position come from pins 47 and 48, not pin 29. With no vehicle-speed pulses, the DME should interpret road speed as zero and therefore cannot satisfy the governor threshold. Other speed-dependent functions or fault behavior have not yet been completely traced, so disconnecting pin 29 is not presented as a modification method.
Changing only CA5E to C85E changes selector paths; it does not remove the later executable code. Until the exact governor enable/threshold path is isolated or bench-tested, assume that a recoded 525 may retain the road-speed governor.
What should an E30 driver expect?
Starting
The five-point cranking-fuel descriptor and revised cranking-ignition curve can change how the engine catches between starter speed and running speed. The raw fuel outputs are not yet converted into final injector pulse width, so the binary alone does not justify calling the 525 categorically richer, leaner, faster-starting or slower-starting.
Cold and near-freezing starting
The original draft’s roughly 1.9-percent near-0°C prediction is withdrawn for a stock CA5E 525 because that physical curve belongs to the CA9E selector branch. A smaller active temperature-related record changes, but its engineering scaling remains unresolved.
Warm idle, clutch engagement and throttle closing
This remains the most plausible place to notice a difference. The stock 525 selects E30-automatic Surface 3 while the 173 selects E30-manual Surface 2, and the common surface is revised. Final target speed should remain similar because target records, idle ignition and voltage compensation are unchanged. Differences are more likely as RPM dip, flare, decay rate or recovery after clutch-in or accessory load. A C85E-recoded 525 also applies the strong 640-840 RPM smoothing notch, so low-speed clutch take-up or driveline shuffle may feel calmer even though steady-state fueling and full-load power do not change.
Why an automatic-coded ECU can feel normal in a manual car
A manual E30 does not normally provide an automatic D/R load state, so the ECU can remain on a default or P/N-like input while closed-loop feedback returns it to the same target. This is consistent with the reported lack of an obvious drivability difference.
Bottom line
- A stock 525 is not a performance upgrade over a stock 173.
- The stock
CA5E525 genuinely uses its five-point cranking descriptor. - The retained three-point descriptor is selected by first-byte bit-5 application families such as A*/B*/F*, not by
CA9E/524 and not as a temperature fallback. - Closed-loop idle Surfaces 2-5 are E30 manual, E30 automatic, E34 manual and E34 automatic alternatives.
- Recoding the 525 to
C85Eselects manual application paths, activates the 640-840 RPM fuel-command smoothing notch, and retains the five-point crank curve and later calibration values. - The later package appears to contain a roughly 200 km/h / 125 mph road-speed governor; the
C85Erecode is not proven to remove it. - The broad near-freezing enrichment prediction has been corrected.
A useful A/B/C test would compare an unmodified 173, the stock CA5E 525, and a checksum-correct C85E-recoded 525 while logging coolant temperature, battery voltage, revolutions to first fire, wideband lambda, clutch-in RPM undershoot and load-recovery time.
———————————-
Technical reverse-engineering handoff
This section is deliberately more technical than the article above. Its purpose is to let another researcher reproduce the analysis, challenge the provisional labels and continue from the current stopping point. Addresses are hexadecimal. “Confirmed” means the bytes and code path were recovered; it does not imply that an official Bosch engineering name has been found.
1. Reference binaries and identity
| Artifact | Size | SHA-256 | MD5 / checksum note |
|---|---|---|---|
| 0261200173 / 1267355705 external EPROM | 32,768 bytes | 665b857ed42ce50f5189e63a7de0993c7fb15c0cb42134a943308a19ca27bc78 |
MD5 b79efe54a73170ef12b10426a533d4ed; combined checksum 0x40CE valid |
| 0261200525 / 1267356304 external EPROM | 32,768 bytes | 1e223871b648ce1de38f96efa9d9c39950ae0bbbe259d3842b001cabbad0f096 |
MD5 75e05bd4cd419cdf34ff0824f06daa06; combined checksum 0x3FAA valid |
| 0261200524 / 1267356303 external EPROM | 32,768 bytes | 7e048303e5e2564959308b3e891ce7aa455442451c86678a1d130f8441704c68 |
MD5 e3d5138eca26796a5af81745306994c1 |
| Community internal mask-ROM image used to construct the 40 KiB CPU view | 8,192 bytes | 78578932ddc905732a2c074a8a0a3b1468af7393b5439f389b9c69d4f42f133f |
Community-supplied provenance; conclusions depending on it should be independently checked against hardware |
The 524 and 525 external images differ in only 29 identity/application bytes; their executable and calibration regions are otherwise the same. The CPU is from the Bosch/Siemens 8051-family environment used by Motronic 1.3. The analysis language was 8051 big-endian.
2. CPU address reconstruction and checksum
| Source bytes | CPU CODE destination |
|---|---|
| Internal mask ROM 0x0000-0x1FFF | CODE 0x0000-0x1FFF |
| External EPROM 0x2000-0x7FFF | CODE 0x2000-0x7FFF |
| External EPROM 0x0000-0x1FFF | CODE 0x8000-0x9FFF |
The recovered checksum is sum(CODE:0000-9EFF) mod 65536, stored big-endian at CODE 0x9F00, which is external EPROM 0x1F00. This explains why changing the coding block at EPROM 0x1F42 does not change the checksum: that block maps above the covered end address.
3. Variant-coding block and scan structure
The relevant external-EPROM structure is 30 bytes, 0x1F42-0x1F5F. Each logical byte is stored three times and recovered through a majority voter. In the 525/6304 image the exact block is:
80 80 80 7D 7D 7D C8 C8 C8 9E 9E 9E CA CA CA 5E 5E 5E FF FF FF FF FF FF FF FF FF FF FF FF
| EPROM range | Meaning recovered |
|---|---|
| 0x1F42-0x1F47 | Triplicated 807D word. The application-list DPTR begins at 0x1F48, so this is not an application code. |
| 0x1F48-0x1F4D | Triplicated C89E application word |
| 0x1F4E-0x1F53 | Triplicated CA5E application word |
| 0x1F54-0x1F5F | 0xFF padding/terminator; preserve it |
The exact 525 patch is only 0x1F4E, 0x1F4F and 0x1F50 from CA to C8. Leave 0x1F51-0x1F53 as 5E and 0x1F5A-0x1F5F as FF. The operation clears bits only. The list has a record limit of 12, but the 0xFF terminator should end the scan; populating the terminator area could make the scanner continue into unintended data.
4. Main selector initialization
CODE:7879 initializes the main lookup family. It writes pointer-directory base 0x4870 to internal RAM 0x73/0x74, loads the voted application bytes from internal RAM 0xBA/0xBB, and writes the selected 26-byte selector-list base to internal RAM 0x75/0x76.
| Coding | BA / BB | Relevant bit state | Main selector base |
|---|---|---|---|
| C85E | C8 / 5E | BA bit5=0; BB sign=0; BB bit5=0; BA bit3=1; BA bit1=0 | 0x403C |
| CA5E | CA / 5E | Same, except BA bit1=1 | 0x4056 |
| CA9E | CA / 9E | Negative BB branch; BA bit3=1 and bit1=1 | 0x40F2 |
| First-byte bit5 application family | A*/B*/F* examples | BA bit5=1 | 0x410C or 0x4126 depending on remaining option bits |
The earlier 0x4070/0x408A notation for C85E/CA5E was one branch too far: those lists are selected when BB bit5 is set. With BB=0x5E, bit5 is clear, so the correct lists are 0x403C and 0x4056.
5. Exact C85E versus CA5E main-selector delta
The two relevant selector lists are 26 bytes long and differ at four logical indices:
| Logical index | C85E selector | Resolved C85E record | CA5E selector | Resolved CA5E record |
|---|---|---|---|---|
| 3 | 08 | Pointer 0x4878 → 0x4C6E | 34 | Pointer 0x48A4 → 0x4DFA |
| 5 | 3C | Pointer 0x48AC → 0x4E38 | 42 | Pointer 0x48B2 → 0x4E5E |
| 8 | 12 | Pointer 0x4882 → 0x4CDE | 38 | Pointer 0x48A8 → 0x4E12 |
| 12 | 1B | Record 0x4D35 after selector-flag handling | 3B | Record 0x4E1C after selector-flag handling |
Odd selector values carry a low-bit flag rather than pointing at an odd-aligned 16-bit directory entry. The complete semantics of that flag remain unresolved; the listed final descriptor targets are the recovered results.
6. Logical index 3: decoded low-RPM smoothing gain
C85E record 0x4C6E is 3B 06 02 05 04 19 0C C2 FF 1B 1B FF FF FF. CA5E record 0x4DFA is 3B 06 02 05 04 19 0C C2 FF FF FF FF FF FF. Both use recovered engine-speed state byte 0x3B, six points and the same RPM axis. Only the outputs differ.
| RPM | C85E raw | CA5E raw |
|---|---|---|
| 560 | 255 / FF | 255 / FF |
| 640 | 27 / 1B | 255 / FF |
| 840 | 27 / 1B | 255 / FF |
| 1000 | 255 / FF | 255 / FF |
| 2000 | 255 / FF | 255 / FF |
| 2480 | 255 / FF | 255 / FF |
CODE:213C calls selector setup at CODE 0x7879 and then calibration initialization at CODE 0x35BF. That routine starts with logical index 0 and advances through successive records. Index 1 is stored to internal RAM 0xA6, index 2 to 0x6C, and index 3 to internal RAM 0x62. Indices 4 and 5 are subsequently multiplied together for another parameter, which is why index 3 should not be interpreted as a direct fuel quantity.
The value at RAM 0x62 is consumed in the main engine/fueling update path at CODE 0x2A10, also seen at the bank/mapping alias near CODE 0x95D2. The code takes the difference between a desired 16-bit quantity and the current quantity in RAM 0x41/0x42, calls the multi-byte multiplication helper at CODE 0x054E with the gain, and adds or subtracts the scaled result. RAM 0x61 acts as a fractional/error accumulator. The best recovered functional form is current += (desired-current) × gain / 256. Therefore FF is approximately unity response, not “255 units of fuel,” and 1B is strong smoothing.
7. Other changed main-fuel records
| Index | C85E complete descriptor | CA5E complete descriptor | Status |
|---|---|---|---|
| 5 | 38 04 46 37 28 47 6E 5A 50 0E |
38 04 46 44 1B 47 6E 50 4A 0E |
Different one-dimensional temperature-state record. It participates with index 4 in a multiplication path. Official name and engineering scaling remain open. |
| 8 | 38 04 37 37 28 47 6C 60 4C 00 |
38 04 37 37 28 47 6C 60 4C 00 |
Selectors point to separate copies, but the copies are byte-identical in this ROM. |
| 12 | 3B 04 09 0A 0A C4 40 04 14 14 14 9C FF FF FF F0 B0 B0 B0 C0 90 90 90 A0 80 80 90 A0 |
3B 04 04 0F 0A C4 40 04 14 14 14 9C D0 D0 E0 F0 B0 B0 B0 C0 90 90 90 A0 80 80 90 A0 |
Different 4×4 surface in the fueling path. First axis uses state 0x3B; second uses state 0x40. Exact Bosch label and units remain open. |
8. Cranking-fuel selector correction
Main logical slots 22 and 24 contain selector 0x2E in all of the C85E, CA5E and CA9E lists examined. Pointer base 0x4870 plus selector 0x2E resolves through directory bytes at 0x489E to descriptor 0x4DDA. In the 173/5705 image, that address contains the three-point record 3B 03 05 0B EC FF 9A 73. In the 525/6304 image it contains the five-point record 3B 05 05 04 02 04 ED FE B3 CD CD A7. The selector is unchanged; the descriptor stored at the selected address changed.
The alternate selector lists at 0x410C and 0x4126 contain 0x7A at slots 22 and 24. Pointer bytes at 0x48EA resolve 0x7A to descriptor 0x5075, where the retained three-point curve is stored. These lists are chosen by first-byte bit5 variants, not by CA9E.
9. Cranking-ignition and idle families
Cranking ignition uses a separate selector family. C85E, CA5E and CA9E select descriptor index 114; first-byte bit5 families select alternate index 135. Recoding CA5E to C85E therefore does not switch the cranking-ignition descriptor. The 525 still uses its later index-114 bytes and three points at 160, 320 and 760 RPM.
Closed-loop idle also has a separate selector family: C85E uses selector list 0x425E / Surface 2; CA5E uses 0x4264 / Surface 3; C89E uses 0x426A / Surface 4; CA9E uses 0x4270 / Surface 5. The article tables above contain all currently decoded raw cells. Target-idle, idle-ignition and idle-valve voltage-compensation records were unchanged after relocation, so expected differences are controller dynamics rather than a deliberately higher warm-idle target.
10. Road-speed input and governor
The 55-pin vehicle diagram identifies DME pin 29 as the vehicle-speed signal from the instrument cluster. Pins 47 and 48 are the engine-speed/reference inputs. A missing pin-29 signal therefore does not deprive the DME of engine RPM or crank position. Static analysis indicates a later-package road-speed governor around 200 km/h / 125 mph; without vehicle-speed pulses its threshold cannot be reached. The exact cut strategy, hysteresis, fault response and whether a particular variant selector enables or disables it remain to be isolated. Treat the governor conclusion as medium confidence until bench or instrumented-road validation.
11. Programming and safety notes
- The board photograph is consistent with a 28-pin 27C256-family external EPROM, but socketing cannot be assumed. Desoldering carries pad and thermal-damage risk.
- Use multiple identical reads before modifying anything. Record file hashes and compare against the values above when working with these exact images.
- Keep the original chip unchanged. Program a separate compatible blank, blank-check it, program it once with the complete 32 KiB image and verify every byte.
- An OTP 27C256 is disposable after a bad burn. A genuine windowed UV-erasable 27C256 or supported reprogrammable substitute is friendlier for iteration, provided voltage, pinout and programmer support are verified.
- The three-byte CA5E-to-C85E patch applies to the exact 525/6304 image identified above. Do not transplant offsets blindly into a 526, 380, 382 or differently identified software version.
12. Confidence and remaining work
| Finding | Confidence | What would close it |
|---|---|---|
| Variant block triplication, 30-byte extent, scan start, exact 525 patch and checksum exclusion | High | Independent disassembly reproduction and read-back from a recoded spare EPROM |
| C85E/CA5E main selector bases and four changed logical entries | High | Runtime trace of RAM 0x75/0x76 after startup under both codes |
| Five-point record used by C85E, CA5E and CA9E in the later package; three-point alternate belongs to bit5-set families | High | Runtime logging of the selected descriptor pointer during crank |
| Index-3 value is a fractional smoothing gain | High for arithmetic role; medium for engineering name | Bench trace of RAM 0x62, desired/current quantity and injector output versus RPM |
| Manual low-RPM notch exists to reduce driveline shuffle/torque oscillation | Medium, inferred | A/B testing of CA5E and C85E in the same 525 hardware with clutch-engagement and RPM-oscillation logging |
| Index-5 and index-12 official functions and engineering scaling | Unresolved | Trace their consumers through the final pulse-width path and correlate RAM variables with coolant/load sweeps |
| Later 6304 road-speed governor at about 200 km/h / 125 mph | Medium | Isolate threshold/enable bytes and validate on a signal-generator bench without road testing |
| Exact loop period for the smoothing equation | Unresolved | Timer/executive scheduling trace around CODE 0x2A10 |
13. Suggested next experiments
- Build two verified 525 images differing only at EPROM 0x1F4E-0x1F50, then log selected pointer bases and RAM 0x62 during a controlled bench run.
- Feed a programmable crank/RPM signal through 500-1100 RPM and step the load/airflow input while capturing injector command. This should expose the 27/256 smoothing notch without driving the car.
- Perform cold-start A/B tests at matched coolant temperature and battery voltage. Log revolutions to first fire, RPM overshoot, injector pulse width and lambda; do not infer fuel quantity directly from raw table bytes.
- Test closed-loop idle with clutch-in, electrical load and A/C-load simulations. Measure RPM undershoot, overshoot, settling time and idle-valve command.
- Use a frequency generator on pin 29 to isolate the road-speed threshold, hysteresis and cut behavior on the bench.
- Dump any 526 before recoding it. Decode its 0x1F42-0x1F5F block and trace CA3E versus C85E through every selector family; changing an AWD automatic code to a rear-drive manual code affects more than one transmission bit.
- Recover official Bosch function names only when supported by period documentation or a complete consumer trace. Until then, keep provisional labels and raw units explicit.


Recent Comments