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.
This commit is contained in:
yann MAGNIN 2019-06-14 14:49:13 +02:00
parent 7a0e037705
commit 76aeea1fa5
35 changed files with 1054 additions and 639 deletions

481
LICENSE
View File

@ -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
reasonfor example, because of any applicable exception or limitation to copyrightthen
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.

View File

@ -5,7 +5,7 @@
# ---
include global.mk
NAME := dump
NAME := vhex
EXEC := $(NAME).g1a
HEADER := -Iinclude
DEBUG := link_map.txt

View File

@ -1,3 +1,46 @@
# vhex
# Vhex disassembler
Vhex is a GUI, Vim based, disassembler for fx9860g.
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 <id>` jump to the syscall function.
* `ram <zone>` jump to the ram mapped in zone (p0,p1,p2,p3,p4).
* `jmp <address>` 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

View File

@ -22,6 +22,10 @@ SECTIONS
.rodata : SUBALIGN(4) {
*(.rodata)
. = ALIGN(4);
_bcmd_cache = . ;
*(.cmd.cache)
_ecmd_cache = . ;
} > rom

View File

@ -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/

37
include/command.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef __COMMANDS_H__
# define __COMMANDS_H__
#include <stddef.h>
#include <stdint.h>
#include <utils.h>
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__*/

View File

@ -1,35 +0,0 @@
#ifndef __COMMANDS_H__
# define __COMMANDS_H__
#include <stddef.h>
#include <stdint.h>
#include <utils.h>
//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__*/

View File

@ -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

View File

@ -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__*/

View File

@ -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.

View File

@ -1,19 +0,0 @@
#include <commands.h>
#include <string.h>
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;
}

20
src/commands/cache.c Normal file
View File

@ -0,0 +1,20 @@
#include <command.h>
#include <string.h>
// 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]);
}

View File

@ -1,61 +1,76 @@
#include <commands.h>
#include <command.h>
#include <string.h>
#include <errno.h>
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);
}

216
src/commands/help.c Normal file
View File

@ -0,0 +1,216 @@
#include <command.h>
#include <syscalls.h>
#include <string.h>
#include <errno.h>
/* 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 <zone>\n"
" :syscall <id>\n"
" :ram <zone>\n"
" :rom\n"
" :help <command>\n"
"We invited you to try\n\":help <cmd>\" 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);
}

View File

@ -0,0 +1,58 @@
#include <command.h>
#include <string.h>
// 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;
}

51
src/commands/jump_ram.c Normal file
View File

@ -0,0 +1,51 @@
#include <command.h>
#include <string.h>
// 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;
}

44
src/commands/jump_rom.c Normal file
View File

@ -0,0 +1,44 @@
#include <command.h>
#include <string.h>
// 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;
}

120
src/commands/jump_syscall.c Normal file
View File

@ -0,0 +1,120 @@
#include <command.h>
#include <string.h>
// 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];
}

View File

@ -0,0 +1,29 @@
#include <command.h>
#include <string.h>
// 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;
}

49
src/commands/jump_vbr.c Normal file
View File

@ -0,0 +1,49 @@
#include <command.h>
#include <string.h>
// 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;
}

18
src/commands/quit.c Normal file
View File

@ -0,0 +1,18 @@
#include <command.h>
#include <string.h>
// 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;
}

View File

@ -1,20 +0,0 @@
#include <commands.h>
#include <string.h>
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;
}

View File

@ -1,24 +0,0 @@
#include <commands.h>
#include <string.h>
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;
}

View File

@ -1,18 +0,0 @@
#include <commands.h>
#include <string.h>
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;
}

16
src/commands/where.c Normal file
View File

@ -0,0 +1,16 @@
#include <command.h>
#include <string.h>
// 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));
}

View File

@ -3,9 +3,7 @@
#include <opcode.h>
#include <string.h>
//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);
}

View File

@ -2,7 +2,8 @@
#include <syscalls.h>
#include <string.h>
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);
}

View File

@ -8,10 +8,17 @@
#include <string.h>
#include <errno.h>
// 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)

View File

@ -1,9 +1,13 @@
#include <utils.h>
#include <syscalls.h>
#include <commands.h>
#include <command.h>
#include <string.h>
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);
}
}

View File

@ -3,47 +3,47 @@
#include <syscalls.h>
//
// 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);
}

View File

@ -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;

View File

@ -1,8 +1,8 @@
#ifndef DEBUG
# include <commands.h>
//# include <commands.h>
# include <syscalls.h>
#else
# include "commands.h"
//# include "commands.h"
# include <stdlib.h>
# include <stdio.h>
#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)

View File

@ -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

View File

@ -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

View File

@ -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, ...)
{