View Single Post
Old 11-03-2015, 06:18 AM   #14
ztan
Senior Member
 
Join Date: Jul 2013
Drives: Toyota 86
Location: Gold Coast, Australia
Posts: 311
Thanks: 44
Thanked 358 Times in 142 Posts
Mentioned: 60 Post(s)
Tagged: 0 Thread(s)
Hooking new code into existing routines.

This is an example of how to hook code into an existing routine. Not 100% elegant, but there is plenty of free space to work with in our ECUs so I haven't optimized it for space.

Be careful when using the delayed slot instructions (jsr, rts, bra...) if you have any delayed instructions that reference addresses, the results can be quite screwy. The 32 bit instructions instructions in a delayed slot also are not reliable. Use of jsr/n, rts/n makes code more reliable, even though it takes up an extra clock cycle.

Example:

In the A01G ROM, the routine at 2B0E8 in the stock ROM scales sensor voltage data in fr4 according to multiplier and offset (Throttle angle, Accelerator angle, Batt Voltage, MAP sensor, Evap Pressure sensor)
Evap pressure sensor data is read when r6 = 06 and r13 = 0B.
At the end of this block of code, the program then branches to 2B100 with the scaled value stored in fr9.

Code:
ROM:0002B0E8             loc_2B0E8:                              ; CODE XREF: Scale_16_bit_sensor_data_in_table
ROM:0002B0E8 46 08                       shll2   r6              ; Shift Logical Left 2
ROM:0002B0EA 46 00                       shll    r6              ; Shift Logical Left
ROM:0002B0EC D2 21                       mov.l   #off_10E0C, r2  ; Move Immediate Long Data
ROM:0002B0EE 60 63                       mov     r6, r0          ; Move Data
ROM:0002B0F0 06 2E                       mov.l   @(r0,r2), r6    ; Move Long Data
ROM:0002B0F2 F0 68                       fmov.s  @r6, fr0        ; Floating-point move single precision: Multiplier value
ROM:0002B0F4 72 04                       add     #4, r2          ; Add binary
ROM:0002B0F6 06 2E                       mov.l   @(r0,r2), r6    ; Move Long Data
ROM:0002B0F8 F9 68                       fmov.s  @r6, fr9        ; Floating-point move single precision: Offset value
ROM:0002B0FA A0 01                       bra     loc_2B100       ; Branch
ROM:0002B0FC F9 4E                       fmac    fr0, fr4, fr9   ; Floating-point multiply and accumulate: fr9 = fr0(multiplier)*fr4(sensor voltage)+fr9(offset)
This substitute code loads a ROM address for a new subroutine in a patch of empty ROM in place of the old sensor scaling, returning with a sensor value in fr9 before branching to 2B100:

Code:
ROM:0002B0E8             loc_2B0E8:                              ; CODE XREF: sub_2B0A2
ROM:0002B0E8 D2 03                       mov.l   #sub_B97C0, r2  ; Move Immediate Long Data
ROM:0002B0EA 42 4B                       jsr/n   @R2 ; sub_B97C0 ; Jump to Subroutine with No delay slot
ROM:0002B0EC A0 08                       bra     loc_2B100       ; Branch
ROM:0002B0EE 00 09                       nop                     ; No Operation
ROM:0002B0EE             ; ---------------------------------------------------------------------------
ROM:0002B0F0 FF FF FF FF+                .datab.l 2, h'FFFFFFFF
ROM:0002B0F8 00 0B 97 C0 off_2B0F8:      .data.l sub_B97C0       ; DATA XREF: sub_2B0A2:loc_2B0E8
ROM:0002B0FC FF FF                       .datab.b 2, h'FF
The new subroutine at B97C0 replicates the original routine, checks if the Evap sensor is being evaluated; returns immediately if not, and runs on to new code otherwise before returning.

Code:
ROM:000B97C0             sub_B97C0:                              ; CODE XREF: sub_2B0A2
ROM:000B97C0                                                     ; DATA XREF: sub_2B0A2:loc_2B0E8
ROM:000B97C0 4F 22                       sts.l   pr, @-r15       ; Store System Register Long
ROM:000B97C2 46 08                       shll2   r6              ; Shift Logical Left 2
ROM:000B97C4 46 00                       shll    r6              ; Shift Logical Left
ROM:000B97C6 02 10 0E 0C                 movi20  #off_10E0C, r2  ; 20-bit immediate data transfer
ROM:000B97CA 60 63                       mov     r6, r0          ; Move Data
ROM:000B97CC 06 2E                       mov.l   @(r0,r2), r6    ; Move Long Data
ROM:000B97CE F0 68                       fmov.s  @r6, fr0        ; Floating-point move single precision: Multiplier value
ROM:000B97D0 72 04                       add     #4, r2          ; Add binary
ROM:000B97D2 06 2E                       mov.l   @(r0,r2), r6    ; Move Long Data
ROM:000B97D4 F9 68                       fmov.s  @r6, fr9        ; Floating-point move single precision: Offset value
ROM:000B97D6 F9 4E                       fmac    fr0, fr4, fr9   ; Floating-point multiply and accumulate: fr9 = fr0(multiplier)*fr4(sensor voltage)+fr9(offset)
ROM:000B97D8 60 D3                       mov     r13, r0         ; Move Data
ROM:000B97DA 88 0B                       cmp/eq  #h'B, r0        ; Compare: Equal: if sensor value being returned is Evap (r13 = 0B), the T bit is set
ROM:000B97DC 8B 2F                       bf      loc_B983E       ; Branch if False:  Branch to return to stack after restoring pr

ROM:000B97DE Write new routines in here... then return to stack after restoring pr (at B983E in this case)

............

ROM:000B983E             loc_B983E:                              ; CODE XREF: sub_B97C0
ROM:000B983E 4F 26                       lds.l   @r15+, pr       ; Load to System Register Long
ROM:000B9840 00 6B                       rts/n                   ; Return from Subroutine with No delay slot
ztan is offline   Reply With Quote
The Following 6 Users Say Thank You to ztan For This Useful Post:
DocWalt (11-03-2015), DustinS (11-03-2015), elBarto (11-03-2015), Guff (07-13-2016), mkivsoopra (11-10-2015), Wayno (07-19-2016)