From fbcc4e37f0e6dd57622d1901745ff6eda5eded6e Mon Sep 17 00:00:00 2001 From: yann MAGNIN Date: Fri, 14 Jun 2019 19:24:48 +0200 Subject: [PATCH] Clear header. Add documentations. Update README.md --- README.md | 34 ++++++++++++++++------------------ include/command.h | 24 ++++++++++++------------ include/errno.h | 6 ++++-- include/history.h | 9 +++++++++ include/opcode.h | 3 ++- include/string.h | 28 +++++++++++++++++++++++----- include/syscalls.h | 23 +++++++++++++++++++++-- include/types.h | 5 +++-- include/utils.h | 27 ++++++++++++++++++++++----- src/boot/crt0.c | 2 +- src/commands/cache.c | 10 ++++++++++ src/commands/entry.c | 27 ++++----------------------- src/commands/help.c | 22 +++++++++++++++++----- src/commands/jump_address.c | 2 +- src/commands/jump_rom.c | 2 +- src/commands/jump_syscall.c | 4 ++-- src/commands/jump_vbr.c | 2 +- src/commands/where.c | 2 +- src/keys.c | 3 ++- 19 files changed, 152 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 2914dc6..52a2a50 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,40 @@ # Vhex disassembler Vhex is a GUI, Vim based, disassembler for fx9860g. -The Casio's OS code is not open-source but we can read the binary for understand his working. +The Casio's OS code is not open-source, but we can read the binary for understand his working. There are in particular the syscalls, OS's functions that can be called as a library since the add-ins, which are a gold mine of clues about the functioning of the material. ![](https://framapic.org/kMVBl2hbDXOo/PBd7D1FR0LF2.gif) ## features -* All SH3 instructions is traduced "on-the-fly". +* All SH3 instructions traduced "on-the-fly". * Can handle 3 modes for movements. * Can handle commands. * Commands history. * Compatible with SH3 and SH4 architecture. -List of currently supported commands: +### List of currently supported commands: -* `systab` jump to the syscall entry (Casio do not use `TRAPA` instruction, just jump into constant address). -* `vbrjmp int` jump to the Casio interrupt handler. -* `vbrjmp except` jump to the Casio exception handler. -* `vbrjmp fault` jump to the Casio memory fault handlers. -* `syscall ` jump to the syscall function. -* `ram ` jump to the ram mapped in zone (p0,p1,p2,p3,p4). -* `jmp
` jump to the address. -* `rom` jump to the start of the ROM. +* `systab` jump into the Casio "syscall handler". +* `vbrjmp ` jump into the Casio interrupt, exception or tlb miss handlers. +* `syscall ` jump into the syscall function. +* `ram ` jump into the RAM mapped at different parts of the Virtual Memory. +* `jmp
` jump where you want. +* `rom ` jump into the ROM mapped at different parts of the Virtual Memory. +* `help ` display command's help. -List of currently supported modes: +### List of currently supported modes: -TODO WRITE DOC -* `UNUSED` -* `NORMAL` -* `COMMAND` +* `UNUSED` The session is unused. +* `NORMAL` User can move freely where it wants. +* `COMMAND` User can type some commands. ## Building -Before compiling for the first time, There are a few dependencies: +Before compiling for the first time, There are few dependencies: * A suitable GCC toolchain in the `PATH`. You can absolutely *not* build Vhex - with your system compiler!`sh3eb-elf` is strongly advised. + with your system compiler! `sh3eb-elf` is strongly advised. * [g1a wrapper](https://bitbucket.org/Lephenixnoir/add-in-wrapper/src/master/) to generate the Casio header. * [P7](https://p7.planet-casio.com/) communication utilities. diff --git a/include/command.h b/include/command.h index f67f98c..0169373 100644 --- a/include/command.h +++ b/include/command.h @@ -3,35 +3,35 @@ #include #include +/* Define session_s */ #include -struct cmd_info +/* cmd_block - data part of command block */ +struct cmd_block { char *name; void (*constructor)(int, char **, struct session_s *, char *); const char *man; }; - +// CMDBLOCK() +// Generate a "command block" stored in ".cmd.cahce" section. +// We need to "hide" the block, so we generate anonyme name using +// __COUNTER__ macros. #define gen_name(n) _##n #define anonym_name(n) gen_name(n) #define CMDBLOCK(cmd,callback,string) \ __attribute__((section(".cmd.cache"))) \ - static const struct cmd_info anonym_name(__COUNTER__) = { \ + static const struct cmd_block anonym_name(__COUNTER__) = { \ .name = cmd, \ .constructor = callback, \ .man = string \ } -//TODO: write doc. +/* command_entry() - parse and execute the user's command. */ void command_entry(struct session_s *session, struct vhex_s *vhex); + +/* cmd_cache_find() - find command in the cache section. */ const struct cmd_info *cmd_cache_find(char const *name); -/*void address_jump(int argc, char **argv, struct session_s *session, char *info); -void syscall_jump(int argc, char **argv, struct session_s *session, char *info); -void ram_jump(int argc, char **argv, struct session_s *session, char *info); -void vbr_jump(int argc, char **argv, struct session_s *session, char *info); -void quit_command(int argc, char **argv, struct session_s *session, char *info); -void where_command(int argc, char **argv, struct session_s *session, char *info); -void help_command(int argc, char **argv, struct session_s *session, char *info); -*/ + #endif /*__COMMANDS_H__*/ diff --git a/include/errno.h b/include/errno.h index 946131c..c87cf2f 100644 --- a/include/errno.h +++ b/include/errno.h @@ -1,5 +1,7 @@ -#ifndef __KERNEL_ERRNO_H__ -# define __KERNEL_ERRNO_H__ 1 +#ifndef __ERRNO_H__ +# define __ERRNO_H__ 1 + +// Errno wrapped headers. #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ diff --git a/include/history.h b/include/history.h index e28913e..6f8b39f 100644 --- a/include/history.h +++ b/include/history.h @@ -1,21 +1,30 @@ #ifndef __HISTORY_H__ # define __HISTORY_H__ +/* Define type. */ #include +/* node - history node data part.*/ struct node { const char data[32]; struct node *next; }; +/* history_s - history data part. */ struct history_s { struct node *list; off_t offset; size_t deep; }; +/* history_update() - create new node into the history list. */ int history_update(struct node **list, const char *data); + +/* history_get() - get a node data. */ const void *history_get(struct node *list, off_t offset); + +/* history_quit() - free all allocated memory. */ void history_quit(struct node **list); + #endif /*__HISTORY_H__*/ diff --git a/include/opcode.h b/include/opcode.h index 6d1591f..498fe23 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -5,6 +5,7 @@ #include #include +/* opcode - instruction data part. */ struct opcode { const char *name; @@ -13,7 +14,7 @@ struct opcode uint16_t arg_mask[ARGUMENTS_MAX]; }; - +// Define ALL SH3 instructions. static const struct opcode opcode[] = { { .name = "add #h'%x,r%d", diff --git a/include/string.h b/include/string.h index 076116a..2aeebf2 100644 --- a/include/string.h +++ b/include/string.h @@ -4,25 +4,43 @@ #include #include +// Define weak symbols #define WEAK __attribute__((weak)) -//#ifndef DEBUG +/* memset() - fill memory with a constant byte. */ WEAK void *memset(void *s, int c, size_t n); + #ifndef DEBUG -WEAK void vsprintf(char *str, char const *format, va_list ap); -WEAK void sprintf(char *str, char const *format, ...); +/* vsprintf(), sprintf() - formatted output conversion. */ +void vsprintf(char *str, char const *format, va_list ap); +void sprintf(char *str, char const *format, ...); #endif /* DEBUG */ + +/* strcat() - concatenate two string */ WEAK char *strcat(char *dest, char const *src); + +/* strcmp() - compare two strings */ WEAK int strcmp(const char *s1, const char *s2); + +/* strcpy(), strncpy() - copy a string. */ WEAK char *strncpy(char *dest, char const *str, size_t size); WEAK char *strcpy(char *dest, char const *src); + +/* strlen - calculate the lenght of a string. */ WEAK size_t strlen(char const *str); -// Custom functions + + +// +// Custom string function. +// +/* strtotab() - generate table of word and indicate the number of word. */ int strtotab(int *argc, char ***argv, char const *str); + +/* strtotab_quit() - free all allocated memory by strtotab function. */ void strtotab_quit(int *argc, char ***argv); +/* atoi_base() - atoi wrapped function, but add the base number. */ uint32_t atoi_base(char const *str, int base); -//#endif /* DEBUG */ #endif /*__STRING_H__*/ diff --git a/include/syscalls.h b/include/syscalls.h index c7f1f77..fc4b351 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -3,6 +3,7 @@ #include +// Internal Casio datat structure struct rect { int left; @@ -11,16 +12,34 @@ struct rect int bottom; }; - -// Casio prototype. +// +// Casio prototypes. +// +/* GetKey() - display Casio's VRAM and wait keyboard input. */ void casio_GetKey(unsigned int *key); + +/* Bdisp_AllClr_VRAM() - clear entirely the Casio's VRAM */ void casio_Bdisp_AllClr_VRAM(void); + +/* Bdisp_AreaClr_VRAM() - clear only VRAM area. */ void casio_Bdisp_AreaClr_VRAM(const struct rect *buf); + +/* PrintMini() - print string in Casio's VRAM (and display on screen ?) */ void casio_PrintMini(size_t x, size_t y, char const *str, int mode); + +/* Bdisp_DrawLine_VRAM() - draw line in Casio's VRAM. */ void casio_Bdisp_DrawLine_VRAM(int x1, int y1, int x2, int y2); + +/* RestoreDisp() - restore saved screen. */ void casio_RestoreDisp(unsigned char page); + +/* SaveDisp() - save the content of the screen. */ void casio_SaveDisp(unsigned char page); + +/* Malloc() - malloc syscall */ void *casio_Malloc(size_t size); + +/* Free() - free syscall */ void *casio_Free(void *ptr); diff --git a/include/types.h b/include/types.h index f6fcd40..3258831 100644 --- a/include/types.h +++ b/include/types.h @@ -4,18 +4,19 @@ #include #include -//TODO: write doc - +// Define properly off_t type. # ifndef __off_t_defined typedef uint32_t off_t; # define __off_t_defined # endif +// Define properly ssize_t type. #ifndef __ssize_t_defined typedef int32_t ssize_t; # define __ssize_t_defined #endif +// Force inline function. #define INLINE __attribute__((always_inline)) inline #endif /*__TYPES_H__*/ diff --git a/include/utils.h b/include/utils.h index a01b2ee..4b64be9 100644 --- a/include/utils.h +++ b/include/utils.h @@ -2,8 +2,12 @@ # define __UTILS_H__ #include +// Define history_s #include +// +// SCREEN AND FONT PART. +// #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define FONT_WIDTH 4 @@ -11,6 +15,9 @@ #define LINE_OFFSET ((SCREEN_HEIGHT / FONT_HEIGHT) - 1) #define COLUMN_OFFSET (SCREEN_WIDTH / FONT_WIDTH) +// +// KEYS'S ID PART. +// #define KEY_UP 30018 #define KEY_DOWN 30023 #define KEY_LEFT 30020 @@ -72,11 +79,17 @@ #define KEY_8 0x38 #define KEY_9 0x39 +//TODO: move me into opcode.h #define ARGUMENTS_MAX 3 +//TODO: move me into opcode.h #define INSTRUCTION_SIZE 2 + + +// Define some buffer size. #define SESSIONS_SLOT 6 #define CMD_LENGHT_MAX 15 +// Define session modes. enum session_mode_e { UNUSED, @@ -84,6 +97,7 @@ enum session_mode_e NORMAL, }; +// session_s - session data part. struct session_s { enum session_mode_e mode; @@ -91,6 +105,7 @@ struct session_s int cursor; }; +// Define insert modes. enum insert_mode { LETTER, @@ -99,7 +114,7 @@ enum insert_mode SHIFT }; - +// vhex_s - vhex data part. struct vhex_s { int current_session; @@ -113,11 +128,13 @@ struct vhex_s struct history_s history; }; -// screen part. -void dclear(void); -void dupdate(void); - +/* display instructions() - display binary instructions. */ void display_instructions(const struct session_s *session); + +/* display_metainfos() - display status bar. */ void display_metainfos(const struct vhex_s *vhex, const struct session_s *session); + +/* key_handling() - GetKey abstraction. */ void key_handling(struct vhex_s *vhex, struct session_s *session, unsigned int key); + #endif /*__UTILS_H__*/ diff --git a/src/boot/crt0.c b/src/boot/crt0.c index 74db59a..a354909 100644 --- a/src/boot/crt0.c +++ b/src/boot/crt0.c @@ -2,7 +2,7 @@ #include extern int main(void); -//define by bootstrap.ld +//defined by bootstrap.ld extern uint32_t bbss; extern uint32_t sbss; extern uint32_t bdata_rom; diff --git a/src/commands/cache.c b/src/commands/cache.c index 71f52d6..206f760 100644 --- a/src/commands/cache.c +++ b/src/commands/cache.c @@ -5,6 +5,16 @@ extern uint32_t bcmd_cache; extern uint32_t ecmd_cache; +// +// cmd_cache_find() +// Try to find the command into the command cache. +// +// NOTE: +// The cache is generated during the compilation; all command +// blocks is stored in the ".cmd.cache" section. +// We use the section symbols to know where the cache end. +// (see bootstrap.ld). +// const struct cmd_info *cmd_cache_find(char const *name) { const struct cmd_info *cache; diff --git a/src/commands/entry.c b/src/commands/entry.c index cfc2f99..fdfa440 100644 --- a/src/commands/entry.c +++ b/src/commands/entry.c @@ -2,29 +2,10 @@ #include #include -//--- -// Define all "command block". One block is composed by: -// * id: used uniquely for the "command_find()" internal cache. -// * name: string which contains the user's command. -// * anchor: used if the constructor are not set, it is the new "location" of the anchor. -// * constructor: the command constructor (and the new anchor location will be ignored). -//--- -//TODO: generate automatically anonymous name, and remove "command_find()" cache. -/*CMDBLOCK(rom, "rom", 0x00300200, NULL); -CMDBLOCK(systab, "systab", 0x80010070, NULL); -CMDBLOCK(ram, "ram", NULL, &ram_jump); -CMDBLOCK(vbrjmp, "vbrjmp", NULL, &vbr_jump); -CMDBLOCK(addr_jump, "jmp", NULL, &address_jump); -CMDBLOCK(sysc_jump, "syscall", NULL, &syscall_jump); - -CMDBLOCK(exit, "quit", NULL, &quit_command); -CMDBLOCK(locate, "where", NULL, &where_command); -*/ - - // // command_find -// Try to find the user command in the internal cache and execute constructor. +// Try to find the user command in the internal cache and execute +// the command's function. // static int command_find(int argc, char **argv, struct session_s *session, struct vhex_s *vhex) @@ -36,7 +17,7 @@ struct vhex_s *vhex) if (command == NULL) return (EINVAL); if (command->constructor == NULL){ - strcpy(vhex->info, "constructor error"); + strcpy(vhex->info, "function error"); return (ENOSYS); } tmp = session->anchor; @@ -51,7 +32,7 @@ struct vhex_s *vhex) // // command_entry() -// The goal of this part is to parse and execute user's command. +// The goal of this part is to parse and execute the user's command. // void command_entry(struct session_s *session, struct vhex_s *vhex) { diff --git a/src/commands/help.c b/src/commands/help.c index 382fae9..4621747 100644 --- a/src/commands/help.c +++ b/src/commands/help.c @@ -3,13 +3,11 @@ #include #include -/* FIXME: write doc !! */ - // Internal prototype. -static void help_command(int argc, char **argv, struct session_s *session, char *info); +static void help(int argc, char **argv, struct session_s *session, char *info); // Define help command into the cache section. -CMDBLOCK("help", &help_command, +CMDBLOCK("help", &help, "Help for Vhex version 1.0\n" "This chapter introduces\noperations available with vhex.\n" "\n" @@ -95,6 +93,7 @@ CMDBLOCK("help", &help_command, "work for any purpose and\nwithout any legal restrictions, " "except those required by law.\n"); +/* get_nb_line() - Return the number of lines contain in the command's manual. */ static int get_nb_line(char const *str) { int nb_line; @@ -114,6 +113,7 @@ static int get_nb_line(char const *str) return (nb_line + 1); } +/* get_line() - Return the address of a target line */ static const char *get_line(char const *str, int line) { int cursor; @@ -133,6 +133,14 @@ static const char *get_line(char const *str, int line) return (str); } +// +// display_text() - Display only lines which should be visible. +// +// NOTE: +// Due to the Casio's GetKey function, the font used is a little bit weird, +// some characters have not the same size, so we can't calculate easily +// the line size. (TODO: fix that). +// static void display_text(char *buf, char const *str, int current_line) { char const *text; @@ -161,6 +169,7 @@ static void display_text(char *buf, char const *str, int current_line) print(0, nb_line * FONT_HEIGHT, buf); } +/* help_engine() - Display help information and handle keyboard. */ static void help_engine(char const *text, int nb_line) { char buf[COLUMN_OFFSET + 1]; @@ -182,6 +191,8 @@ static void help_engine(char const *text, int nb_line) sprintf(buf, "%d/%d", cursor + 1, nb_line + 1); print(SCREEN_WIDTH - (strlen(buf) * FONT_WIDTH) - 1, SCREEN_HEIGHT - FONT_HEIGHT, buf); getkey(&key); + + // Keys hanlding. if (key == KEY_UP && cursor > 0) cursor -= 1; if (key == KEY_DOWN && cursor < nb_line) @@ -191,7 +202,8 @@ static void help_engine(char const *text, int nb_line) } } -static void help_command(int argc, char **argv, struct session_s *session, char *info) +/* help() - display command manual pages. */ +static void help(int argc, char **argv, struct session_s *session, char *info) { const struct cmd_info *command; int nb_line; diff --git a/src/commands/jump_address.c b/src/commands/jump_address.c index 14dce13..84f0404 100644 --- a/src/commands/jump_address.c +++ b/src/commands/jump_address.c @@ -4,7 +4,7 @@ // Internal prototype. static void address_jump(int argc, char **argv, struct session_s *session, char *info); -// Define the command block into the cache +// Define the command block into the cache. CMDBLOCK("jmp", &address_jump, "JMP command help\n" "This command takes one\nparameter: the address (hexa)\n" diff --git a/src/commands/jump_rom.c b/src/commands/jump_rom.c index 78a4e88..d449b42 100644 --- a/src/commands/jump_rom.c +++ b/src/commands/jump_rom.c @@ -24,7 +24,7 @@ CMDBLOCK("rom", &rom_jump, "MMU is disable and the area\nis not cached.\n" ); -/* rom_jump() - jump into the start of the ROM */ +/* rom_jump() - jump into the ROM mapped in different parts of the Virtual Memory. */ static void rom_jump(int argc, char **argv, struct session_s *session, char *info) { if (argc != 2){ diff --git a/src/commands/jump_syscall.c b/src/commands/jump_syscall.c index ffb89ce..14cf4b3 100644 --- a/src/commands/jump_syscall.c +++ b/src/commands/jump_syscall.c @@ -101,8 +101,8 @@ static INLINE int check_address(char *str) // // syscall_jump() // Casio doesn't use the TRAPA instruction (software interruption), for switch from -// user mode to privileged mode. They just jump to a content area (always at 0x80010070) -// and use the table of syscall addresses to redirect the jump. (and the table is always +// user mode to privileged mode. They just jump always at 0x80010070 and use the +// table of syscall addresses to redirect the jump. (and the table address is always // stored at 0x8001007c). // static void syscall_jump(int argc, char **argv, struct session_s *session, char *info) diff --git a/src/commands/jump_vbr.c b/src/commands/jump_vbr.c index f40e721..461c5c8 100644 --- a/src/commands/jump_vbr.c +++ b/src/commands/jump_vbr.c @@ -22,7 +22,7 @@ CMDBLOCK("vbrjmp", &vbrjmp, ); // -// vbr_jump() - jump to the exception, tlb or interrupt Casio handler. +// vbr_jump() - jump to the exception, tlb or interrupt, Casio handler. // Due to the SH3 / SH4 VBR system, there are 3 vectors offset called // by the processor: // * vbr + 0x100 -> general exeptions. diff --git a/src/commands/where.c b/src/commands/where.c index 9f11eca..8228d1f 100644 --- a/src/commands/where.c +++ b/src/commands/where.c @@ -7,7 +7,7 @@ static void where(int argc, char **argv, struct session_s *session, char *info); // Define the command into the cache. CMDBLOCK("where", &where, NULL); -/* where() - display the user postision in the Virtual Memory. */ +/* where() - display the user positision in the Virtual Memory. */ static void where(int argc, char **argv, struct session_s *session, char *info) { (void)argc; diff --git a/src/keys.c b/src/keys.c index 7265287..93ed490 100644 --- a/src/keys.c +++ b/src/keys.c @@ -27,7 +27,8 @@ static int check_session(unsigned int key, struct vhex_s *vhex) // // check_special() // As explained below, the Casio getkey function has an internal status. -// Here we check if a "special" keys are pressed and update internal Vhex key's status. +// Here we check if a "special" keys are pressed and update internal Vhex +// "keyboard's status". // static int check_special(unsigned int key, struct vhex_s *vhex, struct session_s *session) {