mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2024-12-29 13:03:37 +01:00
fxos: remove fxos from this repository
The tool is now hosted on its own repository Lephenixnoir/fxos.
This commit is contained in:
parent
b29eea1df0
commit
eeeb0fa6b1
28 changed files with 10 additions and 3479 deletions
27
Makefile
27
Makefile
|
@ -24,15 +24,8 @@ bin = $(TARGETS:%=bin/%)
|
||||||
|
|
||||||
# fxconv has no sources files because it's written in Python, and fxsdk has no
|
# fxconv has no sources files because it's written in Python, and fxsdk has no
|
||||||
# source either because it's written in Bash.
|
# source either because it's written in Bash.
|
||||||
src = $(wildcard $1/*.c)
|
src-fxg1a := $(wildcard fxg1a/*.c)
|
||||||
src-fxg1a := $(call src,fxg1a)
|
obj-fxg1a := $(src-fxg1a:%=build/%.o)
|
||||||
src-fxos := $(call src,fxos)
|
|
||||||
lex-fxos := $(wildcard fxos/*.l)
|
|
||||||
|
|
||||||
obj = $($1:%=build/%.o)
|
|
||||||
lex = $($1:%.l=build/%.yy.c.o)
|
|
||||||
obj-fxg1a := $(call obj,src-fxg1a)
|
|
||||||
obj-fxos := $(call obj,src-fxos) $(call lex,lex-fxos)
|
|
||||||
|
|
||||||
# Sed command to copy install path to fxsdk.sh. On Mac OS, BSD sed is used so
|
# Sed command to copy install path to fxsdk.sh. On Mac OS, BSD sed is used so
|
||||||
# we need to do it a bit differently with a printf helper to insert a literal
|
# we need to do it a bit differently with a printf helper to insert a literal
|
||||||
|
@ -48,7 +41,6 @@ all: $(bin)
|
||||||
|
|
||||||
all-fxsdk: bin/fxsdk.sh
|
all-fxsdk: bin/fxsdk.sh
|
||||||
all-fxg1a: bin/fxg1a
|
all-fxg1a: bin/fxg1a
|
||||||
all-fxos: bin/fxos
|
|
||||||
|
|
||||||
# Explicit targets
|
# Explicit targets
|
||||||
|
|
||||||
|
@ -56,8 +48,6 @@ bin/fxsdk.sh: fxsdk/fxsdk.sh | bin/
|
||||||
sed -e $(sed) $< > $@
|
sed -e $(sed) $< > $@
|
||||||
bin/fxg1a: $(obj-fxg1a) | bin/
|
bin/fxg1a: $(obj-fxg1a) | bin/
|
||||||
gcc $^ -o $@ $(lflags)
|
gcc $^ -o $@ $(lflags)
|
||||||
bin/fxos: $(obj-fxos) | bin/
|
|
||||||
gcc $^ -o $@ $(lflags)
|
|
||||||
|
|
||||||
bin/:
|
bin/:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
@ -70,12 +60,6 @@ build/%.c.o: %.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
gcc -c $< -o $@ $(cflags) $(dflags)
|
gcc -c $< -o $@ $(cflags) $(dflags)
|
||||||
|
|
||||||
# Flex lexers for the fxos database
|
|
||||||
build/fxos/lexer-%.yy.c: fxos/lexer-%.l
|
|
||||||
flex -o $@ -s $<
|
|
||||||
build/fxos/lexer-%.yy.c.o: build/fxos/lexer-%.yy.c
|
|
||||||
gcc -c $< -o $@ $(cflags) -Wno-unused-function $(dflags) -I fxos
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Dependency system, misc.
|
# Dependency system, misc.
|
||||||
#
|
#
|
||||||
|
@ -91,8 +75,6 @@ Makefile.cfg:
|
||||||
|
|
||||||
.PHONY: all clean distclean
|
.PHONY: all clean distclean
|
||||||
|
|
||||||
.PRECIOUS: build/fxos/lexer-%.yy.c
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Installing
|
# Installing
|
||||||
#
|
#
|
||||||
|
@ -110,7 +92,6 @@ install: $(bin)
|
||||||
install -d $(PREFIX)/bin
|
install -d $(PREFIX)/bin
|
||||||
install -d $(PREFIX)/share/fxsdk
|
install -d $(PREFIX)/share/fxsdk
|
||||||
install $(bin:bin/fxsdk.sh=) $(m755) $(PREFIX)/bin
|
install $(bin:bin/fxsdk.sh=) $(m755) $(PREFIX)/bin
|
||||||
install fxos/*.txt $(m644) $(PREFIX)/share/fxsdk
|
|
||||||
install -d $(PREFIX)/share/fxsdk/assets
|
install -d $(PREFIX)/share/fxsdk/assets
|
||||||
install fxsdk/assets/* $(m644) $(PREFIX)/share/fxsdk/assets
|
install fxsdk/assets/* $(m644) $(PREFIX)/share/fxsdk/assets
|
||||||
install bin/fxsdk.sh $(m755) $(PREFIX)/bin/fxsdk
|
install bin/fxsdk.sh $(m755) $(PREFIX)/bin/fxsdk
|
||||||
|
@ -118,7 +99,7 @@ install: $(bin)
|
||||||
install fxconv/fxconv.py $(m644) $(PREFIX)/bin
|
install fxconv/fxconv.py $(m644) $(PREFIX)/bin
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(PREFIX)/bin/{fxsdk,fxg1a,fxos,fxconv,fxconv.py}
|
rm -f $(PREFIX)/bin/{fxsdk,fxg1a,fxconv,fxconv.py}
|
||||||
rm -rf $(PREFIX)/share/fxsdk
|
rm -rf $(PREFIX)/share/fxsdk
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -127,8 +108,6 @@ uninstall:
|
||||||
|
|
||||||
clean-fxg1a:
|
clean-fxg1a:
|
||||||
@rm -rf build/fxg1a
|
@rm -rf build/fxg1a
|
||||||
clean-fxos:
|
|
||||||
@rm -rf build/fxos
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf build
|
@rm -rf build
|
||||||
|
|
20
README.md
20
README.md
|
@ -15,7 +15,10 @@ favorite operating system.
|
||||||
|
|
||||||
## Tool description
|
## Tool description
|
||||||
|
|
||||||
### Project management (_fxsdk_)
|
A tool called fxos used to live here and has now moved to [its own
|
||||||
|
repository](/Lephenixnoir/fxos).
|
||||||
|
|
||||||
|
**Project management (_fxsdk_)**
|
||||||
|
|
||||||
`fxsdk` lets you set up projects almost instantly with a default folder
|
`fxsdk` lets you set up projects almost instantly with a default folder
|
||||||
structure and a working Makefile linking against gint for both fx-9860G and
|
structure and a working Makefile linking against gint for both fx-9860G and
|
||||||
|
@ -28,7 +31,7 @@ with the role and description of each option.
|
||||||
`fxsdk` only writes files at project creation time, so you keep control over
|
`fxsdk` only writes files at project creation time, so you keep control over
|
||||||
your build system and configuration - it just helps you get started faster.
|
your build system and configuration - it just helps you get started faster.
|
||||||
|
|
||||||
### G1A file generation (_fxg1a_)
|
**G1A file generation (_fxg1a_)**
|
||||||
|
|
||||||
`fxg1a` is a versatile g1a file editor that creates, edits and dumps the header
|
`fxg1a` is a versatile g1a file editor that creates, edits and dumps the header
|
||||||
of fx-9860G add-ins files. It is used to build a g1a file out of a binary
|
of fx-9860G add-ins files. It is used to build a g1a file out of a binary
|
||||||
|
@ -37,22 +40,12 @@ program.
|
||||||
It supports PNG icons, checking the validity and checksums of the header,
|
It supports PNG icons, checking the validity and checksums of the header,
|
||||||
repairing broken headers and dumping both the application data and icon.
|
repairing broken headers and dumping both the application data and icon.
|
||||||
|
|
||||||
### Data conversion (_fxconv_)
|
**Data conversion (_fxconv_)**
|
||||||
|
|
||||||
`fxconv` is a tool that interacts specifically with gint. It converts data
|
`fxconv` is a tool that interacts specifically with gint. It converts data
|
||||||
files such as images and fonts into gint-specific format and embeds the result
|
files such as images and fonts into gint-specific format and embeds the result
|
||||||
into object files that expose a single variable.
|
into object files that expose a single variable.
|
||||||
|
|
||||||
### OS disassembly and study (_fxos_)
|
|
||||||
|
|
||||||
`fxos` is a powerful disassembler and OS fiddling tool. It knows the structure
|
|
||||||
of OS files and can extract metadata, language information and syscalls through
|
|
||||||
a simple command-line interface.
|
|
||||||
|
|
||||||
Its key feature is the production of annotated assembler listings where
|
|
||||||
syscalls invocations and peripheral registers are identified and named. This
|
|
||||||
makes it a lot easier to climb back abstraction levels from the code.
|
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
|
||||||
The fxSDK is platform-agnostic; a single install will cover any target
|
The fxSDK is platform-agnostic; a single install will cover any target
|
||||||
|
@ -69,7 +62,6 @@ Broadly, you will need:
|
||||||
* `fxsdk` if you want to benefit from the automated project setup
|
* `fxsdk` if you want to benefit from the automated project setup
|
||||||
* `fxg1a` if you want to compile add-ins for fx-9860G
|
* `fxg1a` if you want to compile add-ins for fx-9860G
|
||||||
* `fxconv` if you want to compile gint or develop add-ins with it
|
* `fxconv` if you want to compile gint or develop add-ins with it
|
||||||
* `fxos` if you want to disassemble or study OS dumps
|
|
||||||
|
|
||||||
Each tool can be enabled or disabled with `--enable-<tool>` and
|
Each tool can be enabled or disabled with `--enable-<tool>` and
|
||||||
`--disable-<tool>`. For a default build you need no arguments:
|
`--disable-<tool>`. For a default build you need no arguments:
|
||||||
|
|
6
configure
vendored
6
configure
vendored
|
@ -10,7 +10,6 @@ PREFIX="$HOME/.local"
|
||||||
BUILD_fxsdk=1
|
BUILD_fxsdk=1
|
||||||
BUILD_fxconv=1
|
BUILD_fxconv=1
|
||||||
BUILD_fxg1a=1
|
BUILD_fxg1a=1
|
||||||
BUILD_fxos=1
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tool name checking
|
# Tool name checking
|
||||||
|
@ -20,8 +19,7 @@ check()
|
||||||
{
|
{
|
||||||
[[ $1 = "fxsdk" ]] ||
|
[[ $1 = "fxsdk" ]] ||
|
||||||
[[ $1 = "fxconv" ]] ||
|
[[ $1 = "fxconv" ]] ||
|
||||||
[[ $1 = "fxg1a" ]] ||
|
[[ $1 = "fxg1a" ]]
|
||||||
[[ $1 = "fxos" ]]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -38,7 +36,6 @@ Tool selection:
|
||||||
"fxsdk" Command-line options (you generally want this)
|
"fxsdk" Command-line options (you generally want this)
|
||||||
"fxconv" Asset conversion for gint (or any 4-aligned-VRAM system)
|
"fxconv" Asset conversion for gint (or any 4-aligned-VRAM system)
|
||||||
"fxg1a" G1A file wrapper, editor and analyzer
|
"fxg1a" G1A file wrapper, editor and analyzer
|
||||||
"fxos" OS fiddling tool, including syscall disassembly
|
|
||||||
|
|
||||||
--enable-<tool> Build and install the selected tool [default]
|
--enable-<tool> Build and install the selected tool [default]
|
||||||
--disable-<tool> Do not build or install the selected tool
|
--disable-<tool> Do not build or install the selected tool
|
||||||
|
@ -100,7 +97,6 @@ gen()
|
||||||
[[ $BUILD_fxsdk = 1 ]] && echo -n " fxsdk"
|
[[ $BUILD_fxsdk = 1 ]] && echo -n " fxsdk"
|
||||||
[[ $BUILD_fxconv = 1 ]] && echo -n " fxconv"
|
[[ $BUILD_fxconv = 1 ]] && echo -n " fxconv"
|
||||||
[[ $BUILD_fxg1a = 1 ]] && echo -n " fxg1a"
|
[[ $BUILD_fxg1a = 1 ]] && echo -n " fxg1a"
|
||||||
[[ $BUILD_fxos = 1 ]] && echo -n " fxos"
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* analysis_short(): Print a one-line summary for an address */
|
|
||||||
void analysis_short(struct os const *os, uint32_t value)
|
|
||||||
{
|
|
||||||
/* Find out whether it is a syscall address */
|
|
||||||
int syscall = os_syscall_find(os, value);
|
|
||||||
|
|
||||||
if(syscall != -1)
|
|
||||||
{
|
|
||||||
printf(" %%%03x", syscall);
|
|
||||||
|
|
||||||
/* Also find out the syscall's name! */
|
|
||||||
struct sys_call const *call = sys_find(syscall);
|
|
||||||
if(call) printf(" %s", call->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find out any peripheral register address */
|
|
||||||
struct reg_address const *reg = reg_find(value);
|
|
||||||
if(reg) printf(" %s", reg->name);
|
|
||||||
}
|
|
220
fxos/asm-sh3.txt
220
fxos/asm-sh3.txt
|
@ -1,220 +0,0 @@
|
||||||
# Instruction decoding table: 'sh3'
|
|
||||||
# Format: [01nmdi]{16}, followed by the mnemonic and the list of arguments.
|
|
||||||
# There should be at most one series of each argument letter in the opcode.
|
|
||||||
#
|
|
||||||
# Possible argument strings are predefined and include:
|
|
||||||
# rn rm #imm
|
|
||||||
# jump8 jump12 disp pcdisp
|
|
||||||
# @rn @rm @rn+ @rm+ @-rn
|
|
||||||
# @(disp,rn) @(disp,rm) @(r0,rn) @(r0,rm) @(disp,gbr)
|
|
||||||
#
|
|
||||||
# The disassembler substitutes some elements as follows:
|
|
||||||
# rn -> value of the "n"-sequence
|
|
||||||
# rm -> value of the "m"-sequence
|
|
||||||
# #imm -> value of the "i"-sequence
|
|
||||||
# disp -> value of the "d"-sequence
|
|
||||||
# jump8 -> value of the 8-bit "d"-sequence plus value of PC
|
|
||||||
# jump12 -> value of the 12-bit "d"-sequence plus value of PC
|
|
||||||
# pcdisp -> same as "jump8", but also prints pointed value (for data)
|
|
||||||
|
|
||||||
0000000001001000 clrs
|
|
||||||
0000000000001000 clrt
|
|
||||||
0000000000101000 clrmac
|
|
||||||
0000000000011001 div0u
|
|
||||||
0000000000111000 ldtlb
|
|
||||||
0000000000001001 nop
|
|
||||||
0000000000101011 rte
|
|
||||||
0000000000001011 rts
|
|
||||||
0000000001011000 sets
|
|
||||||
0000000000011000 sett
|
|
||||||
0000000000011011 sleep
|
|
||||||
|
|
||||||
0100nnnn00010101 cmp/pl rn
|
|
||||||
0100nnnn00010001 cmp/pz rn
|
|
||||||
0100nnnn00010000 dt rn
|
|
||||||
0000nnnn00101001 movt rn
|
|
||||||
0100nnnn00000100 rotl rn
|
|
||||||
0100nnnn00000101 rotr rn
|
|
||||||
0100nnnn00100100 rotcl rn
|
|
||||||
0100nnnn00100101 rotcr rn
|
|
||||||
0100nnnn00100000 shal rn
|
|
||||||
0100nnnn00100001 shar rn
|
|
||||||
0100nnnn00000000 shll rn
|
|
||||||
0100nnnn00000001 shlr rn
|
|
||||||
0100nnnn00001000 shll2 rn
|
|
||||||
0100nnnn00001001 shlr2 rn
|
|
||||||
0100nnnn00011000 shll8 rn
|
|
||||||
0100nnnn00011001 shlr8 rn
|
|
||||||
0100nnnn00101000 shll16 rn
|
|
||||||
0100nnnn00101001 shlr16 rn
|
|
||||||
|
|
||||||
0011nnnnmmmm1100 add rm, rn
|
|
||||||
0011nnnnmmmm1110 addc rm, rn
|
|
||||||
0011nnnnmmmm1111 addv rm, rn
|
|
||||||
0010nnnnmmmm1001 and rm, rn
|
|
||||||
0011nnnnmmmm0000 cmp/eq rm, rn
|
|
||||||
0011nnnnmmmm0010 cmp/hs rm, rn
|
|
||||||
0011nnnnmmmm0011 cmp/ge rm, rn
|
|
||||||
0011nnnnmmmm0110 cmp/hi rm, rn
|
|
||||||
0011nnnnmmmm0111 cmp/gt rm, rn
|
|
||||||
0010nnnnmmmm1100 cmp/str rm, rn
|
|
||||||
0011nnnnmmmm0100 div1 rm, rn
|
|
||||||
0010nnnnmmmm0111 div0s rm, rn
|
|
||||||
0011nnnnmmmm1101 dmuls.l rm, rn
|
|
||||||
0011nnnnmmmm0101 dmulu.l rm, rn
|
|
||||||
0110nnnnmmmm1110 exts.b rm, rn
|
|
||||||
0110nnnnmmmm1111 exts.w rm, rn
|
|
||||||
0110nnnnmmmm1100 extu.b rm, rn
|
|
||||||
0110nnnnmmmm1101 extu.w rm, rn
|
|
||||||
0110nnnnmmmm0011 mov rm, rn
|
|
||||||
0000nnnnmmmm0111 mul.l rm, rn
|
|
||||||
0010nnnnmmmm1111 muls.w rm, rn
|
|
||||||
0010nnnnmmmm1110 mulu.w rm, rn
|
|
||||||
0110nnnnmmmm1011 neg rm, rn
|
|
||||||
0110nnnnmmmm1010 negc rm, rn
|
|
||||||
0110nnnnmmmm0111 not rm, rn
|
|
||||||
0010nnnnmmmm1011 or rm, rn
|
|
||||||
0100nnnnmmmm1100 shad rm, rn
|
|
||||||
0100nnnnmmmm1101 shld rm, rn
|
|
||||||
0011nnnnmmmm1000 sub rm, rn
|
|
||||||
0011nnnnmmmm1010 subc rm, rn
|
|
||||||
0011nnnnmmmm1011 subv rm, rn
|
|
||||||
0110nnnnmmmm1000 swap.b rm, rn
|
|
||||||
0110nnnnmmmm1001 swap.w rm, rn
|
|
||||||
0010nnnnmmmm1000 tst rm, rn
|
|
||||||
0010nnnnmmmm1010 xor rm, rn
|
|
||||||
0010nnnnmmmm1101 xtrct rm, rn
|
|
||||||
|
|
||||||
0100mmmm00001110 ldc rm, sr
|
|
||||||
0100mmmm00011110 ldc rm, gbr
|
|
||||||
0100mmmm00101110 ldc rm, vbr
|
|
||||||
0100mmmm00111110 ldc rm, ssr
|
|
||||||
0100mmmm01001110 ldc rm, spc
|
|
||||||
0100mmmm10001110 ldc rm, r0_bank
|
|
||||||
0100mmmm10011110 ldc rm, r1_bank
|
|
||||||
0100mmmm10101110 ldc rm, r2_bank
|
|
||||||
0100mmmm10111110 ldc rm, r3_bank
|
|
||||||
0100mmmm11001110 ldc rm, r4_bank
|
|
||||||
0100mmmm11011110 ldc rm, r5_bank
|
|
||||||
0100mmmm11101110 ldc rm, r6_bank
|
|
||||||
0100mmmm11111110 ldc rm, r7_bank
|
|
||||||
0100mmmm00001010 lds rm, mach
|
|
||||||
0100mmmm00011010 lds rm, macl
|
|
||||||
0100mmmm00101010 lds rm, pr
|
|
||||||
0000nnnn00000010 stc sr, rn
|
|
||||||
0000nnnn00010010 stc gbr, rn
|
|
||||||
0000nnnn00100010 stc vbr, rn
|
|
||||||
0000nnnn00110010 stc ssr, rn
|
|
||||||
0000nnnn01000010 stc spc, rn
|
|
||||||
0000nnnn10000010 stc r0_bank, rn
|
|
||||||
0000nnnn10010010 stc r1_bank, rn
|
|
||||||
0000nnnn10100010 stc r2_bank, rn
|
|
||||||
0000nnnn10110010 stc r3_bank, rn
|
|
||||||
0000nnnn11000010 stc r4_bank, rn
|
|
||||||
0000nnnn11010010 stc r5_bank, rn
|
|
||||||
0000nnnn11100010 stc r6_bank, rn
|
|
||||||
0000nnnn11110010 stc r7_bank, rn
|
|
||||||
0000nnnn00001010 sts mach, rn
|
|
||||||
0000nnnn00011010 sts macl, rn
|
|
||||||
0000nnnn00101010 sts pr, rn
|
|
||||||
|
|
||||||
0100nnnn00101011 jmp @rn
|
|
||||||
0100nnnn00001011 jsr @rn
|
|
||||||
0000nnnn10000011 pref @rn
|
|
||||||
0100nnnn00011011 tas.b @rn
|
|
||||||
0010nnnnmmmm0000 mov.b rm, @rn
|
|
||||||
0010nnnnmmmm0001 mov.w rm, @rn
|
|
||||||
0010nnnnmmmm0010 mov.l rm, @rn
|
|
||||||
0110nnnnmmmm0000 mov.b @rm, rn
|
|
||||||
0110nnnnmmmm0001 mov.w @rm, rn
|
|
||||||
0110nnnnmmmm0010 mov.l @rm, rn
|
|
||||||
0000nnnnmmmm1111 mac.l @rm+, @rn+
|
|
||||||
0100nnnnmmmm1111 mac.w @rm+, @rn+
|
|
||||||
|
|
||||||
0110nnnnmmmm0100 mov.b @rm+, rn
|
|
||||||
0110nnnnmmmm0101 mov.w @rm+, rn
|
|
||||||
0110nnnnmmmm0110 mov.l @rm+, rn
|
|
||||||
|
|
||||||
0100mmmm00000111 ldc.l @rm+, sr
|
|
||||||
0100mmmm00010111 ldc.l @rm+, gbr
|
|
||||||
0100mmmm00100111 ldc.l @rm+, vbr
|
|
||||||
0100mmmm00110111 ldc.l @rm+, ssr
|
|
||||||
0100mmmm01000111 ldc.l @rm+, spc
|
|
||||||
0100mmmm10000111 ldc.l @rm+, r0_bank
|
|
||||||
0100mmmm10010111 ldc.l @rm+, r1_bank
|
|
||||||
0100mmmm10100111 ldc.l @rm+, r2_bank
|
|
||||||
0100mmmm10110111 ldc.l @rm+, r3_bank
|
|
||||||
0100mmmm11000111 ldc.l @rm+, r4_bank
|
|
||||||
0100mmmm11010111 ldc.l @rm+, r5_bank
|
|
||||||
0100mmmm11100111 ldc.l @rm+, r6_bank
|
|
||||||
0100mmmm11110111 ldc.l @rm+, r7_bank
|
|
||||||
0100mmmm00000110 lds.l @rm+, mach
|
|
||||||
0100mmmm00010110 lds.l @rm+, macl
|
|
||||||
0100mmmm00100110 lds.l @rm+, pr
|
|
||||||
|
|
||||||
0010nnnnmmmm0100 mov.b rm, @-rn
|
|
||||||
0010nnnnmmmm0101 mov.w rm, @-rn
|
|
||||||
0010nnnnmmmm0110 mov.l rm, @-rn
|
|
||||||
|
|
||||||
0100nnnn00000011 stc.l sr, @-rn
|
|
||||||
0100nnnn00010011 stc.l gbr, @-rn
|
|
||||||
0100nnnn00100011 stc.l vbr, @-rn
|
|
||||||
0100nnnn00110011 stc.l ssr, @-rn
|
|
||||||
0100nnnn01000011 stc.l spc, @-rn
|
|
||||||
0100nnnn10000011 stc.l r0_bank, @-rn
|
|
||||||
0100nnnn10010011 stc.l r1_bank, @-rn
|
|
||||||
0100nnnn10100011 stc.l r2_bank, @-rn
|
|
||||||
0100nnnn10110011 stc.l r3_bank, @-rn
|
|
||||||
0100nnnn11000011 stc.l r4_bank, @-rn
|
|
||||||
0100nnnn11010011 stc.l r5_bank, @-rn
|
|
||||||
0100nnnn11100011 stc.l r6_bank, @-rn
|
|
||||||
0100nnnn11110011 stc.l r7_bank, @-rn
|
|
||||||
0100nnnn00000010 sts.l mach, @-rn
|
|
||||||
0100nnnn00010010 sts.l macl, @-rn
|
|
||||||
0100nnnn00100010 sts.l pr, @-rn
|
|
||||||
|
|
||||||
10000000nnnndddd mov.b r0, @(disp, rn)
|
|
||||||
10000001nnnndddd mov.w r0, @(disp, rn)
|
|
||||||
0001nnnnmmmmdddd mov.l rm, @(disp, rn)
|
|
||||||
10000100mmmmdddd mov.b @(disp, rm), r0
|
|
||||||
10000101mmmmdddd mov.w @(disp, rm), r0
|
|
||||||
0101nnnnmmmmdddd mov.l @(disp, rm), rn
|
|
||||||
0000nnnnmmmm0100 mov.b rm, @(r0, rn)
|
|
||||||
0000nnnnmmmm0101 mov.w rm, @(r0, rn)
|
|
||||||
0000nnnnmmmm0110 mov.l rm, @(r0, rn)
|
|
||||||
0000nnnnmmmm1100 mov.b @(r0, rm), rn
|
|
||||||
0000nnnnmmmm1101 mov.w @(r0, rm), rn
|
|
||||||
0000nnnnmmmm1110 mov.l @(r0, rm), rn
|
|
||||||
11000000dddddddd mov.b r0, @(disp, gbr)
|
|
||||||
11000001dddddddd mov.w r0, @(disp, gbr)
|
|
||||||
11000010dddddddd mov.l r0, @(disp, gbr)
|
|
||||||
11000100dddddddd mov.b @(disp, gbr), r0
|
|
||||||
11000101dddddddd mov.w @(disp, gbr), r0
|
|
||||||
11000110dddddddd mov.l @(disp, gbr), r0
|
|
||||||
|
|
||||||
11001101iiiiiiii and.b #imm, @(r0, gbr)
|
|
||||||
11001111iiiiiiii or.b #imm, @(r0, gbr)
|
|
||||||
11001100iiiiiiii tst.b #imm, @(r0, gbr)
|
|
||||||
11001110iiiiiiii xor.b #imm, @(r0, gbr)
|
|
||||||
|
|
||||||
1001nnnndddddddd mov.w pcdisp, rn
|
|
||||||
1101nnnndddddddd mov.l pcdisp, rn
|
|
||||||
11000111dddddddd mova pcdisp, r0
|
|
||||||
|
|
||||||
0000mmmm00100011 braf rm
|
|
||||||
0000mmmm00000011 bsrf rm
|
|
||||||
10001011dddddddd bf jump8
|
|
||||||
10001111dddddddd bf/s jump8
|
|
||||||
10001001dddddddd bt jump8
|
|
||||||
10001101dddddddd bt/s jump8
|
|
||||||
1010dddddddddddd bra jump12
|
|
||||||
1011dddddddddddd bsr jump12
|
|
||||||
|
|
||||||
0111nnnniiiiiiii add #imm, rn
|
|
||||||
11001001iiiiiiii and #imm, r0
|
|
||||||
10001000iiiiiiii cmp/eq #imm, r0
|
|
||||||
1110nnnniiiiiiii mov #imm, rn
|
|
||||||
11001011iiiiiiii or #imm, r0
|
|
||||||
11001000iiiiiiii tst #imm, r0
|
|
||||||
11001010iiiiiiii xor #imm, r0
|
|
||||||
11000011iiiiiiii trapa #imm
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Instruction decoding table: 'sh4'
|
|
||||||
# This table is an extension for SH4 processors. See 'asm-sh3.txt' for details
|
|
||||||
# on the format.
|
|
||||||
|
|
||||||
0000nnnn01110011 movco.l r0, @rn
|
|
||||||
0000mmmm01100011 movli.l @rm, r0
|
|
||||||
0100mmmm10101001 movua.l @rm, r0
|
|
||||||
0100mmmm11101001 movua.l @rm+, r0
|
|
||||||
0000nnnn11000011 movca.l r0, @rn
|
|
||||||
|
|
||||||
0000nnnn11100011 icbi @rn
|
|
||||||
0000nnnn10010011 ocbi @rn
|
|
||||||
0000nnnn10100011 ocbp @rn
|
|
||||||
0000nnnn10110011 ocbwb @rn
|
|
||||||
|
|
||||||
0000nnnn11010011 prefi @rn
|
|
||||||
0000000010101011 synco
|
|
||||||
|
|
||||||
0100mmmm00111010 ldc rm, sgr
|
|
||||||
0100mmmm11111010 ldc rm, dbr
|
|
||||||
0100mmmm00110110 ldc.l @rm+, sgr
|
|
||||||
0100mmmm11110110 ldc.l @rm+, dbr
|
|
||||||
0000nnnn00111010 stc sgr, rn
|
|
||||||
0000nnnn11111010 stc dbr, rn
|
|
||||||
0100nnnn00110010 stc.l sgr, @-rn
|
|
||||||
0100nnnn11110010 stc.l dbr, @-rn
|
|
74
fxos/asm.c
74
fxos/asm.c
|
@ -1,74 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* asm_free_item(): Free an assembly instruction details */
|
|
||||||
static void asm_free_item(void *item)
|
|
||||||
{
|
|
||||||
struct asm_insn *insn = item;
|
|
||||||
free(insn->mnemonic);
|
|
||||||
free(insn->literal1);
|
|
||||||
free(insn->literal2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* asm_load(): Load an assembly table */
|
|
||||||
void asm_load(char const *file)
|
|
||||||
{
|
|
||||||
err_context("assembly", file, NULL);
|
|
||||||
if(!table_available())
|
|
||||||
{
|
|
||||||
err("too many tables, skipping");
|
|
||||||
err_pop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the file to memory */
|
|
||||||
int fd;
|
|
||||||
size_t size;
|
|
||||||
void *data = map(file, &fd, &size);
|
|
||||||
if(!data) { err_pop(); return; }
|
|
||||||
|
|
||||||
/* If the file is named "asm-x.txt", use "x" as the table name */
|
|
||||||
char *name = match_table_name(file, "asm", ".txt");
|
|
||||||
|
|
||||||
/* Parse the contents; the lexer in is [lexer-asm.l] and the parser is
|
|
||||||
implemented as an automaton with basic error correction. */
|
|
||||||
int count;
|
|
||||||
struct asm_insn *ins = lex_asm(data, size, &count);
|
|
||||||
|
|
||||||
table_create("asm", name, asm_free_item, count, sizeof *ins, ins);
|
|
||||||
|
|
||||||
unmap(data, fd, size);
|
|
||||||
err_pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global storage for asm_match() */
|
|
||||||
static uint16_t asm_match_opcode;
|
|
||||||
|
|
||||||
/* asm_match(): Check if an instruction matches a pattern */
|
|
||||||
int asm_match(void *item)
|
|
||||||
{
|
|
||||||
struct asm_insn *insn = item;
|
|
||||||
return ((insn->bits ^ asm_match_opcode) & insn->arg_mask) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* asm_decode(): Match a 16-bit opcode against the assembly database */
|
|
||||||
int asm_decode(uint16_t opcode, struct asm_match *match, int next)
|
|
||||||
{
|
|
||||||
asm_match_opcode = opcode;
|
|
||||||
char const *table;
|
|
||||||
struct asm_insn *insn = table_find("asm", asm_match, &table, next);
|
|
||||||
if(!insn) return 1;
|
|
||||||
|
|
||||||
/* Set match details */
|
|
||||||
match->insn = insn;
|
|
||||||
match->table = table;
|
|
||||||
|
|
||||||
match->n = (opcode >> insn->n_sh) & insn->n_mask;
|
|
||||||
match->m = (opcode >> insn->m_sh) & insn->m_mask;
|
|
||||||
match->d = (opcode >> insn->d_sh) & insn->d_mask;
|
|
||||||
match->i = (opcode >> insn->i_sh) & insn->i_mask;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Architecture we are disassembling for */
|
|
||||||
static enum mpu mpu = MPU_GUESS;
|
|
||||||
/* Current program counter */
|
|
||||||
static uint32_t pc = 0;
|
|
||||||
/* Data chunk under disassembly (whole file) */
|
|
||||||
static uint8_t *data;
|
|
||||||
static size_t len;
|
|
||||||
/* Non-NULL when disassembling an OS */
|
|
||||||
static struct os const *os = NULL;
|
|
||||||
|
|
||||||
/* pcdisp(): Compute the address of a PC-relative displacement
|
|
||||||
@pc Current PC value
|
|
||||||
@disp Displacement value (from opcode)
|
|
||||||
@unit Number of bytes per step (1, 2 or 4), depends on instruction
|
|
||||||
Returns the pointed location. */
|
|
||||||
static uint32_t pcdisp(uint32_t pc, uint32_t disp, int unit)
|
|
||||||
{
|
|
||||||
pc += 4;
|
|
||||||
if(unit == 4) pc &= ~3;
|
|
||||||
|
|
||||||
return pc + disp * unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pcread(): Read data pointed through a PC-relative displacement
|
|
||||||
@pc Current PC value
|
|
||||||
@disp Displacement value (from opcode)
|
|
||||||
@unit Number of bytes per set (also number of bytes read)
|
|
||||||
@out If non-NULL, set to 1 if pointed address is out of the file
|
|
||||||
Returns the value pointed at, an undefined value if out of bounds. */
|
|
||||||
static uint32_t pcread(uint32_t pc, uint32_t disp, int unit, int *out)
|
|
||||||
{
|
|
||||||
/* Take physical addresses */
|
|
||||||
uint32_t addr = pcdisp(pc, disp, unit) & 0x1fffffff;
|
|
||||||
if(out) *out = (addr + unit > len);
|
|
||||||
|
|
||||||
uint32_t value = 0;
|
|
||||||
while(unit--) value = (value << 8) | data[addr++];
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* matches(): Count number of matches for a single instruction
|
|
||||||
@opcode 16-bit opcode value
|
|
||||||
Returns the number of matching instructions in the database. */
|
|
||||||
static int matches(uint16_t opcode)
|
|
||||||
{
|
|
||||||
struct asm_match match;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
while(!asm_decode(opcode, &match, count))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arg_output(int type, char const *literal,
|
|
||||||
struct asm_match const *match, int opsize)
|
|
||||||
{
|
|
||||||
int n = match->n;
|
|
||||||
int m = match->m;
|
|
||||||
int d = match->d;
|
|
||||||
int i = match->i;
|
|
||||||
|
|
||||||
/* Sign extensions of d to 8 and 12 bits */
|
|
||||||
int32_t d8 = (int8_t)d;
|
|
||||||
int32_t d12 = (d & 0x800) ? (int32_t)(d | 0xfffff000) : (d);
|
|
||||||
/* Sign extension of i to 8 bits */
|
|
||||||
int32_t i8 = (int8_t)i;
|
|
||||||
|
|
||||||
int out_of_bounds;
|
|
||||||
uint32_t addr;
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case LITERAL:
|
|
||||||
printf("%s", literal);
|
|
||||||
break;
|
|
||||||
case IMM:
|
|
||||||
printf("#%d", i8);
|
|
||||||
break;
|
|
||||||
case RN:
|
|
||||||
printf("r%d", n);
|
|
||||||
break;
|
|
||||||
case RM:
|
|
||||||
printf("r%d", m);
|
|
||||||
break;
|
|
||||||
case JUMP8:
|
|
||||||
value = pcdisp(pc, d8, 2);
|
|
||||||
printf("<%x", value);
|
|
||||||
if(os) analysis_short(os, value | 0x80000000);
|
|
||||||
printf(">");
|
|
||||||
break;
|
|
||||||
case JUMP12:
|
|
||||||
value = pcdisp(pc, d12, 2);
|
|
||||||
printf("<%x", value);
|
|
||||||
if(os) analysis_short(os, value | 0x80000000);
|
|
||||||
printf(">");
|
|
||||||
break;
|
|
||||||
case PCDISP:
|
|
||||||
addr = pcdisp(pc, d, opsize);
|
|
||||||
value = pcread(pc, d, opsize, &out_of_bounds);
|
|
||||||
|
|
||||||
printf("<%x>", addr);
|
|
||||||
if(out_of_bounds) printf("(out of bounds)");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("(#0x%0*x", opsize * 2, value);
|
|
||||||
if(os) analysis_short(os, value);
|
|
||||||
printf(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case AT_RN:
|
|
||||||
printf("@r%d", n);
|
|
||||||
break;
|
|
||||||
case AT_RM:
|
|
||||||
printf("@r%d", m);
|
|
||||||
break;
|
|
||||||
case AT_RMP:
|
|
||||||
printf("@r%d+", m);
|
|
||||||
break;
|
|
||||||
case AT_RNP:
|
|
||||||
printf("@r%d+", n);
|
|
||||||
break;
|
|
||||||
case AT_MRN:
|
|
||||||
printf("@-r%d", n);
|
|
||||||
break;
|
|
||||||
case AT_DRN:
|
|
||||||
printf("@(%d, r%d)", d * opsize, n);
|
|
||||||
break;
|
|
||||||
case AT_DRM:
|
|
||||||
printf("@(%d, r%d)", d * opsize, m);
|
|
||||||
break;
|
|
||||||
case AT_R0RN:
|
|
||||||
printf("@(r0, r%d)", n);
|
|
||||||
break;
|
|
||||||
case AT_R0RM:
|
|
||||||
printf("@(r0, r%d)", m);
|
|
||||||
break;
|
|
||||||
case AT_DGBR:
|
|
||||||
printf("@(%d, gbr)", d * opsize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void instruction_output(uint16_t opcode, struct asm_match const *match)
|
|
||||||
{
|
|
||||||
char const *mnemonic = match->insn->mnemonic;
|
|
||||||
printf(" %5x: %04x %s", pc, opcode, mnemonic);
|
|
||||||
|
|
||||||
/* Find out operation size */
|
|
||||||
|
|
||||||
size_t n = strlen(mnemonic);
|
|
||||||
int opsize = 0;
|
|
||||||
|
|
||||||
if(n >= 3 && mnemonic[n-2] == '.')
|
|
||||||
{
|
|
||||||
int c = mnemonic[n-1];
|
|
||||||
opsize = (c == 'b') + 2 * (c == 'w') + 4 * (c == 'l');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output arguments */
|
|
||||||
|
|
||||||
if(!match->insn->arg1) return;
|
|
||||||
printf("%*s", (int)(8-n), "");
|
|
||||||
arg_output(match->insn->arg1, match->insn->literal1, match, opsize);
|
|
||||||
|
|
||||||
if(!match->insn->arg2) return;
|
|
||||||
printf(", ");
|
|
||||||
arg_output(match->insn->arg2, match->insn->literal2, match, opsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void instruction_single(uint16_t opcode)
|
|
||||||
{
|
|
||||||
struct asm_match match;
|
|
||||||
asm_decode(opcode, &match, 0);
|
|
||||||
instruction_output(opcode, &match);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void instruction_conflicts(uint16_t opcode, int count)
|
|
||||||
{
|
|
||||||
struct asm_match match;
|
|
||||||
printf("\n # conflicts[%d] on <%x>(%04x)\n", count, pc, opcode);
|
|
||||||
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
asm_decode(opcode, &match, i);
|
|
||||||
instruction_output(opcode, &match);
|
|
||||||
printf(" # table '%s'\n", match.table);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disassembly_os(): Disassemble an address or a syscall */
|
|
||||||
void disassembly_os(struct os const *src, struct disassembly const *opt)
|
|
||||||
{
|
|
||||||
/* Initialize this file's global state */
|
|
||||||
mpu = src->mpu;
|
|
||||||
pc = opt->start;
|
|
||||||
data = src->data;
|
|
||||||
len = src->len;
|
|
||||||
os = src;
|
|
||||||
|
|
||||||
/* Override MPU guesses if user requested a specific platform */
|
|
||||||
if(opt->mpu != MPU_GUESS) mpu = opt->mpu;
|
|
||||||
|
|
||||||
/* Handle situations where the start address is a syscall */
|
|
||||||
if(opt->syscall)
|
|
||||||
{
|
|
||||||
pc = os_syscall(os, opt->start);
|
|
||||||
if(pc == (uint32_t)-1)
|
|
||||||
{
|
|
||||||
err("syscall 0x%04x does not exist", opt->start);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Take physical addresses */
|
|
||||||
pc &= 0x1fffffff;
|
|
||||||
|
|
||||||
/* Cut the length if it reaches past the end of the file */
|
|
||||||
uint32_t limit = (pc + opt->len) & ~1;
|
|
||||||
if(limit > os->len) limit = os->len;
|
|
||||||
|
|
||||||
/* Enforce alignment of PC */
|
|
||||||
if(pc & 1)
|
|
||||||
{
|
|
||||||
err("address is not 2-aligned, skipping 1 byte");
|
|
||||||
pc += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *data = os->data;
|
|
||||||
|
|
||||||
while(pc < limit)
|
|
||||||
{
|
|
||||||
if(os)
|
|
||||||
{
|
|
||||||
int syscall = os_syscall_find(os, pc | 0x80000000);
|
|
||||||
if(syscall == -1)
|
|
||||||
syscall = os_syscall_find(os, pc | 0xa0000000);
|
|
||||||
if(syscall != -1)
|
|
||||||
{
|
|
||||||
struct sys_call const *s = sys_find(syscall);
|
|
||||||
printf("\n<%x %%%03x", pc, syscall);
|
|
||||||
if(s) printf(" %s", s->name);
|
|
||||||
printf(">\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t opcode = (data[pc] << 8) | data[pc + 1];
|
|
||||||
int count = matches(opcode);
|
|
||||||
|
|
||||||
if(count == 0) printf(" %5x: %04x\n", pc, opcode);
|
|
||||||
else if(count == 1) instruction_single(opcode);
|
|
||||||
else instruction_conflicts(opcode, count);
|
|
||||||
|
|
||||||
pc += 2;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
//---
|
|
||||||
// Cross-platform endianness conversion. (seriously?)
|
|
||||||
//---
|
|
||||||
|
|
||||||
#ifndef FX_ENDIANNESS
|
|
||||||
#define FX_ENDIANNESS
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
|
|
||||||
#include <libkern/OSByteOrder.h>
|
|
||||||
|
|
||||||
#define htobe16(x) OSSwapHostToBigInt16(x)
|
|
||||||
#define htole16(x) OSSwapHostToLittleInt16(x)
|
|
||||||
#define be16toh(x) OSSwapBigToHostInt16(x)
|
|
||||||
#define le16toh(x) OSSwapLittleToHostInt16(x)
|
|
||||||
|
|
||||||
#define htobe32(x) OSSwapHostToBigInt32(x)
|
|
||||||
#define htole32(x) OSSwapHostToLittleInt32(x)
|
|
||||||
#define be32toh(x) OSSwapBigToHostInt32(x)
|
|
||||||
#define le32toh(x) OSSwapLittleToHostInt32(x)
|
|
||||||
|
|
||||||
#define htobe64(x) OSSwapHostToBigInt64(x)
|
|
||||||
#define htole64(x) OSSwapHostToLittleInt64(x)
|
|
||||||
#define be64toh(x) OSSwapBigToHostInt64(x)
|
|
||||||
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
|
||||||
|
|
||||||
#elif defined(__linux__)
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FX_ENDIANNESS */
|
|
|
@ -1,84 +0,0 @@
|
||||||
#include <errors.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define MAX 32
|
|
||||||
|
|
||||||
/* Array of context strings. */
|
|
||||||
static char const *context[MAX] = { NULL };
|
|
||||||
/* Number of active elements. */
|
|
||||||
static int elements = 0;
|
|
||||||
|
|
||||||
/* push(): Push an element in the context buffer
|
|
||||||
@el New element
|
|
||||||
Returns non-zero if the buffer is full. */
|
|
||||||
static int push(char const *el)
|
|
||||||
{
|
|
||||||
if(elements >= MAX - 2) return 1;
|
|
||||||
context[elements++] = el;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* err_context(): Push one or more context elements */
|
|
||||||
int err_context(char const *context, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, context);
|
|
||||||
int x = 0;
|
|
||||||
|
|
||||||
/* Delimiter between calls to err_context(), for err_pop() */
|
|
||||||
x |= push(NULL);
|
|
||||||
x |= push(context);
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
char const *el = va_arg(args, char const *);
|
|
||||||
if(!el) break;
|
|
||||||
x |= push(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* err_pop(): Pop back context elements */
|
|
||||||
void err_pop(void)
|
|
||||||
{
|
|
||||||
/* Clear everything until the last NULL delimiter */
|
|
||||||
while(--elements >= 0 && context[elements])
|
|
||||||
{
|
|
||||||
context[elements] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void err_debug(void)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < MAX; i++) fprintf(stderr, "%s: ", context[i]);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* errf(): Emit an error message */
|
|
||||||
void errf(int flags, char const *str, ...)
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, str);
|
|
||||||
|
|
||||||
for(int i = 0; i <= MAX-2 && (context[i] || context[i+1]); i++)
|
|
||||||
{
|
|
||||||
if(context[i]) fprintf(stderr, "%s: ", context[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
vfprintf(stderr, str, args);
|
|
||||||
|
|
||||||
if(flags & ERR_ERRNO)
|
|
||||||
{
|
|
||||||
fprintf(stderr, ": %s", strerror(saved_errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
//---
|
|
||||||
// errors: Error message management
|
|
||||||
//
|
|
||||||
// An attempt at producing elaborate error messages providing context from
|
|
||||||
// multiple function calls, with a small amount of code.
|
|
||||||
//
|
|
||||||
// Basically, caller functions define context and message parameters
|
|
||||||
// before doing anything risky. When an error occurs in a sub-function,
|
|
||||||
// the context is used to prepend relevant information and fill in the
|
|
||||||
// error message where relevant.
|
|
||||||
//
|
|
||||||
// This means that the caller functions must know it advance what kind of
|
|
||||||
// messages can be emitted to accurately set the context. Although it
|
|
||||||
// would work through library calls, it is not very suitable. It's rather
|
|
||||||
// meant for the logic of applications.
|
|
||||||
//---
|
|
||||||
|
|
||||||
#ifndef FXOS_ERRORS
|
|
||||||
#define FXOS_ERRORS
|
|
||||||
|
|
||||||
/* Error levels */
|
|
||||||
#define ERR_CRIT 0x01 /* Aborts part or whole of the program's task */
|
|
||||||
#define ERR_ERR 0x02 /* Unexpected behavior */
|
|
||||||
#define ERR_WARN 0x03 /* Internal consistency issues */
|
|
||||||
#define ERR_LOG 0x04 /* Internal logging */
|
|
||||||
/* Error flags */
|
|
||||||
#define ERR_ERRNO 0x10
|
|
||||||
|
|
||||||
/* err_context(): Push one or more context elements
|
|
||||||
@context Context string, must live until it is popped by err_pop()
|
|
||||||
@... More contexts, same requirements as the first (NULL-terminated)
|
|
||||||
Returns non-zero if the deepest context level (at least 15) is reached. */
|
|
||||||
int err_context(char const *context, ...);
|
|
||||||
|
|
||||||
/* err_pop(): Pop back context elements
|
|
||||||
Pops back all context elements that were added by the previous call to
|
|
||||||
err_context(), no matter their number. */
|
|
||||||
void err_pop(void);
|
|
||||||
|
|
||||||
/* errf(): Emit an error message
|
|
||||||
Error message is printed via fprintf() and supports the same format. All the
|
|
||||||
arguments are passed directly.
|
|
||||||
|
|
||||||
Available flags are any combination of at most one error level:
|
|
||||||
ERR_CRIT -- Unrecoverable error
|
|
||||||
ERR_ERR -- Normal error
|
|
||||||
ERR_WARN -- Warning
|
|
||||||
ERR_LOG -- Logging
|
|
||||||
and any of these boolean flags:
|
|
||||||
ERR_ERRNO -- Also print strerror(errno) as a suffix (as perror()).
|
|
||||||
|
|
||||||
Error levels might be used later on for filtering. Messages without level
|
|
||||||
will always be displayed.
|
|
||||||
|
|
||||||
@flags An OR-combination of the previous flags, or 0
|
|
||||||
@str Error messages
|
|
||||||
@... Arguments to format [str] through fprintf() */
|
|
||||||
void errf(int flags, char const *str, ...);
|
|
||||||
|
|
||||||
/* err(): Short error function */
|
|
||||||
#define err(str, ...) errf(0, str, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
#endif /* FXOS_ERRORS */
|
|
410
fxos/fxos.h
410
fxos/fxos.h
|
@ -1,410 +0,0 @@
|
||||||
//---
|
|
||||||
// fxos:fxos - Main interfaces
|
|
||||||
//---
|
|
||||||
|
|
||||||
#ifndef FX_FXOS
|
|
||||||
#define FX_FXOS
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Microprocessor platforms */
|
|
||||||
enum mpu {
|
|
||||||
MPU_GUESS = 0,
|
|
||||||
MPU_SH7705 = 1,
|
|
||||||
MPU_SH7305 = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Memory (memory.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct region: A valid memory region for at least one platform */
|
|
||||||
struct region
|
|
||||||
{
|
|
||||||
uint32_t start; /* Start address */
|
|
||||||
uint32_t end; /* End address */
|
|
||||||
char const *name; /* Name, used to identify RAM dump files */
|
|
||||||
enum mpu platform; /* Platform hint or MPU_GUESS */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* memory_region(): Find the region where an address is located
|
|
||||||
Returns NULL if the address points to no valid memory. This function rejects
|
|
||||||
addresses of peripheral registers in P3 or P4 space and only heeds for
|
|
||||||
contiguous RAM or ROM areas.
|
|
||||||
|
|
||||||
@address 32-bit virtual memory address
|
|
||||||
Returns a region description matching the address, NULL if none is known.*/
|
|
||||||
struct region const *memory_region(uint32_t address);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** General table storage (tables.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct table: Parametric data table */
|
|
||||||
struct table {
|
|
||||||
char const *type; /* Table type, set by user */
|
|
||||||
char *name; /* Table name, also set by user */
|
|
||||||
void (*free_item)(void *); /* Function to free individual items */
|
|
||||||
|
|
||||||
int count; /* Number of items in the table */
|
|
||||||
size_t size; /* Size of each item */
|
|
||||||
void *items; /* Table data */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* table_available(): Whether a table can be allocated
|
|
||||||
Returns non-zero if there is space left for a new table, zero if not. */
|
|
||||||
int table_available(void);
|
|
||||||
|
|
||||||
/* table_create(): Create a new table
|
|
||||||
Allocates a new table inside the global storage. The created table can be
|
|
||||||
searched immediately with table_find().
|
|
||||||
|
|
||||||
@type Table type, expectedly a string constant
|
|
||||||
@name Name string, this module takes ownership and will free() it
|
|
||||||
@free_item Function to use to destroy items in the future
|
|
||||||
@count Number of items
|
|
||||||
@size Size of each item
|
|
||||||
@items Full data array */
|
|
||||||
void table_create(char const *type, char *name, void (*free_item)(void *),
|
|
||||||
int count, size_t size, void *items);
|
|
||||||
|
|
||||||
/* table_find(): Find matching entries in the database tables
|
|
||||||
|
|
||||||
This function traverses all the tables of type @type and returns all the
|
|
||||||
elements [e] such that [match(e)] is non-zero.
|
|
||||||
|
|
||||||
The search starts with [next=0] and returns the first match; further calls
|
|
||||||
with [next!=0] will return more matching elements until no more are found
|
|
||||||
(in which case this function returns NULL) or this function is called again
|
|
||||||
with [next=0] to start a new search.
|
|
||||||
|
|
||||||
@type Table filter by type
|
|
||||||
@match Match function
|
|
||||||
@name Set to matching table name, if not NULL
|
|
||||||
@next Set it to 0 on the first call, and non-zero after that
|
|
||||||
Returns a match if one is found, NULL otherwise. */
|
|
||||||
void *table_find(char const *type, int (*match)(void *), char const **name,
|
|
||||||
int next);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Assembly tables (asm.c, lexer-asm.l)
|
|
||||||
** These tables reference all assembler instructions used by fxos to
|
|
||||||
** disassemble code. In case of conflict, fxos will disassemble the same
|
|
||||||
** opcode several times.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct asm_insn: Entry of an instruction table */
|
|
||||||
struct asm_insn {
|
|
||||||
uint16_t bits; /* Opcode; arbitrary values for arguments */
|
|
||||||
uint16_t arg_mask; /* 1 for constant bits, 0 for arguments */
|
|
||||||
|
|
||||||
/* Position of the arguments */
|
|
||||||
uint8_t n_sh, m_sh, d_sh, i_sh;
|
|
||||||
/* Masks indicating the length of arguments */
|
|
||||||
uint16_t n_mask, m_mask, d_mask, i_mask;
|
|
||||||
|
|
||||||
char *mnemonic; /* NUL-terminated mnemonic */
|
|
||||||
|
|
||||||
int arg1; /* asm_arg member */
|
|
||||||
int arg2; /* asm_arg member */
|
|
||||||
|
|
||||||
char *literal1; /* When arg1 == LITERAL, argument string */
|
|
||||||
char *literal2; /* When arg2 == LITERAL, argument string */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* enum asm_arg: Argument variants */
|
|
||||||
enum asm_arg {
|
|
||||||
LITERAL=1, /* Literal string, eg. "vbr" or "@(r0, gbr)" */
|
|
||||||
IMM, RN, RM, /* "#imm", "rn", "rm" */
|
|
||||||
JUMP8, JUMP12, /* Jump from displacement (PC + disp) */
|
|
||||||
PCDISP, /* PC-displacement with data */
|
|
||||||
AT_RN, AT_RM, /* "@rn", "@rm" */
|
|
||||||
AT_RMP, AT_RNP, AT_MRN, /* Post-increment and pre-decrement */
|
|
||||||
AT_DRN, AT_DRM, /* Displacement structure addressing */
|
|
||||||
AT_R0RN, AT_R0RM, /* r0 structure addressing */
|
|
||||||
AT_DGBR, /* GBR addressing */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* struct asm_match: Matching of a 16-bit code against an instruction
|
|
||||||
Specifies the source instruction and the value of the parameters. The value
|
|
||||||
of [m], [n], [d] or [i] is unspecified for parameters that are not used in
|
|
||||||
the matched instruction's opcode. */
|
|
||||||
struct asm_match {
|
|
||||||
/* Matching instruction */
|
|
||||||
struct asm_insn const *insn;
|
|
||||||
|
|
||||||
char const *table; /* Table name */
|
|
||||||
int m, n, d, i; /* Parameter assignment */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* asm_load(): Load an assembly table
|
|
||||||
Loads all instructions described by @file into a table named "x" is @file's
|
|
||||||
basename is on the form "asm-x.txt" and the whole basename otherwise. The
|
|
||||||
resulting table is available immediately to use with asm_match().
|
|
||||||
|
|
||||||
Skips every row that does not conform to the file's syntax after printing a
|
|
||||||
message to stderr.
|
|
||||||
|
|
||||||
@file Input file path */
|
|
||||||
void asm_load(char const *file);
|
|
||||||
|
|
||||||
/* asm_decode(): Match a 16-bit opcode against the assembly database
|
|
||||||
This function searches matches of a 16-bit instruction code inside the
|
|
||||||
instruction database. Depending on the database files currently loaded,
|
|
||||||
there can be several matches; this function uses static variables to
|
|
||||||
maintain state information through several calls.
|
|
||||||
|
|
||||||
First call this function with [next] set to 0. If there is no match, the
|
|
||||||
call will return non-zero and [*match] will be left unchanged. Otherwise,
|
|
||||||
the first matching instruction will be described in [*match], the call will
|
|
||||||
return 0 and internal static variables will be reset.
|
|
||||||
|
|
||||||
Repeatedly call this function with [next != 0] to get further matches. The
|
|
||||||
search ends when there are no more matches, in which case this function
|
|
||||||
returns non-zero and [*match] is left unchanged. Any non-zero value for
|
|
||||||
[next] is suitable.
|
|
||||||
|
|
||||||
The name of the table providing the match is set in [match->table]. Please
|
|
||||||
bear in mind, though, that table names do not uniquely identify tables.
|
|
||||||
|
|
||||||
@opcode 16-bit opcode to be matched against the database
|
|
||||||
@match Set to a description of the matching instruction (must not be NULL)
|
|
||||||
@next Set it to 0 on the first call, and non-zero after that
|
|
||||||
Returns 0 if a match is found, non-zero otherwise. */
|
|
||||||
int asm_decode(uint16_t opcode, struct asm_match *match, int next);
|
|
||||||
|
|
||||||
/* asm_quit(): Unload all assembly tables
|
|
||||||
Releases all memory held by the assembly table database. */
|
|
||||||
void asm_quit(void);
|
|
||||||
|
|
||||||
/* lex_asm(): Assembly table lexer and parser
|
|
||||||
Lexes and parses string @data of length @length, allocating and filling an
|
|
||||||
instruction array whose size is stored in [*count] if @count is non-NULL.
|
|
||||||
Prints messages to stderr for every syntax error in the file.
|
|
||||||
|
|
||||||
@data Input memory, not NUL-terminated (typically a memory-mapped file)
|
|
||||||
@length Length of input string
|
|
||||||
@count Set to number of successfully decoded instructions if non-NULL
|
|
||||||
Returns a free()able array of decoded instructions. */
|
|
||||||
struct asm_insn *lex_asm(void *data, size_t length, int *count);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Syscall tables (sys.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct sys_call: Entry of a syscall table */
|
|
||||||
struct sys_call {
|
|
||||||
uint32_t number; /* Syscall number */
|
|
||||||
char *name; /* Symbol or function name */
|
|
||||||
char *descr; /* Prototype or description */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* sys_load(): Load a syscall table
|
|
||||||
Loads a syscall description table. If @file is named "sys-x.txt" then the
|
|
||||||
table name is set to "x", otherwise @file's basename.
|
|
||||||
Prints syntax errors and skips invalid lines.
|
|
||||||
|
|
||||||
@file Input file path */
|
|
||||||
void sys_load(char const *path);
|
|
||||||
|
|
||||||
/* sys_find(): Find information on a given syscall number
|
|
||||||
Traverse the syscall tables currently loaded and returns the first entry
|
|
||||||
matching the provided syscall number, if any is found.
|
|
||||||
|
|
||||||
@number Syscall number
|
|
||||||
Returns a description of the syscall, NULL if none was found. */
|
|
||||||
struct sys_call const *sys_find(uint32_t number);
|
|
||||||
|
|
||||||
/* sys_quit(): Release memory held by the syscall tables */
|
|
||||||
void sys_quit(void);
|
|
||||||
|
|
||||||
/* lex_sys(): Syscall table lexer and parser
|
|
||||||
Lexes and parses string @data of length @len, allocating and filling a
|
|
||||||
syscall array whose size is stored in [*count] if @count is not NULL.
|
|
||||||
Prints syntax errors on stderr.
|
|
||||||
|
|
||||||
@data Input memory (typically memory-mapped file)
|
|
||||||
@len Length of input
|
|
||||||
@count Set to number of decoded entries if not NULL
|
|
||||||
Returns a free()able table of decoded syscall entries. */
|
|
||||||
struct sys_call *lex_sys(void *data, size_t len, int *count);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Peripheral register tables (reg.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct reg_address: Entry of a peripheral register table */
|
|
||||||
struct reg_address {
|
|
||||||
uint32_t address; /* Register address */
|
|
||||||
char *name; /* Typically an upper-case dotted specifier */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* reg_load(): Load a peripheral register table
|
|
||||||
Loads a peripheral register listing. If @file is named "reg-x.txt" then the
|
|
||||||
table name is set to "x", otherwise @file's basename.
|
|
||||||
Prints syntax errors and skips invalid lines. Loaded data is available
|
|
||||||
immediately through reg_find().
|
|
||||||
|
|
||||||
@file Input file path */
|
|
||||||
void reg_load(char const *path);
|
|
||||||
|
|
||||||
/* reg_find(): Find information on a given peripheral register address
|
|
||||||
Looks up the loaded tables and returns the first entry matching the given
|
|
||||||
address (if any).
|
|
||||||
|
|
||||||
@address Any input address
|
|
||||||
Returns a pointer to the matching register, NULL if none was found. */
|
|
||||||
struct reg_address const *reg_find(uint32_t address);
|
|
||||||
|
|
||||||
/* reg_quit(): Release memory held by the peripheral register tables */
|
|
||||||
void reg_quit(void);
|
|
||||||
|
|
||||||
/* lex_reg(): Peripheral register table lexer and parser
|
|
||||||
Lexes and parses @data (of length @length). Allocates and fills a register
|
|
||||||
description array and stores its size in [*count] if @count is not NULL.
|
|
||||||
Prints messages on stderr if there are syntax errors.
|
|
||||||
|
|
||||||
@data Input string (needs not be NUL-terminated)
|
|
||||||
@len Length of input
|
|
||||||
@count Set to the number of decoded register addresses, if not NULL
|
|
||||||
Returns a free()able table with the decoded data. */
|
|
||||||
struct reg_address *lex_reg(void *data, size_t len, int *count);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** General OS operations (os.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct os: Basic OS information */
|
|
||||||
struct os {
|
|
||||||
void *data; /* Operating system dump */
|
|
||||||
size_t len; /* File length */
|
|
||||||
int fd; /* Underlying file descriptor */
|
|
||||||
|
|
||||||
char version[15]; /* NUL-terminated OS version string */
|
|
||||||
enum mpu mpu; /* User-provided or guessed MPU type */
|
|
||||||
|
|
||||||
uint32_t syscall_table; /* Syscall table address */
|
|
||||||
int syscalls; /* Number of valid syscalls found */
|
|
||||||
|
|
||||||
uint32_t footer; /* Footer address (-1 if not found) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* os_load(): Load an OS file and find out basic properties
|
|
||||||
Guesses the MPU type, finds the syscall table and its size, finds the footer
|
|
||||||
address.
|
|
||||||
|
|
||||||
@path File path
|
|
||||||
@os Will be filled with loaded data and information
|
|
||||||
Returns non-zero in case of loading error or file format error. */
|
|
||||||
int os_load(char const *path, struct os *os);
|
|
||||||
|
|
||||||
/* os_syscall(): Get the address of a syscall entry
|
|
||||||
Does not check bounds, only returns (uint32_t)-1 if the requested entry of
|
|
||||||
the table is past the end of the file.
|
|
||||||
|
|
||||||
@os Source OS
|
|
||||||
@syscall Syscall entry number
|
|
||||||
Returns the syscall address. */
|
|
||||||
uint32_t os_syscall(struct os const *os, int syscall);
|
|
||||||
|
|
||||||
/* os_syscall_find(): Find a syscall which points to an address
|
|
||||||
This function looks for a syscall entry (among the ones that point to valid
|
|
||||||
memory) whose value is @entry.
|
|
||||||
|
|
||||||
@os Loaded OS structure
|
|
||||||
@entry Researched value
|
|
||||||
Returns a syscall ID if some is found, -1 otherwise. */
|
|
||||||
int os_syscall_find(struct os const *os, uint32_t entry);
|
|
||||||
|
|
||||||
/* os_free(): Free an OS file opened with os_load()
|
|
||||||
@os Loaded OS structure */
|
|
||||||
void os_free(struct os const *os);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** File identification (info.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* info_os(): Print general information on an OS file
|
|
||||||
|
|
||||||
This function prints the OS metadata, traverses the syscall table, and
|
|
||||||
shows a few details of known binary regions such as the footer.
|
|
||||||
|
|
||||||
@os Input OS file */
|
|
||||||
void info_os(struct os const *os);
|
|
||||||
|
|
||||||
/* info_binary(): Print general information on a binary file
|
|
||||||
|
|
||||||
This function tries to determine the platform by looking for SH4-only
|
|
||||||
instructions or SH7705 and SH7305-specific registers addresses. The analysis
|
|
||||||
results are printed on stdout.
|
|
||||||
|
|
||||||
@data Input file data (memory-mapped)
|
|
||||||
@len Length of input */
|
|
||||||
void info_binary(void *data, size_t len);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Disassembling (disassembly.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* struct disassembly: Disassembly options */
|
|
||||||
struct disassembly
|
|
||||||
{
|
|
||||||
int binary; /* OS file (0) or binary file (1) */
|
|
||||||
enum mpu mpu; /* Force architecture (or MPU_GUESS) */
|
|
||||||
|
|
||||||
uint32_t start; /* Start address or syscall ID */
|
|
||||||
int syscall; /* Non-zero if [start] is a syscall ID */
|
|
||||||
uint32_t len; /* Length of disassembled region */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* disassembly_os(): Disassemble an address or a syscall
|
|
||||||
Produces a disassembly listing of the program on stdout, annotated with
|
|
||||||
every piece of information that can be extracted from the OS.
|
|
||||||
|
|
||||||
@os Operating system image to disassemble
|
|
||||||
@opt Disassembly region and options */
|
|
||||||
void disassembly_os(struct os const *os, struct disassembly const *opt);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Blind analysis (analysis.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* analysis_short(): Print a one-line summary for an address
|
|
||||||
Prints a list of space-separated elements summarizing the information that
|
|
||||||
can be found about the provided value (typically an address). This summary
|
|
||||||
is often inserted in disassembled code as annotation.
|
|
||||||
|
|
||||||
@os Source OS
|
|
||||||
@value Analyzed value, often an address */
|
|
||||||
void analysis_short(struct os const *os, uint32_t value);
|
|
||||||
|
|
||||||
/* struct analysis: In-depth analysis options */
|
|
||||||
struct analysis
|
|
||||||
{
|
|
||||||
/* Force underlying architecture */
|
|
||||||
enum mpu mpu;
|
|
||||||
|
|
||||||
/* Analysis mode */
|
|
||||||
enum {
|
|
||||||
ANALYSIS_SYSCALL = 0x01,
|
|
||||||
ANALYSIS_ADDRESS = 0x02,
|
|
||||||
ANALYSIS_REGISTER = 0x04,
|
|
||||||
|
|
||||||
ANALYSIS_FULL = 0x07,
|
|
||||||
} type;
|
|
||||||
|
|
||||||
/* Max number of printed occurrences */
|
|
||||||
int occurrences;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FX_FXOS */
|
|
120
fxos/info.c
120
fxos/info.c
|
@ -1,120 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <endianness.h>
|
|
||||||
|
|
||||||
char const *info_str =
|
|
||||||
"Header information:\n"
|
|
||||||
" Bootcode timestamp (DateA) (0x8000ffb0) : %s\n"
|
|
||||||
" Serial number (0x8000ffd0) : %s\n"
|
|
||||||
" Bootcode checksum (0x8000fffc) : 0x%s\n"
|
|
||||||
" OS version (0x80010020) : %s\n";
|
|
||||||
|
|
||||||
char const *footer_str =
|
|
||||||
"\nFooter information:\n"
|
|
||||||
" Detected footer address : 0x8%07x\n"
|
|
||||||
" Langdata entries found : %d\n"
|
|
||||||
" OS date (DateO) (0x8%07x)" " : %s\n"
|
|
||||||
" OS checksum (0x8%07x)" " : 0x%s\n";
|
|
||||||
|
|
||||||
char const *syscall_str =
|
|
||||||
"\nSyscall information:\n"
|
|
||||||
" Syscall table address (0x8001007c) : 0x%08x\n"
|
|
||||||
" Entries that point to valid memory : 0x%x\n"
|
|
||||||
" First seemingly invalid entry : 0x%08x\n"
|
|
||||||
" Syscall entries outside ROM:\n";
|
|
||||||
|
|
||||||
char const *syscall_nonrom_str =
|
|
||||||
" %%%04x -> 0x%08x (%s memory)\n";
|
|
||||||
|
|
||||||
/* extract_str(): Extract a string from the OS file
|
|
||||||
This function checks offsets and bounds and writes "(eof)" if the provided
|
|
||||||
file is too small for the tested offset. */
|
|
||||||
static void extract_str(struct os const * os, uint32_t address, size_t size,
|
|
||||||
char *dst)
|
|
||||||
{
|
|
||||||
if(address + size > os->len)
|
|
||||||
{
|
|
||||||
strcpy(dst, "(eof)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst, os->data + address, size);
|
|
||||||
dst[size] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extract_int(): Extract a string from the OS file */
|
|
||||||
static void extract_int(struct os const *os, uint32_t address, char *dst)
|
|
||||||
{
|
|
||||||
if(address + 4 > os->len)
|
|
||||||
{
|
|
||||||
strcpy(dst, "(eof)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t x;
|
|
||||||
memcpy(&x, os->data + address, 4);
|
|
||||||
x = be32toh(x);
|
|
||||||
sprintf(dst, "%08x", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* info_os(): Print general information on an OS file */
|
|
||||||
void info_os(struct os const *os)
|
|
||||||
{
|
|
||||||
void *data = os->data;
|
|
||||||
size_t len = os->len;
|
|
||||||
|
|
||||||
char bios_timestamp[15];
|
|
||||||
extract_str(os, 0xffb0, 14, bios_timestamp);
|
|
||||||
|
|
||||||
char serial[9];
|
|
||||||
extract_str(os, 0xffd0, 8, serial);
|
|
||||||
|
|
||||||
char bios_checksum[9];
|
|
||||||
extract_int(os, 0xfffc, bios_checksum);
|
|
||||||
|
|
||||||
printf(info_str, bios_timestamp, serial, bios_checksum, os->version);
|
|
||||||
|
|
||||||
if(os->footer == (uint32_t)-1)
|
|
||||||
{
|
|
||||||
printf("\nFooter could not be found.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t addr = os->footer + 8;
|
|
||||||
int langdata = 0;
|
|
||||||
|
|
||||||
while(addr + 8 < len && !memcmp(data + addr, "Langdata", 8))
|
|
||||||
{
|
|
||||||
langdata++;
|
|
||||||
addr += 0x30;
|
|
||||||
}
|
|
||||||
|
|
||||||
char os_timestamp[15];
|
|
||||||
extract_str(os, addr, 14, os_timestamp);
|
|
||||||
|
|
||||||
char os_checksum[9];
|
|
||||||
extract_int(os, addr + 0x18, os_checksum);
|
|
||||||
|
|
||||||
printf(footer_str, os->footer, langdata, addr, os_timestamp,
|
|
||||||
addr + 0x18, os_checksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(syscall_str, os->syscall_table, os->syscalls,
|
|
||||||
os_syscall(os, os->syscalls));
|
|
||||||
|
|
||||||
int total = 0;
|
|
||||||
for(int i = 0; i < os->syscalls; i++)
|
|
||||||
{
|
|
||||||
uint32_t e = os_syscall(os, i);
|
|
||||||
struct region const *r = memory_region(e);
|
|
||||||
if(!r || !strcmp(r->name, "ROM")) continue;
|
|
||||||
|
|
||||||
printf(syscall_nonrom_str, i, e, r->name);
|
|
||||||
total++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!total) printf(" (none)\n");
|
|
||||||
}
|
|
187
fxos/lexer-asm.l
187
fxos/lexer-asm.l
|
@ -1,187 +0,0 @@
|
||||||
%{
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
/* Text value for parser */
|
|
||||||
static char *yylval;
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option prefix="asm"
|
|
||||||
%option noyywrap
|
|
||||||
%option nounput
|
|
||||||
|
|
||||||
code ^[01nmdi]{16}
|
|
||||||
literal [^ ,\t\n]+|[^ ,\t\n(]*"("[^")"\n]*")"[^ ,\t\n]*
|
|
||||||
|
|
||||||
space [ \t]+
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
^#[^\n]* ;
|
|
||||||
{space} ;
|
|
||||||
, ;
|
|
||||||
[\n] yylineno++;
|
|
||||||
|
|
||||||
{code} { yylval = strdup(yytext); return 0; }
|
|
||||||
^.{0,16} { err("%d: invalid opcode at start of line", yylineno); }
|
|
||||||
|
|
||||||
"#imm" { return IMM; }
|
|
||||||
"rn" { return RN; }
|
|
||||||
"rm" { return RM; }
|
|
||||||
"jump8" { return JUMP8; }
|
|
||||||
"jump12" { return JUMP12; }
|
|
||||||
"pcdisp" { return PCDISP; }
|
|
||||||
"@rn" { return AT_RN; }
|
|
||||||
"@rm" { return AT_RM; }
|
|
||||||
"@rm+" { return AT_RMP; }
|
|
||||||
"@rn+" { return AT_RNP; }
|
|
||||||
"@-rn" { return AT_MRN; }
|
|
||||||
"@(disp,"[ ]*"rn)" { return AT_DRN; }
|
|
||||||
"@(disp,"[ ]*"rm)" { return AT_DRM; }
|
|
||||||
"@(r0,"[ ]*"rn)" { return AT_R0RN; }
|
|
||||||
"@(r0,"[ ]*"rm)" { return AT_R0RM; }
|
|
||||||
"@(disp",[ ]*"gbr)" { return AT_DGBR; }
|
|
||||||
{literal} { yylval = strdup(yytext); return LITERAL; }
|
|
||||||
|
|
||||||
<<EOF>> { return -1; }
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* set_code(): Build an efficient representation of an opcode
|
|
||||||
Takes a 16-byte string as argument, representing the parameterized opcode,
|
|
||||||
and computes a bit-based representation inside the assembly structure.
|
|
||||||
|
|
||||||
@code 16-bit opcode made of '0', '1', 'm', 'n', 'd' and 'i'
|
|
||||||
@insn Instruction object */
|
|
||||||
void set_code(char const *code, struct asm_insn *insn)
|
|
||||||
{
|
|
||||||
insn->bits = insn->arg_mask = 0;
|
|
||||||
insn->n_sh = insn->n_mask = 0;
|
|
||||||
insn->m_sh = insn->m_mask = 0;
|
|
||||||
insn->d_sh = insn->d_mask = 0;
|
|
||||||
insn->i_sh = insn->i_mask = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
int c = code[i];
|
|
||||||
|
|
||||||
/* Constant bits */
|
|
||||||
if(c == '0' || c == '1')
|
|
||||||
{
|
|
||||||
insn->bits = (insn->bits << 1) | (c - '0');
|
|
||||||
insn->arg_mask <<= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Argument bits */
|
|
||||||
insn->bits <<= 1;
|
|
||||||
insn->arg_mask = (insn->arg_mask << 1) | 1;
|
|
||||||
|
|
||||||
if(c == 'n')
|
|
||||||
{
|
|
||||||
insn->n_sh = 15 - i;
|
|
||||||
insn->n_mask = (insn->n_mask << 1) | 1;
|
|
||||||
}
|
|
||||||
if(c == 'm')
|
|
||||||
{
|
|
||||||
insn->m_sh = 15 - i;
|
|
||||||
insn->m_mask = (insn->m_mask << 1) | 1;
|
|
||||||
}
|
|
||||||
if(c == 'd')
|
|
||||||
{
|
|
||||||
insn->d_sh = 15 - i;
|
|
||||||
insn->d_mask = (insn->d_mask << 1) | 1;
|
|
||||||
}
|
|
||||||
if(c == 'i')
|
|
||||||
{
|
|
||||||
insn->i_sh = 15 - i;
|
|
||||||
insn->i_mask = (insn->i_mask << 1) | 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
insn->arg_mask = ~insn->arg_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lex_asm(): Assembly table lexer and parser */
|
|
||||||
struct asm_insn *lex_asm(void *data, size_t length, int *count)
|
|
||||||
{
|
|
||||||
/* First count the number of instruction codes */
|
|
||||||
|
|
||||||
YY_BUFFER_STATE buf = yy_scan_bytes(data, length);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
int total = 0, t;
|
|
||||||
while((t = yylex()) != -1)
|
|
||||||
{
|
|
||||||
total += (t == 0);
|
|
||||||
if(t == 0 || t == LITERAL) free(yylval);
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
|
|
||||||
/* Allocate a large enough instruction array */
|
|
||||||
|
|
||||||
struct asm_insn *table = calloc(total, sizeof *table);
|
|
||||||
if(!table)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot allocate memory for database");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lex all instructions and fill in the array */
|
|
||||||
|
|
||||||
buf = yy_scan_bytes(data, length);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
struct asm_insn *insn = table - 1;
|
|
||||||
int line = -1;
|
|
||||||
int named = 1;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
t = yylex();
|
|
||||||
|
|
||||||
if(yylineno != line || t == 0 || t == -1)
|
|
||||||
{
|
|
||||||
/* Finalize current instruction */
|
|
||||||
if(!named) err("%d: unnamed instruction", line);
|
|
||||||
insn++;
|
|
||||||
}
|
|
||||||
if(t == -1) break;
|
|
||||||
|
|
||||||
if(t == 0)
|
|
||||||
{
|
|
||||||
set_code(yylval, insn);
|
|
||||||
free(yylval);
|
|
||||||
line = yylineno;
|
|
||||||
named = 0;
|
|
||||||
}
|
|
||||||
else if(t == LITERAL && !named)
|
|
||||||
{
|
|
||||||
insn->mnemonic = yylval;
|
|
||||||
named = 1;
|
|
||||||
}
|
|
||||||
else if(!named)
|
|
||||||
{
|
|
||||||
err("%d: missing mnemonic", line);
|
|
||||||
}
|
|
||||||
else if(!insn->arg1)
|
|
||||||
{
|
|
||||||
insn->arg1 = t;
|
|
||||||
if(t == LITERAL) insn->literal1 = yylval;
|
|
||||||
}
|
|
||||||
else if(!insn->arg2)
|
|
||||||
{
|
|
||||||
insn->arg2 = t;
|
|
||||||
if(t == LITERAL) insn->literal2 = yylval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
if(count) *count = insn - table;
|
|
||||||
return table;
|
|
||||||
}
|
|
117
fxos/lexer-reg.l
117
fxos/lexer-reg.l
|
@ -1,117 +0,0 @@
|
||||||
%{
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
/* Values for tokens generated by the lexer */
|
|
||||||
static union {
|
|
||||||
char *text;
|
|
||||||
long long integer;
|
|
||||||
} yylval;
|
|
||||||
|
|
||||||
/* Token list */
|
|
||||||
#define NUMBER 0
|
|
||||||
#define SYMBOL 1
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option prefix="reg"
|
|
||||||
%option noyywrap
|
|
||||||
%option nounput
|
|
||||||
|
|
||||||
decimal 0|[1-9][0-9]*
|
|
||||||
octal 0[0-7]+
|
|
||||||
hexa 0x[0-9a-fA-F]+
|
|
||||||
number {decimal}|{octal}|{hexa}
|
|
||||||
|
|
||||||
symbol [^0-9 \t\n][^\n]*
|
|
||||||
|
|
||||||
space [ \t]+
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
^#[^\n]* ;
|
|
||||||
{space} ;
|
|
||||||
[\n] yylineno++;
|
|
||||||
|
|
||||||
{number} { yylval.integer = integer(yytext, NULL); return NUMBER; }
|
|
||||||
{symbol} { yylval.text = strdup(yytext); return SYMBOL; }
|
|
||||||
|
|
||||||
<<EOF>> return -1;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* lex_reg(): Peripheral register table lexer and parser */
|
|
||||||
struct reg_address *lex_reg(void *data, size_t len, int *count)
|
|
||||||
{
|
|
||||||
/* Count number of register descriptions (upper bound) */
|
|
||||||
|
|
||||||
YY_BUFFER_STATE buf = yy_scan_bytes(data, len);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
int total = 0, t;
|
|
||||||
while((t = yylex()) != -1)
|
|
||||||
{
|
|
||||||
total += (t == NUMBER);
|
|
||||||
if(t == SYMBOL) free(yylval.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
|
|
||||||
/* Allocate a large enough register array */
|
|
||||||
|
|
||||||
struct reg_address *table = calloc(total, sizeof *table);
|
|
||||||
if(!table)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot allocate memory for database");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lex all instructions and fill in the array */
|
|
||||||
|
|
||||||
buf = yy_scan_bytes(data, len);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
struct reg_address *reg = table - 1;
|
|
||||||
int line = -1;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
t = yylex();
|
|
||||||
|
|
||||||
if(t == NUMBER || t == -1)
|
|
||||||
{
|
|
||||||
/* Finalize current instruction */
|
|
||||||
if(reg >= table && !reg->name)
|
|
||||||
err("%d: unnamed register", line);
|
|
||||||
else reg++;
|
|
||||||
}
|
|
||||||
if(t == -1) break;
|
|
||||||
|
|
||||||
if(t == NUMBER)
|
|
||||||
{
|
|
||||||
reg->address = yylval.integer;
|
|
||||||
line = yylineno;
|
|
||||||
}
|
|
||||||
else if(t == SYMBOL && reg < table)
|
|
||||||
{
|
|
||||||
err("%d: expected register address", yylineno);
|
|
||||||
free(yylval.text);
|
|
||||||
}
|
|
||||||
else if(t == SYMBOL && !reg->name)
|
|
||||||
{
|
|
||||||
reg->name = yylval.text;
|
|
||||||
}
|
|
||||||
else if(t == SYMBOL)
|
|
||||||
{
|
|
||||||
err("%d: excess names for 0x%08x\n", reg->address);
|
|
||||||
free(yylval.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
if(count) *count = reg - table;
|
|
||||||
return table;
|
|
||||||
}
|
|
123
fxos/lexer-sys.l
123
fxos/lexer-sys.l
|
@ -1,123 +0,0 @@
|
||||||
%{
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
/* Values for tokens generated by the lexer */
|
|
||||||
static union {
|
|
||||||
char *text;
|
|
||||||
long long integer;
|
|
||||||
} yylval;
|
|
||||||
|
|
||||||
/* Token list */
|
|
||||||
#define NUMBER 0
|
|
||||||
#define TEXT 1
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option prefix="sys"
|
|
||||||
%option noyywrap
|
|
||||||
%option nounput
|
|
||||||
|
|
||||||
decimal 0|[1-9][0-9]*
|
|
||||||
octal 0[0-7]+
|
|
||||||
hexa 0x[0-9a-fA-F]+
|
|
||||||
number {decimal}|{octal}|{hexa}
|
|
||||||
|
|
||||||
space [ \t]+
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
^#[^\n]* ;
|
|
||||||
{space} ;
|
|
||||||
[\n] yylineno++;
|
|
||||||
|
|
||||||
{number} { yylval.integer = integer(yytext, NULL); return NUMBER; }
|
|
||||||
[^ \t\n0-9].* { yylval.text = strdup(yytext); return TEXT; }
|
|
||||||
|
|
||||||
<<EOF>> return -1;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* lex_sys(): Syscall table lexer and parser */
|
|
||||||
struct sys_call *lex_sys(void *data, size_t len, int *count)
|
|
||||||
{
|
|
||||||
/* Count the number of syscalls */
|
|
||||||
|
|
||||||
YY_BUFFER_STATE buf = yy_scan_bytes(data, len);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
int total = 0, t;
|
|
||||||
while((t = yylex()) != -1)
|
|
||||||
{
|
|
||||||
total += (t == NUMBER);
|
|
||||||
if(t == TEXT) free(yylval.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
|
|
||||||
/* Allocate a large enough syscall array */
|
|
||||||
|
|
||||||
struct sys_call *table = calloc(total, sizeof *table);
|
|
||||||
if(!table)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot allocate memory for database");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lex all instructions and fill in the array */
|
|
||||||
|
|
||||||
buf = yy_scan_bytes(data, len);
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
struct sys_call *call = table - 1;
|
|
||||||
int line = -1;
|
|
||||||
int named = 1;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
t = yylex();
|
|
||||||
|
|
||||||
if(t == NUMBER || t == -1)
|
|
||||||
{
|
|
||||||
/* Finalize current instruction */
|
|
||||||
if(!named) err("%d: unnamed syscall", line);
|
|
||||||
else call++;
|
|
||||||
}
|
|
||||||
if(t == -1) break;
|
|
||||||
|
|
||||||
if(t == NUMBER)
|
|
||||||
{
|
|
||||||
call->number = yylval.integer;
|
|
||||||
line = yylineno;
|
|
||||||
named = 0;
|
|
||||||
}
|
|
||||||
else if(t == TEXT && call < table)
|
|
||||||
{
|
|
||||||
err("%d: expected syscall id", yylineno);
|
|
||||||
free(yylval.text);
|
|
||||||
}
|
|
||||||
else if(t == TEXT && named == 0)
|
|
||||||
{
|
|
||||||
call->name = yylval.text;
|
|
||||||
named = 1;
|
|
||||||
}
|
|
||||||
else if(t == TEXT && named == 1)
|
|
||||||
{
|
|
||||||
call->descr = yylval.text;
|
|
||||||
named = 2;
|
|
||||||
}
|
|
||||||
else if(t == TEXT)
|
|
||||||
{
|
|
||||||
err("%d: excess qualifiers for syscall 0x%03x", line,
|
|
||||||
call->number);
|
|
||||||
free(yylval.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yy_delete_buffer(buf);
|
|
||||||
if(count) *count = call - table;
|
|
||||||
return table;
|
|
||||||
}
|
|
301
fxos/main.c
301
fxos/main.c
|
@ -1,301 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
static char const *help_string =
|
|
||||||
"usage: %1$s info (<os file> | -b <binary file>)\n"
|
|
||||||
" %1$s disasm <os file> (-a <address> | -s <syscall id>) [options...]\n"
|
|
||||||
" %1$s disasm -b <binary file> [options...]\n"
|
|
||||||
" %1$s analyze [-f] [-s] [-a] [-r] <number> <os file> [options...]\n"
|
|
||||||
"\n"
|
|
||||||
"fxos is a reverse-engineering tool to disassemble and analyze fx9860g-like\n"
|
|
||||||
"OS dumps, providing efficient annotations through an editable database.\n"
|
|
||||||
"\n"
|
|
||||||
"Commands:\n"
|
|
||||||
" info Identify an OS image: version, platform, date, checksums...\n"
|
|
||||||
" Identify the architecture of a binary file.\n"
|
|
||||||
" disasm Disassemble and annotate code with relative address targets,\n"
|
|
||||||
" syscall invocations and hints about memory structure.\n"
|
|
||||||
" analyze Dig an address or syscall number, finding syscall references,\n"
|
|
||||||
" 4-aligned occurrences, memory region and probable role.\n"
|
|
||||||
"\n"
|
|
||||||
"General options:\n"
|
|
||||||
" -b Work with an arbitrary binary file, not an OS\n"
|
|
||||||
"\n"
|
|
||||||
"Table extensions:\n"
|
|
||||||
" --table-asm <file> Use instruction codes and mnemonics from <file>\n"
|
|
||||||
" --table-sys <file> Use syscall prototypes and descriptions from <file>\n"
|
|
||||||
" --table-reg <file> Use peripheral register addresses from <file>\n"
|
|
||||||
"\n"
|
|
||||||
"Disassembly options:\n"
|
|
||||||
" -a <address> Start disassembling at this address\n"
|
|
||||||
" -s <syscall id> Start disassembling at this syscall's address\n"
|
|
||||||
" -l <length> Length of region\n"
|
|
||||||
" -3, --sh3 Assume SH3 OS and platform (default: guess)\n"
|
|
||||||
" -4, --sh4 Assume SH4 OS and platform (default: guess)\n"
|
|
||||||
"\n"
|
|
||||||
"Analysis modes:\n"
|
|
||||||
" -f, --full Run all analysis passes on <number> (same as -sar)\n"
|
|
||||||
" -s, --syscall Run syscall ID analysis\n"
|
|
||||||
" -a, --address Run code/data address analyis\n"
|
|
||||||
" -r, --register Run peripheral register analysis\n"
|
|
||||||
"\n"
|
|
||||||
"Analysis options:\n"
|
|
||||||
" --occurrences <num> Show at most <num> occurrences (integer or \"all\")\n"
|
|
||||||
"\n"
|
|
||||||
"All numbers support base prefixes '0' (octal) and '0x' (hexadecimal).\n";
|
|
||||||
|
|
||||||
#define OPT_ASM 1
|
|
||||||
#define OPT_SYS 2
|
|
||||||
#define OPT_REG 3
|
|
||||||
#define OPT_OCC 4
|
|
||||||
|
|
||||||
/*
|
|
||||||
** "info" command
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main_info(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int error=0, option=0, binary=0;
|
|
||||||
|
|
||||||
struct option const longs[] = {
|
|
||||||
{ "help", no_argument, NULL, 'h' },
|
|
||||||
};
|
|
||||||
|
|
||||||
while(option >= 0 && option != '?')
|
|
||||||
switch((option = getopt_long(argc, argv, "hb", longs, NULL)))
|
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
binary = 1;
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(error) return 1;
|
|
||||||
char const *path = argv[optind + 1];
|
|
||||||
|
|
||||||
if(!path)
|
|
||||||
{
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_context(path, NULL);
|
|
||||||
|
|
||||||
struct os os;
|
|
||||||
if(os_load(path, &os)) { err_pop(); return 1; }
|
|
||||||
|
|
||||||
if(binary)
|
|
||||||
{
|
|
||||||
err("TODO: Binary file info x_x");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info_os(&os);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_free(&os);
|
|
||||||
err_pop();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** "disasm" command
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main_disassembly(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int error=0, option=0;
|
|
||||||
|
|
||||||
/* First load some of fxos' default resources */
|
|
||||||
asm_load(FXSDK_PREFIX "/share/fxsdk/asm-sh3.txt");
|
|
||||||
asm_load(FXSDK_PREFIX "/share/fxsdk/asm-sh4.txt");
|
|
||||||
sys_load(FXSDK_PREFIX "/share/fxsdk/sys-simlo.txt");
|
|
||||||
sys_load(FXSDK_PREFIX "/share/fxsdk/sys-lephe.txt");
|
|
||||||
reg_load(FXSDK_PREFIX "/share/fxsdk/reg-sh7305.txt");
|
|
||||||
reg_load(FXSDK_PREFIX "/share/fxsdk/reg-simlo.txt");
|
|
||||||
|
|
||||||
struct disassembly opt = { 0 };
|
|
||||||
opt.mpu = MPU_GUESS;
|
|
||||||
opt.len = 0x20;
|
|
||||||
|
|
||||||
struct option const longs[] = {
|
|
||||||
{ "help", no_argument, NULL, 'h' },
|
|
||||||
{ "sh3", no_argument, NULL, '3' },
|
|
||||||
{ "sh4", no_argument, NULL, '4' },
|
|
||||||
{ "table-asm", required_argument, NULL, OPT_ASM },
|
|
||||||
{ "table-sys", required_argument, NULL, OPT_SYS },
|
|
||||||
{ "table-reg", required_argument, NULL, OPT_REG },
|
|
||||||
};
|
|
||||||
|
|
||||||
while(option >= 0 && option != '?')
|
|
||||||
switch((option = getopt_long(argc, argv, "hb34a:s:l:", longs, NULL)))
|
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
opt.binary = 1;
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
opt.mpu = MPU_SH7705;
|
|
||||||
break;
|
|
||||||
case '4':
|
|
||||||
opt.mpu = MPU_SH7305;
|
|
||||||
break;
|
|
||||||
case OPT_ASM:
|
|
||||||
asm_load(optarg);
|
|
||||||
break;
|
|
||||||
case OPT_SYS:
|
|
||||||
printf("TODO: Load additional syscall tables x_x\n");
|
|
||||||
break;
|
|
||||||
case OPT_REG:
|
|
||||||
printf("TODO: Load additional register tables x_x\n");
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
case 's':
|
|
||||||
opt.start = integer(optarg, &error);
|
|
||||||
opt.syscall = (option == 's');
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
opt.len = integer(optarg, &error);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(error) return 1;
|
|
||||||
char const *path = argv[optind + 1];
|
|
||||||
|
|
||||||
if(!path)
|
|
||||||
{
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_context(path, NULL);
|
|
||||||
|
|
||||||
if(opt.binary)
|
|
||||||
{
|
|
||||||
printf("TODO: Disassembly binary x_x");
|
|
||||||
err_pop();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct os os;
|
|
||||||
if(os_load(path, &os)) { err_pop(); return 1; }
|
|
||||||
|
|
||||||
disassembly_os(&os, &opt);
|
|
||||||
|
|
||||||
os_free(&os);
|
|
||||||
err_pop();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** "analyze" command
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main_analyze(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int error=0, option=0;
|
|
||||||
struct analysis opt = { 0 };
|
|
||||||
|
|
||||||
struct option const longs[] = {
|
|
||||||
{ "help", no_argument, NULL, 'h' },
|
|
||||||
{ "table-asm", required_argument, NULL, OPT_ASM },
|
|
||||||
{ "table-sys", required_argument, NULL, OPT_SYS },
|
|
||||||
{ "table-reg", required_argument, NULL, OPT_REG },
|
|
||||||
{ "full", no_argument, NULL, 'f' },
|
|
||||||
{ "syscall", no_argument, NULL, 's' },
|
|
||||||
{ "address", no_argument, NULL, 'a' },
|
|
||||||
{ "register", no_argument, NULL, 'r' },
|
|
||||||
{ "occurrences", required_argument, NULL, OPT_OCC },
|
|
||||||
};
|
|
||||||
|
|
||||||
while(option >= 0 && option != '?')
|
|
||||||
switch((option = getopt_long(argc,argv,"hfsar", longs, NULL)))
|
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
fprintf(stderr, help_string, argv[0]);
|
|
||||||
return 0;
|
|
||||||
case OPT_ASM:
|
|
||||||
asm_load(optarg);
|
|
||||||
break;
|
|
||||||
case OPT_SYS:
|
|
||||||
// sys_load(optarg);
|
|
||||||
break;
|
|
||||||
case OPT_REG:
|
|
||||||
// reg_load(optarg);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
opt.type = ANALYSIS_FULL;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
opt.type |= ANALYSIS_SYSCALL;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
opt.type |= ANALYSIS_ADDRESS;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
opt.type |= ANALYSIS_REGISTER;
|
|
||||||
break;
|
|
||||||
case OPT_OCC:
|
|
||||||
opt.occurrences = integer(optarg, &error);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
error = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(error) return 1;
|
|
||||||
|
|
||||||
/* If no analysis mode was specified, do everything */
|
|
||||||
if(!opt.type) opt.type = ANALYSIS_FULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Program entry
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if(argc < 2)
|
|
||||||
{
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *cmd = argv[1];
|
|
||||||
argv[1] = "";
|
|
||||||
|
|
||||||
/* Switch on command name */
|
|
||||||
if(!strcmp(cmd, "info"))
|
|
||||||
return main_info(argc, argv);
|
|
||||||
else if(!strcmp(cmd, "disasm"))
|
|
||||||
return main_disassembly(argc, argv);
|
|
||||||
else if(!strcmp(cmd, "analyze"))
|
|
||||||
return main_analyze(argc, argv);
|
|
||||||
|
|
||||||
else if(!strcmp(cmd, "-?") || !strcmp(cmd, "-h") ||
|
|
||||||
!strcmp(cmd, "--help"))
|
|
||||||
{
|
|
||||||
err(help_string, argv[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
err("invalid operation '%s'", cmd);
|
|
||||||
err("Try '%s --help'.", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
|
|
||||||
/* Shared by all platforms (though ROM is 4M on most) */
|
|
||||||
|
|
||||||
static struct region ROM = { 0x80000000, 0x807fffff, "ROM", MPU_GUESS };
|
|
||||||
static struct region RAM = { 0x88000000, 0x88040000, "RAM", MPU_GUESS };
|
|
||||||
|
|
||||||
static struct region P2_ROM = { 0xa0000000, 0xa07fffff, "P2 ROM", MPU_GUESS };
|
|
||||||
static struct region P2_RAM = { 0xa8000000, 0xa8040000, "P2 RAM", MPU_GUESS };
|
|
||||||
|
|
||||||
/* SH7305 only */
|
|
||||||
|
|
||||||
static struct region RS = { 0xfd800000, 0xfd8007ff, "RS", MPU_SH7305 };
|
|
||||||
static struct region IL = { 0xe5200000, 0xe5203fff, "IL", MPU_SH7305 };
|
|
||||||
static struct region XRAM = { 0xe5007000, 0xe5008fff, "XRAM", MPU_SH7305 };
|
|
||||||
static struct region YRAM = { 0xe5017000, 0xe5018fff, "YRAM", MPU_SH7305 };
|
|
||||||
|
|
||||||
/* A summary */
|
|
||||||
static struct region *regions[] = {
|
|
||||||
&ROM, &RAM, &P2_ROM, &P2_RAM, &IL, &RS, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* memory_in(): Check if an address if inside a given region */
|
|
||||||
static int memory_in(uint32_t address, struct region const *reg)
|
|
||||||
{
|
|
||||||
return reg && address >= reg->start && address <= reg->end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* memory_region(): Find the region where an address is located */
|
|
||||||
struct region const *memory_region(uint32_t address)
|
|
||||||
{
|
|
||||||
for(int i = 0; regions[i]; i++)
|
|
||||||
{
|
|
||||||
if(memory_in(address, regions[i])) return regions[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
91
fxos/os.c
91
fxos/os.c
|
@ -1,91 +0,0 @@
|
||||||
#include <endianness.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
/* os_load(): Load an OS file and find out basic properties */
|
|
||||||
int os_load(char const *path, struct os *os)
|
|
||||||
{
|
|
||||||
if(!path || !os) return 1;
|
|
||||||
|
|
||||||
os->data = map(path, &os->fd, &os->len);
|
|
||||||
if(!os->data) return 1;
|
|
||||||
if(os->len < 0x10080)
|
|
||||||
{
|
|
||||||
err("too small for the OS format I know (min. 0x10080 bytes)",
|
|
||||||
os->len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the OS version */
|
|
||||||
|
|
||||||
memcpy(os->version, os->data + 0x10020, 14);
|
|
||||||
os->version[14] = 0;
|
|
||||||
|
|
||||||
/* Guess the MPU type (or assume SH7305). Until version 03.00, the last
|
|
||||||
digit of the version number indicated the presence of an SH7305 */
|
|
||||||
|
|
||||||
os->mpu = MPU_SH7305;
|
|
||||||
if(!strncmp(os->version, "02.", 3) && os->version[13] == '0')
|
|
||||||
os->mpu = MPU_SH7705;
|
|
||||||
|
|
||||||
/* Find the syscall table address */
|
|
||||||
|
|
||||||
memcpy(&os->syscall_table, os->data + 0x1007c, 4);
|
|
||||||
os->syscall_table = be32toh(os->syscall_table);
|
|
||||||
|
|
||||||
/* Count the number of valid syscall entries */
|
|
||||||
|
|
||||||
os->syscalls = 0;
|
|
||||||
while(memory_region(os_syscall(os, os->syscalls))) os->syscalls++;
|
|
||||||
|
|
||||||
/* Find the footer address (last occurrence of "CASIOABSLangdata") */
|
|
||||||
|
|
||||||
char const *signature = "CASIOABSLangdata";
|
|
||||||
void *occ = NULL, *next = memmem(os->data, os->len, signature, 16);
|
|
||||||
void *end = os->data + os->len;
|
|
||||||
|
|
||||||
while(next)
|
|
||||||
{
|
|
||||||
occ = next;
|
|
||||||
next = memmem(next + 1, end - (next + 1), signature, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
os->footer = (occ) ? (occ - os->data) : (uint32_t)-1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* os_syscall(): Get the address of a syscall entry */
|
|
||||||
uint32_t os_syscall(struct os const *os, int syscall)
|
|
||||||
{
|
|
||||||
uint32_t table_entry = (os->syscall_table & 0x1fffffff) + 4 * syscall;
|
|
||||||
if(table_entry + 4 > os->len) return (uint32_t)-1;
|
|
||||||
|
|
||||||
uint32_t address;
|
|
||||||
memcpy(&address, os->data + table_entry, 4);
|
|
||||||
address = be32toh(address);
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* os_syscall_find(): Find a syscall which points to an address */
|
|
||||||
int os_syscall_find(struct os const *os, uint32_t entry)
|
|
||||||
{
|
|
||||||
/* Try to make this slightly quicker */
|
|
||||||
uint32_t table_entry = (os->syscall_table & 0x1fffffff);
|
|
||||||
entry = htobe32(entry);
|
|
||||||
|
|
||||||
uint32_t *entries = os->data + table_entry;
|
|
||||||
for(int i = 0; i < os->syscalls; i++) if(entries[i] == entry) return i;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* os_free(): Free an OS file opened with os_load() */
|
|
||||||
void os_free(struct os const *os)
|
|
||||||
{
|
|
||||||
if(os && os->data) unmap(os->data, os->fd, os->len);
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
# T6K11 interface
|
|
||||||
0xb4000000 T6K11.REG
|
|
||||||
0xb4010000 T6K11.DATA
|
|
||||||
|
|
||||||
# Exception handling
|
|
||||||
0xff000020 TRA
|
|
||||||
0xff000024 EXPEVT
|
|
||||||
0xff000028 INTEVT
|
|
||||||
0xff2f0004 EXPMASK
|
|
||||||
|
|
||||||
# Memory Management Unit
|
|
||||||
0xff000000 MMU.PTEH
|
|
||||||
0xff000004 MMU.PTEL
|
|
||||||
0xff00000c MMU.TEA
|
|
||||||
0xff000010 MMU.MMUCR
|
|
||||||
0xff000034 MMU.PTEA
|
|
||||||
0xff000070 MMU.PASCR
|
|
||||||
0xff000078 MMU.IRMCR
|
|
||||||
|
|
||||||
# Interrupt controller
|
|
||||||
0xa4140000 INTC.ICR0
|
|
||||||
0xa414001c INTC.ICR1
|
|
||||||
0xa4140010 INTC.INTPRI00
|
|
||||||
0xa4140024 INTC.INTREQ00
|
|
||||||
0xa4140044 INTC.INTMSK00
|
|
||||||
0xa4140064 INTC.INTMSKCLR00
|
|
||||||
0xa41400c0 INTC.NMIFCR
|
|
||||||
0xa4700000 INTC.USERIMSK
|
|
||||||
0xa4080000 INTC.IPRA
|
|
||||||
0xa4080004 INTC.IPRB
|
|
||||||
0xa4080008 INTC.IPRC
|
|
||||||
0xa408000c INTC.IPRD
|
|
||||||
0xa4080010 INTC.IPRE
|
|
||||||
0xa4080014 INTC.IPRF
|
|
||||||
0xa4080018 INTC.IPRG
|
|
||||||
0xa408001c INTC.IPRH
|
|
||||||
0xa4080020 INTC.IPRI
|
|
||||||
0xa4080024 INTC.IPRJ
|
|
||||||
0xa4080028 INTC.IPRK
|
|
||||||
0xa408002c INTC.IPRL
|
|
||||||
0xa4080080 INTC.IMR0
|
|
||||||
0xa4080084 INTC.IMR1
|
|
||||||
0xa4080088 INTC.IMR2
|
|
||||||
0xa408008c INTC.IMR3
|
|
||||||
0xa4080090 INTC.IMR4
|
|
||||||
0xa4080094 INTC.IMR5
|
|
||||||
0xa4080098 INTC.IMR6
|
|
||||||
0xa408009c INTC.IMR7
|
|
||||||
0xa40800a0 INTC.IMR8
|
|
||||||
0xa40800a4 INTC.IMR9
|
|
||||||
0xa40800a8 INTC.IMR10
|
|
||||||
0xa40800ac INTC.IMR11
|
|
||||||
0xa40800b0 INTC.IMR12
|
|
||||||
0xa40800c0 INTC.IMCR0
|
|
||||||
0xa40800c4 INTC.IMCR1
|
|
||||||
0xa40800c8 INTC.IMCR2
|
|
||||||
0xa40800cc INTC.IMCR3
|
|
||||||
0xa40800d0 INTC.IMCR4
|
|
||||||
0xa40800d4 INTC.IMCR5
|
|
||||||
0xa40800d8 INTC.IMCR6
|
|
||||||
0xa40800dc INTC.IMCR7
|
|
||||||
0xa40800e0 INTC.IMCR8
|
|
||||||
0xa40800e4 INTC.IMCR9
|
|
||||||
0xa40800e8 INTC.IMCR10
|
|
||||||
0xa40800ec INTC.IMCR11
|
|
||||||
0xa40800f0 INTC.IMCR12
|
|
||||||
|
|
||||||
# Direct Memory Access Controller: TODO
|
|
||||||
|
|
||||||
# Reset and power-down modes
|
|
||||||
0xa4150020 POWER.STBCR
|
|
||||||
0xa4150030 POWER.MSTPCR0
|
|
||||||
0xa4150034 POWER.MSTPCR1
|
|
||||||
0xa4150038 POWER.MSTPCR2
|
|
||||||
0xa4150040 POWER.BAR
|
|
||||||
|
|
||||||
# Real-Time Clock
|
|
||||||
0xa465fec0 RTC.R64CNT
|
|
||||||
0xa465fec2 RTC.RSECCNT
|
|
||||||
0xa465fec4 RTC.RMINCNT
|
|
||||||
0xa465fec6 RTC.RHRCNT
|
|
||||||
0xa465fec8 RTC.RWKCNT
|
|
||||||
0xa465feca RTC.RDAYCNT
|
|
||||||
0xa465fecc RTC.RMONCNT
|
|
||||||
0xa465fece RTC.RYRCNT
|
|
||||||
0xa465fed0 RTC.RSECAR
|
|
||||||
0xa465fed2 RTC.RMINAR
|
|
||||||
0xa465fed4 RTC.RHRAR
|
|
||||||
0xa465fed6 RTC.RWKAR
|
|
||||||
0xa465fed8 RTC.RDAYAR
|
|
||||||
0xa465feda RTC.RMONAR
|
|
||||||
0xa465fedc RTC.RCR1
|
|
||||||
0xa465fede RTC.RCR2
|
|
||||||
0xa465fee0 RTC.RYRAR
|
|
||||||
0xa465fee4 RTC.RCR3
|
|
||||||
|
|
||||||
# User Break Controller
|
|
||||||
0xff200000 UBC.CBR0
|
|
||||||
0xff200004 UBC.CRR0
|
|
||||||
0xff200008 UBC.CAR0
|
|
||||||
0xff20000c UBC.CAMR0
|
|
||||||
0xff200020 UBC.CBR1
|
|
||||||
0xff200024 UBC.CRR1
|
|
||||||
0xff200028 UBC.CAR1
|
|
||||||
0xff20002c UBC.CAMR1
|
|
||||||
0xff200030 UBC.CDR1
|
|
||||||
0xff200034 UBC.CDMR1
|
|
||||||
0xff200038 UBC.CETR1
|
|
||||||
0xff200600 UBC.CCMFR
|
|
||||||
0xff200620 UBC.CBCR
|
|
||||||
|
|
||||||
# RCLK Watchdog Timer
|
|
||||||
0xa4520000 RWDT.RWTCNT
|
|
||||||
0xA4520004 RWDT.RWTCSR
|
|
|
@ -1,141 +0,0 @@
|
||||||
# Processor version
|
|
||||||
0xff2f0000 CPUOPM
|
|
||||||
0xff000030 PVR
|
|
||||||
0xff000040 CVR
|
|
||||||
0xff000044 PRR
|
|
||||||
|
|
||||||
# Key Scan Interface
|
|
||||||
0xa44b0000 KEYSC.DATA
|
|
||||||
0xa44b000c KEYSC.UCNTREG
|
|
||||||
0xa44b000e KEYSC.AUTOFIXREG
|
|
||||||
0xa44b0010 KEYSC.UMODEREG
|
|
||||||
0xa44b0012 KEYSC.USTATEREG
|
|
||||||
0xa44b0014 KEYSC.UINTREG
|
|
||||||
0xa44b0016 KEYSC.UWSETREG
|
|
||||||
0xa44b0018 KEYSC.UINTERVALREG
|
|
||||||
0xa44b001a KEYSC.OUTPINSET
|
|
||||||
0xa44b001c KEYSC.INPINSET
|
|
||||||
|
|
||||||
# Timer Unit
|
|
||||||
0xa4490004 TMU.TSTR
|
|
||||||
0xa4490008 TMU0.TCOR
|
|
||||||
0xa449000c TMU0.TCNT
|
|
||||||
0xa4490010 TMU0.TCR
|
|
||||||
0xa4490014 TMU1.TCOR
|
|
||||||
0xa4490018 TMU1.TCNT
|
|
||||||
0xa449001c TMU1.TCR
|
|
||||||
0xa4490020 TMU2.TCOR
|
|
||||||
0xa4490024 TMU2.TCNT
|
|
||||||
0xa4490028 TMU2.TCR
|
|
||||||
|
|
||||||
# Serial Communication Interface
|
|
||||||
0xa4410000 SCIF.SCSMR
|
|
||||||
0xa4410004 SCIF.SCBRR
|
|
||||||
0xa4410008 SCIF.SCSCR
|
|
||||||
0xa441000c SCIF.SCFTDR
|
|
||||||
0xa4410010 SCIF.SCFSR
|
|
||||||
0xa4410014 SCIF.SCFRDR
|
|
||||||
0xa4410018 SCIF.SCFCR
|
|
||||||
0xa441001c SCIF.SCFDR
|
|
||||||
0xa4410024 SCIF.SCLSR
|
|
||||||
|
|
||||||
# Pin Function Controller
|
|
||||||
0xa4050100 PFC.PACR
|
|
||||||
0xa4050102 PFC.PBCR
|
|
||||||
0xa4050104 PFC.PCCR
|
|
||||||
0xa4050106 PFC.PDCR
|
|
||||||
0xa4050108 PFC.PECR
|
|
||||||
0xa405010a PFC.PFCR
|
|
||||||
0xa405010c PFC.PGCR
|
|
||||||
0xa405010e PFC.PHCR
|
|
||||||
0xa4050110 PFC.PJCR
|
|
||||||
0xa4050112 PFC.PKCR
|
|
||||||
0xa4050114 PFC.PLCR
|
|
||||||
0xa4050116 PFC.PMCR
|
|
||||||
0xa4050118 PFC.PNCR
|
|
||||||
0xa405014c PFC.PPCR
|
|
||||||
0xa405011a PFC.PQCR
|
|
||||||
0xa405011c PFC.PRCR
|
|
||||||
0xa405011e PFC.PSCR
|
|
||||||
0xa4050140 PFC.PTCR
|
|
||||||
0xa4050142 PFC.PUCR
|
|
||||||
0xa4050144 PFC.PVCR
|
|
||||||
0xa405014e PFC.PSELA
|
|
||||||
0xa4050150 PFC.PSELB
|
|
||||||
0xa4050152 PFC.PSELC
|
|
||||||
0xa4050154 PFC.PSELD
|
|
||||||
0xa4050156 PFC.PSELE
|
|
||||||
0xa405015e PFC.PSELF
|
|
||||||
0xa40501c8 PFC.PSELG
|
|
||||||
0xa40501d6 PFC.PSELH
|
|
||||||
0xa4050158 PFC.HIZCRA
|
|
||||||
0xa405015a PFC.HIZCRB
|
|
||||||
0xa405015c PFC.HIZCRC
|
|
||||||
0xa4050180 PFC.MSELCRA
|
|
||||||
0xa4050182 PFC.MSELCRB
|
|
||||||
0xa4050184 PFC.DRVCRD
|
|
||||||
0xa4050186 PFC.DRVCRA
|
|
||||||
0xa4050188 PFC.DRVCRB
|
|
||||||
0xa405018a PFC.DRVCRC
|
|
||||||
0xa40501c3 PFC.PULCRBSC
|
|
||||||
0xa40501c5 PFC.PULCRTRST
|
|
||||||
0xa4050190 PFC.PULCRA
|
|
||||||
0xa4050191 PFC.PULCRB
|
|
||||||
0xa4050192 PFC.PULCRC
|
|
||||||
0xa4050193 PFC.PULCRD
|
|
||||||
0xa4050194 PFC.PULCRE
|
|
||||||
0xa4050195 PFC.PULCRF
|
|
||||||
0xa4050196 PFC.PULCRG
|
|
||||||
0xa4050197 PFC.PULCRH
|
|
||||||
0xa4050198 PFC.PULCRJ
|
|
||||||
0xa4050199 PFC.PULCRK
|
|
||||||
0xa405019a PFC.PULCRL
|
|
||||||
0xa405019b PFC.PULCRM
|
|
||||||
0xa405019c PFC.PULCRN
|
|
||||||
0xa40501c6 PFC.PULCRP
|
|
||||||
0xa405019d PFC.PULCRQ
|
|
||||||
0xa405019e PFC.PULCRR
|
|
||||||
0xa405019f PFC.PULCRS
|
|
||||||
0xa40501c0 PFC.PULCRT
|
|
||||||
0xa40501c1 PFC.PULCRU
|
|
||||||
0xa40501c2 PFC.PULCRV
|
|
||||||
|
|
||||||
# Bus State Controller
|
|
||||||
0xfec10000 BSC.CMNCR
|
|
||||||
0xfec10004 BSC.CS0BCR
|
|
||||||
0xfec10008 BSC.CS2BCR
|
|
||||||
0xfec1000c BSC.CS3BCR
|
|
||||||
0xfec10010 BSC.CS4BCR
|
|
||||||
0xfec10014 BSC.CS5ABCR
|
|
||||||
0xfec10018 BSC.CS5BBCR
|
|
||||||
0xfec1001c BSC.CS6ABCR
|
|
||||||
0xfec10020 BSC.CS6BBCR
|
|
||||||
0xfec10024 BSC.CS0WCR
|
|
||||||
0xfec10028 BSC.CS2WCR
|
|
||||||
0xfec1002c BSC.CS3WCR
|
|
||||||
0xfec10030 BSC.CS4WCR
|
|
||||||
0xfec10034 BSC.CS5AWCR
|
|
||||||
0xfec10038 BSC.CS5BWCR
|
|
||||||
0xfec1003c BSC.CS6AWCR
|
|
||||||
0xfec10040 BSC.CS6BWCR
|
|
||||||
0xfec10044 BSC.SDCR
|
|
||||||
0xfec10048 BSC.RTCSR
|
|
||||||
0xfec1004c BSC.RTCNT
|
|
||||||
0xfec10050 BSC.RTCOR
|
|
||||||
0xfec14000 BSC.SDMR2
|
|
||||||
0xfec15000 BSC.SDMR3
|
|
||||||
|
|
||||||
# Clock Pulse Generator
|
|
||||||
0xa4150000 CPG.FRQCR
|
|
||||||
0xa4150008 CPG.FCLKCR
|
|
||||||
0xa4150010 CPG.DDCLKCR
|
|
||||||
0xa4150014 CPG.USBCLKCR
|
|
||||||
0xa4150024 CPG.PLLCR
|
|
||||||
0xa4150028 CPG.PLL2CR
|
|
||||||
0xa415003c CPG.SPUCLKCR
|
|
||||||
0xa4150044 CPG.SSCGCR
|
|
||||||
0xa4150050 CPG.FLLFRQ
|
|
||||||
0xa4150060 CPG.LSTATS
|
|
||||||
|
|
||||||
# More addresses are around on Casiopeia.
|
|
||||||
# See http://www.casiopeia.net/forum/viewtopic.php?f=11&t=1756#p14588.
|
|
58
fxos/reg.c
58
fxos/reg.c
|
@ -1,58 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
/* reg_free_item(): Free a peripheral register item */
|
|
||||||
static void reg_free_item(void *item)
|
|
||||||
{
|
|
||||||
struct reg_address *reg = item;
|
|
||||||
free(reg->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reg_load(): Load a peripheral register table */
|
|
||||||
void reg_load(char const *file)
|
|
||||||
{
|
|
||||||
err_context("register", file, NULL);
|
|
||||||
if(!table_available())
|
|
||||||
{
|
|
||||||
err("too many tables, skipping");
|
|
||||||
err_pop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the file to memory */
|
|
||||||
int fd;
|
|
||||||
size_t size;
|
|
||||||
void *data = map(file, &fd, &size);
|
|
||||||
if(!data) { err_pop(); return; }
|
|
||||||
|
|
||||||
/* If the file is named "reg-x.txt", use "x" as the table name */
|
|
||||||
char *name = match_table_name(file, "reg", ".txt");
|
|
||||||
|
|
||||||
/* Parse the contents */
|
|
||||||
int count;
|
|
||||||
struct reg_address *regs = lex_reg(data, size, &count);
|
|
||||||
|
|
||||||
table_create("reg", name, reg_free_item, count, sizeof *regs, regs);
|
|
||||||
|
|
||||||
unmap(data, fd, size);
|
|
||||||
err_pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global storage for reg_match() */
|
|
||||||
static uint32_t reg_match_address;
|
|
||||||
|
|
||||||
/* reg_match(): Search routine for reg_find() */
|
|
||||||
static int reg_match(void *item)
|
|
||||||
{
|
|
||||||
struct reg_address *reg = item;
|
|
||||||
return reg->address == reg_match_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reg_find(): Find information on a given peripheral register address */
|
|
||||||
struct reg_address const *reg_find(uint32_t address)
|
|
||||||
{
|
|
||||||
reg_match_address = address;
|
|
||||||
return table_find("reg", reg_match, NULL, 0);
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
0x000 sys_init
|
|
||||||
0x004 tlb_init
|
|
||||||
void tlb_init(void)
|
|
||||||
0x025 t6k11_read_datareg
|
|
||||||
uint8_t t6k11_read_datareg(void)
|
|
||||||
0x3fc tlb_map
|
|
||||||
void tlb_map(int shifted_vpn, int way, uint32_t data_field)
|
|
|
@ -1,656 +0,0 @@
|
||||||
0x001 vbr_tlb_error
|
|
||||||
0x002 vbr_cpu_address
|
|
||||||
0x003 vbr_tlb_exception
|
|
||||||
0x005 App_RegisterAddins
|
|
||||||
int App_RegisterAddins(void)
|
|
||||||
0x009 App_FindFreeAddinSlot
|
|
||||||
int FindFreeAddinSlot(void)
|
|
||||||
0x00a App_GetAddinHeaderAddr
|
|
||||||
int GetAddindHeaderAddr(int addin_no, int offset, void *result)
|
|
||||||
0x00e App_GetAddindEstrip
|
|
||||||
int App_GetAddindEstrip(int addin_no, int estrip_no, void *result)
|
|
||||||
0x013 GlibAddinAplExecutionCheck
|
|
||||||
0x014 GlibGetAddinLibInfo
|
|
||||||
0x015 GlibGetOSVersionInfo
|
|
||||||
int GlibGetOSVersionInfo(char *a, char *b, short *c, short *d)
|
|
||||||
0x018 MMU_FlushCache
|
|
||||||
0x01b DD_Clear
|
|
||||||
0x01c Bdisp_WriteGraph_VRAM
|
|
||||||
0x01d Bdisp_WriteGraph_DD
|
|
||||||
0x01e Bdisp_WriteGraph_DDVRAM
|
|
||||||
0x022 Bdisp_ReadArea_VRAM
|
|
||||||
0x023 Bdisp_ReadArea_DD
|
|
||||||
0x024 Bdisp_GetDisp_DD
|
|
||||||
0x025 DD_Read
|
|
||||||
0x026 DD_ReadFromPage
|
|
||||||
0x027 DD_WriteToPage
|
|
||||||
0x028 Bdisp_PutDisp_DD
|
|
||||||
0x02a Bdisp_DrawShapeToVRAM
|
|
||||||
0x02f Bdisp_DrawShapeToVRAM
|
|
||||||
0x030 Bdisp_DrawLineVRAM
|
|
||||||
0x031 Bdisp_ClearLineVRAM
|
|
||||||
0x032 Bdisp_DrawShapeToDD
|
|
||||||
0x033 Bdisp_DrawShapeToVRAM_DD
|
|
||||||
0x034 Bdisp_DrawShapeToDD
|
|
||||||
0x035 Bdisp_DrawShapeToVRAM_DD
|
|
||||||
0x039 RTC_Reset
|
|
||||||
void RTC_Reset(unsigned int mode)
|
|
||||||
0x03a RTC_GetTime
|
|
||||||
void RTC_GetTime(uint *hour, uint *minute, uint *second, uint *millisecond)
|
|
||||||
0x03b RTC_GetTicks
|
|
||||||
int RTC_GetTicks(void)
|
|
||||||
0x03c RTC_Elapsed_ms
|
|
||||||
int RTC_Elapsed_ms(int start_value, int duration_ms)
|
|
||||||
0x05c Num_UIntToBCD
|
|
||||||
0x05d Num_BCDToUInt
|
|
||||||
|
|
||||||
0x118 Timer_Install
|
|
||||||
int Timer_Install(int timerID, void *handler, int elapse), also known as Bcre_cychdr
|
|
||||||
0x119 Timer_Deinstall
|
|
||||||
int Timer_Deinstall(int timerID), also known as Bdel_cychdr
|
|
||||||
0x11a Timer_Start
|
|
||||||
int Timer_Start(int timerID)
|
|
||||||
0x11b Timer_Stop
|
|
||||||
int Timer_Stop(int timerID)
|
|
||||||
0x11f Bdisp_PutDispArea_DD
|
|
||||||
0x12d DD_Poweroff
|
|
||||||
0x130 Wait_ms
|
|
||||||
0x132 DD_SetContrast
|
|
||||||
0x133 DD_SetFRS
|
|
||||||
0x134 DD_SetBias
|
|
||||||
0x135 GetVRAMAddress
|
|
||||||
0x136 GetCharacterGlyph
|
|
||||||
0x137 GetCharacterMiniGlyph
|
|
||||||
0x138 Cursor_SetPosition
|
|
||||||
int Cursor_SetPosition(char column, char row)
|
|
||||||
0x139 Cursor_SetFlashStyle
|
|
||||||
int Cursor_SetFlashStyle(short flashStyle)
|
|
||||||
0x13a Cursor_SetFlashMode
|
|
||||||
void Cursor_SetFlashMode(long flashMode)
|
|
||||||
0x13b Cursor_GetSettings
|
|
||||||
uint Cursor_GetSettings(uint *settingsArray)
|
|
||||||
0x13c Print_OS
|
|
||||||
void Print_OS(unsigned char *msg, int type)
|
|
||||||
0x142 Bdisp_AllClr_DD
|
|
||||||
0x143 Bdisp_AllClr_VRAM
|
|
||||||
0x144 Bdisp_AllClr_DDVRAM
|
|
||||||
0x145 Bdisp_GetDisp_VRAM
|
|
||||||
0x146 Bdisp_SetPoint_VRAM
|
|
||||||
0x147 Bdisp_SetPoint_DD
|
|
||||||
0x148 Bdisp_SetPoint_DDVRAM
|
|
||||||
0x149 Bdisp_GetPoint_VRAM
|
|
||||||
0x14a Bdisp_AreaClr_DD
|
|
||||||
0x14b Bdisp_AreaClr_VRAM
|
|
||||||
0x14c Bdisp_AreaClr_DDVRAM
|
|
||||||
0x14d Bdisp_AreaReverseVRAM
|
|
||||||
0x150 PrintXY
|
|
||||||
void PrintXY(int x, int y, unsigned char *msg, int type)
|
|
||||||
0x153 Disp_Save
|
|
||||||
0x154 Disp_Restore
|
|
||||||
0x155 Disp_GetPtr
|
|
||||||
0x156 PopUpWin
|
|
||||||
0x158 Disp_Manage
|
|
||||||
0x159 System_UpdateOS
|
|
||||||
0x15d PrintCR
|
|
||||||
0x15f atoi
|
|
||||||
0x160 LongToAsc
|
|
||||||
int LongToAsc(int value, unsigned char *dest, int digits)
|
|
||||||
0x161 LongToAscHex
|
|
||||||
int LongToAscHex(int value, unsigned char *dest, int digits)
|
|
||||||
0x162 pc_toupper
|
|
||||||
void pc_toupper(char *str)
|
|
||||||
0x163 pc_tolower
|
|
||||||
void pc_tolower(char *str)
|
|
||||||
0x172 strcmp
|
|
||||||
0x173 strcmp
|
|
||||||
0x175 some_datatable
|
|
||||||
0x176 DiagnosticMode
|
|
||||||
0x18a InvertMem
|
|
||||||
void InvertMem(void *memoryrange, int count)
|
|
||||||
0x19f SMEM_Optimization
|
|
||||||
void SMEM_Optimization(void)
|
|
||||||
0x1a9 GUI_ProgressBar
|
|
||||||
0x1b7 Get8x8BitmapPointer_1
|
|
||||||
0x1b8 Get8x8BitmapPointer_2
|
|
||||||
0x1b9 Get8x8BitmapPointer_3
|
|
||||||
0x1ba Get8x8BitmapPointer_4
|
|
||||||
0x1bb Get8x8BitmapPointer_5
|
|
||||||
0x1bc Get8x8BitmapPointer_6
|
|
||||||
0x1bd Get8x8BitmapPointer_7
|
|
||||||
|
|
||||||
0x20e StorageMemory_GetFilePos
|
|
||||||
int StorageMemory_GetFilePos(int handle, int *pos)
|
|
||||||
0x236 RebootOS
|
|
||||||
0x23d RTC_TriggerAlarm
|
|
||||||
void RTC_TriggerAlarm(void)
|
|
||||||
0x23e RTC_SetDateTime
|
|
||||||
void RTC_SetDateTime(unsigned char *[7] time)
|
|
||||||
0x241 Keyboard_ClrBuffer
|
|
||||||
0x242 Bkey_Set_RepeatTime
|
|
||||||
0x243 Bkey_Get_RepeatTime
|
|
||||||
0x244 Bkey_Set_RepeatTime_Default
|
|
||||||
0x245 Keyboard_EnableAutoRepeat
|
|
||||||
0x246 Keyboard_DisableAutoRepeat
|
|
||||||
0x247 Keyboard_GetKeyWait
|
|
||||||
0x248 Keyboard_PutKeycode
|
|
||||||
0x249 Keyboard_GetKeyDownTime
|
|
||||||
short Keyboard_GetKeyDownTime(void)
|
|
||||||
0x24a Keyboard_IsAnyKeyDown
|
|
||||||
int Keyboard_IsAnyKeyDown(short *matrixcode)
|
|
||||||
0x24b Keyboard_IsSpecialKeyDown
|
|
||||||
int Keyboard_IsSpecialKeyDown(short *matrixcode)
|
|
||||||
0x24c Keyboard_IsSpecialKeyDown
|
|
||||||
int Keyboard_IsSpecialKeyDown(short *matrixcode)
|
|
||||||
0x24d Keyboard_KeyDown
|
|
||||||
int Keyboard_KeyDown(void)
|
|
||||||
0x24e Keyboard_SecondaryInterruptHandler
|
|
||||||
0x24f Keyboard_PutKeymatrixCode
|
|
||||||
int Keyboard_PutKeymatrixCode(short *matrixcode)
|
|
||||||
0x251 Keyboard_TimerHandler
|
|
||||||
0x25e Keyboard_PrimaryInterruptHandler
|
|
||||||
0x268 GetFKeyIconPointer
|
|
||||||
void GetFKeyIconPointer(int fkeyno, unsigned char *bitmap)
|
|
||||||
0x284 BCD_GetNaN
|
|
||||||
int BCD_GetNaN(unsigned char *value, unsigned char *result)
|
|
||||||
0x285 Serial_Open_57600
|
|
||||||
int Serial_Open_57600(void)
|
|
||||||
0x286 BCD_AnsToSerial
|
|
||||||
0x28d Comm_Open
|
|
||||||
int Comm_Open(unsigned short parameters)
|
|
||||||
0x28e Comm_Close
|
|
||||||
0x28f Comm_WaitForAnyBuffer
|
|
||||||
int Comm_WaitForAnyBuffer(int timeout_ms, int P2, int *P3)
|
|
||||||
0x290 Comm_ReadOneByte
|
|
||||||
int Comm_ReadOneByte(unsigned char *result)
|
|
||||||
0x291 Comm_TransmitOneByte
|
|
||||||
0x292 Comm_WaitForAndReadNBytes
|
|
||||||
int Comm_WaitForAndReadNBytes(char *buffer, int bytes)
|
|
||||||
0x293 Comm_TransmitNBytes
|
|
||||||
0x294 Comm_ClearReceiveBuffer
|
|
||||||
0x295 Comm_ClearTransmitBuffer
|
|
||||||
0x296 Comm_IsValidPacketAvailable
|
|
||||||
int Comm_IsValidPacketAvailable(unsigned char *result)
|
|
||||||
0x298 Comm_IsOpen
|
|
||||||
0x299 Comm_GetCurrentSelector
|
|
||||||
int Comm_GetCurrentSelector(void)
|
|
||||||
0x2a1 HexToByte
|
|
||||||
int HexToByte(short *hex, char *result)
|
|
||||||
0x2a2 HexToWord
|
|
||||||
int HexToWord(int *hex, short *result)
|
|
||||||
0x2a3 ByteToHex
|
|
||||||
0x2a4 WordToHex
|
|
||||||
0x2a5 Comm_Padding_5C
|
|
||||||
0x2a6 Comm_ReversePadding_5C
|
|
||||||
0x2a7 AscHexToNibble
|
|
||||||
void AscHexToNibble(char hex, char *result)
|
|
||||||
0x2a8 NibbleToAscHex
|
|
||||||
0x2a9 strlen
|
|
||||||
0x2aa slow_memcpy
|
|
||||||
0x2ab Serial_Open2
|
|
||||||
int Serial_Open2(unsigned short parameters)
|
|
||||||
0x2af Comm_Spy0thByte
|
|
||||||
int Comm_Spy0thByte(unsigned char *result)
|
|
||||||
0x2db Comm_ProcessInPacket
|
|
||||||
int Comm_ProcessInPacket(TReceivePacketDesc *rpd)
|
|
||||||
0x2e1 Comm_PrepareAckPacket
|
|
||||||
int Comm_PrepareAckPacket(TReceivePacketDesc *rpd, unsigned char subtype, void *datapointer, unsigned short datasize)
|
|
||||||
0x2e2 Comm_PrepareErrorPacket
|
|
||||||
void Comm_PrepareErrorPacket(TReceivePacketDesc *rpd, unsigned char subtype)
|
|
||||||
0x2e3 Comm_PrepareTerminatePacket
|
|
||||||
void Comm_PrepareTerminatePacket(TReceivePacketDesc *rpd, unsigned char subtype)
|
|
||||||
0x2e4 Comm_PrepareRoleswapPacket
|
|
||||||
void Comm_PrepareRoleswapPacket(TReceivePacketDesc *rpd, unsigned char subtype)
|
|
||||||
0x2e5 Comm_PrepareCheckPacket
|
|
||||||
void Comm_PrepareCheckPacket(TReceivePacketDesc *rpd, unsigned char subtype)
|
|
||||||
0x2e6 Comm_PrepareCommandPacket
|
|
||||||
int Comm_PrepareCommandPacket(TReceivePacketDesc *rpd, unsigned char subtype, void *datapointer, unsigned short datasize)
|
|
||||||
0x2e7 Comm_PrepareDataPacket
|
|
||||||
int Comm_PrepareDataPacket(TReceivePacketDesc *rpd, unsigned char subtype, void *datapointer, unsigned short datasize)
|
|
||||||
0x2ee System_GetOSVersion
|
|
||||||
void System_GetOSVersion(unsigned char *version)
|
|
||||||
|
|
||||||
0x35e memset_range
|
|
||||||
0x35f memset
|
|
||||||
0x363 MCS_CreateDirectory
|
|
||||||
int MCS_CreateDirectory(unsigned char *dir, char *dirno)
|
|
||||||
0x364 MCS_WriteItem
|
|
||||||
int MCS_WriteItem(unsigned char *dir, unsigned char *item, short itemType, int data_length, int buffer)
|
|
||||||
0x366 MCS_DeleteDirectory
|
|
||||||
int MCS_DeleteDirectory(unsigned char *dir)
|
|
||||||
0x367 MCS_DeleteItem
|
|
||||||
int MCS_DeleteItem(unsigned char *dir, unsigned char *item)
|
|
||||||
0x368 MCS_GetState
|
|
||||||
int MCS_GetState(int *maxspace, int *currentload, int *remainingspace)
|
|
||||||
0x369 MCS_GetSystemDirectoryInfo
|
|
||||||
int MCS_GetSystemDirectoryInfo(unsigned char *dir, unsigned int *pdir, char *dirno)
|
|
||||||
0x370 MCS_RenameItem
|
|
||||||
int MCS_RenameItem(unsigned char *srcdir, unsigned char *srcitem, unsigned char *tgtdir, int tgtitem)
|
|
||||||
0x371 MCS_OverwriteData
|
|
||||||
int MCS_OverwriteData(unsigned char *dir, unsigned char *item, int write_offset, int bytes_to_write, void *buffer)
|
|
||||||
0x372 MCS_GetItemData
|
|
||||||
int MCS_GetItemData(unsigned char *dir, unsigned char *item, int offset, int bytes_to_read, void *buffer)
|
|
||||||
0x373 MCS_RenameDirectory
|
|
||||||
int MCS_RenameDirectory(unsigned char *oldname, unsigned char *newname)
|
|
||||||
0x374 BMCSRenameVariable
|
|
||||||
0x375 MCS_SearchDirectory
|
|
||||||
int MCS_SearchDirectory(unsigned char *dir, TMainMemoryDirectoryEntry *dir, char *dirno)
|
|
||||||
0x376 MCS_SearchDirectoryItem
|
|
||||||
int MCS_SearchDirectoryItem(unsigned char *dir, unsigned char *item, char *flags_0, TDirectoryItem *item, int *data, int *data_length)
|
|
||||||
0x37c MCS_GetFirstDataPointerByDirno
|
|
||||||
int MCS_GetFirstDataPointerByDirno(char *dirno, void *pdata)
|
|
||||||
0x37d MCS_GetDirectoryEntryByNumber
|
|
||||||
int MCS_GetDirectoryEntryByNumber(char dirno, TMainMemoryDirectoryEntry *pdir)
|
|
||||||
0x37e MCS_SearchItem
|
|
||||||
int MCS_SearchItem(unsigned char *item, TMainMemoryDirectoryEntry *pdir, unsigned short *itemno)
|
|
||||||
0x37f MCS_str8cpy
|
|
||||||
int MCS_str8cpy(unsigned char *source, unsigned char *target, int mode)
|
|
||||||
0x380 MCS_GetDirectoryEntryAddress
|
|
||||||
void MCS_GetDirectoryEntryAddress(void *directory_entry_address)
|
|
||||||
0x381 MCS_GetCurrentBottomAddress
|
|
||||||
void MCS_GetCurrentBottomAddress(void *current_bottom_address)
|
|
||||||
0x383 MCS_GetCapa
|
|
||||||
int MCS_GetCapa(int *current_bottom)
|
|
||||||
0x392 MCS_GetMainMemoryStart
|
|
||||||
int MCS_GetMainMemoryStart(void)
|
|
||||||
0x3dc Setup_GetInfo
|
|
||||||
int Setup_GetInfo(unsigned char *, int, TSetupInfo *info), where the first arguments are used only in fx-CG 10/20
|
|
||||||
0x3ea the start of a datatable ***
|
|
||||||
0x3ed Interrupt_SetOrClrStatusFlags
|
|
||||||
int Interrupt_SetOrClrStatusFlags(int flagmask, int set)
|
|
||||||
0x3ee Interrupt_QueryStatusFlags
|
|
||||||
int Interrupt_QueryStatusFlags(int flagmask, int clear)
|
|
||||||
0x3f4 PowerOff
|
|
||||||
0x3f5 ClearMainMemory
|
|
||||||
0x3f6 SH7337_TMU_Stop
|
|
||||||
0x3f7 SH7337_TMU_int_handler
|
|
||||||
0x3fa Hmem_SetMMU
|
|
||||||
void Hmem_SetMMU(int virtualPageNumber, int physicalPageNumber, int pageManagement)
|
|
||||||
0x3fb MMU_ConfigureAndFlush
|
|
||||||
void MMU_ConfigureAndFlush(void)
|
|
||||||
0x3fc TLB_SetAddressValue
|
|
||||||
void TLB_SetAddressValue(int entryAddress, int way, int value)
|
|
||||||
0x3fe GetStackPtr
|
|
||||||
0x3ff MMU_FlushCache
|
|
||||||
|
|
||||||
0x400 MMU_ConfigureAndEnable
|
|
||||||
void MMU_ConfigureAndEnable(void)
|
|
||||||
0x404 GetPhysicalROMstart
|
|
||||||
0x405 GetPhysicalRAMstart
|
|
||||||
0x409 Serial_ResetAndDisable
|
|
||||||
void *Serial_ResetAndDisable(void)
|
|
||||||
0x40a Serial_GetInterruptHandler
|
|
||||||
void *Serial_GetInterruptHandler(void)
|
|
||||||
0x40b Serial_SetInterruptHandler
|
|
||||||
int Serial_SetInterruptHandler(int type, void *handler)
|
|
||||||
0x40c Serial_ReadOneByte
|
|
||||||
int Serial_ReadOneByte(unsigned char *result)
|
|
||||||
0x40d Serial_ReadNBytes
|
|
||||||
int Serial_ReadNBytes(unsigned char *result, int max_size, short *actually_transferred)
|
|
||||||
0x40e Serial_BufferedTransmitOneByte
|
|
||||||
int Serial_BufferedTransmitOneByte(unsigned char byte)
|
|
||||||
0x40f Serial_BufferedTransmitNBytes
|
|
||||||
int Serial_BufferedTransmitNBytes(unsigned char *bytes, int requested_count)
|
|
||||||
0x410 Serial_DirectTransmitOneByte
|
|
||||||
int Serial_DirectTransmitOneByte(unsigned char byte)
|
|
||||||
0x411 Serial_GetReceivedBytesAvailable
|
|
||||||
int Serial_GetReceivedBytesAvailable(void)
|
|
||||||
0x412 Serial_GetFreeTransmitSpace
|
|
||||||
int Serial_GetFreeTransmitSpace(void)
|
|
||||||
0x413 Serial_ClearReceiveBuffer
|
|
||||||
int Serial_ClearReceiveBuffer(void)
|
|
||||||
0x414 Serial_ClearTransmitBuffer
|
|
||||||
int Serial_ClearTransmitBuffer(void)
|
|
||||||
0x418 Serial_Open
|
|
||||||
int Serial_Open(unsigned char *mode)
|
|
||||||
0x419 Serial_Close(int mode)
|
|
||||||
0x41b Serial_CallReceiveIntErrorResetHandler
|
|
||||||
void *Serial_CallReceiveIntErrorResetHandler(void)
|
|
||||||
0x41c Serial_CallReceiveIntHandler
|
|
||||||
void *Serial_CallReceiveIntHandler(void)
|
|
||||||
0x41d Serial_CallTransmitIntErrorResetHandler
|
|
||||||
void *Serial_CallTransmitIntErrorResetHandler(void)
|
|
||||||
0x41e Serial_CallTransmitIntHandler
|
|
||||||
void *Serial_CallTransmitIntHandler(void)
|
|
||||||
0x420 OS_inner_Sleep
|
|
||||||
0x422 Serial_SpyNthByte
|
|
||||||
int Serial_SpyNthByte(int byteno_to_spy, unsigned char *result)
|
|
||||||
0x423 Serial_GetStatus
|
|
||||||
void Serial_GetStatus(unsigned int *serial_status)
|
|
||||||
0x425 Serial_IsOpen
|
|
||||||
int Serial_IsOpen(void)
|
|
||||||
0x429 Bfile_identify_device_OS
|
|
||||||
int Bfile_identify_device_OS(const FONTCHARACTER *filename)
|
|
||||||
0x42c Bfile_OpenFile_OS
|
|
||||||
0x42d Bfile_CloseFile_OS
|
|
||||||
0x42e Bfile_GetMediaFree_OS
|
|
||||||
0x42f Bfile_GetFileSize_OS
|
|
||||||
0x431 Bfile_SeekFile_OS
|
|
||||||
0x432 Bfile_ReadFile_OS
|
|
||||||
0x434 Bfile_CreateEntry_OS
|
|
||||||
0x435 Bfile_WriteFile_OS
|
|
||||||
0x438 Bfile_RenameEntry
|
|
||||||
0x439 Bfile_DeleteEntry
|
|
||||||
0x43b Bfile_FindFirst
|
|
||||||
0x43c Bfile_FindNext
|
|
||||||
0x43d Bfile_FindClose
|
|
||||||
0x44e memcpy
|
|
||||||
0x44f memcmp
|
|
||||||
0x450 Bfile_GetFilenameLength
|
|
||||||
int Bfile_GetFilenameLength(const FONTCHARACTER *filename)
|
|
||||||
0x451 Bfile_Name_cmp
|
|
||||||
0x452 Bfile_Name_cpy
|
|
||||||
0x453 Bfile_Name_ncpy
|
|
||||||
0x456 Bfile_NameToStr_ncpy
|
|
||||||
void Bfile_NameToStr_ncpy(char *dest, FONTCHARACTER *src, int n)
|
|
||||||
0x457 Bfile_StrToName_ncpy
|
|
||||||
void Bfile_StrToName_ncpy(FONTCHARACTER *dest, char *src, int n)
|
|
||||||
0x462 GetAppName
|
|
||||||
char *GetAppName(char *dest)
|
|
||||||
0x463 SetAppName
|
|
||||||
int SetAppName(char *src)
|
|
||||||
0x464 CmpAppName
|
|
||||||
int CmpAppName(char *name)
|
|
||||||
0x465 GetIntPtrContent
|
|
||||||
int GetIntPtrContent(unsigned char *ptr)
|
|
||||||
0x467 LongToAscHex
|
|
||||||
int LongToAscHex(int value, char *dest, int digits)
|
|
||||||
0x468 hasSDOption
|
|
||||||
0x469 Battery_DisplayLowStatus
|
|
||||||
int Battery_DisplayLowStatus(int delayflag)
|
|
||||||
0x46b App_BuiltInCount
|
|
||||||
int App_BuiltInCount(void)
|
|
||||||
0x476 Battery_IsLow
|
|
||||||
int Battery_IsLow(void)
|
|
||||||
0x477 EnableGetkeyToMainFunctionReturn
|
|
||||||
void EnableGetkeyToMainFunctionReturn(void)
|
|
||||||
0x478 DisableGetkeyToMainFunctionReturn
|
|
||||||
void DisableGetkeyToMainFunctionReturn(void)
|
|
||||||
0x47f SetAutoPowerOffTime
|
|
||||||
0x480 GetAutoPowerOffTime
|
|
||||||
0x486 GetdatatablePtr
|
|
||||||
0x48d SetAutoPowerOffFlag
|
|
||||||
0x48e GetAutoPowerOffFlag
|
|
||||||
0x492 Battery_IsLow
|
|
||||||
int Battery_IsLow(int delayflag)
|
|
||||||
0x494 CallbackAtQuitMainFunction
|
|
||||||
0x495 Battery_DisplayLowStatus
|
|
||||||
int Battery_DisplayLowStatus(int delayflag)
|
|
||||||
0x499 Heap_SetTopChunk
|
|
||||||
int Heap_SetTopChunk(int size)
|
|
||||||
0x49a App_Start
|
|
||||||
int App_Start(int r4, int r5, int index, int force)
|
|
||||||
0x49c Battery_GetStatus
|
|
||||||
int Battery_GetStatus(int delayflag)
|
|
||||||
0x49e RebootOS
|
|
||||||
0x4a0 AUX_DisplayErrorMessage
|
|
||||||
void AUX_DisplayErrorMessage(void)
|
|
||||||
0x4ad USB_InterruptHandler
|
|
||||||
0x4ae USB_TimerHandler
|
|
||||||
void USB_TimerHandler(void)
|
|
||||||
0x4b0 AUX_DisplayFKeyIcons
|
|
||||||
void AUX_DisplayFKeyIcons(void)
|
|
||||||
0x4cb Keyboard_RemapFKeyCode
|
|
||||||
void Keyboard_RemapFKeyCode(int mode, TFKeyDef *source)
|
|
||||||
0x4d1 AUX_DisplayFKeyIcon
|
|
||||||
void AUX_DisplayFKeyIcon(int pos, unsigned char *bitmap)
|
|
||||||
0x4dc char Setup_GetEntry(unsigned int index)
|
|
||||||
0x4dd Setup_SetEntry
|
|
||||||
char *Setup_SetEntry(unsigned int index, char setting)
|
|
||||||
0x4de Setup_GetEntryPtr
|
|
||||||
char *Setup_GetEntryPtr(unsigned int index)
|
|
||||||
0x4df Alpha_GetData
|
|
||||||
char *Alpha_GetData(char var, char *dest)
|
|
||||||
0x4e0 Alpha_SetData
|
|
||||||
char *Alpha_SetData(char var, char *src)
|
|
||||||
0x4e1 Alpha_ClearAll
|
|
||||||
void Alpha_ClearAll(void)
|
|
||||||
0x4e6 HourGlass
|
|
||||||
void HourGlass(void)
|
|
||||||
0x4e9 LocalizeStringID
|
|
||||||
0x4f5 BCD_ToStrAsNumber1
|
|
||||||
int BCD_ToStrAsNumber1(char *data, char *string)
|
|
||||||
0x4f6 BCD_ToStrAsNumber2
|
|
||||||
int BCD_ToStrAsNumber2(char *data, char *string)
|
|
||||||
|
|
||||||
0x500 BCDToInternal
|
|
||||||
int BCDToInternal(TBCDinternal *target, TBCDvalue *source)
|
|
||||||
0x518 Setup_GetEntry_3E
|
|
||||||
0x519 Setup_GetEntry_40
|
|
||||||
0x51a Setup_SetEntry_3E
|
|
||||||
0x51b Setup_SetEntry_40
|
|
||||||
0x531 MB_IsLead
|
|
||||||
int MB_IsLead(char c)
|
|
||||||
0x533 MB_ElementCount
|
|
||||||
int MB_ElementCount(char *str)
|
|
||||||
0x534 MB_ByteCount
|
|
||||||
int MB_ByteCount(char *str)
|
|
||||||
0x536 MB_strcat
|
|
||||||
char *MB_strcat(char *dest, char *src)
|
|
||||||
0x537 MB_strncat
|
|
||||||
char *MB_strncat(char *dest, char *src, int bytes)
|
|
||||||
0x538 MB_strcpy
|
|
||||||
char *MB_strcpy(char *dest, char *src)
|
|
||||||
0x53c MB_GetSecondElemPtr
|
|
||||||
char *MB_GetSecondElemPtr(char *str)
|
|
||||||
0x53d MB_GetElement
|
|
||||||
short MB_GetElement(char *str)
|
|
||||||
0x53e MB_CopyToHeap
|
|
||||||
char *MB_CopyToHeap(char *src)
|
|
||||||
0x53f memcmp
|
|
||||||
0x541 itoa
|
|
||||||
0x542 to_uppercase
|
|
||||||
0x543 to_lowercase
|
|
||||||
0x544 BCD_0
|
|
||||||
0x545 BCD_1
|
|
||||||
0x546 BCD_2
|
|
||||||
0x547 BCD_10
|
|
||||||
0x548 BCD_1/3
|
|
||||||
0x549 BCD_0.5
|
|
||||||
0x54a BCD_32767
|
|
||||||
0x54b BCD_-32768
|
|
||||||
0x54c BCD_65536
|
|
||||||
0x54d BCD_0x7fffffff
|
|
||||||
0x54e BCD_-2Gi
|
|
||||||
0x54f BCD_4Gi
|
|
||||||
0x550 BCD_pi
|
|
||||||
0x551 BCD_2pi
|
|
||||||
0x552 BCD_pi/2
|
|
||||||
0x553 BCD_e
|
|
||||||
0x554 BCD_5
|
|
||||||
0x5a6 BCD_SetAsInt
|
|
||||||
int BCD_SetAsInt(int input, TBCDValue *result)
|
|
||||||
0x5af BCD_pi/4
|
|
||||||
0x5b0 BCD_ln(10)
|
|
||||||
0x5b1 BCD_ln(2)
|
|
||||||
0x5b2 BCD_9.99e+99
|
|
||||||
0x5b3 BCD_-9.99e+99
|
|
||||||
0x5b4 BCD_9.99999999999999e+99
|
|
||||||
0x5b5 BCD_227.85
|
|
||||||
0x5b6 BCD_sqrt(2)
|
|
||||||
0x5b7 BCD_sqrt(2)/2
|
|
||||||
0x5b8 BCD_506.6282746310
|
|
||||||
|
|
||||||
0x645 CalculateExpression
|
|
||||||
void CalculateExpression(char **formula, char opcode[2], TBCDValue *result, int p4)
|
|
||||||
0x64a CalculateExpression0
|
|
||||||
0x652 PRGM_NextOpcode
|
|
||||||
void PRGM_NextOpcode(char opcode[2], char **program)
|
|
||||||
0x6a6 PRGM_IsEndOfLine
|
|
||||||
int PRGM_IsEndOfLine(char *opcode)
|
|
||||||
0x6c4 Keyboard_PRGM_GetKey
|
|
||||||
int Keyboard_PRGM_GetKey(TBCDValue *result)
|
|
||||||
0x6d4 Alpha_GetData2
|
|
||||||
int Alpha_GetData2(char var, char *dest)
|
|
||||||
|
|
||||||
0x713 Print_ClearLine
|
|
||||||
0x763 Bdisp_DrawRectangle
|
|
||||||
void Bdisp_DrawRectangle(int x1, int y1, int x2, int y2)
|
|
||||||
0x7fc OpcodeToStr
|
|
||||||
int OpcodeToStr(unsigned short opcode, unsigned char *string)
|
|
||||||
|
|
||||||
0x804 CLIP_Store
|
|
||||||
int CLIP_Store(unsigned char *buffer, int length)
|
|
||||||
0x807 locate
|
|
||||||
0x808 Print
|
|
||||||
0x809 PrintRev
|
|
||||||
0x80a PrintC
|
|
||||||
0x80b PrintRevC
|
|
||||||
0x80c PrintLine
|
|
||||||
0x80d PrintRLine
|
|
||||||
0x80e Cursor_GetFlashStyle
|
|
||||||
int Cursor_GetFlashStyle(void)
|
|
||||||
0x80f Cursor_GetSettings
|
|
||||||
int Cursor_GetSettings(struct CursorSettings *settings)
|
|
||||||
0x811 Cursor_SetFlashOn
|
|
||||||
void Cursor_SetFlashOn(char flash_style)
|
|
||||||
0x812 Cursor_SetFlashOff
|
|
||||||
void Cursor_SetFlashOff(void)
|
|
||||||
0x813 SaveDisp
|
|
||||||
0x814 RestoreDisp
|
|
||||||
0x829 MCS_CreateDirectory
|
|
||||||
unsigned char *MCS_CreateDirectory(unsigned char *dir)
|
|
||||||
0x82a MCS_PutInternalItem
|
|
||||||
int MCS_PutInternalItem(char dirtype, unsigned char *item, int data_len, void *buffer)
|
|
||||||
0x82b MCSPutVar2
|
|
||||||
int MCSPutVar2(unsigned char *dir, unsigned char *item, int data_len, void *buffer)
|
|
||||||
0x830 MCSOvwDat2
|
|
||||||
int MCSOvwDat2(unsigned char *dir, unsigned char *item, int bytes_to_write, void *buffer, int write_offset)
|
|
||||||
0x832 MCS_OverwriteOpenItem
|
|
||||||
int MCS_OverwriteOpenItem(int bytes_to_write, void *buffer, int write_offset)
|
|
||||||
0x833 MCS_ClearInternalDirectory
|
|
||||||
int MCS_ClearInternalDirectory(char dirtype)
|
|
||||||
0x834 MCS_ClearDirectory
|
|
||||||
int MCS_ClearDirectory(unsigned char *dir)
|
|
||||||
0x835 MCS_DeleteInternalItem
|
|
||||||
int MCS_DeleteInternalItem(char dirtype, unsigned char *dir)
|
|
||||||
0x836 MCSDelVar2
|
|
||||||
int MCSDelVar2(unsigned char *dir, unsigned char *item)
|
|
||||||
0x83a MCS_GotoInternalItem
|
|
||||||
int MCS_GotoInternalItem(char dirtype, unsigned char *item, int direction)
|
|
||||||
0x83b MCS_OpenMainMemoryItem
|
|
||||||
int MCS_OpenMainMemoryItem(unsigned char *dir, unsigned char *item, char direction)
|
|
||||||
0x83c MCS_GotoHandleNeighbour
|
|
||||||
int MCS_GotoHandleNeighbour(char direction)
|
|
||||||
0x83d MCS_CheckOpenedItem
|
|
||||||
int MCS_CheckOpenedItem(char *dirtype, int *data_len)
|
|
||||||
0x83e MCS_GetOpenItem
|
|
||||||
int MCS_GetOpenItem(unsigned char *item)
|
|
||||||
0x83f MCS_OpenInternalDirectoryItem
|
|
||||||
int MCS_OpenInternalDirectoryItem(char dirtype, unsigned char *item, int *data_len)
|
|
||||||
0x840 MCSGetDlen2
|
|
||||||
int MCSGetDlen2(unsigned char *dir, unsigned char *item, int *data_len)
|
|
||||||
0x841 MCSGetData1
|
|
||||||
int MCSGetData1(int offset, int len_to_copy, void *buffer)
|
|
||||||
0x843 MCS_MapMCS_Result
|
|
||||||
int MCS_MapMCS_Result(void)
|
|
||||||
0x844 MCSGetCapa
|
|
||||||
0x84d MCS_OpenAlphaMemItem
|
|
||||||
int MCS_OpenAlphaMemItem(char variablename, int *data_len, void *data_ptr)
|
|
||||||
0x852 MCS_DirtypeToItemtype
|
|
||||||
int MCS_DirtypeToItemtype(char dirtype)
|
|
||||||
0x853 MCS_ItemtypeToDirtype
|
|
||||||
int MCS_ItemtypeToDirtype(char itemtype)
|
|
||||||
0x863 MCS_DirtypeToName
|
|
||||||
unsigned char *MCS_DirtypeToName(char dirtype)
|
|
||||||
0x866 MCS_MapError
|
|
||||||
int MCS_MapError(int error_in)
|
|
||||||
0x869 Alpha_ClearAllAndAns
|
|
||||||
void Alpha_ClearAllAndAns(void)
|
|
||||||
0x86f MCS_DeleteDirectoryItems
|
|
||||||
void MCS_DeleteDirectoryItems(unsigned char *dir)
|
|
||||||
0x8db EditExpression
|
|
||||||
int EditExpression(int mode, short key, int row, TBCDValue *value, char *editbuffer, short editbufferlen, char *pretext, int mode2)
|
|
||||||
0x8dc EditValue
|
|
||||||
int EditValue(int mode, short key, int row, TBCDValue *value, char *pretext)
|
|
||||||
0x8e6 EditMBStringCtrl
|
|
||||||
void EditMBStringCtrl(unsigned char *, int xposmax, void *, void *, void *, int, int)
|
|
||||||
0x8ea DisplayMBString
|
|
||||||
void DisplayMBString(unsigned char *, int, int xpos, int x, int y)
|
|
||||||
0x8ec EditMBStringChar
|
|
||||||
void EditMBStringChar(unsigned char *, int xposmax, int xpos, int char)
|
|
||||||
0x8f7 DisplayMBString2
|
|
||||||
void DisplayMBString2(int, unsigned char *, int, int xpos, int zero, int x, int y, int, int, int)
|
|
||||||
0x8fe PopupWin
|
|
||||||
void PopupWin(int nlines)
|
|
||||||
|
|
||||||
0x901 DisplayMessageBox
|
|
||||||
void DisplayMessageBox(int height, unsigned char *message)
|
|
||||||
0x905 DisplayErrorMessage
|
|
||||||
void DisplayErrorMessage(int id)
|
|
||||||
0x90b SetShiftAlphaState
|
|
||||||
0x90c GetInsOverwriteState
|
|
||||||
0x90d SetInsOverwriteState
|
|
||||||
0x90e ClrShiftAlphaState
|
|
||||||
0x90f GetKey
|
|
||||||
int GetKey(unsigned int *keycode)
|
|
||||||
0x910 PutKey
|
|
||||||
int PutKey(int keycode, int mode)
|
|
||||||
0x91b GetShiftAlphaState
|
|
||||||
0x924 TestMode
|
|
||||||
void TestMode(void)
|
|
||||||
0x954 DisplayErrorMessage
|
|
||||||
0x985 App_CONICS
|
|
||||||
0x998 App_DYNA
|
|
||||||
0x9ad PrintXY
|
|
||||||
0x9df App_EACT
|
|
||||||
0x9e1 App_Equation
|
|
||||||
0x9e2 App_EQUA
|
|
||||||
0x9f5 App_Program
|
|
||||||
|
|
||||||
0xa00 App_FINANCE
|
|
||||||
0xa1f Keyboard_RemapFKeyCode
|
|
||||||
void Keyboard_RemapFKeyCode(TKeyDef *workspace, TKeyDef *source, int mode)
|
|
||||||
0xa35 AUX_DisplayMessage
|
|
||||||
0xa48 App_GRAPH_TABLE
|
|
||||||
0xa4a App_LINK
|
|
||||||
0xa6a App_Optimization
|
|
||||||
0xa6b App_Memory
|
|
||||||
0xa75 App_RECUR
|
|
||||||
0xa97 App_RUN_MAT_EXE
|
|
||||||
0xaae App_RUN_MAT
|
|
||||||
0xac6 App_STAT
|
|
||||||
0xac8 App_SYSTEM
|
|
||||||
0xacc free
|
|
||||||
0xacd malloc
|
|
||||||
0xace memcmp
|
|
||||||
0xacf smart_memcpy
|
|
||||||
0xad0 memset
|
|
||||||
0xad4 strcat
|
|
||||||
0xad5 smart_strcmp
|
|
||||||
0xad6 strlen
|
|
||||||
0xad7 strncat
|
|
||||||
0xad8 strncmp
|
|
||||||
0xad9 strncpy
|
|
||||||
0xada strrchr
|
|
||||||
0xae8 CatalogDialog
|
|
||||||
|
|
||||||
0xc4f PrintMiniSd
|
|
||||||
0xca7 OpcodeType
|
|
||||||
int OpcodeType(char *);
|
|
||||||
0xcb0 Basic_Send_Send38k
|
|
||||||
0xcb1 Basic_Receive_Receive38k
|
|
||||||
0xcb2 Basic_OpenComPort38k_CloseComPort38k
|
|
||||||
0xcc4 InputNumber
|
|
||||||
int InputNumber(unsigned char *heading, int maxlen, int mode)
|
|
||||||
0xcc5 InputString
|
|
||||||
int InputString(unsigned char *buffer, unsigned char *heading, int maxlen)
|
|
||||||
0xccb GetRAMSize
|
|
||||||
int GetRAMSize(void)
|
|
||||||
0xcd0 another_diagnostic_dialog
|
|
||||||
|
|
||||||
0xd64 InputDateDialog
|
|
||||||
int InputDateDialog(int *day, int *month, int *year, int *p4)
|
|
||||||
0xd65 InputMonthDialog
|
|
||||||
int InputMonthDialog(int *month, int *p2)
|
|
||||||
0xd66 InputDayDialog
|
|
||||||
int InputDayDialog(int *day, int *p2)
|
|
||||||
0xd67 InputYearDialog
|
|
||||||
int InputYearDialog(int *year, int *p2)
|
|
||||||
0xdab StoreExpressionToGraphFuncMemory
|
|
||||||
void StoreExpressionToGraphFuncMemory(int fun_no, int, char *expression)
|
|
||||||
|
|
||||||
0xe6b calloc
|
|
||||||
0xe6c memmove
|
|
||||||
0xe6d realloc
|
|
||||||
0xe6e strchr
|
|
||||||
0xe6f strstr
|
|
59
fxos/sys.c
59
fxos/sys.c
|
@ -1,59 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <util.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* sys_free_item(): Free a syscall description item */
|
|
||||||
static void sys_free_item(void *item)
|
|
||||||
{
|
|
||||||
struct sys_call *call = item;
|
|
||||||
free(call->name);
|
|
||||||
free(call->descr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sys_load(): Load a syscall table */
|
|
||||||
void sys_load(char const *file)
|
|
||||||
{
|
|
||||||
err_context("syscall", file, NULL);
|
|
||||||
if(!table_available())
|
|
||||||
{
|
|
||||||
err("too many tables, skipping");
|
|
||||||
err_pop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the file to memory */
|
|
||||||
int fd;
|
|
||||||
size_t size;
|
|
||||||
void *data = map(file, &fd, &size);
|
|
||||||
if(!data) { err_pop(); return; }
|
|
||||||
|
|
||||||
/* If the file is named "sys-x.txt", use "x" as the table name */
|
|
||||||
char *name = match_table_name(file, "sys", ".txt");
|
|
||||||
|
|
||||||
/* Parse the contents */
|
|
||||||
int count;
|
|
||||||
struct sys_call *calls = lex_sys(data, size, &count);
|
|
||||||
|
|
||||||
table_create("sys", name, sys_free_item, count, sizeof *calls, calls);
|
|
||||||
|
|
||||||
unmap(data, fd, size);
|
|
||||||
err_pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global storage for the sys_match() function */
|
|
||||||
static uint32_t sys_match_number;
|
|
||||||
|
|
||||||
/* sys_match(): Search routine for sys_find() */
|
|
||||||
static int sys_match(void *item)
|
|
||||||
{
|
|
||||||
struct sys_call *call = item;
|
|
||||||
return call->number == sys_match_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sys_find(): Find information on a given syscall number */
|
|
||||||
struct sys_call const *sys_find(uint32_t number)
|
|
||||||
{
|
|
||||||
sys_match_number = number;
|
|
||||||
return table_find("sys", sys_match, NULL, 0);
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Up to 128 tables can be defined */
|
|
||||||
#define MAX 128
|
|
||||||
static struct table db[MAX] = { 0 };
|
|
||||||
/* Number of tables currently used */
|
|
||||||
static int db_size = 0;
|
|
||||||
|
|
||||||
/* table_free(): Free a table and its contents
|
|
||||||
@t Table pointer */
|
|
||||||
static void table_free(struct table *t)
|
|
||||||
{
|
|
||||||
if(!t) return;
|
|
||||||
free(t->name);
|
|
||||||
|
|
||||||
if(t->items) for(int i = 0; i < t->count; i++)
|
|
||||||
{
|
|
||||||
t->free_item(t->items + i * t->size);
|
|
||||||
}
|
|
||||||
free(t->items);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* table_quit(): Destroy all allocated tables and release memory */
|
|
||||||
__attribute__((destructor))
|
|
||||||
static void table_quit(void)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < db_size; i++) table_free(&db[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* table_available(): Whether a table can be allocated */
|
|
||||||
int table_available(void)
|
|
||||||
{
|
|
||||||
return db_size < MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* table_create(): Create a new table */
|
|
||||||
void table_create(char const *type, char *name, void (*free_item)(void *),
|
|
||||||
int count, size_t size, void *items)
|
|
||||||
{
|
|
||||||
if(!table_available()) return;
|
|
||||||
struct table *t = &db[db_size++];
|
|
||||||
|
|
||||||
t->type = type;
|
|
||||||
t->name = name;
|
|
||||||
t->free_item = free_item;
|
|
||||||
t->count = count;
|
|
||||||
t->size = size;
|
|
||||||
t->items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* table_find(): Find matching entries in the database tables */
|
|
||||||
void *table_find(char const *type, int (*match)(void *), char const **name,
|
|
||||||
int next)
|
|
||||||
{
|
|
||||||
static int table = 0;
|
|
||||||
static int index = 0;
|
|
||||||
if(!next) table = index = 0;
|
|
||||||
|
|
||||||
while(table < db_size)
|
|
||||||
{
|
|
||||||
struct table const *t = &db[table];
|
|
||||||
|
|
||||||
if(!strcmp(t->type, type))
|
|
||||||
while(index < t->count)
|
|
||||||
{
|
|
||||||
void *entry = t->items + index * t->size;
|
|
||||||
index++;
|
|
||||||
if(match(entry))
|
|
||||||
{
|
|
||||||
if(name) *name = t->name;
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table++;
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
98
fxos/util.c
98
fxos/util.c
|
@ -1,98 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <fxos.h>
|
|
||||||
#include <errors.h>
|
|
||||||
|
|
||||||
/* integer(): Convert base 8, 10 or 16 into integers */
|
|
||||||
long long integer(char const *str, int *error)
|
|
||||||
{
|
|
||||||
char *end;
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
long long ll = strtoll(str, &end, 0);
|
|
||||||
if(errno == ERANGE)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "error: integer is too large: '%s'\n", str);
|
|
||||||
if(error) *error = 1;
|
|
||||||
|
|
||||||
/* In my situation this is often better than LLONG_MIN/MAX */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*end)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "invalid integer: '%s'\n", str);
|
|
||||||
if(error) *error = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ll;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* match_table_name(): Some specific matching on filenames */
|
|
||||||
char *match_table_name(char const *path, char const *type, char const *suffix)
|
|
||||||
{
|
|
||||||
char const *base = strrchr(path, '/');
|
|
||||||
base = (base) ? (base + 1) : (path);
|
|
||||||
|
|
||||||
size_t len = strlen(base);
|
|
||||||
size_t len_t = strlen(type);
|
|
||||||
size_t len_s = strlen(suffix);
|
|
||||||
|
|
||||||
if(len > len_t + len_s + 1
|
|
||||||
&& !strncmp(type, base, len_t)
|
|
||||||
&& base[len_t] == '-'
|
|
||||||
&& !strcmp(suffix, base + len - len_s))
|
|
||||||
{
|
|
||||||
return strndup(base + len_t + 1, len - len_t - len_s - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return strdup(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* map(): Map a file to memory */
|
|
||||||
void *map(char const *path, int *fd, size_t *size)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
struct stat statbuf;
|
|
||||||
|
|
||||||
*fd = open(path, O_RDONLY);
|
|
||||||
if(*fd < 0)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot open file");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = fstat(*fd, &statbuf);
|
|
||||||
if(x < 0)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot stat file");
|
|
||||||
close(*fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = statbuf.st_size;
|
|
||||||
|
|
||||||
void *data = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, *fd, 0);
|
|
||||||
if(data == MAP_FAILED)
|
|
||||||
{
|
|
||||||
errf(ERR_ERRNO, "cannot map file");
|
|
||||||
close(*fd);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unmap(): Unmap a file loaded with map() */
|
|
||||||
void unmap(void *data, int fd, size_t size)
|
|
||||||
{
|
|
||||||
munmap(data, size);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
44
fxos/util.h
44
fxos/util.h
|
@ -1,44 +0,0 @@
|
||||||
//---
|
|
||||||
// util: Utility functions
|
|
||||||
//---
|
|
||||||
|
|
||||||
#ifndef FXOS_UTIL
|
|
||||||
#define FXOS_UTIL
|
|
||||||
|
|
||||||
/* integer(): Convert base 8, 10 or 16 into integers
|
|
||||||
Prints an error message and sets *error to 1 in case of conversion error or
|
|
||||||
overflow.
|
|
||||||
|
|
||||||
@str Original integer representation ("10", "0x1f", "07")
|
|
||||||
@error Set to 1 on error, otherwise unchanged (can be NULL)
|
|
||||||
Returns result of conversion (valid if *error is not 1) */
|
|
||||||
long long integer(const char *str, int *error);
|
|
||||||
|
|
||||||
/* match_table_name(): Some specific matching on filenames
|
|
||||||
Returns the table name to associate with the file located at @path for a
|
|
||||||
table of type @type, with file suffix @suffix.
|
|
||||||
|
|
||||||
Essentially if the basename of the file at @path is on the form
|
|
||||||
{@type}-{x}{@suffix}
|
|
||||||
then an malloc'ed copy of x is returned. Otherwise an malloc'ed copy of the
|
|
||||||
basename is returned. */
|
|
||||||
char *match_table_name(char const *path, char const *type, char const *suffix);
|
|
||||||
|
|
||||||
/* map(): Map a file to memory
|
|
||||||
Maps a file given by its path to memory, and return the associated region,
|
|
||||||
a file descriptor and the size.
|
|
||||||
|
|
||||||
@path File path
|
|
||||||
@fd Will be set to fd of open file
|
|
||||||
@size Will be set to file size
|
|
||||||
Returns NULL no error, in which case the file is closed and [*fd] and
|
|
||||||
[*size] are undefined; otherwise, returns a pointer to mapped data. */
|
|
||||||
void *map(char const *path, int *fd, size_t *size);
|
|
||||||
|
|
||||||
/* unmap(): Unmap a file loaded with map()
|
|
||||||
@data Region returned by map()
|
|
||||||
@fd File descriptor set by map()
|
|
||||||
@size Size set by map() */
|
|
||||||
void unmap(void *data, int fd, size_t size);
|
|
||||||
|
|
||||||
#endif /* FXOS_UTIL */
|
|
Loading…
Reference in a new issue