Read about our upcoming Code of Conduct on this issue

Commit f6fd6f29 authored by Daniel Fort's avatar Daniel Fort
Browse files

Merged unified into update-to-700D.115

--HG--
branch : update-to-700D.115
......@@ -56,10 +56,12 @@ On the 5D there are the following fonts added to the stubs.S file:
0xf00d1110: HCanonGothic 36 px, ascii only (0xFFE2)
0xf00d585c: CanonMonoSpace 40 px, ascii only (0xFFD8)
Alex, 16Mar2011
https://bitbucket.org/hudson/magic-lantern/changeset/cfba492ea84d
Daniel Fort, 05Jul2017
https://bitbucket.org/hudson/magic-lantern/pull-requests/844/find_fntpy-update/diff
"""
......@@ -105,6 +107,17 @@ def parseBitmap(m, off, base):
nb_byte = nb_byte + 1
print ' bitmap size = 0x%x' % ( nb_byte*height )
def guess_load_addr(rom, name):
if rom[4:12] == "gaonisoy":
return 0xFF010000 # assume old DIGIC 4 ROM dumped from 0xFF010000
if "ROM0" in name:
return 0xF0000000 # ROM0 from ML/LOGS/
if "ROM1" in name:
return 0xF8000000 # ROM1 from ML/LOGS/
# unknown, just report the offset inside the ROM.
return 0
f = open(sys.argv[1], 'rb')
m = f.read()
f.close()
......@@ -112,10 +125,11 @@ f.close()
if (len(sys.argv)>2):
base = int(sys.argv[2], 16)
else:
base = 0xff010000
base = guess_load_addr(m, sys.argv[1])
print 'Find bitmap fonts in Canon DSLR firmwares'
print 'Arm.Indy. based on work by Pel, Trammel Hudson and A1ex\n'
print 'Arm.Indy. based on work by Pel, Trammel Hudson and A1ex'
print 'Assume ROM file was dumped from 0x%08x \n' % base
off = 0
while off < len(m) and off <> -1:
......
......@@ -9,6 +9,7 @@ top_dir = "../"
force_used = [
"SetASIFMode",
"_audio_ic_write_bulk",
"AbortEDmac",
]
force_unused = [
"vram_get_number", # old way of accessing VRAM (5D2 only)
......@@ -71,6 +72,7 @@ def cleanup_stub(inp_file, out_file):
lines = open(inp_file).readlines()
if out_file: out_file = open(out_file, "w")
else: out_file = sys.stdout
# for each line
for l in lines:
......@@ -85,17 +87,25 @@ def cleanup_stub(inp_file, out_file):
if not check_used(name):
print "%s: unused" % name
if "???," not in l:
if out_file:
print >> out_file, comment_out(l)
print >> out_file, comment_out(l)
continue
elif name in force_used and l.strip().startswith("///"):
# commented out? uncomment and the address looks valid
addr = m.groups()[1]
addr = addr.replace("RAM_OFFSET", "");
addr = addr.strip(" -");
try:
addr = int(addr, 16)
l = l.lstrip('/ ')
except:
print "%s: invalid address %s" % (name, addr)
if out_file:
print >> out_file, l
print >> out_file, l
if out_file:
if out_file != sys.stdout:
out_file.close()
check_used("FIO_ReadFile")
#check_used("CreateDialogBox")
inputs = sys.argv[1:]
......
MODEL=5D3
FW_VERSION=113
CFLAG_USER += -DCONFIG_5D3_113=1
x: clean_install_fir
......
MODEL=5D3
FW_VERSION=123
CFLAG_USER += -DCONFIG_5D3_123=1
x: clean_install_fir
include ../Makefile.minimal
MODEL=EOSM
include ../Makefile.minimal
......@@ -8,6 +8,39 @@ extern WEAK_FUNC(ret_0) void* edmac_copy_rectangle_adv(void* dst, void* src, int
#define HAS_DMA_MEMCPY ((void*)&dma_memcpy != (void*)&ret_0)
#define HAS_EDMAC_MEMCPY ((void*)&edmac_memcpy != (void*)&ret_0)
static void mem_benchmark_fill(uint32_t * src, uint32_t * dst, int size)
{
for (int i = 0; i < size/4; i++)
{
src[i] = rand();
}
memset(dst, 0, size);
}
static void mem_benchmark_check(void* src, void* dst, int size, int x, int y)
{
sync_caches();
int color_fg = COLOR_WHITE;
char * msg = "OK";
if (memcmp(src, dst, size) != 0)
{
msg = "ERR!";
color_fg = COLOR_RED;
/* save the source and destination buffers, for debugging */
dump_seg(src, size, "ML/LOGS/benchsrc.bin");
dump_seg(dst, size, "ML/LOGS/benchdst.bin");
}
bmp_printf(
FONT(FONT_MONO_20, color_fg, COLOR_BLACK) | FONT_ALIGN_RIGHT,
x, y, msg
);
}
typedef void (*mem_bench_fun)(
int arg0,
int arg1,
......@@ -15,7 +48,7 @@ typedef void (*mem_bench_fun)(
int arg3
);
static void mem_benchmark_run(char* msg, int* y, int bufsize, mem_bench_fun bench_fun, int arg0, int arg1, int arg2, int arg3)
static void mem_benchmark_run(char* msg, int* y, int bufsize, mem_bench_fun bench_fun, int arg0, int arg1, int arg2, int arg3, int is_memcpy)
{
bmp_fill(COLOR_BLACK, 0, 0, 720, font_large.height);
bmp_printf(FONT_LARGE, 0, 0, "%s", msg);
......@@ -41,10 +74,11 @@ static void mem_benchmark_run(char* msg, int* y, int bufsize, mem_bench_fun benc
msleep(500);
display_off();
}
msleep(100);
msleep(200);
int times = 0;
int t0 = get_ms_clock_value();
int t0m = get_ms_clock_value();
int64_t t0 = get_us_clock_value();
for (int i = 0; i < INT_MAX; i++)
{
if (i%2) info_led_off(); else info_led_on();
......@@ -52,19 +86,19 @@ static void mem_benchmark_run(char* msg, int* y, int bufsize, mem_bench_fun benc
bench_fun(arg0, arg1, arg2, arg3);
/* run the benchmark for roughly 1 second */
if (get_ms_clock_value_fast() - t0 > 1000)
if (get_ms_clock_value_fast() - t0m > 1000)
{
times = i + 1;
break;
}
}
int t1 = get_ms_clock_value();
int dt = t1 - t0;
int64_t t1 = get_us_clock_value();
int64_t dt = t1 - t0;
info_led_off();
/* units: KB/s */
int speed = bufsize * times / dt;
int speed = (int64_t) bufsize * times * 1000000ull / dt / 1024;
/* transform in MB/s x100 */
speeds[display] = speed * 100 / 1024;
......@@ -72,13 +106,30 @@ static void mem_benchmark_run(char* msg, int* y, int bufsize, mem_bench_fun benc
if (speeds[0])
{
bmp_printf(FONT_MONO_20, 0, *y += 20, "%s :%4d.%02d MB/s; %4d.%02d MB/s disp off", msg, speeds[1]/100, speeds[1]%100, speeds[0]/100, speeds[0]%100);
bmp_printf(FONT_MONO_20, 0, 100, "Test function: Display on: Display off: ");
bmp_printf(FONT_MONO_20, 0, *y += 20, "%s %4d.%02d MB/s %4d.%02d MB/s ", msg, speeds[1]/100, speeds[1]%100, speeds[0]/100, speeds[0]%100);
}
else
{
bmp_printf(FONT_MONO_20, 0, *y += 20, "%s :%4d.%02d MB/s; (test skipped) ", msg, speeds[1]/100, speeds[1]%100);
bmp_printf(FONT_MONO_20, 0, *y += 20, "%s %4d.%02d MB/s (test skipped) ", msg, speeds[1]/100, speeds[1]%100);
}
msleep(1000);
display_on();
if (is_memcpy)
{
/* perform an extra call, just for checking whether the copying is done correctly */
/* assume memcpy-like syntax: (src, dst, size) */
info_led_on();
bmp_printf(FONT_LARGE, 0, 0, "%s (verifying) ", msg);
bmp_printf(FONT_MONO_20 | FONT_ALIGN_RIGHT, 720, *y, SYM_DOTS);
mem_benchmark_fill((void*)arg1, (void*)arg0, arg2);
bench_fun(arg0, arg1, arg2, arg3);
mem_benchmark_check((void*)arg1, (void*)arg0, arg2, 720, *y);
info_led_off();
}
msleep(200);
}
static void mem_test_bmp_fill(int arg0, int arg1, int arg2, int arg3)
......@@ -156,42 +207,42 @@ static void mem_benchmark_task()
goto cleanup;
}
int y = 80;
int y = 100;
#if 0 // need to hack the source code to run this benchmark
extern int defish_ind;
defish_draw_lv_color();
void defish_draw_lv_color_loop(uint64_t* src_buf, uint64_t* dst_buf, int* ind);
if (defish_ind)
mem_benchmark_run("defish_draw_lv_color", &y, 720*os.y_ex, (mem_bench_fun)defish_draw_lv_color_loop, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), defish_ind, 0);
mem_benchmark_run("defish_draw_lv_color", &y, 720*os.y_ex, (mem_bench_fun)defish_draw_lv_color_loop, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), defish_ind, 0, 0);
#endif
mem_benchmark_run("memcpy cacheable ", &y, bufsize, (mem_bench_fun)memcpy, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("memcpy uncacheable ", &y, bufsize, (mem_bench_fun)memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("memcpy64 cacheable ", &y, bufsize, (mem_bench_fun)memcpy64, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("memcpy64 uncacheable", &y, bufsize, (mem_bench_fun)memcpy64, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("memcpy cacheable ", &y, bufsize, (mem_bench_fun)memcpy, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("memcpy uncacheable ", &y, bufsize, (mem_bench_fun)memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("memcpy64 cacheable ", &y, bufsize, (mem_bench_fun)memcpy64, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("memcpy64 uncacheable", &y, bufsize, (mem_bench_fun)memcpy64, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0, 1);
if (HAS_DMA_MEMCPY)
{
mem_benchmark_run("dma_memcpy cacheable", &y, bufsize, (mem_bench_fun)dma_memcpy, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("dma_memcpy uncacheab", &y, bufsize, (mem_bench_fun)dma_memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("dma_memcpy cacheable", &y, bufsize, (mem_bench_fun)dma_memcpy, (intptr_t)CACHEABLE(buf1), (intptr_t)CACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("dma_memcpy uncacheab", &y, bufsize, (mem_bench_fun)dma_memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0, 1);
}
if (HAS_EDMAC_MEMCPY)
{
mem_benchmark_run("edmac_memcpy ", &y, bufsize, (mem_bench_fun)edmac_memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0);
mem_benchmark_run("edmac_copy_rectangle", &y, 720*480, (mem_bench_fun)mem_test_edmac_copy_rectangle, 0, 0, 0, 0);
mem_benchmark_run("edmac_memcpy ", &y, bufsize, (mem_bench_fun)edmac_memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("edmac_copy_rectangle", &y, 720*480, (mem_bench_fun)mem_test_edmac_copy_rectangle, 0, 0, 0, 0, 0);
}
mem_benchmark_run("memset cacheable ", &y, bufsize, (mem_bench_fun)memset, (intptr_t)CACHEABLE(buf1), 0, bufsize, 0);
mem_benchmark_run("memset uncacheable ", &y, bufsize, (mem_bench_fun)memset, (intptr_t)UNCACHEABLE(buf1), 0, bufsize, 0);
mem_benchmark_run("memset64 cacheable ", &y, bufsize, (mem_bench_fun)memset64, (intptr_t)CACHEABLE(buf1), 0, bufsize, 0);
mem_benchmark_run("memset64 uncacheable", &y, bufsize, (mem_bench_fun)memset64, (intptr_t)UNCACHEABLE(buf1), 0, bufsize, 0);
mem_benchmark_run("read32 cacheable ", &y, bufsize, (mem_bench_fun)mem_test_read32, (intptr_t)CACHEABLE(buf1), bufsize, 0, 0);
mem_benchmark_run("read32 uncacheable ", &y, bufsize, (mem_bench_fun)mem_test_read32, (intptr_t)UNCACHEABLE(buf1), bufsize, 0, 0);
mem_benchmark_run("read64 cacheable ", &y, bufsize, (mem_bench_fun)mem_test_read64, (intptr_t)CACHEABLE(buf1), bufsize, 0, 0);
mem_benchmark_run("read64 uncacheable ", &y, bufsize, (mem_bench_fun)mem_test_read64, (intptr_t)UNCACHEABLE(buf1), bufsize, 0, 0);
mem_benchmark_run("bmp_fill to idle buf", &y, 720*480, (mem_bench_fun)mem_test_bmp_fill, 0, 0, 720, 480);
mem_benchmark_run("memset cacheable ", &y, bufsize, (mem_bench_fun)memset, (intptr_t)CACHEABLE(buf1), 0, bufsize, 0, 0);
mem_benchmark_run("memset uncacheable ", &y, bufsize, (mem_bench_fun)memset, (intptr_t)UNCACHEABLE(buf1), 0, bufsize, 0, 0);
mem_benchmark_run("memset64 cacheable ", &y, bufsize, (mem_bench_fun)memset64, (intptr_t)CACHEABLE(buf1), 0, bufsize, 0, 0);
mem_benchmark_run("memset64 uncacheable", &y, bufsize, (mem_bench_fun)memset64, (intptr_t)UNCACHEABLE(buf1), 0, bufsize, 0, 0);
mem_benchmark_run("read32 cacheable ", &y, bufsize, (mem_bench_fun)mem_test_read32, (intptr_t)CACHEABLE(buf1), bufsize, 0, 0, 0);
mem_benchmark_run("read32 uncacheable ", &y, bufsize, (mem_bench_fun)mem_test_read32, (intptr_t)UNCACHEABLE(buf1), bufsize, 0, 0, 0);
mem_benchmark_run("read64 cacheable ", &y, bufsize, (mem_bench_fun)mem_test_read64, (intptr_t)CACHEABLE(buf1), bufsize, 0, 0, 0);
mem_benchmark_run("read64 uncacheable ", &y, bufsize, (mem_bench_fun)mem_test_read64, (intptr_t)UNCACHEABLE(buf1), bufsize, 0, 0, 0);
mem_benchmark_run("bmp_fill to idle buf", &y, 720*480, (mem_bench_fun)mem_test_bmp_fill, 0, 0, 720, 480, 0);
bmp_fill(COLOR_BLACK, 0, 0, 720, font_large.height);
bmp_printf(FONT_LARGE, 0, 0, "Benchmark complete.");
......
......@@ -7,7 +7,7 @@ CR2HDR_LDFLAGS=-lm -m32
CR2HDR_DEPS=$(SRC_DIR)/chdk-dng.c dcraw-bridge.c exiftool-bridge.c adobedng-bridge.c amaze_demosaic_RT.c dither.c timing.c kelvin.c
HOST=host
EXIFTOOL_VERS=10.33
EXIFTOOL_VERS=10.58
ifdef CROSS
HOSTCC=$(MINGW_GCC)
......
......@@ -53,10 +53,10 @@ static int is_bright[4];
#include "timing.h"
#include "kelvin.h"
#include "../../src/module.h"
#undef MODULE_STRINGS_SECTION
#define MODULE_STRINGS_SECTION
#define MODULE_STRINGS_PREFIX dual_iso_strings
#include "../module_strings_wrapper.h"
#include "module_strings.h"
MODULE_STRINGS()
/** Command-line interface */
......@@ -541,23 +541,6 @@ static void reverse_bytes_order(void* buf, int count)
}
}
const char* module_get_string(int module, const char* name)
{
module_strpair_t *strings = &__module_strings_MODULE_NAME[0];
if (strings)
{
for ( ; strings->name != NULL; strings++)
{
if (!strcmp(strings->name, name))
{
return strings->value;
}
}
}
return 0;
}
static void save_debug_dng(char* filename)
{
int black20 = raw_info.black_level;
......@@ -587,7 +570,7 @@ static int is_file(const char* filename)
int main(int argc, char** argv)
{
printf("cr2hdr: a post processing tool for Dual ISO images\n\n");
printf("Last update: %s\n", module_get_string(0, "Last update"));
printf("Last update: %s\n", module_get_string(dual_iso_strings, "Last update"));
fast_randn_init();
......
# define the module name - make sure name is max 8 characters
MODULE_NAME=edmac
MODULE_OBJS=edmac.o edmac_util.o edmac_test.o md5.o
# include modules environment
include ../Makefile.modules
# fixme: cleaner way to localize symbols?
edmac.sym: edmac.mo
$(call build,STRIP,$(READELF) -sW $< | grep GLOBAL | grep -v UND | grep -v COM | grep -v "__module_.*$(MODULE_NAME)" | $(AWK) "{print \$$8;}" | sort \
| grep -v edmac_format_size > localsyms)
$(call build,STRIP,$(OBJCOPY) edmac.mo edmac.mo --localize-symbols localsyms)
$(call rm_files, localsyms)
$(call build,EXPORTS,$(READELF) -sW $< | grep GLOBAL | grep -v UND | grep -v COM | grep -v "__module_.*$(MODULE_NAME)" | $(AWK) "{print \$$2 \" \" \$$8;}" | sort > $@ && cat $@)
EDmac tools
===========
EDMAC reverse engineering and diagnostic tools.
:Authors: a1ex, g3gg0
:License: GPL
:Summary: EDMAC reverse engineering and diagnostic tools.
#include <module.h>
#include <dryos.h>
#include <property.h>
#include <bmp.h>
#include <menu.h>
#include <console.h>
#include <shoot.h>
#include <beep.h>
#include <edmac.h>
#include <timer.h>
#include <asm.h>
extern WEAK_FUNC(ret_0) char * asm_guess_func_name_from_string(uint32_t func_addr);
static int edmac_selection;
static void edmac_display_page(int i0, int x0, int y0)
{
bmp_printf(
FONT_MONO_20,
x0, y0,
"EDM# Address Size\n"
);
y0 += fontspec_font(FONT_MONO_20)->height * 2;
for (int i = 0; i < 16; i++)
{
char msg[100];
int ch = i0 + i;
uint32_t addr = edmac_get_address(ch);
int state = edmac_get_state(ch);
struct edmac_info info = edmac_get_info(ch);
char * sz = edmac_format_size(&info);
if (strlen(sz) <= 10)
{
snprintf(msg, sizeof(msg), "[%2d] %8x: %s", ch, addr, sz);
}
else
{
snprintf(msg, sizeof(msg), "[%2d] %8x: %d", ch, addr, edmac_get_total_size(&info, 0));
}
if (state != 0 && state != 1)
{
STR_APPEND(msg, " (%x)", state);
}
uint32_t dir = edmac_get_dir(ch);
uint32_t conn_w = edmac_get_connection(ch, EDMAC_DIR_WRITE);
uint32_t conn_r = edmac_get_connection(ch, EDMAC_DIR_READ);
int color =
dir == EDMAC_DIR_UNUSED ? COLOR_GRAY(20) : /* unused? */
state == 0 ? COLOR_GRAY(50) : /* inactive? */
state == 1 ? COLOR_GREEN1 : /* active? */
COLOR_RED ; /* no idea */
if (dir == EDMAC_DIR_WRITE)
{
if (conn_w == 0)
{
/* Write EDMAC, but could not figure out where it's connected */
/* May be either unused, or connected to 0 (RAW data) */
STR_APPEND(msg, " <w!>");
}
else
{
STR_APPEND(msg, " <w%x>", conn_w);
}
}
else if (dir == EDMAC_DIR_READ)
{
if (conn_r == 0xFF)
{
/* Read EDMAC, but could not figure out where it's connected */
STR_APPEND(msg, " <r!>");
}
else
{
STR_APPEND(msg, " <r%x>", conn_r);
}
}
if (dir != EDMAC_DIR_UNUSED && strchr(msg, '!'))
{
color = COLOR_YELLOW;
}
bmp_printf(
FONT(FONT_MONO_20, color, COLOR_BLACK),
x0, y0 + i * fontspec_font(FONT_MONO_20)->height,
msg
);
}
}
static void edmac_display_detailed(int channel)
{
uint32_t base = edmac_get_base(channel);
int x = 50;
int y = 50;
bmp_printf(
FONT_LARGE,
x, y,
"EDMAC #%d - %x\n",
channel,
base
);
y += font_large.height;
/* http://magiclantern.wikia.com/wiki/Register_Map#EDMAC */
uint32_t dir = edmac_get_dir(channel);
char* dir_s =
dir == EDMAC_DIR_READ ? "read" :
dir == EDMAC_DIR_WRITE ? "write" :
"unused";
if (dir == EDMAC_DIR_UNUSED)
{
/* attempting to get info from unused channels may crash on old models */
/* if it doesn't crash, the additional info doesn't make any sense */
bmp_printf(FONT_MONO_20, 50, y + font_large.height, "Unused");
return;
}
uint32_t state = edmac_get_state(channel);
uint32_t flags = edmac_get_flags(channel);
uint32_t addr = edmac_get_address(channel);
char flags_desc[32] = "";
if (flags)
{
snprintf(flags_desc, sizeof(flags_desc),
"(%d bytes per transfer)",
edmac_bytes_per_transfer(flags)
);
}
union edmac_size_t
{
struct { short x, y; } size;
uint32_t raw;
};
union edmac_size_t size_n = (union edmac_size_t) shamem_read(base + 0x0C);
union edmac_size_t size_b = (union edmac_size_t) shamem_read(base + 0x10);
union edmac_size_t size_a = (union edmac_size_t) shamem_read(base + 0x14);
uint32_t off1b = shamem_read(base + 0x18);
uint32_t off2b = shamem_read(base + 0x1C);
uint32_t off1a = shamem_read(base + 0x20);
uint32_t off2a = shamem_read(base + 0x24);
uint32_t off3 = shamem_read(base + 0x28);
uint32_t off40 = shamem_read(base + 0x40);
uint32_t conn_w = edmac_get_connection(channel, EDMAC_DIR_WRITE);
uint32_t conn_r = edmac_get_connection(channel, EDMAC_DIR_READ);
struct edmac_info info = edmac_get_info(channel);
int fh = fontspec_font(FONT_MONO_20)->height;
bmp_printf(FONT_MONO_20, 50, y += fh, "Address : %8x ", addr);
bmp_printf(FONT_MONO_20, 50, y += fh, "State : %8x ", state);
bmp_printf(FONT_MONO_20, 50, y += fh, "Flags : %8x %s", flags, flags_desc);
bmp_printf(FONT_MONO_20, 50, y += fh, "Size : %s ", edmac_format_size(&info));
y += fh;
bmp_printf(FONT_MONO_20, 50, y += fh, "Size A : %8x (%d x %d) ", size_a.raw, size_a.size.x, size_a.size.y);
bmp_printf(FONT_MONO_20, 50, y += fh, "Size B : %8x (%d x %d) ", size_b.raw, size_b.size.x, size_b.size.y);
bmp_printf(FONT_MONO_20, 50, y += fh, "Size N : %8x (%d x %d) ", size_n.raw, size_n.size.x, size_n.size.y);
bmp_printf(FONT_MONO_20, 50, y += fh, "off1a : %8x ", off1a);
bmp_printf(FONT_MONO_20, 50, y += fh, "off1b : %8x ", off1b);
bmp_printf(FONT_MONO_20, 50, y += fh, "off2a : %8x ", off2a);
bmp_printf(FONT_MONO_20, 50, y += fh, "off2b : %8x ", off2b);
bmp_printf(FONT_MONO_20, 50, y += fh, "off3 : %8x ", off3);
bmp_printf(FONT_MONO_20, 50, y += fh, "off40 : %8x ", off40);
y += fh;
bmp_printf(FONT_MONO_20, 50, y += fh, "Connection : write=0x%x read=0x%x dir=%s", conn_w, conn_r, dir_s);
if (is_camera("5D3", "*"))
{
/**
* ConnectReadEDmac(channel, conn)
* RAM:edmac_register_interrupt(channel, cbr_handler, ...)
* => *(8 + 32*arg0 + *0x12400) = arg1
* and also: *(12 + 32*arg0 + *0x12400) = arg1
*/
uint32_t cbr1 = MEM(8 + 32*(channel) + MEM(0x12400));
uint32_t cbr2 = MEM(12 + 32*(channel) + MEM(0x12400));
bmp_printf(FONT_MONO_20, 50, y += fh, "CBR handler: %8x %s", cbr1, asm_guess_func_name_from_string(cbr1));
bmp_printf(FONT_MONO_20, 50, y += fh, "CBR abort : %8x %s", cbr2, asm_guess_func_name_from_string(cbr2));
}
}
static MENU_UPDATE_FUNC(edmac_display)
{
if (!info->can_custom_draw) return;
info->custom_drawing = CUSTOM_DRAW_THIS_MENU;
bmp_fill(COLOR_BLACK, 0, 0, 720, 480);
if (edmac_selection == 0 || edmac_selection == 1) // overview
{
if (edmac_selection == 0)
{
edmac_display_page(0, 0, 30);
edmac_display_page(16, 360, 30);
}