DSM/ECU: Difference between revisions

From Jane Hacker Wiki
Jump to navigation Jump to search
Line 63: Line 63:
** tasm6111.tab
** tasm6111.tab
** standard_E932.lst
** standard_E932.lst
** <code>
** <pre>
This is the symbolic and commented source code for the DSM E931
This is the symbolic and commented source code for the DSM E931
and E932 ECU. To assemble "standard_E932_E931_source.asm",
and E932 ECU. To assemble "standard_E932_E931_source.asm",
Line 86: Line 86:
TASM compatible opcodes for the E931/E932 ECUs. Works with the provided source files. Might be incomplete if you want to use something not already used by the standard code...
TASM compatible opcodes for the E931/E932 ECUs. Works with the provided source files. Might be incomplete if you want to use something not already used by the standard code...
</code>
</pre>
* http://www.bcdsm.org/forum/index.php?topic=11843.0
* http://www.bcdsm.org/forum/index.php?topic=11843.0
** https://web.archive.org/web/20050301180032/http://www.ece.ubc.ca/~elec259/Static/datasheets/M68HC11RM.pdf
** https://web.archive.org/web/20050301180032/http://www.ece.ubc.ca/~elec259/Static/datasheets/M68HC11RM.pdf

Revision as of 12:29, 1 May 2021

General

- https://web.archive.org/web/20050427181808/http://dsm-ecu.com/

ECU troubleshooting and daughterboard [RUS]

ECU numbers

EPROM images

Editing notes

E931 disassembly with comments

More decompile

http://www.ceddy.us/

Processor info

Docs

This is the symbolic and commented source code for the DSM E931 and E932 ECU. To assemble "standard_E932_E931_source.asm", download the telemark assembler TASM from http://home.comcast.net/~tasm/ to the same directory and execute asm.bat from the DOS prompt. The assembler will produce two files: standard_E932_E931_source.lst is a line by line listing of the assembly with addresses while standard_E932_E931_source.obj is the 32KB binary image to burn on EPROM. Default setting produces the E931 standard binary image Required file, not provided (from http://home.comcast.net/~tasm/): TASM.EXE, Version 3.2 Contents: standard_E932_E931_source.asm Assembly source file for the E931/E932. See notes at the beginning of that file for more details. Default setting produces the standard E931 EPROM image. asm.bat Batch file to assemble standard_E932_E931_source.asm standard_E931.bin Binary file read from an actual E931 EPROM. Assembly of standard_E932_E931_source.asm using the "E931" setting should produce an identical binary. standard_E932.bin Binary file read from an actual E932 EPROM. Assembly of standard_E932_E931_source.asm using the "E932" setting should produce an identical binary. standard_E931.lst Assembly listing file for the standard E931, usefull if you just want to edit an EPROM image without assembly.. standard_E932.lst Assembly listing file for the standard E932, usefull if you just want to edit an EPROM image without assembly.. tasm6111.tab TASM compatible opcodes for the E931/E932 ECUs. Works with the provided source files. Might be incomplete if you want to use something not already used by the standard code... Christian [email protected]

MH6111 Instruction Set

00 TEST
01 NOP
02 AIM DIR
03 OIM DIR
04 LSRD
05 ASLD
06 TAP
07 TPA
08 INX
09 DEX
0A CLV
0B SEV
0C CLC
0D SEC
0E CLI
0F SEI
1 * 1 2 3 ? 3 ? 1 3 1 3 1 2 1 2 1 3 1 3 1 2 1 2 1 2 1 2 1 2 1 2
TEST OPERATION TEST MODE ONLY NO OPERATION
AND IN MEMORY
OR IN MEMORY
LOGICAL SHIFT RIGHT DOUBLE ACCUMULATOR ARITHMETIC / LOGICAL SHIFT LEFT DOUBLE ACC TRANSFER FROM ACC A TO CONDITION CODE REGISTER TRANSFER FROM CONDITION CODE REGISTER TO ACC A INCREMENT INDEX REGISTER X
DECREMENT INDEX REGISTER X
CLEAR TWOS COMPLEMENT OVERFLOW BIT
SET TWOS COMPLEMENT OVERFLOW BIT
CLEAR CARRY
SET CARRY
CLEAR INTERRUPT MASK
SET INTERRUPT MASK
10 SBA
11 CBA
14 IDIV
15 FDIV
16 TAB
17 TBA
18 XGXY
19 DAA
1A XGDX
1B ABA
1C CPD
1D CPD
1F CPD
20 BRA
21 BRN
22 BHI
23 BLS
24 BCC
25 BCS
26 BNE
27 BEQ
28 BVC
29 BVS
2A BPL
2B BMI
2C BGE
2D BLT
2E BGT
2F BLE
SUBTRACT ACCUMULATORS
COMPARE ACCUMULATORS
INTEGER DIVIDE
FRACTIONAL DIVIDE
TRANSFER ACCUMULATOR A TO ACCUMULATOR B TRANSFER FROM ACCUMULATOR B TO ACCUMULATOR A EXCHANGE REGISTER X AND REGISTER Y
DIR DIR
IMM DIR EXT
/ BHS / BLO
30 TSX
31 INS
32 PULA
33 PULB
34 DES
35 TXS
36 PSHA
37 PSHB
38 PULX
39 RTS
3A ABX
3B RTI
1 2
1 2
2 6
2 6
1 2
1 2
1 4
1 2
1 EXCHANGE DOUBLE ACCUMLATOR AND INDEX REG X
/ LSLD
1 2 3 5 2 6 3 7
2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3
1 3 1 3 1 4 1 4 1 3 1 3 1 3 1 3 1 5 1 5 1 3 1 12
ADD ACCUMULATOR B TO ACCUMULATOR A COMPARE DOUBLE ACCUMULATOR
COMPARE DOUBLE ACCUMULATOR
COMPARE DOUBLE ACCUMULATOR
BRANCH ALWAYS
BRANCH NEVER
BRANCH IF HIGHER
BRANCH IF LOWER OR SAME
BRANCH IF CARRY CLR / BRANCH IF HIGHER OR SAME BRANCH IF CARRY SET / BRANCH IF LOWER
BRANCH IF NOT EQUAL TO ZERO BRANCH IF EQUAL
BRANCH IF OVERFLOW CLEAR BRANCH IF OVERFLOW SET BRANCH IF PLUS
BRANCH IF MINUS
BRANCH IF GREATER THAN OR EQUAL TO ZERO BRANCH IF LESS THAN ZERO
BRANCH IF GREATER THAN ZERO
BRANCH IF LESS THAN OR EQUAL TO ZERO
TRANSFER FROM STACK POINTER TO INDEX REGISTER X INCREMENT STACK POINTER
PULL DATA FROM STACK
PULL DATA FROM STACK
DECREMENT STACK POINTER
TRANSFER FROM INDEX REGISTER X TO STACK POINTER PUSH DATA ONTO STACK
PUSH DATA ONTO STACK
PULL INDEX REGISTER X FROM STACK
RETURN FROM SUBROUTINE
ADD ACCUMULATOR B TO INDEX REGISTER X
RETURN FROM INTERRUPT
DECIMAL ADJUST ACCUMULATOR A
https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&ft=1619871639&lt=11619875
2
2

https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&2ft0=2116-10958-70116, 389:2&1ltA=M1619875
3C PSHX
3D MUL
3E WAI
3F SWI
40 NEGA
43 COMA
44 LSRA
46 RORA
47 ASRA
48 ASLA
49 ROLA
4A DECA 4C INCA 4D TSTA 4F CLRA
50 NEGB
53 COMB
54 LSRB
56 RORB
57 ASRB
58 ASLB
59 ROLB
5A DECB 5C INCB 5D TSTB 5F CLRB
14 1 10 1 14 1 14
PUSH INDEX REGISTER X ONTO STACK MULTIPLY UNSIGNED
WAIT FOR INTERRUPT
SOFTWARE INTERRUPT
60 NEG IND,X
63 COM IND,X
64 LSR IND,X
66 ROR IND,X
67 ASR IND,X
68 ASL / LSL
69 ROL IND,X
6A DEC IND,X 6C INC IND,X
6D TST IND,X
6E JMP IND,X
6F CLR IND,X
70 NEG EXT
73 COM EXT
74 LSR EXT
76 ROR EXT
77 ASR EXT
78 ASL / LSL
79 ROL EXT
7A DEC EXT 7C INC EXT
7D TST EXT
7E JMP EXT
7F CLR EXT
80 SUBA IMM
81 CMPA IMM
82 SBCA IMM
83 SUBD IMM
84 ANDA IMM
IND,X
26 NEGATE
26 COMPLEMENT
26 LOGICAL SHIFT RIGHT
26 ROTATE RIGHT
26 ARITHMETIC SHIFT RIGHT
26 ARITHMETIC / LOGICAL SHIFT LEFT 26 ROTATE LEFT
26 DECREMENT
26 INCREMENT
2 6 TEST
2 3 JUMP
26 CLEAR
36 NEGATE
36 COMPLEMENT
36 LOGICAL SHIFT RIGHT
36 ROTATE RIGHT
36 ARITHMETIC SHIFT RIGHT
36 ARITHMETIC / LOGICAL SHIFT LEFT 36 ROTATE LEFT
36 DECREMENT
36 INCREMENT
36 TEST
33 JUMP
36 CLEAR
22 SUBTRACT
22 COMPARE
22 SUBTRACT WITH CARRY
34 SUBTRACT DOUBLE ACCUMULATOR 22 LOGICAL AND
/ LSLA
/ LSLB
COMPLEMENT
LOGICAL SHIFT RIGHT
ROTATE RIGHT
ARITHMETIC SHIFT RIGHT ARITHMETIC / LOGICAL SHIFT LEFT ROTATE LEFT
DECREMENT
INCREMENT
EXT
1 2 NEGATE
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2 12TEST 1 2 CLEAR
1 2 NEGATE
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2 12TEST 1 2 CLEAR
COMPLEMENT
LOGICAL SHIFT RIGHT
ROTATE RIGHT
ARITHMETIC SHIFT RIGHT ARITHMETIC / LOGICAL SHIFT LEFT ROTATE LEFT
DECREMENT
INCREMENT
https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&ft=1619871639&lt=12619875
2
2

https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&2ft0=2116-10958-70116, 389:2&1ltA=M1619875
85
86
87
88
89
8A
8B
8C
8D
8E
8F
90
91
92
93
94
95
96
97
98
99
9A
9B
9C
9D
9E
9F
A0
A0 80 A1
A1 80 A2
A2 80 A3
A3 80 A4
A4 80 A5
A5 80 A6
A6 80 A7
A7 80 A8
A8 80 A9
A9 80 AA
AA 80 AB
AB 80 AC
AC 80 AD
AD 80 AE
AE 80 AF
BITA IMM 2 2 LDAA IMM 2 2 BRSET DIR 4 EORA IMM 2 2 ADCA IMM 2 2 ORAA IMM 2 2 ADDA IMM 2 2 CPX IMM 3 4 BSR 2 6 LDS IMM 3 3 BRCLR DIR 4
SUBA DIR 2 3 CMPA DIR 2 3 SBCA DIR 2 3 SUBD DIR 2 5 ANDA DIR 2 3 BITA DIR 2 3 LDAA DIR 2 3 STAA DIR 2 3 EORA DIR 2 3 ADCA DIR 2 3 ORAA DIR 2 3 ADDA DIR 2 3 CPX DIR 2 5 JSR DIR 2 5 LDS DIR 2 4 STS DIR 2 4
SUBA IND,X 2 4 SUBA IND,Y 2 CMPA IND,X 2 4 CMPA IND,Y+ 2 SBCA IND,X 2 4 SBCA IND,Y 2 SUBD IND,X 2 6 SUBD IND,Y 2 6 ANDA IND,X 2 4 ANDA IND,Y 2 4 BITA IND,X 2 4 BITA IND,Y 2 4 LDAA IND,X 2 4 LDAA IND,Y+ 2 STAA IND,X 2 4 STAA IND,Y 2 EORA IND,X 2 4 EORA IND,Y 2 4 ADCA IND,X 2 4 ADCA IND,Y 2 4 ORAA IND,X 2 4 ORAA IND,Y 2 4 ADDA IND,X 2 4 ADDA IND,Y 2 4 CPX IND,X 2 6 CPX IND,Y 2 6 JSR IND,X 2 6 JSR IND,Y 2 LDS IND,X 2 5 LDS IND,Y 2 5 STS IND,X 2 5
BIT TEST
LOAD ACCUMULATOR
BRANCH IF BIT(S) ARE SET EXCLUSIVE OR
ADD WITH CARRY
INCLUSIVE OR
ADD WITHOUT CARRY
COMPARE INDEX REGISTER X BRANCH TO SUBROUTINE
LOAD STACK POINTER
BRANCH IF BIT(S) ARE CLEAR
SUBTRACT
COMPARE
SUBTRACT WITH CARRY SUBTRACT DOUBLE ACCUMULATOR LOGICAL AND
BIT TEST
LOAD ACCUMULATOR
STORE ACCUMULATOR
EXCLUSIVE OR
ADD WITH CARRY
INCLUSIVE OR
ADD WITHOUT CARRY
COMPARE INDEX REGISTER X JUMP TO SUBROUTINE
LOAD STACK POINTER
STORE STACK POINTER
SUBTRACT
SUBTRACT
COMPARE
COMPARE WITH/Y+
SUBTRACT WITH CARRY SUBTRACT WITH CARRY SUBTRACT DOUBLE ACCUMULATOR SUBTRACT DOUBLE ACCUMULATOR LOGICAL AND
LOGICAL AND
BIT TEST
BIT TEST
LOAD ACCUMULATOR
LOAD ACCUMULATOR WITH/Y+ STORE ACCUMULATOR
STORE ACCUMULATOR EXCLUSIVE OR EXCLUSIVE OR
ADD WITH CARRY ADD WITH CARRY INCLUSIVE OR INCLUSIVE OR
ADD WITHOUT CARRY
ADD WITHOUT CARRY COMPARE INDEX REGISTER X COMPARE INDEX REGISTER X JUMP TO SUBROUTINE
JUMP TO SUBROUTINE
LOAD STACK POINTER
LOAD STACK POINTER
STORE STACK POINTER
https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&ft=1619871639&lt=13619875
2
2

https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&2ft0=2116-10958-70116, 389:2&1ltA=M1619875
AF 80
B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
BA
BB
BC
BD
BE
BF
C0
C1
C2
C3
C4
C5
C6
C8
C9
CA
CB
CC
CD 08 CD 09 CD 1A CD 3A CD 8C CD CE CD DF CD EE
CE CF
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
DA
DB
DC
DD
STS IND,Y 2 5
SUBA EXT 3 4 CMPA EXT 3 4 SBCA EXT 3 4 SUBD EXT 3 6 ANDA EXT 3 4 BITA EXT 3 4 LDAA EXT 3 4 STAA EXT 3 4 EORA EXT 3 4 ADCA EXT 3 4 ORAA EXT 3 4 ADDA EXT 3 4 CPX EXT 3 6 JSR EXT 3 6 LDS EXT 3 5 STS EXT 3 5
SUBB IMM 2 2 CMPB IMM 2 2 SBCB IMM 2 2 ADDD IMM 3 4 ANDB IMM 2 2 BITB IMM 2 2 LDAB IMM 2 2 EORB IMM 2 2 ADCB IMM 2 2 ORAB IMM 2 2 ADDB IMM 2 2 LDD IMM 3 3
INY 2 4 DEY 2 4 XGDY 2 ABY 2 CMPY IMM, Y++ 4 LDY IMM 4 4 STY DIR 3 5 LDY IND,X 3 6
LDX IMM 3 3 ***** 3
SUBB DIR 2 3 CMPB DIR 2 3 SBCB DIR 2 3 ADDD DIR 2 5 ANDB DIR 2 3 BITB DIR 2 3 LDAB DIR 2 3 STAB DIR 2 3 EORB DIR 2 3 ADCB DIR 2 3 ORAB DIR 2 3 ADDB DIR 2 3 LDD DIR 2 4 STD DIR 2 4
STORE STACK POINTER
SUBTRACT
COMPARE
SUBTRACT WITH CARRY SUBTRACT DOUBLE ACCUMULATOR LOGICAL AND
BIT TEST
LOAD ACCUMULATOR
STORE ACCUMULATOR
EXCLUSIVE OR
ADD WITH CARRY
INCLUSIVE OR
ADD WITHOUT CARRY
COMPARE INDEX REGISTER X JUMP TO SUBROUTINE
LOAD STACK POINTER
STORE STACK POINTER
SUBTRACT
COMPARE
SUBTRACT WITH CARRY
ADD DOUBLE ACCUMULATOR LOGICAL AND
BIT TEST
LOAD ACCUMULATOR EXCLUSIVE OR
ADD WITH CARRY INCLUSIVE OR
ADD WITHOUT CARRY
LOAD DOUBLE ACCUMULATOR
INCREMENT INDEX REGISTER Y
DECREMENT INDEX REGISTER Y
EXCHANGE DOUBLE ACCUMULATOR AND INDEX REG Y ADD ACCUMULATOR B TO INDEX REG Y
CMPY INDEX REGISTER Y AND INCREMENT.
LOAD INDEX REGISTER Y
STORE INDEX REGISTER Y
LOAD INDEX REGISTER Y
LOAD INDEX REGISTER X ?????
SUBTRACT
COMPARE
SUBTRACT WITH CARRY
ADD DOUBLE ACCUMULATOR LOGICAL AND
BIT TEST
LOAD ACCUMULATOR
STORE ACCUMULATOR EXCLUSIVE OR
ADD WITH CARRY
INCLUSIVE OR
ADD WITHOUT CARRY
LOAD DOUBLE ACCUMULATOR STORE DOUBLE ACCUMULATOR
https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&ft=1619871639&lt=14619875
2
2

https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&2ft0=2116-10958-70116, 389:2&1ltA=M1619875
DE DF
E0
E0 80 E1
E1 80 E2
E2 80 E3
E3 80 E4
E4 80 E5
E5 80 E6
E6 80 E7
E7 80 E8
E8 80 E9
E9 80 EA
EA 80 EB
EB 80 EC
EC 80 ED
ED 80 EE
EE 80 EF
EF 80
F0
F1
F2
F3
F4
F5
F6
F7
F8
F9
FA
FB
FC
FD
FE
FF
LDX DIR STX DIR
SUBB IND,X SUBB IND,Y CMPB IND,X CMPB IND,Y SBCB IND,X SBCB IND,Y ADDD IND,X ADDD IND,Y ANDB IND,X ANDB IND,Y BITB IND,X BITB IND,Y LDAB IND,X LDAB IND,Y STAB IND,X STAB IND,Y EORB IND,X EORB IND,Y ADCB IND,X ADCB IND,Y ORAB IND,X ORAB IND,Y ADDB IND,X ADDB IND,Y LDD IND,X LDD IND,Y STD IND,X STD IND,Y LDX IND,X LDX IND,Y++ STX IND,X STX IND,X
SUBB EXT CMPB EXT SBCB EXT ADDD EXT ANDB EXT BITB EXT LDAB EXT STAB EXT EORB EXT ADCB EXT ORAB EXT ADDB EXT LDD EXT STD EXT LDX EXT STX EXT
24 LOAD INDEX REGISTER X 24 STORE INDEX REGISTER X
24 SUBTRACT
24 SUBTRACT
24 COMPARE
24 COMPARE
24 SUBTRACT WITH CARRY 24 SUBTRACT WITH CARRY 26 ADD DOUBLE ACCUMULATOR 26 ADD DOUBLE ACCUMULATOR 24 LOGICAL AND
24 LOGICAL AND
24 BIT TEST
24 BIT TEST
24 LOAD ACCUMULATOR 24 LOAD ACCUMULATOR 24 STORE ACCUMULATOR 24 STORE ACCUMULATOR 24 EXCLUSIVE OR
24 EXCLUSIVE OR
24 ADD WITH CARRY
24 ADD WITH CARRY
24 INCLUSIVE OR
24 INCLUSIVE OR
24 ADD WITHOUT CARRY
24 ADD WITHOUT CARRY
25 LOAD DOUBLE ACCUMULATOR
25 LOAD DOUBLE ACCUMULATOR
25 STORE DOUBLE ACCUMULATOR
25 STORE DOUBLE ACCUMULATOR
25 LOAD INDEX REGISTER X
25 LOAD INDEX REGISTER X WITH/Y++ 25 STORE INDEX REGISTER X
25 STORE INDEX REGISTER X
34 SUBTRACT
34 COMPARE
34 SUBTRACT WITH CARRY
36 ADD DOUBLE ACCUMULATOR 34 LOGICAL AND
34 BIT TEST
34 LOAD ACCUMULATOR
34 STORE ACCUMULATOR
34 EXCLUSIVE OR
34 ADD WITH CARRY
34 INCLUSIVE OR
34 ADD WITHOUT CARRY
35 LOAD DOUBLE ACCUMULATOR 35 STORE DOUBLE ACCUMULATOR 35 LOAD INDEX REGISTER X 35 STORE INDEX REGISTER X
https://www.scribd.com/document_downloads/direct/293622595?extension=pdf&ft=1619871639&lt=15619875
2
2

MH6211 Instruction Set

Bytes Code A B Desc
00 TEST 1 * TEST OPERATION TEST MODE ONLY
00 TEST 1 * TEST OPERATION TEST MODE ONLY
01 NOP 1 2 NO OPERATION
02 AIM DIR 3 ? AND IN MEMORY
03 OIM DIR 3 ? OR IN MEMORY
04 LSRD 1 3 LOGICAL SHIFT RIGHT DOUBLE ACCUMULATOR
05 ASLD / LSLD 1 3 ARITHMETIC / LOGICAL SHIFT LEFT DOUBLE ACC
06 TAP 1 2 TRANSFER FROM ACC A TO CONDITION CODE REGISTER
07 TPA 1 2 TRANSFER FROM CONDITION CODE REGISTER TO ACC A
08 INX 1 3 INCREMENT INDEX REGISTER X
09 DEX 1 3 DECREMENT INDEX REGISTER X
0A CLV 1 2 CLEAR TWOS COMPLEMENT OVERFLOW BIT
0B SEV 1 2 SET TWOS COMPLEMENT OVERFLOW BIT
0C CLC 1 2 CLEAR CARRY
0D SEC 1 2 SET CARRY
0E CLI 1 2 CLEAR INTERRUPT MASK
0F SEI 1 2 SET INTERRUPT MASK
10 SBA 1 2 SUBTRACT ACCUMULATORS
11 CBA 1 2 COMPARE ACCUMULATORS
14 IDIV DIR 2 6 INTEGER DIVIDE
15 FDIV DIR 2 6 FRACTIONAL DIVIDE (b = D/M, > a = D%M)
16 TAB 1 2 TRANSFER ACCUMULATOR A TO ACCUMULATOR B
17 TBA 1 2 TRANSFER FROM ACCUMULATOR B TO ACCUMULATOR A
18 XGXY 1 4 EXCHANGE REGISTER X AND REGISTER Y
19 DAA 1 2 DECIMAL ADJUST ACCUMULATOR A
1A XGDX 1 EXCHANGE DOUBLE ACCUMLATOR AND INDEX REG X
1B ABA 1 2 ADD ACCUMULATOR B TO ACCUMULATOR A
1C CPD IMM 3 5 COMPARE DOUBLE ACCUMULATOR
1D CPD DIR 2 6 COMPARE DOUBLE ACCUMULATOR
1F CPD EXT 3 7 COMPARE DOUBLE ACCUMULATOR
20 BRA 2 3 BRANCH ALWAYS
21 BRN 2 3 BRANCH NEVER
22 BHI 2 3 BRANCH IF HIGHER
23 BLS 2 3 BRANCH IF LOWER OR SAME
24 BCC / BHS 2 3 BRANCH IF CARRY CLR / BRANCH IF HIGHER OR SAME
25 BCS / BLO 2 3 BRANCH IF CARRY SET / BRANCH IF LOWER
26 BNE 2 3 BRANCH IF NOT EQUAL TO ZERO
27 BEQ 2 3 BRANCH IF EQUAL
28 BVC 2 3 BRANCH IF OVERFLOW CLEAR
29 BVS 2 3 BRANCH IF OVERFLOW SET
2A BPL 2 3 BRANCH IF PLUS
2B BMI 2 3 BRANCH IF MINUS
2C BGE 2 3 BRANCH IF GREATER THAN OR EQUAL TO ZERO
2D BLT 2 3 BRANCH IF LESS THAN ZERO
2E BGT 2 3 BRANCH IF GREATER THAN ZERO
2F BLE 2 3 BRANCH IF LESS THAN OR EQUAL TO ZERO
30 TSX 1 3 TRANSFER FROM STACK POINTER TO INDEX REGISTER X
31 INS 1 3 INCREMENT STACK POINTER
32 PULA 1 4 PULL DATA FROM STACK
33 PULB 1 4 PULL DATA FROM STACK
34 DES 1 3 DECREMENT STACK POINTER
35 TXS 1 3 TRANSFER FROM INDEX REGISTER X TO STACK POINTER
36 PSHA 1 3 PUSH DATA ONTO STACK
37 PSHB 1 3 PUSH DATA ONTO STACK
38 PULX 1 5 PULL INDEX REGISTER X FROM STACK
39 RTS 1 5 RETURN FROM SUBROUTINE
3A ABX 1 3 ADD ACCUMULATOR B TO INDEX REGISTER X
3B RTI 1 12 RETURN FROM INTERRUPT
3C PSHX 1 4 PUSH INDEX REGISTER X ONTO STACK
3D MUL 1 10 MULTIPLY UNSIGNED
3E WAI 1 14 WAIT FOR INTERRUPT
3F SWI 1 14 SOFTWARE INTERRUPT
40 NEGA 1 2 NEGATE
43 COMA 1 2 COMPLEMENT
44 LSRA 1 2 LOGICAL SHIFT RIGHT
46 RORA 1 2 ROTATE RIGHT
47 ASRA 1 2 ARITHMETIC SHIFT RIGHT
48 ASLA / LSLA 1 2 ARITHMETIC / LOGICAL SHIFT LEFT
49 ROLA 1 2 ROTATE LEFT
4A DECA 1 2 DECREMENT
4C INCA 1 2 INCREMENT
4D TSTA 1 2 TEST
4F CLRA 1 2 CLEAR
50 NEGB 1 2 NEGATE
53 COMB 1 2 COMPLEMENT
54 LSRB 1 2 LOGICAL SHIFT RIGHT
56 RORB 1 2 ROTATE RIGHT
57 ASRB 1 2 ARITHMETIC SHIFT RIGHT
58 ASLB / LSLB 1 2 ARITHMETIC / LOGICAL SHIFT LEFT
59 ROLB 1 2 ROTATE LEFT
5A DECB 1 2 DECREMENT
5C INCB 1 2 INCREMENT
5D TSTB 1 2 TEST
5F CLRB 1 2 CLEAR
60 NEG IND,X 2 6 NEGATE
63 COM IND,X 2 6 COMPLEMENT
64 LSR IND,X 2 6 LOGICAL SHIFT RIGHT
66 ROR IND,X 2 6 ROTATE RIGHT
67 ASR IND,X 2 6 ARITHMETIC SHIFT RIGHT
68 ASL / LSL IND,X 2 6 ARITHMETIC / LOGICAL SHIFT LEFT
69 ROL IND,X 2 6 ROTATE LEFT
6A DEC IND,X 2 6 DECREMENT
6C INC IND,X 2 6 INCREMENT
6D TST IND,X 2 6 TEST
6E JMP IND,X 2 3 JUMP
6F CLR IND,X 2 6 CLEAR
70 NEG EXT 3 6 NEGATE
73 COM EXT 3 6 COMPLEMENT
74 LSR EXT 3 6 LOGICAL SHIFT RIGHT
76 ROR EXT 3 6 ROTATE RIGHT
77 ASR EXT 3 6 ARITHMETIC SHIFT RIGHT
78 ASL / LSL EXT 3 6 ARITHMETIC / LOGICAL SHIFT LEFT
79 ROL EXT 3 6 ROTATE LEFT
7A DEC EXT 3 6 DECREMENT
7C INC EXT 3 6 INCREMENT
7D TST EXT 3 6 TEST
7E JMP EXT 3 3 JUMP
7F CLR EXT 3 6 CLEAR
80 SUBA IMM 2 2 SUBTRACT
81 CMPA IMM 2 2 COMPARE
82 SBCA IMM 2 2 SUBTRACT WITH CARRY
83 SUBD IMM 3 4 SUBTRACT DOUBLE ACCUMULATOR
84 ANDA IMM 2 2 LOGICAL AND
85 BITA IMM 2 2 BIT TEST
86 LDAA IMM 2 2 LOAD ACCUMULATOR
87 BRSET DIR 4 BRANCH IF BIT(S) ARE SET
88 EORA IMM 2 2 EXCLUSIVE OR
89 ADCA IMM 2 2 ADD WITH CARRY
8A ORAA IMM 2 2 INCLUSIVE OR
8B ADDA IMM 2 2 ADD WITHOUT CARRY
8C CPX IMM 3 4 COMPARE INDEX REGISTER X
8D BSR 2 6 BRANCH TO SUBROUTINE
8E LDS IMM 3 3 LOAD STACK POINTER
8F BRCLR DIR 4 BRANCH IF BIT(S) ARE CLEAR
90 SUBA DIR 2 3 SUBTRACT
91 CMPA DIR 2 3 COMPARE
92 SBCA DIR 2 3 SUBTRACT WITH CARRY
93 SUBD DIR 2 5 SUBTRACT DOUBLE ACCUMULATOR
94 ANDA DIR 2 3 LOGICAL AND
95 BITA DIR 2 3 BIT TEST
96 LDAA DIR 2 3 LOAD ACCUMULATOR
97 STAA DIR 2 3 STORE ACCUMULATOR
98 EORA DIR 2 3 EXCLUSIVE OR
99 ADCA DIR 2 3 ADD WITH CARRY
9A ORAA DIR 2 3 INCLUSIVE OR
9B ADDA DIR 2 3 ADD WITHOUT CARRY
9C CPX DIR 2 5 COMPARE INDEX REGISTER X
9D JSR DIR 2 5 JUMP TO SUBROUTINE
9E LDS DIR 2 4 LOAD STACK POINTER
9F STS DIR 2 4 STORE STACK POINTER
A0 SUBA IND,X 2 4 SUBTRACT
A0 80 SUBA IND,Y 2 SUBTRACT
A1 CMPA IND,X 2 4 COMPARE
A1 80 CMPA IND,Y+ 2 COMPARE WITH/Y+
A2 SBCA IND,X 2 4 SUBTRACT WITH CARRY
A2 80 SBCA IND,Y 2 SUBTRACT WITH CARRY
A3 SUBD IND,X 2 6 SUBTRACT DOUBLE ACCUMULATOR
A3 80 SUBD IND,Y 2 6 SUBTRACT DOUBLE ACCUMULATOR
A4 ANDA IND,X 2 4 LOGICAL AND
A4 80 ANDA IND,Y 2 4 LOGICAL AND
A5 BITA IND,X 2 4 BIT TEST
A5 80 BITA IND,Y 2 4 BIT TEST
A6 LDAA IND,X 2 4 LOAD ACCUMULATOR
A6 80 LDAA IND,Y+ 2 LOAD ACCUMULATOR WITH/Y+
A7 STAA IND,X 2 4 STORE ACCUMULATOR
A7 80 STAA IND,Y 2 STORE ACCUMULATOR
A8 EORA IND,X 2 4 EXCLUSIVE OR
A8 80 EORA IND,Y 2 4 EXCLUSIVE OR
A9 ADCA IND,X 2 4 ADD WITH CARRY
A9 80 ADCA IND,Y 2 4 ADD WITH CARRY
AA ORAA IND,X 2 4 INCLUSIVE OR
AA 80 ORAA IND,Y 2 4 INCLUSIVE OR
AB ADDA IND,X 2 4 ADD WITHOUT CARRY
AB 80 ADDA IND,Y 2 4 ADD WITHOUT CARRY
AC CPX IND,X 2 6 COMPARE INDEX REGISTER X
AC 80 CPX IND,Y 2 6 COMPARE INDEX REGISTER X
AD JSR IND,X 2 6 JUMP TO SUBROUTINE
AD 80 JSR IND,Y 2 JUMP TO SUBROUTINE
AE LDS IND,X 2 5 LOAD STACK POINTER
AE 80 LDS IND,Y 2 5 LOAD STACK POINTER
AF STS IND,X 2 5 STORE STACK POINTER
AF 80 STS IND,Y 2 5 STORE STACK POINTER
B0 SUBA EXT 3 4 SUBTRACT
B1 CMPA EXT 3 4 COMPARE
B2 SBCA EXT 3 4 SUBTRACT WITH CARRY
B3 SUBD EXT 3 6 SUBTRACT DOUBLE ACCUMULATOR
B4 ANDA EXT 3 4 LOGICAL AND
B5 BITA EXT 3 4 BIT TEST
B6 LDAA EXT 3 4 LOAD ACCUMULATOR
B7 STAA EXT 3 4 STORE ACCUMULATOR
B8 EORA EXT 3 4 EXCLUSIVE OR
B9 ADCA EXT 3 4 ADD WITH CARRY
BA ORAA EXT 3 4 INCLUSIVE OR
BB ADDA EXT 3 4 ADD WITHOUT CARRY
BC CPX EXT 3 6 COMPARE INDEX REGISTER X
BD JSR EXT 3 6 JUMP TO SUBROUTINE
BE LDS EXT 3 5 LOAD STACK POINTER
BF STS EXT 3 5 STORE STACK POINTER
C0 SUBB IMM 2 2 SUBTRACT
C1 CMPB IMM 2 2 COMPARE
C2 SBCB IMM 2 2 SUBTRACT WITH CARRY
C3 ADDD IMM 3 4 ADD DOUBLE ACCUMULATOR
C4 ANDB IMM 2 2 LOGICAL AND
C5 BITB IMM 2 2 BIT TEST
C6 LDAB IMM 2 2 LOAD ACCUMULATOR
C7 BRSET IND, X 4 BRANCH IF BIT(S) SET
C8 EORB IMM 2 2 EXCLUSIVE OR
C9 ADCB IMM 2 2 ADD WITH CARRY
CA ORAB IMM 2 2 INCLUSIVE OR
CB ADDB IMM 2 2 ADD WITHOUT CARRY
CC LDD IMM 3 3 LOAD DOUBLE ACCUMULATOR
CD 08 INY 2 4 INCREMENT INDEX REGISTER Y
CD 09 DEY 2 4 DECREMENT INDEX REGISTER Y
CD 1A XGDY 2 EXCHANGE DOUBLE ACCUMULATOR AND INDEX REG Y
CD 3A ABY 2 ADD ACCUMULATOR B TO INDEX REG Y
CD 8C CMPY IMM, Y++ 4 CMPY INDEX REGISTER Y AND INCREMENT.
CD A3 CPD IND,Y
CD AC CPX IND,Y
CD CE LDY IMM 4 4 LOAD INDEX REGISTER Y
CD DF STY DIR 3 5 STORE INDEX REGISTER Y
CD EE LDY IND,X 3 6 LOAD INDEX REGISTER Y
CD EF STX IND,Y 3 6
CD FE 4????
CE LDX IMM 3 3 LOAD INDEX REGISTER X
CF ***** 3 ?????(4!!!!!)
CF STOP 1
D0 SUBB DIR 2 3 SUBTRACT
D1 CMPB DIR 2 3 COMPARE
D2 SBCB DIR 2 3 SUBTRACT WITH CARRY
D3 ADDD DIR 2 5 ADD DOUBLE ACCUMULATOR
D4 ANDB DIR 2 3 LOGICAL AND
D5 BITB DIR 2 3 BIT TEST
D6 LDAB DIR 2 3 LOAD ACCUMULATOR
D7 STAB DIR 2 3 STORE ACCUMULATOR
D8 EORB DIR 2 3 EXCLUSIVE OR
D9 ADCB DIR 2 3 ADD WITH CARRY
DA ORAB DIR 2 3 INCLUSIVE OR
DB ADDB DIR 2 3 ADD WITHOUT CARRY
DC LDD DIR 2 4 LOAD DOUBLE ACCUMULATOR
DD STD DIR 2 4 STORE DOUBLE ACCUMULATOR
DE LDX DIR 2 4 LOAD INDEX REGISTER X
DF STX DIR 2 4 STORE INDEX REGISTER X
E0 SUBB IND,X 2 4 SUBTRACT
E0 80 SUBB IND,Y 2 4 SUBTRACT
E1 CMPB IND,X 2 4 COMPARE
E1 80 CMPB IND,Y 2 4 COMPARE
E2 SBCB IND,X 2 4 SUBTRACT WITH CARRY
E2 80 SBCB IND,Y 2 4 SUBTRACT WITH CARRY
E3 ADDD IND,X 2 6 ADD DOUBLE ACCUMULATOR
E3 80 ADDD IND,Y 2 6 ADD DOUBLE ACCUMULATOR
E4 ANDB IND,X 2 4 LOGICAL AND
E4 80 ANDB IND,Y 2 4 LOGICAL AND
E5 BITB IND,X 2 4 BIT TEST
E5 80 BITB IND,Y 2 4 BIT TEST
E6 LDAB IND,X 2 4 LOAD ACCUMULATOR
E6 80 LDAB IND,Y 2 4 LOAD ACCUMULATOR
E7 STAB IND,X 2 4 STORE ACCUMULATOR
E7 80 STAB IND,Y 2 4 STORE ACCUMULATOR
E8 EORB IND,X 2 4 EXCLUSIVE OR
E8 80 EORB IND,Y 2 4 EXCLUSIVE OR
E9 ADCB IND,X 2 4 ADD WITH CARRY
E9 80 ADCB IND,Y 2 4 ADD WITH CARRY
EA ORAB IND,X 2 4 INCLUSIVE OR
EA 80 ORAB IND,Y 2 4 INCLUSIVE OR
EB ADDB IND,X 2 4 ADD WITHOUT CARRY
EB 80 ADDB IND,Y 2 4 ADD WITHOUT CARRY
EC LDD IND,X 2 5 LOAD DOUBLE ACCUMULATOR
EC 80 LDD IND,Y 2 5 LOAD DOUBLE ACCUMULATOR
ED STD IND,X 2 5 STORE DOUBLE ACCUMULATOR
ED 80 STD IND,Y 2 5 STORE DOUBLE ACCUMULATOR
EE LDX IND,X 2 5 LOAD INDEX REGISTER X
EE 80 LDX IND,Y++ 2 5 LOAD INDEX REGISTER X WITH/Y++
EF STX IND,X 2 5 STORE INDEX REGISTER X
EF 80 STX IND,X 2 5 STORE INDEX REGISTER X
F0 SUBB EXT 3 4 SUBTRACT
F1 CMPB EXT 3 4 COMPARE
F2 SBCB EXT 3 4 SUBTRACT WITH CARRY
F3 ADDD EXT 3 6 ADD DOUBLE ACCUMULATOR
F4 ANDB EXT 3 4 LOGICAL AND
F5 BITB EXT 3 4 BIT TEST
F6 LDAB EXT 3 4 LOAD ACCUMULATOR
F7 STAB EXT 3 4 STORE ACCUMULATOR
F8 EORB EXT 3 4 EXCLUSIVE OR
F9 ADCB EXT 3 4 ADD WITH CARRY
FA ORAB EXT 3 4 INCLUSIVE OR
FB ADDB EXT 3 4 ADD WITHOUT CARRY
FC LDD EXT 3 5 LOAD DOUBLE ACCUMULATOR
FD STD EXT 3 5 STORE DOUBLE ACCUMULATOR
FE LDX EXT 3 5 LOAD INDEX REGISTER X
FF STX EXT 3 5 STORE INDEX REGISTER X

Procs Docs Tossed

Related?

Board parts

Chips

ISC drivers

MH6111 Processor

Standalones

AEM

Megasquirt

Speeduino

Link ECU (VR4LINK)

Haltech

Pretty disassembly notes

GENERAL NOTES

Project started with the help of dsm-ecu Yahoo group, thanks for the great info. Most disassembly comments in this file by Christian, [email protected].

CPU

The microcomputer chip used in the 1G DSM ECU seems to be a custom application built around the 6801 architecture, Check the 6801, 6803, 6301, 68HC11 at web sites such as alldatasheet.com, etc.

CPU clock frequency is assumed to be 2MHz, i.e. the instructions cycle time is 0.5us.

Assembly binary verifications

The 2 binaries produced without any customization ("enableCustom" definition is commented-out) have been verified to be identical to the E931 and E932 eprom images at hand.

To check the validity of symbolic substitution, the entire code section and tables was offset by $0200 using "codeOffset" and the corresponding binary was tested on my car (E932) without any problems for weeks. Additional tests were conducted by writing inline code in several part of the code and no adverse effect was ever noted.

To check the validity of symbolic substitution for ram addresses, every ram location starting at $0057 was offset by 1 (i.e. temp1 was at memory address $58 instead of $57, etc) and the corresponding binary was tested on my car (E932) without any problems during car startup and engine revving. No additional test performed.

This means that the code can be modified inline and in most cases, ram memories can be moved around by changing the label addresses. Note however that some groups of ram memories have to be moved in blocks because the code assumes they are contiguous. e.g. the temp1 to temp9 variables, the inj1_offT, inj3_offT, inj4_offT and inj2_offT variables, etc.

Ram memory

Memory from $0040 to $01bf is backed-up by battery, meaning it is preserved when the ECU is powered-off as long as battery power is supplied. However, memory from $0057 to $0190 is cleared to 0 by the code every time the ECU is powered-on. That can be however changed by modifying the code... Battery backup was checked by disabling memory reset using the "noRamReset" and then check ram memory at $018f to see if it gets preserved after power off/on cycle, and it did. During the test, $018f was used as a distance counter using the reed switch.

Comments

Some comments use variable names quite loosly. For instance, multi-byte variables such as [airCnt0:airCnt1:airCnt2] might be refered to as only airCnt0. airCnt0 might therefore refer to the single byte airCnt0, to the 16 bit value [airCnt0:airCnt1] or to the 24 bit complete variable, depending on the context.

Comments were added incrementally as my knowledge of code and variables increased. As new knowledge was learned, old comments were updated or corrected as much as possible but not necessarily all of them, so beware... In the end, the code is the only truth... Some small areas of the code were also never completly understood as a general understanding was reached and I did not care to go further e.g. airflow sensor active filter reset.

Opcodes

  • cmpd: cmpd1 is used for some addressing modes instead of cmpd since TASM does not support unusual mitsubishi ECU cmpd opcodes..
  • brclr: branch if ALL the given bits are clear
  • brset: branch if ANY of the given bits are set (as opposed to usual implementation of ALL bits set...)
  • The addressing mode using Y indexing also implicitly modifies the y register. It seems that y is increased by 1 or 2 depending whether the instruction is a 8 bit or 16 bits operation... The following cases are confirmed:
cmpa $00,y  -> y = y + 1 
cmpb $00,y  -> y = y + 1 
ldaa $00,y  -> y = y + 1
suba $00,y  -> y = y + 1
ldx  $00,y  -> y = y + 2
std  $00,y  -> y = y + 2

Telemark assembler

This assembler does not provide warning messages when code assembles to the same memory space, e.g. you insert code in the middle of the file which result in the rest of the code to be offset by N bytes. This results in the interrupt vector table to be overwritten. No warning is given. The only way to know about it is to manually check the listing file produced by the assembler. Check that the buffer space between sections is all "$ff". Check that there is no code spilage over .org statements. Check that the address space does not exceed $ffff. Use the "codeOffset" at the beginnng of the file to correct the problem.

Fuel injector and coil power transistor control

Although the 4 fuel injectors and the 2 coil power transistors are mapped to regular ports (port1, port2 and port5) which can be read to know the current state of these outputs, they are also mapped in hardware to output compare registers in order to activate or deactivate them at specific time instants. Writing to the ports might therefore not work unless the output compare configuration registers are changed to disable harware control of these outputs. This might not be possible unless an "output enable" bit exists, which I haven't found at this point... Another way to activate or deactivate them would be to use the output compare registers (as currently done by the ECU code) and provoke an immediat output change.

Here is my current understanding of how injector scheduling works, not everything is clear to me so don't take this as gospel...:

The output compare registers for the fuel injectors seem to be at least double buffered and maybe triple buffered (see schedInjSim routine). That means that up to 3 different output compare values can be written to t1_outCmpWr and t2_outCmpWr to activate or deactivate the injectors at those time instants. Each time a value is written to t1_outCmpWr or t2_outCmpWr, the corresponding injector state is also internally stored. That means that to activate injector #1 at time X, you would first reset bit 0 of t1_csr, corresponding to injector #1 and then write X to t1_outCmpWr. You could then immediately schedule the deactivation of injector #1 by setting bit 0 of t1_csr to 1 and then write the deactivation time to t1_outCmpWr. When one of the output compare register stored value matches the clock at t1t2_clk, the injector is activated/deactivated and the corresponding interrupt routine is called (if the interrupt mask is clear...) at outCompInt1 or outCompInt2.

Here is my current understanding of how the coil power transistor scheduling works, not everything is clear to me so don't take this as gospel...: t3_outCmpWr is the output compare register used to activate or deactivate the coil power transistors (energize the coil and provoke ignition at the specified time instants) To energize the coil for cylinder 1 and 4 at time X you would write X to t3_outCmpWr and reset(0) bit 2 of t3_csr0. At time X, t3_csr0.2 would be loaded into port5.1 which would energize the coil. t3_csr0.2 should not be changed until that happens. In the code, most of the time 2 successive values (the same one) are written to t3_outCmpWr but there are some instances where only 1 value is written. My impression is that the first value serves to activate/deactivate the coil power transistor at the specified instant while the second one only serves to generate an interrupt in order to call the outCompInt3 routine. Hence when only the coil need to be activated/deactivated without calling outCompInt3, you would only write one value. If in addition you want to have outCompInt3 called when the coil is energized/ignited, you would write two successive values (corresponding to the same time...). This is all speculation of course... As for the 2 clocks at t3_clock1 and t3_clock1, I assume they are connected to the same internal clock at 250KHz but might be input capture registers latched when one of the two output compare at t3_outCmpWr is triggered??????? Again speculation, this is the part of the code I understand the least...

Timing diagram

  • 4 cylinders = 2 rotations = 2 * 360degrees = 720 degrees
  • For sequential injection, fuel injection starts on the cas falling edge
    • i.e. cylinder #1 injection starts at -5 BTDC of #3 TDC
  • Simultaneous injection of all 4 injectors is performed when starting to crank or starting a cold engine or during acceleration, check the tech manual and code for more details. Simultaneous injection starts on the 5deg BTDC cas signal except in the case of acceleration where it starts when an injector is deactivated and no other injector is active (i.e. at the beginning of the time period where no injector is active)
  • Coil energization is usually scheduled (the energization time is loaded into the output compare register, energization will occur at the specified time) from the cas rising edge. Coil ignition can be scheduled when energization occurs (output compare interrupt) or on the cas falling edge depending on the desired timing. Note however that coil energization can also be scheduled when ignition occurs on the preceeding cylinder. This would correspond to scheduling ignition before the cas rising edge (at high rpm I assume). Coil energization can also be scheduled on the cas falling edge when the desired timing is high (e.g. 10deg ATDC). As this shows, there are several combinations and the complexity of the code to handle the coil reflects that fact.
   
                        No 1 TDC         No 3 TDC          No 4 TDC          No 2 TDC
                           :                 :                 :                 :
                  ___________                         _____ 
TDC sensor       |           |                       |     |
signal           |         : |               :       |     |   :                 :
             ____|___________|_______________________|_____|________________________
degrees         85           55                      85   15
(BTDC/ATDC)                :                 :                 :                 :
                   ______            ______            ______            ______ 
CAS sensor        |      |          |      |          |      |          |      |
signal            |      | :        |      | :        |      | :        |      | :
             _____|______|__________|______|__________|______|__________|______|____
degrees           75     5 :       75      5 :       75      5 :        75     5 :
(BTDC)                     :                 :                 :                 :          
                           :                 :                 :                 : 
No 1 cyl.      compression :   combustion    :    exhaust      :     intake      : compression
No 3 cyl.        intake    :   compression   :   combustion    :     exhaust     :  intake     
No 4 cyl.        exhaust   :     intake      :   compression   :    combustion   :  exhaust    
No 2 cyl.      combustion  :     exhaust     :    intake       :    compression  : combustion

Airflow calculations dependencies, more details in code

  masProc: airflow sensor interrupt, increases [airCntNew0:airCntNew1] 
    |     by airQuantum for every airflow sensor pulse received
    |
    | 
    |
    |--> [airCntNew0:airCntNew1]: Increased by airQuantum for every airflow sensor pulse
             |                    Reset and used as input to [airCnt0:airCnt1:airCnt2]
             |                    on every cas falling edge, i.e. air is counted twice
             |                    per rotation, once for every cylinder cycle... It can 
             |                    therefore be seen as the air count per cylinder.
             |
             |--> [airCnt0:airCnt1:airCnt2]: Filtered version of 256*[airCntNew0:airCntNew1]
                        |                    exponential averaging is used.
                        |
                        |
                        |
                        |--> mafraw16: 16 bit airflow sensor pulse frequency (mafraw16/10.24)Hz
                        |       |      mafraw16 = 8205*[airCnt0:airCnt1]/Tcas
                        |       |
                        |       |
                        |       |--> mafraw: 8 bit airflow sensor pulse frequency (6.25*mafraw)Hz
                        |                    mafraw: = mafraw16/64
                        |
                        |
                        |
                        |--> airVol16: Equals [airCnt0:airCnt1] * masScalar/65536
                        |       |
                        |       |
                        |       |
                        |       |--> airVol   : Equals airVol16/2
                        |       |--> airVolT  : Equals airVol16/2 * iatCompFact/128
                        |       |--> airVolTB : Equals airVol16/2 * iatCompFact/128 * baroFact/128
                        |       |--> airVolB  : Equals airVol16/2 * baroFact/128
                        |
                        |
                        |--> injPw: Injector pulse width in "normal" operation, 
                                    injPw = [airCnt0:airCnt1] * injFactor/256  + other corrections

Discussion on MAS compensation factors

Total airflow sensor compensation is made-up of:

totMasComp(freq,iat,baro) = masComp + t_masComp(freq) + t_masLin(freq,iat,baro)

where maxComp is a fixed offset ($64 for 1G and $40 for 2G) and t_masComp and t_masLin are table values interpolated from frequency, intake air temperature and barometric pressure. t_masComp(freq) is basically compensation for the airflow sensor charcteristic curve as a function of frequency (to linearize the number of pulse per sec vs. the volume of air passing through the sensor) while t_masLin(freq,iat,baro) is a smaller factor probably compensating for temperature drift (electronic) and airflow characteristic change as a function of air density???

Assuming the following:

* injComp     = 100% (for 260cc injectors at 36psi)
* workFtrim   = 100%
* o2FuelAdj   = 100%
* iatCompFact = 100% (at 25.6degC)
* baroFact    = 100% (~1 bar)
* openLoopEnr = 100%
* coldTempEnr = 100%
* enrWarmup   = 0%

Then the injector pulswidth is calculated by the ECU as (excluding deadtime)

injPw(usec/cylinder) = numPulsePerCasInterrupts * $9c * totMasComp * 16/256
                     = numPulsePerCasInterrupts * totMasComp * 9.75

If we also assume a 14.7 air to fuel ratio, Dair=1.18 air density (g/litre) at 25degC, Dgas=0.775 fuel density (g/cc) then we would need 23900 usec of injection per litre of air using the same 260cc at 36psi, working that factor into the equation, we get

injPw(usec/cylinder) = numPulsePerCasInterrupts * totMasComp * 9.75
                     = numPulsePerCasInterrupts * totMasComp/2452 * 2452 * 9.75 
                     = numPulsePerCasInterrupts * totMasComp/2452 * 23900usecOfInjection/litreOfAir

This means that under the above assumptions, totMasComp/2452 has units of litreOfAirPerAirflowSensorPulse.

The factor 2452 is similar to the one provided by J. Oberholtzer, I think. The exact value must be somewhere in that range...

masScalar is also used for maf compensation ($5e86,24198 for 1G, $7A03,31235 for 2g) for controls other than fuel injection. It probably correspond to some metric of the totMasComp curve (average or max under given conditions). From 1G and 2G numbers, It could correspond to the max of the masComp + t_masComp(freq) curve multiplied by 0.808*128? It could also correspond to the masComp + t_masComp(freq) curve sampled at around 69Hz and multiplied by 128.

masScalar = maxTotMasComp*0.808*128 = totMasComp(69Hz)*128

We then have in the case of masScalar = maxTotMasComp*0.808*128:

airVol16 = numPulsePerCasInterrupts * $9c * masScalar / 65536
         = numPulsePerCasInterrupts * $9c * maxTotMasComp*0.808*128 / 65536
         = numPulsePerCasInterrupts * maxTotMasComp * 0.2462
         = numPulsePerCasInterrupts * maxTotMasComp/2452 * 2452*0.2462
         = numPulsePerCasInterrupts * maxTotMasComp/2452 * 603.68

since totMasComp/2452 is litreOfAirPerAirflowSensorPulse, we have

airVol16 = numPulsePerCasInterrupts * litreOfAirPerAirflowSensorPulse * 603.68

Using again 1.18g/litre air density we get

airVol16 = numPulsePerCasInterrupts * litreOfAirPerAirflowSensorPulse *1.18 * 603.68/1.18
         = numPulsePerCasInterrupts * gramsOfAirPerAirflowSensorPulse * 512
         = gramsOfAirPerCasInterrupts * 512

In that case, airVol16/512 can be seen has having units of gramsOfAirPerCasInterrupts (grams of air entering one cylinder). Note that the factor of 512 is not random, the factor 0.808 is used to get it in that case...

The load index values used to interpolate the fuel map is then

airVol16/2 <= 96
     
    loadIndex = (airVol16/2-32)/16 
              = (gramsOfAirPerCasInterrupts*512/2 -32)/16
              = gramsOfAirPerCasInterrupts*16-2
    
airVol16/2 >= 96
     
    loadIndex = gramsOfAirPerCasInterrupts * 512/2 * 0.668/16
              = gramsOfAirPerCasInterrupts*10.69

Which correspond to (gramsOfAirPerCasInterrupts for each index value)

  0      1      2       3       4       5       6      7       8       9       10     11
0.125  0.1875  0.25  0.3125  0.3750  0.4678  0.5614 0.6549  0.7485  0.8421  0.9356  1.0292

gramsOfAirPerRevolution would be twice those values. Notice that the max value of 1.0292 correspond to about 250HP when BSFC=0.55 which is in the range of the stock 1G 195HP...

Also notice that the 8 bit airflow airVol = airVol16/2 will saturate to $ff when airVol16/2 = 255 which correspond to gramsOfAirPerCasInterrupts = 1 gram. airVolT airVolTB and airVolB will also saturate in the same range...

We can now compare these results with the stock boost gauge. It has a max range of 1Kg per sq cm which equals 14.2 psi. The boost gauge duty cycle is given by

bGaugeODuty = t_bGauge(airVolT/32)/24

When maximum airVolT = 255 = iatCompFact*airVol16/2, bGaugeODuty = 20/24 = 0.83. At 25.6 degC, iatCompFact = 1.0 and therefore airVol16=510 which translates to 1g of air. boost gauge duty of 0.83 correspond to approx. 10.9psi (by eye...). Assuming a displacement of 0.5litre per cylinder and charge air density of 1.18 (25degC, probably too low for that psi range, unless you have a perfect intercooler..) we would get 1.18*0.5*(10.9+14.5)/14.5 = 1.03g of air per cylinder (cas interrupt). This is quite close to the 1.0g we had earlier.

The 0psi point on the gauge correspond to a duty cycle of about 40.5% which correspond to bGaugeODuty=9.75/24 which from t_bGauge correspond to airVolT/32=2.875 which means airVolT = 92. with iatCompFact = 1.0 @25degC, we get airVol16 = 2*airVolT/iatCompFact = 184 which correspond to 0.36grams of air Assuming a displacement of 0.5litre per cylinder and charge air density of 1.18@25degC we would get 1.18*0.5 = 0.59g of air per cylinder (cas interrupt) at 0psi. Compared to 0.36g we had earlier this is a large error but then there are several factor not taken onto account in the calculations, I suppose???.

Engine coolant and intake air temperature

Approximate sensor curves (temperature against ADC value, taken from MMCD). The control points in the service manual are quite close (0 to 2 degC off).

ADC ECT
degC
IAT ===== ADC ECT
degC
IAT ===== ADC ECT
degC
IAT ===== ADC ECT
degC
IAT
$00 158.0 184.0 $40 52.0 56.0 $80 21.0 23.0 $c0 -7.0 -7.0
$01 154.4 178.1 $41 51.3 55.3 $81 20.6 22.5 $c1 -7.5 -7.6
$02 150.9 172.5 $42 50.7 54.6 $82 20.2 22.1 $c2 -8.1 -8.2
$03 147.5 167.2 $43 50.1 53.9 $83 19.8 21.7 $c3 -8.6 -8.8
$04 144.2 162.0 $44 49.5 53.3 $84 19.4 21.2 $c4 -9.2 -9.4
$05 140.9 157.1 $45 48.9 52.6 $85 19.0 20.8 $c5 -9.8 -10.1
$06 137.7 152.4 $46 48.3 52.0 $86 18.7 20.4 $c6 -10.4 -10.7
$07 134.6 148.0 $47 47.7 51.3 $87 18.3 19.9 $c7 -10.9 -11.3
$08 131.6 143.7 $48 47.2 50.7 $88 17.9 19.5 $c8 -11.5 -12.0
$09 128.6 139.6 $49 46.6 50.1 $89 17.6 19.0 $c9 -12.1 -12.6
$0a 125.7 135.7 $4a 46.1 49.4 $8a 17.2 18.6 $ca -12.7 -13.2
$0b 122.9 132.0 $4b 45.6 48.8 $8b 16.9 18.2 $cb -13.2 -13.9
$0c 120.2 128.5 $4c 45.0 48.2 $8c 16.5 17.7 $cc -13.8 -14.5
$0d 117.5 125.1 $4d 44.5 47.7 $8d 16.1 17.3 $cd -14.3 -15.1
$0e 114.9 121.9 $4e 44.0 47.1 $8e 15.7 16.8 $ce -14.9 -
$0f 112.4 118.8 $4f 43.5 46.5 $8f 15.3 16.4 $cf -15.4 -16.3
$10 110.0 116.0 $50 43.0 46.0 $90 15.0 16.0 $d0 -16.0 -17.0
$11 107.6 113.2 $51 42.4 45.4 $91 14.5 15.5 $d1 -16.5 -17.6
$12 105.3 110.6 $52 41.9 44.9 $92 14.1 15.1 $d2 -17.0 -18.2
$13 103.0 108.1 $53 41.4 44.3 $93 13.7 14.6 $d3 -17.5 -18.8
$14 100.8 105.8 $54 40.9 43.8 $94 13.3 14.2 $d4 -18.0 -19.4
$15 98.7 103.5 $55 40.4 43.3 $95 12.9 13.7 $d5 -18.6 -20.1
$16 96.7 101.4 $56 39.9 42.8 $96 12.4 13.3 $d6 -19.2 -20.8
$17 94.7 99.4 $57 39.3 42.3 $97 12.0 12.8 $d7 -19.8 -21.5
$18 92.8 97.5 $58 38.8 41.8 $98 11.5 12.4 $d8 -20.5 -22.3
$19 91.0 95.7 $59 38.3 41.4 $99 11.1 12.0 $d9 -21.3 -23.1
$1a 89.2 93.9 $5a 37.8 40.9 $9a 10.6 11.5 $da -22.1 -24.0
$1b 87.5 92.3 $5b 37.3 40.4 $9b 10.2 11.1 $db -23.0 -24.9
$1c 85.9 90.7 $5c 36.9 39.9 $9c 9.7 10.7 $dc -24.0 -26.0
$1d 84.3 89.2 $5d 36.4 39.4 $9d 9.3 10.2 $dd -25.0 -27.1
$1e 82.8 87.7 $5e 35.9 38.9 $9e 8.8 9.8 $de -26.2 -28.3
$1f 81.3 86.3 $5f 35.4 38.4 $9f 8.4 9.4 $df -27.5 -29.6
$20 80.0 85.0 $60 35.0 38.0 $a0 8.0 9.0 $e0 -29.0 -31.0
$21 78.6 83.6 $61 34.5 37.5 $a1 7.5 8.5 $e1 -30.5 -32.5
$22 77.4 82.4 $62 34.0 37.0 $a2 7.1 8.1 $e2 -32.2 -34.1
$23 76.2 81.1 $63 33.6 36.4 $a3 6.6 7.7 $e3 -33.9 -35.7
$24 75.0 79.9 $64 33.1 35.9 $a4 6.2 7.3 $e4 -35.8 -37.5
$25 73.9 78.8 $65 32.7 35.4 $a5 5.8 6.9 $e5 -37.7 -39.3
$26 72.9 77.7 $66 32.3 34.9 $a6 5.3 6.4 $e6 -39.7 -41.2
$27 71.9 76.6 $67 31.8 34.4 $a7 4.9 6.0 $e7 -41.7 -43.0
$28 70.9 75.5 $68 31.4 33.9 $a8 4.5 5.6 $e8 -43.7 -44.9
$29 69.9 74.5 $69 31.0 33.4 $a9 4.0 5.2 $e9 -45.8 -46.8
$2a 69.0 73.5 $6a 30.5 32.9 $aa 3.6 4.7 $ea -47.8 -48.7
$2b 68.1 72.5 $6b 30.1 32.4 $ab 3.2 4.3 $eb -49.8 -50.6
$2c 67.3 71.5 $6c 29.7 31.9 $ac 2.7 3.8 $ec -51.8 -52.4
$2d 66.4 70.6 $6d 29.3 31.4 $ad 2.3 3.4 $ed -53.7 -54.1
$2e 65.6 69.7 $6e 28.8 30.9 $ae 1.8 2.9 $ee -55.5 -55.8
$2f 64.8 68.8 $6f 28.4 30.4 $af 1.4 2.4 $ef -57.3 -57.4
$30 64.0 68.0 $70 28.0 30.0 $b0 1.0 2.0 $f0 -59.0 -59.0
$31 63.1 67.1 $71 27.5 29.5 $b1 0.5 1.5 $f1 -59.0 -59.0
$32 62.3 66.3 $72 27.1 29.0 $b2 0.0 0.9 $f2 -59.0 -59.0
$33 61.5 65.5 $73 26.6 28.6 $b3 -0.3 0.4 $f3 -59.0 -59.0
$34 60.7 64.7 $74 26.2 28.1 $b4 -0.8 -0.0 $f4 -59.0 -59.0
$35 59.9 63.9 $75 25.7 27.7 $b5 -1.3 -0.5 $f5 -59.0 -59.0
$36 59.2 63.1 $76 25.3 27.2 $b6 -1.8 -1.1 $f6 -59.0 -59.0
$37 58.4 62.3 $77 24.8 26.8 $b7 -2.3 -1.6 $f7 -59.0 -59.0
$38 57.6 61.6 $78 24.4 26.4 $b8 -2.8 -2.2 $f8 -59.0 -59.0
$39 56.9 60.9 $79 23.9 25.9 $b9 -3.3 -2.8 $f9 -59.0 -59.0
$3a 56.1 60.1 $7a 23.5 25.5 $ba -3.8 -3.3 $fa -59.0 -59.0
$3b 55.4 59.4 $7b 23.0 25.1 $bb -4.3 -3.9 $fb -59.0 -59.0
$3c 54.7 58.7 $7c 22.6 24.7 $bc -4.8 -4.5 $fc -59.0 -59.0
$3d 54.0 58.0 $7d 22.2 24.2 $bd -5.3 -5.1 $fd -59.0 -59.0
$3e 53.3 57.3 $7e 21.8 23.8 $be -5.9 -5.7 $fe -59.0 -59.0
$3f 52.6 56.6 $7f 21.4 23.4 $bf -6.4 -6.3 $ff -59.0 -59.0