Vhex v2 - add-in redisign: Add minimal kernel and minimal libs
This commit is contained in:
parent
ace25fd496
commit
84efc8c451
|
@ -55,3 +55,6 @@ dkms.conf
|
|||
# Other
|
||||
*.txt
|
||||
build/
|
||||
debug
|
||||
.tests
|
||||
.old
|
||||
|
|
128
Makefile
128
Makefile
|
@ -1,64 +1,93 @@
|
|||
#!/usr/bin/make -f
|
||||
# ---
|
||||
# Project: FIXME WRITE DOC !!
|
||||
# Author: yann.magnin@epitech.eu
|
||||
# ---
|
||||
include global.mk
|
||||
## ---
|
||||
## Project: sprite-coder
|
||||
## Author:
|
||||
## theo.cousinet@epitech.eu
|
||||
## yann.magnin@epitech.eu
|
||||
## ---
|
||||
|
||||
NAME := vhex
|
||||
EXEC := $(NAME).g1a
|
||||
HEADER := -Iinclude
|
||||
DEBUG := link_map.txt
|
||||
LDFLAG := -T bootstrap.ld
|
||||
ICON := icon.bmp
|
||||
BUILD := build/
|
||||
##---
|
||||
## Static variables
|
||||
##--
|
||||
HEADER := include
|
||||
BUILD := build
|
||||
DEBUG := debug
|
||||
|
||||
NAME := vhex
|
||||
EXEC := $(NAME).g1a
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
ICON := icon.bmp
|
||||
|
||||
|
||||
COMPILER := sh3eb-elf-
|
||||
CC := $(COMPILER)gcc
|
||||
OBJCOPY := $(COMPILER)objcopy
|
||||
WRAPPER := g1a-wrapper
|
||||
CFLAGS := -Werror -Wall -W -Wextra -std=c18 -m3 -mb -mrenesas \
|
||||
-ffreestanding -nostdlib -fstrict-volatile-bitfields \
|
||||
-Wno-unused-const-variable -Wno-unused-function \
|
||||
-Wno-unused-variable -Wno-unused-but-set-variable \
|
||||
-Wno-unused-parameter
|
||||
|
||||
|
||||
red := \033[1;31m
|
||||
green := \033[1;32m
|
||||
blue := \033[1;34m
|
||||
white := \033[1;37m
|
||||
nocolor := \033[1;0m
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated variables
|
||||
##---
|
||||
SRC :=
|
||||
DIRECTORY := src/ $(sort $(dir $(wildcard src/*/*/)))
|
||||
DIRECTORY := $(shell find src -not -path "*/\.*" -type d)
|
||||
# Get all source files
|
||||
$(foreach path,$(DIRECTORY),$(eval \
|
||||
SRC += $(wildcard $(path)*.c) \
|
||||
$(wildcard $(path)*.s) \
|
||||
$(wildcard $(path)*.S)) \
|
||||
)
|
||||
OBJ := $(patsubst src_%,$(BUILD)%.o,$(subst /,_,$(basename $(SRC))))
|
||||
SRC += $(wildcard $(path)/*.c) \
|
||||
$(wildcard $(path)/*.S) \
|
||||
$(wildcard $(path)/*.s) \
|
||||
))
|
||||
# Geneate all object files
|
||||
OBJ := $(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))))
|
||||
|
||||
#all: ;@echo $(SRC) $(OBJ)
|
||||
all: | $(BUILD) $(EXEC)
|
||||
|
||||
install: $(EXEC)
|
||||
sudo p7 send $<
|
||||
|
||||
|
||||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
@ printf "$(green)/-------\n/ Link files\n/-------$(nocolor)\n"
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(BUILD)$(NAME).elf $^ $(HEADER) -lgcc > $(DEBUG)
|
||||
$(OBJCPY) -R .comment -R .bss -O binary $(BUILD)$(NAME).elf $(BUILD)$(NAME).bin
|
||||
$(WRAPPER) $(BUILD)$(NAME).bin -o $@ -i $(ICON)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf $(OBJ) -I $(HEADER) -lgcc > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -R .comment -R .bss -O binary $(DEBUG)/$(NAME).elf $(DEBUG)/$(NAME).bin
|
||||
$(WRAPPER) $(DEBUG)/$(NAME).bin -o $@ -i $(ICON)
|
||||
|
||||
$(BUILD):
|
||||
$(BUILD) $(DEBUG):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
@ mkdir -p $@
|
||||
|
||||
install: $(EXEC)
|
||||
sudo p7 send --force $^
|
||||
|
||||
#
|
||||
# TODO: find better way to do the job
|
||||
# Units tests part.
|
||||
#
|
||||
tests:
|
||||
gcc -std=c11 -Wall -Wno-error=deprecated-declarations -Wno-deprecated-declarations \
|
||||
-Werror -D DEBUG -o unit_tests $(HEADER) -I. src/history.c src/string/strtotab.c \
|
||||
src/string/atoi_base.c $(wildcard tests/*.c) --coverage -lcriterion
|
||||
./unit_tests
|
||||
gcovr --exclude tests/ --branches
|
||||
rm *.gc*
|
||||
rm ./unit_tests
|
||||
check:
|
||||
@ echo 'src: $(SRC)'
|
||||
@ echo 'obj: $(OBJ)'
|
||||
@ echo 'directory: $(DIRECTORY)'
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst src_%,$(BUILD)%.o,$(subst /,_,$(basename $1))): $1
|
||||
$(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< -I $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
|
||||
|
@ -67,19 +96,16 @@ $(foreach source,$(SRC),$(eval \
|
|||
)
|
||||
|
||||
|
||||
#---
|
||||
# Clean rules
|
||||
#---
|
||||
|
||||
|
||||
##---
|
||||
## Cleaning rules
|
||||
##---
|
||||
clean:
|
||||
@ printf "$(red)Delete objects files$(nocolor)\n"
|
||||
rm -rf $(BUILD)
|
||||
rm -f *.gc*
|
||||
rm -f $(DEBUG)
|
||||
rm -f $(NAME).bin
|
||||
rm -f $(NAME).elf
|
||||
rm -rf $(DEBUG)
|
||||
|
||||
fclean: clean
|
||||
@ printf "$(red)Delete binary files$(nocolor)\n"
|
||||
rm -f $(EXEC)
|
||||
|
||||
re: fclean all
|
||||
|
@ -87,4 +113,4 @@ re: fclean all
|
|||
|
||||
|
||||
|
||||
.PHONY: clean re fclean install tests
|
||||
.PHONY: re fclean clean all install
|
||||
|
|
52
bootstrap.ld
52
bootstrap.ld
|
@ -1,52 +0,0 @@
|
|||
OUTPUT_ARCH(sh3)
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
ENTRY(_initialize)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
rom : o = 0x00300200, l = 512k
|
||||
ram : o = 0x08100000, l = 8k
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ORIGIN(rom);
|
||||
.pretext : {
|
||||
*(.pretext.entry)
|
||||
*(.pretext)
|
||||
} > rom
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
} > rom
|
||||
|
||||
.rodata : SUBALIGN(4) {
|
||||
*(.rodata)
|
||||
. = ALIGN(4);
|
||||
_bcmd_cache = . ;
|
||||
*(.cmd.cache)
|
||||
_ecmd_cache = . ;
|
||||
} > rom
|
||||
|
||||
|
||||
. = ORIGIN(ram);
|
||||
.bss (NOLOAD) : {
|
||||
_bbss = . ;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
} > ram : NONE
|
||||
_sbss = SIZEOF(.bss);
|
||||
|
||||
.data ALIGN(4) : ALIGN(4) {
|
||||
_bdata_rom = LOADADDR(.data) ;
|
||||
_bdata_ram = . ;
|
||||
*(.data)
|
||||
} > ram AT> rom
|
||||
_sdata = SIZEOF(.data) ;
|
||||
|
||||
/* unused sections */
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.comment.*)
|
||||
}
|
||||
}
|
28
global.mk
28
global.mk
|
@ -1,28 +0,0 @@
|
|||
# Global options, used in each Makefile in the project
|
||||
# If you have to change a tool name, or to add an option
|
||||
# for every part of the project, this is the good place.
|
||||
|
||||
COMPILER := sh3eb-elf-
|
||||
CC := $(COMPILER)gcc
|
||||
OBJCPY := $(COMPILER)objcopy
|
||||
AR := $(COMPILER)ar
|
||||
LD := $(COMPILER)ld
|
||||
WRAPPER := g1a-wrapper
|
||||
|
||||
CFLAGS := -Werror -Wall -W -Wextra -std=c18 -m3 -mb -mrenesas \
|
||||
-ffreestanding -nostdlib -fstrict-volatile-bitfields \
|
||||
-Wno-unused-const-variable
|
||||
|
||||
BUILD-DIR := build/
|
||||
SRC-DIR := src/
|
||||
|
||||
red := \033[1;31m
|
||||
green := \033[1;32m
|
||||
blue := \033[1;34m
|
||||
white := \033[1;37m
|
||||
nocolor := \033[1;0m
|
||||
|
||||
define n
|
||||
# Force new line character
|
||||
|
||||
endef
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __KERNEL_ATOMIC_H__
|
||||
# define __KERNEL_ATOMIC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern void atomic_start(void);
|
||||
extern void atomic_end(void);
|
||||
|
||||
#endif /*__KERNEL_ATOMIC_H__*/
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef __KERNEL_ARCH_ATTRIBUTES_H__
|
||||
# define __KERNEL_ARCH_ATTRIBUTES_H__
|
||||
|
||||
// Generate "anonyme name" for each gaps.
|
||||
#define gap_name2(name) _##name
|
||||
#define gap_name(name) gap_name2(name)
|
||||
#define GAPS(bytes) const uint8_t gap_name(__LINE__)[bytes]
|
||||
|
||||
#endif /*__KERNEL_ARCH_ATTRIBUTES_H__*/
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __KERNEL_CONTEXT_H__
|
||||
# define __KERNEL_CONTEXT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct fx9860_context_s
|
||||
{
|
||||
struct {
|
||||
uint16_t control;
|
||||
uint16_t autofix;
|
||||
uint16_t scan_mode;
|
||||
uint16_t scan_state;
|
||||
uint16_t interrupt;
|
||||
uint16_t scan_wait;
|
||||
uint16_t scan_interval;
|
||||
uint16_t kyoutdr;
|
||||
uint16_t kyindr;
|
||||
} keyboard;
|
||||
struct {
|
||||
uint16_t ipra;
|
||||
uint16_t iprb;
|
||||
uint16_t iprc;
|
||||
uint16_t iprd;
|
||||
uint16_t ipre;
|
||||
uint16_t iprf;
|
||||
uint16_t iprg;
|
||||
uint16_t iprh;
|
||||
uint16_t ipri;
|
||||
uint16_t iprj;
|
||||
uint16_t iprk;
|
||||
uint16_t iprl;
|
||||
} intc;
|
||||
} fx9860_context_t;
|
||||
|
||||
// Context primitive.
|
||||
extern void fx9860_context_save(fx9860_context_t *context);
|
||||
extern void fx9860_context_restore(fx9860_context_t *context);
|
||||
|
||||
#endif /*__KERNEL_CONTEXT_H__*/
|
|
@ -0,0 +1,514 @@
|
|||
#ifndef __KERNEL_MODULES_SH7724_INTC_H__
|
||||
# define __KERNEL_MODULES_SH7724_INTC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/union_types.h>
|
||||
#include <kernel/attributes.h>
|
||||
|
||||
struct SH7305_intc_s
|
||||
{
|
||||
//---
|
||||
// Interrupt priority register.
|
||||
//---
|
||||
volatile word_union(IPRA,
|
||||
uint8_t TMU0_0 : 4; /* Timer 0 */
|
||||
uint8_t TMU0_1 : 4; /* Timer 1 */
|
||||
uint8_t TMU0_2 : 4; /* Timer 2 */
|
||||
uint8_t IrDA : 4; /* Infrared Communication */
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRB,
|
||||
uint8_t const : 4;
|
||||
uint8_t LCDC : 4; /* LCD Controller */
|
||||
uint8_t DMAC1A : 4; /* Direct Memory Controller 1 */
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRC,
|
||||
uint8_t TMU1_0 : 4; /* TMU1 Channel 0 */
|
||||
uint8_t TMU1_1 : 4; /* TMU1 Channel 1 */
|
||||
uint8_t TMU1_2 : 4; /* TMU1 Channel 2 */
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRD,
|
||||
uint8_t const : 4;
|
||||
uint8_t MMCIF : 4; /* MultiMedia Card Interface */
|
||||
uint8_t const : 4;
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRE,
|
||||
uint8_t DMAC0A : 4; /* Direct Memory Controller 1 */
|
||||
uint8_t const : 4;
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRF,
|
||||
uint8_t KEYSC : 4; /* Key Scan Interface */
|
||||
uint8_t DMAC0B : 4; /* Direct Memory transfer / error info */
|
||||
uint8_t USB0_1 : 4; /* USB Controller */
|
||||
uint8_t CMT : 4; /* Compare Match Timer*/
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRG,
|
||||
uint8_t SCIF0 : 4; /* SCIF0 transfert / error info */
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRH,
|
||||
uint8_t MSIOF0 : 4; /* Clock-synchronized SCIF channel 0 */
|
||||
uint8_t MSIOF1 : 4; /* Clock-synchronized SCIF channel 1 */
|
||||
uint8_t const : 4;
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRI,
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4;
|
||||
uint8_t const : 4;
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRJ,
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4;
|
||||
uint8_t FSI : 4; /* FIFO - buffered Serial Interface */
|
||||
uint8_t SDHI1 : 4; /* SD Card Host channel 1 */
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRK,
|
||||
uint8_t RTC : 4; /* Real Time Clock */
|
||||
uint8_t DMAC1B : 4; /* DMAC1 transfer/error info */
|
||||
uint8_t const : 4;
|
||||
uint8_t SDHI0 : 4; /* SD Card Host channel 0 */
|
||||
);
|
||||
GAPS(2);
|
||||
volatile word_union(IPRL,
|
||||
uint8_t const : 4; /* Extra TMU ?? */
|
||||
uint8_t const : 4;
|
||||
uint8_t TPU : 4; /* Timer-Pulse Unit */
|
||||
uint8_t const : 4;
|
||||
);
|
||||
GAPS(0x52);
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt mask register.
|
||||
// FIXME
|
||||
// This is the SH7224 Interrupt mask registers, so find
|
||||
// the interrupt mask regiters for the SH7305.
|
||||
//---
|
||||
volatile byte_union(IMR0,
|
||||
uint8_t const : 1;
|
||||
uint8_t TUNI2 : 1; /* TMU1 (timer2) */
|
||||
uint8_t TUNI1 : 1; /* TMU1 (timer1) */
|
||||
uint8_t TUNI0 : 1; /* TMU1 (timer0) */
|
||||
uint8_t SDHII3 : 1; /* SDHI1 */
|
||||
uint8_t SDHII2 : 1; /* SDHI1 */
|
||||
uint8_t SDHII1 : 1; /* SDHI1 */
|
||||
uint8_t SDHII0 : 1; /* SDHI1 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR1,
|
||||
uint8_t VOUI : 1; /* VIO */
|
||||
uint8_t VEU1I : 1; /* VIO */
|
||||
uint8_t BEU0I : 1; /* VIO */
|
||||
uint8_t CEU0I : 1; /* VIO */
|
||||
uint8_t DEI3 : 1; /* DMAC0A */
|
||||
uint8_t DEI2 : 1; /* DMAC0A */
|
||||
uint8_t DEI1 : 1; /* DMAC0A */
|
||||
uint8_t DEI0 : 1; /* DMAC0A */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR2,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t VPUI : 1; /* VPU */
|
||||
uint8_t ATAPI : 1; /* ATAPI */
|
||||
uint8_t EtherMAC: 1; /* Ether */
|
||||
uint8_t const : 1;
|
||||
uint8_t SCIFA0 : 1; /* SCIFA0 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR3,
|
||||
uint8_t DEI3 : 1; /* DMAC1A */
|
||||
uint8_t DEI2 : 1; /* DMAC1A */
|
||||
uint8_t DEI1 : 1; /* DMAC1A */
|
||||
uint8_t DEI0 : 1; /* DMAC1A */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t IRDAI : 1; /* IrDA */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR4,
|
||||
uint8_t const : 1;
|
||||
uint8_t TUNI2 : 1; /* TMU0 (timer2) */
|
||||
uint8_t TUNI1 : 1; /* TMU0 (timer1) */
|
||||
uint8_t TUNI0 : 1; /* TMU0 (timer0) */
|
||||
uint8_t JPUI : 1; /* JPU */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t LCDCI : 1; /* LCDC */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR5,
|
||||
uint8_t KEYI : 1; /* KEYSC */
|
||||
uint8_t DADERR : 1; /* DMAC0B */
|
||||
uint8_t DEI5 : 1; /* DMAC0B */
|
||||
uint8_t DEI4 : 1; /* DMAC0B */
|
||||
uint8_t VEU0I : 1; /* VEU3F0 */
|
||||
uint8_t SCIF2 : 1; /* SCIF */
|
||||
uint8_t SCIF1 : 1; /* SCIF */
|
||||
uint8_t SCIF0 : 1; /* SCIF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR6,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t ICBI : 1; /* ICB */
|
||||
uint8_t SCIFA4 : 1; /* SCIFA4 */
|
||||
uint8_t CEU1I : 1; /* CEU1 */
|
||||
uint8_t const : 1;
|
||||
uint8_t MSIOFI1 : 1; /* MSIOF */
|
||||
uint8_t MSIOFI0 : 1; /* MSIOF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR7,
|
||||
uint8_t DTE0I : 1; /* I2C0 */
|
||||
uint8_t WAITT0I : 1; /* I2C0 */
|
||||
uint8_t TACK0I : 1; /* I2C0 */
|
||||
uint8_t AL0I : 1; /* I2C0 */
|
||||
uint8_t DTE1I : 1; /* I2C1 */
|
||||
uint8_t WAITT1I : 1; /* I2C1 */
|
||||
uint8_t TACK1I : 1; /* I2C1 */
|
||||
uint8_t AL1I : 1; /* I2C1 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR8,
|
||||
uint8_t SDHII3 : 1; /* SDHI0 */
|
||||
uint8_t SDHII2 : 1; /* SDHI0 */
|
||||
uint8_t SDHII1 : 1; /* SDHI0 */
|
||||
uint8_t SDHII0 : 1; /* SDHI0 */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t SCIFA5 : 1; /* SCIFA5 */
|
||||
uint8_t FSI : 1; /* FSI */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR9,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t CMTI : 1; /* CMT */
|
||||
uint8_t const : 1;
|
||||
uint8_t USI1 : 1; /* USB */
|
||||
uint8_t USI0 : 1; /* USB */
|
||||
uint8_t const : 1;
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR10,
|
||||
uint8_t const : 1;
|
||||
uint8_t DADERR : 1; /* DMAC1B */
|
||||
uint8_t DEI5 : 1; /* DMAC1B */
|
||||
uint8_t DEI4 : 1; /* DMAC1B */
|
||||
uint8_t const : 1;
|
||||
uint8_t ATI : 1; /* RTC */
|
||||
uint8_t PRI : 1; /* RTC */
|
||||
uint8_t CUI : 1; /* RTC */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR11,
|
||||
uint8_t BRK : 1; /* 2DG */
|
||||
uint8_t CEI : 1; /* 2DG */
|
||||
uint8_t INI : 1; /* 2DG */
|
||||
uint8_t TRI : 1; /* 2DG */
|
||||
uint8_t const : 1;
|
||||
uint8_t TPUI : 1; /* TPU */
|
||||
uint8_t LMBI : 1; /* ICB */
|
||||
uint8_t TSIFI : 1; /* TSIF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMR12,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t _2DDMAC : 1; /* 2DDMAC */
|
||||
);
|
||||
GAPS(15);
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt clear mask register.
|
||||
// FIXME
|
||||
// This is the SH7224 Interrupt mask registers, so find
|
||||
// the interrupt mask regiters for the SH7305.
|
||||
//---
|
||||
volatile byte_union(IMCR0,
|
||||
uint8_t const : 1;
|
||||
uint8_t TUNI2 : 1; /* TMU1 (timer2) */
|
||||
uint8_t TUNI1 : 1; /* TMU1 (timer1) */
|
||||
uint8_t TUNI0 : 1; /* TMU1 (timer0) */
|
||||
uint8_t SDHII3 : 1; /* SDHI1 */
|
||||
uint8_t SDHII2 : 1; /* SDHI1 */
|
||||
uint8_t SDHII1 : 1; /* SDHI1 */
|
||||
uint8_t SDHII0 : 1; /* SDHI1 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR1,
|
||||
uint8_t VOUI : 1; /* VIO */
|
||||
uint8_t VEU1I : 1; /* VIO */
|
||||
uint8_t BEU0I : 1; /* VIO */
|
||||
uint8_t CEU0I : 1; /* VIO */
|
||||
uint8_t DEI3 : 1; /* DMAC0A */
|
||||
uint8_t DEI2 : 1; /* DMAC0A */
|
||||
uint8_t DEI1 : 1; /* DMAC0A */
|
||||
uint8_t DEI0 : 1; /* DMAC0A */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR2,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t VPUI : 1; /* VPU */
|
||||
uint8_t ATAPI : 1; /* ATAPI */
|
||||
uint8_t EtherMAC: 1; /* Ether */
|
||||
uint8_t const : 1;
|
||||
uint8_t SCIFA0 : 1; /* SCIFA0 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR3,
|
||||
uint8_t DEI3 : 1; /* DMAC1A */
|
||||
uint8_t DEI2 : 1; /* DMAC1A */
|
||||
uint8_t DEI1 : 1; /* DMAC1A */
|
||||
uint8_t DEI0 : 1; /* DMAC1A */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t IRDAI : 1; /* IrDA */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR4,
|
||||
uint8_t const : 1;
|
||||
uint8_t TUNI2 : 1; /* TMU0 (timer2) */
|
||||
uint8_t TUNI1 : 1; /* TMU0 (timer1) */
|
||||
uint8_t TUNI0 : 1; /* TMU0 (timer0) */
|
||||
uint8_t JPUI : 1; /* JPU */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t LCDCI : 1; /* LCDC */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR5,
|
||||
uint8_t KEYI : 1; /* KEYSC */
|
||||
uint8_t DADERR : 1; /* DMAC0B */
|
||||
uint8_t DEI5 : 1; /* DMAC0B */
|
||||
uint8_t DEI4 : 1; /* DMAC0B */
|
||||
uint8_t VEU0I : 1; /* VEU3F0 */
|
||||
uint8_t SCIF2 : 1; /* SCIF */
|
||||
uint8_t SCIF1 : 1; /* SCIF */
|
||||
uint8_t SCIF0 : 1; /* SCIF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR6,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t ICBI : 1; /* ICB */
|
||||
uint8_t SCIFA4 : 1; /* SCIFA4 */
|
||||
uint8_t CEU1I : 1; /* CEU1 */
|
||||
uint8_t const : 1;
|
||||
uint8_t MSIOFI1 : 1; /* MSIOF */
|
||||
uint8_t MSIOFI0 : 1; /* MSIOF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR7,
|
||||
uint8_t DTE0I : 1; /* I2C0 */
|
||||
uint8_t WAITT0I : 1; /* I2C0 */
|
||||
uint8_t TACK0I : 1; /* I2C0 */
|
||||
uint8_t AL0I : 1; /* I2C0 */
|
||||
uint8_t DTE1I : 1; /* I2C1 */
|
||||
uint8_t WAITT1I : 1; /* I2C1 */
|
||||
uint8_t TACK1I : 1; /* I2C1 */
|
||||
uint8_t AL1I : 1; /* I2C1 */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR8,
|
||||
uint8_t SDHII3 : 1; /* SDHI0 */
|
||||
uint8_t SDHII2 : 1; /* SDHI0 */
|
||||
uint8_t SDHII1 : 1; /* SDHI0 */
|
||||
uint8_t SDHII0 : 1; /* SDHI0 */
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t SCIFA5 : 1; /* SCIFA5 */
|
||||
uint8_t FSI : 1; /* FSI */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR9,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t CMTI : 1; /* CMT */
|
||||
uint8_t const : 1;
|
||||
uint8_t USI1 : 1; /* USB */
|
||||
uint8_t USI0 : 1; /* USB */
|
||||
uint8_t const : 1;
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR10,
|
||||
uint8_t const : 1;
|
||||
uint8_t DADERR : 1; /* DMAC1B */
|
||||
uint8_t DEI5 : 1; /* DMAC1B */
|
||||
uint8_t DEI4 : 1; /* DMAC1B */
|
||||
uint8_t const : 1;
|
||||
uint8_t ATI : 1; /* RTC */
|
||||
uint8_t PRI : 1; /* RTC */
|
||||
uint8_t CUI : 1; /* RTC */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR11,
|
||||
uint8_t BRK : 1; /* 2DG */
|
||||
uint8_t CEI : 1; /* 2DG */
|
||||
uint8_t INI : 1; /* 2DG */
|
||||
uint8_t TRI : 1; /* 2DG */
|
||||
uint8_t const : 1;
|
||||
uint8_t TPUI : 1; /* TPU */
|
||||
uint8_t LMBI : 1; /* ICB */
|
||||
uint8_t TSIFI : 1; /* TSIF */
|
||||
);
|
||||
GAPS(3);
|
||||
volatile byte_union(IMCR12,
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t const : 1;
|
||||
uint8_t _2DDMAC : 1; /* 2DDMAC */
|
||||
);
|
||||
GAPS(0xbff0e);
|
||||
|
||||
//---
|
||||
// Interrupt Control registers 0
|
||||
//---
|
||||
volatile word_union(ICR0,
|
||||
uint8_t NMIL :1; /* Non Maskable Interrupt Input level */
|
||||
uint8_t MAI :1; /* Non Maskable Interrupt interrupt Mask */
|
||||
uint8_t const :4; /* All 0 */
|
||||
uint8_t NMIB :1; /* Non Maskable Interrupt Block Mode */
|
||||
uint8_t NMIE :1; /* Non Maskable Interrupt Edge Select */
|
||||
uint8_t const :2; /* All 1 */
|
||||
uint8_t LVLMODE :1; /* Interrupt Source Retention Mode */
|
||||
uint8_t const :5; /* All 0 */
|
||||
);
|
||||
GAPS(0x0e);
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt Priority registers
|
||||
//---
|
||||
volatile long_union(INTPRI00,
|
||||
uint32_t IRQ0 : 4; /* Interrupt Request 0 */
|
||||
uint32_t IRQ1 : 4; /* Interrupt Request 1 */
|
||||
uint32_t IRQ2 : 4; /* Interrupt Request 2 */
|
||||
uint32_t IRQ3 : 4; /* Interrupt Request 3 */
|
||||
uint32_t IRQ4 : 4; /* Interrupt Request 4 */
|
||||
uint32_t IRQ5 : 4; /* Interrupt Request 5 */
|
||||
uint32_t IRQ6 : 4; /* Interrupt Request 6 */
|
||||
uint32_t IRQ7 : 4; /* Interrupt Request 7 */
|
||||
);
|
||||
GAPS(8);
|
||||
|
||||
//---
|
||||
// Interrupt Control register 1
|
||||
//---
|
||||
volatile word_union(ICR1,
|
||||
uint8_t IRQ0S :2; /* Interrupt Request 0 Sense Select */
|
||||
uint8_t IRQ1S :2; /* Interrupt Request 1 Sense Select */
|
||||
uint8_t IRQ2S :2; /* Interrupt Request 2 Sense Select */
|
||||
uint8_t IRQ3S :2; /* Interrupt Request 3 Sense Select */
|
||||
uint8_t IRQ4S :2; /* Interrupt Request 4 Sense Select */
|
||||
uint8_t IRQ5S :2; /* Interrupt Request 5 Sense Select */
|
||||
uint8_t IRQ6S :2; /* Interrupt Request 6 Sense Select */
|
||||
uint8_t IRQ7S :2; /* Interrupt Request 7 Sense Select */
|
||||
);
|
||||
GAPS(6);
|
||||
|
||||
//---
|
||||
// Interrupt request register.
|
||||
//---
|
||||
volatile byte_union(INTREQ00,
|
||||
uint8_t IRQ0 : 1; /* Interrupt Request 0 */
|
||||
uint8_t IRQ1 : 1; /* Interrupt Request 1 */
|
||||
uint8_t IRQ2 : 1; /* Interrupt Request 2 */
|
||||
uint8_t IRQ3 : 1; /* Interrupt Request 3 */
|
||||
uint8_t IRQ4 : 1; /* Interrupt Request 4 */
|
||||
uint8_t IRQ5 : 1; /* Interrupt Request 5 */
|
||||
uint8_t IRQ6 : 1; /* Interrupt Request 6 */
|
||||
uint8_t IRQ7 : 1; /* Interrupt Request 7 */
|
||||
);
|
||||
GAPS(0x1f);
|
||||
|
||||
//---
|
||||
// Interrupt mask register.
|
||||
//---
|
||||
volatile byte_union(INTMSK00,
|
||||
uint8_t IRQ0 : 1; /* Interrupt Request 0 */
|
||||
uint8_t IRQ1 : 1; /* Interrupt Request 1 */
|
||||
uint8_t IRQ2 : 1; /* Interrupt Request 2 */
|
||||
uint8_t IRQ3 : 1; /* Interrupt Request 3 */
|
||||
uint8_t IRQ4 : 1; /* Interrupt Request 4 */
|
||||
uint8_t IRQ5 : 1; /* Interrupt Request 5 */
|
||||
uint8_t IRQ6 : 1; /* Interrupt Request 6 */
|
||||
uint8_t IRQ7 : 1; /* Interrupt Request 7 */
|
||||
);
|
||||
GAPS(0x1f);
|
||||
|
||||
//---
|
||||
// Interrupt mask clear register. (write only).
|
||||
//---
|
||||
volatile byte_union(INTMSKCLR00,
|
||||
uint8_t IRQ0 : 1; /* Interrupt Request 0 */
|
||||
uint8_t IRQ1 : 1; /* Interrupt Request 1 */
|
||||
uint8_t IRQ2 : 1; /* Interrupt Request 2 */
|
||||
uint8_t IRQ3 : 1; /* Interrupt Request 3 */
|
||||
uint8_t IRQ4 : 1; /* Interrupt Request 4 */
|
||||
uint8_t IRQ5 : 1; /* Interrupt Request 5 */
|
||||
uint8_t IRQ6 : 1; /* Interrupt Request 6 */
|
||||
uint8_t IRQ7 : 1; /* Interrupt Request 7 */
|
||||
);
|
||||
GAPS(0x5b);
|
||||
|
||||
//---
|
||||
// Non Maskable Interrupt flags control register
|
||||
//---
|
||||
volatile word_union(NMIFCR,
|
||||
uint16_t const NMIL : 1; /* NMI input Level */
|
||||
uint16_t const : 14; /* All 0 */
|
||||
uint16_t NMIFL : 1; /* NMI Interrupt Request Detection */
|
||||
);
|
||||
GAPS(0x5bff3e);
|
||||
|
||||
//---
|
||||
// User interrupt mask level register.
|
||||
//---
|
||||
volatile long_union(USERMSK,
|
||||
uint32_t SECRET : 8; /* Only write 0xa5 */
|
||||
uint32_t const : 8; /* All 0 */
|
||||
uint32_t UIMASK : 4; /* User Interrupt Mask Level */
|
||||
uint32_t const : 4; /* All 0 */
|
||||
);
|
||||
};
|
||||
|
||||
#define SH7305_INTC (*(volatile struct SH7305_intc_s *)0xa4080000)
|
||||
#endif /*__KERNEL_MODULES_SH7724_INTC_H__*/
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef __KERNEL_MODULES_SH7724_KEYSC_H__
|
||||
# define __KERNEL_MODULES_SH7724_KEYSC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/union_types.h>
|
||||
#include <kernel/attributes.h>
|
||||
|
||||
struct sh7305_keysc_s
|
||||
{
|
||||
volatile const uint16_t KIUDATA[6];
|
||||
volatile word_union(CONTROL,
|
||||
uint16_t KEYIE : 1; /* Key Interrupt enable */
|
||||
uint16_t const :13; /* All 0 */
|
||||
uint16_t INTMODE : 2; /* Key Interrupt mode (?) */
|
||||
);
|
||||
volatile word_union(AUTOFIX,
|
||||
uint16_t ENABLE : 1; /* enable AUTOFIX (?) */
|
||||
uint16_t const : 8; /* All 0 */
|
||||
uint16_t UNKNOWN0 : 3; /* ????? */
|
||||
uint16_t const : 1; /* All 0 */
|
||||
uint16_t UNKNOWN1 : 3; /* ????? */
|
||||
);
|
||||
volatile word_union(SCAN_MODE,
|
||||
uint16_t UNKNOWN0 : 3; /* Scan Timing (?) */
|
||||
uint16_t UNKNOWN1 : 3; /* Scan mode (?) */
|
||||
uint16_t const : 10; /* All 0 */
|
||||
);
|
||||
volatile word_union(SCAN_STATE,
|
||||
uint16_t const :15; /* All 0 */
|
||||
uint16_t STATE : 1; /* ????? */
|
||||
);
|
||||
volatile word_union(INTERRUPT,
|
||||
uint16_t const : 1; /* All 0 */
|
||||
uint16_t KYCPU_IE : 7; /* KEYSC interrupt setup (see Planet Casio's bible) */
|
||||
uint16_t const STATUS : 8; /* Indicate the "type" of interruption (pressed, released, etc) */
|
||||
);
|
||||
volatile word_union(SCAN_WAIT,
|
||||
uint16_t const : 1; /* All 0 */
|
||||
uint16_t TIME :15; /* Time between interrupt */
|
||||
);
|
||||
volatile uint16_t SCAN_INTERVAL;
|
||||
volatile word_union(KYOUTDR,
|
||||
uint16_t const : 4; /* All 0 */
|
||||
uint16_t KYO5DT : 2; /* Key Controll ouput 5 */
|
||||
uint16_t KYO4DT : 2; /* Key Controll ouput 4 */
|
||||
uint16_t KYO3DT : 2; /* Key Controll ouput 3 */
|
||||
uint16_t KYO2DT : 2; /* Key Controll ouput 2 */
|
||||
uint16_t KYO1DT : 2; /* Key Controll ouput 1 */
|
||||
uint16_t KYO0DT : 2; /* Key Controll ouput 0 */
|
||||
);
|
||||
volatile word_union(KYINDR,
|
||||
uint16_t const : 8; /* All 0 */
|
||||
uint16_t KYDIR6 : 1; /* Key Direction 6 */
|
||||
uint16_t KYDIR5 : 1; /* Key Direction 5 */
|
||||
uint16_t KYDIR4 : 1; /* Key Direction 4 */
|
||||
uint16_t KYDIR3 : 1; /* Key Direction 3 */
|
||||
uint16_t KYDIR2 : 1; /* Key Direction 2 */
|
||||
uint16_t KYDIR1 : 1; /* Key Direction 1 */
|
||||
uint16_t KYDIR0 : 1; /* Key Direction 0 */
|
||||
);
|
||||
};
|
||||
|
||||
#define SH7305_KEYSC (*(volatile struct sh7305_keysc_s *)0xa44b0000)
|
||||
|
||||
#endif /*__KERNEL_MODULES_SH7724_KEYSC_H__*/
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __KERNEL_HARDWARE_T6K11_H__
|
||||
# define __KERNEL_HARDWARE_T6K11_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Screen primitive
|
||||
extern void t6k11_display(void *vram);
|
||||
|
||||
#endif /*__KERNEL_HARDWARE_T6K11_H__*/
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef __KERNEL_TTY_H__
|
||||
# define __KERNEL_TTY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct tty_s
|
||||
{
|
||||
struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} max;
|
||||
} cursor;
|
||||
};
|
||||
|
||||
// primitives.
|
||||
extern int tty_open(void);
|
||||
extern int tty_write(char const *buffer, ...);
|
||||
//extern void tty_read(char *buffer, size_t count);
|
||||
extern int tty_close(void);
|
||||
|
||||
#endif /*__KERNEL_TTY_H__*/
|
|
@ -16,6 +16,16 @@ typedef int32_t ssize_t;
|
|||
# define __ssize_t_defined
|
||||
#endif
|
||||
|
||||
// Define MPU arch.
|
||||
typedef enum mpu_e
|
||||
{
|
||||
MPU_SH7305,
|
||||
MPU_SH7724,
|
||||
MPU_SH7337,
|
||||
MPU_SH7355,
|
||||
MPU_UNKNOWN,
|
||||
} mpu_t;
|
||||
|
||||
// Force inline function.
|
||||
#define INLINE __attribute__((always_inline)) inline
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __KERNEL_MODULES_TYPES_H__
|
||||
# define __KERNEL_MODULES_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define byte_union(name, fields) \
|
||||
union { \
|
||||
uint8_t BYTE; \
|
||||
struct { \
|
||||
fields \
|
||||
} __attribute__((packed, aligned(1))); \
|
||||
} __attribute__((packed, aligned(1))) name
|
||||
|
||||
#define word_union(name, fields) \
|
||||
union { \
|
||||
uint16_t WORD; \
|
||||
struct { \
|
||||
fields \
|
||||
} __attribute__((packed, aligned(2))); \
|
||||
} __attribute__((packed, aligned(2))) name
|
||||
|
||||
#define long_union(name, fields) \
|
||||
union { \
|
||||
uint32_t LONG_WORD; \
|
||||
struct { \
|
||||
fields \
|
||||
} __attribute__((packed, aligned(4))); \
|
||||
} __attribute__((packed, aligned(4))) name
|
||||
|
||||
|
||||
#endif /*__KERNEL_MODULES_TYPES_H__*/
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __LIB_DISPLAY_H__
|
||||
# define __LIB_DISPLAY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// Define font bitmap informations.
|
||||
#define KERNEL_FONT_BITMAP_WIDTH 127 // Bitmap width
|
||||
#define KERNEL_FONT_BITMAP_HEIGHT 23 // Bitmap height
|
||||
#define KERNEL_FONT_BITMAP_CWIDTH 4 // Character width (bitmap)
|
||||
#define KERNEL_FONT_BITMAP_CHEIGHT 6 // Character height (bitmap)
|
||||
#define KERNEL_FONT_REAL_WIDTH 3 // Charater width (real)
|
||||
#define KERNEL_FONT_REAL_HEIGHT 5 // Character height (real)
|
||||
#define KERNEL_FONT_NB_CHAR_X ((KERNEL_FONT_BITMAP_WIDTH / KERNEL_FONT_BITMAP_CWIDTH) + 1)
|
||||
#define KERNEL_FONT_NB_CHAR_Y ((KERNEL_FONT_BITMAP_HEIGHT / KERNEL_FONT_BITMAP_CHEIGHT) + 1)
|
||||
|
||||
// Define screen informations.
|
||||
#define DISPLAY_SCREEN_WIDTH 128
|
||||
#define DISPLAY_SCREEN_HEIGHT 64
|
||||
|
||||
// Primtives
|
||||
extern void dclear(void);
|
||||
extern void dprint(int x, int y, char const *str, ...);
|
||||
extern void dascii(int x, int y, char const c);
|
||||
extern void dscroll(int line);
|
||||
extern void dupdate(void);
|
||||
|
||||
// Sheared Video RAM
|
||||
extern uint32_t *VRAM;
|
||||
|
||||
#endif /*__LIB_DISPLAY_H__*/
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef __LIB_STDIO_H__
|
||||
# define __LIB_STDIO_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* vsprintf(), sprintf() - formatted output conversion. */
|
||||
void vsprintf(char *str, char const *format, va_list ap);
|
||||
void sprintf(char *str, char const *format, ...);
|
||||
|
||||
#endif /*__LIB_STDIO_H__*/
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __STRING_H__
|
||||
# define __STRING_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* memset() - fill memory with a constant byte. */
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
/* strcat() - concatenate two string */
|
||||
char *strcat(char *dest, char const *src);
|
||||
|
||||
/* strcmp() - compare two strings */
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
|
||||
/* strcpy(), strncpy() - copy a string. */
|
||||
char *strncpy(char *dest, char const *str, size_t size);
|
||||
char *strcpy(char *dest, char const *src);
|
||||
|
||||
/* strlen - calculate the lenght of a string. */
|
||||
size_t strlen(char const *str);
|
||||
|
||||
#endif /*__STRING_H__*/
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef __STRING_H__
|
||||
# define __STRING_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// Define weak symbols
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
/* memset() - fill memory with a constant byte. */
|
||||
WEAK void *memset(void *s, int c, size_t n);
|
||||
|
||||
#ifndef DEBUG
|
||||
/* vsprintf(), sprintf() - formatted output conversion. */
|
||||
void vsprintf(char *str, char const *format, va_list ap);
|
||||
void sprintf(char *str, char const *format, ...);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* strcat() - concatenate two string */
|
||||
WEAK char *strcat(char *dest, char const *src);
|
||||
|
||||
/* strcmp() - compare two strings */
|
||||
WEAK int strcmp(const char *s1, const char *s2);
|
||||
|
||||
/* strcpy(), strncpy() - copy a string. */
|
||||
WEAK char *strncpy(char *dest, char const *str, size_t size);
|
||||
WEAK char *strcpy(char *dest, char const *src);
|
||||
|
||||
/* strlen - calculate the lenght of a string. */
|
||||
WEAK size_t strlen(char const *str);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Custom string function.
|
||||
//
|
||||
/* strtotab() - generate table of word and indicate the number of word. */
|
||||
int strtotab(int *argc, char ***argv, char const *str);
|
||||
|
||||
/* strtotab_quit() - free all allocated memory by strtotab function. */
|
||||
void strtotab_quit(int *argc, char ***argv);
|
||||
|
||||
/* atoi_base() - atoi wrapped function, but add the base number. */
|
||||
uint32_t atoi_base(char const *str, int base);
|
||||
|
||||
#endif /*__STRING_H__*/
|
|
@ -1,56 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
extern int main(void);
|
||||
|
||||
//defined by bootstrap.ld
|
||||
extern uint32_t bbss;
|
||||
extern uint32_t sbss;
|
||||
extern uint32_t bdata_rom;
|
||||
extern uint32_t bdata_ram;
|
||||
extern uint32_t sdata;
|
||||
|
||||
|
||||
//
|
||||
// section_dump()
|
||||
// copy a memory region using symbol information.
|
||||
//
|
||||
__attribute__((section(".pretext")))
|
||||
void section_dump(uint32_t * restrict dest, uint32_t * restrict load, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < size >> 2)
|
||||
dest[i] = load[i];
|
||||
}
|
||||
|
||||
//
|
||||
// section_reset()
|
||||
// clear a memory region using symbol information.
|
||||
//
|
||||
__attribute__((section(".pretext")))
|
||||
void section_reset(uint32_t *bsection, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < size >> 2)
|
||||
bsection[i] = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize() - the real add-in entry.
|
||||
// We are currently running in the storage memory, so we should
|
||||
// load data in RAM and wipe the bss section for initialize static
|
||||
// and global variables.
|
||||
//
|
||||
__attribute__((section(".pretext.entry")))
|
||||
int initialize(void)
|
||||
{
|
||||
int exit;
|
||||
|
||||
section_reset(&bbss, (size_t)&sbss);
|
||||
section_dump(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
||||
exit = main();
|
||||
return (exit);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// External symbols defined by the linker script.
|
||||
extern uint32_t bcmd_cache;
|
||||
extern uint32_t ecmd_cache;
|
||||
|
||||
//
|
||||
// cmd_cache_find()
|
||||
// Try to find the command into the command cache.
|
||||
//
|
||||
// NOTE:
|
||||
// The cache is generated during the compilation; all command
|
||||
// blocks is stored in the ".cmd.cache" section.
|
||||
// We use the section symbols to know where the cache end.
|
||||
// (see bootstrap.ld).
|
||||
//
|
||||
const struct cmd_block *cmd_cache_find(char const *name)
|
||||
{
|
||||
const struct cmd_block *cache;
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
cache = (void *)&bcmd_cache;
|
||||
while ((ptrdiff_t)(&cache[++i]) != (ptrdiff_t)&ecmd_cache
|
||||
&& strcmp(cache[i].name, name));
|
||||
if ((ptrdiff_t)(&cache[i]) == (ptrdiff_t)&ecmd_cache)
|
||||
return (NULL);
|
||||
return (&cache[i]);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
//
|
||||
// command_find
|
||||
// Try to find the user command in the internal cache and execute
|
||||
// the command's function.
|
||||
//
|
||||
static int command_find(int argc, char **argv, struct session_s *session,
|
||||
struct vhex_s *vhex)
|
||||
{
|
||||
const struct cmd_block *command;
|
||||
int tmp;
|
||||
|
||||
command = cmd_cache_find(*argv);
|
||||
if (command == NULL)
|
||||
return (EINVAL);
|
||||
if (command->constructor == NULL){
|
||||
strcpy(vhex->info, "function error");
|
||||
return (ENOSYS);
|
||||
}
|
||||
tmp = session->anchor;
|
||||
memset(vhex->info, '\0', CMD_LENGHT_MAX);
|
||||
command->constructor(argc, argv, session, vhex->info);
|
||||
if (*vhex->info == '\0')
|
||||
sprintf(vhex->info, "%#x", session->anchor);
|
||||
if (tmp != session->anchor)
|
||||
session->cursor = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// command_entry()
|
||||
// The goal of this part is to parse and execute the user's command.
|
||||
//
|
||||
void command_entry(struct session_s *session, struct vhex_s *vhex)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
if (history_update(&vhex->history.list, vhex->insert.cmd) == 0){
|
||||
vhex->history.offset = 0;
|
||||
vhex->history.deep += 1;
|
||||
}
|
||||
ret = strtotab(&argc, &argv, vhex->insert.cmd);
|
||||
memset(vhex->insert.cmd, '\0', CMD_LENGHT_MAX);
|
||||
if (ret != 0){
|
||||
sprintf(vhex->info, "error (%d)", ret);
|
||||
return;
|
||||
}
|
||||
if (command_find(argc, argv, session, vhex) != 0)
|
||||
strcat(vhex->info, "command error");
|
||||
session->mode = (session->anchor == 0x00000000) ? UNUSED : NORMAL;
|
||||
strtotab_quit(&argc, &argv);
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <syscalls.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
// Internal prototype.
|
||||
static void help(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define help command into the cache section.
|
||||
CMDBLOCK("help", &help,
|
||||
"Help for Vhex version 1.0\n"
|
||||
"This chapter introduces\noperations available with vhex.\n"
|
||||
"\n"
|
||||
"I] Keys mapping\n"
|
||||
"II] Status bar\n"
|
||||
"III] Unused mode\n"
|
||||
"IV] Command mode\n"
|
||||
"V] Normal mode\n"
|
||||
"VI] Credits\n"
|
||||
"VII] Copyright\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"I] Keys mapping\n"
|
||||
"Move around: [UP], [DOWN]\n"
|
||||
"Change mode: [OPTN]\n"
|
||||
"Letter: [ALPHA] + [A ~ Z]\n"
|
||||
"Letter lock: [SHIFT] + [ALPHA]\n"
|
||||
"Letter unlock: [ALPHA]\n"
|
||||
"Number: [0 ~ 9]\n"
|
||||
"sessions: [F0 ~ F9]\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"II] Status bar\n"
|
||||
"The first information (at the\nbottom left) display is the\nkeyboard status:\n"
|
||||
" * [s] : shift mode.\n"
|
||||
" * [l] : letter mode.\n"
|
||||
" * [L] : caps lock.\n"
|
||||
" * [n] : number mode.\n"
|
||||
"The second information is the\ncommand zone.\n"
|
||||
"The third information is the\ncurrent mode (unused, normal,\ncommand).\n"
|
||||
"And the last information is the session's id currently using.\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"III] Unused mode\n"
|
||||
"This mode is set when the\nsession is not used.\n"
|
||||
"Basically you can't do a lot of things, but you can enter into\n"
|
||||
"the command mode using the\n[OPTN] key.\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"IV] Normal mode.\n"
|
||||
"This mode allows the user to\nmove into the Virtual Memory\n"
|
||||
"using [UP] and [DOWN].\n"
|
||||
"Be careful, there is no security"
|
||||
"and some parts of the Virtual\n"
|
||||
"Memory can make your\ncalculator crash.\n"
|
||||
"If a crash occurs, don't worry, you have \"just\" read a\n"
|
||||
"non-readable space.\n"
|
||||
"Your machine will continue to\nwork perfectly after\nthe reset.\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"V] Command mode\n"
|
||||
"The command mode is probably\nthe most important part\nof Vhex.\n"
|
||||
"It's the only way to move\nquickly into the different part\n"
|
||||
"of the Virtual Memory.\n"
|
||||
"To enter in command mode the\nuser can press the [OTPN] key,\n"
|
||||
"normally a \":#\" appear and\nthe user can write\ncommand.\n"
|
||||
"All commands currently\nintegrated in Vhex:\n"
|
||||
" :systab\n"
|
||||
" :vbrjmp <zone>\n"
|
||||
" :syscall <id>\n"
|
||||
" :ram <zone>\n"
|
||||
" :rom\n"
|
||||
" :help <command>\n"
|
||||
"We invited you to try\n\":help <cmd>\" if you don't know how a"
|
||||
" command work.\n"
|
||||
"Each command typed by the user\nis stored in a history that it\n"
|
||||
"can access using [UP] and\n[DOWN] keys.\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"VI] Credits\n"
|
||||
"Special thank to:\n"
|
||||
" - Lephenixnoir\n"
|
||||
" - PierrotLL\n"
|
||||
" - Simon Lothar\n"
|
||||
" - Kristaba\n"
|
||||
"And all communities of Planet\nCasio for his help.\n"
|
||||
"specially to LephenixNoir for\nhis advices and his patience.\n"
|
||||
"\n"
|
||||
"================================"
|
||||
"VII] Copyright\n"
|
||||
"The Vhex programme use CC0\nlicence.\n"
|
||||
"It allows anyone to freely\nreuse, improve or modify my\n"
|
||||
"work for any purpose and\nwithout any legal restrictions, "
|
||||
"except those required by law.\n");
|
||||
|
||||
/* get_nb_line() - Return the number of lines contain in the command's manual. */
|
||||
static int get_nb_line(char const *str)
|
||||
{
|
||||
int nb_line;
|
||||
int cursor;
|
||||
|
||||
if (str == NULL || *str == '\0')
|
||||
return (-EBADMSG);
|
||||
cursor = 0;
|
||||
nb_line = 0;
|
||||
do {
|
||||
cursor += 1;
|
||||
if (cursor >= COLUMN_OFFSET || *str == '\n'){
|
||||
nb_line += 1;
|
||||
cursor = 0;
|
||||
}
|
||||
} while (*(++str) != '\0');
|
||||
return (nb_line + 1);
|
||||
}
|
||||
|
||||
/* get_line() - Return the address of a target line */
|
||||
static const char *get_line(char const *str, int line)
|
||||
{
|
||||
int cursor;
|
||||
int nb_line;
|
||||
|
||||
if (line == 0)
|
||||
return (str);
|
||||
cursor = 0;
|
||||
nb_line = 0;
|
||||
do {
|
||||
cursor += 1;
|
||||
if (cursor >= COLUMN_OFFSET || *str == '\n'){
|
||||
nb_line += 1;
|
||||
cursor = 0;
|
||||
}
|
||||
} while (*(++str) != '\0' && nb_line < line);
|
||||
return (str);
|
||||
}
|
||||
|
||||
//
|
||||
// display_text() - Display only lines which should be visible.
|
||||
//
|
||||
// NOTE:
|
||||
// Due to the Casio's GetKey function, the font used is a little bit weird,
|
||||
// some characters have not the same size, so we can't calculate easily
|
||||
// the line size. (TODO: fix that).
|
||||
//
|
||||
static void display_text(char *buf, char const *str, int current_line)
|
||||
{
|
||||
char const *text;
|
||||
int nb_line;
|
||||
int cursor;
|
||||
|
||||
text = get_line(str, current_line);
|
||||
if (*text == '\0')
|
||||
return;
|
||||
nb_line = 0;
|
||||
cursor = 0;
|
||||
do {
|
||||
if (*text != '\n'){
|
||||
buf[cursor] = *text;
|
||||
cursor += 1;
|
||||
}
|
||||
if (cursor >= COLUMN_OFFSET || *text == '\n'){
|
||||
buf[cursor] = '\0';
|
||||
print(0, nb_line * FONT_HEIGHT, buf);
|
||||
nb_line += 1;
|
||||
cursor = 0;
|
||||
continue;
|
||||
}
|
||||
} while (*(++text) != '\0' && nb_line < LINE_OFFSET);
|
||||
if (cursor != 0)
|
||||
print(0, nb_line * FONT_HEIGHT, buf);
|
||||
}
|
||||
|
||||
/* help_engine() - Display help information and handle keyboard. */
|
||||
static void help_engine(char const *text, int nb_line)
|
||||
{
|
||||
char buf[COLUMN_OFFSET + 1];
|
||||
unsigned int key;
|
||||
int cursor;
|
||||
int exit;
|
||||
|
||||
exit = 1;
|
||||
cursor = 0;
|
||||
while (exit != 0){
|
||||
dclear();
|
||||
// Display text.
|
||||
display_text(buf, text, cursor);
|
||||
|
||||
// Display exit info.
|
||||
dclear_area(0, SCREEN_HEIGHT - FONT_HEIGHT - 2, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||||
dline_horizontal(SCREEN_HEIGHT - FONT_HEIGHT - 2, 0, SCREEN_WIDTH - 1);
|
||||
print(0, SCREEN_HEIGHT - FONT_HEIGHT, "press [EXIT]");
|
||||
sprintf(buf, "%d/%d", cursor + 1, nb_line + 1);
|
||||
print(SCREEN_WIDTH - (strlen(buf) * FONT_WIDTH) - 1, SCREEN_HEIGHT - FONT_HEIGHT, buf);
|
||||
getkey(&key);
|
||||
|
||||
// Keys hanlding.
|
||||
if (key == KEY_UP && cursor > 0)
|
||||
cursor -= 1;
|
||||
if (key == KEY_DOWN && cursor < nb_line)
|
||||
cursor += 1;
|
||||
if (key == KEY_EXIT)
|
||||
exit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* help() - display command manual pages. */
|
||||
static void help(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
const struct cmd_block *command;
|
||||
int nb_line;
|
||||
|
||||
(void)session;
|
||||
command = cmd_cache_find((argc == 1) ? "help" : argv[1]);
|
||||
if (command == NULL){
|
||||
strcpy(info, "command error");
|
||||
return;
|
||||
}
|
||||
nb_line = 0;
|
||||
if (command->man != NULL)
|
||||
nb_line = get_nb_line(command->man);
|
||||
if (command->man == NULL || nb_line < 0){
|
||||
strcpy(info, "no help entry");
|
||||
return;
|
||||
}
|
||||
nb_line -= LINE_OFFSET + 1;
|
||||
if (nb_line < 0)
|
||||
nb_line = 0;
|
||||
help_engine(command->man, nb_line);
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal prototype.
|
||||
static void address_jump(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define the command block into the cache.
|
||||
CMDBLOCK("jmp", &address_jump,
|
||||
"JMP command help\n"
|
||||
"This command takes one\nparameter: the address (hexa)\n"
|
||||
"you would jump into the Virtual Memory.\n"
|
||||
"\n"
|
||||
"Be careful, there is no security"
|
||||
"and some parts of the Virtual\n"
|
||||
"Memory can make your\ncalculator crash.\n"
|
||||
"\n"
|
||||
"If a crash occurs, don't worry, you have \"just\" read a\n"
|
||||
"non-readable space.\n"
|
||||
"Your calculator will continue\nto work perfectly after\nthe reset.\n"
|
||||
"\n"
|
||||
"Virtual Memory map:\n"
|
||||
"Area P0 - 2Go - MMU enable\n"
|
||||
"0x00300000 : add-in header\n"
|
||||
"0x00300200 : add-in mapping\n"
|
||||
"0x08000000 : RAM (cache)\n"
|
||||
"Area P1 - 500Mo - MMU disable\n"
|
||||
"0x80000000 : ROM (cache)\n"
|
||||
"0x88000000 : RAM (cache)\n"
|
||||
"Area P2 - 500Mo - MMU disable\n"
|
||||
"0xa0000000 : ROM (no cache)\n"
|
||||
"0xa8000000 : RAM (no cache)\n"
|
||||
"Area P3 - 500Mo - MMU enable\n"
|
||||
"?????? CRASH ??????\n"
|
||||
"Area P4 - 500Mo - MMU disable\n"
|
||||
"0xe0000000 : Store queue area\n"
|
||||
"0xe5000000 : On chip RAM\n"
|
||||
"0xf0000000 : Instr. cache addr\n"
|
||||
"0xf1000000 : Instr. cache data\n"
|
||||
"0xf2000000 : Instr. TLB addr\n"
|
||||
"0xf3000000 : Instr. TLB data\n"
|
||||
"0xf4000000 : Operand cache addr\n"
|
||||
"0xf5000000 : Operand cache data\n"
|
||||
"0xf6000000 : TLB/PMB cache addr\n"
|
||||
"0xf7000000 : TLB/PMB cache data\n"
|
||||
"0xfc000000 : Control register\n"
|
||||
);
|
||||
|
||||
static INLINE int check_address(char *str)
|
||||
{
|
||||
--str;
|
||||
while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f'));
|
||||
return ((*str != '\0') ? 1 : 0);
|
||||
}
|
||||
|
||||
/* address_jump() - jump into Virtual Memory. */
|
||||
static void address_jump(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
if (argc != 2 || check_address(argv[1]) != 0){
|
||||
strcpy(info, "arguments error");
|
||||
return;
|
||||
}
|
||||
// clear the lower bits to force align the address.
|
||||
// (one instruction takes 2 bytes, so we need to respect the alignment).
|
||||
session->anchor = atoi_base(argv[1], 16) >> 1 << 1;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal prototype.
|
||||
static void ram_jump(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
/* Define the command block into the cache section. */
|
||||
CMDBLOCK("ram", &ram_jump,
|
||||
"RAM command help\n"
|
||||
"This function allows user to\njump into different parts of\n"
|
||||
"the RAM mapped in the Virtual\nMemory.\n"
|
||||
"\n"
|
||||
":ram p0\n"
|
||||
"Jump into the P0 area, basically"
|
||||
"the user space who is managed\n"
|
||||
"by the Memory Management\nUnit.\n"
|
||||
"\n"
|
||||
":ram p1\n"
|
||||
"Jump into the RAM mapped in the P1 area; MMU is disabled and\n"
|
||||
"the area is cached.\n"
|
||||
"\n"
|
||||
":ram p2\n"
|
||||
"Jump into the RAM mapped in the P2 area; MMU is disable "
|
||||
"and the area is not cached.\n"
|
||||
"\n"
|
||||
":ram p4\n"
|
||||
"Jump into the internal chip\nmemory area; MMU is enabled\n"
|
||||
"and the area is cached.\n"
|
||||
);
|
||||
|
||||
/* ram_jump() - jump into the RAM mapped in different parts of the Virtual Memory. */
|
||||
static void ram_jump(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
if (argc != 2){
|
||||
strcpy(info, "argument error");
|
||||
return;
|
||||
}
|
||||
if (strcmp(argv[1], "p0") && strcmp(argv[1], "p1")
|
||||
&& strcmp(argv[1], "p2") && strcmp(argv[1], "p4")){
|
||||
sprintf(info, "bad argument");
|
||||
return;
|
||||
}
|
||||
if (!strcmp(argv[1], "p0"))
|
||||
session->anchor = 0x08100000;
|
||||
if (!strcmp(argv[1], "p1"))
|
||||
session->anchor = 0x88000000;
|
||||
if (!strcmp(argv[1], "p2"))
|
||||
session->anchor = 0xa8000000;
|
||||
if (!strcmp(argv[1], "p4"))
|
||||
session->anchor = 0xe5000000;
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// internal prototype.
|
||||
static void rom_jump(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define the command into the cache.
|
||||
CMDBLOCK("rom", &rom_jump,
|
||||
"ROM command help\n"
|
||||
"This command allows user to\njump into different parts of\n"
|
||||
"the ROM mapped in the Virtual\nMemory.\n"
|
||||
"\n"
|
||||
":rom addin\n"
|
||||
"Jump into the dynamic add-in\nmapping area.\n"
|
||||
"Normaly you can see the\nVhex binary :)\n"
|
||||
"(see \":help jmp\" to get the\nVirtual Memory map)\n"
|
||||
"\n"
|
||||
":rom p1\n"
|
||||
"Jump into the ROM mapped in\nthe P1 area.\n"
|
||||
"MMU is disable and the area\nis cached.\n"
|
||||
"\n"
|
||||
"rom p2\n"
|
||||
"Jump into the ROM mapped in\nthe P2 area.\n"
|
||||
"MMU is disable and the area\nis not cached.\n"
|
||||
);
|
||||
|
||||
/* rom_jump() - jump into the ROM mapped in different parts of the Virtual Memory. */
|
||||
static void rom_jump(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
if (argc != 2){
|
||||
strcpy(info, "argument error");
|
||||
return;
|
||||
}
|
||||
if (strcmp(argv[1], "addin") && strcmp(argv[1], "p1") && strcmp(argv[1], "p2")){
|
||||
sprintf(info, "bad argument");
|
||||
return;
|
||||
}
|
||||
if (!strcmp(argv[1], "addin"))
|
||||
session->anchor = 0x00300200;
|
||||
if (!strcmp(argv[1], "p1"))
|
||||
session->anchor = 0x80000000;
|
||||
if (!strcmp(argv[1], "p2"))
|
||||
session->anchor = 0xa0000000;
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal prototype.
|
||||
static void syscall_jump(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
/* Define command block into the cache section. */
|
||||
CMDBLOCK("syscall", &syscall_jump,
|
||||
"SYSCALL command help\n"
|
||||
"Take one parameter: syscall id.\n"
|
||||
"This command will jump at the\nsyscall's code entry.\n"
|
||||
"\n"
|
||||
"Syscall list (not exhaustive):\n"
|
||||
"0x013 : GLibAddinAppExecutionCheck\n"
|
||||
"0x014 : GLibGetAddinLibInfo\n"
|
||||
"0x014 : GLibGetOSVersionInfo\n"
|
||||
"0x01c : Bdisp_WriteGraph_VRAM\n"
|
||||
"0x01d : Bdisp_WriteGraph_DD\n"
|
||||
"0x01e : Bdisp_WriteGraph_DDVRAM\n"
|
||||
"0x022 : Bdisp_ReadArea_VRAM\n"
|
||||
"0x023 : Bdisp_ReadArea_DD_OS\n"
|
||||
"0x024 : Bdisp_GetDisp_DD\n"
|
||||
"0x026 : DD_GET\n"
|
||||
"0x028 : Bdisp_PutDisp_DD\n"
|
||||
"0x030 : Bdisp_DrawLineVRAM\n"
|
||||
"0x031 : Bdisp_ClearLine_VRAM\n"
|
||||
"0x118 : Bcre_cychdr\n"
|
||||
"0x119 : Bdel_cychdr\n"
|
||||
"0x142 : Bdisp_AllClr_DD\n"
|
||||
"0x143 : Bdisp_AllClr_VRAM\n"
|
||||
"0x144 : Bdisp_AllClr_DDVRAM\n"
|
||||
"0x145 : Bdisp_GetDisp_VRAM\n"
|
||||
"0x147 : Bdisp_SetPoint_DD\n"
|
||||
"0x148 : Bdisp_SetPoint_DDVRAM\n"
|
||||
"0x149 : Bdisp_GetPoint_VRAM\n"
|
||||
"0x14a : Bdisp_AreaClr_DD\n"
|
||||
"0x14b : Bdisp_AreaClr_VRAM\n"
|
||||
"0x14c : Bdisp_AreaClr_DDVRAM\n"
|
||||
"0x14d : Bdisp_AreaReverseVRAM\n"
|
||||
"0x11a : Bsta_cychdr\n"
|
||||
"0x11b : Bstp_cychdr\n"
|
||||
"0x11f : Bdisp_PutDispArea_DD\n"
|
||||
"0x1e7 : BfileFLS_CloseFile\n"
|
||||
"0x218 : flsFindCLose\n"
|
||||
"0x242 : Bkey_Set_RepeatTime\n"
|
||||
"0x243 : Bkey_Get_RepeatTime\n"
|
||||
"0x244 : Bkey_Set_RepeatTime_Default\n"
|
||||
"0x247 : Bkey_GetKeyWait\n"
|
||||
"0x24c : Chattering\n"
|
||||
"0x374 : BMCSRenameVariable\n"
|
||||
"0x3ed : SetFlagPaturn\n"
|
||||
"0x3fa : Hmem_SetMMU\n"
|
||||
"0x420 : BSrl_DummyWAIT\n"
|
||||
"0x42c : Bfile_OpenFile_OS\n"
|
||||
"0x42d : Bfile_CloseFile_OS\n"
|
||||
"0x42e : Bfile_GetMediaFree_OS\n"
|
||||
"0x42f : Bfile_GetFileSize_OS\n"
|
||||
"0x431 : Bfile_SeekFile_OS\n"
|
||||
"0x432 : Bfile_ReadFile_OS\n"
|
||||
"0x434 : Bfile_CreateEntry\n"
|
||||
"0x435 : Bfile_WriteFile_OS\n"
|
||||
"0x439 : Bfile_DeleteEntry\n"
|
||||
"0x43b : Bfile_FindFirst\n"
|
||||
"0x43d : Bfile_FindClose\n"
|
||||
"0x43c : Bfile_FindNext\n"
|
||||
"0x462 : GetAppName\n"
|
||||
"0x494 : CallBackAtQuitMainFunction\n"
|
||||
"0x807 : Locate_OS\n"
|
||||
"0x82b : MCSPutVar2\n"
|
||||
"0x830 : MCSOvwDat2\n"
|
||||
"0x836 : MCSDelVar2\n"
|
||||
"0x840 : MCSGetDlen2\n"
|
||||
"0x841 : MCSGetData1\n"
|
||||
"0x844 : MCSGetCapa\n"
|
||||
"0x8fe : PopUpWin\n"
|
||||
"0x808 : Print\n"
|
||||
"0x809 : PrintRev\n"
|
||||
"0x80b : PrintRev\n"
|
||||
"0x80d : PrintRLine\n"
|
||||
"0x80a : PrintC\n"
|
||||
"0x80c : PrintLine\n"
|
||||
"0x813 : SaveDisp\n"
|
||||
"0x814 : RestoreDisp\n"
|
||||
"0x90f : GetKey\n"
|
||||
"0x9ad : PrintXY\n"
|
||||
"0xacc : free\n"
|
||||
"0xacd : malloc\n"
|
||||
"0xc4f : PrintMiniSd\n"
|
||||
"0xe6b : calloc\n"
|
||||
"0xe6d : realloc\n"
|
||||
"0x1032 : Bkey_GetKeyTableInfo\nJumpFunc\n"
|
||||
);
|
||||
|
||||
static INLINE int check_address(char *str)
|
||||
{
|
||||
--str;
|
||||
while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f'));
|
||||
return ((*str != '\0') ? 1 : 0);
|
||||
}
|
||||
|
||||
//
|
||||
// syscall_jump()
|
||||
// Casio doesn't use the TRAPA instruction (software interruption), for switch from
|
||||
// user mode to privileged mode. They just jump always at 0x80010070 and use the
|
||||
// table of syscall addresses to redirect the jump. (and the table address is always
|
||||
// stored at 0x8001007c).
|
||||
//
|
||||
static void syscall_jump(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
uint32_t *systab;
|
||||
uint32_t id;
|
||||
|
||||
if (argc != 2 || check_address(argv[1]) != 0){
|
||||
strcpy(info, "arguments error");
|
||||
return;
|
||||
}
|
||||
id = atoi_base(argv[1], 16);
|
||||
systab = (void*)(*(uint32_t *)0x8001007c);
|
||||
session->anchor = systab[id];
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal prototype.
|
||||
static void systab_jump(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define the command block into the cache
|
||||
CMDBLOCK("systab", &systab_jump,
|
||||
"SYSTAB command help\n"
|
||||
"This function allows user to\njump into the Casio \"syscall\n"
|
||||
"handler\".\n"
|
||||
"\n"
|
||||
"Curiously, Casio doesn't use the"
|
||||
"TRAPA instruction for handle\n"
|
||||
"syscall, but jump at\n0x80010070.\n"
|
||||
"This don't explain why we are\nalways in privileged mode, but\n"
|
||||
"now we can affirm that Casio\ndo it intentionally.\n"
|
||||
);
|
||||
|
||||
/* systab_jump() - Jump into the Casio "syscall handler". */
|
||||
static void systab_jump(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
if (argc != 1){
|
||||
strcpy(info, "argument error");
|
||||
return;
|
||||
}
|
||||
(void)argv;
|
||||
session->anchor = 0x80010070;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// Internal prototype
|
||||
static void vbrjmp(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// TODO: write doc.
|
||||
CMDBLOCK("vbrjmp", &vbrjmp,
|
||||
"VBR JUMP command help\n"
|
||||
"This command jump into Casio's\nhandlers.\n"
|
||||
"\n"
|
||||
"Due to the SH3 / SH4 VBR system\n, there are 3 vectors offset\n"
|
||||
"called by the processor:\n"
|
||||
" * exception (VBR + 0x100)\n"
|
||||
" * tlb miss (VBR + 0x400)\n"
|
||||
" * interrupt (VBR + 0x600)\n"
|
||||
"\n"
|
||||
"You can access to each handler\nusing this command list:\n"
|
||||
":vbrjmp except VBR + 0x100\n"
|
||||
":vbrjmp fault VBR + 0x400\n"
|
||||
":vbrjmp int VBR + 0x600\n"
|
||||
);
|
||||
|
||||
//
|
||||
// vbr_jump() - jump to the exception, tlb or interrupt, Casio handler.
|
||||
// Due to the SH3 / SH4 VBR system, there are 3 vectors offset called
|
||||
// by the processor:
|
||||
// * vbr + 0x100 -> general exeptions.
|
||||
// * vbr + 0x400 -> tlb miss.
|
||||
// * vbr + 0x600 -> interrupts.
|
||||
//
|
||||
static void vbrjmp(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
if (argc != 2){
|
||||
strcpy(info, "arguments error");
|
||||
return;
|
||||
}
|
||||
if (strcmp(argv[1], "fault") && strcmp(argv[1], "except") && strcmp(argv[1], "int")){
|
||||
sprintf(info, "bad argument");
|
||||
return;
|
||||
}
|
||||
__asm__ volatile ("stc vbr, %0" : "=r"(session->anchor));
|
||||
if (!strcmp(argv[1], "except"))
|
||||
session->anchor += 0x100;
|
||||
if (!strcmp(argv[1], "fault"))
|
||||
session->anchor += 0x400;
|
||||
if (!strcmp(argv[1], "int"))
|
||||
session->anchor += 0x600;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// internal prototype.
|
||||
static void quit(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define the command into the cache.
|
||||
CMDBLOCK("quit", &quit, NULL);
|
||||
|
||||
/* quit() - switch to UNUSED mode */
|
||||
static void quit(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
strcpy(info, "exit");
|
||||
session->mode = UNUSED;
|
||||
session->anchor = 0x00000000;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
// internal prototype.
|
||||
static void where(int argc, char **argv, struct session_s *session, char *info);
|
||||
|
||||
// Define the command into the cache.
|
||||
CMDBLOCK("where", &where, NULL);
|
||||
|
||||
/* where() - display the user positision in the Virtual Memory. */
|
||||
static void where(int argc, char **argv, struct session_s *session, char *info)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
sprintf(info, "%#x", session->anchor + (session->cursor << 1));
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
#include <utils.h>
|
||||
#include <syscalls.h>
|
||||
#include <opcode.h>
|
||||
#include <string.h>
|
||||
|
||||
//TODO: move me ?
|
||||
static INLINE int get_shift(uint16_t mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mask == 0x0000)
|
||||
return (0);
|
||||
i = -1;
|
||||
while (++i < 16 && !(mask & (0x01 << i)));
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* get_instructions() - find mnemonic and instruction argument(s) */
|
||||
static void get_instructions(char *str, uint16_t bytes_code)
|
||||
{
|
||||
int shift[ARGUMENTS_MAX];
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
i = -1;
|
||||
while (opcode[++i].name != NULL
|
||||
&& (bytes_code & opcode[i].mask) != opcode[i].code);
|
||||
if (opcode[i].name == NULL){
|
||||
strcpy(str, "????");
|
||||
return;
|
||||
}
|
||||
j = -1;
|
||||
while (++j < ARGUMENTS_MAX)
|
||||
shift[j] = get_shift(opcode[i].arg_mask[j]);
|
||||
//TODO: update this.
|
||||
sprintf(str, opcode[i].name,
|
||||
(bytes_code & opcode[i].arg_mask[0]) >> shift[0],
|
||||
(bytes_code & opcode[i].arg_mask[1]) >> shift[1],
|
||||
(bytes_code & opcode[i].arg_mask[2]) >> shift[2]);
|
||||
}
|
||||
|
||||
//
|
||||
// display_instructions()
|
||||
// Translate "on-the-fly" each binary instructions stored at
|
||||
// the anchor location.
|
||||
// Almost instructions can be translated; only FPU instructions
|
||||
// is not handled because it's not available on the SH3 based MPU.
|
||||
//
|
||||
void display_instructions(const struct session_s *session)
|
||||
{
|
||||
char mnemonic[128];
|
||||
uint16_t *area;
|
||||
char buf[64];
|
||||
size_t y;
|
||||
|
||||
if (session->mode == COMMAND){
|
||||
restore_window(1);
|
||||
return;
|
||||
}
|
||||
if (session->mode == UNUSED || session->anchor == 0x00000000){
|
||||
print((SCREEN_WIDTH >> 1) - ((sizeof("Empty session") * FONT_WIDTH) >> 1),
|
||||
(SCREEN_HEIGHT >> 1) - (FONT_HEIGHT >> 1), "Empty session");
|
||||
return;
|
||||
}
|
||||
y = -1;
|
||||
area = (void*)(session->anchor + (session->cursor << 1));
|
||||
while (++y < LINE_OFFSET){
|
||||
get_instructions(mnemonic, area[y]);
|
||||
sprintf(buf, "%4x %4x %s", &(area[y]), area[y], mnemonic);
|
||||
print(0, y * FONT_HEIGHT, buf);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#include <utils.h>
|
||||
#include <syscalls.h>
|
||||
#include <string.h>
|
||||
|
||||
/* display_metainfo() - display the "status" bar and display user's information */
|
||||
void display_metainfos(const struct vhex_s *vhex, const struct session_s *session)
|
||||
{
|
||||
static const char *mode_name[] = {"unused", "command", "normal", "free"};
|
||||
static const char insert_name[] = {'l', 'L', 'n', 's'};
|
||||
const void *tmp;
|
||||
char buf[32];
|
||||
|
||||
// clear area
|
||||
dclear_area(0, SCREEN_HEIGHT - FONT_HEIGHT - 2, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||||
dline_horizontal(SCREEN_HEIGHT - FONT_HEIGHT - 2, 0, SCREEN_WIDTH - 1);
|
||||
|
||||
// Display informations
|
||||
sprintf(buf, "[%s][%d]", mode_name[session->mode], vhex->current_session);
|
||||
print(SCREEN_WIDTH - (strlen(buf) * FONT_WIDTH) - 1, SCREEN_HEIGHT - FONT_HEIGHT, buf);
|
||||
if (session->mode == COMMAND)
|
||||
sprintf(buf, "[%c]:%s#", insert_name[vhex->insert.mode], vhex->insert.cmd);
|
||||
else {
|
||||
tmp = (*vhex->info == '\0') ? vhex->insert.cmd : vhex->info;
|
||||
sprintf(buf, "[%c] %s", insert_name[vhex->insert.mode], tmp);
|
||||
}
|
||||
print(0, SCREEN_HEIGHT - FONT_HEIGHT, buf);
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
#ifndef DEBUG
|
||||
# include <history.h>
|
||||
# include <syscalls.h>
|
||||
#else
|
||||
# include "history.h"
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
//---
|
||||
// history_update()
|
||||
// Add new history node to the chained list. This is a singly
|
||||
// linked list, but the node insertion from the beginning.
|
||||
//
|
||||
// Exemple: add node A, B, C and D
|
||||
// 1. A -> NULL
|
||||
// 2. B -> A -> NULL
|
||||
// 3. C -> B -> A -> NULL
|
||||
// 4. D -> C -> B -> A -> NULL
|
||||
//---
|
||||
int history_update(struct node **list, const char *data)
|
||||
{
|
||||
void *swap;
|
||||
|
||||
if (list == NULL)
|
||||
return (EFAULT);
|
||||
swap = *list;
|
||||
*list = (struct node *)malloc(sizeof(struct node));
|
||||
if (*list == NULL){
|
||||
*list = swap;
|
||||
return (ENOMEM);
|
||||
}
|
||||
strcpy((void*)(*list)->data, data);
|
||||
(*list)->next = swap;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// history_get()
|
||||
// primitive function which will return the data stored in
|
||||
// the "offset" position in the list.
|
||||
//
|
||||
const void *history_get(struct node *list, off_t offset)
|
||||
{
|
||||
if (list == NULL)
|
||||
return (NULL);
|
||||
if (offset == 0)
|
||||
return (list->data);
|
||||
return (history_get(list->next, offset - 1));
|
||||
}
|
||||
|
||||
//
|
||||
// history_quit()
|
||||
// Free all allocated memory.
|
||||
//
|
||||
void history_quit(struct node **list)
|
||||
{
|
||||
if (list == NULL || *list == NULL)
|
||||
return;
|
||||
history_quit(&(*list)->next);
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
|
||||
void fx9860_context_save(fx9860_context_t *context)
|
||||
{
|
||||
// Save Interrupt Controller (INTC)
|
||||
context->intc.ipra = SH7305_INTC.IPRA.WORD;
|
||||
context->intc.iprb = SH7305_INTC.IPRB.WORD;
|
||||
context->intc.iprc = SH7305_INTC.IPRC.WORD;
|
||||
context->intc.iprd = SH7305_INTC.IPRD.WORD;
|
||||
context->intc.ipre = SH7305_INTC.IPRE.WORD;
|
||||
context->intc.iprf = SH7305_INTC.IPRF.WORD;
|
||||
context->intc.iprg = SH7305_INTC.IPRG.WORD;
|
||||
context->intc.iprh = SH7305_INTC.IPRH.WORD;
|
||||
context->intc.ipri = SH7305_INTC.IPRI.WORD;
|
||||
context->intc.iprj = SH7305_INTC.IPRJ.WORD;
|
||||
context->intc.iprk = SH7305_INTC.IPRK.WORD;
|
||||
context->intc.iprl = SH7305_INTC.IPRL.WORD;
|
||||
|
||||
// Save Key Scan (KEYSC) context.
|
||||
context->keyboard.control = SH7305_KEYSC.CONTROL.WORD;
|
||||
context->keyboard.autofix = SH7305_KEYSC.AUTOFIX.WORD;
|
||||
context->keyboard.scan_mode = SH7305_KEYSC.SCAN_MODE.WORD;
|
||||
context->keyboard.scan_state = SH7305_KEYSC.SCAN_STATE.WORD;
|
||||
context->keyboard.interrupt = SH7305_KEYSC.INTERRUPT.WORD;
|
||||
context->keyboard.scan_wait = SH7305_KEYSC.SCAN_WAIT.WORD;
|
||||
context->keyboard.scan_interval = SH7305_KEYSC.SCAN_INTERVAL;
|
||||
context->keyboard.kyoutdr = SH7305_KEYSC.KYOUTDR.WORD;
|
||||
context->keyboard.kyindr = SH7305_KEYSC.KYINDR.WORD;
|
||||
}
|
||||
|
||||
void fx9860_context_restore(fx9860_context_t *context)
|
||||
{
|
||||
// Restore Key Scan (KEYSC) context.
|
||||
SH7305_KEYSC.CONTROL.WORD = context->keyboard.control;
|
||||
SH7305_KEYSC.AUTOFIX.WORD = context->keyboard.autofix;
|
||||
SH7305_KEYSC.SCAN_MODE.WORD = context->keyboard.scan_mode;
|
||||
SH7305_KEYSC.SCAN_STATE.WORD = context->keyboard.scan_state;
|
||||
SH7305_KEYSC.INTERRUPT.WORD = context->keyboard.interrupt;
|
||||
SH7305_KEYSC.SCAN_WAIT.WORD = context->keyboard.scan_wait;
|
||||
SH7305_KEYSC.SCAN_INTERVAL = context->keyboard.scan_interval;
|
||||
SH7305_KEYSC.KYOUTDR.WORD = context->keyboard.kyoutdr;
|
||||
SH7305_KEYSC.KYINDR.WORD = context->keyboard.kyindr;
|
||||
|
||||
// Restore Interrupt Controller (INTC)
|
||||
SH7305_INTC.IPRA.WORD = context->intc.ipra;
|
||||
SH7305_INTC.IPRB.WORD = context->intc.iprb;
|
||||
SH7305_INTC.IPRC.WORD = context->intc.iprc;
|
||||
SH7305_INTC.IPRD.WORD = context->intc.iprd;
|
||||
SH7305_INTC.IPRE.WORD = context->intc.ipre;
|
||||
SH7305_INTC.IPRF.WORD = context->intc.iprf;
|
||||
SH7305_INTC.IPRG.WORD = context->intc.iprg;
|
||||
SH7305_INTC.IPRH.WORD = context->intc.iprh;
|
||||
SH7305_INTC.IPRI.WORD = context->intc.ipri;
|
||||
SH7305_INTC.IPRJ.WORD = context->intc.iprj;
|
||||
SH7305_INTC.IPRK.WORD = context->intc.iprk;
|
||||
SH7305_INTC.IPRL.WORD = context->intc.iprl;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
#include <kernel/types.h>
|
||||
|
||||
/* check_sh3 - Detecting sh3-based MPU */
|
||||
static mpu_t check_sh3(uint16_t tplcr)
|
||||
{
|
||||
if (tplcr == 0x0fff)
|
||||
return (MPU_SH7337);
|
||||
if (tplcr == 0x00ff)
|
||||
return (MPU_SH7355);
|
||||
return (MPU_UNKNOWN);
|
||||
}
|
||||
|
||||
/* check_sh3 - Detecting sh4-based MPU */
|
||||
static mpu_t check_sh4(void)
|
||||
{
|
||||
volatile uint32_t *pvr = (void *)0xff000030;
|
||||
volatile uint32_t *prr = (void *)0xff000044;
|
||||
uint32_t product;
|
||||
|
||||
if ((*pvr & 0xffffff00) != 0x10300b00)
|
||||
return (MPU_UNKNOWN);
|
||||
product = *prr & 0xfffffff0;
|
||||
if (product == 0x00002c00)
|
||||
return (MPU_SH7305);
|
||||
if (product == 0x00002200)
|
||||
return (MPU_SH7724);
|
||||
return (MPU_UNKNOWN);
|
||||
}
|
||||
|
||||
//
|
||||
// get_mpu()
|
||||
//
|
||||
// Return the MPU identifier of the calculator.
|
||||
// Thanks to SimonLothar and Lephenixnoir for this function
|
||||
// and related information.
|
||||
//
|
||||
// Processor version register (PVR) and product control register (PRR)
|
||||
// hold information about the MPU version, they but are only accessible on
|
||||
// SH-4-based MPUs.
|
||||
// To detect SH-3-based MPUs, this function uses port L control register
|
||||
// (PLCR), whose bits 8 to 15 cannot be set with SH7337 where bits 8 to 11
|
||||
// can be set with SH7355.
|
||||
//
|
||||
// Additionally, the CPU core ID register (CPIDR) at 0xff000048 returns 1
|
||||
// on SH7305.
|
||||
//
|
||||
mpu_t mpu_get(void)
|
||||
{
|
||||
volatile uint16_t *plcr = (void *)0xa4000114;
|
||||
uint16_t splcr;
|
||||
uint16_t tplcr;
|
||||
mpu_t mpu;
|
||||
|
||||
// Check port L control register.
|
||||
splcr = *plcr;
|
||||
*plcr = 0xffff;
|
||||
tplcr = *plcr;
|
||||
*plcr = splcr;
|
||||
|
||||
mpu = check_sh3(tplcr);
|
||||
if (mpu != MPU_UNKNOWN)
|
||||
return (mpu);
|
||||
return (check_sh4());
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
.globl _section_wipe
|
||||
.global _section_load
|
||||
.type _section_load, @function
|
||||
.type _section_wipe, @function
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** section_map(uint32_t *dest, uint32_t *src, size_t size)
|
||||
** Load section using his symbols.
|
||||
*/
|
||||
_section_load:
|
||||
shlr2 r6 ! sections are force 4-aligned by the linker.
|
||||
tst r6, r6 ! check null section...
|
||||
bt load_loop_end ! ...if null, exit.
|
||||
|
||||
load_loop_entry:
|
||||
mov.l @r5, r1 ! get "src" data.
|
||||
mov.l r1, @r4 ! copy into the "dest" section.
|
||||
add #4, r5 ! update "src" address.
|
||||
dt r6 ! check the load size.
|
||||
bf/s load_loop_entry ! loop jump.
|
||||
add #4, r4 ! update "dest" address.
|
||||
|
||||
load_loop_end:
|
||||
rts ! clean exit.
|
||||
nop ! delayed branch.
|
||||
|
||||
|
||||
/*
|
||||
** section_wipe(uint32_t *bsection, size_t size)
|
||||
** Wipe section using his symbols.
|
||||
*/
|
||||
_section_wipe:
|
||||
mov #0, r0 ! wipe data.
|
||||
shlr2 r5 ! the section force 4-aligned by the linker.
|
||||
tst r5, r5 ! Check null section...
|
||||
bt wipe_loop_end ! ...if null, exit !
|
||||
|
||||
wipe_loop_entry:
|
||||
mov.l r0, @r4 ! wipe section part.
|
||||
dt r5 ! check the section size.
|
||||
bf/s wipe_loop_entry ! loop jump.
|
||||
add #4, r4 ! address update.
|
||||
|
||||
wipe_loop_end:
|
||||
rts ! clean exit.
|
||||
nop ! delayed branch.
|
||||
|
||||
.end
|
|
@ -0,0 +1,151 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <kernel/types.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal symbols
|
||||
//uint32_t gcc_fix[256];
|
||||
//uint32_t *VRAM = gcc_fix;
|
||||
mpu_t current_mpu = MPU_UNKNOWN;
|
||||
const char *casio_os_version = (void*)0xa0010020;
|
||||
fx9860_context_t casio_context;
|
||||
uint32_t casio_vbr;
|
||||
|
||||
// Symbols defined by the linker
|
||||
extern uint32_t bbss;
|
||||
extern uint32_t sbss;
|
||||
extern uint32_t bdata_ram;
|
||||
extern uint32_t bdata_rom;
|
||||
extern uint32_t sdata;
|
||||
extern uint32_t bvhex_ram;
|
||||
extern uint32_t bvhex_rom;
|
||||
extern uint32_t svhex;
|
||||
extern uint32_t vhex_vbr;
|
||||
|
||||
// Internal functions.
|
||||
extern void section_wipe(uint32_t *section, size_t size);
|
||||
extern void section_load(uint32_t *dest, uint32_t *src, size_t size);
|
||||
extern uint32_t vbr_set(uint32_t new_vbr);
|
||||
extern uint32_t vbr_get(void);
|
||||
extern mpu_t mpu_get(void);
|
||||
extern int main(void);
|
||||
extern void vhex_context_set(void);
|
||||
|
||||
|
||||
__attribute__((section(".pretext")))
|
||||
int start(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
// Wipe .bss section and dump .data / Vhex sections
|
||||
section_wipe(&bbss, (size_t)&sbss);
|
||||
section_load(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
||||
section_load(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
|
||||
// Check MPU hardware.
|
||||
current_mpu = mpu_get();
|
||||
if (current_mpu != MPU_SH7305)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Mask interrupt, change context and switch VBR.
|
||||
atomic_start();
|
||||
fx9860_context_save(&casio_context);
|
||||
casio_vbr = vbr_set((uint32_t)&vhex_vbr);
|
||||
vhex_context_set();
|
||||
atomic_end();
|
||||
|
||||
// VBR test.
|
||||
__asm__ volatile ("trapa #0");
|
||||
|
||||
// Call high level abstraction.
|
||||
error = main();
|
||||
|
||||
// Mask interrupt, change context and switch VBR.
|
||||
atomic_start();
|
||||
fx9860_context_restore(&casio_context);
|
||||
vbr_set(casio_vbr);
|
||||
atomic_end();
|
||||
|
||||
// Return the abstraction error.
|
||||
return (error);
|
||||
}
|
||||
|
||||
//
|
||||
// initialize() - kernel entry
|
||||
// This is the "real" entry of the kernel (after stack and CPU configuration).
|
||||
// This part *SHOULD* be exception safe because the CPU block all exception and interruption,
|
||||
// so if an exception occur during the "bootstrap" part, the processor will "crash".
|
||||
//
|
||||
/*void initialize(void)
|
||||
{
|
||||
interrupt_block();
|
||||
printk(KERN_NOTICE, "Kernel initialization...\n");
|
||||
|
||||
// Wipe BSS section !
|
||||
printk(KERN_NOTICE, "Wipe bss / dump data...\n");
|
||||
memcpy(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
||||
memset(&bbss, 0x00, (size_t)&sbss);
|
||||
|
||||
|
||||
// Check MPU.
|
||||
current_mpu = mpu_get();
|
||||
if (current_mpu != MPU_SH7305)
|
||||
{
|
||||
printk(KERN_NOTICE, "ARCH ERROR !\n");
|
||||
int i = -1;
|
||||
while (++i < 500000);
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Dump kernel and data.
|
||||
printk(KERN_NOTICE, "Dump VBR space...\n");
|
||||
memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
|
||||
// Initialize Interruption (extern module, VBR, handlers)
|
||||
printk(KERN_NOTICE, "Initialize hardware context...\n");
|
||||
sh7305_context_initialize();
|
||||
|
||||
// Save / set new VBR.
|
||||
printk(KERN_NOTICE, "Switch VBR / SR register...\n");
|
||||
__asm__ volatile (
|
||||
"stc vbr, %0;"
|
||||
"stc sr, %1;"
|
||||
"ldc %2, vbr;"
|
||||
"ldc %3, sr"
|
||||
: "=r"(casio_vbr), "=r"(casio_sr)
|
||||
: "r"(&vhex_vbr), "r"(0x60000000)
|
||||
:
|
||||
);
|
||||
|
||||
printk(KERN_NOTICE, "Initialize heap space...\n");
|
||||
pm_heap_initialize((void*)0x8806000, (void*)0x8808000, 32);
|
||||
|
||||
// Kernel initialized !
|
||||
printk(KERN_NOTICE, "Kernel initialized !\n");
|
||||
interrupt_unblock();
|
||||
|
||||
// Call shell.
|
||||
shell_entry();
|
||||
|
||||
// Kernel exit part.
|
||||
printk(KERN_NOTICE, "Kernel exit !");
|
||||
interrupt_block();
|
||||
|
||||
// restore Casio's context.
|
||||
printk(KERN_NOTICE, "Restore hardware context...\n");
|
||||
sh7305_context_restore();
|
||||
|
||||
// Restore VBR / CPU configurations.
|
||||
printk(KERN_NOTICE, "Restore VBR / SR...\n");
|
||||
__asm__ volatile ("ldc %0, vbr" : : "r"(&casio_vbr) : );
|
||||
__asm__ volatile ("ldc %0, sr" : : "r"(casio_sr) : );
|
||||
|
||||
// Clean exit.
|
||||
interrupt_unblock();
|
||||
return (0);
|
||||
}*/
|
|
@ -0,0 +1,35 @@
|
|||
.global _vbr_get
|
||||
.global _vbr_set
|
||||
|
||||
.type _vbr_set, @function
|
||||
.type _vbr_get, @function
|
||||
|
||||
.text
|
||||
.align 2
|
||||
_vbr_get:
|
||||
stc vbr, r0 ! Get VBR register.
|
||||
rts ! Exit
|
||||
nop ! (db) nop
|
||||
|
||||
_vbr_set:
|
||||
! Block interrupt
|
||||
stc sr, r1 ! Get SR register.
|
||||
mov r1, r3 ! Save current SR data.
|
||||
mov.l .bl_mask, r2 ! Get SR.BL mask.
|
||||
or r2, r1 ! Set SR.BL to 1.
|
||||
ldc r1, sr ! Update SR register.
|
||||
|
||||
! Get / Changle VBR
|
||||
stc vbr, r0 ! Get VBR register.
|
||||
ldc r4, vbr ! Update VBR register.
|
||||
|
||||
! Unblock interrupt.
|
||||
ldc r3, sr ! Restore SR register.
|
||||
|
||||
! Exit
|
||||
rts ! Exit
|
||||
nop ! (db) nop
|
||||
|
||||
.align 4
|
||||
.bl_mask: .long 0x100000f0
|
||||
.end
|
|
@ -0,0 +1,52 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
|
||||
void vhex_context_set(void)
|
||||
{
|
||||
// Initialize Interrupt Controller (INTC).
|
||||
SH7305_INTC.IPRA.WORD = 0x0000;
|
||||
SH7305_INTC.IPRB.WORD = 0x0000;
|
||||
SH7305_INTC.IPRC.WORD = 0x0000;
|
||||
SH7305_INTC.IPRD.WORD = 0x0000;
|
||||
SH7305_INTC.IPRE.WORD = 0x0000;
|
||||
SH7305_INTC.IPRF.WORD = 0x0000;
|
||||
SH7305_INTC.IPRG.WORD = 0x0000;
|
||||
SH7305_INTC.IPRH.WORD = 0x0000;
|
||||
SH7305_INTC.IPRI.WORD = 0x0000;
|
||||
SH7305_INTC.IPRJ.WORD = 0x0000;
|
||||
SH7305_INTC.IPRK.WORD = 0x0000;
|
||||
SH7305_INTC.IPRL.WORD = 0x0000;
|
||||
|
||||
// Configure Key Scan (KEYSC)
|
||||
/* SH7305_INTC.IMR5.KEYI = 1; // Mask KEYSC interrupt.
|
||||
SH7305_INTC.IPRF.KEYSC = 15; // Disable KEYSC interrupt.
|
||||
SH7305_KEYSC.CONTROL.KEYIE = 0; // Disable KEYSC interrupt during init.
|
||||
SH7305_KEYSC.CONTROL.INTMODE = 0b00; // Use default (?) interrupt mode.
|
||||
SH7305_KEYSC.AUTOFIX.ENABLE = 1; // Enable key bounce fix (?)
|
||||
SH7305_KEYSC.AUTOFIX.UNKNOWN0 = 0b100; // Unknown, use Casio's value. (autofix)
|
||||
SH7305_KEYSC.AUTOFIX.UNKNOWN1 = 0b10; // Unknown, use Casio's value. (autofix)
|
||||
SH7305_KEYSC.SCAN_MODE.UNKNOWN0 = 0b000; // Unknown, use Casio's value. (scan mode)
|
||||
SH7305_KEYSC.SCAN_MODE.UNKNOWN1 = 0b010; // Unknown, use Casio's value. (scan mode)
|
||||
SH7305_KEYSC.INTERRUPT.KYCPU_IE = 0b0000100; // Interrupt when one key is pressed or released.
|
||||
SH7305_KEYSC.SCAN_WAIT.TIME = 0x00; // No time between each interrupt.
|
||||
SH7305_KEYSC.SCAN_INTERVAL = 0x98; // Unknown, use Casio's value. (scan interval)
|
||||
SH7305_KEYSC.KYOUTDR.KYO5DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYOUTDR.KYO4DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYOUTDR.KYO3DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYOUTDR.KYO2DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYOUTDR.KYO1DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYOUTDR.KYO0DT = 0b11; // Trigger when high-impedance state is detected.
|
||||
SH7305_KEYSC.KYINDR.KYDIR6 = 1; // Scan [F1],[SHIFT],[ALPHA],[x,o,T],[div],[7],[4],[1],[0]
|
||||
SH7305_KEYSC.KYINDR.KYDIR5 = 1; // Scan [F2],[OPT],[^2],[log],[FD],[8],[5],[2],[.]
|
||||
SH7305_KEYSC.KYINDR.KYDIR4 = 1; // Scan [F3],[VAR],[^],[ln],[(],[9],[6],[3],[x10]
|
||||
SH7305_KEYSC.KYINDR.KYDIR3 = 1; // Scan [F4],[MENU],[EXIT],[sin],[)],[DEL],[x],[+],[(-)]
|
||||
SH7305_KEYSC.KYINDR.KYDIR2 = 1; // Scan [F5],[left],[down],[cos],[,],[%],[-],[EXE]
|
||||
SH7305_KEYSC.KYINDR.KYDIR1 = 1; // Scan [F6],[up],[right],[tan],[->]
|
||||
SH7305_KEYSC.KYINDR.KYDIR0 = 1; // Scan [AC/ON]
|
||||
SH7305_KEYSC.CONTROL.KEYIE = 1; // Enable KEYSC interrupt.
|
||||
SH7305_INTC.IPRF.KEYSC = 15; // Set KEYSC interrupt priority (max).
|
||||
SH7305_INTC.IMCR5.KEYI = 1; // Clear KEYSC interrupt mask.
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
.global _t6k11_display
|
||||
.type _t6k11_display, @function
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/*
|
||||
_t6k11_display(void *vram)
|
||||
This function will display the vram on the screen.
|
||||
This is the T6K11 drivers, DO NOT USE this function if you are
|
||||
not absolutly sure that what you are doing.
|
||||
|
||||
TODO: use DMA ?
|
||||
*/
|
||||
# register organisation:
|
||||
# r0 Y axis loop.
|
||||
# r1 LCD register selector.
|
||||
# r2 LCD data register.
|
||||
# r3 X axis loop.
|
||||
# r4 VRAM address.
|
||||
_t6k11_display:
|
||||
mov.l r8, @-r15
|
||||
mov.l r9, @-r15
|
||||
mov.l 1f, r1
|
||||
mov.l 2f, r2
|
||||
mov #4, r6
|
||||
mov #0, r7
|
||||
mov #7, r8
|
||||
mov #192, r5
|
||||
mov #64, r0
|
||||
loop_y:
|
||||
|
||||
mov.b r6, @r1
|
||||
mov.b r5, @r2
|
||||
mov.b r6, @r1
|
||||
mov.b r7, @r2
|
||||
mov.b r8, @r1
|
||||
mov #16, r3
|
||||
loop_x:
|
||||
|
||||
mov.b @r4+, r9
|
||||
mov.b r9, @r2
|
||||
|
||||
dt r3
|
||||
bf loop_x
|
||||
|
||||
dt r0
|
||||
bf.s loop_y
|
||||
add #1, r5
|
||||
mov.l @r15+, r9
|
||||
rts
|
||||
mov.l @r15+, r8
|
||||
|
||||
.align 4
|
||||
1: .long 0xb4000000 /* LCD register selector */
|
||||
2: .long 0xb4010000 /* LCD data register */
|
|
@ -0,0 +1,7 @@
|
|||
#include <kernel/tty.h>
|
||||
|
||||
int tty_close(void)
|
||||
{
|
||||
// Do nothing for now.
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include <kernel/tty.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Internal TTY object.
|
||||
struct tty_s tty;
|
||||
|
||||
int tty_open(void)
|
||||
{
|
||||
// Initialize TTY.
|
||||
tty.cursor.x = 0;
|
||||
tty.cursor.y = 0;
|
||||
tty.cursor.max.x = DISPLAY_SCREEN_WIDTH / (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
tty.cursor.max.y = DISPLAY_SCREEN_HEIGHT / (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
|
||||
// Clear VRAM.
|
||||
dclear();
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#include <kernel/tty.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Internal TTY object.
|
||||
extern struct tty_s tty;
|
||||
|
||||
static void tty_new_line(void)
|
||||
{
|
||||
tty.cursor.x = 0;
|
||||
if (tty.cursor.y + 1 >= tty.cursor.max.y)
|
||||
{
|
||||
dscroll(KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
return;
|
||||
}
|
||||
tty.cursor.y = tty.cursor.y + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
static void tty_update_cursor(void)
|
||||
{
|
||||
tty.cursor.x = tty.cursor.x + 1;
|
||||
if (tty.cursor.x >= tty.cursor.max.x)
|
||||
tty_new_line();
|
||||
}
|
||||
|
||||
int tty_write(char const *str, ...)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Do not handle strig format for now.
|
||||
|
||||
// Display string format.
|
||||
i = -1;
|
||||
while (str[++i] != '\0')
|
||||
{
|
||||
// Check new line char.
|
||||
if (str[i] == '\n')
|
||||
tty_new_line();
|
||||
// Display char.
|
||||
dascii(
|
||||
tty.cursor.x * (KERNEL_FONT_REAL_WIDTH + 1),
|
||||
tty.cursor.y * (KERNEL_FONT_REAL_HEIGHT + 1),
|
||||
str[i]
|
||||
);
|
||||
tty_update_cursor();
|
||||
}
|
||||
dupdate();
|
||||
return (i);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
.global _atomic_start
|
||||
.global _atomic_end
|
||||
|
||||
.type _atomic_start, @function
|
||||
.type _atomic_end, @function
|
||||
|
||||
.align 2
|
||||
_atomic_start:
|
||||
stc sr, r1 ! Get SR register.
|
||||
mov.l .bl_mask, r0 ! Get SR.BL mask.
|
||||
or r0, r1 ! Set SR.BL to 1.
|
||||
ldc r1, sr ! Update SR register.
|
||||
rts ! Exit.
|
||||
nop ! (db) nop.
|
||||
|
||||
_atomic_end:
|
||||
stc sr, r1 ! Get SR regiter.
|
||||
mov.l .bl_mask, r0 ! Get SR.BL register.
|
||||
not r0, r0 ! Get correct mask to remove the SR.BL bit.
|
||||
and r0, r1 ! Set SR.BL to 0.
|
||||
ldc r1, sr ! Update SR register.
|
||||
rts ! Exit.
|
||||
nop ! (db) nop.
|
||||
|
||||
.align 4
|
||||
.bl_mask: .long (1 << 28)
|
||||
.end
|
|
@ -0,0 +1,38 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".vhex.exception"), interrupt_handler))
|
||||
void exception_handler(void)
|
||||
{
|
||||
uint32_t spc;
|
||||
uint32_t ssr;
|
||||
uint32_t sr;
|
||||
|
||||
|
||||
// Get some registers's data.
|
||||
__asm__ volatile (
|
||||
"stc spc, %0;"
|
||||
"stc ssr, %1;"
|
||||
"stc sr, %2"
|
||||
: "=r"(spc), "=r"(ssr), "=r"(sr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
"spc: %#x\n"
|
||||
"ssr: %#x\n"
|
||||
"sr: %#x",
|
||||
*((uint32_t *)0xff000020),
|
||||
*((uint32_t *)0xff000024),
|
||||
spc,
|
||||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".vhex.interrupt"), interrupt_handler))
|
||||
void interrupt_handler(void)
|
||||
{
|
||||
dclear();
|
||||
dprint(0, 0, "Interrupt handler (%#x)\n", *(uint32_t*)0xff000028);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".glados.tlb"), interrupt_handler))
|
||||
void tlb_handler(void)
|
||||
{
|
||||
uint32_t spc;
|
||||
uint32_t ssr;
|
||||
uint32_t sr;
|
||||
|
||||
|
||||
// Get some registers's data.
|
||||
__asm__ volatile (
|
||||
"stc spc, %0;"
|
||||
"stc ssr, %1;"
|
||||
"stc sr, %2"
|
||||
: "=r"(spc), "=r"(ssr), "=r"(sr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
"spc: %#x\n"
|
||||
"ssr: %#x\n"
|
||||
"sr: %#x",
|
||||
*((uint32_t *)0xff000020),
|
||||
*((uint32_t *)0xff000024),
|
||||
spc,
|
||||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
170
src/keys.c
170
src/keys.c
|
@ -1,170 +0,0 @@
|
|||
#include <utils.h>
|
||||
#include <syscalls.h>
|
||||
#include <command.h>
|
||||
#include <string.h>
|
||||
|
||||
//
|
||||
// check_session()
|
||||
// Check if the pressed key is [Fx], and switch the current session.
|
||||
//
|
||||
static int check_session(unsigned int key, struct vhex_s *vhex)
|
||||
{
|
||||
static const unsigned int keys_switch[SESSIONS_SLOT] = {
|
||||
KEY_F1, KEY_F2, KEY_F3,
|
||||
KEY_F4, KEY_F5, KEY_F6
|
||||
};
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < SESSIONS_SLOT && key != keys_switch[i]);
|
||||
if (i < SESSIONS_SLOT){
|
||||
vhex->current_session = i;
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
//
|
||||
// check_special()
|
||||
// As explained below, the Casio getkey function has an internal status.
|
||||
// Here we check if a "special" keys are pressed and update internal Vhex
|
||||
// "keyboard's status".
|
||||
//
|
||||
static int check_special(unsigned int key, struct vhex_s *vhex, struct session_s *session)
|
||||
{
|
||||
if (!(key == KEY_OPTN || key == KEY_SHIFT || key == KEY_ALPHA))
|
||||
return (-1);
|
||||
if (vhex->insert.mode == LETTER){
|
||||
vhex->insert.mode = NUMBER;
|
||||
if (key == KEY_ALPHA)
|
||||
return (0);
|
||||
}
|
||||
if (key == KEY_OPTN){
|
||||
if (session->mode != COMMAND){
|
||||
memset(vhex->info, '\0', CMD_LENGHT_MAX);
|
||||
session->mode = COMMAND;
|
||||
save_window(1);
|
||||
}
|
||||
else
|
||||
session->mode = (session->anchor == 0x00000000) ? UNUSED : NORMAL;
|
||||
}
|
||||
if (key == KEY_SHIFT)
|
||||
vhex->insert.mode = (vhex->insert.mode == SHIFT) ? NUMBER : SHIFT;
|
||||
if (key == KEY_ALPHA){
|
||||
//TODO: update this.
|
||||
if (vhex->insert.mode == SHIFT)
|
||||
vhex->insert.mode = CAPS_LOCK;
|
||||
else if (vhex->insert.mode == CAPS_LOCK)
|
||||
vhex->insert.mode = NUMBER;
|
||||
else
|
||||
vhex->insert.mode = LETTER;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// check_alphanum()
|
||||
// Check if the key pressed is an alphanumeric character and update the user command.
|
||||
//
|
||||
/* TODO: find better way to do the job (?) */
|
||||
static int check_alphanum(unsigned int key, struct vhex_s *vhex, struct session_s *session)
|
||||
{
|
||||
static const unsigned int keys_alpha[] = {
|
||||
KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H,
|
||||
KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P,
|
||||
KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
|
||||
KEY_Y, KEY_Z
|
||||
};
|
||||
static const unsigned int keys_number[] = {
|
||||
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
|
||||
KEY_5, KEY_6, KEY_7, KEY_8, KEY_9
|
||||
};
|
||||
unsigned int *cache;
|
||||
size_t size;
|
||||
size_t end;
|
||||
size_t i;
|
||||
char buf;
|
||||
|
||||
if (session->mode != COMMAND)
|
||||
return (-1);
|
||||
i = -1;
|
||||
size = strlen(vhex->insert.cmd);
|
||||
end = (vhex->insert.mode == NUMBER) ? 10 : 26;
|
||||
cache = (vhex->insert.mode == NUMBER) ? (void *)keys_number : (void *)keys_alpha;
|
||||
while (++i < end && key != cache[i]);
|
||||
if (i >= end)
|
||||
return (-1);
|
||||
if (size < CMD_LENGHT_MAX){
|
||||
buf = (vhex->insert.mode == NUMBER) ? '0' + i : 'a' + i;
|
||||
strcat(vhex->insert.cmd, &buf);
|
||||
}
|
||||
if (vhex->insert.mode == LETTER)
|
||||
vhex->insert.mode = NUMBER;
|
||||
vhex->history.offset = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// check_arrow()
|
||||
// Check if the key pressed is an arrow key.
|
||||
// Here we just check left and right key, but they do not have the same action when
|
||||
// the mode is COMMAND or not; basically:
|
||||
// * COMMAND : Udpate the user's command using the history.
|
||||
// * NORMAL : Move the anchor cursor.
|
||||
// * UNUSED : Do nothing.
|
||||
//
|
||||
static int check_arrow(unsigned int key, struct vhex_s *vhex, struct session_s *session)
|
||||
{
|
||||
if (key != KEY_UP && key != KEY_DOWN)
|
||||
return (-1);
|
||||
if (session->mode == COMMAND
|
||||
&& ((key == KEY_UP && vhex->history.offset < vhex->history.deep)
|
||||
|| (key == KEY_DOWN && vhex->history.offset > 0))){
|
||||
if (vhex->history.offset == 0)
|
||||
strcpy(vhex->insert.backup, vhex->insert.cmd);
|
||||
vhex->history.offset += (key == KEY_UP) ? 1 : -1;
|
||||
if (vhex->history.offset > 0)
|
||||
strcpy(vhex->insert.cmd,
|
||||
history_get(vhex->history.list, vhex->history.offset - 1));
|
||||
else
|
||||
strcpy(vhex->insert.cmd, vhex->insert.backup);
|
||||
}
|
||||
if (session->mode == NORMAL)
|
||||
session->cursor += (key == KEY_UP) ? -1 : 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// key_handling()
|
||||
// We need to do several things here; the Casio getkey function handles [SHIFT], [ALPHA]
|
||||
// and [MENU] key and it is able to do some special thing using the key combination like
|
||||
// shutdown the calculator, change the brightness or return to the main menu using.
|
||||
// But when the user press on [SHIFT] or [ALPHA], getkey() return not the same value for
|
||||
// the same key (and we cannot know the "status").
|
||||
// So we need to "emulate" the getkey's status and execute the appropriate action with
|
||||
// the key returned by Casio.
|
||||
//
|
||||
void key_handling(struct vhex_s *vhex, struct session_s *session, unsigned int key)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (check_session(key, vhex) == 0
|
||||
|| check_special(key, vhex, session) == 0
|
||||
|| check_arrow(key, vhex, session) == 0
|
||||
|| check_alphanum(key, vhex, session) == 0
|
||||
|| session->mode != COMMAND)
|
||||
return;
|
||||
if (key == KEY_DEL || key == KEY_INS){
|
||||
size = strlen(vhex->insert.cmd);
|
||||
if (size > 0)
|
||||
strncpy(vhex->insert.cmd, vhex->insert.cmd, size - 1);
|
||||
}
|
||||
if (key == KEY_SPACE)
|
||||
strcat(vhex->insert.cmd, " ");
|
||||
if (key == KEY_QUOTE)
|
||||
strcat(vhex->insert.cmd, "\"");
|
||||
if (key == KEY_ENTER){
|
||||
vhex->insert.mode = NUMBER;
|
||||
command_entry(session, vhex);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
static const uint8_t kernel_font_bitmap[] = {
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xef, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xad,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x5e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x2a, 0x92, 0x11, 0x11, 0x28, 0x00, 0x00, 0x38, 0xbb, 0xab, 0xbb, 0xbb,
|
||||
0x80, 0x08, 0x23, 0x02, 0x57, 0x31, 0x52, 0x41, 0x22, 0x00, 0x01, 0x51,
|
||||
0x11, 0x54, 0x41, 0x55, 0x22, 0x27, 0x21, 0x04, 0x0a, 0xc4, 0x40, 0x82,
|
||||
0xae, 0x0e, 0x04, 0xa2, 0xee, 0xee, 0xe2, 0xee, 0x00, 0x80, 0x24, 0x00,
|
||||
0x1c, 0xd1, 0x41, 0x04, 0x08, 0x80, 0x11, 0x45, 0x04, 0x45, 0x45, 0x44,
|
||||
0x88, 0x9c, 0x80, 0x10, 0x2b, 0x09, 0x81, 0x10, 0x02, 0x01, 0x03, 0x8b,
|
||||
0xb8, 0xbb, 0x8b, 0xb8, 0x20, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xee,
|
||||
0xec, 0xee, 0xea, 0xee, 0xa8, 0xae, 0xee, 0xee, 0x6e, 0xaa, 0xaa, 0xae,
|
||||
0xe0, 0xe4, 0x05, 0x55, 0x15, 0x11, 0x14, 0x89, 0x51, 0xd5, 0x55, 0x55,
|
||||
0x09, 0x55, 0x55, 0x45, 0x10, 0x54, 0x0b, 0xb2, 0x2b, 0xba, 0xb9, 0x13,
|
||||
0x22, 0xaa, 0xba, 0xb3, 0x92, 0xaa, 0x91, 0x12, 0x10, 0x80, 0x55, 0x54,
|
||||
0x54, 0x45, 0x52, 0x25, 0x45, 0x55, 0x47, 0x51, 0x25, 0x57, 0x52, 0x44,
|
||||
0x11, 0x00, 0xca, 0xee, 0xce, 0x8e, 0xae, 0xca, 0xea, 0xae, 0x8e, 0xac,
|
||||
0x4e, 0x4a, 0xa4, 0xee, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00,
|
||||
0x90, 0x9a, 0x11, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
|
||||
0x30, 0x39, 0x14, 0x31, 0x52, 0x54, 0x00, 0x42, 0x76, 0x26, 0x35, 0x37,
|
||||
0x55, 0x55, 0x57, 0x22, 0x20, 0x70, 0x6c, 0x86, 0xee, 0x6c, 0xc4, 0xa4,
|
||||
0xea, 0xaa, 0xac, 0xc4, 0xaa, 0xa4, 0xa4, 0x84, 0x26, 0xe1, 0x55, 0x15,
|
||||
0x08, 0x54, 0x89, 0x89, 0x55, 0x58, 0xd0, 0x49, 0x55, 0xd4, 0x90, 0x88,
|
||||
0x99, 0xc1, 0xb1, 0x99, 0x93, 0x2b, 0xb2, 0x9a, 0xa9, 0x20, 0xa3, 0x19,
|
||||
0x92, 0xa9, 0x39, 0x93, 0x03, 0x80
|
||||
};
|
||||
|
||||
void dascii(int x, int y, char const c)
|
||||
{
|
||||
off_t bitmap_offset_x;
|
||||
off_t bitmap_offset_y;
|
||||
off_t vram_offset_y;
|
||||
int real_width;
|
||||
int real_height;
|
||||
uint8_t pixel_test;
|
||||
int pixel_cursor;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
// Calculate the charactere position (bitmap)
|
||||
bitmap_offset_y = (c / KERNEL_FONT_NB_CHAR_X) * (KERNEL_FONT_BITMAP_WIDTH * KERNEL_FONT_BITMAP_CHEIGHT);
|
||||
bitmap_offset_x = (c - ((c / KERNEL_FONT_NB_CHAR_X) * KERNEL_FONT_NB_CHAR_X)) * KERNEL_FONT_BITMAP_CWIDTH;
|
||||
|
||||
// Set default size.
|
||||
real_width = KERNEL_FONT_REAL_WIDTH;
|
||||
real_height = KERNEL_FONT_REAL_HEIGHT;
|
||||
|
||||
// Check X axis culling.
|
||||
if (x < 0)
|
||||
{
|
||||
bitmap_offset_x = bitmap_offset_x + x;
|
||||
real_width = KERNEL_FONT_REAL_WIDTH + x;
|
||||
x = 0;
|
||||
}
|
||||
else if (x + KERNEL_FONT_REAL_WIDTH >= DISPLAY_SCREEN_WIDTH)
|
||||
real_width = DISPLAY_SCREEN_WIDTH - x;
|
||||
|
||||
// Check Y axis culling.
|
||||
if (y < 0)
|
||||
{
|
||||
real_height = KERNEL_FONT_REAL_HEIGHT + y;
|
||||
bitmap_offset_y = bitmap_offset_y + ((-y) * KERNEL_FONT_BITMAP_WIDTH);
|
||||
y = 0;
|
||||
}
|
||||
else if (y + KERNEL_FONT_REAL_HEIGHT >= DISPLAY_SCREEN_HEIGHT)
|
||||
real_height = DISPLAY_SCREEN_HEIGHT - y;
|
||||
|
||||
// Check potential error.
|
||||
// @note we do not check real_height because the while() while do the job for us.
|
||||
if (real_width < 0)
|
||||
return;
|
||||
|
||||
// Calculate VRAM buffer starting position.
|
||||
// @note:
|
||||
// The screen width size is always 128 and we
|
||||
// use 4-aligned Video RAM so 32 pixel per "slot"
|
||||
// and 128 / 32 = 4
|
||||
// y * 4 can be optimised by used shift operator
|
||||
// this is why we use y << 2 because 2^2 = 4.
|
||||
vram_offset_y = y << 2;
|
||||
|
||||
// Draw character, pixer per pixel... (x_x)
|
||||
i = -1;
|
||||
while (++i < real_height)
|
||||
{
|
||||
j = -1;
|
||||
while (++j < real_width)
|
||||
{
|
||||
pixel_cursor = bitmap_offset_x + bitmap_offset_y + j;
|
||||
pixel_test = 0x80 >> (pixel_cursor & 0x07);
|
||||
if (pixel_test & kernel_font_bitmap[pixel_cursor >> 3])
|
||||
{
|
||||
VRAM[((x + j) >> 5) + vram_offset_y] |= 0x80000000 >> ((x + j) & 0x1f);
|
||||
}
|
||||
}
|
||||
bitmap_offset_y = bitmap_offset_y + KERNEL_FONT_BITMAP_WIDTH;
|
||||
vram_offset_y = vram_offset_y + 4;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
void dclear(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 256;
|
||||
while (--i >= 0)
|
||||
VRAM[i] = 0x00000000;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <lib/stdio.h>
|
||||
#include <lib/display.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void dprint(int x, int y, char const *str, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
int default_pos_x;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
// printf string manipulation.
|
||||
// TODO: remove me !
|
||||
va_start(ap, str);
|
||||
vsprintf(buffer, str, ap);
|
||||
va_end(ap);
|
||||
|
||||
i = -1;
|
||||
default_pos_x = x;
|
||||
while (buffer[++i] != '\0')
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
y = y + KERNEL_FONT_REAL_HEIGHT + 1;
|
||||
x = default_pos_x;
|
||||
continue;
|
||||
}
|
||||
dascii(x, y, buffer[i]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
void dscroll(int lines)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Scoll n lines
|
||||
i = 0;
|
||||
while ((i >> 2) < 63 - lines)
|
||||
{
|
||||
VRAM[i + 0] = VRAM[i + (lines << 2) + 0];
|
||||
VRAM[i + 1] = VRAM[i + (lines << 2) + 1];
|
||||
VRAM[i + 2] = VRAM[i + (lines << 2) + 2];
|
||||
VRAM[i + 3] = VRAM[i + (lines << 2) + 3];
|
||||
i = i + 4;
|
||||
}
|
||||
// Clear last n lines
|
||||
while ((i >> 2) < 64)
|
||||
{
|
||||
VRAM[i + 0] = 0x0000;
|
||||
VRAM[i + 1] = 0x0000;
|
||||
VRAM[i + 2] = 0x0000;
|
||||
VRAM[i + 3] = 0x0000;
|
||||
i = i + 4;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/hardware/t6k11.h>
|
||||
|
||||
//FIXME: Check OS 3.00 !
|
||||
void dupdate(void)
|
||||
{
|
||||
t6k11_display(VRAM);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <lib/stdio.h>
|
||||
|
||||
void sprintf(char *str, char const *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(str, format, ap);
|
||||
va_end(ap);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#include <string.h>
|
||||
#include <lib/stdio.h>
|
||||
|
||||
static size_t strbase(char *dest, uint32_t nb, size_t size, int base)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ static size_t strndump(char *dest, char const *str, size_t size)
|
|||
return (i);
|
||||
}
|
||||
|
||||
__attribute__((weak)) void vsprintf(char *str, char const *format, va_list ap)
|
||||
void vsprintf(char *str, char const *format, va_list ap)
|
||||
{
|
||||
size_t size;
|
||||
size_t len;
|
||||
|
@ -102,12 +102,3 @@ __attribute__((weak)) void vsprintf(char *str, char const *format, va_list ap)
|
|||
}
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
__attribute__((weak)) void sprintf(char *str, char const *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(str, format, ap);
|
||||
va_end(ap);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <lib/string.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
for (size_t i = 0 ; i < count ; i = i + 1)
|
||||
((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
|
||||
return (dest);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#include <utils.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
//TODO: update me :(
|
||||
__attribute__((weak)) void *memset(void *s, int c, size_t n)
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
while ((int)--n >= 0)
|
||||
((uint8_t*)s)[n] = c;
|
|
@ -1,6 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
__attribute__((weak)) char *strcat(char *dest, char const *src)
|
||||
char *strcat(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
size_t start;
|
|
@ -0,0 +1,13 @@
|
|||
#include <lib/string.h>
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL)
|
||||
return (0);
|
||||
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
|
||||
{
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
}
|
||||
return (*s1 - *s2);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
__attribute__((weak)) char *strcpy(char *dest, char const *src)
|
||||
char *strcpy(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
@ -13,7 +13,7 @@ __attribute__((weak)) char *strcpy(char *dest, char const *src)
|
|||
return (dest);
|
||||
}
|
||||
|
||||
__attribute__((weak)) char *strncpy(char *dest, char const *str, size_t size)
|
||||
char *strncpy(char *dest, char const *str, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
__attribute__((weak)) size_t strlen(char const *str)
|
||||
size_t strlen(char const *str)
|
||||
{
|
||||
size_t i;
|
||||
|
49
src/main.c
49
src/main.c
|
@ -1,49 +0,0 @@
|
|||
#include <utils.h>
|
||||
#include <string.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
//
|
||||
// vhex_constructor()
|
||||
// Initialize all information needed by the add-in: session,
|
||||
// GetKey configuration, ...
|
||||
//
|
||||
static void vhex_constructor(struct vhex_s *vhex)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
memset(vhex->info, '\0', CMD_LENGHT_MAX);
|
||||
memset(vhex->insert.cmd, '\0', CMD_LENGHT_MAX);
|
||||
//TODO: Auto detect GetKey configuration !!
|
||||
vhex->insert.mode = NUMBER;
|
||||
vhex->history.list = NULL;
|
||||
vhex->history.offset = 0;
|
||||
vhex->history.deep = 0;
|
||||
vhex->current_session = 0;
|
||||
while (++i < SESSIONS_SLOT){
|
||||
vhex->session[i].mode = UNUSED;
|
||||
vhex->session[i].anchor = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// main()
|
||||
// User entry, but we need to initialize some information before
|
||||
// starting the "main loop".
|
||||
//
|
||||
int main(void)
|
||||
{
|
||||
struct vhex_s vhex;
|
||||
unsigned int key;
|
||||
|
||||
key = 0;
|
||||
vhex_constructor(&vhex);
|
||||
while (1){
|
||||
dclear();
|
||||
display_instructions(&vhex.session[vhex.current_session]);
|
||||
display_metainfos(&vhex, &vhex.session[vhex.current_session]);
|
||||
getkey(&key);
|
||||
key_handling(&vhex, &vhex.session[vhex.current_session], key);
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#include <string.h>
|
||||
|
||||
static INLINE int check_base(char n, int base)
|
||||
{
|
||||
char max;
|
||||
|
||||
max = (base <= 10) ? '0' + base - 1 : ('a' + base - 11);
|
||||
return ((max < n));
|
||||
}
|
||||
|
||||
//
|
||||
// atoi_base()
|
||||
// Wrapped atoi function that takes the base which the number
|
||||
// (stored in the string) are encoded
|
||||
//
|
||||
uint32_t atoi_base(char const *str, int base)
|
||||
{
|
||||
uint32_t result;
|
||||
size_t start;
|
||||
|
||||
start = -1;
|
||||
result = 0;
|
||||
while (str[++start] != '\0' && check_base(str[start], base) == 0){
|
||||
result *= base;
|
||||
if (str[start] <= '9')
|
||||
result += str[start] - '0';
|
||||
else
|
||||
result += (str[start] - 'a') + 10;
|
||||
}
|
||||
return (result);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <string.h>
|
||||
|
||||
__attribute__((weak)) int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL)
|
||||
return (0);
|
||||
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2){
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
}
|
||||
return (*s1 - *s2);
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
#ifndef DEBUG
|
||||
//# include <commands.h>
|
||||
# include <syscalls.h>
|
||||
#else
|
||||
//# include "commands.h"
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
// Internal prototypes.
|
||||
extern int strtotab(int *argc, char ***argv, char const *str);
|
||||
extern void strtotab_quit(int *argc, char ***argv);
|
||||
|
||||
//
|
||||
// parser_get_word()
|
||||
// Get the word at the current cursor location.
|
||||
//
|
||||
static ssize_t parser_get_word(char ***tab, size_t *tab_pos,
|
||||
char const *str, int *counter)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
i = -1;
|
||||
while (str[++i] != '\0' && str[i] != '\n' && str[i] != ' ' && str[i] != '\t');
|
||||
if (*tab != NULL){
|
||||
(*tab)[*tab_pos] = (char*)malloc(i + 1);
|
||||
if ((*tab)[*tab_pos] == NULL)
|
||||
return (-1);
|
||||
memset((*tab)[*tab_pos], 0, i + 1);
|
||||
strncpy((*tab)[(*tab_pos)++], str, i);
|
||||
}
|
||||
(*counter)++;
|
||||
return (i);
|
||||
}
|
||||
|
||||
//
|
||||
// parser_get_inibitor()
|
||||
// This function will get the content of an inhibitor (and check if the
|
||||
// inhibitor characteres are alone or not).
|
||||
//
|
||||
static ssize_t parser_get_inibitor(char ***tab, size_t *tab_pos,
|
||||
char const *str, int *counter)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
i = 0;
|
||||
while (str[++i] != '\0' && str[i] != '\"');
|
||||
if (str[i] != '\"')
|
||||
return (0);
|
||||
if (*tab != NULL){
|
||||
(*tab)[*tab_pos] = (char*)malloc(i + 1);
|
||||
if ((*tab)[*tab_pos] == NULL)
|
||||
return (-1);
|
||||
memset((*tab)[*tab_pos], 0, i + 1);
|
||||
strncpy((*tab)[(*tab_pos)++], str + 1, i - 1);
|
||||
}
|
||||
(*counter)++;
|
||||
return (i + 1);
|
||||
}
|
||||
|
||||
//
|
||||
// parser_setup_arg()
|
||||
// This function removes useless spaces, tabs and handle '\"' inhibitor.
|
||||
// Return the number of word(s) stored in "str".
|
||||
//
|
||||
static int parser_entry(char ***tab, char const *str)
|
||||
{
|
||||
size_t tab_pos;
|
||||
ssize_t size;
|
||||
int counter;
|
||||
|
||||
str--;
|
||||
counter = 0;
|
||||
tab_pos = 0;
|
||||
while (*(++str) != '\0' && *str != '\n'){
|
||||
if (*str == '\"'){
|
||||
size = parser_get_inibitor(tab, &tab_pos, str, &counter);
|
||||
if (size < 0)
|
||||
return (-1);
|
||||
str += size;
|
||||
}
|
||||
if (*str != ' ' && *str != '\t'){
|
||||
size = parser_get_word(tab, &tab_pos, str, &counter) - 1;
|
||||
if (size < 0)
|
||||
return (-1);
|
||||
str += size;
|
||||
}
|
||||
}
|
||||
return (counter);
|
||||
}
|
||||
|
||||
//
|
||||
// strtotab()
|
||||
// Generate word table and indicated the number of word find in the string.
|
||||
//
|
||||
int strtotab(int *argc, char ***argv, char const *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Check memory fault.
|
||||
if (argc == NULL || argv == NULL || str == NULL)
|
||||
return (EFAULT);
|
||||
|
||||
// Get the number of word.
|
||||
*argv = NULL;
|
||||
*argc = parser_entry(argv, str);
|
||||
if (*argc <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
// Alloc tab.
|
||||
*argv = (char **)malloc(sizeof(char *) * (*argc + 1));
|
||||
if (*argv == NULL)
|
||||
return (ENOMEM);
|
||||
i = *argc;
|
||||
while (--i >= 0)
|
||||
(*argv)[i] = NULL;
|
||||
|
||||
// Get word.
|
||||
if (parser_entry(argv, str) != *argc){
|
||||
strtotab_quit(argc, argv);
|
||||
return (ENOMEM);
|
||||
}
|
||||
(*argv)[*argc] = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* strtotab() - Free all allocated memory generated by "strtotab()" */
|
||||
void strtotab_quit(int *argc, char ***argv)
|
||||
{
|
||||
if (argc == NULL || argv == NULL)
|
||||
return;
|
||||
if (*argv == NULL){
|
||||
*argc = 0;
|
||||
return;
|
||||
}
|
||||
while (--(*argc) >= 0)
|
||||
free((*argv)[*argc]);
|
||||
free(*argv);
|
||||
*argv = NULL;
|
||||
*argc = 0;
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
.global _casio_GetKey
|
||||
.global _casio_PrintMini
|
||||
.global _casio_Bdisp_PutDisp_DD
|
||||
.global _casio_Bdisp_AllClr_VRAM
|
||||
.global _casio_Bdisp_DrawLine_VRAM
|
||||
.global _casio_Bdisp_AreaClr_VRAM
|
||||
.global _casio_RestoreDisp
|
||||
.global _casio_SaveDisp
|
||||
.global _casio_Malloc
|
||||
.global _casio_Free
|
||||
|
||||
.type _casio_GetKey, @function
|
||||
.type _casio_PrintMini, @function
|
||||
.type _casio_Bdisp_PutDisp_DD, @function
|
||||
.type _casio_Bdisp_AllClr_VRAM, @function
|
||||
.type _casio_Bdisp_DrawLine_VRAM, @function
|
||||
.type _casio_Bdisp_AreaClr_VRAM, @function
|
||||
.type _casio_RestoreDisp, @function
|
||||
.type _casio_SaveDisp, @function
|
||||
.type _casio_Malloc, @function
|
||||
.type _casio_Free, @function
|
||||
|
||||
.align 2
|
||||
_casio_GetKey:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_getkey, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_PrintMini:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_printMini, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Bdisp_AllClr_VRAM:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_clear, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Bdisp_PutDisp_DD:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_display, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Bdisp_DrawLine_VRAM:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_line, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Bdisp_AreaClr_VRAM:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_clear_area, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_RestoreDisp:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_restore_disp, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_SaveDisp:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_save_disp, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Malloc:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_malloc, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
_casio_Free:
|
||||
mov.l .syscall_tab, r1
|
||||
mov.l .sys_free, r0
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
|
||||
.align 4
|
||||
.syscall_tab: .long 0x80010070
|
||||
.sys_line: .long 0x00000030
|
||||
.sys_clear: .long 0x00000143 /*Bdisp_AllClr_VRAM */
|
||||
.sys_getkey: .long 0x0000090f
|
||||
.sys_display: .long 0x00000028
|
||||
.sys_printMini: .long 0x00000c4f
|
||||
.sys_clear_area: .long 0x0000014b
|
||||
.sys_restore_disp: .long 0x00000814
|
||||
.sys_save_disp: .long 0x00000813
|
||||
.sys_malloc: .long 0x00000acd
|
||||
.sys_free: .long 0x00000acc
|
||||
|
||||
.end
|
|
@ -0,0 +1,34 @@
|
|||
#include <lib/stdio.h>
|
||||
#include <lib/display.h>
|
||||
#include <kernel/tty.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *line;
|
||||
|
||||
// Open TTY and display entry message
|
||||
tty_open();
|
||||
tty_write("Welcome to Vhex !\n");
|
||||
|
||||
// Main loop
|
||||
while (1)
|
||||
{
|
||||
// Write input indications.
|
||||
// TODO: write current working directory ?
|
||||
tty_write(">");
|
||||
|
||||
// Get each line writen by the user.
|
||||
/*nbread = getline(&line, &size, 0);
|
||||
if (nbread == EOF)
|
||||
{
|
||||
// TODO: check jobs ?
|
||||
break;
|
||||
}*/
|
||||
|
||||
// TODO: do some job.
|
||||
}
|
||||
|
||||
// Close TTY and return.
|
||||
tty_close();
|
||||
return (0);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#include <criterion/criterion.h>
|
||||
|
||||
// Internal prototypes.
|
||||
extern uint32_t atoi_base(char const *str, int base);
|
||||
|
||||
Test(atoi_base, base_10)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = atoi_base("12345", 10);
|
||||
cr_assert_eq(result, 12345, "returned: %d\n", result);
|
||||
cr_assert_eq(atoi_base("50926", 10), 50926);
|
||||
cr_assert_eq(atoi_base("999999", 10), 999999);
|
||||
}
|
||||
|
||||
Test(atoi_base, base_16)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = atoi_base("abcdef", 16);
|
||||
cr_assert_eq(result, 0xabcdef, "returned: %#x\n", result);
|
||||
cr_assert_eq(atoi_base("50926", 16), 0x50926);
|
||||
cr_assert_eq(atoi_base("999999", 16), 0x999999);
|
||||
}
|
||||
|
||||
Test(atoi_base, base_error)
|
||||
{
|
||||
cr_assert_eq(atoi_base("xxxxxx", 16), 0);
|
||||
cr_assert_eq(atoi_base("50926x56", 16), 0x50926);
|
||||
cr_assert_eq(atoi_base("o", 16), 0);
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "tests/internal.h"
|
||||
#include "history.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
//TODO: write doc.
|
||||
|
||||
Test(history, add)
|
||||
{
|
||||
struct node *list;
|
||||
|
||||
list = NULL;
|
||||
cr_assert_eq(history_update(&list, "ls -l"), 0);
|
||||
cr_assert_eq(history_update(&list, "cat -e"), 0);
|
||||
cr_assert_eq(history_update(NULL, "cat -e"), EFAULT);
|
||||
// malloc fails.
|
||||
malloc_hook_update(FAIL_NEXT);
|
||||
cr_assert_eq(history_update(&list, "cat -e"), ENOMEM);
|
||||
|
||||
// Check info.
|
||||
cr_assert_str_eq(list->data, "cat -e");
|
||||
cr_assert_str_eq(list->next->data, "ls -l");
|
||||
cr_assert_null(list->next->next);
|
||||
}
|
||||
|
||||
Test(history, get)
|
||||
{
|
||||
struct node *list;
|
||||
|
||||
list = NULL;
|
||||
history_update(&list, "ls -l");
|
||||
history_update(&list, "cat -e");
|
||||
cr_assert_str_eq(history_get(list, 1), "ls -l");
|
||||
cr_assert_str_eq(history_get(list, 0), "cat -e");
|
||||
cr_assert_null(history_get(list, 4));
|
||||
}
|
||||
|
||||
Test(history, quit)
|
||||
{
|
||||
struct node *list;
|
||||
|
||||
list = NULL;
|
||||
history_quit(&list);
|
||||
history_update(&list, "ls -l");
|
||||
history_update(&list, "cat -e");
|
||||
history_update(&list, "test");
|
||||
history_update(&list, "yes");
|
||||
history_quit(&list);
|
||||
history_quit(NULL);
|
||||
cr_assert_null(list);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef __INTERNAL_H__
|
||||
# define __INTERNAL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//
|
||||
// status_t - all status available for hook.
|
||||
// * FAIL_NONE : force malloc to work normaly.
|
||||
// * FAIL_NEXT : force the next call of malloc to return NULL.
|
||||
// * FAIL_NEXT_DYN : force X-nth call of malloc to return NULL.
|
||||
// * FAIL_ALWAYS : force all malloc to return NULL.
|
||||
//
|
||||
typedef enum status_e
|
||||
{
|
||||
FAIL_NONE,
|
||||
FAIL_NEXT,
|
||||
FAIL_ALWAYS,
|
||||
FAIL_NEXT_DYN
|
||||
} status_t;
|
||||
|
||||
/* malloc_hook_update - udpate the behavior of the malloc hook */
|
||||
void malloc_hook_update(status_t status, ...);
|
||||
|
||||
#endif /*__INTERNAL_H__*/
|
|
@ -1,91 +0,0 @@
|
|||
#include "tests/internal.h"
|
||||
#include <malloc.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// Internal prototypes / static symbols.
|
||||
static void my_malloc_init_hook(void);
|
||||
static void *my_malloc_hook(size_t size, const void *caller);
|
||||
static void *old_malloc_hook;
|
||||
static int hook_dyn_fail;
|
||||
static int hook_status;
|
||||
|
||||
//
|
||||
// my_malloc_hook()
|
||||
// This function will replace the current malloc hook by our own
|
||||
// hook (which can return NULL if we want, it allows us to check
|
||||
// the behavior of our code).
|
||||
//
|
||||
// NOTE:
|
||||
// "man __malloc_hook" indicate to use "__malloc_initialize_hook"
|
||||
// which will execute the initialization routine. But from glibc 2.24
|
||||
// onwards, this variable has been removed from the API.
|
||||
// So, this is why we use "constructor" attribute to call our routine
|
||||
// at the beginning of the test.
|
||||
//
|
||||
__attribute__((constructor))
|
||||
static void my_malloc_init_hook(void)
|
||||
{
|
||||
old_malloc_hook = __malloc_hook;
|
||||
__malloc_hook = my_malloc_hook;
|
||||
hook_status = FAIL_NONE;
|
||||
}
|
||||
|
||||
//
|
||||
// my_malloc_hook()
|
||||
// For some tests we need to simulate (properly) a malloc fail; to do this
|
||||
// we use a malloc hook and add static variables to force him to return
|
||||
// NULL address.
|
||||
//
|
||||
// NOTE:
|
||||
// All hooks of the glibc will be removed because of their poor behavior
|
||||
// in multi threaded environment.
|
||||
// But recently we have seen that the malloc() function is defined by the
|
||||
// weak symbol, so it is probably possible to override malloc() and do
|
||||
// the same job.
|
||||
//
|
||||
static void *my_malloc_hook(size_t size, const void *caller)
|
||||
{
|
||||
void *result;
|
||||
|
||||
if (hook_status != FAIL_NONE && hook_status != FAIL_NEXT_DYN){
|
||||
if (hook_status == FAIL_NEXT)
|
||||
hook_status = FAIL_NONE;
|
||||
return (NULL);
|
||||
}
|
||||
if (hook_status == FAIL_NEXT_DYN){
|
||||
hook_dyn_fail -= 1;
|
||||
if (hook_dyn_fail <= 0){
|
||||
hook_status = FAIL_NONE;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
__malloc_hook = old_malloc_hook;
|
||||
result = malloc(size);
|
||||
(void)caller;
|
||||
//printf("caller: %p - area: %p\n", caller, result);
|
||||
old_malloc_hook = __malloc_hook;
|
||||
__malloc_hook = my_malloc_hook;
|
||||
return (result);
|
||||
}
|
||||
|
||||
//
|
||||
// malloc_hook_udpate()
|
||||
// This function is the only way to interact with the hook; it will
|
||||
// define the behavior of malloc:
|
||||
// * FAIL_NEXT : force the next call of malloc to return NULL.
|
||||
// * FAIL_NEXT_DYN : force X-nth call of malloc to return NULL.
|
||||
// * FAIL_ALWAYS : force all malloc return NULL.
|
||||
// * FAIL_NONE : force malloc to work normally.
|
||||
//
|
||||
void malloc_hook_update(status_t status, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
hook_dyn_fail = 0;
|
||||
if (status == FAIL_NEXT_DYN){
|
||||
va_start(ap, status);
|
||||
hook_dyn_fail = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
}
|
||||
hook_status = status;
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "tests/internal.h"
|
||||
#include <errno.h>
|
||||
|
||||
// Internal prototypes.
|
||||
extern int strtotab(int *argc, char ***argv, char const *str);
|
||||
extern void strtotab_quit(int *argc, char ***argv);
|
||||
|
||||
Test(strtotab, quote)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
ret = strtotab(&argc, &argv, "hey? \"What's \nup?\" yo!\"\n");
|
||||
cr_expect_eq(ret, 0);
|
||||
cr_expect_eq(argc, 3);
|
||||
cr_assert_str_eq(argv[0], "hey?");
|
||||
cr_assert_str_eq(argv[1], "What's \nup?");
|
||||
cr_assert_str_eq(argv[2], "yo!\"");
|
||||
}
|
||||
|
||||
Test(strtotab, noword)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
ret = strtotab(&argc, &argv, "");
|
||||
cr_expect_eq(ret, EINVAL);
|
||||
cr_expect_eq(argc, 0);
|
||||
cr_assert_null(argv);
|
||||
}
|
||||
|
||||
Test(strtotab, entry_error)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
ret = strtotab(NULL, &argv, "aaaaaaaaa aa");
|
||||
cr_expect_eq(ret, EFAULT);
|
||||
ret = strtotab(&argc, NULL, "aaaaaaaaa aa");
|
||||
cr_expect_eq(ret, EFAULT);
|
||||
ret = strtotab(&argc, &argv, NULL);
|
||||
cr_expect_eq(ret, EFAULT);
|
||||
}
|
||||
|
||||
Test(strtotab, spaces_tabs)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
ret = strtotab(&argc, &argv, "hey? What's\t\t \t up?");
|
||||
cr_expect_eq(ret, 0);
|
||||
cr_expect_eq(argc, 3);
|
||||
cr_assert_str_eq(argv[0], "hey?");
|
||||
cr_assert_str_eq(argv[1], "What's");
|
||||
cr_assert_str_eq(argv[2], "up?");
|
||||
}
|
||||
|
||||
Test(strtotab, normal)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
ret = strtotab(&argc, &argv, "hey? What's up?\n");
|
||||
cr_expect_eq(ret, 0);
|
||||
cr_assert_eq(argc, 3);
|
||||
cr_assert_str_eq(argv[0], "hey?");
|
||||
cr_assert_str_eq(argv[1], "What's");
|
||||
cr_assert_str_eq(argv[2], "up?");
|
||||
}
|
||||
|
||||
Test(strtotab, alloc_fails)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
malloc_hook_update(FAIL_NEXT);
|
||||
ret = strtotab(&argc, &argv, "hey? \"What's up?");
|
||||
cr_assert_eq(ret, ENOMEM);
|
||||
malloc_hook_update(FAIL_NEXT_DYN, 2);
|
||||
ret = strtotab(&argc, &argv, "hey? \"What's up?");
|
||||
cr_assert_eq(ret, ENOMEM);
|
||||
malloc_hook_update(FAIL_NEXT_DYN, 2);
|
||||
ret = strtotab(&argc, &argv, "\"What's\" up?");
|
||||
cr_assert_eq(ret, ENOMEM);
|
||||
|
||||
}
|
||||
|
||||
Test(strtotab, quit)
|
||||
{
|
||||
char **argv;
|
||||
int argc;
|
||||
|
||||
strtotab(&argc, &argv, "hey? What's up?");
|
||||
strtotab_quit(&argc, &argv);
|
||||
cr_assert_eq(argc, 0);
|
||||
cr_assert_null(argv);
|
||||
strtotab_quit(NULL, &argv);
|
||||
strtotab_quit(&argc, NULL);
|
||||
argv = NULL;
|
||||
strtotab_quit(&argc, &argv);
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
OUTPUT_ARCH(sh3)
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/*
|
||||
** bootram is the RAM physical location for global variable
|
||||
** during the bootloader step.
|
||||
** This location is realy important because no Casio's OS data
|
||||
** should be overwrite (specially TLB information stored by Casio).
|
||||
*/
|
||||
bootram (rwx) : o = 0x88040000, l = 252k
|
||||
osram (rwx) : o = 0x8807f000, l = 4k
|
||||
rom (rx) : o = 0x00300200, l = 512k
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
** ROM sections
|
||||
*/
|
||||
. = ORIGIN(rom);
|
||||
.text : {
|
||||
*(.pretext)
|
||||
*(.text)
|
||||
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} > rom
|
||||
|
||||
|
||||
/*
|
||||
** RAM sctions
|
||||
*/
|
||||
. = ORIGIN(bootram);
|
||||
|
||||
/* BootStrap Stack: should be wiped later ! */
|
||||
/* (we force the section to be non loadable when the program is run) */
|
||||
.bss (NOLOAD) : {
|
||||
_bbss = . ;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
} > bootram :NONE
|
||||
_sbss = SIZEOF(.bss);
|
||||
|
||||
/* Read-write data going to RAM */
|
||||
.data : ALIGN(4) {
|
||||
_bdata_rom = LOADADDR(.data) ;
|
||||
_bdata_ram = . ;
|
||||
*(.data)
|
||||
|
||||
/* Video RAM space */
|
||||
_VRAM = ALIGN(4);
|
||||
. = (. + 1024);
|
||||
} > bootram AT> rom
|
||||
_sdata = SIZEOF(.data);
|
||||
|
||||
|
||||
/*
|
||||
** VBR space !
|
||||
*/
|
||||
/* Interrupt / exception handlers */
|
||||
.vhex : SUBALIGN(4) {
|
||||
_bvhex_rom = LOADADDR(.vhex) ;
|
||||
_bvhex_ram = . ;
|
||||
_vhex_vbr = . - 0x100;
|
||||
*(.vhex.exception) ;
|
||||
. = _vhex_vbr + 0x400 ;
|
||||
*(.vhex.tlb) ;
|
||||
. = _vhex_vbr + 0x600 ;
|
||||
*(.vhex.interrupt) ;
|
||||
. = ALIGN(4);
|
||||
} > osram AT> rom
|
||||
_svhex = SIZEOF(.vhex);
|
||||
|
||||
/* unwanted section */
|
||||
/DISCARD/ : {
|
||||
*(.debug_info)
|
||||
*(.debug_abbrev)
|
||||
*(.debug_loc)
|
||||
*(.debug_aranges)
|
||||
*(.debug_ranges)
|
||||
*(.debug_line)
|
||||
*(.debug_str)
|
||||
*(.jcr)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue