We're trying to solve a puzzle on one of the automotive forums regarding how the BMW S62 engine utilizes its two MAF (mass air flow) sensors to determine the air mass flow entering the engine. This sensor is critical for correct engine operation and people often replace the sensor without knowing for sure if it needs to be replaced. By understanding how the ECU utilizes the sensor, one can devise a simple test with a multimeter to confirm or disprove whether a new sensor is needed.
Someone has access to the disassembled instructions for the ECU (Motorola M68000) and has shared screenshots of the two subroutines which he believes are relevant to mass air flow evaluation.
There are a few schools of thought as to what is happening here:
The average of the two MAF sensor voltages is being used. I don't see that in this particular set of instructions.
The result from the lookup table is halved.
The two results are computed separately and then added together. This however conflicts with the field data collected.
Only one sensor is being used (in other words, the sense of the S62 check is inverted, but it physically makes no sense)
Could someone help me to make sense of what the instructions are doing? Here is my stab at it, I just cannot "piece" it all together to make sense of it:
sub_12D96: move.l a2, -(sp) ; Push long value at address a2 to stack movea.l #SYS_TIMERTICS_COUNTER, a2 ; Move SYS_TIMERTICS_COUNTER address to a2 btst #7, (PSYNC_ST).l ; Bit-test on something, not sure how this works beq.s loc_12E02 ; If true, go to loc_12E02, else continue move.b (ZUSTAND_MOTOR).l, d0 ; Move a byte from ZUSTAND_MOTOR address to data register d0 andi.b #$1C, d0 ; Bitwise-and 0x1C with data register d0 ; [to check if engine is running] beq.s loc_12DEE ; If binary-equal, go to loc_12DEE, else continue pea (1).w ; Push effective address onto stack (does this set stack pointer?) move.w (HFM1_AD).l, d0 ; Move word value from HFM1_AD to data register d0 (why move.w and not move.l?) move.l d0, -(sp) ; Push long value to stack jsr sub_1AA3A ; Jump to subroutine sub_1AA3A addq.l #8, sp ; Add 8 to stack pointer (move stack pointer address by 8?) move.b (K_MOTORTYP).l, d0 ; Move byte from K_MOTORTYP to data register d0 andi.l $#EF, d0 ; Bitwise-and 0xEF with data register d0 moveq #$20, d1 ; Move 0x20 to data register d1 cmp.l d0, d1 ; Compare d0 with d1 bne.s loc_12DEE ; If binary-not-equal, go to loc_12DEE, else continue pea (2).w ; Push effective address onto stack (does this set stack pointer?) move.w (HFM2_AD).l, d0 ; Move word value from HFM2_AD to data register d0 (why move.w and not move.l?) move.l d0, -(sp) ; Push long value to stack jsr sub_1AA3A ; Jump to subroutine sub_1AA3A sub_1AA3A: arg_2= 6 ; define constant (arg_2 = 6) arg_7= $B ; define constant (arg_7 = 11) clr.l d0 clr.w d1 move.w arg_2(sp), d0 ; move a word 6 places after stack pointer to d0 lsl.w #3,d0 ; left-shift the word at d0 by 3 bits (multiply by 8) tbls.w (KL_HFM_ML_V_b).l, d0 ; lookup word from KL_HFM_ML_V_b table with d0 as input