Post by dino2gnt on Aug 10, 2022 18:59:42 GMT
Is anyone out there?
I've been taking a several week break after going hard on SBEC3 reverse engineering for 8-9 months, but I'm starting to get back into it and figure I should stir up some discussion.
I've been trying to figure out from the table lookup function how table axes are laid out, for example how the pointer moves in the table Y axis when only the X axis scale is included in the table data and I feel like I'm right on the edge of understanding (and the edge of ability!) and would love some feedback on what I've got here.
This is from 05293190AC (USDM MY 98 / 99), and surprisingly is completely different than the 05293013AC (USDM MY 97) I have (figuratively) right next to it.
This is from 05293190AC (USDM MY 98 / 99), and surprisingly is completely different than the 05293013AC (USDM MY 97) I have (figuratively) right next to it.
ROM:C214 ; Lookup rB by prescaled rA in a table, return interpolated value in rA, rB & maybe 0xF8C5D
ROM:C214
ROM:C214 Table_2D: ; CODE XREF: sub_104AE+22p
ROM:C214 ; sub_10A6E+4Ep ...
ROM:C214 pshm E, Y, K
ROM:C216 ais #-0Ah ; add -10 to the stack pointer (move the stack pointer 10 bytes towards zero)
ROM:C21A txy ; y = x
ROM:C21C tsx ; x = stack pointer
ROM:C21E tde ; e = d, save our original A & B values to E
ROM:C220 clrb
ROM:C222 tbyk ; 0, Y = HEIGHT (# of ROWS)
ROM:C222 ; 1, Y = WIDTH (# of COLUMNS)
ROM:C222 ; 2, Y = SIGNED or UNSIGNED
ROM:C222 ; 3, Y = First cell of the X axis scale
ROM:C222 ;
ROM:C222 ; 0, X = rA value (the Y axis value)
ROM:C222 ; 1, X = Calculated slope?
ROM:C222 ; 2, X = HEIGHT (Table Y axis)
ROM:C222 ; 3, X = WIDTH (Table X axis)
ROM:C222 ; 4, X = SIGNED or UNSIGNED
ROM:C222 ; 7, X = Pointer to table
ROM:C224 ; assume YK = 0
ROM:C224 sty 7, X ; store table base address to X+7
ROM:C226 ldaa 1, Y ; Table width value (# of columns)
ROM:C228 staa 3, X ; Store width to 3,X
ROM:C228 ; .
ROM:C22A lbeq loc_C312 ; If the value stored was a zero, special case
ROM:C22E ldaa 0, Y ; Table height value (# of rows)
ROM:C230 staa 2, X ; store height to 2,X
ROM:C230 ; .
ROM:C232 lbeq loc_C31C ; if width is zero, special case
ROM:C236 ldaa 2, Y ; Signed or unsigned
ROM:C238 staa 4, X ; Store it in stack-land
ROM:C238 ; .
ROM:C23A ted ; move D (A&B) back from E
ROM:C23C staa 0, X ; Store our index value A to stack-land
ROM:C23E aiy #3 ; Move to the beginging of the table data
ROM:C23E ; .
ROM:C240 cmpb 0, Y ; Check if X-axis value in B is ...
ROM:C242 bls loc_C254 ; ... less than or equal to the lowest X-axis value
ROM:C244 ldaa 3, X ; else load A with the table width
ROM:C246 deca ; ...and subtract 1 from the width
ROM:C248
ROM:C248 loc_C248: ; CODE XREF: Table_2D+3Ej
ROM:C248 beq loc_C254 ; Branch if the dec made A = 0
ROM:C24A cmpb 1, Y ; compare B to the width/X-axis value (this is starting in the top-left cell of the table and moving right / incrementing)
ROM:C24C bcs loc_C258 ; Branch if width-axis value is greater than B
ROM:C24E aiy #1 ; Move in width / increase Y to the next cell
ROM:C24E ; IY should increment to the highest cell that is less than rB (0,Y)
ROM:C250 deca ; Dec A and loop
ROM:C252 bra loc_C248 ; loop
ROM:C254 ; ---------------------------------------------------------------------------
ROM:C254
ROM:C254 loc_C254: ; CODE XREF: Table_2D+2Ej
ROM:C254 ; Table_2D:loc_C248j
ROM:C254 clr 1, X
ROM:C256 bra loc_C278 ; Table width from memory
ROM:C258 ; ---------------------------------------------------------------------------
ROM:C258
ROM:C258 loc_C258: ; CODE XREF: Table_2D+38j
ROM:C258 tba ; B -> A
ROM:C25A pshm X ; Push X to stack
ROM:C25C ldx #0 ; zero IX
ROM:C260 ldab 1, Y ; Calculate the difference between the cell below us 0,Y and the cell we where we stopped 1,Y
ROM:C260 ; This is all still in the X axis value-index
ROM:C262 subb 0, Y
ROM:C264 bne loc_C26A ; if not zero
ROM:C266 ldaa #0FFh
ROM:C268 bra loc_C274
ROM:C26A ; ---------------------------------------------------------------------------
ROM:C26A
ROM:C26A loc_C26A: ; CODE XREF: Table_2D+50j
ROM:C26A abx ; Add the difference in (0,Y) and (1,Y) to IX
ROM:C26C suba 0, Y ; rA is a copy of rB from the tba @ c258
ROM:C26C ; subtract 0,Y from rA
ROM:C26C ; This is the difference between the cell below us (0,Y) and the lookup value rB
ROM:C26E clrb ; Zero B
ROM:C270 idiv ; IX = D / IX (remainder in D)
ROM:C270 ; IX is the difference between the two cells
ROM:C270 ; rA is the difference between the lower cell and the raw value
ROM:C272 xgdx ; Swap the remainder(D) and the quotient(IX); D is now the quotient and IX is the remainder
ROM:C274
ROM:C274 loc_C274: ; CODE XREF: Table_2D+54j
ROM:C274 pulm X ; Pull X back off the stack; overwrite remainder from above, IX is now the modified stack pointer again
ROM:C276 stab 1, X ; This is the difference between the cell above us (1,Y) and the cell below us (0,Y) divided by the difference in the raw value (rB) and the cell below us (0,Y). This must be for interpolation
ROM:C278
ROM:C278 loc_C278: ; CODE XREF: Table_2D+42j
ROM:C278 ldab 3, X ; Table width from memory
ROM:C27A aby ; add B to IY
ROM:C27C ldd 7, X ; load D with pointer to the table base address
ROM:C27E pshm Y ; Push Y
ROM:C280 pulm E ; Pull Y back off the stack as E
ROM:C282 sde ; Subtract D from E (result in E)
ROM:C282 ; This is the difference between the base table pointer and IY - how far we've moved "to the right" to find the correct column.
ROM:C284 ted ; Move result back to D
ROM:C286 subb #3 ; Subtract 3 from B (don't count the header)
ROM:C288 subb 3, X ; Subtract B from the table width (don't count the X axis values?)
ROM:C28A bra loc_C2C8
ROM:C28C ; ---------------------------------------------------------------------------
[ ... ]
ROM:C2C8 loc_C2C8: ; CODE XREF: Table_2D+76j
ROM:C2C8 aslb
ROM:C2CA aslb
ROM:C2CC aslb ; 4x left-shift rB
ROM:C2CE aslb
ROM:C2D0 tde ; D -> E
ROM:C2D2 ldab 0, X ; rA, the height(Y)-axis value
ROM:C2D4 ldaa 2, X ; Table height in rows
ROM:C2D6 deca ; Decrement table height by 1
ROM:C2D8 mul ; Multiply the Y-axis value by the table row count
ROM:C2DA tab ; A -> B (Copy the high byte of the MUL result to B)
ROM:C2DC ade ; Add A:B to E (this seems weird after a MUL -> TAB)
ROM:C2DE ldab 3, X ; rB = table width
ROM:C2E0 mul ; Multiple the high byte of the previous MUL by the table width
ROM:C2E2 aby ; Add the low byte of the result to IY
ROM:C2E4 ldab 1, X ; Load the slope-something-whatever value
ROM:C2E6 bsr sub_C32E ; I super don't understand what's going on here.
ROM:C2E8 tba
ROM:C2EA ldab 3, X ; rB = table width
ROM:C2EC aby
ROM:C2EE ldab 1, X ; Load the slope-something-whatever value
ROM:C2F0 bsr sub_C32E
ROM:C2F2 xgdy
ROM:C2F4 pshm Y
ROM:C2F6 tsy
ROM:C2F8 ldaa 0, X ; rA = the height-axis value
ROM:C2FA ldab 2, X ; rB = The table height
ROM:C2FC decb ; rB = the table height minus 1
ROM:C2FE mul ; D = B * A
ROM:C300 bsr sub_C32E
ROM:C302 pulm Y
ROM:C304 ste 5, X
ROM:C308 xgex
ROM:C30A tba
ROM:C30C staa 0xF8C5D
ROM:C310 bra loc_C328
ROM:C312 ; ---------------------------------------------------------------------------
ROM:C312
ROM:C312 loc_C312: ; CODE XREF: Table_2D+16j
ROM:C312 ; Table_2D+8Ej ...
ROM:C312 ldy 7, X ; IY = table pointer
ROM:C314 aiy #3 ; Skip header
ROM:C316 ldaa 3, Y ; Why 3?
ROM:C318 tab
ROM:C31A bra loc_C328
ROM:C31C ; ---------------------------------------------------------------------------
ROM:C31C
ROM:C31C loc_C31C: ; CODE XREF: Table_2D+1Ej
ROM:C31C ldd 7, X ; D = table pointer
ROM:C31E addd 3, X ; add the width value
ROM:C320 xgdy ; Swap D to IY
ROM:C322 aiy #3 ; Move Y to the beginging of the table data
ROM:C324 ldaa 3, Y ; Read this byte from table (why 3?)
ROM:C326 tab ; Copy it to B
ROM:C328
ROM:C328 loc_C328: ; CODE XREF: Table_2D+FCj
ROM:C328 ; Table_2D+106j
ROM:C328 ais #0Ah
ROM:C32A pulm K, Y, E
ROM:C32C rts
ROM:C32C ; End of function Table_2D
ROM:C32C
ROM:C32E
ROM:C32E ; =============== S U B R O U T I N E =======================================
ROM:C32E
ROM:C32E
ROM:C32E sub_C32E: ; CODE XREF: Table_2D+D2p
ROM:C32E ; Table_2D+DCp ...
ROM:C32E pshm E
ROM:C330 pshm D
ROM:C332 ldaa 1, Y
ROM:C334 suba 0, Y ; Calc delta between 1,Y and 0,Y (again?)
ROM:C336 brclr 4, X, #0FFh, loc_C340 ; 4,X is Signed or Unsigned flag
ROM:C336 ; 0x0 unsigned, 0x80 or 0xFF is signed
ROM:C336 ; This is clear for unsigned tables
ROM:C33C blt loc_C34C
ROM:C33E bra loc_C342
ROM:C340 ; ---------------------------------------------------------------------------
ROM:C340
ROM:C340 loc_C340: ; CODE XREF: sub_C32E+8j
ROM:C340 bcs loc_C34C ; if 0,Y is greater than 1,Y for some reason, carry would be set
ROM:C342
ROM:C342 loc_C342: ; CODE XREF: sub_C32E+10j
ROM:C342 mul ; D = A * B
ROM:C342 ; A is the delta between Y,0 and Y,1
ROM:C342 ; B is the slope-something-whatever value 1,X
ROM:C344 adca #0 ; Add 0 to A with carry, i.e. round the high byte of the result in A
ROM:C346 tab ; Copy the high byte to B
ROM:C348 addb 0, Y ; Add the table HEIGHT to B / move us down a row?
ROM:C34A bra loc_C358 ; Move A & B to E
ROM:C34C ; ---------------------------------------------------------------------------
ROM:C34C
ROM:C34C loc_C34C: ; CODE XREF: sub_C32E+Ej
ROM:C34C ; sub_C32E:loc_C340j
ROM:C34C nega
ROM:C34E mul
ROM:C350 adca #0
ROM:C352 nega
ROM:C354 adda 0, Y ; 0, Y = HEIGHT (# of ROWS)
ROM:C356 tab
ROM:C358
ROM:C358 loc_C358: ; CODE XREF: sub_C32E+1Cj
ROM:C358 tde ; Move A & B to E
ROM:C35A pulm D ; Pull D back off the stack
ROM:C35C ande #0FFh ; And 0xFF with E / this appears to discard the high byte?
ROM:C360 clrb ; Clear B / discard the low byte of D
ROM:C362 ade ; Add D to E
ROM:C364 ted ; Copy E to D
ROM:C366 pulm E ; Pull E back off the stack
ROM:C368 rts ; Values in D and E
ROM:C368 ; End of function sub_C32E ; The calling function cares about B, so...