some reverse engineering notes.
for FRSP we call first FA_CreateTestImage to get a prepared image job.
struct struc_JobClass *cmd_FA_CreateTestImage()
{
struct struc_JobClass *job; // r4@3
unsigned int length; // [sp+Ch] [bp-44h]@3
unsigned int *data_ptr; // [sp+10h] [bp-40h]@3
struct struc_ShootParm tv; // [sp+14h] [bp-3Ch]@3
DryosDebugMsg(0x90, 0x16, "FA_CreateTestImage");
exec_command_vararg("sht_FA_CreateTestImage");
msleep(20);
if ( !word_2771C )
{
SRM_ChangeMemoryManagementForFactory();
}
++word_2771C;
PROP_GetMulticastProperty(PROP_SHUTTER, &data_ptr, &length);
tv.Tv = *data_ptr;
tv.Tv2 = *data_ptr;
PROP_GetMulticastProperty(PROP_APERTURE, &data_ptr, &length);
tv.Av = *data_ptr;
tv.Av2 = *data_ptr;
PROP_GetMulticastProperty(PROP_ISO, &data_ptr, &length);
tv.ISO = *data_ptr;
tv.PO_lo = 185;
tv.PO_hi = 0;
tv.TP = 153;
job = CreateSkeltonJob(&tv, FA_CreateTestImage_cbr);
DryosDebugMsg(0x90, 0x16, "hJob(%#lx)(tv=%#x,av=%#x,iso=%#x)", job, (unsigned __int8)tv.Tv, (unsigned __int8)tv.Av, (unsigned __int8)tv.ISO);
DryosDebugMsg(0x90, 0x16, "FA_CreateTestImage Fin");
return job;
}
it sets factory mode, gets Tv, Av and ISO into a struct shootParm
#pragma pack(push, 1)
struct __attribute__((packed)) __attribute__((aligned(1))) struc_ShootParm
{
char Tv;
char Av;
char Tv2;
char Av2;
char ISO;
char field_5;
char unk_HI;
char unk_LO;
int field_8;
int field_C;
char field_10;
char field_11;
char WftReleaseCheck;
char field_13;
char field_14;
char field_15;
char field_16;
char field_17;
char field_18;
char TP;
char field_1A;
char PO_hi;
char PO_lo;
char field_1D;
char field_1E;
char field_1F;
char field_20;
char field_21;
char field_22;
char field_23;
char field_24;
__int16 field_25;
char field_27;
char field_28;
char field_29;
char field_2A;
char field_2B;
int field_2C;
char EshutMode__;
char EshutMode_;
char field_32;
char field_33;
int field_34;
int field_38;
int field_3C;
char field_40;
};
#pragma pack(pop)
and then calls CreateSkeltonJob to create a job for these parameters
struct struc_JobClass *__cdecl CreateSkeltonJob(struct struc_ShootParm *shootParam, int (__cdecl *cbr)(int, int))
{
int v4; // r0@1
const char *v5; // r2@1
int v6; // r3@1
struct struc_memChunk *v7; // r0@4
struct struc_JobClass *job; // r5@4
signed int jobField; // r0@4
int v10; // r1@5
int v11; // r0@6
int v12; // r0@10
const char *v13; // r2@10
int v14; // r3@10
struct struc_Container *v15; // r0@13
struct struc_Container *v16; // r0@14
signed int v17; // r0@16
struct struc_memSuite *Mem1Component; // r0@21
void *v20; // [sp+0h] [bp-38h]@1
struct struc_memSuite *suite; // [sp+8h] [bp-30h]@1
int data; // [sp+Ch] [bp-2Ch]@3
v20 = shootParam;
suite = 0;
DryosDebugMsg(0x8F, 5, "CreateSkeltonJob (%#x)", cbr);
SRM_AllocateMemoryResourceForJobObject(0x114C, SRM_AllocateMemoryResourceFor1stJob_cbr, &suite);
v4 = TakeSemaphoreTimeout((void *)dword_27A44, 0x64);
if ( v4 )
{
v6 = v4;
v5 = "SRM_AllocateMemoryResourceForJobObject failed [%#x]";
}
data = v4;
if ( v4 )
{
goto LABEL_9;
}
v7 = GetFirstChunkFromSuite(suite);
job = (struct struc_JobClass *)GetMemoryAddressOfMemoryChunk(v7);
memzero(job, 0x114Cu);
jobField = 0;
do
{
v10 = 0x31 * jobField;
job->jobs[jobField++].job_ref = job;
job->jobs[4 * v10 / 0xC4u].signature = "JobClass";
}
while ( jobField < 3 );
job->suite = suite;
SRM_AllocateMemoryResourceForCaptureWork(0x40000, (int)SRM_AllocateMemoryResourceFor1stJob_cbr, (unsigned int *)&job->Mem1Component_0x4000_MEM1);
v11 = TakeSemaphoreTimeout((void *)dword_27A44, 0x64);
data = v11;
if ( v11 || !job->Mem1Component_0x4000_MEM1 )
{
v5 = (const char *)"SRM_AllocateMemoryResourceForCaptureWork failed [%#x, %#x]";
v20 = suite;
v6 = v11;
LABEL_9:
DryosDebugMsg(0x8F, 6, v5, v6, v20);
data = 5;
prop_request_change(PROP_MVR_REC, &data, 4u);
return (struct struc_JobClass *)&unk_5;
}
SRM_AllocateMemoryResourceFor1stJob((int)SRM_AllocateMemoryResourceFor1stJob_cbr, (int)&job->ImageBuffer);
v12 = TakeSemaphoreTimeout((void *)dword_27A44, 0x64);
if ( v12 )
{
v14 = v12;
v13 = "SRM_AllocateMemoryResourceFor1stJob failed [%#x]";
}
data = v12;
if ( v12 )
{
LABEL_18:
DryosDebugMsg(0x8F, 6, v13, v14);
return (struct struc_JobClass *)&unk_5;
}
memcpy_0(&job->ShootParam, shootParam, 0x31u);
GetCurrentDcsParam(&job->DcsParam);
jobSetUnitPictType(job, job->DcsParam.PictType);
job->cbr = cbr;
job->cbr_ptr = &job->cbr;
job->field_25C = 1;
job->JobID = dword_27A24 + 1;
v15 = CreateContainerWithoutLock("JobClass");
job->FileContainer = v15;
if ( (unsigned __int8)v15 & 1 || (v16 = CreateContainerWithoutLock("JobClass"), job->JobClassContainer = v16, (unsigned __int8)v16 & 1) )
{
v14 = data;
v13 = (const char *)"CreateContainerWithoutLock failed [%#x]";
goto LABEL_18;
}
v17 = Container_AddObject(job->FileContainer, "Mem1Component", (int)job->Mem1Component_0x4000_MEM1, 0x40000, (int)sub_FF0F2008, 0);
data = v17;
if ( v17 & 1 )
{
v14 = v17;
v13 = "AddObject failed [%#x]";
goto LABEL_18;
}
Mem1Component = job->Mem1Component_0x4000_MEM1;
job->pLuckyTable = &Mem1Component[0x2600];
DryosDebugMsg(0x8F, 5, "Mem1Component 0x%x pLuckyTable 0x%x", Mem1Component, &Mem1Component[0x2600]);
irq_disable();
if ( !powersave_count )
{
cmd_DisablePowerSave();
}
++dword_27A24;
++powersave_count;
irq_enable();
return job;
}
the job structure is this one:
#pragma pack(push, 4)
struct struc_JobClass
{
struc_JobClassListElem jobs[3];
_BYTE gap24C[4];
struct struc_memSuite *suite;
int (__cdecl **cbr_ptr)(int, int);
int (__cdecl *cbr)(int, int);
int field_25C;
int JobID;
int field_264;
int field_268;
int ObjectID;
int field_270;
int field_274;
int field_278;
int Destination;
struct struc_ShootParm ShootParam;
struc_AfterParam AfterParam;
__attribute__((aligned(4))) struct struc_DcsParam DcsParam;
int ShootImageStorage;
struct struc_memSuite *ImageMemory_0x4_JPEG_L;
struct struc_memSuite *ImageMemory_0x1_JPEG_M;
struct struc_memSuite *ImageMemory_0x1_JPEG_S;
struct struc_memSuite *ImageMemory_0x40000000;
struct struc_memSuite *ImageMemory_0x80000000;
struct struc_memSuite *ImageMemory_0x40;
struct struc_memSuite *ImageMemory_0x20;
struct struc_memSuite *ImageMemory_0x10;
struct struc_memSuite *ImageMemory_0x800;
struct struc_memSuite *ImageMemory_0x200_JPEG_M1;
struct struc_memSuite *ImageMemory_0x400_JPEG_M2;
struct struc_memSuite *ImageMemory_0x100;
struct struc_memSuite *ImageMemory_0x10000;
struct struc_memSuite *ImageMemory_0x8000;
struct struc_memSuite *ImageMemory_0x4000;
struct struc_memSuite *ImageMemory_0x1000;
struct struc_memSuite *ImageMemory_0x2000;
struct struc_memSuite *ImageMemory_0x20000000_RAW;
struct struc_memSuite *ImageMemory_0x10000000;
struct struc_memSuite *ImageMemory_0x1000000;
struct struc_memSuite *ImageMemory_0x80000;
struct struc_memSuite *ImageMemory_0x400000;
struct struc_memSuite *ImageMemory_0x100000;
struct struc_memSuite *ImageMemory_0x200000;
int field_F88;
_BYTE gapF8C[140];
int field_1018;
int field_101C;
struct struc_Container *FileContainer;
void *JobClassContainer;
struct struc_memSuite *Mem1Component_0x4000_MEM1;
int field_102C;
int field_1030;
int DonePictType;
int field_1038;
struct struc_memSuite *ImageBuffer;
int HDRCorrectImageBuffer;
int HDRUnderImageBuffer;
int HDROverImageBuffer;
int field_104C;
int field_1050;
int field_1054;
int field_1058;
struct struc_memSuite *ImageMemory_0x2000000;
int field_1060;
int field_1064;
int field_1068;
_BYTE gap106C[116];
int field_10E0;
void *pLuckyTable;
struct struc_LuckyParm LuckyParam;
_BYTE gap1128[16];
int BackupWbOutList;
int BackupLensOutList;
int BackupFnoOutList;
int BackupLongExpNoiseReductionList;
int BackupMultipleExposureSettingList;
};
#pragma pack(pop)
this job is then returned to silent.mo which will start the capturing process using FA_CaptureTestImage
void __cdecl cmd_FA_CaptureTestImage(struct struc_JobClass **hJob)
{
struct struc_JobClass *job; // r4@1
int fa_flag; // [sp+0h] [bp-10h]@1
job = *hJob;
DryosDebugMsg(0x90, 0x16, "FA_CaptureTestImage(hJob:%#lx)", *hJob);
SCS_FaSetSkeltonJob(job);
faGetProperty(PROP_FA_ADJUST_FLAG, &fa_flag, 4u);
fa_flag |= 4u;
faSetProperty(PROP_FA_ADJUST_FLAG, &fa_flag, 4u);
msleep(20);
sht_FA_ReleaseStart();
exec_command_vararg("sht_FA_ReleaseStart");
msleep(20);
sht_FA_ReleaseData();
exec_command_vararg("sht_FA_ReleaseData");
if ( TakeSemaphoreTimeout(FactRC_Semaphore_2, 20000) & 1 )
{
DryosDebugMsg(0x90, 6, "ERROR TakeSemaphore");
}
fa_flag &= 0xFFFFFFFB;
faSetProperty(PROP_FA_ADJUST_FLAG, &fa_flag, 4u);
DryosDebugMsg(0x90, 0x16, "FA_CaptureTestImage Fin");
}
the exposure is started and data is retrieved with
signed int sht_FA_ReleaseStart()
{
return StageClass_Post(ShootCapture->StageClass, ShootCapture, 1, 0, 0);
}
signed int sht_FA_ReleaseData()
{
return StageClass_Post(ShootCapture->StageClass, ShootCapture, 2, 0, 0);
}
FA_ReleaseData is calling the CBR FA_CreateTestImage_cbr() which releases the semaphore FactRC_Semaphore_2.
this CBR was given in FA_CreateTestImage with CreateSkeltonJob(&tv, FA_CreateTestImage_cbr).
the data in the job could imho get read using GetImageBuffer()
void *__fastcall GetImageBuffer(struct struc_JobClass *job)
{
void *result; // r0@2
if ( job->jobs[0].signature == "JobClass" )
{
result = job->jobs[0].job_ref->ImageBuffer;
}
else
{
DryosDebugMsg(0x8F, 6, "GetImageBuffer failed");
result = &byte_7;
}
return result;
}