Author Topic: FRSP related infos  (Read 4774 times)

g3gg0

  • Developer
  • Hero Member
  • *****
  • Posts: 3166
FRSP related infos
« on: January 22, 2015, 10:55:35 PM »
some reverse engineering notes.

for FRSP we call first  FA_CreateTestImage  to get a prepared image job.

Code: [Select]
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

Code: [Select]
#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

Code: [Select]
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:

Code: [Select]
#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

Code: [Select]
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
Code: [Select]
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()

Code: [Select]
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;
}


Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: paypal@g3gg0.de
ONLY donate for things we have done, not for things you expect!

DeafEyeJedi

  • Hero Member
  • *****
  • Posts: 3401
  • 5D3 | M1 | 7D | 70D | SL1 | M2 | 50D
Re: FRSP related infos
« Reply #1 on: January 23, 2015, 12:07:07 AM »
Interesting notes -- question is this possible to copy and compile into the Silent.mo for 5D 1.1.3 to get the same FRSP version that you just implemented for 7D 2.0.3 last week?

I'm asking because the latest FRSP on 7D 2.0.3 has been kicking ass so far... Can't wait to do the same for 5D3!

Thanks again @g3gg0!
5D3.113 | 5D3.123 | EOSM.203 | 7D.203 | 70D.112 | 100D.101 | EOSM2.* | 50D.109

g3gg0

  • Developer
  • Hero Member
  • *****
  • Posts: 3166
Re: FRSP related infos
« Reply #2 on: January 23, 2015, 12:20:50 AM »
a) its not the correct thread for that and b) whats wrong with FRSP for 5D3? it works fine here.
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: paypal@g3gg0.de
ONLY donate for things we have done, not for things you expect!

DeafEyeJedi

  • Hero Member
  • *****
  • Posts: 3401
  • 5D3 | M1 | 7D | 70D | SL1 | M2 | 50D
Re: FRSP related infos
« Reply #3 on: January 23, 2015, 05:21:05 AM »
My apologies -- You're right it's not in the correct thread so I instead sent you a PM regarding 5D3 FRSP.

Thanks!
5D3.113 | 5D3.123 | EOSM.203 | 7D.203 | 70D.112 | 100D.101 | EOSM2.* | 50D.109