I've looked at this some more.
I'm confident that
3c6afc2: 7878 ldrb r0, [r7, #1]
corresponds to
val = img[y + x + 1]
Furthermore, from the ROMLOG, we see
R6 0xB2D6FE98
R7 0xB2D6FE98
In other words, the bogus pointer also appears in R6.
Based on
3c6ae46: 4bc2 ldr r3, [pc, #776] ; (3c6b150 <md_detect_motion+0x350>) ; vid_get_viewport_live_fb
3c6ae48: f000 fa59 bl 3c6b2fe <action_stack_AS_MOTION_DETECTOR+0xc2> ; long call
3c6ae4c: 1e04 subs r4, r0, #0
3c6ae4e: d103 bne.n 3c6ae58 <md_detect_motion+0x58>
3c6ae50: 4bc0 ldr r3, [pc, #768] ; (3c6b154 <md_detect_motion+0x354>) ; vid_get_viewport_fb
3c6ae52: f000 fa54 bl 3c6b2fe <action_stack_AS_MOTION_DETECTOR+0xc2> ; long call
3c6ae56: 1c04 adds r4, r0, #0
3c6ae58: 4bbf ldr r3, [pc, #764] ; (3c6b158 <md_detect_motion+0x358>) ; vid_get_viewport_image_offset
3c6ae5a: f000 fa50 bl 3c6b2fe <action_stack_AS_MOTION_DETECTOR+0xc2> ; long call
3c6ae5e: 4bbf ldr r3, [pc, #764] ; (3c6b15c <md_detect_motion+0x35c>) ; vid_get_viewport_height
3c6ae60: 1826 adds r6, r4, r0
R6 is vid_get_viewport_live_fb() + vid_get_viewport_image_offset(). The fact that R7 has the same value suggests the crash happened in the first iteration of the loop (in this particular call to md_detect_motion.)
vid_get_viewport_live_fb is exonerated
return viewport_buffers[(active_viewport_buffer-1)&3];
viewport_buffers
ROM:FFB2F90C DCD 0x40566B80
ROM:FFB2F910 DCD 0x405A6000
ROM:FFB2F914 DCD 0x405E5480
ROM:FFB2F918 DCD 0x40624900
vid_get_viewport_image_offset is
int vid_get_viewport_image_offset() {
return (vid_get_viewport_yoffset() * vid_get_viewport_byte_width() * vid_get_viewport_yscale()) + (vid_get_viewport_xoffset() * 3);
}
Of these, vid_get_viewport_byte_width and vid_get_viewport_yscale are simple constants.
vid_get_viewport_yoffset and vid_get_viewport_xoffset are both rather nonsensical lookups based on shooting_get_prop(PROPCASE_ASPECT_RATIO)
int vid_get_viewport_xoffset()
{
// viewport width offset table for each image size
// 0 = 4:3, 1 = 16:9, 2 = 3:2, 3 = 1:1
static long vp_w[4] = { 0, 0, 0, 0 }; // should all be even values for edge overlay
return vp_w[shooting_get_prop(PROPCASE_ASPECT_RATIO)];
}
int vid_get_viewport_yoffset()
{
// viewport height offset table for each image size
// 0 = 4:3, 1 = 16:9, 2 = 3:2, 3 = 1:1
static long vp_h[4] = { 0, 0, 0, 0 };
return vp_h[shooting_get_prop(PROPCASE_ASPECT_RATIO)];
}
However, these should be harmless unless the PROPCASE_ASPECT_RATIO value is out of range.
A3400 is defined as a propset 5 cameras, which makes PROPCASE_ASPECT_RATIO 300
This leads to two things that can be tested by someone who has this camera:
1) what is the value of propcase 300 on this camera? In CHDK menu, go to miscellaneous -> debug parameters, set debug data display to props, set Propcase page to 30. Try changing aspect ratios (if available), look at it in REC mode while halfshooting, shooting, and running the MD script.
2) Replace all the nonsense lookups with just a return <value>, or if this camera does in fact have variable aspect ratios that affect the viewport, put in the correct values.
Other possibilities:
1) my analysis above is wrong.
2) There is memory corruption happening somewhere else.