Reverse-engineering the ECM

As far as I know, the V6 ECM had two versions: '85 and '86-'88. These same ECMs should also be found in other GM V6 cars. The PROM might have as many as 12 different versions: ('85, '86-'87, '88) x (manual, auto) x (49 state, California). This information can be deduced by comparing part numbers in the Fiero Store catalog (or looking in a P22.) The L4 ECM is different from the V6 ECM.

I don't know how far Frans Godschalk has gotten in reverse engineering the V6 Fiero ECM. However, I've also been doing the same thing. Below is what I've discovered so far. This ECM is from an '86 Fiero SE. I think the same ECM was used from '86 through '88 and with the same EPROM in both '86 and '87.

I've made a dump of the EPROM and ROM contents and have a preliminary disassembly. There is about 10K to 10.5K of code and slightly more than 1.5K of data, most of that in the EPROM. The code uses the 6801 enhancements to the original 6800 instruction set but not the further 68HC11 enhancements. I'm sure I'll have more more to report after looking through the dissassembly.

A while ago I dumped the contents of the V6 ECM's ROM and PROM. I've been looking at a disassembly of the program and figuring out how parts of it work. First off, the 12K of ROM contains 1633 bytes of data, 10226 bytes of code, 42 bytes of code related data, and 387 unused bytes. Three of the data bytes are never referenced. The code consists of 5005 instructions, 1430 of which are branches or control transfer instructions. And 873 of those are conditional!

The ECM hardware generates a periodic interrupt at 160 Hz. (Where have we seen that number before?) The entire ECM program operates off of this one interrupt. Except for some initialization code, there is no non-interrupt level code. In fact, the interrupt service routine never returns, it simply cleans the return address off the stack and waits for the next interrupt. There are no other interrupts in the ECM. This means that fully autonomous hardware generates all the high speed signals like the fuel injector and ignition pulses.

At each tick of the 160 Hz, various tasks are performed. Some are done every tick. Others only on just odd or just even ticks. There are also 16 tasks, one of which is performed each tick. Every tenth of a second, all 16 tasks will have been completed. In general, this means that the ECM cannot adjust engine performance faster than 10 times a second. Perhaps this explains the engine surging at low rpm that many list members have complained about.

So far, among other things, I've found the code that blinks diagnostic codes out the "Check Engine" light, and also the code that sends data out the ALDL interface. It turns out there are _five_ ALDL modes. Three of them are for testing the ECM out of the car. (There is a general ROM and RAM check mode, an analog input test mode, and a digital pulse input test mode.) All these test modes send 12 bytes of data. The normal ALDL mode sends five bytes of data, two of which are constants from the PROM. The diagnostic ALDL mode sends 25 bytes (the first of which is the same as in the five byte mode.)

The three ALDL diagnostic code bytes contain flags in this order (msb to lsb): 12 13 14 15 21 22 23 24, 25 31 32 33 34 35 41 42, 43 44 45 51 52 53 54 55 Codes 12, 41, 43, and 54 can never be set. Codes 31 and 53 could be set in the ALDL data stream but will never be blinked via the "Check Engine" light. And of course, code 12 will always be blinked.

After the diagnostic codes, the first of the three status bytes contains internal ECM status flags. The next two status bytes contain the contents of a pair of digital input/output ports.

I'm just starting to figure out how other inputs to the ECM are measured and reported in the ALDL data. Does anyone know (and is willing to divulge) the mapping for the various analog values? Like the conversion of the reported coolant temperature to degrees C or F.

I took a look at the logic that the V6 ECM program uses to deal with codes. The ECM has three groups of code flags: A, B, and C. A and B start out clear when the ignition is turned on. C is in permanent memory. The ECM never clears a code set in C. The ECM has the capability to clear all of C after a given number of engine starts with no new error code, but this feature is disabled by the Fiero PROM. The only way to clear C is to remove (battery) power from the ECM. Group C is the source of codes blinked with the Check Engine Soon light or sent out the ALDL.

As the engine runs, new codes are entered into A. (Except for code 55 which goes directly to C.) Ten times a second, the ECM compares groups A and B. Through some logic which I haven't figured out yet, it decides to light or not light the CES bulb. At the same time, it also copies A into B, and then clears A. The previously mentioned logic also decides to sometimes combine B into C. I think the logic is waiting for a stable set of new codes before setting them permanently.

In summary, the CES light only indicates currently active codes. Previously set codes will never activate the CES light. And the only way to look at a code via CES blinking or the ALDL is for the code to become permanently set.

For an '86 or '87 with a manual transmission, the rev limit is 6010 RPM. The limiter will engage (by totally shutting off the fuel injectors) after 1/4 second above the limit. The limiter will stay engaged until the engine slows to 4007 RPM. At that point, the injectors will resume firing at full blast. Roger Feingold just confirmed this. The doctor says his whiplash isn't serious. :-)

For an '86 (and probably some other years) with an automatic transmission, the rev limit is 5849 RPM. The fuel cutin speed is the same 4007 RPM.

For an '88 with a manual transmission, the rev limit is ... ... 1310343 RPM. Yes, over a million. The cutin speed is a wimpy 655171 RPM.

Note, there may be another hardware enforced, resistor&capacitor programmed limit someplace much lower than a million RPM. That would be consistent with the rest of the ECM design - which mimics GM's management hierarchy with one level of management watching over the backs of the next level.

Here is the pinout of various significant components and connectors:

          Ribbon    Edge      U17       U19/U20   U21       U18
          Cable     Card      CPU(6801) ROM+RAM   IO        AtoD

 1        GND       D0        GND       GND       GND       GND
 2        Z1-??     ~RESET    EDGE-17   A1        A1        GND
 3        Z1-??     D1        PULLUP    A3        R/~W      D7
 4        Z1-??     ~IRQ      ~IRQ      A5        A10       D6
 5        Z1-??     D2        GND       D0        ~CS0800   D5
 6        Z1-??     U17-6     EDGE-6    D1        E         D4
 7        Z1-??     D3        EDGE-8    D2                  D3
 8        Z1-??     U17-7     VCC       D3                  D2
 9        Z1-??     D4        A0        D4                  D1
10        Z1-??     U17-39    A1        D5                  D0
11        Z1-??     D5        A2        D6                  R/~W
12        Z1-??     E         A3        D7                  E
13        A1        D6        A4        A7                  A1
14        E         R/~W      A5        A15                 ~CS1000
15        R/~W      D7        A6        A8        ~IRQ      ~RESET
16        EDGE-34   A15       A7        A14
17        D0        U17-2     A8        A9        D0
18        D1        A8        A9        A13       D1        GND
19        D2        A0        A10       A10       D2
20        D3        A14       A11       A11       D3
21        D4        A1        GND       A12       D4
22        D5        A9        A12       ROMENABLE D5
23        D6        A2        A13       R/~W      D6
24        D7        A13       A14       ???       D7
25        VCC       A3        A15       VCC       VCC
26        GND       A10       D7        VCCSTNDBY ???
27        Z1-??     A4        D6        ~RESET              VCC
28        Z1-??     A12       D5        E                   VCC
29        ~CS3000   A5        D4                  ~RESET
30        ~CS3800   A11       D3
31        ~IRQ      A6        D2
32        A12       ROMENABLE D1
33        VCC       A7        D0
34        A11       RIBBON-16 R/~W
35        ROMENABLE VCC       GND
36        A10       VCC       E
37        A13       GND       E         A6        A5
38        A9        Z1-12     GND       A4        A4
39        A14       GND       EDGE-10   A2        A3
40        A8        GND       ~RESET    A0        A2
41        ~RESET
42        A15
43        A7
44        A6
45        A5
46        A4
47        A3
48        A2
49        A0
50        GND

Various notes:

The following have pullup resistors: U17-2, U17-3, U17-4, U17-6, and ROMENABLE
Pulling ROMENABLE low disables all ROM and EPROM but not RAM and I/O.
U19-24, U20-24, and U21-26 are connected together but not to anything else.
The E clock frequency is 1.048275 MHz.
U13 is a type 2732 EPROM.
U17 appears to be the CPU core of a Motorola 6801 MPU.
U19's VCCSTNDBY is connected to a continuous source of power.
U20's VCCSTNDBY is connected to VCC.
U22 is a '138 octal decoder that decodes the first 16K into 2K blocks.
U25 is a '00 quad NAND gate that provides ~CS and ~OE control for U13.
Z1 appears to be a hybrid circuit perhaps containing calibrated resistors.
The ECM appears to draw all its power from the "memory power" source.
When running by itself on a workbench, the ECM draws about half an amp.
The "ignition power" source (via ECM fuse) is used only to control ECM power.
Allowing ignition power to float appeared to cause VCCSTNDBY to rise to 12V.
256 bytes of RAM (in U19 and U20) are available from $0000 to $00FF.
VCCSTNDBY powers the RAM from $00C0 to $00FF while the ignition is off.
U19 probably contains the RAM from $0080 to $00FF.
U20 probably contains the RAM from $0000 to $007F.
I/O locations in U19 and U20 have repeated images from $0800 to $08FF.
I/O locations in U21 have repeated images from $0C00 to $0FFF.
I/O locations in U18 have repeated images from $1000 to $18FF.
4096 bytes of EPROM (in U13) are accessed from $3000 to $3FFF.
8192 bytes of ROM (in U19 and U20) are located from $E000 to $FFFF.
All other addresses are unused and available for the edge card test connector.

From: Ludis Langens

[Top] Back to ECM Info Online Service Guide Main Page