Pages: 1 [2] 3 4
Print
Author Topic: 1996 EJ20 Legacy ECU "T8"  (Read 7267 times)
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #15 on: January 24, 2009, 12:06:08 PM »

I've been offline the last few days, lightning nuked the modem, just got a replacement yesterday.

I will be heading off to work for approx 10 days and doubt I'll have internet access.

I'll try and copy this whole thread and the other so I have something to do at night on laptop if I get bored.

1329 is correct by the way, i just referenced it to what I have in my Evoscan settings.

How are we going to find battery voltage etc? All the items that are not in error codes.

Cheers,
Daniel.
Logged
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #16 on: January 27, 2009, 10:27:57 AM »

How are we going to find battery voltage etc? All the items that are not in error codes.
In the previous example, we saw how the ECU reads the TPS voltage using the A/D converter. The A/D converter in the CPU chip has 8 channels. So in theory, the ECU could read voltage from 8 different sensors.

Here's a simplified explanation for how the ADC works: Each ADC channel has its own input pin to the CPU chip. The program writes the number of the channel it wants to read to memory address 0x0020 (dp + 0x20). Then the ADC hardware reads the voltage on the corresponding pin, converts it to a number and stores it at memory address 0x0022 (dp + 0x22). The program then reads the voltage value from "dp + 0x22".

The ADC channels are numbered from 0 to 7. If we look back at the TPS code we can see that the TPS is connected to channel 4.

Code:
00DF75    642004        ldm     #0x04, dp + 0x20                ; Write to A/D control register

Some other voltage inputs are: Battery, Temperature Sensor, Mass Airflow Sensor, TPS and O2 Sensor. There may also be others. We know that TPS is channel 4. We'll cross the others off the list as we find them and then one of the remaining channels will be the Battery Voltage.
Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #17 on: February 04, 2009, 11:53:00 AM »

Hey Daniel! Enjoying the snow?

I'm just catching this thread up with the other one. You'll probably have to read that thread to make sense of what I've written here.

No error code for Atmospheric Pressure Sensor, therefore definitely no sensor. No point searching for it.

Looking through the hex editor, I can see the fuel map in its usual place at 8120 and the rpm and load scales at 8100 and 8110 respectively.

Code:
00008100   0C 10 18 20 28 30 38 40 48 50 58 60 68 70 78 80   ... (08@HPX`hpx.

00008110   05 0A 0C 0E 10 12 14 16 1C 20 22 24 26 2A 2C 33   ......... "$&*,3

00008120   81 83 83 81 80 80 7E 7F 80 7F 80 81 82 82 82 82   ......~.........
00008130   7F 82 84 83 81 80 7F 7F 80 7F 7F 85 83 83 83 83   ................
00008140   81 83 84 83 82 81 81 80 7F 80 80 82 83 83 83 83   ................
00008150   83 82 82 81 81 80 7F 80 7E 7F 80 80 82 82 82 82   ........~.......
00008160   82 81 82 82 81 81 80 7E 7F 81 82 83 83 83 83 83   .......~........
00008170   82 82 82 80 80 80 7F 7F 80 7F 7E 80 81 7F 7F 7F   ..........~.....
00008180   81 80 7F 7F 7F 7E 7E 7F 7E 80 81 80 80 7F 7F 7F   .....~~.~.......
00008190   82 81 81 7F 7F 7F 80 80 80 81 80 7F 81 81 81 82   ................
000081A0   83 82 7F 7E 7E 7E 7F 81 81 81 80 7F 80 83 82 7F   ...~~~..........
000081B0   85 84 81 81 80 80 81 82 82 82 82 82 81 82 82 80   ................
000081C0   88 86 83 82 80 7F 80 81 81 80 80 80 80 80 81 80   ................
000081D0   85 83 82 81 80 82 81 80 80 80 80 80 80 80 7F 80   ................
000081E0   81 81 80 7F 7F 80 7F 7F 7F 7E 7E 7E 7F 7E 7D 7F   .........~~~.~}.
000081F0   7E 7D 7E 7E 7F 7F 7E 7D 7D 7D 7D 7D 7E 80 80 7F   ~}~~..~}}}}}~...
00008200   81 81 80 7F 7F 7E 7E 7D 7C 7F 7F 7E 7F 80 80 80   .....~~}|..~....
00008210   83 84 82 80 80 7E 7E 7D 7E 7F 7F 80 80 80 80 82   .....~~}~.......

Following exactly the same method as in Brett's thread:

Find the subroutine that references the map:
Code:
H:\SVX\Daniel>findstr 0x8120 Sub-*
Sub-AC4E.txt:00AC68    A22081        ldx     #0x8120
The code looks very similar to Brett's ECU:
Code:
00AC68    A22081        ldx     #0x8120             ; address of fuel map
00AC6B    8E7210        stx     0x1072                ; Map address
00AC6E    A20081        ldx     #0x8100             ; address of rpm scale
00AC71    8E7410        stx     0x1074                ; X Scale Address
00AC74    A21081        ldx     #0x8110             ; address of load scale
00AC77    8E7610        stx     0x1076                ; Y Scale Address
00AC7A    AE6210        ldx     0x1062               ; Internal RPM
00AC7D    8E7A10        stx     0x107a               ; X value
00AC80    D8            clm                                 
00AC81    AD4011        lda     ax, 0x1140         ; Internal Load
00AC84    0A            asl     ax                            ; Shift left 3 (SEE BELOW)
00AC85    0A            asl     ax
00AC86    0A            asl     ax
00AC87    8D7810        sta     ax, 0x1078          ; Y value
00AC8A    F8            sem
00AC8B    200092        jsr     0x9200               ; call 16x16 3D Map lookup subroutine
00AC8E    8D0A13        sta     al, 0x130a         ; store return value at 130a
In this case, the internal RPM is at 1062 and the internal load is at 1140.

The internal rpm is (RPM / 12.5) and we need (RPM / 25) for the select monitor. First find the subroutine that calculates the RPM:
Code:
Sub-E98C.txt:00E9DD    8D6210        sta     ax, 0x1062
It looks exactly the same as Brett's ECU, but with different addresses.
Code:
....
00E9D7    8D6410        sta     ax, 0x1064           ; 16 bit raw RPM reading (RPM / 3.125)
00E9DA    58            cli
00E9DB    4A            lsr     ax                              ; divide by 4
00E9DC    4A            lsr     ax
00E9DD    8D6210        sta     ax, 0x1062           ; 16 bit internal rpm (rpm / 12.5)
00E9E0    AA            tax
00E9E1    C9FF00        cmp     ax, #0x00ff
00E9E4    9003          bcc     0xe9e9
00E9E6    A9FF00        lda     ax, #0x00ff
00E9E9    F8            sem     
00E9EA    8D7010        sta     al, 0x1070            ; 8 bit internal rpm (RPM / 12.5)
00E9ED    D8            clm                             
00E9EE    8A            txa
00E9EF    4A            lsr     ax                              ; divide by 2
00E9F0    C9FF00        cmp     ax, #0x00ff
00E9F3    9003          bcc     0xe9f8
00E9F5    A9FF00        lda     ax, #0x00ff
00E9F8    F8            sem                     
00E9F9    8D6F10        sta     al, 0x106f              ; store (rpm / 25) at 106F, 012A and 1338.
00E9FC    8D2A01        sta     al, 0x012a
00E9FF    8D3813        sta     al, 0x1338
....
We can use 106F or 1338 for the select monitor RPM. I don't know what 012a is doing there because we don't have any RAM at that address AFAICT.

Now let's find the Load Parameter:

Code:
H:\SVX\Daniel>findstr 0x1140 Sub-*
...
Sub-E350.txt:00E40D    8D4011        sta     ax, 0x1140
...
Now find the address 1140 inside Sub-E350 and see what else it is stored.
Code:
00E40D    8D4011        sta     ax, 0x1140                      ; Internal Load
00E410    8DF812        sta     ax, 0x12f8
00E413    4A            lsr     ax                                          ; Divide by 16
00E414    4A            lsr     ax
00E415    4A            lsr     ax
00E416    4A            lsr     ax
00E417    F8            sem                                     ; m:1 x:0
00E418    8D0513        sta     al, 0x1305                         ; Select Monitor Load

Finally, we know that Sub-9200 is a 16x16 3D map lookup. So we'll see what other maps it references:
Code:
H:\SVX\Daniel>findstr 0x9200 Sub-*
Sub-AC4E.txt:00AC8B    200092        jsr     0x9200
Sub-B235.txt:00B280    200092        jsr     0x9200
Sub-B235.txt:00B2A8    200092        jsr     0x9200
Sub-ACD4.txt:00ACF6    200092        jsr     0x9200
Sub-F7CC.txt:00F7EE    200092        jsr     0x9200

Sub-AC4E refers to the fuel map at 8120 as already discussed.
Sub-B235 refers to maps at 8500 and 8900. Probably the base timing and maximum advance maps.
Sub-ACD4 refers to a map at 8BA0. Don't know what this is.
Sub-F7CC refers to a map at 9000. Don't know what this is.

Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #18 on: February 05, 2009, 03:29:35 PM »

Im Back!!

Hardly any snow here! Its stupid.. I really want snow to mess around with and beat all the "inferior" non AWD cars, but the snow has only been here for the last 2 days, and melts within an hour! Rubbish!

Anyhow, I'm back home now again.
I had quite some silly hours messing around with this and the other thread and picking things to bits, but got completely lost!
I then started reading and making a note of all the instructions and tried to understand what was going on, it made it a lot clearer to me.

Right here goes:

I just went on a rampage and started hunting for things within the 102D, then 102E address, before giving up.

Code:
-findstr 102d Sub-* | findstr seb
Sub-A4F4.txt:00A51C    0C2D1040      seb     #0x40, 0x102d
Sub-A533.txt:00A568    0C2D1004      seb     #0x04, 0x102d
Sub-A582.txt:00A59A    0C2D1020      seb     #0x20, 0x102d

Then decided to go for the first one 0x40.

Code:
Sub-A4F4.txt
00A514    AE9C11        ldx     0x119c                          ; Branch target from A52C
00A517    E00D03        cpx     #0x030d
00A51A    9004          bcc     0xa520
00A51C    0C2D1040      seb     #0x40, 0x102d
00A520    60            rts                                     ; Branch target from A51A

00A521    0C301080      seb     #0x80, 0x1030                   ; Branch target from A50F, Branch target from A527
00A525    8007          bra     0xa52e

00A527    2C311008F5    bbs     #0x08, 0x1031, 0xa521           ; Branch target from A503, Branch target from A50A
00A52C    80E6          bra     0xa514

00A52E    1C2D1040      clb     #0x40, 0x102d                   ; Branch target from A4F4, Branch target from A4F9, Branch target from A525
00A532    60            rts     

Then figured out Ldx was 119C so:

Code:

-findstr 119c  sub-*
Sub-9FF7.txt:00A075    AE9C11        ldx     0x119c
Sub-A0AB.txt:00A11E    AE9C11        ldx     0x119c
Sub-A12B.txt:00A1E0    AE9C11        ldx     0x119c
ranch target from A1CA, Branch target from A1D5
Sub-A4F4.txt:00A514    AE9C11        ldx     0x119c
ranch target from A52C
Sub-A5A7.txt:00A5E1    8E9C11        stx     0x119c
Sub-A5A7.txt:00A5F7    AE9C11        ldx     0x119c
ranch target from A5C8
Sub-A5A7.txt:00A605    8E9C11        stx     0x119c
ranch target from A5FF, Branch target from A602
Sub-A67A.txt:00A790    AE9C11        ldx     0x119c

Had a rake through all those files, and discovered that in each one of those txt files looking down the lines of code that anything that was being "loaded" were set values using the hash (#) Prefix, and not other addresses or A/D stuff.
So i tried the same for 0x04 and 0x20 from 102D and figured out that none of them apply to my car.
Neutral Switch. Not in use!
Engine Torque Control. Not in use!
CO Resistor. Not in use!

Every address is loaded with a set value in the code.

I then went onto 102E but lost track.

I don't know if I'm doing this right but basically all of 102D doesn't do anything in my car?
or am I going horribly wrong somewhere?

Cheers,
Daniel.
Logged
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #19 on: February 05, 2009, 04:16:01 PM »

Oh, I was also wondering if you could spare a moment and explain the Accumulator/Stack/Index Register to me?

What's the difference between:
Accumulator A
Accumulator B
Index Register X
Index Register Y

And then there's the Stack?!
So it has 5 places it can store random "floating" values to do calculations with? I kind of understand (I think) what the Stack does. But what's the difference between the Index Register and the Accumulator?
I noticed you have "A" (16bit)
Al (8Bit) and Ah (8Bit)
But then again (I've not seen it in code yet) there's Xh and Xl as well as "normal" X

Both the Accumulator and the Index register have
STX and STA as well as LDX and LDA

You have TAX and  TXA so values can be moved between them.
As well as the TXS and TSX to move it between the stack and Index Register X
So what's the difference? are they the same types of thing with different names?
I was a bit baffled with them..

Anyhow, just read the other thread, need to sit down and digest it all, the fuel map is interesting if they are all the same location, means "tuning" would be fairly straightforward for all the vehicles without hunting around for maps in code. But still miles away from that!

Wish I could just go to sleep and wake up and know everything!

What would be useful, and I noticed that the disassembler can possibly do it, is if the function Stx, lda, ax etc would be written completely behind the text like a note. so you'd have :

00A51C    0C2D1040      seb     #0x40, 0x102d

Turns into:

00A51C    0C2D1040      seb     #0x40, 0x102d ;Set Bits 0x40 at address 0x102d.

That would make it so much easier to understand and read what's going on (Yes, i'm one of these weird people that draws images in their head of situations and links, like big flow charts, to understand them. I think its called Visual Mathematician or something like that...)

Cheers,
Daniel.




« Last Edit: February 05, 2009, 04:18:00 PM by mrdjc » Logged
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #20 on: February 06, 2009, 05:47:50 AM »

Oh, I was also wondering if you could spare a moment and explain the Accumulator/Stack/Index Register to me?

What's the difference between:
Accumulator A
Accumulator B
Index Register X
Index Register Y
The registers are like special memory locations that reside inside the CPU. The CPU cannot do mathematical operations directly on a value in the main memory. It must load it into a CPU register, do the calculation, and then store the result back in the main memory.

The accumulators AX and BX are general purpose registers used for just about everything. They are 16bits in size but they can be subdivided into 8 bit registers. The "high" 8 bits of AX is called AH and the "low" 8 bits is called AL. Similarly, BX can be subdivided into BH and BL.

The index registers X and Y are similar but they cannot support the full set of mathematical operations that is possible with AX and BX. Nor can they be subdivided. There is no XH and XL or YH and YL. One useful thing that you can do with them is use them as in index. Suppose we want to look at a particular column in a lookup table. For example: Column 4. We start off with AX=0004.

Code:
00008000    01 23 45 67 89 AB CD EF (columns are numbered left to right from zero)

adc     ax, #0x8000                    ; Add address of start of table - so AX is now 8004
tax                                               ; Transfer value in AX to X
lda     al, dp + 0x00 + ix              ; Load AL with value at address in X (8004) - so AL is now 89
Note that we do the calculation in an accumulator (AX) and then transfer the result to an index register (X). This is because the index register can't do calculations and the accumulator can't function as an index.

Does that make sense?

And then there's the Stack?!

So it has 5 places it can store random "floating" values to do calculations with? I kind of understand (I think) what the Stack does. But what's the difference between the Index Register and the Accumulator?
I noticed you have "A" (16bit)
Al (8Bit) and Ah (8Bit)
But then again (I've not seen it in code yet) there's Xh and Xl as well as "normal" X

Both the Accumulator and the Index register have
STX and STA as well as LDX and LDA

You have TAX and  TXA so values can be moved between them.
As well as the TXS and TSX to move it between the stack and Index Register X
So what's the difference? are they the same types of thing with different names?
I was a bit baffled with them..
The stack is an area of memory that the program can use as a scratch pad. It's a Last-In-First-Out arrangement. Like a stack of papers on a desk. When you put a paper on the pile, it goes on top of the ones already there. When you take a paper off the top of the pile, you get the last one you put on.
Now turn that upside down.   Shocked The way that it is implemented is that the first thing you "push" onto the stack goes at the top and every subsequent thing you add goes at the bottom of the pile. When you "pull" a value from the stack, you take the bottom item from the pile. Exactly the same as the pile of papers, but upside down.

By convention the stack is normally placed at the top of the RAM, because it grows downwards. It is not limited to 5 places, theoretically you can keep on adding to the stack until it starts overwriting your variables, and then the program goes badly wrong.
The "Stack Pointer" is a register that keeps track of the address of the bottom of the stack. So that the CPU knows where to "push" the next value to, or "pull" it from. The TXS instruction transfers the value of the X register to the "Stack Pointer". It doesn't put the value of X on the stack. The ECU program uses the TXS instruction to initialise the stack pointer to the top of the RAM when the Reset Vector is called.

The instructions PSH and PUL are used for putting things on and off the stack. As I explained elsewhere, when you JSR to a subroutine, the return address is "pushed" onto the stack, so that when you RTS, the CPU can "pull" it off the stack and go back to it.
Quote
Anyhow, just read the other thread, need to sit down and digest it all, the fuel map is interesting if they are all the same location, means "tuning" would be fairly straightforward for all the vehicles without hunting around for maps in code. But still miles away from that!
I've seen dumps of tuner modified ECUs. Generally, they only modify the fuel and timing maps and maybe the rev and speed limiters. These things are not too hard to find. But there are literally dozens of other maps in the ECU and I suspect most tuners don't understand what they are for.
Quote
Wish I could just go to sleep and wake up and know everything!

What would be useful, and I noticed that the disassembler can possibly do it, is if the function Stx, lda, ax etc would be written completely behind the text like a note. so you'd have :

00A51C    0C2D1040      seb     #0x40, 0x102d

Turns into:

00A51C    0C2D1040      seb     #0x40, 0x102d ;Set Bits 0x40 at address 0x102d.

That would make it so much easier to understand and read what's going on (Yes, i'm one of these weird people that draws images in their head of situations and links, like big flow charts, to understand them. I think its called Visual Mathematician or something like that...)

Cheers,
Daniel.

I see what you mean. Those comments would tell you "what" the instruction was doing, but not "why" it is doing it, or what that bit of 102D represents. I'm not sure whether it would be easy to add that functionality to the disassembler.

If you can recognise Load, Store, Compare, Branch instructions then you are halfway there. You can always lookup the others in the manual when you encounter them.

I agree that drawing flowcharts and running through the code on paper or in a simulator is the best way to understand it. It does get easier the more you look at it.
« Last Edit: February 06, 2009, 05:55:31 AM by b3lha » Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #21 on: February 06, 2009, 08:54:29 AM »

Im Back!!

Hardly any snow here! Its stupid.. I really want snow to mess around with and beat all the "inferior" non AWD cars, but the snow has only been here for the last 2 days, and melts within an hour! Rubbish!
Yeah. We had about 4 inches on Sunday night but the roads were all clear by the time I went to work. I tried to have some fun in the office car park, but my Legacy doesn't handbrake turn very well. At times like this I miss my wife's old Mk1 Justy. Now that was a really fun car in the snow.
I just went on a rampage and started hunting for things within the 102D, then 102E address, before giving up.

Code:
-findstr 102d Sub-* | findstr seb
Sub-A4F4.txt:00A51C    0C2D1040      seb     #0x40, 0x102d
Sub-A533.txt:00A568    0C2D1004      seb     #0x04, 0x102d
Sub-A582.txt:00A59A    0C2D1020      seb     #0x20, 0x102d

Then decided to go for the first one 0x40.

0x40 of 102D is the Neutral Switch Error Flag. So presumably the Select Monitor Parameter that you are hunting for is the switch flags (Mode FA0)? This one is a little more complex. The error test is probably something like checking it has seen the switch in both the off and on positions by the time you reach a particular speed.

Looking at Sub-A4F4 I notice this line:
Code:
00A503    2C0020011F    bbs     #0x01, 0x2000, 0xa527
We know that the address 0x2000 is not in our RAM or ROM areas. So it might be some sort of memory-mapped digital input. What I mean is that the 8 bits of the memory location are connected to a series of 8 pins on the ECU. If a pin is grounded, the corresponding bit in the memory location is 1, otherwise 0.
It is possible that the Neutral Switch might be connected to bit 0 of address 2000. This is not definite, but it's worth investigating. You could test this by logging address 2000 while moving the gear stick around and seeing if the value changes.
The select monitor probably reads the switch flags from RAM rather than directly from the digital input, so the next step is to find a piece of code that loads the values from 2000 and stores them somewhere in RAM.
Code:
H:\SVX\Daniel>findstr 0x2000 Sub-* | findstr ld
Sub-EFE4.txt:00EFF4    AD0020        lda     al, 0x2000
Sub-9780.txt:009A48    9C54100020    ldm     #0x2000, 0x1054
Sub-EFE4 is the one we are looking for. It loads the value from address 2000 into AL.
Sub-9780 is storing the immediate value 2000 in address 1054. Not what we are looking for.

In Sub-EFE4, we see it load the value from address 2000. Then it monkeys around a bit. Then it stores AL at 1300 and later at 105A. After that it loads a new value into AL so the rest of the subroutine is irrelevant.
As a first guess, I would say that the switch flags you are looking for might be at 105A. But you'll have to log it and compare to the Select Monitor Instructions to find out.

IIRC that's the same place as in my SVX rom. And the other switch flags (FA1 to FA3) are at 105B, 105C and 105D.
Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #22 on: February 06, 2009, 09:29:10 AM »

Had a rake through all those files, and discovered that in each one of those txt files looking down the lines of code that anything that was being "loaded" were set values using the hash (#) Prefix, and not other addresses or A/D stuff.
So i tried the same for 0x04 and 0x20 from 102D and figured out that none of them apply to my car.
Neutral Switch. Not in use!
Engine Torque Control. Not in use!
CO Resistor. Not in use!

Every address is loaded with a set value in the code.

I then went onto 102E but lost track.

I don't know if I'm doing this right but basically all of 102D doesn't do anything in my car?
or am I going horribly wrong somewhere?
I think that CO Resistor does apply to your car. I have no idea what a CO resistor is or what it does, but it looks like an easy parameter to find. Have another try.

Step 1. Find the subroutine that sets the error code.

Step 2. The subroutine loads a 16bit value from an address and compares it against two limits. If it falls outside of the limits then the counter is incremented. Once the counter passes a threshold, the error flag is set.  If the value falls within the limits then the error flag is cleared and the counter is zeroed.

Step 3. Take the address you found in Step 2 and look for where it is calculated. Remember:  Subroutines that STORE the value are where it is calculated. Subroutines which LOAD the value are where it is used. So we are looking for the subroutine that stores a value in the address you found in step 2.

In this case we don't find anything like "STA address". Sad But there is one that looks a little different to the others. It loads the address as an immediate value into the X register and then does an indexed store STA AX, DP + 0x00 + IX. So it's storing the value of AX in that address. Cheesy

Step 4. Having found the right subroutine, you can see that it divides the value by 4 to make it small enough to fit in 8 bits and then stores it at an address. This is the 8-bit parameter for reading the CO Resistor voltage.

Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #23 on: February 06, 2009, 11:55:39 AM »

Step 1. Find the subroutine that sets the error code.
Code:
findstr 102d sub-* | findstr seb
Sub-A4F4.txt:00A51C    0C2D1040      seb     #0x40, 0x102d
Sub-A533.txt:00A568    0C2D1004      seb     #0x04, 0x102d
[b]Sub-A582.txt:00A59A    0C2D1020      seb     #0x20, 0x102d[/b]

Step 2. The subroutine loads a 16bit value from an address and compares it against two limits. If it falls outside of the limits then the counter is incremented. Once the counter passes a threshold, the error flag is set.  If the value falls within the limits then the error flag is cleared and the counter is zeroed.

Code:
Sub-A582.txt
00A582    A25512        ldx     #0x1255                         ; Call target from 9E3A
[b]00A585    AC5212        ldy     0x1252[/b]
00A588    CCA68C        cpy     0x8ca6
00A58B    B005          bcs     0xa592
00A58D    CCAC8C        cpy     0x8cac
00A590    B00D          bcs     0xa59f
00A592    206296        jsr     0x9662                          ; Branch target from A58B
00A595    CDAA8C        cmp     al, 0x8caa
00A598    9004          bcc     0xa59e
00A59A    0C2D1020      seb     #0x20, 0x102d
00A59E    60            rts                                     ; Branch target from A598

00A59F    1C2D1020      clb     #0x20, 0x102d                   ; Branch target from A590
00A5A3    740000        ldm     #0x00, dp + 0x00 + ix
00A5A6    60            rts   

Step 3. Take the address you found in Step 2 and look for where it is calculated. Remember:  Subroutines that STORE the value are where it is calculated. Subroutines which LOAD the value are where it is used. So we are looking for the subroutine that stores a value in the address you found in step 2.

Code:
findstr 1252 sub-*
Sub-A582.txt:00A585    AC5212        ldy     0x1252
Sub-B106.txt:00B120    AD5212        lda     ax, 0x1252
Sub-B106.txt:00B18D    AD5212        lda     ax, 0x1252
Sub-DE07.txt:00DE10    890D5212      mpy     0x1252
Sub-DE07.txt:00DE18    42AD5212      lda     bx, 0x1252
[b]Sub-E1DE.txt:00E234    A25212        ldx     #0x1252[/b]

In this case we don't find anything like "STA address". Sad But there is one that looks a little different to the others. It loads the address as an immediate value into the X register and then does an indexed store STA AX, DP + 0x00 + IX. So it's storing the value of AX in that address. Cheesy

Step 4. Having found the right subroutine, you can see that it divides the value by 4 to make it small enough to fit in 8 bits and then stores it at an address. This is the 8-bit parameter for reading the CO Resistor voltage.

Code:
Sub-E1DE.txt
00E1DE    342008FC      bbc     #0x08, dp + 0x20, 0xe1de        ; Call target from DB26, Read from A/D control register, Branch target from E1DE
00E1E2    AD7111        lda     al, 0x1171
00E1E5    C902          cmp     al, #0x02
00E1E7    D01A          bne     0xe203
00E1E9    D8            clm                                     ; m:0 x:0
00E1EA    A522          lda     ax, dp + 0x22                   ; Read from A/D successive approximation register
00E1EC    A24210        ldx     #0x1042
00E1EF    3C2510010005  bbc     #0x0001, 0x1025, 0xe1fa
00E1F5    2080E2        jsr     0xe280
00E1F8    8005          bra     0xe1ff

00E1FA    0C25100100    seb     #0x0001, 0x1025                 ; Branch target from E1EF
00E1FF    9500          sta     ax, dp + 0x00 + ix              ; Branch target from E1F8
00E201    F8            sem                                     ; m:1 x:0
00E202    60            rts     

00E203    C901          cmp     al, #0x01                       ; Branch target from E1E7
00E205    D026          bne     0xe22d
00E207    D8            clm                                     ; m:0 x:0
00E208    A522          lda     ax, dp + 0x22                   ; Read from A/D successive approximation register
00E20A    8D6C12        sta     ax, 0x126c
00E20D    A23A10        ldx     #0x103a
00E210    2C2E10010009  bbs     #0x0001, 0x102e, 0xe21f
00E216    3C2510040003  bbc     #0x0004, 0x1025, 0xe21f
00E21C    2080E2        jsr     0xe280
00E21F    0C25100400    seb     #0x0004, 0x1025                 ; Branch target from E210, Branch target from E216
00E224    9500          sta     ax, dp + 0x00 + ix
00E226    4A            lsr     ax
00E227    4A            lsr     ax
00E228    F8            sem                                     ; m:1 x:0
00E229    8D2C13        sta     al, 0x132c
00E22C    60            rts     

00E22D    C906          cmp     al, #0x06                       ; Branch target from E205
00E22F    D01C          bne     0xe24d
00E231    D8            clm                                     ; m:0 x:0
00E232    A522          lda     ax, dp + 0x22                   ; Read from A/D successive approximation register
[b]00E234    A25212        ldx     #0x1252
00E237    3C2510100003  bbc     #0x0010, 0x1025, 0xe240
00E23D    2080E2        jsr     0xe280
00E240    0C25101000    seb     #0x0010, 0x1025                 ; Branch target from E237
00E245    9500          sta     ax, dp + 0x00 + ix
00E247    4A            lsr     ax
00E248    4A            lsr     ax
00E249    F8            sem                                     ; m:1 x:0
00E24A    8D2D13        sta     al, 0x132d
00E24D    60            rts                                     ; Branch target from E22F[/b]

So 132d should be my 8 bit address for CO resistor (whatever it is, hopefully Brett might know!)
Is this right?

Another question.. In some examples it does one lsr ax, in others two, in others three and in others four!
If its 16bit.. surely you only want to devide it in half once to make it 8 bit?

Cheers,
Daniel.
Logged
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #24 on: February 06, 2009, 04:43:16 PM »


So 132d should be my 8 bit address for CO resistor (whatever it is, hopefully Brett might know!)
Is this right?

Yes. You've got it now. Well Done.

Another question.. In some examples it does one lsr ax, in others two, in others three and in others four!
If its 16bit.. surely you only want to devide it in half once to make it 8 bit?

Cheers,
Daniel.

Actually, you need to divide by 256 to make it 8 bit (8 right shifts). An eight bit number can hold values up to 255 (0xFF). Each extra bit doubles the range. A 16 bit number can hold values up to 65535 (0xFFFF). It's the same principle as with decimal, where an extra column multiplies the range by 10.

In this subroutine the A/D Converter hardware has 10 bits, but the value is stored as 16 bits. That is why there are two right shifts to convert it to 8 bits.
Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #25 on: February 16, 2009, 06:55:29 AM »

Hey Daniel,

I just been comparing your Legacy ECU with my Legacy ECU. The program code is identical, and so are the parameter addresses. I strongly suspect the hardware is the same too. The only differences are in the maps and data.

I found another map hidden amongst the code at address 9670. It is blank on your car but has data on mine. I don't know what it is for.

Phil.
Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #26 on: February 16, 2009, 07:20:28 AM »

Its the same as yours?! What number is your ECU?

I have to admit I've been a bit sidetracked doing other things over the last week, but I'm sure I'll get back to it sooner or later.

So does that mean you can share all your parameters? Grin

Cheers,
Daniel.
Logged
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #27 on: February 16, 2009, 08:43:52 AM »

Mine is a '96 GX Wagon with the EJ22 engine. Rom ID: 7432A1.

As I said, the program code is identical, only the maps and constants differ (1927 bytes out of 32768).

I haven't done much work on understanding this ECU, but I have a good set of parameters. They should work for you also.

10a2 AFR Correction
109a Advance
1305 Load
1306 Injector Pulse Width
1307 MAF Sensor Voltage
1308 Mass Airflow
1310 O2 Sensor
1314 ISC Duty Cycle
1328 Knock Correction
1329 TPS
1335 Battery Voltage
1336 Speed
1337 Coolant Temp
1338 RPM
133a O2 Max
133b O2 Min
Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
b3lha
*
Offline Offline

Posts: 198



View Profile WWW
« Reply #28 on: February 19, 2009, 10:47:29 AM »

Daniel, you were asking before about RomRaider definitions.

Here is a RomRaider definition file that will allow you to look at the fuel and timing tables. I have added definitions for your 742FA1, my 7432A1 and Brett's 703315. It is designed to work with the 32K ROM dump that you extracted with the Polaris tool.

Just three tables for now. Lots more to be added when they are decoded.

EDIT: Branden asked me to clarify this post with an explanation of RomRaider and what can be done with it. I'm no expert with it because I haven't really used it much.

For later model ECUs, RomRaider can be used to read the ROM, modify the maps (tune the engine), and flash the modified ROM back to the ECU. I think it does some datalogging too, but not to the same extent as Evoscan.

For the early ECUs that we're discussing in this thread, you have to use a different tool to read the ROM to a file. Then you can use RomRaider to modify the maps in the ROM file. These older ECUs can't be flashed. You have to burn the modified ROM into an EPROM chip and insert it into the ECU. In some cases, hardware modification, and/or a daughterboard will also be required.

The definitions that I posted are *untested* and simply a starting point for further work. I would not advise anyone to try and use them to tune their engine without doing their own extensive research first.

The RomRaider FAQ should answer most questions better than I can: http://www.romraider.com/Documentation/RomRaiderFAQ

To use RomRaider with a 703315, 742FA1 or 7432A1 ECU, copy the xml file posted here to your RomRaider directory. Then run RomRaider and go into "ECU Definition Manager". Add the file to the list of ECU definitons and click "Save". Then go into "File/Open Image" and open the 32K ROM file that you extracted from the ECU. You can then view and modify the various maps.
« Last Edit: February 20, 2009, 08:50:41 AM by b3lha » Logged

See my Subaru ECU and TCU website.
http://www.alcyone.org.uk/ssm
mrdjc
*
Offline Offline

Posts: 38


View Profile
« Reply #29 on: February 21, 2009, 06:36:34 AM »

Oooh nice work!

I'm still far to busy out and about so haven't got round to finding out more.. But one of these days I will!

Just had a look with romraider... Its not very.. uniform is it?
The Fuel map, I take it it is a learned map? Or are these hard written into the code?

The advance and base timing look alright.. but doesn't quite look like what I thought it would..
I know if i sit in 2nd gear doing 30 for a few sec at about 3500-4000RPM then nail it, its as fast as it goes.. just pulls and pulls.  But the advance is almost none there.. The base timing however.. High rpm, low load (low speed)  makes sense!

Might actually learn something!

Anyhow, good job putting that together.. now that I can see the map I might actually get some motivation!

We're currently gutting the upstairs of the house, re-paneling and insulating, Im meant to be widening 40M of driveway (built on peat..) And we are also doing drains around a building and widening bit more of road, as well as putting in ducting for cables... then half the house is getting rewired with Cat6 network cable and WF100 Sat cable.

Bit busy!

Cheers,
Daniel.
Logged
Pages: 1 [2] 3 4
Print
Jump to: