Register - Login
Views: 99794730
Main - Memberlist - Active users - Calendar - Wiki - IRC Chat - Online users
Ranks - Rules/FAQ - Stats - Latest Posts - Color Chart - Smilies
05-03-22 05:18:04 AM
Jul - General Game/ROM Hacking - Z80: help identifying an algorithm (or at least its conditions) New poll - New thread - New reply
Next newer thread | Next older thread
andlabs
Member
Level: 38


Posts: 159/309
EXP: 361452
For next: 8995

Since: 03-19-10

From: United States

Since last post: 1.1 years
Last activity: 138 days

Posted on 10-27-13 02:14:28 PM Link | Quote
Code:


ROM:198D ; =============== S U B R O U T I N E =======================================

ROM:198D
ROM:198D
ROM:198D sub_198D: ; CODE XREF: ROM:1061p
ROM:198D ; sub_1343+17p ...
ROM:198D ld h, 1 ; 100h
ROM:198F ld a, b ; a = b - c
ROM:1990 sub c
ROM:1991 jr nc, loc_199E ; if a xxx 0 goto loc
ROM:1993 neg ; a = -a
ROM:1995 srl a ; a >>= 1 (a /= 2)
ROM:1997 ld c, a ; c = a
ROM:1998 add a, b ; a += b
ROM:1999 ld l, a ; a = (100h)[a]
ROM:199A ld a, (hl)
ROM:199B ld l, c ; a -= (100h)[c]
ROM:199C sub (hl) ; alternatively, swap b and c, then do the below
ROM:199D ret
ROM:199E ; ---------------------------------------------------------------------------
ROM:199E
ROM:199E loc_199E: ; CODE XREF: sub_198D+4j
ROM:199E srl a ; a >>= 1 (a /= 2)
ROM:19A0 ld b, a ; b = a
ROM:19A1 add a, c ; a += c
ROM:19A2 ld l, a ; a = (100h)[a]
ROM:19A3 ld a, (hl)
ROM:19A4 ld l, b ; a -= (100h)[b]
ROM:19A5 sub (hl)
ROM:19A6 ret
ROM:19A6 ; End of function sub_198D



Data at 100h:


ROM:0100                 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1

ROM:0100 db 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4
ROM:0100 db 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 0Ah, 0Ah
ROM:0100 db 0Ah, 0Bh, 0Bh, 0Ch, 0Ch, 0Dh, 0Dh, 0Eh, 0Eh, 0Fh, 0Fh
ROM:0100 db 10h, 10h, 11h, 11h, 12h, 12h, 13h, 13h, 14h, 14h, 15h
ROM:0100 db 15h, 16h, 17h, 17h, 18h, 19h, 19h, 1Ah, 1Ah, 1Bh, 1Ch
ROM:0100 db 1Ch, 1Dh, 1Eh, 1Eh, 1Fh, 20h, 21h, 21h, 22h, 23h, 24h
ROM:0100 db 24h, 25h, 26h, 27h, 27h, 28h, 29h, 2Ah, 2Bh, 2Bh, 2Ch
ROM:0100 db 2Dh, 2Eh, 2Fh, 30h, 31h, 31h, 32h, 33h, 34h, 35h, 36h
ROM:0100 db 37h, 38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h, 41h
ROM:0100 db 42h, 43h, 44h, 45h, 46h, 47h, 48h, 49h, 4Ah, 4Bh, 4Ch
ROM:0100 db 4Dh, 4Eh, 4Fh, 51h, 52h, 53h, 54h, 55h, 56h, 57h, 59h
ROM:0100 db 5Ah, 5Bh, 5Ch, 5Dh, 5Fh, 60h, 61h, 62h, 64h, 65h, 66h
ROM:0100 db 67h, 69h, 6Ah, 6Bh, 6Ch, 6Eh, 6Fh, 70h, 72h, 73h, 74h
ROM:0100 db 76h, 77h, 79h, 7Ah, 7Bh, 7Dh, 7Eh, 7Fh, 81h, 82h, 84h
ROM:0100 db 85h, 87h, 88h, 8Ah, 8Bh, 8Dh, 8Eh, 90h, 91h, 93h, 94h
ROM:0100 db 96h, 97h, 99h, 9Ah, 9Ch, 9Dh, 9Fh, 0A0h, 0A2h, 0A4h
ROM:0100 db 0A5h, 0A7h, 0A9h, 0AAh, 0ACh, 0ADh, 0AFh, 0B1h, 0B2h
ROM:0100 db 0B4h, 0B6h, 0B7h, 0B9h, 0BBh, 0BDh, 0BEh, 0C0h, 0C2h
ROM:0100 db 0C4h, 0C5h, 0C7h, 0C9h, 0CBh, 0CCh, 0CEh, 0D0h, 0D2h
ROM:0100 db 0D4h, 0D5h, 0D7h, 0D9h, 0DBh, 0DDh, 0DFh, 0E1h, 0E2h
ROM:0100 db 0E4h, 0E6h, 0E8h, 0EAh, 0ECh, 0EEh, 0F0h, 0F2h, 0F4h
ROM:0100 db 0F6h, 0F8h, 0FAh, 0FCh, 0FEh



The given function takes b and c as input and produces a as output.

This is Time Trax for Genesis's sound driver, and at this point in the program I come across a structure like


    db command_byte

db unknown_parameter
dw jump_table_target_1
dw jump_table_target_2
dw jump_table_target_3
...
jump_table_target_1:
db command_bytes...



unknown_parameter is loaded into b and some other value is loaded into c; the result is the index into the jump table.

I am trying to determine one of the following two things:
1) Is unknown_parameter the size of the jump table? Or in other words, is b the upper bound of a?
2) What does this function do? I have no idea...
Thanks.
andlabs
Member
Level: 38


Posts: 160/309
EXP: 361452
For next: 8995

Since: 03-19-10

From: United States

Since last post: 1.1 years
Last activity: 138 days

Posted on 10-27-13 04:43:34 PM Link | Quote
Well I got my answer to the first question: yes b is the upper bound of a, and yes that unknown_parameter is the size of the list. (The linked thread came before this one.) I'll still leave this open in case anyone wants to try figuring out the mathematical function of this subroutine (question 2); when I figure out the other code that calls this function I can explain what that does. Thanks anyway!
andlabs
Member
Level: 38


Posts: 161/309
EXP: 361452
For next: 8995

Since: 03-19-10

From: United States

Since last post: 1.1 years
Last activity: 138 days

Posted on 10-29-13 02:34:53 AM (last edited by andlabs at 10-29-13 02:36:40 AM) Link | Quote
I figured out this function is mainly used for volume control. Here's the gist of it:


For each operator (each FM channel has four operators that get combined)

x = current operator's "total level" (an attenuation value 0x00..0x7F) ^ 0x7F
If the current operator is connected to the speaker and not to another operator
x = this function(b = x, c = an external parameter loaded by the 68000; I think it's the global volume and it's 0xFF by default and 0xFF or 0x00 otherwise)
x = this function(b = x, c = current channel volume (set by an effect command))
SetTotalLevel(x ^ 0x7F) (to set back to TL)



My best guess is that this is a linear->log (linear->exponential?) conversion function with built-in max()...
Next newer thread | Next older thread
Jul - General Game/ROM Hacking - Z80: help identifying an algorithm (or at least its conditions) New poll - New thread - New reply


Rusted Logic

Acmlmboard - commit 47be4dc [2021-08-23]
©2000-2022 Acmlm, Xkeeper, Kaito Sinclaire, et al.

26 database queries, 2 query cache hits.
Query execution time: 0.081155 seconds
Script execution time: 0.007722 seconds
Total render time: 0.088877 seconds