Gintracer v0.6.4 - Color schematics

@update
* support multiple color schematics (night, day, ...).
* wrappe gint display API.
* disasm: [VARS] will skip the callgraph generation until the next breakpoint is reached.
* add some notes information
* add some syscall information

@fix
* tabulation and space display
This commit is contained in:
Yatis 2021-03-08 13:54:10 +01:00
parent b4d3db625e
commit 19e46a55f0
14 changed files with 352 additions and 80 deletions

View File

@ -1,13 +1,14 @@
@fix
* fix fixed size 'space' character
* fix tabulation
* fix destructor
* fix fx9860 support
@update
* hexdump: search commands
* savefile
* load saved file
* list color scheme on SMEM.
* icon
@feature
* night mode (refacto gui and handle color template)
* transform gintracer into a librairy
* handle session (send the session instead of ucontext !)

Binary file not shown.

View File

@ -17,4 +17,33 @@
#define GUI_DISP_NB_COLUMN (DWIDTH / (FWIDTH + 1))
#define GUI_DISP_NB_ROW (DHEIGHT / (FHEIGHT + 1))
/* color scheme definition */
struct colorscheme {
uint16_t background;
uint16_t font;
uint16_t note;
uint16_t line;
};
/* gcolor_scheme_change(): Change the color scheme */
extern void gcolor_scheme_change(void);
/* gclear(): Clear the VRAM and set the appropriate background color */
extern void gclear(void);
/* gupdate(): Display the VRAM to the screen */
extern void gupdate(void);
/* gtextXY(): Display plain text */
extern void gtextXY(int x, int y, const char *text);
/* gprintXY(): Display printf-format text */
extern void gprintXY(int x, int y, const char *format, ...);
/* gprintXY(): Display note */
extern void gnoteXY(int x, int y, const char *note);
/* ghreverse(): Reverse pixels color on a horizontal area */
extern void ghreverse(int ypos, size_t size);
/* ghline(): Display horizontal line */
extern void ghline(int ypos);
#endif /*__GINTRACE_GUI_DISPLAY_H__*/

View File

@ -47,6 +47,7 @@ struct tracer {
uint16_t *memory;
uintptr_t next_break;
uintptr_t next_instruction;
int skip;
};
/* extern menu information */

244
src/gui/display.c Normal file
View File

@ -0,0 +1,244 @@
#include "gintrace/gui/display.h"
#include <gint/display.h>
#include <gint/std/stdio.h>
/* define all color scheme */
struct colorscheme night = {
.background = 0x4aec,
.font = 0xffff,
.note = 0x5ab0,
.line = 0xffff
};
struct colorscheme days = {
.background = 0x0000,
.font = 0xffff,
.note = 0xf100,
.line = 0xffff
};
struct colorscheme days2 = {
.background = 0xffff,
.font = 0x0000,
.note = 0xb900,
.line = 0x0000
};
struct colorscheme *color_scheme = &days2;
struct colorscheme *color_scheme_list[] = { &night, &days, &days2, NULL };
//---
// Color
//---
/* gcolor_scheme_change(): Change the color scheme */
void gcolor_scheme_change(void)
{
static int counter = 0;
counter = counter + 1;
if (color_scheme_list[counter] == NULL)
counter = 0;
color_scheme = color_scheme_list[counter];
}
//---
// Drawing wrapper
//---
/* gclear(): Clear the VRAM and set the appropriate background color */
void gclear(void)
{
dclear(color_scheme->background);
}
/* gupdate(): Display the VRAM to the screen */
void gupdate(void)
{
dupdate();
}
/* ghreverse(): Reverse pixels color on a horizontal area */
void ghreverse(int ypos, size_t size)
{
#ifdef FXCG50
/* FIXME: border !!! */
uint32_t *long_vram;
int y1;
int y2;
y1 = ypos;
y2 = ypos + size;
long_vram = (void *)gint_vram;
for(int i = 198 * y1; i < 198 * y2; i++)
long_vram[i] = ~long_vram[i];
#endif
}
/* ghline(): Display horizontal line */
void ghline(int ypos)
{
dhline(ypos, color_scheme->line);
}
/* gprintXY(): Display printf-format text */
void gprintXY(int x, int y, const char *format, ...)
{
char str[512];
va_list args;
va_start(args, format);
vsnprintf(str, 512, format, args);
va_end(args);
gtextXY(x, y, str);
}
/* gprintXY(): Display note */
void gnoteXY(int x, int y, const char *note)
{
drect(0, y * (FHEIGHT + 1) - 1,
DWIDTH, (y + 1) * (FHEIGHT + 1) - 1,
color_scheme->note);
uint16_t bg = color_scheme->background;
uint16_t fg = color_scheme->font;
color_scheme->background = color_scheme->note;
color_scheme->font = 0xffff;
gtextXY(x, y, note);
color_scheme->background = bg;
color_scheme->font = fg;
}
//---
// Text engine
//---
struct textinfo {
struct {
uint16_t bg;
uint16_t fg;
} color;
struct {
int x;
int y;
} cursor;
const char *text;
int counter;
};
/* gtext_line_discipline(): Check special char */
static int gtext_line_discipline(struct textinfo *info)
{
int offset;
switch (info->text[0]) {
case ' ':
info->cursor.x = info->cursor.x + 1;
return (1);
case '\n':
info->cursor.x = 0;
info->cursor.y = info->cursor.y + 1;
return (1);
case '\b':
info->cursor.x = info->cursor.x - 1;
return (1);
case '\v':
info->cursor.y = info->cursor.y - 1;
return (1);
case '\r':
info->cursor.x = 0;
return (1);
case '\t':
offset = 5 - (info->counter - ((info->counter / 5) * 5));
info->cursor.x = info->cursor.x + offset;
return (1);
default:
return (0);
}
}
/* gtext_echapement(): Check echapement char */
static int gtext_echapement(struct textinfo *info)
{
struct {
int id;
uint16_t color;
} color_table[] = {
{.id = 30, .color = 0x001f},
{.id = 31, .color = 0x07e0},
{.id = 32, .color = 0xf800},
{.id = 33, .color = 0x0000},
{.id = 34, .color = 0x0000},
{.id = 35, .color = 0x0000},
{.id = 36, .color = 0x0000},
{.id = 37, .color = 0x0000},
};
if (info->text[0] != '\\'
|| info->text[1] != 'e'
|| info->text[2] != '[') {
return (0);
}
int echap = -1;
for (int i = 0; info->text[i] != '\0'; ++i) {
if (info->text[i] == 'm') {
if (echap == -1)
return (0);
if (echap == 0) {
info->color.fg = color_scheme->font;
return (i + 1);
}
for (int j = 0; color_table[i].id != -1; ++j) {
if (color_table[i].id != echap)
continue;
info->color.fg = color_table[i].color;
return (i + 1);
}
return (0);
}
if (info->text[i] < '0' && info->text[i] > '9')
return (0);
if (echap == -1)
echap = 0;
echap = (echap * 10) + (info->text[i] - '0');
}
return (0);
}
/* gtextXY(): Display plain text */
void gtextXY(int x, int y, const char *text)
{
struct textinfo textinfo = {
.color = {
.bg = color_scheme->background,
.fg = color_scheme->font,
},
.cursor = {
.x = x,
.y = y,
},
.text = text,
.counter = 0
};
uint16_t tmp;
while (textinfo.text[0] != '\0') {
tmp = gtext_line_discipline(&textinfo);
if (tmp != 0) {
textinfo.text = &textinfo.text[tmp];
continue;
}
tmp = gtext_echapement(&textinfo);
if (tmp != 0) {
textinfo.text = &textinfo.text[tmp];
continue;
}
tmp = textinfo.text[0] << 8;
dtext_opt(textinfo.cursor.x * (FWIDTH + 1),
textinfo.cursor.y * (FHEIGHT + 1),
textinfo.color.fg, textinfo.color.bg,
DTEXT_LEFT, DTEXT_TOP, (void*)&tmp);
textinfo.text = &textinfo.text[1];
textinfo.cursor.x += 1;
textinfo.counter += 1;
}
}

View File

@ -40,13 +40,20 @@ void fkey_button(int position, char const *text)
/* fkey_menu(): A rectangular F-key with the bottom right corner removed */
void fkey_menu(int position, char const *text)
{
int width;
dsize(text, NULL, &width, NULL);
int x = 4 + 65 * (position - 1);
int y = 207;
int w = 63;
fkey_button(position, text);
dline(x + w - 1, y + 10, x + w - 5, y + 14, C_WHITE);
dline(x + w - 1, y + 11, x + w - 4, y + 14, C_WHITE);
dline(x + w - 1, y + 12, x + w - 3, y + 14, C_WHITE);
dline(x + w - 1, y + 13, x + w - 2, y + 14, C_WHITE);
dline(x + 1, y + 0, x + w - 1, y + 0, C_BLACK);
drect(x + 0, y + 1, x + w - 0, y + 9, C_BLACK);
dline(x + 0, y + 10, x + w - 1, y + 10, C_BLACK);
dline(x + 0, y + 11, x + w - 2, y + 11, C_BLACK);
dline(x + 0, y + 12, x + w - 3, y + 12, C_BLACK);
dline(x + 0, y + 13, x + w - 4, y + 13, C_BLACK);
dline(x + 1, y + 14, x + w - 5, y + 14, C_BLACK);
dtext(x + ((w - width) >> 1), y + 3, C_WHITE, text);
}

View File

@ -4,12 +4,12 @@
#include "gintrace/gui/menu.h"
#include "gintrace/gui/fkey.h"
#include "gintrace/gui/input.h"
#include "gintrace/gui/display.h"
#include "gintrace/lexer.h"
#include <gint/std/string.h>
#include <gint/std/stdlib.h>
#include <gint/keyboard.h>
#include <gint/display.h>
/* menu_create(): Create a group of menus */
int menu_create(struct menu_group **gmenu)
@ -106,7 +106,7 @@ int menu_draw(struct menu_group *gmenu)
if (gmenu == NULL)
return (menu_retval_efault);
dclear(C_WHITE);
gclear();
if (gmenu->selected != NULL && gmenu->selected->display != NULL)
gmenu->selected->display((void*)gmenu->arg);
counter = 0;
@ -128,7 +128,7 @@ int menu_draw(struct menu_group *gmenu)
}
if (gmenu->menu_counter >= 7)
fkey_action(6, ">");
dupdate();
gupdate();
return (menu_retval_success);
}
@ -144,6 +144,10 @@ int menu_keyboard(struct menu_group *gmenu)
if (gmenu == NULL)
return (menu_retval_efault);
key = getkey().key;
if (key == KEY_0) {
gcolor_scheme_change();
return (menu_retval_success);
}
if (key == KEY_EXE) {
gmenu->is_open = 1;
return (menu_retval_success);

View File

@ -52,9 +52,16 @@ static void gintrace_handler(struct ucontext *context)
}
/* if no instruction skip, restore */
spc = context->spc;
ubc_set_breakpoint(0, (void*)context->spc, NULL);
breakpoint = tracer.next_break;
if (tracer.skip == 0) {
spc = context->spc;
ubc_set_breakpoint(0, (void*)context->spc, NULL);
breakpoint = tracer.next_break;
} else {
ubc_set_breakpoint(0, (void*)tracer.next_break, NULL);
breakpoint = tracer.next_break;
spc = tracer.next_break;
}
/* unblock UBC interrupt */
ubc_unblock();
@ -64,14 +71,15 @@ static void gintrace_handler(struct ucontext *context)
/* casio_handler(): Casio handler */
static void casio_handler(void)
{
#if 0
void (*bfile_openfile_os)(const uint16_t *filename, int mode, int p3);
bfile_openfile_os = syscall;
bfile_openfile_os(u"\\fls0\\dyntest", BFile_ReadOnly, 0);
#endif
bfile_openfile_os(u"\\\\fls0\\abcdefgijklmn", BFile_ReadOnly, 0);
#if 0
void (*debug_menu_filesystem)(void) = syscall;
debug_menu_filesystem();
#endif
}
/* main(): User entry */
@ -86,7 +94,8 @@ int main(void)
/* get syscall address */
void **systab = *(void ***)0x8002007c;
syscall = systab[0x1e48];
//syscall = systab[0x1e48]; // Fugue_debug_menu
syscall = systab[0x1da3]; // Bfile_OpenFile_OS
/* intialize UBC information */

View File

@ -8,7 +8,6 @@
#include <gint/std/stdlib.h>
#include <gint/std/string.h>
#include <gint/keyboard.h>
#include <gint/display.h>
#include <gint/bfile.h>
#include <gint/gint.h>
@ -117,6 +116,8 @@ static void callnode_display(struct callnode *node, uint32_t bitmap[4],
char pipe;
int idx;
int i;
int x;
int y;
if (node == NULL || *row + callgraph.cursor.voffset >= GUI_DISP_NB_ROW)
return;
@ -130,10 +131,9 @@ static void callnode_display(struct callnode *node, uint32_t bitmap[4],
shift = i & 0x1f;
if ((bitmap[idx] & (1 << shift)) != 0
&& *row + callgraph.cursor.voffset >= 0) {
dtext((2 + callgraph.cursor.hoffset + (i << 2))
* (FWIDTH + 1), (*row
+ callgraph.cursor.voffset)
* (FHEIGHT + 1), C_BLACK, "| ");
x = callgraph.cursor.hoffset + (i << 2) + 2;
y = callgraph.cursor.voffset + (*row);
gtextXY(x, y, "| ");
}
}
@ -151,14 +151,13 @@ static void callnode_display(struct callnode *node, uint32_t bitmap[4],
if (*row + callgraph.cursor.voffset >= 0) {
callnode_generate_info(line, 256, node);
if (depth < 0) {
int a = callgraph.cursor.hoffset + (i << 2);
int b = callgraph.cursor.voffset + (*row);
dtext(a * (FWIDTH + 1), b * (FHEIGHT + 1), C_BLACK, line);
x = callgraph.cursor.hoffset + (i << 2);
y = callgraph.cursor.voffset + (*row);
gtextXY(x, y, line);
} else {
int a = callgraph.cursor.hoffset + (i << 2) + 2;
int b = callgraph.cursor.voffset + (*row);
dprint(a * (FWIDTH + 1), b * (FHEIGHT + 1),
C_BLACK, "%c-- %s", pipe, line);
x = callgraph.cursor.hoffset + (i << 2) + 2;
y = callgraph.cursor.voffset + (*row);
gprintXY(x, y, "%c-- %s", pipe, line);
}
}
*row = *row + 1;

View File

@ -5,7 +5,6 @@
#include <gint/std/stdio.h>
#include <gint/keyboard.h>
#include <gint/display.h>
#include "./src/menu/internal/dictionary.h"
@ -47,7 +46,7 @@ static void printXY(int column, int row, const char *text, uintptr_t reg)
idx = snprintf(&bf[idx], 128 - idx, ", %s", addrname);
a = 1;
}
dtext(column * (FWIDTH + 1), row * (FHEIGHT + 1), C_BLACK, bf);
gtextXY(column, row, bf);
}
/* context_ctor: Menu constructor */

View File

@ -16,26 +16,6 @@
/* TODO: find a way to have local information (session) */
struct tracer tracer;
//---
// Internal disassembler processing
//---
/* dhreverse(): Reverse pixels color on a horizontal area (TODO: move me !!) */
static void dhreverse(int ypos, size_t size)
{
#ifdef FXCG50
/* FIXME: border !!! */
uint32_t *long_vram;
int y1;
int y2;
y1 = ypos;
y2 = ypos + size;
long_vram = (void *)gint_vram;
for(int i = 198 * y1; i < 198 * y2; i++)
long_vram[i] = ~long_vram[i];
#endif
}
/* disasm_util_line_update(): Little helper to update the line index
* @nte:
@ -261,27 +241,21 @@ int disasm_display_addr_info(int *row, struct buffcursor *cursor,
/* check note */
if (cursor->note_idx != 0) {
drect(0, (*row) * (FHEIGHT + 1) - 1, DWIDTH,
((*row) * (FHEIGHT + 1) - 1) + (FHEIGHT + 1),
0x556655);
dtext(tracer.disp.hoffset * (FWIDTH + 1),
(*row) * (FHEIGHT + 1), C_WHITE, ptr);
gnoteXY(tracer.disp.hoffset, *row, ptr);
} else {
/* check instruction */
dtext(tracer.disp.hoffset * (FWIDTH + 1),
(*row) * (FHEIGHT + 1), C_BLACK, ptr);
gtextXY(tracer.disp.hoffset, *row, ptr);
/* highlight SPC if possible */
ptr = &tracer.buffer.anchor.addr[pc];
if ((uintptr_t)ptr == context->spc)
dhreverse((*row) * (FHEIGHT + 1) - 1,
FHEIGHT + 2);
ghreverse((*row) * (FHEIGHT+1) - 1, FHEIGHT+2);
/* draw next break / instruction */
if (tracer.next_break != context->spc
&& ptr == (void*)tracer.next_break) {
dhline((*row) * (FHEIGHT + 1) - 1, C_BLACK);
dhline( ((*row) + 1) * (FHEIGHT + 1) - 1,
C_BLACK);
ghline(((*row) + 0) * (FHEIGHT + 1) - 1);
ghline(((*row) + 1) * (FHEIGHT + 1) - 1);
}
}
@ -343,6 +317,7 @@ static void disasm_init(struct ucontext *context)
{
int a;
tracer.skip = 0;
tracer.buffer.anchor.addr = (void*)(uintptr_t)((context->spc + 1) & ~1);
tracer.next_break = context->spc;
tracer.next_instruction = context->spc;
@ -459,6 +434,10 @@ static int disasm_keyboard(struct ucontext *context, int key)
context->spc = tracer.next_break;
return (1);
}
if (key == KEY_VARS) {
tracer.skip = 1;
return (1);
}
return(0);
}

View File

@ -7,7 +7,6 @@
#include <gint/std/stdio.h>
#include <gint/std/string.h>
#include <gint/keyboard.h>
#include <gint/display.h>
/* define the menu information */
/* TODO: find a way to have local information (session) */
@ -33,26 +32,17 @@ static void hexdump_display(struct ucontext *context)
x = hexdump.cursor.hoffset;
y = hexdump.cursor.voffset;
for (int i = 0; i < GUI_DISP_NB_ROW; ++i) {
dprint(x * (FWIDTH + 1), (y + i) * (FHEIGHT + 1),
C_BLACK, "%p ", record);
gprintXY(x - 2, y + i, "%p", record);
for (int j = 0; j < 8; ++j) {
dprint((x + 9 + (j * 3)) * (FWIDTH + 1),
(y + i) * (FHEIGHT + 1),
C_BLACK, "%.2x ", record[j]);
gprintXY(x + 9 + (j * 3), y + i, "%.2x", record[j]);
if (record[j] < 0x20 || record[j] > 0x7e) {
dtext((x + 34 + j) * (FWIDTH + 1),
(y + i) * (FHEIGHT + 1),
C_BLACK, ".");
gtextXY(x + 34 + j, y + i, ".");
continue;
}
dprint((x + 34 + j) * (FWIDTH + 1),
(y + i) * (FHEIGHT + 1),
C_BLACK, "%c", record[j]);
gprintXY(x + 34 + j, y + i, "%c", record[j]);
}
dtext((x + 33) * (FWIDTH + 1),
(y + i) * (FHEIGHT + 1), C_BLACK, "|");
dtext((x + 42) * (FWIDTH + 1),
(y + i) * (FHEIGHT + 1), C_BLACK, "|");
gtextXY(x + 33, y + i, "|");
gtextXY(x + 42, y + i, "|");
record = &record[8];
}
}

View File

@ -61,7 +61,13 @@ const char *dictionary_notes_check(void *address)
// Notes
//---
struct osnote osnote_table_03502202[] = {
{.address = 0x801815a6, .name = "uint32_t atomic_start(void)"},
{.address = 0x802de518, .name = "int fugue_strlen_secure(const char *str)"},
{.address = 0x8037a31c, .name = "int fugue_strlen(const char *str)"},
{.address = 0x8017233e, .name = "int fugue_dump_volume_info(const char *volume_name, void *buffer)"},
{.address = 0x8014f808, .name = "int fugue_open(struct bpb *bios, uint8_t *pathname, int mode)"},
{.address = 0x8014f2ac, .name = "int fugue_dump_info(strcuct casio_fs *fs, void *buffer)"},
{.address = 0x8015443e, .name = "int fugue_check_file_validity(strcuct bpb *bios, void *file, void *previous)"},
{.address = 0x00000000, .name = NULL},
};

View File

@ -615,8 +615,12 @@ const struct sysname casio_syscalls[] = {
//
// Yatis
//
{.syscall = 0x0db0, .name = "int fugue_unmount(void);"},
{.syscall = 0x0db1, .name = "int fugue_mount(void);"},
{.syscall = 0x0dd2, .name = "const uint16_t *FONTCHARACTER_convert_to_FUGUECHARACTER(const uint16_t *src, uint8_t *dest);"},
{.syscall = 0x0ea6, .name = "void Debug_menu_TestMode(void);"},
{.syscall = 0x0ea7, .name = "void Debug_menu_TestMode(int unknown);"},
{.syscall = 0x1da1, .name = "int fugue_logical_format(void);"},
{.syscall = 0x1e44, .name = "void Debug_menu_FileSystem(void);"},
{.syscall = 0x1e45, .name = "void Debug_menu_Fugue_OpenFileInfo(void);"},
{.syscall = 0x1e48, .name = "void Debug_menu_Fugue_VolumeInfo(void);"},