This is where the BIN Hackers and definition junkies discuss the inner workings of the EEC code and hardware. General tuning questions do not go here. Only technical/hardware-specific/code questions and discussions belong here.

Moderators: EDS50, cgrey8, 2Shaker, Jon 94GT

Post Reply
cprhodin
Gear Head
Posts: 7
Joined: Mon Apr 30, 2012 4:32 am

Disassembling a Math Function

Post by cprhodin » Wed May 02, 2012 5:09 am

Hi,

I've been disassembling the code from an LA3 ('88 Turbo Coupe). So far I've identified the interrupt code, some of the tables and some of the functions. Currently I'm trying to figure out a function that does something with the tables. It's accessing a 2 dimensional table at location calculated with "((r52 * r51) + r49) + r57:r56". What I can't figure out is why the three passes through the multiply at the end. Here's the routine, anybody recognize it?

func5943: mulub r54, R52, R51
addb r54, R49
jnc L594E
incb r55
L594E: add r56, R54

ldb r49, [r56]+
ldb r51, [R56]
scall func5972
add r56, R52
ldb r51, [R56]
dec r56
ldb r49, [R56]
ldb r52, R59
scall func5972
ldb r51, R59
ldb r49, R52
ldb r48, R50

func5972: mulub r58, R48, R51
mulub r54, R48, R49
sub r58, R54
addb r59, R49
add r58, #0x0080
ret


Chris

mpaton
BIN Hacker
Posts: 381
Joined: Mon Jun 23, 2008 1:39 pm

Re: Disassembling a Math Function

Post by mpaton » Wed May 02, 2012 11:34 am

Think about how you would do linear interpolation in a 2D table.
A 1D table, you interpolate between 2 values.
What do you have to do when the value you want lies in the middle of a 2D grid of 4 values?

Understanding the 1D interpolation at 0x589B and how that value is used in 0x5943 would help you also. It's quite simple but clever.
cprhodin wrote:Hi,

I've been disassembling the code from an LA3 ('88 Turbo Coupe). So far I've identified the interrupt code, some of the tables and some of the functions. Currently I'm trying to figure out a function that does something with the tables. It's accessing a 2 dimensional table at location calculated with "((r52 * r51) + r49) + r57:r56". What I can't figure out is why the three passes through the multiply at the end. Here's the routine, anybody recognize it?

func5943: mulub r54, R52, R51
addb r54, R49
jnc L594E
incb r55
L594E: add r56, R54

ldb r49, [r56]+
ldb r51, [R56]
scall func5972
add r56, R52
ldb r51, [R56]
dec r56
ldb r49, [R56]
ldb r52, R59
scall func5972
ldb r51, R59
ldb r49, R52
ldb r48, R50

func5972: mulub r58, R48, R51
mulub r54, R48, R49
sub r58, R54
addb r59, R49
add r58, #0x0080
ret


Chris

User avatar
tvrfan
Tuning Addict
Posts: 590
Joined: Sat May 14, 2011 11:41 pm
Location: New Zealand

Re: Disassembling a Math Function

Post by tvrfan » Wed May 02, 2012 4:34 pm

I'll explain it as explained to me.....

The tables actually represent a 2D to 1D conversion (2 variables to 1 answer).

So imagine BOTH your input variables fall part way between defined points (=cells) in the table.
In effect this means the true answer lies between FOUR cells in the table (those 4 cells surround the point the 2 input variables reference). If you don't get this, STOP and reread it a few times, because it's crucial to understand before going on.

So then all the calc has to do is interpolate the two pairs of cells vertically, and then interpolate the two answers from the two pairs to get the final answer....= 3 interpolates. So that second block of code is simply a math 'interpolate' function.

here's the early version from my box -

3277: 5c,33,34,36 ml3b R36,R34,R33 R36W = R34B * R33B; # Y*cols. Get into correct column.
327b: 74,31,36 ad2b R36,R31 R36 += R31; # (Y*cols)+X. = Correct (lower) cell offset.
327e: d3,02 jnc 3282 if ((uns) R36 >= R31) {
3280: 17,37 incb R37 R37++;} # Add carry if byte o/flow.
3282: 64,36,38 ad2w R38,R36 R38 += R36; # Real cell address, table+offset
3285: b2,39,31 ldb R31,[R38++] R31 = [R38++]; # R31 = [0,0] BASE cell, below input value.
3288: b2,38,33 ldb R33,[R38] R33 = [R38]; # R33 = [1,0] cell, [ next X value]
328b: 28,1c scall 32a9 TabInterp(); # R3b = Interpolated X,0 (R31, R33) by fract X
328d: 64,34,38 ad2w R38,R34 R38 += R34;
3290: b2,38,33 ldb R33,[R38] R33 = [R38]; # R33 = [1,1] cell (next x, next y)
3293: 05,38 decw R38 R38--;
3295: b2,38,31 ldb R31,[R38] R31 = [R38]; # R31 = [0,1] cell (this x, next y)
3298: b0,3b,34 ldb R34,R3b R34 = R3b; # save interpolated X
329b: 28,0c scall 32a9 TabInterp(); # Interpolated (X,1) value by fract X.
329d: b0,3b,33 ldb R33,R3b R33 = R3b; # intpolated (X,1)
32a0: b0,34,31 ldb R31,R34 R31 = R34; # intpolated (X,0)
32a3: b0,32,30 ldb R30,R32 R30 = R32; # set interpolate fraction to Y value
32a6: 28,01 scall 32a9 TabInterp(); # Interpolate intpld(x,0), intpld(x,1) in fraction Y
32a8: f0 ret return

TabInterp:
32a9: 5c,33,30,3a ml3b R3a,R30,R33 R3aW = R30B * R33B; # R3a = fraction * high val
32ad: 5c,31,30,36 ml3b R36,R30,R31 R36W = R30B * R31B; # R36 = fraction * low val
32b1: 68,36,3a sb2w R3a,R36 R3a -= R36; # R3a = (fract*high)-(fract*low) [= increment*fract]
32b4: 74,31,3b ad2b R3b,R31 R3b += R31; # R3b = increment*fract/256 + low
32b7: 65,80,00,3a ad2w R3a,80 R3a += 128; # round up for answer in R3b
32bb: f0 ret return
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler

cprhodin
Gear Head
Posts: 7
Joined: Mon Apr 30, 2012 4:32 am

Re: Disassembling a Math Function

Post by cprhodin » Wed May 02, 2012 10:10 pm

Thanks, it's much easier to understand once the intent is made clear. Now I can see that the X,Y points in the table are placed at fixed intervals (256) and the inputs are scaled to the table.

ChrisR

User avatar
tvrfan
Tuning Addict
Posts: 590
Joined: Sat May 14, 2011 11:41 pm
Location: New Zealand

Re: Disassembling a Math Function

Post by tvrfan » Thu May 03, 2012 4:34 pm

Often the tables are set at regular intervals, but not always. That math 'interpolate' strategy still works however, even if the table parameters are not linear.

Note that some of the function lookups are used solely to map variables (like engine temp, rpm, etc) into a scale (say 0-11) which is then used in a lookup table. These aren't always linear (on input), and allow the table scale to be more detailed in some places (like around idle).

It's a very clever and neat solution. Whoever programmed these boxes certainly wasn't dumb !!
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler

Post Reply

Who is online

Users browsing this forum: No registered users and 43 guests