From 76aeea1fa5c67e479441f9232c6e89900f1b8667 Mon Sep 17 00:00:00 2001 From: yann MAGNIN Date: Fri, 14 Jun 2019 14:49:13 +0200 Subject: [PATCH] Update License used by the project --> switch to CC0. Add change project name to Vhex. Update command handling, now we generate and hide the cache (and command block) during the compilation. Add documentations. Add manual pages. Add units tests. Update some modules. --- LICENSE | 481 +++++++++--------------------------- Makefile | 2 +- README.md | 47 +++- bootstrap.ld | 4 + global.mk | 3 +- include/command.h | 37 +++ include/commands.h | 35 --- include/syscalls.h | 8 +- include/utils.h | 17 +- src/boot/crt0.c | 2 +- src/commands/address_jump.c | 19 -- src/commands/cache.c | 20 ++ src/commands/entry.c | 91 ++++--- src/commands/help.c | 216 ++++++++++++++++ src/commands/jump_address.c | 58 +++++ src/commands/jump_ram.c | 51 ++++ src/commands/jump_rom.c | 44 ++++ src/commands/jump_syscall.c | 120 +++++++++ src/commands/jump_systab.c | 29 +++ src/commands/jump_vbr.c | 49 ++++ src/commands/quit.c | 18 ++ src/commands/ram_jump.c | 20 -- src/commands/syscall_jump.c | 24 -- src/commands/vbr_jump.c | 18 -- src/commands/where.c | 16 ++ src/display/intructions.c | 21 +- src/display/metainfos.c | 11 +- src/history.c | 24 +- src/keys.c | 132 ++++++---- src/main.c | 34 +-- src/string/atoi_base.c | 5 + src/string/strtotab.c | 19 +- src/syscalls.s | 14 +- tests/internal.h | 1 + tests/malloc_hook.c | 3 +- 35 files changed, 1054 insertions(+), 639 deletions(-) create mode 100644 include/command.h delete mode 100644 include/commands.h delete mode 100644 src/commands/address_jump.c create mode 100644 src/commands/cache.c create mode 100644 src/commands/help.c create mode 100644 src/commands/jump_address.c create mode 100644 src/commands/jump_ram.c create mode 100644 src/commands/jump_rom.c create mode 100644 src/commands/jump_syscall.c create mode 100644 src/commands/jump_systab.c create mode 100644 src/commands/jump_vbr.c create mode 100644 src/commands/quit.c delete mode 100644 src/commands/ram_jump.c delete mode 100644 src/commands/syscall_jump.c delete mode 100644 src/commands/vbr_jump.c create mode 100644 src/commands/where.c diff --git a/LICENSE b/LICENSE index 5797ceb..a343ccd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,362 +1,119 @@ -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative -Commons Corporation ("Creative Commons") is not a law firm and does not provide -legal services or legal advice. Distribution of Creative Commons public licenses -does not create a lawyer-client or other relationship. Creative Commons makes -its licenses and related information available on an "as-is" basis. Creative -Commons gives no warranties regarding its licenses, any material licensed -under their terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the fullest -extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and conditions -that creators and other rights holders may use to share original works of -authorship and other material subject to copyright and certain other rights -specified in the public license below. The following considerations are for -informational purposes only, are not exhaustive, and do not form part of our -licenses. - -Considerations for licensors: Our public licenses are intended for use by -those authorized to give the public permission to use material in ways otherwise -restricted by copyright and certain other rights. Our licenses are irrevocable. -Licensors should read and understand the terms and conditions of the license -they choose before applying it. Licensors should also secure all rights necessary -before applying our licenses so that the public can reuse the material as -expected. Licensors should clearly mark any material not subject to the license. -This includes other CC-licensed material, or material used under an exception -or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors - -Considerations for the public: By using one of our public licenses, a licensor -grants the public permission to use the licensed material under specified -terms and conditions. If the licensor's permission is not necessary for any -reason–for example, because of any applicable exception or limitation to copyright–then -that use is not regulated by the license. Our licenses grant only permissions -under copyright and certain other rights that a licensor has authority to -grant. Use of the licensed material may still be restricted for other reasons, -including because others have copyright or other rights in the material. A -licensor may make special requests, such as asking that all changes be marked -or described. Although not required by our licenses, you are encouraged to -respect those requests where reasonable. More considerations for the public -: wiki.creativecommons.org/Considerations_for_licensees - -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public -License - -By exercising the Licensed Rights (defined below), You accept and agree to -be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike -4.0 International Public License ("Public License"). To the extent this Public -License may be interpreted as a contract, You are granted the Licensed Rights -in consideration of Your acceptance of these terms and conditions, and the -Licensor grants You such rights in consideration of benefits the Licensor -receives from making the Licensed Material available under these terms and -conditions. - -Section 1 – Definitions. - -a. Adapted Material means material subject to Copyright and Similar Rights -that is derived from or based upon the Licensed Material and in which the -Licensed Material is translated, altered, arranged, transformed, or otherwise -modified in a manner requiring permission under the Copyright and Similar -Rights held by the Licensor. For purposes of this Public License, where the -Licensed Material is a musical work, performance, or sound recording, Adapted -Material is always produced where the Licensed Material is synched in timed -relation with a moving image. - -b. Adapter's License means the license You apply to Your Copyright and Similar -Rights in Your contributions to Adapted Material in accordance with the terms -and conditions of this Public License. - -c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, -approved by Creative Commons as essentially the equivalent of this Public -License. - -d. Copyright and Similar Rights means copyright and/or similar rights closely -related to copyright including, without limitation, performance, broadcast, -sound recording, and Sui Generis Database Rights, without regard to how the -rights are labeled or categorized. For purposes of this Public License, the -rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. - -e. Effective Technological Measures means those measures that, in the absence -of proper authority, may not be circumvented under laws fulfilling obligations -under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, -and/or similar international agreements. - -f. Exceptions and Limitations means fair use, fair dealing, and/or any other -exception or limitation to Copyright and Similar Rights that applies to Your -use of the Licensed Material. - -g. License Elements means the license attributes listed in the name of a Creative -Commons Public License. The License Elements of this Public License are Attribution, -NonCommercial, and ShareAlike. - -h. Licensed Material means the artistic or literary work, database, or other -material to which the Licensor applied this Public License. - -i. Licensed Rights means the rights granted to You subject to the terms and -conditions of this Public License, which are limited to all Copyright and -Similar Rights that apply to Your use of the Licensed Material and that the -Licensor has authority to license. - -j. Licensor means the individual(s) or entity(ies) granting rights under this -Public License. - -k. NonCommercial means not primarily intended for or directed towards commercial -advantage or monetary compensation. For purposes of this Public License, the -exchange of the Licensed Material for other material subject to Copyright -and Similar Rights by digital file-sharing or similar means is NonCommercial -provided there is no payment of monetary compensation in connection with the -exchange. - -l. Share means to provide material to the public by any means or process that -requires permission under the Licensed Rights, such as reproduction, public -display, public performance, distribution, dissemination, communication, or -importation, and to make material available to the public including in ways -that members of the public may access the material from a place and at a time -individually chosen by them. - -m. Sui Generis Database Rights means rights other than copyright resulting -from Directive 96/9/EC of the European Parliament and of the Council of 11 -March 1996 on the legal protection of databases, as amended and/or succeeded, -as well as other essentially equivalent rights anywhere in the world. - -n. You means the individual or entity exercising the Licensed Rights under -this Public License. Your has a corresponding meaning. - -Section 2 – Scope. - - a. License grant. - -1. Subject to the terms and conditions of this Public License, the Licensor -hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, -irrevocable license to exercise the Licensed Rights in the Licensed Material -to: - -A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial -purposes only; and - -B. produce, reproduce, and Share Adapted Material for NonCommercial purposes -only. - -2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions -and Limitations apply to Your use, this Public License does not apply, and -You do not need to comply with its terms and conditions. - - 3. Term. The term of this Public License is specified in Section 6(a). - -4. Media and formats; technical modifications allowed. The Licensor authorizes -You to exercise the Licensed Rights in all media and formats whether now known -or hereafter created, and to make technical modifications necessary to do -so. The Licensor waives and/or agrees not to assert any right or authority -to forbid You from making technical modifications necessary to exercise the -Licensed Rights, including technical modifications necessary to circumvent -Effective Technological Measures. For purposes of this Public License, simply -making modifications authorized by this Section 2(a)(4) never produces Adapted -Material. - - 5. Downstream recipients. - -A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed -Material automatically receives an offer from the Licensor to exercise the -Licensed Rights under the terms and conditions of this Public License. - -B. Additional offer from the Licensor – Adapted Material. Every recipient -of Adapted Material from You automatically receives an offer from the Licensor -to exercise the Licensed Rights in the Adapted Material under the conditions -of the Adapter's License You apply. - -C. No downstream restrictions. You may not offer or impose any additional -or different terms or conditions on, or apply any Effective Technological -Measures to, the Licensed Material if doing so restricts exercise of the Licensed -Rights by any recipient of the Licensed Material. - -6. No endorsement. Nothing in this Public License constitutes or may be construed -as permission to assert or imply that You are, or that Your use of the Licensed -Material is, connected with, or sponsored, endorsed, or granted official status -by, the Licensor or others designated to receive attribution as provided in -Section 3(a)(1)(A)(i). - - b. Other rights. - -1. Moral rights, such as the right of integrity, are not licensed under this -Public License, nor are publicity, privacy, and/or other similar personality -rights; however, to the extent possible, the Licensor waives and/or agrees -not to assert any such rights held by the Licensor to the limited extent necessary -to allow You to exercise the Licensed Rights, but not otherwise. - -2. Patent and trademark rights are not licensed under this Public License. - -3. To the extent possible, the Licensor waives any right to collect royalties -from You for the exercise of the Licensed Rights, whether directly or through -a collecting society under any voluntary or waivable statutory or compulsory -licensing scheme. In all other cases the Licensor expressly reserves any right -to collect such royalties, including when the Licensed Material is used other -than for NonCommercial purposes. - -Section 3 – License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the following -conditions. - - a. Attribution. - -1. If You Share the Licensed Material (including in modified form), You must: - -A. retain the following if it is supplied by the Licensor with the Licensed -Material: - -i. identification of the creator(s) of the Licensed Material and any others -designated to receive attribution, in any reasonable manner requested by the -Licensor (including by pseudonym if designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of warranties; - - - -v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; - -B. indicate if You modified the Licensed Material and retain an indication -of any previous modifications; and - -C. indicate the Licensed Material is licensed under this Public License, and -include the text of, or the URI or hyperlink to, this Public License. - -2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner -based on the medium, means, and context in which You Share the Licensed Material. -For example, it may be reasonable to satisfy the conditions by providing a -URI or hyperlink to a resource that includes the required information. - -3. If requested by the Licensor, You must remove any of the information required -by Section 3(a)(1)(A) to the extent reasonably practicable. - -b. ShareAlike.In addition to the conditions in Section 3(a), if You Share -Adapted Material You produce, the following conditions also apply. - -1. The Adapter's License You apply must be a Creative Commons license with -the same License Elements, this version or later, or a BY-NC-SA Compatible -License. - -2. You must include the text of, or the URI or hyperlink to, the Adapter's -License You apply. You may satisfy this condition in any reasonable manner -based on the medium, means, and context in which You Share Adapted Material. - -3. You may not offer or impose any additional or different terms or conditions -on, or apply any Effective Technological Measures to, Adapted Material that -restrict exercise of the rights granted under the Adapter's License You apply. - -Section 4 – Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that apply to -Your use of the Licensed Material: - -a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, -reuse, reproduce, and Share all or a substantial portion of the contents of -the database for NonCommercial purposes only; - -b. if You include all or a substantial portion of the database contents in -a database in which You have Sui Generis Database Rights, then the database -in which You have Sui Generis Database Rights (but not its individual contents) -is Adapted Material, including for purposes of Section 3(b); and - -c. You must comply with the conditions in Section 3(a) if You Share all or -a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not replace -Your obligations under this Public License where the Licensed Rights include -other Copyright and Similar Rights. - -Section 5 – Disclaimer of Warranties and Limitation of Liability. - -a. Unless otherwise separately undertaken by the Licensor, to the extent possible, -the Licensor offers the Licensed Material as-is and as-available, and makes -no representations or warranties of any kind concerning the Licensed Material, -whether express, implied, statutory, or other. This includes, without limitation, -warranties of title, merchantability, fitness for a particular purpose, non-infringement, -absence of latent or other defects, accuracy, or the presence or absence of -errors, whether or not known or discoverable. Where disclaimers of warranties -are not allowed in full or in part, this disclaimer may not apply to You. - -b. To the extent possible, in no event will the Licensor be liable to You -on any legal theory (including, without limitation, negligence) or otherwise -for any direct, special, indirect, incidental, consequential, punitive, exemplary, -or other losses, costs, expenses, or damages arising out of this Public License -or use of the Licensed Material, even if the Licensor has been advised of -the possibility of such losses, costs, expenses, or damages. Where a limitation -of liability is not allowed in full or in part, this limitation may not apply -to You. - -c. The disclaimer of warranties and limitation of liability provided above -shall be interpreted in a manner that, to the extent possible, most closely -approximates an absolute disclaimer and waiver of all liability. - -Section 6 – Term and Termination. - -a. This Public License applies for the term of the Copyright and Similar Rights -licensed here. However, if You fail to comply with this Public License, then -Your rights under this Public License terminate automatically. - -b. Where Your right to use the Licensed Material has terminated under Section -6(a), it reinstates: - -1. automatically as of the date the violation is cured, provided it is cured -within 30 days of Your discovery of the violation; or - - 2. upon express reinstatement by the Licensor. - -For the avoidance of doubt, this Section 6(b) does not affect any right the -Licensor may have to seek remedies for Your violations of this Public License. - -c. For the avoidance of doubt, the Licensor may also offer the Licensed Material -under separate terms or conditions or stop distributing the Licensed Material -at any time; however, doing so will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. - -Section 7 – Other Terms and Conditions. - -a. The Licensor shall not be bound by any additional or different terms or -conditions communicated by You unless expressly agreed. - -b. Any arrangements, understandings, or agreements regarding the Licensed -Material not stated herein are separate from and independent of the terms -and conditions of this Public License. - -Section 8 – Interpretation. - -a. For the avoidance of doubt, this Public License does not, and shall not -be interpreted to, reduce, limit, restrict, or impose conditions on any use -of the Licensed Material that could lawfully be made without permission under -this Public License. - -b. To the extent possible, if any provision of this Public License is deemed -unenforceable, it shall be automatically reformed to the minimum extent necessary -to make it enforceable. If the provision cannot be reformed, it shall be severed -from this Public License without affecting the enforceability of the remaining -terms and conditions. - -c. No term or condition of this Public License will be waived and no failure -to comply consented to unless expressly agreed to by the Licensor. - -d. Nothing in this Public License constitutes or may be interpreted as a limitation -upon, or waiver of, any privileges and immunities that apply to the Licensor -or You, including from the legal processes of any jurisdiction or authority. - -Creative Commons is not a party to its public licenses. Notwithstanding, Creative -Commons may elect to apply one of its public licenses to material it publishes -and in those instances will be considered the "Licensor." The text of the -Creative Commons public licenses is dedicated to the public domain under the -CC0 Public Domain Dedication. Except for the limited purpose of indicating -that material is shared under a Creative Commons public license or as otherwise -permitted by the Creative Commons policies published at creativecommons.org/policies, -Creative Commons does not authorize the use of the trademark "Creative Commons" -or any other trademark or logo of Creative Commons without its prior written -consent including, without limitation, in connection with any unauthorized -modifications to any of its public licenses or any other arrangements, understandings, -or agreements concerning use of licensed material. For the avoidance of doubt, -this paragraph does not form part of the public licenses. - -Creative Commons may be contacted at creativecommons.org. +Creative Commons Legal Code + +CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES +NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE +AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION +ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE +OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS +LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION +OR WORKS PROVIDED HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer exclusive +Copyright and Related Rights (defined below) upon the creator and subsequent +owner(s) (each and all, an "owner") of an original work of authorship and/or +a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later claims +of infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further production +of creative, cultural and scientific works, or to gain reputation or greater +distribution for their Work in part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with +a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or +her Copyright and Related Rights in the Work and the meaning and intended +legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be protected +by copyright and related or neighboring rights ("Copyright and Related Rights"). +Copyright and Related Rights include, but are not limited to, the following: + +i. the right to reproduce, adapt, distribute, perform, display, communicate, +and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + +iii. publicity and privacy rights pertaining to a person's image or likeness +depicted in a Work; + +iv. rights protecting against unfair competition in regards to a Work, subject +to the limitations in paragraph 4(a), below; + +v. rights protecting the extraction, dissemination, use and reuse of data +in a Work; + +vi. database rights (such as those arising under Directive 96/9/EC of the +European Parliament and of the Council of 11 March 1996 on the legal protection +of databases, and under any national implementation thereof, including any +amended or successor version of such directive); and + +vii. other similar, equivalent or corresponding rights throughout the world +based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time extensions), +(iii) in any current or future medium and for any number of copies, and (iv) +for any purpose whatsoever, including without limitation commercial, advertising +or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the +benefit of each member of the public at large and to the detriment of Affirmer's +heirs and successors, fully intending that such Waiver shall not be subject +to revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account Affirmer's +express Statement of Purpose. In addition, to the extent the Waiver is so +judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer's Copyright and Related Rights in the Work (i) +in all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional purposes +(the "License"). The License shall be deemed effective as of the date CC0 +was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of +the License, and in such case Affirmer hereby affirms that he or she will +not (i) exercise any of his or her remaining Copyright and Related Rights +in the Work or (ii) assert any associated claims and causes of action with +respect to the Work, in either case contrary to Affirmer's express Statement +of Purpose. + + 4. Limitations and Disclaimers. + +a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, +licensed or otherwise affected by this document. + +b. Affirmer offers the Work as-is and makes no representations or warranties +of any kind concerning the Work, express, implied, statutory or otherwise, +including without limitation warranties of title, merchantability, fitness +for a particular purpose, non infringement, or the absence of latent or other +defects, accuracy, or the present or absence of errors, whether or not discoverable, +all to the greatest extent permissible under applicable law. + +c. Affirmer disclaims responsibility for clearing rights of other persons +that may apply to the Work or any use thereof, including without limitation +any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims +responsibility for obtaining any necessary consents, permissions or other +rights required for any use of the Work. + +d. Affirmer understands and acknowledges that Creative Commons is not a party +to this document and has no duty or obligation with respect to this CC0 or +use of the Work. diff --git a/Makefile b/Makefile index dbec214..9ba3e61 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ # --- include global.mk -NAME := dump +NAME := vhex EXEC := $(NAME).g1a HEADER := -Iinclude DEBUG := link_map.txt diff --git a/README.md b/README.md index 1d4ba06..2914dc6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,46 @@ -# vhex +# Vhex disassembler -Vhex is a GUI, Vim based, disassembler for fx9860g. \ No newline at end of file +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. +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". +* Can handle 3 modes for movements. +* Can handle commands. +* Commands history. +* Compatible with SH3 and SH4 architecture. + +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. + +List of currently supported modes: + +TODO WRITE DOC +* `UNUSED` +* `NORMAL` +* `COMMAND` + +## Building + +Before compiling for the first time, There are a few dependencies: +* A suitable GCC toolchain in the `PATH`. You can absolutely *not* build Vhex + 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. + +To compile the project, you just plug the calculator and execute: + + % make + % make install diff --git a/bootstrap.ld b/bootstrap.ld index 630930a..042fae1 100644 --- a/bootstrap.ld +++ b/bootstrap.ld @@ -22,6 +22,10 @@ SECTIONS .rodata : SUBALIGN(4) { *(.rodata) + . = ALIGN(4); + _bcmd_cache = . ; + *(.cmd.cache) + _ecmd_cache = . ; } > rom diff --git a/global.mk b/global.mk index 2ecdb21..aff5d7f 100644 --- a/global.mk +++ b/global.mk @@ -10,7 +10,8 @@ LD := $(COMPILER)ld WRAPPER := g1a-wrapper CFLAGS := -Werror -Wall -W -Wextra -std=c18 -m3 -mb -mrenesas \ - -ffreestanding -nostdlib -fstrict-volatile-bitfields + -ffreestanding -nostdlib -fstrict-volatile-bitfields \ + -Wno-unused-const-variable BUILD-DIR := build/ SRC-DIR := src/ diff --git a/include/command.h b/include/command.h new file mode 100644 index 0000000..f67f98c --- /dev/null +++ b/include/command.h @@ -0,0 +1,37 @@ +#ifndef __COMMANDS_H__ +# define __COMMANDS_H__ + +#include +#include +#include + +struct cmd_info +{ + char *name; + void (*constructor)(int, char **, struct session_s *, char *); + const char *man; +}; + + +#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__) = { \ + .name = cmd, \ + .constructor = callback, \ + .man = string \ + } + +//TODO: write doc. +void command_entry(struct session_s *session, struct vhex_s *vhex); +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/commands.h b/include/commands.h deleted file mode 100644 index a556d27..0000000 --- a/include/commands.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __COMMANDS_H__ -# define __COMMANDS_H__ - -#include -#include -#include - -//FIXME: MOVE ME ! -struct cmd_info -{ - char *name; - struct { - ptrdiff_t anchor; - size_t size; - } update; - void (*init)(int argc, char **argv, struct session_s *session, char *info); -}; - -#define CMDBLOCK(bname,cmd,ptr,sizez,callback) \ - static const struct cmd_info bname = { \ - .name = cmd, \ - .update = { \ - .anchor = (ptrdiff_t)(ptr), \ - .size = sizez, \ - }, \ - .init = callback \ - } - -//TODO: write doc. -void command_entry(struct session_s *session, struct dump_s *dump); -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 arc, char **argv, struct session_s *session, char *info); -#endif /*__COMMANDS_H__*/ diff --git a/include/syscalls.h b/include/syscalls.h index ecd2b3b..c7f1f77 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -14,8 +14,8 @@ struct rect // Casio prototype. void casio_GetKey(unsigned int *key); -void casio_Bdisp_AllClr_DDVRAM(void); -void casio_Bdisp_AreaClr_DDVRAM(const struct rect *buf); +void casio_Bdisp_AllClr_VRAM(void); +void casio_Bdisp_AreaClr_VRAM(const struct rect *buf); void casio_PrintMini(size_t x, size_t y, char const *str, int mode); void casio_Bdisp_DrawLine_VRAM(int x1, int y1, int x2, int y2); void casio_RestoreDisp(unsigned char page); @@ -28,12 +28,12 @@ void *casio_Free(void *ptr); static INLINE void dclear_area(int x1, int y1, int x2, int y2) { struct rect area = {.left = x1, .top = y1, .right = x2, .bottom = y2}; - casio_Bdisp_AreaClr_DDVRAM(&area); + casio_Bdisp_AreaClr_VRAM(&area); } #define print(x, y, str) casio_PrintMini(x, y, str, 0) #define getkey casio_GetKey #define dline_horizontal(y, x1, x2) casio_Bdisp_DrawLine_VRAM(x1, y, x2, y) -#define dclear casio_Bdisp_AllClr_DDVRAM +#define dclear casio_Bdisp_AllClr_VRAM #define save_window casio_SaveDisp #define restore_window casio_RestoreDisp #define malloc casio_Malloc diff --git a/include/utils.h b/include/utils.h index 83a18e3..a01b2ee 100644 --- a/include/utils.h +++ b/include/utils.h @@ -14,7 +14,7 @@ #define KEY_UP 30018 #define KEY_DOWN 30023 #define KEY_LEFT 30020 -#define KEY_RIGHT 30021 +#define KEY_RIGHT 30020 #define KEY_OPTN 30008 #define KEY_F1 30009 @@ -32,6 +32,7 @@ #define KEY_INS 30033 #define KEY_PI 0xd0 #define KEY_QUOTE KEY_PI +#define KEY_EXIT 30002 #define KEY_A 0x41 #define KEY_B 0x42 @@ -76,20 +77,18 @@ #define SESSIONS_SLOT 6 #define CMD_LENGHT_MAX 15 -enum mode_e +enum session_mode_e { UNUSED, COMMAND, NORMAL, - FREE }; struct session_s { - enum mode_e mode; + enum session_mode_e mode; ptrdiff_t anchor; - off_t cursor; - size_t size; + int cursor; }; enum insert_mode @@ -101,7 +100,7 @@ enum insert_mode }; -struct dump_s +struct vhex_s { int current_session; struct session_s session[SESSIONS_SLOT]; @@ -119,6 +118,6 @@ void dclear(void); void dupdate(void); void display_instructions(const struct session_s *session); -void display_metainfos(const struct dump_s *dump, const struct session_s *session); -void key_handling(struct dump_s *dump, struct session_s *session, unsigned int key); +void display_metainfos(const struct vhex_s *vhex, const struct session_s *session); +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 e0e1d42..74db59a 100644 --- a/src/boot/crt0.c +++ b/src/boot/crt0.c @@ -39,7 +39,7 @@ void section_reset(uint32_t *bsection, size_t size) } // -// initialize() +// initialize() - the real add-in entry. // We are currently running in the storage memory, so we should // load data in RAM and wipe the bss section for initialize static // and global variables. diff --git a/src/commands/address_jump.c b/src/commands/address_jump.c deleted file mode 100644 index d615bb9..0000000 --- a/src/commands/address_jump.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -static INLINE int check_address(char *str) -{ - --str; - while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')); - return ((*str != '\0') ? 1 : 0); -} - -void address_jump(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 2 || check_address(argv[1]) != 0){ - strcpy(info, "arguments error"); - return; - } - session->anchor = atoi_base(argv[1], 16) >> 1 << 1; - session->size = 0xffffffff; -} diff --git a/src/commands/cache.c b/src/commands/cache.c new file mode 100644 index 0000000..71f52d6 --- /dev/null +++ b/src/commands/cache.c @@ -0,0 +1,20 @@ +#include +#include + +// External symbols defined by the linker script. +extern uint32_t bcmd_cache; +extern uint32_t ecmd_cache; + +const struct cmd_info *cmd_cache_find(char const *name) +{ + const struct cmd_info *cache; + size_t i; + + i = -1; + cache = (void *)&bcmd_cache; + while ((ptrdiff_t)(&cache[++i]) != (ptrdiff_t)&ecmd_cache + && strcmp(cache[i].name, name)); + if ((ptrdiff_t)(&cache[i]) == (ptrdiff_t)&ecmd_cache) + return (NULL); + return (&cache[i]); +} diff --git a/src/commands/entry.c b/src/commands/entry.c index b237270..cfc2f99 100644 --- a/src/commands/entry.c +++ b/src/commands/entry.c @@ -1,61 +1,76 @@ -#include +#include #include #include -CMDBLOCK(rom, "rom", 0x00300200, 0xffffffff, NULL); -CMDBLOCK(systab, "systab", 0x80010070, 0xffffffff, NULL); -CMDBLOCK(ram, "ram", NULL, 0xffffffff, &ram_jump); -CMDBLOCK(vbrjmp, "vbrjmp", NULL, 0xffffffff, &vbr_jump); -CMDBLOCK(addr_jump, "jmp", NULL, 0xffffffff, &address_jump); -CMDBLOCK(sysc_jump, "syscall", NULL, 0xffffffff, &syscall_jump); +//--- +// 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); +*/ -//TODO: -// - dynamique allocation cache. -// - rename function. -static int find_command(int argc, char **argv, struct session_s *session, -struct dump_s *dump) +// +// command_find +// Try to find the user command in the internal cache and execute constructor. +// +static int command_find(int argc, char **argv, struct session_s *session, +struct vhex_s *vhex) { - static const struct cmd_info *cache[] = { - &addr_jump, &vbrjmp, &systab, &sysc_jump, &ram, &rom, NULL - }; - size_t i; + const struct cmd_info *command; + int tmp; - i = -1; - while (cache[++i] != NULL && strcmp(cache[i]->name, *argv)); - if (cache[i] == NULL) - return (EBADMSG); - if (cache[i]->init == NULL){ - session->cursor = 0; - session->anchor = cache[i]->update.anchor; - session->size = cache[i]->update.size; - sprintf(dump->info, "%#x", session->anchor); - return (0); + command = cmd_cache_find(*argv); + if (command == NULL) + return (EINVAL); + if (command->constructor == NULL){ + strcpy(vhex->info, "constructor error"); + return (ENOSYS); } - cache[i]->init(argc, argv, session, dump->info); - sprintf(dump->info, "%#x", session->anchor); + tmp = session->anchor; + memset(vhex->info, '\0', CMD_LENGHT_MAX); + command->constructor(argc, argv, session, vhex->info); + if (*vhex->info == '\0') + sprintf(vhex->info, "%#x", session->anchor); + if (tmp != session->anchor) + session->cursor = 0; return (0); } -void command_entry(struct session_s *session, struct dump_s *dump) +// +// command_entry() +// The goal of this part is to parse and execute user's command. +// +void command_entry(struct session_s *session, struct vhex_s *vhex) { char **argv; int argc; int ret; - if (history_update(&dump->history.list, dump->insert.cmd) == 0){ - dump->history.offset = 0; - dump->history.deep += 1; + if (history_update(&vhex->history.list, vhex->insert.cmd) == 0){ + vhex->history.offset = 0; + vhex->history.deep += 1; } - ret = strtotab(&argc, &argv, dump->insert.cmd); - memset(dump->insert.cmd, '\0', CMD_LENGHT_MAX); + ret = strtotab(&argc, &argv, vhex->insert.cmd); + memset(vhex->insert.cmd, '\0', CMD_LENGHT_MAX); if (ret != 0){ - sprintf(dump->info, "error (%d)", ret); + sprintf(vhex->info, "error (%d)", ret); return; } - if (find_command(argc, argv, session, dump) != 0) - strcat(dump->info, "command error"); + if (command_find(argc, argv, session, vhex) != 0) + strcat(vhex->info, "command error"); session->mode = (session->anchor == 0x00000000) ? UNUSED : NORMAL; - session->cursor = 0; strtotab_quit(&argc, &argv); } diff --git a/src/commands/help.c b/src/commands/help.c new file mode 100644 index 0000000..382fae9 --- /dev/null +++ b/src/commands/help.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include + +/* FIXME: write doc !! */ + +// Internal prototype. +static void help_command(int argc, char **argv, struct session_s *session, char *info); + +// Define help command into the cache section. +CMDBLOCK("help", &help_command, +"Help for Vhex version 1.0\n" +"This chapter introduces\noperations available with vhex.\n" +"\n" +"I] Keys mapping\n" +"II] Status bar\n" +"III] Unused mode\n" +"IV] Command mode\n" +"V] Normal mode\n" +"VI] Credits\n" +"VII] Copyright\n" +"\n" +"================================" +"I] Keys mapping\n" +"Move around: [UP], [DOWN]\n" +"Change mode: [OPTN]\n" +"Letter: [ALPHA] + [A ~ Z]\n" +"Letter lock: [SHIFT] + [ALPHA]\n" +"Letter unlock: [ALPHA]\n" +"Number: [0 ~ 9]\n" +"sessions: [F0 ~ F9]\n" +"\n" +"================================" +"II] Status bar\n" +"The first information (at the\nbottom left) display is the\nkeyboard status:\n" +" * [s] : shift mode.\n" +" * [l] : letter mode.\n" +" * [L] : caps lock.\n" +" * [n] : number mode.\n" +"The second information is the\ncommand zone.\n" +"The third information is the\ncurrent mode (unused, normal,\ncommand).\n" +"And the last information is the session's id currently using.\n" +"\n" +"================================" +"III] Unused mode\n" +"This mode is set when the\nsession is not used.\n" +"Basically you can't do a lot of things, but you can enter into\n" +"the command mode using the\n[OPTN] key.\n" +"\n" +"================================" +"IV] Normal mode.\n" +"This mode allows the user to\nmove into the Virtual Memory\n" +"using [UP] and [DOWN].\n" +"Be careful, there is no security" +"and some parts of the Virtual\n" +"Memory can make your\ncalculator crash.\n" +"If a crash occurs, don't worry, you have \"just\" read a\n" +"non-readable space.\n" +"Your machine will continue to\nwork perfectly after\nthe reset.\n" +"\n" +"================================" +"V] Command mode\n" +"The command mode is probably\nthe most important part\nof Vhex.\n" +"It's the only way to move\nquickly into the different part\n" +"of the Virtual Memory.\n" +"To enter in command mode the\nuser can press the [OTPN] key,\n" +"normally a \":#\" appear and\nthe user can write\ncommand.\n" +"All commands currently\nintegrated in Vhex:\n" +" :systab\n" +" :vbrjmp \n" +" :syscall \n" +" :ram \n" +" :rom\n" +" :help \n" +"We invited you to try\n\":help \" if you don't know how a" +" command work.\n" +"Each command typed by the user\nis stored in a history that it\n" +"can access using [UP] and\n[DOWN] keys.\n" +"\n" +"================================" +"VI] Credits\n" +"Special thank to:\n" +" - Lephenixnoir\n" +" - PierrotLL\n" +" - Simon Lothar\n" +" - Kristaba\n" +"And all communities of Planet\nCasio for his help.\n" +"specially to LephenixNoir for\nhis advices and his patience.\n" +"\n" +"================================" +"VII] Copyright\n" +"The Vhex programme use CC0\nlicence.\n" +"It allows anyone to freely\nreuse, improve or modify my\n" +"work for any purpose and\nwithout any legal restrictions, " +"except those required by law.\n"); + +static int get_nb_line(char const *str) +{ + int nb_line; + int cursor; + + if (str == NULL || *str == '\0') + return (-EBADMSG); + cursor = 0; + nb_line = 0; + do { + cursor += 1; + if (cursor >= COLUMN_OFFSET || *str == '\n'){ + nb_line += 1; + cursor = 0; + } + } while (*(++str) != '\0'); + return (nb_line + 1); +} + +static const char *get_line(char const *str, int line) +{ + int cursor; + int nb_line; + + if (line == 0) + return (str); + cursor = 0; + nb_line = 0; + do { + cursor += 1; + if (cursor >= COLUMN_OFFSET || *str == '\n'){ + nb_line += 1; + cursor = 0; + } + } while (*(++str) != '\0' && nb_line < line); + return (str); +} + +static void display_text(char *buf, char const *str, int current_line) +{ + char const *text; + int nb_line; + int cursor; + + text = get_line(str, current_line); + if (*text == '\0') + return; + nb_line = 0; + cursor = 0; + do { + if (*text != '\n'){ + buf[cursor] = *text; + cursor += 1; + } + if (cursor >= COLUMN_OFFSET || *text == '\n'){ + buf[cursor] = '\0'; + print(0, nb_line * FONT_HEIGHT, buf); + nb_line += 1; + cursor = 0; + continue; + } + } while (*(++text) != '\0' && nb_line < LINE_OFFSET); + if (cursor != 0) + print(0, nb_line * FONT_HEIGHT, buf); +} + +static void help_engine(char const *text, int nb_line) +{ + char buf[COLUMN_OFFSET + 1]; + unsigned int key; + int cursor; + int exit; + + exit = 1; + cursor = 0; + while (exit != 0){ + dclear(); + // Display text. + display_text(buf, text, cursor); + + // Display exit info. + dclear_area(0, SCREEN_HEIGHT - FONT_HEIGHT - 2, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + dline_horizontal(SCREEN_HEIGHT - FONT_HEIGHT - 2, 0, SCREEN_WIDTH - 1); + print(0, SCREEN_HEIGHT - FONT_HEIGHT, "press [EXIT]"); + sprintf(buf, "%d/%d", cursor + 1, nb_line + 1); + print(SCREEN_WIDTH - (strlen(buf) * FONT_WIDTH) - 1, SCREEN_HEIGHT - FONT_HEIGHT, buf); + getkey(&key); + if (key == KEY_UP && cursor > 0) + cursor -= 1; + if (key == KEY_DOWN && cursor < nb_line) + cursor += 1; + if (key == KEY_EXIT) + exit = 0; + } +} + +static void help_command(int argc, char **argv, struct session_s *session, char *info) +{ + const struct cmd_info *command; + int nb_line; + + (void)session; + command = cmd_cache_find((argc == 1) ? "help" : argv[1]); + if (command == NULL){ + strcpy(info, "command error"); + return; + } + nb_line = 0; + if (command->man != NULL) + nb_line = get_nb_line(command->man); + if (command->man == NULL || nb_line < 0){ + strcpy(info, "no help entry"); + return; + } + nb_line -= LINE_OFFSET + 1; + if (nb_line < 0) + nb_line = 0; + help_engine(command->man, nb_line); +} diff --git a/src/commands/jump_address.c b/src/commands/jump_address.c new file mode 100644 index 0000000..14dce13 --- /dev/null +++ b/src/commands/jump_address.c @@ -0,0 +1,58 @@ +#include +#include + +// Internal prototype. +static void address_jump(int argc, char **argv, struct session_s *session, char *info); + +// Define the command block into the cache +CMDBLOCK("jmp", &address_jump, +"JMP command help\n" +"This command takes one\nparameter: the address (hexa)\n" +"you would jump into the Virtual Memory.\n" +"\n" +"Be careful, there is no security" +"and some parts of the Virtual\n" +"Memory can make your\ncalculator crash.\n" +"\n" +"If a crash occurs, don't worry, you have \"just\" read a\n" +"non-readable space.\n" +"Your calculator will continue\nto work perfectly after\nthe reset.\n" +"\n" +"Virtual Memory map:\n" +"Area P0 - 2Go - MMU enable\n" +"0x00300000 : add-in header\n" +"0x00300200 : add-in mapping\n" +"0x08000000 : RAM (cache)\n" +"Area P1 - 500Mo - MMU disable\n" +"0x80000000 : ROM (cache)\n" +"0x88000000 : RAM (cache)\n" +"Area P2 - 500Mo - MMU disable\n" +"0xa0000000 : ROM (no cache)\n" +"0xa8000000 : RAM (no cache)\n" +"Area P3 - 500Mo - MMU ebable\n" +"?????? CRASH ??????\n" +"Area P4 - 500Mo - MMU ~enable\n" +"0xe0000000 : Store queue area\n" +"0xe4000000 : MMU disable\n" +"0xe5000000 : On chip RAM\n" +"0xe6000000 : MMU disable\n" +); + +static INLINE int check_address(char *str) +{ + --str; + while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')); + return ((*str != '\0') ? 1 : 0); +} + +/* address_jump() - jump into Virtual Memory. */ +static void address_jump(int argc, char **argv, struct session_s *session, char *info) +{ + if (argc != 2 || check_address(argv[1]) != 0){ + strcpy(info, "arguments error"); + return; + } + // clear the lower bits to force align the address. + // (one instruction takes 2 bytes, so we need to respect the alignment). + session->anchor = atoi_base(argv[1], 16) >> 1 << 1; +} diff --git a/src/commands/jump_ram.c b/src/commands/jump_ram.c new file mode 100644 index 0000000..2bfa095 --- /dev/null +++ b/src/commands/jump_ram.c @@ -0,0 +1,51 @@ +#include +#include + +// Internal prototype. +static void ram_jump(int argc, char **argv, struct session_s *session, char *info); + +/* Define the command block into the cache section. */ +CMDBLOCK("ram", &ram_jump, +"RAM command help\n" +"This function allows user to\njump into different parts of\n" +"the RAM mapped in the Virtual\nMemory.\n" +"\n" +":ram p0\n" +"Jump into the P0 area, basically" +"the user space who is managed\n" +"by the Memory Management\nUnit.\n" +"\n" +":ram p1\n" +"Jump into the RAM mapped in the P1 area; MMU is disabled and\n" +"the area is cached.\n" +"\n" +":ram p2\n" +"Jump into the RAM mapped in the P2 area; MMU is disable " +"and the area is not cached.\n" +"\n" +":ram p4\n" +"Jump into the internal chip\nmemory area; MMU is enabled\n" +"and the area is cached.\n" +); + +/* ram_jump() - jump into the RAM mapped in different parts of the Virtual Memory. */ +static void ram_jump(int argc, char **argv, struct session_s *session, char *info) +{ + if (argc != 2){ + strcpy(info, "argument error"); + return; + } + if (strcmp(argv[1], "p0") && strcmp(argv[1], "p1") + && strcmp(argv[1], "p2") && strcmp(argv[1], "p4")){ + sprintf(info, "bad argument"); + return; + } + if (!strcmp(argv[1], "p0")) + session->anchor = 0x08000000; + if (!strcmp(argv[1], "p1")) + session->anchor = 0x88000000; + if (!strcmp(argv[1], "p2")) + session->anchor = 0xa8000000; + if (!strcmp(argv[1], "p4")) + session->anchor = 0xe5000000; +} diff --git a/src/commands/jump_rom.c b/src/commands/jump_rom.c new file mode 100644 index 0000000..78a4e88 --- /dev/null +++ b/src/commands/jump_rom.c @@ -0,0 +1,44 @@ +#include +#include + +// internal prototype. +static void rom_jump(int argc, char **argv, struct session_s *session, char *info); + +// Define the command into the cache. +CMDBLOCK("rom", &rom_jump, +"ROM command help\n" +"This command allows user to\njump into different parts of\n" +"the ROM mapped in the Virtual\nMemory.\n" +"\n" +":rom addin\n" +"Jump into the dynamic add-in\nmapping area.\n" +"Normaly you can see the\nVhex binary :)\n" +"(see \":help jmp\" to get the\nVirtual Memory map)\n" +"\n" +":rom p1\n" +"Jump into the ROM mapped in\nthe P1 area.\n" +"MMU is disable and the area\nis cached.\n" +"\n" +"rom p2\n" +"Jump into the ROM mapped in\nthe P2 area.\n" +"MMU is disable and the area\nis not cached.\n" +); + +/* rom_jump() - jump into the start of the ROM */ +static void rom_jump(int argc, char **argv, struct session_s *session, char *info) +{ + if (argc != 2){ + strcpy(info, "argument error"); + return; + } + if (strcmp(argv[1], "addin") && strcmp(argv[1], "p1") && strcmp(argv[1], "p2")){ + sprintf(info, "bad argument"); + return; + } + if (!strcmp(argv[1], "addin")) + session->anchor = 0x00300200; + if (!strcmp(argv[1], "p1")) + session->anchor = 0x80000000; + if (!strcmp(argv[1], "p2")) + session->anchor = 0xa0000000; +} diff --git a/src/commands/jump_syscall.c b/src/commands/jump_syscall.c new file mode 100644 index 0000000..ffb89ce --- /dev/null +++ b/src/commands/jump_syscall.c @@ -0,0 +1,120 @@ +#include +#include + +// Internal prototype. +static void syscall_jump(int argc, char **argv, struct session_s *session, char *info); + +/* Define command block into the cache section. */ +CMDBLOCK("syscall", &syscall_jump, +"SYSCALL command help\n" +"Take one parameter: syscall id.\n" +"This command will jump at the\nsyscall's code entry.\n" +"\n" +"Syscall list (not exhaustive):\n" +"0x013 : GLibAddinAppExecutionCheck\n" +"0x014 : GLibGetAddinLibInfo\n" +"0x014 : GLibGetOSVersionInfo\n" +"0x01c : Bdisp_WriteGraph_VRAM\n" +"0x01d : Bdisp_WriteGraph_DD\n" +"0x01e : Bdisp_WriteGraph_DDVRAM\n" +"0x022 : Bdisp_ReadArea_VRAM\n" +"0x023 : Bdisp_ReadArea_DD_OS\n" +"0x024 : Bdisp_GetDisp_DD\n" +"0x026 : DD_GET\n" +"0x028 : Bdisp_PutDisp_DD\n" +"0x030 : Bdisp_DrawLineVRAM\n" +"0x031 : Bdisp_ClearLine_VRAM\n" +"0x118 : Bcre_cychdr\n" +"0x119 : Bdel_cychdr\n" +"0x142 : Bdisp_AllClr_DD\n" +"0x143 : Bdisp_AllClr_VRAM\n" +"0x144 : Bdisp_AllClr_DDVRAM\n" +"0x145 : Bdisp_GetDisp_VRAM\n" +"0x147 : Bdisp_SetPoint_DD\n" +"0x148 : Bdisp_SetPoint_DDVRAM\n" +"0x149 : Bdisp_GetPoint_VRAM\n" +"0x14a : Bdisp_AreaClr_DD\n" +"0x14b : Bdisp_AreaClr_VRAM\n" +"0x14c : Bdisp_AreaClr_DDVRAM\n" +"0x14d : Bdisp_AreaReverseVRAM\n" +"0x11a : Bsta_cychdr\n" +"0x11b : Bstp_cychdr\n" +"0x11f : Bdisp_PutDispArea_DD\n" +"0x1e7 : BfileFLS_CloseFile\n" +"0x218 : flsFindCLose\n" +"0x242 : Bkey_Set_RepeatTime\n" +"0x243 : Bkey_Get_RepeatTime\n" +"0x244 : Bkey_Set_RepeatTime_Default\n" +"0x247 : Bkey_GetKeyWait\n" +"0x24c : Chattering\n" +"0x374 : BMCSRenameVariable\n" +"0x3ed : SetFlagPaturn\n" +"0x3fa : Hmem_SetMMU\n" +"0x420 : BSrl_DummyWAIT\n" +"0x42c : Bfile_OpenFile_OS\n" +"0x42d : Bfile_CloseFile_OS\n" +"0x42e : Bfile_GetMediaFree_OS\n" +"0x42f : Bfile_GetFileSize_OS\n" +"0x431 : Bfile_SeekFile_OS\n" +"0x432 : Bfile_ReadFile_OS\n" +"0x434 : Bfile_CreateEntry\n" +"0x435 : Bfile_WriteFile_OS\n" +"0x439 : Bfile_DeleteEntry\n" +"0x43b : Bfile_FindFirst\n" +"0x43d : Bfile_FindClose\n" +"0x43c : Bfile_FindNext\n" +"0x462 : GetAppName\n" +"0x494 : CallBackAtQuitMainFunction\n" +"0x807 : Locate_OS\n" +"0x82b : MCSPutVar2\n" +"0x830 : MCSOvwDat2\n" +"0x836 : MCSDelVar2\n" +"0x840 : MCSGetDlen2\n" +"0x841 : MCSGetData1\n" +"0x844 : MCSGetCapa\n" +"0x8fe : PopUpWin\n" +"0x808 : Print\n" +"0x809 : PrintRev\n" +"0x80b : PrintRev\n" +"0x80d : PrintRLine\n" +"0x80a : PrintC\n" +"0x80c : PrintLine\n" +"0x813 : SaveDisp\n" +"0x814 : RestoreDisp\n" +"0x90f : GetKey\n" +"0x9ad : PrintXY\n" +"0xacc : free\n" +"0xacd : malloc\n" +"0xc4f : PrintMiniSd\n" +"0xe6b : calloc\n" +"0xe6d : realloc\n" +"0x1032 : Bkey_GetKeyTableInfo\nJumpFunc\n" +); + +static INLINE int check_address(char *str) +{ + --str; + while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')); + return ((*str != '\0') ? 1 : 0); +} + +// +// 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 +// stored at 0x8001007c). +// +static void syscall_jump(int argc, char **argv, struct session_s *session, char *info) +{ + uint32_t *systab; + uint32_t id; + + if (argc != 2 || check_address(argv[1]) != 0){ + strcpy(info, "arguments error"); + return; + } + id = atoi_base(argv[1], 16); + systab = (void*)(*(uint32_t *)0x8001007c); + session->anchor = systab[id]; +} diff --git a/src/commands/jump_systab.c b/src/commands/jump_systab.c new file mode 100644 index 0000000..f2c236f --- /dev/null +++ b/src/commands/jump_systab.c @@ -0,0 +1,29 @@ +#include +#include + +// Internal prototype. +static void systab_jump(int argc, char **argv, struct session_s *session, char *info); + +// Define the command block into the cache +CMDBLOCK("systab", &systab_jump, +"SYSTAB command help\n" +"This function allows user to\njump into the Casio \"syscall\n" +"handler\".\n" +"\n" +"Curiously, Casio doesn't use the" +"TRAPA instruction for handle\n" +"syscall, but jump at\n0x80010070.\n" +"This don't explain why we are\nalways in privileged mode, but\n" +"now we can affirm that Casio\ndo it intentionally.\n" +); + +/* systab_jump() - Jump into the Casio "syscall handler". */ +static void systab_jump(int argc, char **argv, struct session_s *session, char *info) +{ + if (argc != 1){ + strcpy(info, "argument error"); + return; + } + (void)argv; + session->anchor = 0x80010070; +} diff --git a/src/commands/jump_vbr.c b/src/commands/jump_vbr.c new file mode 100644 index 0000000..f40e721 --- /dev/null +++ b/src/commands/jump_vbr.c @@ -0,0 +1,49 @@ +#include +#include + +// Internal prototype +static void vbrjmp(int argc, char **argv, struct session_s *session, char *info); + +// TODO: write doc. +CMDBLOCK("vbrjmp", &vbrjmp, +"VBR JUMP command help\n" +"This command jump into Casio's\nhandlers.\n" +"\n" +"Due to the SH3 / SH4 VBR system\n, there are 3 vectors offset\n" +"called by the processor:\n" +" * exception (VBR + 0x100)\n" +" * tlb miss (VBR + 0x400)\n" +" * interrupt (VBR + 0x600)\n" +"\n" +"You can access to each handler\nusing this command list:\n" +":vbrjmp except VBR + 0x100\n" +":vbrjmp fault VBR + 0x400\n" +":vbrjmp int VBR + 0x600\n" +); + +// +// 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. +// * vbr + 0x400 -> tlb miss. +// * vbr + 0x600 -> interrupts. +// +static void vbrjmp(int argc, char **argv, struct session_s *session, char *info) +{ + if (argc != 2){ + strcpy(info, "arguments error"); + return; + } + if (strcmp(argv[1], "fault") && strcmp(argv[1], "except") && strcmp(argv[1], "int")){ + sprintf(info, "bad argument"); + return; + } + __asm__ volatile ("stc vbr, %0" : "=r"(session->anchor)); + if (!strcmp(argv[1], "except")) + session->anchor += 0x100; + if (!strcmp(argv[1], "fault")) + session->anchor += 0x400; + if (!strcmp(argv[1], "int")) + session->anchor += 0x600; +} diff --git a/src/commands/quit.c b/src/commands/quit.c new file mode 100644 index 0000000..9a3832e --- /dev/null +++ b/src/commands/quit.c @@ -0,0 +1,18 @@ +#include +#include + +// internal prototype. +static void quit(int argc, char **argv, struct session_s *session, char *info); + +// Define the command into the cache. +CMDBLOCK("quit", &quit, NULL); + +/* quit() - switch to UNUSED mode */ +static void quit(int argc, char **argv, struct session_s *session, char *info) +{ + (void)argc; + (void)argv; + strcpy(info, "exit"); + session->mode = UNUSED; + session->anchor = 0x00000000; +} diff --git a/src/commands/ram_jump.c b/src/commands/ram_jump.c deleted file mode 100644 index 1f5235a..0000000 --- a/src/commands/ram_jump.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -void ram_jump(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 2){ - strcpy(info, "arguments error"); - return; - } - if (!strcmp(argv[1], "p0")) - session->anchor = 0x08100000; - if (!strcmp(argv[1], "p1")) - session->anchor = 0x88000000; - if (!strcmp(argv[1], "p2")) - session->anchor = 0xa8000000; - if (!strcmp(argv[1], "p2")) - session->anchor = 0xe6000000; - //FIXME: sh3 size is 0x40000; - session->size = 0x80000; -} diff --git a/src/commands/syscall_jump.c b/src/commands/syscall_jump.c deleted file mode 100644 index c3dc152..0000000 --- a/src/commands/syscall_jump.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -static INLINE int check_address(char *str) -{ - --str; - while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')); - return ((*str != '\0') ? 1 : 0); -} - -void syscall_jump(int argc, char **argv, struct session_s *session, char *info) -{ - uint32_t *systab; - uint32_t id; - - if (argc != 2 || check_address(argv[1]) != 0){ - strcpy(info, "arguments error"); - return; - } - id = atoi_base(argv[1], 16); - systab = (void*)(*(uint32_t *)0x8001007c); - session->anchor = systab[id]; - session->size = 0xffffffff; -} diff --git a/src/commands/vbr_jump.c b/src/commands/vbr_jump.c deleted file mode 100644 index fc46fec..0000000 --- a/src/commands/vbr_jump.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -void vbr_jump(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 2){ - strcpy(info, "arguments error"); - return; - } - __asm__ volatile ("stc vbr, %0" : "=r"(session->anchor)); - if (!strcmp(argv[1], "fault")) - session->anchor += 0x100; - if (!strcmp(argv[1], "except")) - session->anchor += 0x400; - if (!strcmp(argv[1], "int")) - session->anchor += 0x600; - session->size = 2048; -} diff --git a/src/commands/where.c b/src/commands/where.c new file mode 100644 index 0000000..9f11eca --- /dev/null +++ b/src/commands/where.c @@ -0,0 +1,16 @@ +#include +#include + +// internal prototype. +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. */ +static void where(int argc, char **argv, struct session_s *session, char *info) +{ + (void)argc; + (void)argv; + sprintf(info, "%#x", session->anchor + (session->cursor << 1)); +} diff --git a/src/display/intructions.c b/src/display/intructions.c index e7a6f3a..6c5aacc 100644 --- a/src/display/intructions.c +++ b/src/display/intructions.c @@ -3,9 +3,7 @@ #include #include -//TODO: -// - move me ! -// - attribute always inline ? +//TODO: move me ? static INLINE int get_shift(uint16_t mask) { int i; @@ -17,7 +15,8 @@ static INLINE int get_shift(uint16_t mask) return (i); } -static void get_mnemonic(char *str, uint16_t bytes_code) +/* get_instructions() - find mnemonic and instruction argument(s) */ +static void get_instructions(char *str, uint16_t bytes_code) { int shift[ARGUMENTS_MAX]; size_t i; @@ -40,9 +39,13 @@ static void get_mnemonic(char *str, uint16_t bytes_code) (bytes_code & opcode[i].arg_mask[2]) >> shift[2]); } -//TODO: -// - resize buffer. -// - handle multiple modes. +// +// display_instructions() +// Translate "on-the-fly" each binary instructions stored at +// the anchor location. +// Almost instructions can be translated; only FPU instructions +// is not handled because it's not available on the SH3 based MPU. +// void display_instructions(const struct session_s *session) { char mnemonic[128]; @@ -60,9 +63,9 @@ void display_instructions(const struct session_s *session) return; } y = -1; - area = (void*)(session->anchor + session->cursor); + area = (void*)(session->anchor + (session->cursor << 1)); while (++y < LINE_OFFSET){ - get_mnemonic(mnemonic, area[y]); + get_instructions(mnemonic, area[y]); sprintf(buf, "%4x %4x %s", &(area[y]), area[y], mnemonic); print(0, y * FONT_HEIGHT, buf); } diff --git a/src/display/metainfos.c b/src/display/metainfos.c index 0544680..4cc000f 100644 --- a/src/display/metainfos.c +++ b/src/display/metainfos.c @@ -2,7 +2,8 @@ #include #include -void display_metainfos(const struct dump_s *dump, const struct session_s *session) +/* display_metainfo() - display the "status" bar and display user's information */ +void display_metainfos(const struct vhex_s *vhex, const struct session_s *session) { static const char *mode_name[] = {"unused", "command", "normal", "free"}; static const char insert_name[] = {'l', 'L', 'n', 's'}; @@ -14,13 +15,13 @@ void display_metainfos(const struct dump_s *dump, const struct session_s *sessio dline_horizontal(SCREEN_HEIGHT - FONT_HEIGHT - 2, 0, SCREEN_WIDTH - 1); // Display informations - sprintf(buf, "[%s][%d]", mode_name[session->mode], dump->current_session); + sprintf(buf, "[%s][%d]", mode_name[session->mode], vhex->current_session); print(SCREEN_WIDTH - (strlen(buf) * FONT_WIDTH) - 1, SCREEN_HEIGHT - FONT_HEIGHT, buf); if (session->mode == COMMAND) - sprintf(buf, "[%c]:%s#", insert_name[dump->insert.mode], dump->insert.cmd); + sprintf(buf, "[%c]:%s#", insert_name[vhex->insert.mode], vhex->insert.cmd); else { - tmp = (*dump->info == '\0') ? dump->insert.cmd : dump->info; - sprintf(buf, "[%c] %s", insert_name[dump->insert.mode], tmp); + tmp = (*vhex->info == '\0') ? vhex->insert.cmd : vhex->info; + sprintf(buf, "[%c] %s", insert_name[vhex->insert.mode], tmp); } print(0, SCREEN_HEIGHT - FONT_HEIGHT, buf); } diff --git a/src/history.c b/src/history.c index feb63f5..b549b63 100644 --- a/src/history.c +++ b/src/history.c @@ -8,10 +8,17 @@ #include #include -// TODO:write docs ! -// *-* -// |A| --> -// *-* +//--- +// history_update() +// Add new history node to the chained list. This is a singly +// linked list, but the node insertion from the beginning. +// +// Exemple: add node A, B, C and D +// 1. A -> NULL +// 2. B -> A -> NULL +// 3. C -> B -> A -> NULL +// 4. D -> C -> B -> A -> NULL +//--- int history_update(struct node **list, const char *data) { void *swap; @@ -29,6 +36,11 @@ int history_update(struct node **list, const char *data) return (0); } +// +// history_get() +// primitive function which will return the data stored in +// the "offset" position in the list. +// const void *history_get(struct node *list, off_t offset) { if (list == NULL) @@ -38,6 +50,10 @@ const void *history_get(struct node *list, off_t offset) return (history_get(list->next, offset - 1)); } +// +// history_quit() +// Free all allocated memory. +// void history_quit(struct node **list) { if (list == NULL || *list == NULL) diff --git a/src/keys.c b/src/keys.c index b4dbad2..7265287 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1,9 +1,13 @@ #include #include -#include +#include #include -static int check_session(unsigned int key, struct dump_s *dump) +// +// check_session() +// Check if the pressed key is [Fx], and switch the current session. +// +static int check_session(unsigned int key, struct vhex_s *vhex) { static const unsigned int keys_switch[SESSIONS_SLOT] = { KEY_F1, KEY_F2, KEY_F3, @@ -14,46 +18,52 @@ static int check_session(unsigned int key, struct dump_s *dump) i = -1; while (++i < SESSIONS_SLOT && key != keys_switch[i]); if (i < SESSIONS_SLOT){ - dump->current_session = i; + vhex->current_session = i; return (0); } return (-1); } -static int check_insert(unsigned int key, struct dump_s *dump, struct session_s *session) +// +// 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. +// +static int check_special(unsigned int key, struct vhex_s *vhex, struct session_s *session) { if (!(key == KEY_OPTN || key == KEY_SHIFT || key == KEY_ALPHA)) return (-1); - if (dump->insert.mode == LETTER) - dump->insert.mode = NUMBER; + if (vhex->insert.mode == LETTER) + vhex->insert.mode = NUMBER; if (key == KEY_OPTN){ if (session->mode != COMMAND){ - memset(dump->info, '\0', CMD_LENGHT_MAX); + memset(vhex->info, '\0', CMD_LENGHT_MAX); session->mode = COMMAND; save_window(1); } else - //TODO: restore FREE mode ? session->mode = (session->anchor == 0x00000000) ? UNUSED : NORMAL; } if (key == KEY_SHIFT) - dump->insert.mode = (dump->insert.mode == SHIFT) ? NUMBER : SHIFT; + vhex->insert.mode = (vhex->insert.mode == SHIFT) ? NUMBER : SHIFT; if (key == KEY_ALPHA){ - if (dump->insert.mode == SHIFT){ - dump->insert.mode = CAPS_LOCK; - return (0); - } - if (dump->insert.mode == CAPS_LOCK){ - dump->insert.mode = NUMBER; - return (0); - } - dump->insert.mode = LETTER; + //TODO: update this. + if (vhex->insert.mode == SHIFT) + vhex->insert.mode = CAPS_LOCK; + else if (vhex->insert.mode == CAPS_LOCK) + vhex->insert.mode = NUMBER; + else + vhex->insert.mode = LETTER; } return (0); } -//TODO: find better way to do the job (?) -static int check_cmd(unsigned int key, struct dump_s *dump, struct session_s *session) +// +// check_alphanum() +// Check if the key pressed is an alphanumeric character and update the user command. +// +/* TODO: find better way to do the job (?) */ +static int check_alphanum(unsigned int key, struct vhex_s *vhex, struct session_s *session) { static const unsigned int keys_alpha[] = { KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, @@ -74,67 +84,81 @@ static int check_cmd(unsigned int key, struct dump_s *dump, struct session_s *se if (session->mode != COMMAND) return (-1); i = -1; - size = strlen(dump->insert.cmd); - end = (dump->insert.mode == NUMBER) ? 10 : 26; - buf = (dump->insert.mode == NUMBER) ? '0' : 'a'; - cache = (dump->insert.mode == NUMBER) ? (void *)keys_number : (void *)keys_alpha; + size = strlen(vhex->insert.cmd); + end = (vhex->insert.mode == NUMBER) ? 10 : 26; + cache = (vhex->insert.mode == NUMBER) ? (void *)keys_number : (void *)keys_alpha; while (++i < end && key != cache[i]); if (i >= end) return (-1); if (size < CMD_LENGHT_MAX){ - buf += i; - strcat(dump->insert.cmd, &buf); + buf = (vhex->insert.mode == NUMBER) ? '0' + i : 'a' + i; + strcat(vhex->insert.cmd, &buf); } - dump->history.offset = 0; + vhex->history.offset = 0; return (0); } -static int check_arrow(unsigned int key, struct dump_s *dump, struct session_s *session) +// +// check_arrow() +// Check if the key pressed is an arrow key. +// Here we just check left and right key, but they do not have the same action when +// the mode is COMMAND or not; basically: +// * COMMAND : Udpate the user's command using the history. +// * NORMAL : Move the anchor cursor. +// * UNUSED : Do nothing. +// +static int check_arrow(unsigned int key, struct vhex_s *vhex, struct session_s *session) { if (key != KEY_UP && key != KEY_DOWN) return (-1); if (session->mode == COMMAND - && ((key == KEY_UP && dump->history.offset < dump->history.deep) - || (key == KEY_DOWN && dump->history.offset > 0))){ - if (dump->history.offset == 0) - strcpy(dump->insert.backup, dump->insert.cmd); - dump->history.offset += (key == KEY_UP) ? 1 : -1; - if (dump->history.offset > 0) - strcpy(dump->insert.cmd, - history_get(dump->history.list, dump->history.offset - 1)); + && ((key == KEY_UP && vhex->history.offset < vhex->history.deep) + || (key == KEY_DOWN && vhex->history.offset > 0))){ + if (vhex->history.offset == 0) + strcpy(vhex->insert.backup, vhex->insert.cmd); + vhex->history.offset += (key == KEY_UP) ? 1 : -1; + if (vhex->history.offset > 0) + strcpy(vhex->insert.cmd, + history_get(vhex->history.list, vhex->history.offset - 1)); else - strcpy(dump->insert.cmd, dump->insert.backup); - } - if (session->mode != UNUSED && session->mode != COMMAND){ - if (key == KEY_UP && session->cursor > 0) - session->cursor -= INSTRUCTION_SIZE; - if (key == KEY_DOWN && session->cursor < session->size - LINE_OFFSET) - session->cursor += INSTRUCTION_SIZE; + strcpy(vhex->insert.cmd, vhex->insert.backup); } + if (session->mode == NORMAL) + session->cursor += (key == KEY_UP) ? -1 : 1; return (0); } -void key_handling(struct dump_s *dump, struct session_s *session, unsigned int key) +// +// key_handling() +// We need to do several things here; the Casio getkey function handles [SHIFT], [ALPHA] +// and [MENU] key and it is able to do some special thing using the key combination like +// shutdown the calculator, change the brightness or return to the main menu using. +// But when the user press on [SHIFT] or [ALPHA], getkey() return not the same value for +// the same key (and we cannot know the "status"). +// So we need to "emulate" the getkey's status and execute the appropriate action with +// the key returned by Casio. +// +void key_handling(struct vhex_s *vhex, struct session_s *session, unsigned int key) { size_t size; - if (check_session(key, dump) == 0 - || check_insert(key, dump, session) == 0 - || check_arrow(key, dump, session) == 0 - || check_cmd(key, dump, session) == 0 + if (check_session(key, vhex) == 0 + || check_special(key, vhex, session) == 0 + || check_arrow(key, vhex, session) == 0 + || check_alphanum(key, vhex, session) == 0 || session->mode != COMMAND) return; if (key == KEY_DEL || key == KEY_INS){ - size = strlen(dump->insert.cmd); + size = strlen(vhex->insert.cmd); if (size > 0) - strncpy(dump->insert.cmd, dump->insert.cmd, size - 1); + strncpy(vhex->insert.cmd, vhex->insert.cmd, size - 1); } if (key == KEY_SPACE) - strcat(dump->insert.cmd, " "); + strcat(vhex->insert.cmd, " "); if (key == KEY_QUOTE) - strcat(dump->insert.cmd, "\""); + strcat(vhex->insert.cmd, "\""); if (key == KEY_ENTER){ - dump->insert.mode = NUMBER; - command_entry(session, dump); + vhex->insert.mode = NUMBER; + command_entry(session, vhex); } } diff --git a/src/main.c b/src/main.c index b48e784..74f9613 100644 --- a/src/main.c +++ b/src/main.c @@ -3,47 +3,47 @@ #include // -// dump_constructor() +// vhex_constructor() // Initialize all information needed by the add-in: session, // GetKey configuration, ... // -static void dump_constructor(struct dump_s *dump) +static void vhex_constructor(struct vhex_s *vhex) { size_t i; i = -1; - memset(dump->info, '\0', CMD_LENGHT_MAX); - memset(dump->insert.cmd, '\0', CMD_LENGHT_MAX); + memset(vhex->info, '\0', CMD_LENGHT_MAX); + memset(vhex->insert.cmd, '\0', CMD_LENGHT_MAX); //TODO: Auto detect GetKey configuration !! - dump->insert.mode = NUMBER; - dump->history.list = NULL; - dump->history.offset = 0; - dump->history.deep = 0; - dump->current_session = 0; + vhex->insert.mode = NUMBER; + vhex->history.list = NULL; + vhex->history.offset = 0; + vhex->history.deep = 0; + vhex->current_session = 0; while (++i < SESSIONS_SLOT){ - dump->session[i].mode = UNUSED; - dump->session[i].anchor = 0x00000000; + vhex->session[i].mode = UNUSED; + vhex->session[i].anchor = 0x00000000; } } // // main() -// "user" entry, but we need initialize some information before +// User entry, but we need to initialize some information before // starting the "main loop". // int main(void) { - struct dump_s dump; + struct vhex_s vhex; unsigned int key; key = 0; - dump_constructor(&dump); + vhex_constructor(&vhex); while (1){ dclear(); - display_instructions(&dump.session[dump.current_session]); - display_metainfos(&dump, &dump.session[dump.current_session]); + display_instructions(&vhex.session[vhex.current_session]); + display_metainfos(&vhex, &vhex.session[vhex.current_session]); getkey(&key); - key_handling(&dump, &dump.session[dump.current_session], key); + key_handling(&vhex, &vhex.session[vhex.current_session], key); } return (0); } diff --git a/src/string/atoi_base.c b/src/string/atoi_base.c index 59ba1f6..f949050 100644 --- a/src/string/atoi_base.c +++ b/src/string/atoi_base.c @@ -8,6 +8,11 @@ static INLINE int check_base(char n, int base) return ((max < n)); } +// +// atoi_base() +// Wrapped atoi function that takes the base which the number +// (stored in the string) are encoded +// uint32_t atoi_base(char const *str, int base) { uint32_t result; diff --git a/src/string/strtotab.c b/src/string/strtotab.c index f84ecf2..a5efe7c 100644 --- a/src/string/strtotab.c +++ b/src/string/strtotab.c @@ -1,8 +1,8 @@ #ifndef DEBUG -# include +//# include # include #else -# include "commands.h" +//# include "commands.h" # include # include #endif @@ -37,8 +37,8 @@ char const *str, int *counter) // // parser_get_inibitor() -// This function will get the content of an inibitor (and check if the -// inibitor charactere are alone or not). +// This function will get the content of an inhibitor (and check if the +// inhibitor characteres are alone or not). // static ssize_t parser_get_inibitor(char ***tab, size_t *tab_pos, char const *str, int *counter) @@ -62,8 +62,8 @@ char const *str, int *counter) // // parser_setup_arg() -// This function remove useless spaces, tabs and handle '\"' inibithor. -// Return the number of word(s) stored in `str`. +// This function removes useless spaces, tabs and handle '\"' inhibitor. +// Return the number of word(s) stored in "str". // static int parser_entry(char ***tab, char const *str) { @@ -91,8 +91,10 @@ static int parser_entry(char ***tab, char const *str) return (counter); } -//TODO: -// - write doc ! +// +// strtotab() +// Generate word table and indicated the number of word find in the string. +// int strtotab(int *argc, char ***argv, char const *str) { int i; @@ -124,6 +126,7 @@ int strtotab(int *argc, char ***argv, char const *str) return (0); } +/* strtotab() - Free all allocated memory generated by "strtotab()" */ void strtotab_quit(int *argc, char ***argv) { if (argc == NULL || argv == NULL) diff --git a/src/syscalls.s b/src/syscalls.s index e1a9a07..70c827b 100644 --- a/src/syscalls.s +++ b/src/syscalls.s @@ -1,9 +1,9 @@ .global _casio_GetKey .global _casio_PrintMini .global _casio_Bdisp_PutDisp_DD -.global _casio_Bdisp_AllClr_DDVRAM +.global _casio_Bdisp_AllClr_VRAM .global _casio_Bdisp_DrawLine_VRAM -.global _casio_Bdisp_AreaClr_DDVRAM +.global _casio_Bdisp_AreaClr_VRAM .global _casio_RestoreDisp .global _casio_SaveDisp .global _casio_Malloc @@ -12,9 +12,9 @@ .type _casio_GetKey, @function .type _casio_PrintMini, @function .type _casio_Bdisp_PutDisp_DD, @function -.type _casio_Bdisp_AllClr_DDVRAM, @function +.type _casio_Bdisp_AllClr_VRAM, @function .type _casio_Bdisp_DrawLine_VRAM, @function -.type _casio_Bdisp_AreaClr_DDVRAM, @function +.type _casio_Bdisp_AreaClr_VRAM, @function .type _casio_RestoreDisp, @function .type _casio_SaveDisp, @function .type _casio_Malloc, @function @@ -33,7 +33,7 @@ _casio_PrintMini: jmp @r1 nop -_casio_Bdisp_AllClr_DDVRAM: +_casio_Bdisp_AllClr_VRAM: mov.l .syscall_tab, r1 mov.l .sys_clear, r0 jmp @r1 @@ -51,7 +51,7 @@ _casio_Bdisp_DrawLine_VRAM: jmp @r1 nop -_casio_Bdisp_AreaClr_DDVRAM: +_casio_Bdisp_AreaClr_VRAM: mov.l .syscall_tab, r1 mov.l .sys_clear_area, r0 jmp @r1 @@ -89,7 +89,7 @@ _casio_Free: .sys_getkey: .long 0x0000090f .sys_display: .long 0x00000028 .sys_printMini: .long 0x00000c4f -.sys_clear_area: .long 0x0000014c +.sys_clear_area: .long 0x0000014b .sys_restore_disp: .long 0x00000814 .sys_save_disp: .long 0x00000813 .sys_malloc: .long 0x00000acd diff --git a/tests/internal.h b/tests/internal.h index 71df355..ff3b006 100644 --- a/tests/internal.h +++ b/tests/internal.h @@ -8,6 +8,7 @@ // status_t - all status available for hook. // * FAIL_NONE : force malloc to work normaly. // * FAIL_NEXT : force the next call of malloc to return NULL. +// * FAIL_NEXT_DYN : force X-nth call of malloc to return NULL. // * FAIL_ALWAYS : force all malloc to return NULL. // typedef enum status_e diff --git a/tests/malloc_hook.c b/tests/malloc_hook.c index 4d16ab4..fd54d84 100644 --- a/tests/malloc_hook.c +++ b/tests/malloc_hook.c @@ -73,8 +73,9 @@ static void *my_malloc_hook(size_t size, const void *caller) // This function is the only way to interact with the hook; it will // define the behavior of malloc: // * FAIL_NEXT : force the next call of malloc to return NULL. +// * FAIL_NEXT_DYN : force X-nth call of malloc to return NULL. // * FAIL_ALWAYS : force all malloc return NULL. -// * NORMAL : force malloc to work normally. +// * FAIL_NONE : force malloc to work normally. // void malloc_hook_update(status_t status, ...) {