Eos 400d ( Rebel XTI ) - page 169 - DSLR Hack development - CHDK Forum

Eos 400d ( Rebel XTI )

  • 1871 Replies
  • 891278 Views
VRAM
« Reply #1680 on: 28 / March / 2013, 06:27:45 »
Advertisements
  I finally got hook in function which seems like updates GUI. But overlay still flickers. I think it has something to do with "GUIBlinkTimer".
Code: [Select]
int UpdateGUI (int r0, int r1, int r2, int r3, int a, int b, int c, int d)
{      int aa = sub_FF92D950 (r0, r1, r2, r3, a, b, c, d);  // looks like this function get called everytime GUI updates
UnSuspendTask(hVramModTask);
return aa;
}

(*(int*)0x51C0)= (int)&UpdateGUI;  // goes in main.c at initialization

Code: [Select]
void VramModTask(void)
{ char str[25];
while (1)
{ if(GUIMode==OLC_MODE && dpr_data.wb==8)
{ sprintf(str,"%d",dpr_data.color_temp);
bmp_printf(50, 134, str, COLOR_BLACK, COLOR_GRAY_2);
}
SuspendTask(hVramModTask);
}
}

void bmp_printf(int ofset_x, int ofset_y, char *str, int fg_color, int bg_color)
{ int x, y, pixel, pixels;
char c;
if(TakeVramSemaphore(VramInstance_address))return;
while( (c = *str++) )
{ for( y=0 ; y<font_small.height ; y++ )
{ pixels = font_small.bitmap[ c + (y << 7) ];
for( x=0 ; x<font_small.width; x++ )
{ vram.pixel[y+ofset_y][x+ofset_x] = (pixels & 0x8000) ? fg_color : bg_color;
pixels <<=1;
}
}
ofset_x += font_small.width;
}
GiveVramSemaphore(VramInstance_address);
}

VRAM
« Reply #1681 on: 28 / March / 2013, 06:28:09 »
  I finally got hook in function which seems like updates GUI. But overlay still flickers. I think it has something to do with "GUIBlinkTimer".
Code: [Select]
int UpdateGUI (int r0, int r1, int r2, int r3, int a, int b, int c, int d)
{      int aa = sub_FF92D950 (r0, r1, r2, r3, a, b, c, d);  // looks like this function get called everytime GUI updates
UnSuspendTask(hVramModTask);
return aa;
}

(*(int*)0x51C0)= (int)&UpdateGUI;  // goes in main.c at initialization
........

Looks interesting, when looking around the address of this CallBackRoutine (CBR), it looks like it is related to WindowInstance stuff... may be this means that it is called only when there are "windows" on the screen...

Another interesting thing is that on the next few addresses, there are stuff related to:
eventproc_TransferNormalScreen()
I think this eventproc is the one that transfers the FrameBuffer to the real LCD screen.
Everything is drawn in a framebuffer and i guess it's double buffered (i.e. there are 2 frame buffers)
then when the frame buffer is changed this routine will draw the original lcd.

IIRC all eventproc routines are registered in table, and there were register_eventproc() or something...
this way, we can replace the original eventproc with ours... and if I'm right on this, this routine should be used to refresh the screen, hence we can use this to stop flickering...

I'm only guessing here, I have no chance to test it ATM.



this is what i see in RAM, right next after some VRAM buffer (frame buffer)

RAM:0023D008     off_23D008:     .long off_227DFC        @ DATA XREF: RAM:00227E00o
RAM:0023D008                                             @ RAM:off_23D01Co
RAM:0023D00C                     .long off_23D01C
RAM:0023D010                     .long sub_14
RAM:0023D014                     .align 8
RAM:0023D018                     .long eventproc_TransferNormalScreen
RAM:0023D01C     off_23D01C:     .long off_23D008        @ DATA XREF: RAM:0023D00Co
RAM:0023D01C                                             @ RAM:off_23D048o
RAM:0023D020                     .long off_23D048
RAM:0023D024                     .long dword_2C
RAM:0023D028                     .byte    0
RAM:0023D029                     .byte    0
RAM:0023D02A                     .byte    0
RAM:0023D02B                     .byte    0
RAM:0023D02C                     .byte 0x14
RAM:0023D02D                     .byte 0xD0 @ -
RAM:0023D02E                     .byte 0x23 @ #
RAM:0023D02F                     .byte    0
RAM:0023D030     aTransferNormalScreen:.ascii "TransferNormalScreen"



and this is the ROM where it gets registered:

FW:FF934EB4 028                 LDR     R0, =aTransfernormal @ "TransferNormalScreen"
FW:FF934EB8 028                 STR     R2, [LR]        @ Store to Memory
FW:FF934EBC 028                 LDR     R1, =eventproc_TransferNormalScreen @ Load from Memory
FW:FF934EC0 028                 STR     R6, [R4]        @ Store to Memory
FW:FF934EC4 028                 STR     R6, [R5]        @ Store to Memory
FW:FF934EC8 028                 BL      RegisterEventProcedure @ Branch with Link


i'm not 100% sure, but i think at 0x00005448 in RAM starts the eventproc table
format is simple:
struct {
    int * pointer_to_routine;
    char * pointer_to_string;
}

RAM:00005448                     .long eventproc_about
RAM:0000544C                     .long aabout            @ "about"
RAM:00005450                     .long eventproc_about
RAM:00005454                     .long aGetSystemInfo    @ "GetSystemInfo"
RAM:00005458                     .long eventproc_GetSystemInfo
RAM:0000545C                     .long aPrintModelName   @ "PrintModelName"



Unfortunately i do not find the eventproc_TransferNormalScreen()
it seems this list is only registering the eventproc's available for the shell (console) of the camera, and transfernormalscreen is not one of them. Anyway, it is registered right after one of the VRAM's (see above)


These are just few random thoughts that crossed my mind, hope it helps.


VRAM
« Reply #1682 on: 28 / March / 2013, 06:28:26 »
Another interesting thing is that on the next few addresses, there are stuff related to:
eventproc_TransferNormalScreen()
I think this eventproc is the one that transfers the FrameBuffer to the real LCD screen.
Everything is drawn in a framebuffer and i guess it's double buffered (i.e. there are 2 frame buffers)
then when the frame buffer is changed this routine will draw the original lcd.

  eventproc_TransferNormalScreen() calls sub_FF92D950 or "WindowInstance" at the end. ( MOV     PC, R7)
I'm sill trying to find how "vram2" get copied to vram.
#define vram (*(vram_t*)(*(int*)0x19638))
#define vram2 (*(vram_t*)(*(int*)(*(int*)(*(int*)(0x5190)+0x10))))

Maybe i'm wrong about vram2 and it never copies to vram. I know it doesn't respond to any changes, but many routines are using it.

VRAM
« Reply #1683 on: 28 / March / 2013, 06:28:42 »
Another interesting thing is that on the next few addresses, there are stuff related to:
eventproc_TransferNormalScreen()
I think this eventproc is the one that transfers the FrameBuffer to the real LCD screen.
Everything is drawn in a framebuffer and i guess it's double buffered (i.e. there are 2 frame buffers)
then when the frame buffer is changed this routine will draw the original lcd.
  0xAF, looks like eventproc_Transfer_XXXXX_Screen() functions sets (*(int*)0x51C0) to a pointer to a function which transfers vram according to its name.
I have tried pointer from "eventproc_TransferRotateScreen" and screen flipped up side down.  :lol
  Here is some pointers for 0x51C0:
0xFF92D950 -  eventproc_TransferNormalScreen
0xFF92E12C - eventproc_TransferUpsideDownScreen
0xFF92E294 - eventproc_TransferMirrorScreen
0xFF92DCFC - eventproc_TransferRotateScreen  //Probably good macro when camera is up side down under tripod

I guess if we decompile routine at 0xFF92D950, we could understand how vram is copied.


VRAM
« Reply #1684 on: 28 / March / 2013, 06:29:01 »
  I finally got hook in function which seems like updates GUI. But overlay still flickers. I think it has something to do with "GUIBlinkTimer".
Code: [Select]
int UpdateGUI (int r0, int r1, int r2, int r3, int a, int b, int c, int d)
{      int aa = sub_FF92D950 (r0, r1, r2, r3, a, b, c, d);  // looks like this function get called everytime GUI updates
UnSuspendTask(hVramModTask);
return aa;
}

(*(int*)0x51C0)= (int)&UpdateGUI;  // goes in main.c at initialization

Code: [Select]
void VramModTask(void)
{ char str[25];
while (1)
{ if(GUIMode==OLC_MODE && dpr_data.wb==8)
{ sprintf(str,"%d",dpr_data.color_temp);
bmp_printf(50, 134, str, COLOR_BLACK, COLOR_GRAY_2);
}
SuspendTask(hVramModTask);
}
}

void bmp_printf(int ofset_x, int ofset_y, char *str, int fg_color, int bg_color)
{ int x, y, pixel, pixels;
char c;
if(TakeVramSemaphore(VramInstance_address))return;
while( (c = *str++) )
{ for( y=0 ; y<font_small.height ; y++ )
{ pixels = font_small.bitmap[ c + (y << 7) ];
for( x=0 ; x<font_small.width; x++ )
{ vram.pixel[y+ofset_y][x+ofset_x] = (pixels & 0x8000) ? fg_color : bg_color;
pixels <<=1;
}
}
ofset_x += font_small.width;
}
GiveVramSemaphore(VramInstance_address);
}

Yes, it still flickers, but it is totally acceptable now...
Great job, I just committed a change that incorporates this code; many thanks!

VRAM
« Reply #1685 on: 28 / March / 2013, 06:29:17 »
  0xAF, looks like eventproc_Transfer_XXXXX_Screen() functions sets (*(int*)0x51C0) to a pointer to a function which transfers vram according to its name.
I have tried pointer from "eventproc_TransferRotateScreen" and screen flipped up side down.  :lol
  Here is some pointers for 0x51C0:
0xFF92D950 -  eventproc_TransferNormalScreen
0xFF92E12C - eventproc_TransferUpsideDownScreen
0xFF92E294 - eventproc_TransferMirrorScreen
0xFF92DCFC - eventproc_TransferRotateScreen  //Probably good macro when camera is up side down under tripod

I guess if we decompile routine at 0xFF92D950, we could understand how vram is copied.


Yes, flipping down the display can be very interesting for macro; good!

Edu.

VRAM
« Reply #1686 on: 28 / March / 2013, 06:30:07 »
  0xAF, looks like eventproc_Transfer_XXXXX_Screen() functions sets (*(int*)0x51C0) to a pointer to a function which transfers vram according to its name.
I have tried pointer from "eventproc_TransferRotateScreen" and screen flipped up side down.  :lol

I might misunderstood something, are these Transfer functions set the pointer on every call ?
If so then we must replace the pointer on every call of Transfer function... the cache hacks can do this easily i think.
If not, then we are safe to put our function in this pointer and do what i've talked in previous message...

VRAM
« Reply #1687 on: 28 / March / 2013, 06:30:32 »
  0xAF, looks like eventproc_Transfer_XXXXX_Screen() functions sets (*(int*)0x51C0) to a pointer to a function which transfers vram according to its name.
I have tried pointer from "eventproc_TransferRotateScreen" and screen flipped up side down.  :lol
  Here is some pointers for 0x51C0:
0xFF92D950 -  eventproc_TransferNormalScreen
0xFF92E12C - eventproc_TransferUpsideDownScreen
0xFF92E294 - eventproc_TransferMirrorScreen
0xFF92DCFC - eventproc_TransferRotateScreen  //Probably good macro when camera is up side down under tripod

I guess if we decompile routine at 0xFF92D950, we could understand how vram is copied.


Yeah, I've been playing with these functions back in the time.
These are the real transfer functions to the VRAM and i've been looking at their source back then.
Buy didn't look too deep, to understand it fully.
Anyway, I think the copying is not so important, it will be just a copy of the frame buffer to the MMIO address of the real display (or something similar).
Even if we understand how it's copied, it's not so interesring IMO.
It is more important to replace the function that copy the framebuffer to vram, since this way, we can block the real coping, without blocking the TASKs (like with the semaphore).

Or to be more correct, we should not block the display refreshes at all... instead we should do the following:
If we are able to replace the Transfer function with ours, when someone calls this function (we do not care who and why calls it), we just put our stuff to the VRAM and then call the real transfer function. This way our drawn content will be always there and no flickering should be visible.

This will work only if there is no other methods to transfer the FB to VRAM (at least the OFW should not call other functions to transfer)


Let me see if I understood correctly:

* Those functions transfer the contents of certain memory address to the real display.
* We can easily replace which function makes the transfer.

Could we replace one of these functions, and force the firmware to use one of ours? In that case, perhaps we could change "TransferNormalScreen" to something that does "display_overlay + TransferNormalScreen", and that would eliminate all flickering, no? I'll give it a try tonight.

Besides, if we knew how the transfer is made, perhaps we could try other tricks, like inverse all colors for a night-mode display...

VRAM
« Reply #1688 on: 28 / March / 2013, 06:30:52 »

Let me see if I understood correctly:

* Those functions transfer the contents of certain memory address to the real display.
* We can easily replace which function makes the transfer.

Could we replace one of these functions, and force the firmware to use one of ours? In that case, perhaps we could change "TransferNormalScreen" to something that does "display_overlay + TransferNormalScreen", and that would eliminate all flickering, no? I'll give it a try tonight.

Besides, if we knew how the transfer is made, perhaps we could try other tricks, like inverse all colors for a night-mode display...

Basically yes.
But on the second though, if the Transfer functions set the pointer each time they are called (i guess they will), we should patch these functions to set our function in this pointer and not their function. This will be easily achieved with cache hacks ... I will find time very soon to try cache-hacks on 400d.


VRAM
« Reply #1689 on: 28 / March / 2013, 06:32:34 »
eventproc_TransferNormalScreen sets the pointer 0x51C0 to 0xFF92D950 function. Edu sets this pointer to my_UpdateGUI() which calls 0xFF92D950 or "UpdateGUI()" and enqueue_action(display_overlay) .
   Something sets the pointer one time at boot and every GUI window uses it to update vram. I could be wrong, but window instance has section of RAM which looks like a copy of vram. I think the function in 0x51C0 updates it and then copies it to vram. My idea was to find which subroutine does the copy. Maybe BlinkTimer uses it to write to vram.

 

Related Topics


SimplePortal © 2008-2014, SimplePortal