Thanks, that makes a lot of sense.
I think I was approaching this from the wrong direction. I was trying to identify individual tables and then immediately figure out what each table does, instead of using the tables I already know as starting points and tracing the code around them.
The part about following the A/B/X registers is especially helpful. I think I understand the basic idea now: if I already know, for example, that a certain RAM value represents RPM, I should label that RAM location and then follow every reference to it. From there I can hopefully identify the calculations, comparisons and other tables that use RPM.
I could then do the same thing with MAP/load and the other sensor values. Once I have enough of those labelled, the surrounding lookup routines should hopefully start making more sense.
That also gives me a much better way to approach the 3.2 ROM instead of just staring at the disassembly and trying to recognize things by intuition.
I think my next step will be to take the ignition table at 0x5C2, which I am reasonably confident about, and work backwards/forwards from its references. If I can identify the RPM and load values being passed into the lookup routine, that should give me a concrete example to learn the process with.
One thing I'm still not completely clear about: when you say that the table is likely loaded into X and A/B contain the lookup values, is there a typical pattern in 68HC11 code that I should look for immediately before the JSR? For example, are there particular instructions/register combinations that are a strong indication that I'm looking at a 3D table lookup?
I'm still very much learning the HC11 instruction set, so having a few specific patterns to look for in Ghidra would probably help me a lot.
And yes, I agree that this is probably a much better approach than trying to identify everything independently. If I can build up a set of known RAM variables, axes and lookup routines for the 3.2, the rest should hopefully become much less mysterious.
Thanks for the pointers!
Old Siemens ECU (MC68HC11)
-
Tobi_gNT
- Posts: 13
- Joined: Sat Aug 15, 2026 7:12 am
- cars: Golf 3 16V ABF Digifant3.2
BMW 335i N54 MSD80
-
ProfessWRX
- Posts: 185
- Joined: Mon Oct 02, 2023 11:33 pm
- cars: 04 Monte SSSC
04 Tahoe
92 Trans Am - Location: AZ USA
Re: Old Siemens ECU (MC68HC11)
Typically in my bin it will load register a or b and scale them with lsr or lslr or mul by something or sub off the initial row value and then cap it at a max value then load the table address to x then jsr a subroutine. Once you see the subroutine it jsr‘s to label it 3d lookup or 2d lookup. Youll see they are used everywhere.
Youll also find potentially more than one 3d or 2d lookup routines. Some output a a signed value. Some an unsigned. Some a word. Some a byte. So Youll have to either work those out or depending on your intent ignore that but know there’s more than one.
As far as the ram variables, you may find several RPM variables. Some are scaled differently for different purposes so don’t expect only one. Expect all parameters to have several versions. You can trace them all back but looking for the staa or stab that stores to that ram variable. This can help you find sensor scaling. It will pull the AD result and scale it through a 2d table or multiply and add an offset or other ways it scales voltage input for sensors. then staa or stab to the ECT or whichever sensor youre tracing.
Youll also find potentially more than one 3d or 2d lookup routines. Some output a a signed value. Some an unsigned. Some a word. Some a byte. So Youll have to either work those out or depending on your intent ignore that but know there’s more than one.
As far as the ram variables, you may find several RPM variables. Some are scaled differently for different purposes so don’t expect only one. Expect all parameters to have several versions. You can trace them all back but looking for the staa or stab that stores to that ram variable. This can help you find sensor scaling. It will pull the AD result and scale it through a 2d table or multiply and add an offset or other ways it scales voltage input for sensors. then staa or stab to the ECT or whichever sensor youre tracing.
-
Tobi_gNT
- Posts: 13
- Joined: Sat Aug 15, 2026 7:12 am
- cars: Golf 3 16V ABF Digifant3.2
BMW 335i N54 MSD80
Re: Old Siemens ECU (MC68HC11)
Hi, I’m getting back to you again.
Unfortunately, I have to say that I’m not making any further progress. I simply don’t know enough about reverse engineering in Ghidra. My skills and knowledge just aren’t sufficient for this.
I know this is not something that can be solved overnight, but is there perhaps someone here who could give me a hand and take a look at it?
There doesn’t seem to be a correct .xdf file available anywhere for this ECU.
Unfortunately, I have to say that I’m not making any further progress. I simply don’t know enough about reverse engineering in Ghidra. My skills and knowledge just aren’t sufficient for this.
I know this is not something that can be solved overnight, but is there perhaps someone here who could give me a hand and take a look at it?
There doesn’t seem to be a correct .xdf file available anywhere for this ECU.
-
ProfessWRX
- Posts: 185
- Joined: Mon Oct 02, 2023 11:33 pm
- cars: 04 Monte SSSC
04 Tahoe
92 Trans Am - Location: AZ USA
Re: Old Siemens ECU (MC68HC11)
Nobody’s skills are good enough at first. I was never able to get ghidra to work.Tobi_gNT wrote: Sat Sep 12, 2026 6:42 am Hi, I’m getting back to you again.
Unfortunately, I have to say that I’m not making any further progress. I simply don’t know enough about reverse engineering in Ghidra. My skills and knowledge just aren’t sufficient for this.
I know this is not something that can be solved overnight, but is there perhaps someone here who could give me a hand and take a look at it?
There doesn’t seem to be a correct .xdf file available anywhere for this ECU.
Without knowing your goal with doing this specifically we can’t really help you. You clearly think something is missing from your xdf. But what? we don’t know what you want.
-
Tobi_gNT
- Posts: 13
- Joined: Sat Aug 15, 2026 7:12 am
- cars: Golf 3 16V ABF Digifant3.2
BMW 335i N54 MSD80
Re: Old Siemens ECU (MC68HC11)
Okay, so where do I start?
The main ignition map (load) is already known: 0x5C2, 16×16 (I have tested it).
I am looking for the ignition map used during idle and overrun conditions.
I have not yet identified the fuel injection maps. There must be separate maps for idle, overrun and full-load operation. According to VCDS, the ABF has these different operating conditions.
Maybe this will help explain it better: The ABF has a micro switch on the throttle body which provides a 1 signal when the throttle valve is fully closed. If you open the throttle slightly by touching the accelerator pedal, the throttle valve opens and the micro switch changes state. I assume this is what triggers the transition from idle to part-load and/or full-load operation.
The same applies to the "overrun" condition. This can be monitored in VCDS. If you are driving the car and completely release the accelerator pedal, VCDS indicates "overrun". Unfortunately, I do not have a screenshot of this, but VCDS displays the condition as "overrun".
When "overrun" is active, I am specifically looking for the fuel injection curve/map so that, if possible, I could achieve a mild pop-and-bang effect by increasing the injector duty cycle — while simultaneously retarding the ignition timing into the negative range.
Parameters such as coolant temperature and intake air temperature must also play a role in fuel enrichment. However, I have not yet identified any maps or parameters related to these functions.
The lambda control is also completely unknown to me. It should be noted, however, that the ABF does not use a wideband lambda sensor but rather a so-called narrowband (switching) lambda sensor. As far as I know, it operates in a range of approximately 0.1 to 0.9 V.
The next topic would be the rev limiter. It would be interesting to determine whether it uses a fuel cut or an ignition cut. There are several different rev limiters present. I would rather expect some form of selective cylinder deactivation by cutting fuel injection.
Basically, all I currently know is the main ignition map and some of the rev limiters. What I cannot currently determine is exactly how everything works together — specifically, which maps and tables are active under which operating conditions and how they interact with each other.
The main ignition map (load) is already known: 0x5C2, 16×16 (I have tested it).
I am looking for the ignition map used during idle and overrun conditions.
I have not yet identified the fuel injection maps. There must be separate maps for idle, overrun and full-load operation. According to VCDS, the ABF has these different operating conditions.
Maybe this will help explain it better: The ABF has a micro switch on the throttle body which provides a 1 signal when the throttle valve is fully closed. If you open the throttle slightly by touching the accelerator pedal, the throttle valve opens and the micro switch changes state. I assume this is what triggers the transition from idle to part-load and/or full-load operation.
The same applies to the "overrun" condition. This can be monitored in VCDS. If you are driving the car and completely release the accelerator pedal, VCDS indicates "overrun". Unfortunately, I do not have a screenshot of this, but VCDS displays the condition as "overrun".
When "overrun" is active, I am specifically looking for the fuel injection curve/map so that, if possible, I could achieve a mild pop-and-bang effect by increasing the injector duty cycle — while simultaneously retarding the ignition timing into the negative range.
Parameters such as coolant temperature and intake air temperature must also play a role in fuel enrichment. However, I have not yet identified any maps or parameters related to these functions.
The lambda control is also completely unknown to me. It should be noted, however, that the ABF does not use a wideband lambda sensor but rather a so-called narrowband (switching) lambda sensor. As far as I know, it operates in a range of approximately 0.1 to 0.9 V.
The next topic would be the rev limiter. It would be interesting to determine whether it uses a fuel cut or an ignition cut. There are several different rev limiters present. I would rather expect some form of selective cylinder deactivation by cutting fuel injection.
Basically, all I currently know is the main ignition map and some of the rev limiters. What I cannot currently determine is exactly how everything works together — specifically, which maps and tables are active under which operating conditions and how they interact with each other.
-
ProfessWRX
- Posts: 185
- Joined: Mon Oct 02, 2023 11:33 pm
- cars: 04 Monte SSSC
04 Tahoe
92 Trans Am - Location: AZ USA
Re: Old Siemens ECU (MC68HC11)
Did you map every single known data point, table and ram variable in ghidra yet? Thats step one.
-
Tobi_gNT
- Posts: 13
- Joined: Sat Aug 15, 2026 7:12 am
- cars: Golf 3 16V ABF Digifant3.2
BMW 335i N54 MSD80
Re: Old Siemens ECU (MC68HC11)
No i don´t.
16bit
Code: Select all
16bit
Code: Select all
That are the "RPM" for the main ignition map i think. Und maybe the Idle rpm axis sarts on @0x0EC7
That definition uses 15000000/X on its map axes (correct).
more i don´t have figured out.
16bit
Code: Select all
0x8EA7 - main RPM axis
Raw: 085E 0955 0A78 0BD2 0D72 0F6C 11DB 14E5 18BE 1DB2 2431 2CE6 38B8 4926 600E 7F60Code: Select all
7003 6279 5597 4957 4358 3799 3282 2804
2368 1973 1619 1305 1033 801 610 460 rpm
Code: Select all
0x8EC7 - idle RPM axis
Code: Select all
1600 1527 1453 1380 1307 1233 1160 1087
1013 940 867 793 720 647 573 500 rpm
That definition uses 15000000/X on its map axes (correct).
more i don´t have figured out.
-
Tobi_gNT
- Posts: 13
- Joined: Sat Aug 15, 2026 7:12 am
- cars: Golf 3 16V ABF Digifant3.2
BMW 335i N54 MSD80
Re: Old Siemens ECU (MC68HC11)
Hello,
Today I experimented with some unknown maps in the ECU and changed their values as a test. I must have burned around 25 EPROMs and tested all kinds of different settings. However, I couldn't notice any major changes.
The car actually ran reasonably well the whole time. At the same time, I was able to monitor the injection time in milliseconds live using VCDS. The goal of this whole experiment was to find the idle injection map / injection time.
Unfortunately, all of this trial and error was unsuccessful.
I then simply wrote the value 255 into every cell of the 16x16 map at 0x90E.
This resulted in the following phenomenon: When lightly applying the throttle and then letting off and allowing the engine to decelerate, the RPM would hang and only decrease very, very slowly. At first, I thought it had to be the map controlling the idle valve. The ABF has a separate idle stabilization system using what is commonly referred to as an “idle valve.”
However, when I monitored the valve activation (opening) with VCDS, it behaved completely normally, just as it normally does.
The injection time in milliseconds also remained unchanged, so I concluded that this must be another ignition map. Perhaps the part-throttle ignition map?
I then changed all the values to 05, and after that, the RPM no longer remained stuck during deceleration.
What is also strange, though, is that if the ignition timing in this area were incorrect, you would expect some kind of misfire or jerking, wouldn't you? But there was absolutely nothing like that! The RPM simply remained in the same range for quite a while—for example, around 3000 rpm—and after I released the accelerator pedal, it only decreased very slightly. It felt like it took around 10 seconds before the engine finally returned to its normal idle speed of 850 rpm.
Anyway, that's enough experimenting for now ...
Today I experimented with some unknown maps in the ECU and changed their values as a test. I must have burned around 25 EPROMs and tested all kinds of different settings. However, I couldn't notice any major changes.
The car actually ran reasonably well the whole time. At the same time, I was able to monitor the injection time in milliseconds live using VCDS. The goal of this whole experiment was to find the idle injection map / injection time.
Unfortunately, all of this trial and error was unsuccessful.
I then simply wrote the value 255 into every cell of the 16x16 map at 0x90E.
This resulted in the following phenomenon: When lightly applying the throttle and then letting off and allowing the engine to decelerate, the RPM would hang and only decrease very, very slowly. At first, I thought it had to be the map controlling the idle valve. The ABF has a separate idle stabilization system using what is commonly referred to as an “idle valve.”
However, when I monitored the valve activation (opening) with VCDS, it behaved completely normally, just as it normally does.
The injection time in milliseconds also remained unchanged, so I concluded that this must be another ignition map. Perhaps the part-throttle ignition map?
I then changed all the values to 05, and after that, the RPM no longer remained stuck during deceleration.
What is also strange, though, is that if the ignition timing in this area were incorrect, you would expect some kind of misfire or jerking, wouldn't you? But there was absolutely nothing like that! The RPM simply remained in the same range for quite a while—for example, around 3000 rpm—and after I released the accelerator pedal, it only decreased very slightly. It felt like it took around 10 seconds before the engine finally returned to its normal idle speed of 850 rpm.
Anyway, that's enough experimenting for now ...