/* RT-4D custom UI layer (Phase 1: custom standby/home screen). * Compiled with clang --target=thumbv7em, linked at 0x08029000, injected over * the russified stock image. Calls stock SDK functions by absolute address. * Reads only RAM caches + calls display/ADC primitives -> codeplug & CPS untouched. */ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; /* --- stock SDK (thumb entry = addr|1) --- */ #define DRAW_STRING ((void (*)(u8 pg, u8 x, const void *s, u16 n, u8 mode))0x08008A51) #define STOCK_DRAW ((void (*)(void))0x0801E1BD) /* ui_draw_dispatch */ /* --- RAM state --- */ #define GSCR (*(volatile u8 *)0x200008B3) /* current screen id */ #define GDISP ((volatile u8 *)0x200009C3) /* home display struct */ /* draw one full-width (18-char) space-padded line from a source field. * Full-coverage fixed-width paint => no clear needed, no flicker. */ static void line_field(u8 pg, const volatile u8 *src, int n) { char b[18]; int i; for (i = 0; i < 18; i++) { u8 c = (i < n) ? src[i] : 0x20; if (c == 0 || c == 0xFF) c = 0x20; /* pad -> space */ b[i] = (char)c; } DRAW_STRING(pg, 0, b, 18, 0); } static void my_home(void) { line_field(0, GDISP + 0x00, 16); /* line 0: name / mode tag */ line_field(2, GDISP + 0x20, 16); /* line 1: Area A freq/chan */ line_field(4, GDISP + 0x32, 16); /* line 2: Area B */ line_field(6, GDISP + 0x15, 7); /* line 3: CH-/A-/D- prefix */ } /* hooked in at the ui_tick_normal draw dispatch (bl @0x080207E6). */ void my_draw_router(void) { if (GSCR == 0) my_home(); /* our custom home screen */ else STOCK_DRAW(); /* stock draws all other screens */ }