Code: Alles auswählen
CallBIOS (14, 1, [color=red]3[/color], 0, 0);
Dann spart man sich einen Suchlauf für EventDispatcherAddress.
Im allgemeinen finde ich die Suchmethode für FW-Funktionen etwas (echt-)zeitaufwendig. Daher habe ich meistens versucht, einen Einstieg über die TAP-API-Funktionen zu finden, um dann gezielt zu den gewünschten FW-Funktionen zu gelangen. Dieser Ansatz spart jede Menge Zeit beim Starten von TAPs.
Ein Beispiel:
Code: Alles auswählen
#define CMD_MASK 0xfc000000
#define JAL_CMD 0x0c000000
#define JR_CMD 0x03e00008
#define ABS_ADDR(x) (0x80000000 | (((dword)(x) & 0x03ffffff) << 2))
//-----------------------------------------------------------------------------
// getCallAddress() retrieves the address of the n-th function call found
// after the specified address.
dword *getCallAddress(dword *pData, int count)
{
int i = 0, j = 0;
dword *pAddr = NULL;
if(count > 0)
{
while(pData[i] != JR_CMD)
{
if((pData[i] & CMD_MASK) == JAL_CMD)
{
j++;
if(j == count)
{
// return the absolute address encoded in the opcode
pAddr = (dword*)ABS_ADDR(pData[i]);
break;
}
}
i++;
}
}
return pAddr;
}
//--------------------------------------------
// getCallBios(): This operation retrieves the address of the function
// queueing all I/O activities (BIOS).
dword getCallBios()
{
// Find the FW function handling all BIOS operations
// Follow the following call chain:
// TAP_ChannelSetSubtitleTrack -> 1st call -> 1st call -> ___1st call___
dword *pCallBios = (dword*)TAP_Channel_SetSubtitleTrack;
if((pCallBios = getCallAddress(pCallBios, 1)) == NULL)
return 0;
if((pCallBios = getCallAddress(pCallBios, 1)) == NULL)
return 0;
// the last call returns the requested address
return (dword)getCallAddress(pCallBios, 1);
}