diff --git a/.gitignore b/.gitignore index 357250f..6050722 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,6 @@ dkms.conf # Other *.txt build/ +debug +.tests +.old diff --git a/Makefile b/Makefile index 3382f8d..e358daf 100644 --- a/Makefile +++ b/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 diff --git a/bootstrap.ld b/bootstrap.ld deleted file mode 100644 index 042fae1..0000000 --- a/bootstrap.ld +++ /dev/null @@ -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.*) - } -} diff --git a/global.mk b/global.mk deleted file mode 100644 index aff5d7f..0000000 --- a/global.mk +++ /dev/null @@ -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 diff --git a/include/kernel/atomic.h b/include/kernel/atomic.h new file mode 100644 index 0000000..f6c56c6 --- /dev/null +++ b/include/kernel/atomic.h @@ -0,0 +1,10 @@ +#ifndef __KERNEL_ATOMIC_H__ +# define __KERNEL_ATOMIC_H__ + +#include +#include + +extern void atomic_start(void); +extern void atomic_end(void); + +#endif /*__KERNEL_ATOMIC_H__*/ diff --git a/include/kernel/attributes.h b/include/kernel/attributes.h new file mode 100644 index 0000000..ba0890b --- /dev/null +++ b/include/kernel/attributes.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__*/ diff --git a/include/kernel/context.h b/include/kernel/context.h new file mode 100644 index 0000000..f89e0d7 --- /dev/null +++ b/include/kernel/context.h @@ -0,0 +1,40 @@ +#ifndef __KERNEL_CONTEXT_H__ +# define __KERNEL_CONTEXT_H__ + +#include +#include + +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__*/ diff --git a/include/kernel/hardware/intc.h b/include/kernel/hardware/intc.h new file mode 100644 index 0000000..6d1fac1 --- /dev/null +++ b/include/kernel/hardware/intc.h @@ -0,0 +1,514 @@ +#ifndef __KERNEL_MODULES_SH7724_INTC_H__ +# define __KERNEL_MODULES_SH7724_INTC_H__ + +#include +#include +#include +#include + +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__*/ diff --git a/include/kernel/hardware/keysc.h b/include/kernel/hardware/keysc.h new file mode 100644 index 0000000..f6ea2e3 --- /dev/null +++ b/include/kernel/hardware/keysc.h @@ -0,0 +1,66 @@ +#ifndef __KERNEL_MODULES_SH7724_KEYSC_H__ +# define __KERNEL_MODULES_SH7724_KEYSC_H__ + +#include +#include +#include +#include + +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__*/ diff --git a/include/kernel/hardware/t6k11.h b/include/kernel/hardware/t6k11.h new file mode 100644 index 0000000..1010fea --- /dev/null +++ b/include/kernel/hardware/t6k11.h @@ -0,0 +1,10 @@ +#ifndef __KERNEL_HARDWARE_T6K11_H__ +# define __KERNEL_HARDWARE_T6K11_H__ + +#include +#include + +// Screen primitive +extern void t6k11_display(void *vram); + +#endif /*__KERNEL_HARDWARE_T6K11_H__*/ diff --git a/include/kernel/tty.h b/include/kernel/tty.h new file mode 100644 index 0000000..57f224a --- /dev/null +++ b/include/kernel/tty.h @@ -0,0 +1,25 @@ +#ifndef __KERNEL_TTY_H__ +# define __KERNEL_TTY_H__ + +#include +#include + +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__*/ diff --git a/include/types.h b/include/kernel/types.h similarity index 78% rename from include/types.h rename to include/kernel/types.h index 3258831..6c30e36 100644 --- a/include/types.h +++ b/include/kernel/types.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 diff --git a/include/kernel/union_types.h b/include/kernel/union_types.h new file mode 100644 index 0000000..37cc0d3 --- /dev/null +++ b/include/kernel/union_types.h @@ -0,0 +1,32 @@ +#ifndef __KERNEL_MODULES_TYPES_H__ +# define __KERNEL_MODULES_TYPES_H__ + +#include +#include + +#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__*/ diff --git a/include/lib/display.h b/include/lib/display.h new file mode 100644 index 0000000..0238cef --- /dev/null +++ b/include/lib/display.h @@ -0,0 +1,32 @@ +#ifndef __LIB_DISPLAY_H__ +# define __LIB_DISPLAY_H__ + +#include +#include + + +// 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__*/ diff --git a/include/lib/stdio.h b/include/lib/stdio.h new file mode 100644 index 0000000..c60de95 --- /dev/null +++ b/include/lib/stdio.h @@ -0,0 +1,12 @@ +#ifndef __LIB_STDIO_H__ +# define __LIB_STDIO_H__ + +#include +#include +#include + +/* 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__*/ diff --git a/include/lib/string.h b/include/lib/string.h new file mode 100644 index 0000000..7575735 --- /dev/null +++ b/include/lib/string.h @@ -0,0 +1,24 @@ +#ifndef __STRING_H__ +# define __STRING_H__ + +#include +#include + +/* 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__*/ diff --git a/include/string.h b/include/string.h deleted file mode 100644 index 2aeebf2..0000000 --- a/include/string.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __STRING_H__ -# define __STRING_H__ - -#include -#include - -// 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__*/ diff --git a/src/boot/crt0.c b/src/boot/crt0.c deleted file mode 100644 index a354909..0000000 --- a/src/boot/crt0.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -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); -} diff --git a/src/commands/cache.c b/src/commands/cache.c deleted file mode 100644 index e07726e..0000000 --- a/src/commands/cache.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -// 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]); -} diff --git a/src/commands/entry.c b/src/commands/entry.c deleted file mode 100644 index e4a80fd..0000000 --- a/src/commands/entry.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include - -// -// 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); -} diff --git a/src/commands/help.c b/src/commands/help.c deleted file mode 100644 index 533cf3a..0000000 --- a/src/commands/help.c +++ /dev/null @@ -1,228 +0,0 @@ -#include -#include -#include -#include - -// 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 \n" -" :syscall \n" -" :ram \n" -" :rom\n" -" :help \n" -"We invited you to try\n\":help \" if you don't know how a" -" command work.\n" -"Each command typed by the user\nis stored in a history that it\n" -"can access using [UP] and\n[DOWN] keys.\n" -"\n" -"================================" -"VI] Credits\n" -"Special thank to:\n" -" - Lephenixnoir\n" -" - PierrotLL\n" -" - Simon Lothar\n" -" - Kristaba\n" -"And all communities of Planet\nCasio for his help.\n" -"specially to LephenixNoir for\nhis advices and his patience.\n" -"\n" -"================================" -"VII] Copyright\n" -"The Vhex programme use CC0\nlicence.\n" -"It allows anyone to freely\nreuse, improve or modify my\n" -"work for any purpose and\nwithout any legal restrictions, " -"except those required by law.\n"); - -/* 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); -} diff --git a/src/commands/jump_address.c b/src/commands/jump_address.c deleted file mode 100644 index fdaf618..0000000 --- a/src/commands/jump_address.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include - -// Internal prototype. -static void address_jump(int argc, char **argv, struct session_s *session, char *info); - -// Define the command block into the cache. -CMDBLOCK("jmp", &address_jump, -"JMP command help\n" -"This command takes one\nparameter: the address (hexa)\n" -"you would jump into the Virtual Memory.\n" -"\n" -"Be careful, there is no security" -"and some parts of the Virtual\n" -"Memory can make your\ncalculator crash.\n" -"\n" -"If a crash occurs, don't worry, you have \"just\" read a\n" -"non-readable space.\n" -"Your calculator will continue\nto work perfectly after\nthe reset.\n" -"\n" -"Virtual Memory map:\n" -"Area P0 - 2Go - MMU enable\n" -"0x00300000 : add-in header\n" -"0x00300200 : add-in mapping\n" -"0x08000000 : RAM (cache)\n" -"Area P1 - 500Mo - MMU disable\n" -"0x80000000 : ROM (cache)\n" -"0x88000000 : RAM (cache)\n" -"Area P2 - 500Mo - MMU disable\n" -"0xa0000000 : ROM (no cache)\n" -"0xa8000000 : RAM (no cache)\n" -"Area P3 - 500Mo - MMU 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; -} diff --git a/src/commands/jump_ram.c b/src/commands/jump_ram.c deleted file mode 100644 index 5099064..0000000 --- a/src/commands/jump_ram.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -// Internal prototype. -static void ram_jump(int argc, char **argv, struct session_s *session, char *info); - -/* Define the command block into the cache section. */ -CMDBLOCK("ram", &ram_jump, -"RAM command help\n" -"This function allows user to\njump into different parts of\n" -"the RAM mapped in the Virtual\nMemory.\n" -"\n" -":ram p0\n" -"Jump into the P0 area, basically" -"the user space who is managed\n" -"by the Memory Management\nUnit.\n" -"\n" -":ram p1\n" -"Jump into the RAM mapped in the P1 area; MMU is disabled and\n" -"the area is cached.\n" -"\n" -":ram p2\n" -"Jump into the RAM mapped in the P2 area; MMU is disable " -"and the area is not cached.\n" -"\n" -":ram p4\n" -"Jump into the internal chip\nmemory area; MMU is enabled\n" -"and the area is cached.\n" -); - -/* ram_jump() - jump into the RAM mapped in different parts of the Virtual Memory. */ -static void ram_jump(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 2){ - strcpy(info, "argument error"); - return; - } - if (strcmp(argv[1], "p0") && strcmp(argv[1], "p1") - && strcmp(argv[1], "p2") && strcmp(argv[1], "p4")){ - sprintf(info, "bad argument"); - return; - } - if (!strcmp(argv[1], "p0")) - session->anchor = 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; -} diff --git a/src/commands/jump_rom.c b/src/commands/jump_rom.c deleted file mode 100644 index d449b42..0000000 --- a/src/commands/jump_rom.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include - -// internal prototype. -static void rom_jump(int argc, char **argv, struct session_s *session, char *info); - -// Define the command into the cache. -CMDBLOCK("rom", &rom_jump, -"ROM command help\n" -"This command allows user to\njump into different parts of\n" -"the ROM mapped in the Virtual\nMemory.\n" -"\n" -":rom addin\n" -"Jump into the dynamic add-in\nmapping area.\n" -"Normaly you can see the\nVhex binary :)\n" -"(see \":help jmp\" to get the\nVirtual Memory map)\n" -"\n" -":rom p1\n" -"Jump into the ROM mapped in\nthe P1 area.\n" -"MMU is disable and the area\nis cached.\n" -"\n" -"rom p2\n" -"Jump into the ROM mapped in\nthe P2 area.\n" -"MMU is disable and the area\nis not cached.\n" -); - -/* rom_jump() - jump into the 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; -} diff --git a/src/commands/jump_syscall.c b/src/commands/jump_syscall.c deleted file mode 100644 index 14cf4b3..0000000 --- a/src/commands/jump_syscall.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -// Internal prototype. -static void syscall_jump(int argc, char **argv, struct session_s *session, char *info); - -/* Define command block into the cache section. */ -CMDBLOCK("syscall", &syscall_jump, -"SYSCALL command help\n" -"Take one parameter: syscall id.\n" -"This command will jump at the\nsyscall's code entry.\n" -"\n" -"Syscall list (not exhaustive):\n" -"0x013 : GLibAddinAppExecutionCheck\n" -"0x014 : GLibGetAddinLibInfo\n" -"0x014 : GLibGetOSVersionInfo\n" -"0x01c : Bdisp_WriteGraph_VRAM\n" -"0x01d : Bdisp_WriteGraph_DD\n" -"0x01e : Bdisp_WriteGraph_DDVRAM\n" -"0x022 : Bdisp_ReadArea_VRAM\n" -"0x023 : Bdisp_ReadArea_DD_OS\n" -"0x024 : Bdisp_GetDisp_DD\n" -"0x026 : DD_GET\n" -"0x028 : Bdisp_PutDisp_DD\n" -"0x030 : Bdisp_DrawLineVRAM\n" -"0x031 : Bdisp_ClearLine_VRAM\n" -"0x118 : Bcre_cychdr\n" -"0x119 : Bdel_cychdr\n" -"0x142 : Bdisp_AllClr_DD\n" -"0x143 : Bdisp_AllClr_VRAM\n" -"0x144 : Bdisp_AllClr_DDVRAM\n" -"0x145 : Bdisp_GetDisp_VRAM\n" -"0x147 : Bdisp_SetPoint_DD\n" -"0x148 : Bdisp_SetPoint_DDVRAM\n" -"0x149 : Bdisp_GetPoint_VRAM\n" -"0x14a : Bdisp_AreaClr_DD\n" -"0x14b : Bdisp_AreaClr_VRAM\n" -"0x14c : Bdisp_AreaClr_DDVRAM\n" -"0x14d : Bdisp_AreaReverseVRAM\n" -"0x11a : Bsta_cychdr\n" -"0x11b : Bstp_cychdr\n" -"0x11f : Bdisp_PutDispArea_DD\n" -"0x1e7 : BfileFLS_CloseFile\n" -"0x218 : flsFindCLose\n" -"0x242 : Bkey_Set_RepeatTime\n" -"0x243 : Bkey_Get_RepeatTime\n" -"0x244 : Bkey_Set_RepeatTime_Default\n" -"0x247 : Bkey_GetKeyWait\n" -"0x24c : Chattering\n" -"0x374 : BMCSRenameVariable\n" -"0x3ed : SetFlagPaturn\n" -"0x3fa : Hmem_SetMMU\n" -"0x420 : BSrl_DummyWAIT\n" -"0x42c : Bfile_OpenFile_OS\n" -"0x42d : Bfile_CloseFile_OS\n" -"0x42e : Bfile_GetMediaFree_OS\n" -"0x42f : Bfile_GetFileSize_OS\n" -"0x431 : Bfile_SeekFile_OS\n" -"0x432 : Bfile_ReadFile_OS\n" -"0x434 : Bfile_CreateEntry\n" -"0x435 : Bfile_WriteFile_OS\n" -"0x439 : Bfile_DeleteEntry\n" -"0x43b : Bfile_FindFirst\n" -"0x43d : Bfile_FindClose\n" -"0x43c : Bfile_FindNext\n" -"0x462 : GetAppName\n" -"0x494 : CallBackAtQuitMainFunction\n" -"0x807 : Locate_OS\n" -"0x82b : MCSPutVar2\n" -"0x830 : MCSOvwDat2\n" -"0x836 : MCSDelVar2\n" -"0x840 : MCSGetDlen2\n" -"0x841 : MCSGetData1\n" -"0x844 : MCSGetCapa\n" -"0x8fe : PopUpWin\n" -"0x808 : Print\n" -"0x809 : PrintRev\n" -"0x80b : PrintRev\n" -"0x80d : PrintRLine\n" -"0x80a : PrintC\n" -"0x80c : PrintLine\n" -"0x813 : SaveDisp\n" -"0x814 : RestoreDisp\n" -"0x90f : GetKey\n" -"0x9ad : PrintXY\n" -"0xacc : free\n" -"0xacd : malloc\n" -"0xc4f : PrintMiniSd\n" -"0xe6b : calloc\n" -"0xe6d : realloc\n" -"0x1032 : Bkey_GetKeyTableInfo\nJumpFunc\n" -); - -static INLINE int check_address(char *str) -{ - --str; - while ((*(++str) >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')); - return ((*str != '\0') ? 1 : 0); -} - -// -// syscall_jump() -// Casio doesn't use the TRAPA instruction (software interruption), for switch from -// user mode to privileged mode. They just jump 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]; -} diff --git a/src/commands/jump_systab.c b/src/commands/jump_systab.c deleted file mode 100644 index f2c236f..0000000 --- a/src/commands/jump_systab.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -// Internal prototype. -static void systab_jump(int argc, char **argv, struct session_s *session, char *info); - -// Define the command block into the cache -CMDBLOCK("systab", &systab_jump, -"SYSTAB command help\n" -"This function allows user to\njump into the Casio \"syscall\n" -"handler\".\n" -"\n" -"Curiously, Casio doesn't use the" -"TRAPA instruction for handle\n" -"syscall, but jump at\n0x80010070.\n" -"This don't explain why we are\nalways in privileged mode, but\n" -"now we can affirm that Casio\ndo it intentionally.\n" -); - -/* systab_jump() - Jump into the Casio "syscall handler". */ -static void systab_jump(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 1){ - strcpy(info, "argument error"); - return; - } - (void)argv; - session->anchor = 0x80010070; -} diff --git a/src/commands/jump_vbr.c b/src/commands/jump_vbr.c deleted file mode 100644 index 461c5c8..0000000 --- a/src/commands/jump_vbr.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -// Internal prototype -static void vbrjmp(int argc, char **argv, struct session_s *session, char *info); - -// TODO: write doc. -CMDBLOCK("vbrjmp", &vbrjmp, -"VBR JUMP command help\n" -"This command jump into Casio's\nhandlers.\n" -"\n" -"Due to the SH3 / SH4 VBR system\n, there are 3 vectors offset\n" -"called by the processor:\n" -" * exception (VBR + 0x100)\n" -" * tlb miss (VBR + 0x400)\n" -" * interrupt (VBR + 0x600)\n" -"\n" -"You can access to each handler\nusing this command list:\n" -":vbrjmp except VBR + 0x100\n" -":vbrjmp fault VBR + 0x400\n" -":vbrjmp int VBR + 0x600\n" -); - -// -// vbr_jump() - jump to the exception, tlb or interrupt, Casio handler. -// Due to the SH3 / SH4 VBR system, there are 3 vectors offset called -// by the processor: -// * vbr + 0x100 -> general exeptions. -// * vbr + 0x400 -> tlb miss. -// * vbr + 0x600 -> interrupts. -// -static void vbrjmp(int argc, char **argv, struct session_s *session, char *info) -{ - if (argc != 2){ - strcpy(info, "arguments error"); - return; - } - if (strcmp(argv[1], "fault") && strcmp(argv[1], "except") && strcmp(argv[1], "int")){ - sprintf(info, "bad argument"); - return; - } - __asm__ volatile ("stc vbr, %0" : "=r"(session->anchor)); - if (!strcmp(argv[1], "except")) - session->anchor += 0x100; - if (!strcmp(argv[1], "fault")) - session->anchor += 0x400; - if (!strcmp(argv[1], "int")) - session->anchor += 0x600; -} diff --git a/src/commands/quit.c b/src/commands/quit.c deleted file mode 100644 index 9a3832e..0000000 --- a/src/commands/quit.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -// internal prototype. -static void quit(int argc, char **argv, struct session_s *session, char *info); - -// Define the command into the cache. -CMDBLOCK("quit", &quit, NULL); - -/* quit() - switch to UNUSED mode */ -static void quit(int argc, char **argv, struct session_s *session, char *info) -{ - (void)argc; - (void)argv; - strcpy(info, "exit"); - session->mode = UNUSED; - session->anchor = 0x00000000; -} diff --git a/src/commands/where.c b/src/commands/where.c deleted file mode 100644 index 8228d1f..0000000 --- a/src/commands/where.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -// internal prototype. -static void where(int argc, char **argv, struct session_s *session, char *info); - -// Define the command into the cache. -CMDBLOCK("where", &where, NULL); - -/* where() - display the user 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)); -} diff --git a/src/display/intructions.c b/src/display/intructions.c deleted file mode 100644 index 6c5aacc..0000000 --- a/src/display/intructions.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include - -//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); - } -} diff --git a/src/display/metainfos.c b/src/display/metainfos.c deleted file mode 100644 index 4cc000f..0000000 --- a/src/display/metainfos.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include - -/* 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); -} diff --git a/src/history.c b/src/history.c deleted file mode 100644 index b549b63..0000000 --- a/src/history.c +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef DEBUG -# include -# include -#else -# include "history.h" -# include -#endif -#include -#include - -//--- -// 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; -} diff --git a/src/kernel/bootstrap/fx9860_context.c b/src/kernel/bootstrap/fx9860_context.c new file mode 100644 index 0000000..3487746 --- /dev/null +++ b/src/kernel/bootstrap/fx9860_context.c @@ -0,0 +1,59 @@ +#include +#include +#include + +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; +} diff --git a/src/kernel/bootstrap/mpu.c b/src/kernel/bootstrap/mpu.c new file mode 100644 index 0000000..6804b71 --- /dev/null +++ b/src/kernel/bootstrap/mpu.c @@ -0,0 +1,64 @@ +#include + +/* 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()); +} diff --git a/src/kernel/bootstrap/section_actions.s b/src/kernel/bootstrap/section_actions.s new file mode 100644 index 0000000..776bd7f --- /dev/null +++ b/src/kernel/bootstrap/section_actions.s @@ -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 diff --git a/src/kernel/bootstrap/start.c b/src/kernel/bootstrap/start.c new file mode 100644 index 0000000..012bb09 --- /dev/null +++ b/src/kernel/bootstrap/start.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include + +// 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); +}*/ diff --git a/src/kernel/bootstrap/vbr.s b/src/kernel/bootstrap/vbr.s new file mode 100644 index 0000000..93e6c73 --- /dev/null +++ b/src/kernel/bootstrap/vbr.s @@ -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 diff --git a/src/kernel/bootstrap/vhex_context.c b/src/kernel/bootstrap/vhex_context.c new file mode 100644 index 0000000..0b6c18b --- /dev/null +++ b/src/kernel/bootstrap/vhex_context.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +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. +*/ +} diff --git a/src/kernel/hardware/t6k11/display.s b/src/kernel/hardware/t6k11/display.s new file mode 100644 index 0000000..d47a28b --- /dev/null +++ b/src/kernel/hardware/t6k11/display.s @@ -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 */ diff --git a/src/kernel/tty/close.c b/src/kernel/tty/close.c new file mode 100644 index 0000000..bd0bacf --- /dev/null +++ b/src/kernel/tty/close.c @@ -0,0 +1,7 @@ +#include + +int tty_close(void) +{ + // Do nothing for now. + return (0); +} diff --git a/src/kernel/tty/open.c b/src/kernel/tty/open.c new file mode 100644 index 0000000..42cd727 --- /dev/null +++ b/src/kernel/tty/open.c @@ -0,0 +1,18 @@ +#include +#include + +// 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); +} diff --git a/src/kernel/tty/write.c b/src/kernel/tty/write.c new file mode 100644 index 0000000..51fb577 --- /dev/null +++ b/src/kernel/tty/write.c @@ -0,0 +1,49 @@ +#include +#include + +// 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); +} diff --git a/src/kernel/util/atomic.s b/src/kernel/util/atomic.s new file mode 100644 index 0000000..6d7b28a --- /dev/null +++ b/src/kernel/util/atomic.s @@ -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 diff --git a/src/kernel/vbr/exception.c b/src/kernel/vbr/exception.c new file mode 100644 index 0000000..6fe5a78 --- /dev/null +++ b/src/kernel/vbr/exception.c @@ -0,0 +1,38 @@ +#include + +__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); +} diff --git a/src/kernel/vbr/interrupt.c b/src/kernel/vbr/interrupt.c new file mode 100644 index 0000000..f1d6f32 --- /dev/null +++ b/src/kernel/vbr/interrupt.c @@ -0,0 +1,10 @@ +#include + +__attribute__((section(".vhex.interrupt"), interrupt_handler)) +void interrupt_handler(void) +{ + dclear(); + dprint(0, 0, "Interrupt handler (%#x)\n", *(uint32_t*)0xff000028); + dupdate(); + while (1); +} diff --git a/src/kernel/vbr/tlb.c b/src/kernel/vbr/tlb.c new file mode 100644 index 0000000..41d6280 --- /dev/null +++ b/src/kernel/vbr/tlb.c @@ -0,0 +1,38 @@ +#include + +__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); +} diff --git a/src/keys.c b/src/keys.c deleted file mode 100644 index 36ef02f..0000000 --- a/src/keys.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include - -// -// 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); - } -} diff --git a/src/lib/display/dascii.c b/src/lib/display/dascii.c new file mode 100644 index 0000000..082fcdb --- /dev/null +++ b/src/lib/display/dascii.c @@ -0,0 +1,109 @@ +#include +#include + +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; + } +} diff --git a/src/lib/display/dclear.c b/src/lib/display/dclear.c new file mode 100644 index 0000000..1490b75 --- /dev/null +++ b/src/lib/display/dclear.c @@ -0,0 +1,10 @@ +#include + +void dclear(void) +{ + int i; + + i = 256; + while (--i >= 0) + VRAM[i] = 0x00000000; +} diff --git a/src/lib/display/dprint.c b/src/lib/display/dprint.c new file mode 100644 index 0000000..b790ca5 --- /dev/null +++ b/src/lib/display/dprint.c @@ -0,0 +1,31 @@ +#include +#include +#include + +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; + } +} diff --git a/src/lib/display/dscroll.c b/src/lib/display/dscroll.c new file mode 100644 index 0000000..a371a34 --- /dev/null +++ b/src/lib/display/dscroll.c @@ -0,0 +1,26 @@ +#include + +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; + } +} diff --git a/src/lib/display/dupdate.c b/src/lib/display/dupdate.c new file mode 100644 index 0000000..1ec82a9 --- /dev/null +++ b/src/lib/display/dupdate.c @@ -0,0 +1,8 @@ +#include +#include + +//FIXME: Check OS 3.00 ! +void dupdate(void) +{ + t6k11_display(VRAM); +} diff --git a/src/lib/stdio/sprintf.c b/src/lib/stdio/sprintf.c new file mode 100644 index 0000000..a9bcdd0 --- /dev/null +++ b/src/lib/stdio/sprintf.c @@ -0,0 +1,10 @@ +#include + +void sprintf(char *str, char const *format, ...) +{ + va_list ap; + + va_start(ap, format); + vsprintf(str, format, ap); + va_end(ap); +} diff --git a/src/string/sprintf.c b/src/lib/stdio/vsprintf.c similarity index 88% rename from src/string/sprintf.c rename to src/lib/stdio/vsprintf.c index 483de7c..1e24a9d 100644 --- a/src/string/sprintf.c +++ b/src/lib/stdio/vsprintf.c @@ -1,4 +1,4 @@ -#include +#include 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); -} diff --git a/src/lib/string/memcpy.c b/src/lib/string/memcpy.c new file mode 100644 index 0000000..f8cc900 --- /dev/null +++ b/src/lib/string/memcpy.c @@ -0,0 +1,9 @@ +#include +#include + +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); +} diff --git a/src/string/memset.c b/src/lib/string/memset.c similarity index 51% rename from src/string/memset.c rename to src/lib/string/memset.c index 6392c74..6c20f8a 100644 --- a/src/string/memset.c +++ b/src/lib/string/memset.c @@ -1,7 +1,7 @@ -#include +#include //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; diff --git a/src/string/strcat.c b/src/lib/string/strcat.c similarity index 73% rename from src/string/strcat.c rename to src/lib/string/strcat.c index c1c1419..5cc1601 100644 --- a/src/string/strcat.c +++ b/src/lib/string/strcat.c @@ -1,6 +1,6 @@ -#include +#include -__attribute__((weak)) char *strcat(char *dest, char const *src) +char *strcat(char *dest, char const *src) { size_t i; size_t start; diff --git a/src/lib/string/strcmp.c b/src/lib/string/strcmp.c new file mode 100644 index 0000000..e225db5 --- /dev/null +++ b/src/lib/string/strcmp.c @@ -0,0 +1,13 @@ +#include + +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); +} diff --git a/src/string/strcpy.c b/src/lib/string/strcpy.c similarity index 66% rename from src/string/strcpy.c rename to src/lib/string/strcpy.c index f5e78ff..a9eb95d 100644 --- a/src/string/strcpy.c +++ b/src/lib/string/strcpy.c @@ -1,6 +1,6 @@ -#include +#include -__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; diff --git a/src/string/strlen.c b/src/lib/string/strlen.c similarity index 57% rename from src/string/strlen.c rename to src/lib/string/strlen.c index 56cf1c6..d151965 100644 --- a/src/string/strlen.c +++ b/src/lib/string/strlen.c @@ -1,6 +1,6 @@ -#include +#include -__attribute__((weak)) size_t strlen(char const *str) +size_t strlen(char const *str) { size_t i; diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 74f9613..0000000 --- a/src/main.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -// -// 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); -} diff --git a/src/string/atoi_base.c b/src/string/atoi_base.c deleted file mode 100644 index f949050..0000000 --- a/src/string/atoi_base.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -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); -} diff --git a/src/string/strcmp.c b/src/string/strcmp.c deleted file mode 100644 index f0e7635..0000000 --- a/src/string/strcmp.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -__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); -} diff --git a/src/string/strtotab.c b/src/string/strtotab.c deleted file mode 100644 index a5efe7c..0000000 --- a/src/string/strtotab.c +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef DEBUG -//# include -# include -#else -//# include "commands.h" -# include -# include -#endif -#include -#include - -// 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; -} diff --git a/src/syscalls.s b/src/syscalls.s deleted file mode 100644 index 70c827b..0000000 --- a/src/syscalls.s +++ /dev/null @@ -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 diff --git a/src/user/main.c b/src/user/main.c new file mode 100644 index 0000000..0f94379 --- /dev/null +++ b/src/user/main.c @@ -0,0 +1,34 @@ +#include +#include +#include + +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); +} diff --git a/tests/atoi_base_test.c b/tests/atoi_base_test.c deleted file mode 100644 index 0297d8c..0000000 --- a/tests/atoi_base_test.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -// 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); -} diff --git a/tests/history_test.c b/tests/history_test.c deleted file mode 100644 index dac857f..0000000 --- a/tests/history_test.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include "tests/internal.h" -#include "history.h" -#include - - -//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); -} diff --git a/tests/internal.h b/tests/internal.h deleted file mode 100644 index ff3b006..0000000 --- a/tests/internal.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __INTERNAL_H__ -# define __INTERNAL_H__ - -#include -#include - -// -// 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__*/ diff --git a/tests/malloc_hook.c b/tests/malloc_hook.c deleted file mode 100644 index fd54d84..0000000 --- a/tests/malloc_hook.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "tests/internal.h" -#include -#include - -// 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; -} diff --git a/tests/strtab_test.c b/tests/strtab_test.c deleted file mode 100644 index 9372bdf..0000000 --- a/tests/strtab_test.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include "tests/internal.h" -#include - -// 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); -} diff --git a/vhex.g1a b/vhex.g1a index 8d620d4..fec54df 100644 Binary files a/vhex.g1a and b/vhex.g1a differ diff --git a/vhex.ld b/vhex.ld new file mode 100644 index 0000000..b419ecd --- /dev/null +++ b/vhex.ld @@ -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) + } +}