So the next step is to see how the ECU's internal error handling maps to these trouble codes. First we find the subroutine that references this error table.
We use the findstr program to search the subroutines for the address A8FB, and it finds Sub-A891.txt.
findstr a8fb sub-*
Sub-A891.txt:00A8F0 69FBA8 adc ax, #0xa8fb
No surpise. It is the subroutine immediately before the error table. As I said before, Sub-A891 is an error code lookup subroutine. I'm going over this step again because I glossed over it a bit before.
There are two types of errors in the Subaru ECU. Current Errors and Stored Errors. When you do the diagnostics, the ECU flashes one set or the other on the CE light. Which set gets flashed depends on how you connect the diagnosic plugs. Sub-A891 is used for both of these diagnostic procedures, but it is called differently for each.
Lets have a look at how Sub-A891 is called:
findstr a891 Sub-*
Sub-A747.txt:00A7A7 2091A8 jsr 0xa891
Sub-A747.txt:00A803 2091A8 jsr 0xa891
Sub-A747.txt:00A83E 2091A8 jsr 0xa891
Sub-A891.txt:00A8E6 F0A9 beq 0xa891
So Subroutine A891 is called 3 times by Subroutine A747. Open Sub-A747 in notepad and you should find the following.
00A7A4 A24140 ldx #0x4041
00A7A7 2091A8 jsr 0xa891
blah blah blah
00A800 A23944 ldx #0x4439
00A803 2091A8 jsr 0xa891
blah blah blah
00A83B A24140 ldx #0x4041
00A83E 2091A8 jsr 0xa891
The way this works is that the program sets the X register to point at the location of the internal error flags before it calls Sub-A891. So, to lookup the current error codes, it sets X to the location of the current error flags. To lookup the stored error codes, it sets X to the location of the stored error flags. I don't know why there are two calls with X set to 4041, but it doesn't really matter for what we are doing so I'm not going to investigate that now.
The important thing to realise is that we have found the internal error flags at 4041 and 4439. One set is for current errors and one for stored errors. We can figure out which is which quite simply:
findstr 4041 Sub-*
this produces lots of matches (probably the current errors)
findstr 4439 Sub-*
this produces only a few matches (probably the stored errors)
Now we have to figure out the size of the error flags. In both of the ECUs that we are looking at, there are 24 error codes (including the unused ones set to 00). That's 3x8 so probably there are three bytes of error flags.
This is confirmed by at what Sub-A891 does with the X value passed in;
00A8AA B500 lda al, dp + 0x00 + ix
...
00A8B2 B501 lda al, dp + 0x01 + ix
...
00A8BA B502 lda al, dp + 0x02 + ix
These three lines mean
Load the al register with the value at (address stored in the X register)+0 (ie. load al with the value at 4041)
Load the al register with the value at (address stored in the X register)+1 (ie. load al with the value at 4042)
Load the al register with the value at (address stored in the X register)+2 (ie. load al with the value at 4043)
So that's another indication that the address flags are three bytes long 4041-4043 for the current errors and 4439-443B for the stored errors.