diff --git a/.gitignore b/.gitignore index 9a73a45..5b8a11e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,19 +5,12 @@ build/** *.sublime-project *.sublime-workspace -# Object files. -*.o - -# Some notes. +# Lots of unordered project notes notes/** # Output files -libc.a -libgint.a -gintdemo.g1a -gintdbg.g1a +bin/** # Configuration files -gcc.cfg -Makefile.cfg +config/** diff --git a/Makefile b/Makefile index beabd19..f577bc5 100755 --- a/Makefile +++ b/Makefile @@ -4,267 +4,125 @@ # #--- -include Makefile.cfg +# +# Build configuration +# -#--- -# Project variables -#--- +# Some rules don't care if config files are missing (eg. clean, etc) +cfg := config/Makefile.cfg +-include $(cfg) -# Modules -modules-gint = bopti clock core display events gray init keyboard mmu rtc \ - screen tales timer -modules-libc = ctype math setjmp stdio stdlib string time +# Those that do may use this special dependency +cfgdep := $(if $(shell [ -f $(cfg) ] || echo n),CFGDEP,$(cfg)) -# Targets -target-lib = libgint.a -target-std = libc.a -target-g1a = gintdemo.g1a +# Compiler flags, assembler flags, dependency generation, archiving +cflags := -m3 -mb -ffreestanding -nostdlib -Wall -Wextra -std=c11 -O2 \ + -I include $(cfg_defs) +dflags = -MMD -MT $@ -MF $(@:.o=.d) -MP +arflags := -# Tools -cc = sh3eb-elf-gcc -ld = sh3eb-elf-ld -as = sh3eb-elf-as -ar = sh3eb-elf-ar -ob = sh3eb-elf-objcopy -wr = g1a-wrapper +# +# File listings +# -# Flags for gint -lib-cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os \ - -Wall -Wextra @gcc.cfg -g0 +# Target file +target := bin/libgint.a -# Demo application (could be done better) -demo-src = $(notdir $(wildcard demo/*.[cs])) -demo-dep = $(wildcard demo/*.h) -demo-icon = demo/icon.bmp -demo-res = $(notdir $(wildcard demo/resources/*)) -demo-obj = $(patsubst %,build/demo_%.o,$(demo-src) $(demo-res)) -demo-elf = build/gintdemo.elf -demo-bin = build/gintdemo.bin -demo-ldflags = $(demo-cflags) -T demo/gintdemo.ld -L. -lgint -lc -lgcc -demo-cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os \ - -Wall -Wextra +# Automatic names for object and dependency files +src2obj = build/$(1:src/%=%).o +src2dep = build/$(1:src/%=%).d -# Specific objects -obj-std-spec = -obj-lib-spec = build/display_font_system.bmp.o build/version.o +# Source files +src := $(shell find src -name '*.[cs]') +src_obj := $(foreach s,$(src),$(call src2obj,$s)) -# Configuration files, require them only if we're not cleaning -config = gcc.cfg -ifeq "$(filter clean mrproper distclean,$(MAKECMDGOALS))" "" -ifeq ($(wildcard $(config)),) -$(error "Configuration files are missing. Did you ./configure ?") -endif -endif +# Files with special handling +spe := src/display/font.bmp +spe_obj := $(foreach s,$(spe),$(call src2obj,$s)) -# Target folder, require it only if we want to install -ifneq "$(filter install,$(MAKECMDGOALS))" "" -folder := $(shell fxsdk --folder) -ifndef folder -$(error "Could not get the fxSDK storage folder. Did you install fxSDK \ -properly?") -endif -endif +# All object files +obj := $(src_obj) $(spe_obj) +# +# Toolchain +# +gcc = sh3eb-elf-gcc +as = sh3eb-elf-as +ld = sh3eb-elf-ld +ar = sh3eb-elf-ar +conv = fxconv -#--- -# Automatic variables -#--- +# +# Build rules +# -# Modules are subfolders of src/. -modules = $(modules-gint) $(modules-libc) +all: $(target) -define n -# This is a newline character. +$(target): $(obj) | $(dir $(target)) + $(call cmd_l,ar,$@) $(ar) -crs $(arflags) $@ $(obj) -endef +# Assembler sources +build/%.s.o: src/%.s build/%.s.d + @ mkdir -p $(dir $@) + $(call cmd_b,as,$<) $(as) -c $< -o $@ $(sflags) -# Module-scope variables. -$(foreach mod, $(modules), $(eval \ - mod-$(mod)-c = $(notdir $(wildcard src/$(mod)/*.c)) $n\ - mod-$(mod)-asm = $(notdir $(wildcard src/$(mod)/*.s)) $n\ - mod-$(mod)-src = $$(mod-$(mod)-c)$$(mod-$(mod)-asm) $n\ - mod-$(mod)-obj = $$(patsubst %,build/$(mod)_%.o,$$(mod-$(mod)-src)) \ -)) +# C sources +build/%.c.o: src/%.c build/%.c.d $(cfgdep) + @ mkdir -p $(dir $@) + $(call cmd_b,gcc,$<) $(gcc) -c $< -o $@ $(dflags) $(cflags) -# Target-scope variables. -obj-std = $(foreach mod,$(modules-libc),$(mod-$(mod)-obj)) $(obj-std-spec) -obj-lib = $(foreach mod,$(modules-gint),$(mod-$(mod)-obj)) $(obj-lib-spec) +# Special files +$(call src2obj,src/display/font.bmp): src/display/font.bmp + @ mkdir -p $(dir $@) + $(call cmd_m,fxconv,$<) $(conv) -font $< -n gint_font -o $@ -# Dependencies. -hdr-dep = $(wildcard include/*.h include/*/*.h) - - - -#--- -# Rule templates -#--- - -# C source file template: -# $1 module name -# $2 filename -# $3 dependencies -define rule-c-source -build/$1_$2.o: src/$1/$2 $3 $(config) - $(if $(VERBOSE),,@ printf '\e[34;1m gcc\e[0m $$<\n') - $(if $(VERBOSE),,@) $(cc) -c $$< -o $$@ $(lib-cflags) -endef - -# Asm source file template: -# $1 module name -# $2 filename -define rule-asm-source -build/$1_$2.o: src/$1/$2 $(config) - $(if $(VERBOSE),,@ printf '\e[34;1m as\e[0m $$<\n') - $(if $(VERBOSE),,@) $(as) -c $$< -o $$@ -endef - - - -#--- -# Version management -#--- - -# Retrieve version information. -version_string = $(shell cat version | sed 's/[-.]/ /g') -version_type = $(word 1,$(version_string)) -version_major = $(word 2,$(version_string)) -version_minor = $(word 3,$(version_string)) -version_build = $(word 4,$(version_string)) - -# Make up the new version integer. -version_build_n = $(shell echo $$(($(version_build) + 1))) -version_letter = $(shell echo -n $(version_type) | sed -r 's/^(.).*/\1/') -version_symbol = $(shell printf '0x%02x%01x%01x%04x' "'$(version_letter)'" \ - $(version_major) $(version_minor) $(version_build)) - - - -#--- -# Building -#--- - -# Generic rules - -all-lib: $(config) $(target-std) $(target-lib) - -all: $(config) $(target-std) $(target-lib) $(target-g1a) - -build: - $(if $(VERBOSE),,@ printf '\e[35;1m mkdir\e[0m $@\n') - $(if $(VERBOSE),,@) mkdir -p $@ - -version: src include - @ echo '$(version_type)-$(version_major).$(version_minor)-$(version_build_n)' > $@ - - -$(obj-std) $(obj-lib) $(demo-obj): | build - -$(target-std): $(obj-std) version - $(if $(VERBOSE),,@ printf '\e[35;1m ar\e[0m ar $@\n') - $(if $(VERBOSE),,@) $(ar) rcs $@ $(obj-std) - @ printf '\n\e[32;1m\u00bb\e[0m Succesfully built libc (' - @ printf $$(stat -c %s $@) - @ printf ' bytes)\n\n' - -$(target-lib): $(config) $(target-std) $(obj-lib) version - $(if $(VERBOSE),,@ printf '\e[35;1m ar\e[0m $@\n') - $(if $(VERBOSE),,@) $(ar) rcs $@ $(obj-lib) - @ printf '\n\e[32;1m\u00bb\e[0m Succesfully built libgint (' - @ printf $$(stat -c %s $@) - @ printf ' bytes)\n\n' - -$(target-g1a): $(config) $(target-std) $(target-lib) $(demo-obj) - $(if $(VERBOSE),,@ printf '\e[35;1m ld\e[0m $(demo-elf)\n') - $(if $(VERBOSE),,@) $(cc) -o $(demo-elf) $(demo-obj) $(demo-ldflags) - $(if $(VERBOSE),,@ printf '\e[35;1mobjcopy\e[0m $(demo-bin)\n') - $(if $(VERBOSE),,@) $(ob) -R .comment -R .bss -O binary $(demo-elf) $(demo-bin) - $(if $(VERBOSE),,@ printf '\e[35;1m fxg1a\e[0m $@\n') - $(if $(VERBOSE),,@) $(wr) $(demo-bin) -o $@ -i $(demo-icon) - @ printf '\n\e[32;1m\u00bb\e[0m Succesfully built demo application (' - @ printf $$(stat -c %s $@) - @ printf ' bytes)\n\n' - -# Automated rules - -$(foreach mod,$(modules), \ - $(foreach source,$(mod-$(mod)-c), $(eval \ - $(call rule-c-source,$(mod),$(source),$(hdr-dep)))) \ - $(foreach source,$(mod-$(mod)-asm), $(eval \ - $(call rule-asm-source,$(mod),$(source)))) \ -) - -# Specific rules - -# Define the version symbol in a specific object file. ld generates a .stack -# section on sh3eb-elf, which it didn't on x86_64. I don't understand the -# details of why, so I just fall back to removing it afterwards. -build/version.o: - @ echo "_GINT_VERSION = $(version_symbol);" > $@.txt - $(if $(VERBOSE),,@ printf '\e[35;1m ld\e[0m $@\n') - $(if $(VERBOSE),,@) $(ld) -r -R $@.txt -o $@ - $(if $(VERBOSE),,@) $(ob) -R .stack $@ $@ - -build/display_font_%.bmp.o: src/display/font_%.bmp - $(if $(VERBOSE),,@ printf '\e[30;1m fxconv\e[0m -font $<\n') - $(if $(VERBOSE),,@) fxconv -font $< -o $@ -font -n $(<:src/display/font_%.bmp=gint_font_%) - -# Demo application - -build/demo_%.c.o: demo/%.c $(hdr-dep) $(demo-dep) $(config) - $(if $(VERBOSE),,@ printf '\e[34;1m gcc\e[0m $<\n') - $(if $(VERBOSE),,@) $(cc) -c $< -o $@ $(demo-cflags) - -build/demo_%.s.o: demo/%.s $(config) - $(if $(VERBOSE),,@ printf '\e[34;1m as\e[0m $<\n') - $(if $(VERBOSE),,@) $(as) -c $< -o $@ - -build/demo_font_%.bmp.o: demo/resources/font_%.bmp - $(if $(VERBOSE),,@ printf '\e[30;1m fxconv\e[0m -font $<\n') - $(if $(VERBOSE),,@) fxconv -font $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<) - -build/demo_%.bmp.o: demo/resources/%.bmp - $(if $(VERBOSE),,@ printf '\e[30;1m fxconv\e[0m -image $<\n') - $(if $(VERBOSE),,@) fxconv -image $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<) - - - -#--- -# Cleaning and install -#--- +# +# Cleaning +# clean: - @ rm -rf build + @ rm -rf build/ +distclean: clean + @ rm -rf bin/ + @ rm -f $(cfg) -mrproper: clean - @ rm -f $(target-g1a) $(target-lib) $(target-std) - @ rm -f $(config) +# +# Utilities +# -distclean: mrproper +# Evaluated when a rule requires the configuration file but it doesn't exist +CFGDEP: + @ echo "Configuration file $(cfg) is missing. Have you configured?" + @ echo "See \`./configure --help\` for details." + @ false -install: $(target-std) $(target-lib) - $(if $(VERBOSE),,@ printf '\e[35;1m mkdir\e[0m $(folder)\n') - $(if $(VERBOSE),,@) mkdir -p $(folder) +# Make directories: make conveniently leaves a '/' at the end of $(dir ...) +%/: + @ mkdir -p $@ +# Don't try to unlink directories once they're built (that wouldn't work =p) +.PRECIOUS: %/ - $(if $(VERBOSE),,@ printf '\e[33;1minstall\e[0m 644 $^\n') - $(if $(VERBOSE),,@) install -m 644 $^ $(folder) - $(if $(VERBOSE),,@ printf '\e[33;1minstall\e[0m 644 demo/gintdemo.ld\n') - $(if $(VERBOSE),,@) install -m 644 -T demo/gintdemo.ld $(folder)/linker.ld +# Dependency information +-include $(shell [ -d build ] && find build -name *.d) +build/%.d: ; +.PRECIOUS: build/%.d - $(if $(VERBOSE),,@ printf '\e[35;1m mkdir\e[0m $(folder)/gint/modules\n') - $(if $(VERBOSE),,@) mkdir -p $(folder)/gint/modules +# Do not output full commands by default +VERBOSE ?= - $(if $(VERBOSE),,@ printf '\e[33;1minstall\e[0m 644 include/**.h\n') - $(if $(VERBOSE),,@) install -m 644 include/*.h $(folder)/gint - $(if $(VERBOSE),,@) install -m 644 include/modules/*.h $(folder)/gint/modules -ifdef config_ext - $(if $(VERBOSE),,@) install -m 644 include/extended/*.h $(folder)/gint -endif - @ printf "\n\033[32;1m\u00bb\033[0m Successfully installed gint\n\n" +# Simple command output method +# $1 Program name +# $2 Argument string to display +# $3 Command color +define cmd +@ echo -e "\e[""$3"";1m>\e[0;1m $1\e[0m $2" +$(if $(VERBOSE),,@) +endef -install-demo: all - p7 send -f $(target-g1a) - -.PHONY: all-lib all help -.PHONY: clean mrproper distclean -.PHONY: install install-demo +# Some pre-colored command kinds: misc, build, link, clean, install +cmd_m = $(call cmd,$1,$2,30) +cmd_b = $(call cmd,$1,$2,32) +cmd_l = $(call cmd,$1,$2,36) +cmd_c = $(call cmd,$1,$2,31) +cmd_i = $(call cmd,$1,$2,33) diff --git a/README.md b/README.md index e6f748b..d5b21b9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ target) and the [fxSDK](http://git.planet-casio.com/lephe/fxsdk). gint is free software: you may use it for any purpose, share it, modify it and share your changes. No credit of any kind is required, though appreciated. +**TODO: Update this file for everything related to project organization** + Programming interface --------------------- diff --git a/configure b/configure index bb6ae65..e99fe35 100755 --- a/configure +++ b/configure @@ -6,8 +6,11 @@ declare -A conf +# Target platform +conf_target= + # Behavior -conf[GINT_STARTUP_LOG]= +conf[GINT_BOOT_LOG]= conf[GINT_NO_SYSCALLS]= conf[GINT_EXTENDED_LIBC]= conf[GINT_STATIC_GRAY]= @@ -18,45 +21,50 @@ conf[TIMER_SLOTS]=16 conf[EVENTS_QUEUE_SIZE]=64 # Output files -output_gcc="gcc.cfg" -output_make="Makefile.cfg" +output="config/Makefile.cfg" # # Help screen and output util # error="\e[31;1merror:\e[0m" -Cg="$(tput setaf 8)$(tput bold)" -Cr="$(tput setaf 1)$(tput bold)" -Cy="$(tput setaf 2)$(tput bold)" -Cp="$(tput setaf 5)$(tput setaf 62)$(tput bold)" -C0="$(tput setaf 0)$(tput sgr 0)" +C_="$(echo -e '\e[30;1m')" +Cr="$(echo -e '\e[31;1m')" +Cg="$(echo -e '\e[32;1m')" +Cp="$(echo -e '\e[34;1m')" +C0="$(echo -e '\e[0m')" help() { cat << EOF Configuration script for the gint library. +Usage: $0 [options...] + +Required settings: + $Cr--target$C0=${Cg}fx9860g$C0,${Cg}fxcg50$C0 + Select the target platform, either ${Cg}fx9860g$C0 for monochrome + calculators, or ${Cg}fxcg50$C0 for Prizm calculators. Options that affect the behavior of the library: - $Cr--startup-log $Cg[default:$Cp false$Cg]$C0 - Enable a on-screen log at startup if a key is kept pressed while launching + $Cr--boot-log $C_[default:$Cp not specified$C_]$C0 + Enable an on-screen log at startup if a key is kept pressed while launching the add-in, allowing easy debug and crash diagnoses. - $Cr--no-syscalls $Cg[default:$Cp false$Cg]$C0 + $Cr--no-syscalls $C_[default:$Cp not specified$C_]$C0 Never use syscalls. Expect trouble with malloc() and the gray engine. Do not trigger this switch unless you know what you are doing. - $Cr--extended-libc $Cg[default:$Cp false$Cg]$C0 + $Cr--extended-libc $C_[default:$Cp not specified$C_]$C0 Enable specific C99 headers/features that are normally not required by calculator programs. This may allow porting programs from other platforms. - $Cr--static-gray-engine $Cg[default:$Cp false$Cg]$C0 + $Cr--static-gray-engine $C_[default:$Cp not specified$C_]$C0 Place the gray engine vram in static ram instead of using the heap. Always use this option when using both the gray engine and --no-syscalls. Options that customize size limits: - $Cr--atexit-max=$Cy$Cg [default:$Cp 16$Cg]$C0 + $Cr--atexit-max$C0=${Cg}integer$C_ [default:$Cp 16$C_]$C0 Number of exit handlers that can be registered by atexit(). - $Cr--timer-slots=$Cy$Cg [default:$Cp 16$Cg]$C0 + $Cr--timer-slots$C0=${Cg}integer$C_ [default:$Cp 16$C_]$C0 Number of virtual timers that may be registered at the same time. - $Cr--events-queue-size=$Cy$Cg [default:$Cp 64$Cg]$C0 + $Cr--events-queue-size$C0=${Cg}integer$C_ [default:$Cp 64$C_]$C0 Number of events simultaneously stored in the event queue. EOF @@ -69,8 +77,20 @@ EOF fail=false for arg; do case "$arg" in - -h | --help) help;; - --startup-log) conf[GINT_STARTUP_LOG]=true;; + -h | -? | --help) help;; + + --target=*) + conf_target=${arg#*=} + if [[ $conf_target = "fx9860g" ]]; then + conf_target="GINT_FX9860G" + else if [[ $conf_target = "fxcg50" ]]; then + conf_target="GINT_FXCG50" + else + echo -e "$error Invalid target. See $0 --help." + fail=true; + fi; fi;; + + --boot-log) conf[GINT_BOOT_LOG]=true;; --no-syscalls) conf[GINT_NO_SYSCALLS]=true;; --extended-libc) conf[GINT_EXTENDED_LIBC]=true;; --static-gray-engine) conf[GINT_STATIC_GRAY]=true;; @@ -103,34 +123,41 @@ for arg; do case "$arg" in esac; done # -# Output config routines +# Checking mandatory arguments # -output_config_gcc() -{ - [ "${conf[GINT_STARTUP_LOG]}" != "" ] && echo "-D GINT_STARTUP_LOG" - [ "${conf[GINT_NO_SYSCALLS]}" != "" ] && echo "-D GINT_NO_SYSCALLS" - [ "${conf[GINT_EXTENDED_LIBC]}" != "" ] && echo "-D GINT_EXTENDED_LIBC" - [ "${conf[GINT_STATIC_GRAY]}" != "" ] && echo "-D GINT_STATIC_GRAY" - - echo "-D ATEXIT_MAX=${conf[ATEXIT_MAX]}" - echo "-D TIMER_SLOTS=${conf[TIMER_SLOTS]}" - echo "-D EVENTS_QUEUE_SIZE=${conf[EVENTS_QUEUE_SIZE]}" -} - -output_config_make() -{ - [ "${conf[GINT_EXTENDED_LIBC]}" != "" ] && echo "config_ext=true" -} +if [[ ! $conf_target ]]; then + echo -e "$error No target specified. See $0 --help." + fail=true; +fi # # Output config # +output_config() +{ + echo -n "cfg_defs =" + echo -n " -D$conf_target" + + [ "${conf[GINT_BOOT_LOG]}" ] && echo -n " -DGINT_BOOT_LOG" + [ "${conf[GINT_NO_SYSCALLS]}" ] && echo -n " -DGINT_NO_SYSCALLS" + [ "${conf[GINT_EXTENDED_LIBC]}" ] && echo -n " -DGINT_EXTENDED_LIBC" + [ "${conf[GINT_STATIC_GRAY]}" ] && echo -n " -DGINT_STATIC_GRAY" + + echo -n " -DATEXIT_MAX=${conf[ATEXIT_MAX]}" + echo -n " -DTIMER_SLOTS=${conf[TIMER_SLOTS]}" + echo -n " -DEVENTS_QUEUE_SIZE=${conf[EVENTS_QUEUE_SIZE]}" + + echo "" + + [ "${conf[GINT_EXTENDED_LIBC]}" != "" ] && echo "cfg_ext = true" +} + if $fail; then - echo "Configuration has not been modified." + echo "Output file $output has not been modified." else - output_config_gcc > $output_gcc - output_config_make > $output_make - echo "Configuration saved in $output_gcc and $output_make." + mkdir -p config + output_config > $output + echo "Configuration saved in $output, ready to make!" fi diff --git a/demo/gintdemo.c b/demo/gintdemo.c deleted file mode 100644 index 16ffaf5..0000000 --- a/demo/gintdemo.c +++ /dev/null @@ -1,456 +0,0 @@ -#include "gintdemo.h" - -#include -#include -#include -#include -#include - -#include -#include - - - -//--- -// A few procedures for displaying text aligned on a 21*8 grid. -// Not really beautiful... but this will do. -//--- - -void locate(int x, int y, const char *str) -{ - if(x < 1 || x > 21 || y < 1 || y > 8) return; - if(gray_runs()) gtext(x * 6 - 5, y * 8 - 8, str); - else dtext(x * 6 - 5, y * 8 - 8, str); -} - -void print(int x, int y, const char *format, ...) -{ - va_list args; - - va_start(args, format); - __printf(0, format, args); - va_end(args); - - locate(x, y, __stdio_buffer); -} - -/* - printf_test() - Tests formatting functions. - -void printf_test(void) -{ - dclear(); - locate(1, 1, "Formatted printing"); - - print(2, 3, "%%4.2d 5 :\"%4.2d\"", 5); - print(2, 4, "%%-3c '&':\"%-3c\"", '&'); - print(2, 5, "%%#05x 27 :\"%#05x\"", 27); - print(2, 6, "%%1s \"tr\":\"%1s\"", "tr"); - print(2, 7, "%%6p NULL :\"%6p\"", NULL); - - dupdate(); - while(getkey() != KEY_EXIT); -} -*/ - -/* - tlb_debug() - Displays the TLB contents and some information. Only available for - SH7705, because the SH7305's TLB is much more complicated. - -void tlb_debug(void) -{ - // Entry address address (pointer in the address array), entry data - // address (pointer in the data address), and their contents. - unsigned int address, data, a, d; - // Virtual page number and physical page number. - unsigned int vpn, ppn; - // Contents of register MMUCR. - unsigned mmucr; - - int i, r, key = 0; - int way = 0, entry = 0; - int pointer_base; - - const char *protection[] = { "pr", "prw", "ar", "arw" }; - mmucr = *((volatile unsigned int *)gint_reg(Register_MMUCR)); - - dclear(); - locate("MMU register info", 1, 1); - locate("MMUCR.IX = ", 2, 3); - locate(mmucr & 0x02 ? "1" : "0", 13, 3); - dupdate(); - getkey(); - - while(key != KEY_EXIT && way < 4) - { - dclear(); - - print(1, 1, "TLB way=%d %d-%d", way, entry, - entry > 29 ? 31 : entry + 2); - - for(i = 0; i < 3 && entry < 32; i++, entry++) - { - address = 0xf2000000 | (entry << 12) | (way << 8); - data = 0xf3000000 | (entry << 12) | (way << 8); - - a = *((volatile unsigned int *)address); - d = *((volatile unsigned int *)data); - - ppn = (d >> 10) & 0x00007ffff; - // 4-kbyte page - if(d & 0x08) - { - vpn = (a >> 12) | entry; - pointer_base = vpn << 12; - } - // 1-kbyte page - else - { - vpn = (a >> 10) | (entry << 2); - pointer_base = vpn << 10; - } - - r = 2 * i + 3; - print(1, r, "%08x :%08x", pointer_base, ppn << 10); - - r++; - locate((d & 0x08) ? "4k" : "1k", 1, r); - print(5, r, "pr=%s", protection[(d >> 5) & 3]); - locate((d & 0x02) ? "shared" : "exclusive", 13, r); - } - - if(entry == 32) entry = 0, way++; - - dupdate(); - key = getkey(); - } -} -*/ - -#include - -/* - main_menu() - Displays the main menu and returns user's choice: 0 for [EXIT], - application numbers otherwise. Sets the ctaegory and application - number. -*/ -void main_menu(int *category, int *app) -{ - //--- - // Quite a few things to declare... - //--- - - extern image_t res_opt_menu; - - const char *mpu, *mpu_names[] = { - "Unknown", - "SH7337", - "SH7355", - "SH7305", - "SH7724", - "[error]" - }; - - const char *list_tests[] = { - "Keyboard & events", - "Gray engine", - "Image rendering", - "Text rendering", - "Real-time clock", - "Clocks and timers", - NULL - }; -/* - const char *list_perfs[] = { - "Image rendering", - "Text rendering", - NULL - }; -*/ - const char **list = NULL; - int list_len = 0; - - extern unsigned int bgint, egint; - extern unsigned int romdata; - int gint_size = (char *)&egint - (char *)&bgint; - - // Building a version string. - char gint_version[20]; - uint32_t v = (uint32_t)&GINT_VERSION; - sprintf(gint_version, "%s-%d.%d-%d", - (v >> 24 == 'a') ? "alpha" : (v >> 24 == 'b') ? "beta" : - (v >> 24 == 'd') ? "dev" : (v >> 24 == 'r') ? "release" : "?", - (v >> 20) & 0x0f, (v >> 16) & 0x0f, v & 0xffff); - - static int tab = 0, index = 0, scroll = 0; - // Set to 1 when interface has to be redrawn. - int leave = 1; - int i; - - mpu = mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5]; - text_configure(NULL, color_black); - - while(1) - { - //--- - // Displaying the current tab. - //--- - - dclear(); - - switch(tab) - { - case 0: - print(1, 1, "gint %s", gint_version); - print(2, 3, "MPU type %7s", mpu); - print(2, 4, "Add-in size %3dk", - ((uint32_t)&romdata - 0x00300000) >> 10); - print(2, 5, "gint size %5do", gint_size); - - list = NULL; - break; - - case 1: - locate(1, 1, "Test list"); - list = list_tests; - break; -/* - case 2: - locate(1, 1, "Performance"); - list = list_perfs; - break; -*/ - default: - print(1, 1, "Tab %d", tab); - break; - } - dimage_part(0, 56, &res_opt_menu, 0, 0, 42, 8); - - if(list) - { - list_len = 0; - while(list[list_len]) list_len++; - - for(i = scroll; list[i] && i < scroll + 6; i++) - locate(2, i - scroll + 2, list[i]); - - if(scroll > 0) locate(20, 2, "\x0d"); - if(scroll + 6 < list_len) locate(20, 7, "\x0e"); - - drect(0, 8 * (index - scroll) + 8, 127, - 8 * (index - scroll) + 15, color_invert); - } - - dupdate(); - - //--- - // Waiting for events. - //--- - - do - { - leave = 1; - - switch(getkey()) - { - case KEY_F1: - if(!tab) break; - tab = 0; - index = 0; - break; - case KEY_F2: - if(tab == 1) break; - tab = 1; - index = 0; - scroll = 0; - break; -/* case KEY_F3: - *category = 2; - *app = 1; - return; -*/ -/* case KEY_F3: - if(tab == 2) break; - tab = 2; - index = 0; - scroll = 0; - break; -*/ - case KEY_UP: - if(list && list_len > 1) - { - if(index) - { - index--; - if(index < scroll) scroll--; - } - else - { - index = list_len - 1; - scroll = list_len - 6; - if(scroll < 0) scroll = 0; - } - } - else leave = 0; - break; - case KEY_DOWN: - if(list && list_len > 1) - { - if(list[index + 1]) - { - index++; - if(index >= scroll + 6) - scroll++; - } - else - { - index = 0; - scroll = 0; - } - } - else leave = 0; - break; - - case KEY_EXE: - if(!tab) break; - if(category) *category = tab; - if(app) *app = index + 1; - return; - - default: - leave = 0; - } - } - while(!leave); - } - - if(category) *category = 0; - if(app) *app = 0; - return; -} - -/* - main() - No need for description. -*/ -int main(void) -{ - int category, app; - - while(1) - { - main_menu(&category, &app); - if(!category) break; - - switch((category << 8) | app) - { - case 0x0101: test_keyboard_events(); break; - case 0x0102: test_gray(); break; - case 0x0103: test_bopti(); break; - case 0x0104: test_tales(); break; - case 0x0105: test_rtc(); break; - case 0x0106: test_timer(); break; - - case 0x0201: perf_bopti(); break; - case 0x0202: /* perf_tales(); */ break; - } - } - - return 0; -} - -/* -#include -void screen(void) -{ - const uint8_t bmp_header[0x7e] = { - 0x42, 0x4d, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6c, 0x00, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x13, 0x0b, - 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x47, - 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, - }; - const uint16_t file[] = { '\\', '\\', 'f', 'l', 's', '0', '\\', 'g', - 's', 'c', 'r', 'e', 'e', 'n', '.', 'b', 'm', 'p', 0x00 }; - int size = 0x7e + 1024; - - BFile_Remove(file); - BFile_Create(file, BFile_File, &size); - int handle = BFile_Open(file, BFile_WriteOnly); - BFile_Write(handle, bmp_header, 0x7e); - void *vram = (void *)display_getCurrentVRAM() + 1024; - for(int i = 1; i <= 64; i++) - { - BFile_Write(handle, vram - 16 * i, 16); - } - BFile_Close(handle); -} -void screengray(void) -{ - const uint8_t bmp_header[0x7e] = { - 0x42, 0x4d, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6c, 0x00, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x13, 0x0b, - 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x47, - 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, - }; - uint16_t file[] = { '\\', '\\', 'f', 'l', 's', '0', '\\', 'g', 's', - 'c', 'r', 'e', 'e', 'n', '#', '.', 'b', 'm', 'p', 0x00 }; - int size = 0x7e + 1024; - void *vram; - int handle; - - gupdate(); - - file[14] = 'l'; - BFile_Remove(file); - BFile_Create(file, BFile_File, &size); - handle = BFile_Open(file, BFile_WriteOnly); - BFile_Write(handle, bmp_header, 0x7e); - vram = (void *)gray_lightVRAM() + 1024; - for(int i = 1; i <= 64; i++) - { - BFile_Write(handle, vram - 16 * i, 16); - } - BFile_Close(handle); - - file[14] = 'd'; - BFile_Remove(file); - BFile_Create(file, BFile_File, &size); - handle = BFile_Open(file, BFile_WriteOnly); - BFile_Write(handle, bmp_header, 0x7e); - vram = (void *)gray_darkVRAM() + 1024; - for(int i = 1; i <= 64; i++) - { - BFile_Write(handle, vram - 16 * i, 16); - } - BFile_Close(handle); - - gupdate(); -} -*/ diff --git a/demo/gintdemo.h b/demo/gintdemo.h deleted file mode 100644 index 2b4fc24..0000000 --- a/demo/gintdemo.h +++ /dev/null @@ -1,114 +0,0 @@ -//--- -// -// gint demo application -// -// Displays some tests cases for many features of the library. -// -//--- - -#ifndef _GINTDEMO_H -#define _GINTDEMO_H - -//--- -// Main routines and common functions. -//--- - -/* - main() - No need for description. -*/ -int main(void); - -/* - main_menu() - Displays the main menu and returns user's choice by setting the - category and application. Category is 0 when the user leaves the - application. -*/ -void main_menu(int *category, int *app); - -/* - locate() - Displays text using a system-like monospaced font on a 21*8 grid. -*/ -void locate(int x, int y, const char *str); - -/* - print() - Locates a string using formatted printing. -*/ -void print(int x, int y, const char *format, ...); - - - -//--- -// Test applications. -//--- - -/* - test_keyboard_events() - Real-time keyboard management with events. -*/ -void test_keyboard_events(void); - -/* - test_gray() - Lets the user set the gray delays and see the results. -*/ -void test_gray(void); - -/* - test_bopti() - Displays and moves many kinds of bitmaps. -*/ -void test_bopti(void); - -/* - test_tales() - Displays some text using different modes and clipping options. -*/ -void test_tales(void); - -/* - test_rtc() - Just a clock. -*/ -void test_rtc(void); - -/* - test_timer() - Clock timer and timer precision. -*/ -void test_timer(void); - - - -//--- -// Performance applications. -//--- - -/* - perf_bopti() - Compares bopti and MonochromeLib. -*/ -void perf_bopti(void); - -/* - perf_tales() - Compares tales and the system's text rendering functions. -*/ -void perf_tales(void); - - - -//--- -// Debug applications. -//--- - -/* - debug_tlb() - On SH7705, displays the TLB contents. Does nothing on SH7305. -*/ -void debug_tlb(void); - -#endif // _GINTDEMO_H diff --git a/demo/gintdemo.ld b/demo/gintdemo.ld deleted file mode 100644 index 5df3f76..0000000 --- a/demo/gintdemo.ld +++ /dev/null @@ -1,113 +0,0 @@ -/* - This linker script links the object files when generating the ELF - output. Note how symbols romdata, bbss, ebss, bdata and edata are used - in the initialization routine (crt0.c) to initialize the application. - - Two ram areas are specified. The "real ram" is accessed directly while - the other area is virtualized. It is not possible to execute code in - virtualized ram. -*/ - -OUTPUT_ARCH(sh3) -ENTRY(_start) - -MEMORY -{ - /* System-managed mappings map this area into the add-in data */ - rom : o = 0x00300200, l = 512k - /* 0x0810000 is apparently mapped to 0x8801c0000 */ - ram : o = 0x08100000, l = 8k - /* RAM section from P1 area, no MMU involved */ - realram : o = 0x8800d000, l = 12k -} - -SECTIONS -{ - /* ROM sections: binary code and read-only data */ - - .text : { - /* Initialization code. */ - *(.pretext.entry) - *(.pretext) - - _bctors = ABSOLUTE(.); - *(.ctors) - _ectors = ABSOLUTE(.); - _bdtors = ABSOLUTE(.); - *(.dtors) - _edtors = ABSOLUTE(.); - - *(.text) - *(.text.*) - } > rom - - .rodata : { - *(.rodata.fxconv); - *(.rodata.paradox); - *(.rodata) - . = ALIGN(4); - *(.rodata.*) - - _romdata = ALIGN(4) ; - } > rom - - /* RAM sections: bss section and read/write data - The .bss section is to be stripped from the ELF file and wiped at - startup, hence its location is undefined */ - - .bss : { - _bbss = ABSOLUTE(.); - _sbss = ABSOLUTE(SIZEOF(.bss)); - - *(.bss) - } > ram - - .data : AT(_romdata) ALIGN(4) { - _bdata = ABSOLUTE(.); - _sdata = ABSOLUTE(SIZEOF(.data)); - - *(.data) - *(.data.*) - } > ram - - .cc : AT(_romdata + SIZEOF(.data)) ALIGN(4) { - *(.eh_frame) - *(.jcr) - - . = ALIGN(4); - } > ram - - /* Real RAM sections: interrupt handlers and some *uninitialized* gint - data */ - - _gint_data = _romdata + SIZEOF(.data) + SIZEOF(.cc) ; - - .gint : AT(_gint_data) ALIGN(4) { - /* The vbr needs to be 0x100-aligned because of an ld issue */ - . = ALIGN(0x100) ; - - _gint_vbr = . ; - _bgint = ABSOLUTE(.) ; - - /* Exception handler */ - . = _gint_vbr + 0x100 ; - *(.gint.exc) - - /* TLB miss handler */ - . = _gint_vbr + 0x400 ; - *(.gint.tlb) - - /* Interrupt handler */ - . = _gint_vbr + 0x600 ; - *(.gint.int) - - . = ALIGN(4); - _egint = ABSOLUTE(.) ; - } > realram - - .gint_bss : AT(_gint_data + SIZEOF(.gint)) ALIGN(4) { - _bgbss = ABSOLUTE(.) ; - *(.gint.bss) - _egbss = ABSOLUTE(.) ; - } > realram -} diff --git a/demo/icon.bmp b/demo/icon.bmp deleted file mode 100644 index 27f0e48..0000000 Binary files a/demo/icon.bmp and /dev/null differ diff --git a/demo/perf_bopti.c b/demo/perf_bopti.c deleted file mode 100644 index 94a9907..0000000 --- a/demo/perf_bopti.c +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include -#include -#include -#include - -/* -static const uint8_t screen[1024] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 7, 159, 0, 0, 1, 192, 0, 0, 0, 0, 0, 121, 240, 0, 0, 0, -31, 191, 192, 0, 3, 224, 27, 216, 0, 0, 1, 251, 252, 0, 0, 0, 57, 247, 222, -30, 7, 240, 36, 36, 62, 25, 131, 159, 24, 255, 129, 224, 0, 227, 142, 126, 1, -192, 45, 172, 127, 127, 192, 14, 1, 255, 199, 224, 0, 227, 140, 240, 1, 192, -26, 88, 115, 127, 224, 14, 57, 221, 207, 0, 0, 227, 13, 192, 1, 192, 34, 68, -120, 30, 0, 14, 25, 156, 220, 0, 0, 227, 253, 252, 1, 192, 36, 36, 126, 28, -0, 14, 219, 156, 223, 192, 0, 227, 253, 252, 1, 192, 36, 36, 31, 12, 0, 46, -27, 140, 223, 192, 0, 227, 141, 193, 193, 192, 40, 20, 7, 140, 0, 206, 25, 140, -220, 28, 0, 227, 140, 225, 129, 199, 24, 24, 99, 156, 1, 14, 25, 204, 206, 24, -0, 227, 142, 127, 1, 195, 39, 228, 255, 156, 2, 14, 24, 237, 199, 240, 1, 247, -222, 62, 1, 198, 44, 44, 223, 30, 2, 31, 28, 237, 131, 224, 1, 224, 0, 0, 3, -254, 27, 216, 0, 0, 4, 30, 0, 0, 0, 0, 3, 192, 0, 0, 7, 252, 0, 0, 0, 0, 4, -60, 1, 249, 240, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 4, 0, 97, 240, 56, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 224, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 47, 192, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 255, 128, 63, 128, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 32, 255, 0, 48, 78, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 15, 176, 255, 0, 112, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 56, 255, 0, -96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 8, 60, 255, 0, 224, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 130, 56, 126, 255, 3, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 192, -62, 255, 15, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 191, 255, 192, 0, -0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 6, 129, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 6, 0, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 128, 63, 192, -0, 0, 96, 1, 224, 1, 0, 0, 0, 2, 0, 0, 7, 0, 31, 192, 0, 0, 95, 1, 11, 68, 88, -0, 0, 4, 0, 0, 7, 128, 31, 192, 0, 1, 192, 129, 204, 85, 100, 0, 0, 8, 0, 0, -15, 128, 63, 224, 0, 0, 95, 1, 8, 85, 68, 0, 1, 144, 0, 0, 31, 128, 143, 224, -64, 0, 96, 1, 232, 41, 68, 0, 2, 96, 0, 31, 255, 129, 7, 248, 96, 0, 0, 0, 0, -0, 0, 0, 4, 0, 0, 96, 254, 129, 7, 254, 96, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 128, -254, 131, 135, 255, 224, 0, 0, 1, 192, 64, 16, 0, 8, 0, 7, 0, 254, 131, 255, -63, 224, 0, 0, 1, 38, 113, 208, 0, 8, 0, 13, 0, 222, 147, 254, 31, 224, 0, 0, -1, 41, 74, 80, 0, 8, 0, 25, 0, 222, 67, 254, 31, 160, 0, 0, 1, 41, 74, 80, 0, -12, 0, 49, 0, 222, 19, 254, 62, 48, 0, 0, 1, 198, 113, 208, 0, 2, 0, 32, 128, -222, 195, 255, 252, 56, 0, 0, 0, 0, 0, 0, 0, 2, 0, 124, 64, 220, 151, 135, 248, -127, 0, 0, 0, 0, 0, 0, 0, 2, 0, 66, 32, 221, 223, 7, 240, 255, 0, 0, 0, 0, 0, -0, 0, 2, 0, 129, 23, 93, 159, 15, 241, 131, 0, 0, 0, 0, 0, 0, 0, 4, 0, 128, -136, 217, 95, 3, 226, 9, 0, 0, 1, 240, 0, 0, 0, 4, 0, 128, 72, 89, 95, 129, -228, 18, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 72, 73, 127, 128, 224, 36, 0, 0, 0, 0, -0, 0, 0, 28, 1, 0, 76, 129, 127, 192, 96, 8, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, -231, 203, 124, 96, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 1, 28, 123, 240, 12, 64, -1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 2, 28, 143, 128, 15, 192, 7, 0, 0, 0, 0, 0, 0, -0, 16, 1, 4, 17, 143, 24, 15, 192, 14, 0, 0, 0, 0, 0, 0, 0, 28, 1, 4, 1, 135, -24, 31, 192, 24, 0, 0, 0, 0, 0, 0, 0, 18, 1, 62, 1, 135, 248, 63, 224, 192, -0, 0, 0, 0, 0, 0, 0, 35, 1, 195, 1, 135, 128, 254, 126, 1, 0, 0, 0, 0, 0, 0, -0, 35, 193, 131, 195, 135, 255, 248, 112, 1, 0, 0, 0, 0, 0, 0, 0, 67, 241, 131, -14, 207, 255, 192, 224, 3, 0, 0, 0, 0, 0, 0, 3, 67, 15, 143, 56, 255, 7, 1, -224, 7, 0, 0, 0, 0, 0, 0, 28, 130, 7, 255, 112, 204, 7, 131, 224, 31, 0, 0, -0, 0, 0, 0, 32, 134, 30, 29, 120, 156, 7, 255, 224, 127, 0, 0, 0, 0, 0, 63, -197, 206, 60, 56, 192, 248, 15, 255, 248, 255, 0, 0, 0, 0, 0, 120, 5, 227, 248, -56, 195, 248, 127, 191, 254, 63, 0, 0, 0, 0, 7, 254, 255, 193, 255, 15, 193, -255, 15, 31, 252, 31 }; -*/ - -static const uint8_t town[4464] = { 4, 0, 0, 16, 2, 115, 130, 6, 243, 130, 6, 243, 130, 6, 243, 130, 4, 0, 0, 16, 2, 115, 130, 6, 243, 130, 6, 243, 130, 6, 243, 130, 4, 0, 0, 16, 255, 255, 255, 240, 3, 255, 198, 15, 127, 198, 15, 127, 198, 15, 127, 198, 255, 255, 255, 240, 3, 255, 198, 15, 127, 198, 15, 127, 198, 15, 127, 198, 255, 255, 255, 240, 0, 144, 3, 192, 0, 112, 255, 30, 112, 255, 30, 112, 255, 30, 112, 255, 0, 144, 3, 192, 0, 112, 255, 30, 112, 255, 30, 112, 255, 30, 112, 255, 0, 144, 3, 192, 0, 144, 2, 192, 15, 240, 195, 255, 240, 195, 255, 240, 195, 255, 240, 195, 0, 144, 2, 192, 15, 240, 195, 255, 240, 195, 255, 240, 195, 255, 240, 195, 0, 144, 2, 192, 0, 144, 2, 64, 112, 15, 129, 240, 15, 129, 240, 15, 129, 240, 15, 129, 0, 144, 2, 64, 112, 15, 129, 240, 15, 129, 240, 15, 129, 240, 15, 129, 0, 144, 2, 64, 0, 208, 3, 64, 128, 1, 193, 128, 1, 193, 128, 1, 193, 128, 1, 193, 0, 208, 3, 64, 128, 1, 193, 128, 1, 193, 128, 1, 193, 128, 1, 193, 0, 208, 3, 64, 255, 223, 255, 67, 0, 0, 227, 0, 0, 227, 0, 0, 227, 0, 0, 227, 255, 223, 255, 67, 0, 0, 227, 0, 0, 227, 0, 0, 227, 0, 0, 227, 255, 223, 255, 64, 112, 195, 129, 194, 0, 0, 126, 0, 0, 126, 0, 0, 126, 0, 0, 126, 112, 195, 129, 194, 0, 0, 126, 0, 0, 126, 0, 0, 126, 0, 0, 126, 112, 195, 129, 192, 247, 255, 254, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 247, 255, 254, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 247, 255, 254, 192, 72, 0, 2, 98, 240, 113, 202, 240, 113, 202, 240, 113, 202, 240, 113, 202, 72, 0, 2, 98, 240, 113, 202, 240, 113, 202, 240, 113, 202, 240, 113, 202, 72, 0, 2, 96, 240, 0, 2, 70, 25, 255, 46, 25, 255, 46, 25, 255, 46, 25, 255, 46, 240, 0, 2, 70, 25, 255, 46, 25, 255, 46, 25, 255, 46, 25, 255, 46, 240, 0, 2, 64, 96, 1, 226, 198, 30, 48, 110, 30, 48, 110, 30, 48, 110, 30, 48, 110, 96, 1, 226, 198, 30, 48, 110, 30, 48, 110, 30, 48, 110, 30, 48, 110, 96, 1, 226, 192, 64, 2, 19, 199, 56, 32, 111, 56, 32, 111, 56, 32, 111, 56, 32, 111, 64, 2, 19, 199, 56, 32, 111, 56, 32, 111, 56, 32, 111, 56, 32, 111, 64, 2, 19, 192, 128, 2, 19, 71, 252, 96, 247, 252, 96, 247, 252, 96, 247, 252, 96, 247, 128, 2, 19, 71, 252, 96, 247, 252, 96, 247, 252, 96, 247, 252, 96, 247, 128, 2, 19, 64, 0, 2, 19, 71, 15, 241, 231, 15, 241, 231, 15, 241, 231, 15, 241, 231, 0, 2, 19, 71, 15, 241, 231, 15, 241, 231, 15, 241, 231, 15, 241, 231, 0, 2, 19, 64, 3, 194, 18, 71, 12, 63, 255, 12, 63, 231, 12, 63, 231, 12, 63, 255, 3, 194, 18, 71, 12, 63, -255, 12, 63, 231, 12, 63, 231, 12, 63, 255, 3, 194, 18, 64, 6, 99, 242, 195, 152, 31, 0, 248, 31, 195, 152, 31, 195, 152, 31, 0, 6, 99, 242, 195, 152, 31, 0, 248, 31, 195, 152, 31, 195, 152, 31, 0, 6, 99, 242, 192, 10, 84, 10, 193, 252, 24, 0, 28, 31, 129, 252, 31, 129, 252, 24, 0, 10, 84, 10, 193, 252, 24, 0, 28, 31, 129, 252, 31, 129, 252, 24, 0, 10, 84, 10, 192, 10, 87, 251, 192, 126, 48, 0, 14, 62, 0, 126, 62, 0, 126, 48, 0, 10, 87, 251, 192, 126, 48, 0, 14, 62, 0, 126, 62, 0, 126, 48, 0, 10, 87, 251, 192, 10, 80, 3, 192, 31, 224, 0, 7, 252, 3, 255, 255, 255, 255, 224, 0, 10, 80, 3, 192, 31, 224, 0, 7, 252, 3, 255, 255, 255, 255, 224, 0, 10, 80, 3, 192, 10, 208, 3, 64, 12, 56, 0, 12, 32, 6, 16, 64, 0, 2, 56, 0, 10, 208, 3, 64, 12, 56, 0, 12, 32, 6, 16, 64, 0, 2, 56, 0, 10, 208, 3, 64, 250, 95, 254, 64, 56, 175, 7, 28, 144, 7, 255, 252, 0, 2, 175, 7, 250, 95, 254, 64, 56, 175, 7, 28, 144, 7, 255, 252, 0, 2, 175, 7, 250, 95, 254, 64, 106, 86, 219, 64, 34, 225, 159, 242, 200, 4, 130, 8, 0, 2, 225, 159, 106, 86, 219, 64, 34, 225, 159, 242, 200, 4, 130, 8, 0, 2, 225, 159, 106, 86, 219, 64, 10, 80, 3, 64, 62, 225, 227, 6, 228, 15, 255, 240, 0, 1, 225, 227, 10, 80, 3, 64, 62, 225, 227, 6, 228, 15, 255, 240, 0, 1, 225, 227, 10, 80, 3, 64, 255, 255, 255, 192, 4, 243, 130, 6, 156, 10, 16, 64, 0, 1, 243, 130, 255, 255, 255, 192, 4, 243, 130, 6, 156, 10, 16, 64, 0, 1, 243, 130, 255, 255, 255, 192, 0, 0, 3, 192, 7, 127, 198, 15, 0, 15, 255, 255, 255, 255, 127, 198, 0, 0, 3, 192, 7, 127, 198, 15, 0, 15, 255, 255, 255, 255, 127, 198, 0, 0, 3, 192, 0, 0, 0, 0, 0, 112, 255, 30, 0, 3, 192, 0, 0, 60, 112, 255, 0, 0, 0, 0, 0, 112, 255, 30, 0, 3, 192, 0, 0, 60, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 195, 254, 0, 2, 198, 0, 220, 44, 112, 195, 0, 0, 0, 0, 0, 112, 195, 254, 0, 2, 198, 0, 220, 44, 112, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 129, 252, 0, 2, 69, 0, 168, 36, 57, 129, 0, 0, 0, 0, 0, 57, 129, 252, 0, 2, 69, 0, 168, 36, 57, 129, 0, 0, 0, 0, 0, 0, 0, 0, 128, 31, 193, 248, 0, 3, 117, 62, 87, 244, 31, 193, 0, 0, 0, 0, 128, 31, 193, 248, 0, 3, 117, 62, 87, 244, 31, 193, 0, 0, 0, 0, 0, 0, 0, 2, 160, 7, 227, 224, 0, 3, 72, 128, 168, 52, 7, 227, 0, 0, 0, 2, 160, 7, 227, 224, 0, 3, 72, 128, 168, 52, 7, 227, 0, 0, 0, 0, 0, 0, 0, 1, 64, 1, 255, 192, 0, 3, 232, 246, 245, 252, 1, 254, 0, 0, 0, 1, 64, 1, 255, 192, 0, 3, 232, 246, 245, 252, 1, 254, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 194, 0, 16, 2, 199, 40, 138, 44, 0, 195, 0, 0, 0, 128, 0, 0, 194, 0, 16, 2, 199, 40, 138, 44, 0, 195, 0, 0, 0, 128, 0, 0, 2, 160, 0, 3, 137, 0, 40, 2, 64, 24, 6, 36, 3, 138, 0, 0, 2, 160, 0, 3, 137, 0, 40, 2, 64, 24, 6, 36, 3, 138, 0, 0, 2, 160, 0, 0, 1, 64, 0, 2, 44, 128, 40, 2, 64, 0, 0, 36, 2, 46, 0, 0, 1, 64, 0, 2, 44, 128, 40, 2, 64, 0, 0, 36, 2, 46, 0, 0, 1, 64, 0, 0, 0, 0, 0, 3, 238, 64, 68, 2, 192, 0, 0, 44, 3, 238, 0, 0, 0, 0, 0, 3, 238, 64, 68, 2, 192, 0, 0, 44, 3, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 192, 68, 3, 192, 63, 192, 60, 0, 79, 0, 0, 0, 0, 0, 0, 73, 192, 68, 3, 192, 63, 192, 60, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 56, 3, 64, 124, 32, 52, 0, 119, 0, 0, 0, 0, 0, 0, 112, 0, 56, 3, 64, 124, 32, 52, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 64, 80, 32, 52, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 64, 80, 32, 52, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 64, 248, 16, 36, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 64, 248, 16, 36, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 192, 192, 16, 44, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 192, 192, 16, 44, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 192, 255, 240, 44, 8, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 192, 255, 240, 44, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 3, 192, 41, 64, 60, 48, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 3, 192, 41, 64, 60, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 3, 192, 41, 64, 60, 32, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 3, 192, 41, 64, 60, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 16, 3, 64, 47, 64, 52, 56, 0, 0, 0, 0, 0, 8, 0, 0, 8, 16, 3, 64, 47, 64, 52, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 42, 40, 2, 127, 224, 127, 230, 47, 7, 0, 0, 0, 0, 42, 0, 0, 42, 40, 2, 127, 224, 127, 230, 47, 7, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 20, 40, 3, 118, 227, 109, 180, 97, 159, 0, 0, 0, 0, 20, 0, 0, 20, 40, 3, 118, 227, 109, 180, 97, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 3, 64, 32, 64, 52, 97, 227, 0, 0, 0, 0, 0, 0, 0, 0, 68, 3, 64, 32, 64, 52, 97, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 3, 255, 255, 255, 252, 115, 130, 0, 0, 0, 0, 0, 0, 0, 0, 124, 3, 255, 255, 255, 252, 115, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 192, 0, 0, 60, 127, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 192, 0, 0, 60, 127, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 132, 0, 0, 112, 195, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 132, 0, 0, 112, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 126, 0, 0, 120, 0, 0, 57, 129, 0, 0, 0, 0, 0, 0, 0, 40, 126, 0, 0, 120, 0, 0, 57, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 252, 0, 0, 3, 240, 0, 31, 193, 0, 0, 0, 0, 0, 0, 0, 43, 252, 0, 0, 3, 240, 0, 31, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 134, 0, 0, 2, 16, 0, 7, 227, 0, 0, 0, 0, 0, 0, 0, 21, 134, 0, 0, 2, 16, 0, 7, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 6, 0, 0, 1, 224, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 23, 6, 0, 0, 1, 224, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 62, 0, 0, 252, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 15, 62, 0, 0, 252, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 250, 0, 0, 132, 0, 0, 3, 138, 0, 0, 0, 0, 0, 0, 0, 14, 250, 0, 0, 132, 0, 0, 3, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 190, 0, 0, 120, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 6, 190, 0, 0, 120, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 156, 0, 0, 3, 240, 0, 3, 238, 0, 0, 0, 0, 0, 0, 0, 3, 156, 0, 0, 3, 240, 0, 3, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 36, 0, 0, 2, 16, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 1, 36, 0, 0, 2, 16, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 1, 224, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 1, 224, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 4, 0, 0, 16, 2, 115, 130, 6, 243, 130, 6, 243, 130, 6, 243, 130, 4, 0, 0, 16, 2, 115, 130, 6, 243, 130, 6, 243, 130, 6, 243, 130, 4, 0, 0, 16, 255, 255, 255, 240, 3, 255, 198, 15, 127, 198, 15, 127, 198, 15, 127, 198, 255, 255, 255, 240, 3, 255, 198, 15, 127, 198, 15, 127, 198, 15, 127, 198, 255, 255, 255, 240, 0, 144, 3, 192, 0, 112, 255, 30, 112, 255, 30, 112, 255, 30, 112, 255, 0, 144, 3, 192, 0, 112, 255, 30, 112, 255, 30, 112, 255, 30, 112, 255, 0, 144, 3, 192, 0, 144, 2, 192, 15, 240, 195, 255, 240, 195, 255, 240, 195, 255, 240, 195, 0, 144, 2, 192, 15, 240, 195, 255, 240, 195, 255, 240, 195, 255, 240, 195, 0, 144, 2, 192, 0, 144, 2, 64, 112, 15, 129, 240, 15, 129, 240, 15, 129, 240, 15, 129, 0, 144, 2, 64, 112, 15, 129, 240, 15, 129, 240, 15, 129, 240, 15, 129, 0, 144, 2, 64, 0, 208, 3, 64, 128, 1, 193, 128, 1, 193, 128, 1, 193, 128, 1, 193, 0, 208, 3, 64, 128, 1, 193, 128, 1, 193, 128, 1, 193, 128, 1, 193, 0, 208, 3, 64, 255, 223, 255, 67, 0, 0, 227, 0, 0, 227, 0, 0, 227, 0, 0, 227, 255, 223, 255, 67, 0, 0, 227, 0, 0, 227, 0, 0, 227, 0, 0, 227, 255, 223, 255, 64, 112, 195, 129, 194, 0, 0, 126, 0, 0, 126, 0, 0, 126, 0, 0, 126, 112, 195, 129, 194, 0, 0, 126, 0, 0, 126, 0, 0, 126, 0, 0, 126, 112, 195, 129, 192, 247, 255, 254, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 247, 255, 254, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 128, 0, 195, 247, 255, 254, 192, 72, 0, 2, 98, 240, 113, 202, 240, 113, 202, 240, 113, 202, 240, 113, 202, 72, 0, 2, 98, 240, 113, 202, 240, 113, 202, 240, 113, 202, 240, 113, 202, 72, 0, 2, 96, 240, 0, 2, 70, 25, 255, 46, 25, 255, 46, 25, 255, 46, 25, 255, 46, 240, 0, 2, 70, 25, 255, 46, 25, 255, 46, 25, 255, 46, 25, 255, 46, 240, 0, 2, 64, 96, 1, 226, 198, 30, 48, 110, 30, 48, 110, 30, 48, 110, 30, 48, 110, 96, 1, 226, 198, 30, 48, 110, 30, 48, 110, 30, 48, 110, 30, 48, 110, 96, 1, 226, 192, 64, 2, 19, 199, 56, 32, 111, 56, 32, 111, 56, 32, 111, 56, 32, 111, 64, 2, 19, 199, 56, 32, 111, 56, 32, 111, 56, 32, 111, 56, 32, 111, 64, 2, 19, 192, 128, 2, 19, 71, 252, 96, 247, 252, 96, 247, 252, 96, 247, 252, 96, 247, 128, 2, 19, 71, 252, 96, 247, 252, 96, 247, 252, 96, 247, 252, 96, 247, 128, 2, 19, 64, 0, 2, 19, 71, 15, 241, 231, 15, 241, 231, 15, 241, 231, 15, 241, 231, 0, 2, 19, 71, 15, 241, 231, 15, 241, 231, 15, 241, 231, 15, 241, 231, 0, 2, 19, 64, 3, 194, 18, 71, 12, 63, 255, 12, 63, 231, 12, 63, 231, 12, 63, 255, 3, 194, 18, 71, 12, 63, 255, 12, 63, 231, 12, 63, 231, 12, 63, 255, 3, 194, 18, 64, 6, 99, 242, 195, 152, 31, 0, 248, 31, 195, 152, 31, 195, 152, 31, 0, 6, 99, 242, 195, 152, 31, 0, 248, 31, 195, 152, 31, 195, 152, 31, 0, 6, 99, 242, 192, 10, 84, 10, 193, 252, 24, 0, 28, 31, 129, 252, 31, 129, 252, 24, 0, 10, 84, 10, 193, 252, 24, 0, 28, 31, 129, 252, 31, 129, 252, 24, 0, 10, 84, 10, 192, 10, 87, 251, 192, 126, 48, 0, 14, 62, 0, 126, 62, 0, 126, 48, 0, 10, 87, 251, 192, 126, 48, 0, 14, 62, 0, 126, 62, 0, 126, 48, 0, 10, 87, 251, 192, 10, 80, 3, 192, 31, 224, 0, 7, 252, 3, 255, 255, 255, 255, 224, 0, 10, 80, 3, 192, 31, 224, 0, 7, 252, 3, 255, 255, 255, 255, 224, 0, 10, 80, 3, 192, 10, 208, 3, 64, 12, 56, 0, 12, 32, 6, 16, 64, 0, 2, 56, 0, 10, 208, 3, 64, 12, 56, 0, 12, 32, 6, 16, 64, 0, 2, 56, 0, 10, 208, 3, 64, 250, 95, 254, 64, 56, 175, 7, 28, 144, 7, 255, 252, 0, 2, 175, 7, 250, 95, 254, 64, 56, 175, 7, 28, 144, 7, 255, 252, 0, 2, 175, 7, 250, 95, 254, 64, 106, 86, 219, 64, 34, 225, 159, 242, 200, 4, 130, 8, 0, 2, 225, 159, 106, 86, 219, 64, 34, 225, 159, 242, 200, 4, 130, 8, 0, 2, 225, 159, 106, 86, 219, 64, 10, 80, 3, 64, 62, 225, 227, 6, 228, 15, 255, 240, 0, 1, 225, 227, 10, 80, 3, 64, 62, 225, 227, 6, 228, 15, 255, 240, 0, 1, 225, 227, 10, 80, 3, 64, 255, 255, 255, 192, 4, 243, 130, 6, 156, 10, 16, 64, 0, 1, 243, 130, 255, 255, 255, 192, 4, 243, 130, 6, 156, 10, 16, 64, 0, 1, 243, 130, 255, 255, 255, 192, 0, 0, 3, 192, 7, 127, 198, 15, 0, 15, 255, 255, 255, 255, 127, 198, 0, 0, 3, 192, 7, 127, 198, 15, 0, 15, 255, 255, 255, 255, 127, 198, 0, 0, 3, 192, 0, 0, 0, 0, 0, 112, 255, 30, 0, 3, 192, 0, 0, 60, 112, 255, 0, 0, 0, 0, 0, 112, 255, 30, 0, 3, 192, 0, 0, 60, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 195, 254, 0, 2, 198, 0, 220, 44, 112, 195, 0, 0, 0, 0, 0, 112, 195, 254, 0, 2, 198, 0, 220, 44, 112, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 129, 252, 0, 2, 69, 0, 168, 36, 57, 129, 0, 0, 0, 0, 0, 57, 129, 252, 0, 2, 69, 0, 168, 36, 57, 129, 0, 0, 0, 0, 0, 0, 0, 0, 128, 31, 193, 248, 0, 3, 117, 62, 87, 244, 31, 193, 0, 0, 0, 0, 128, 31, 193, 248, 0, 3, 117, 62, 87, 244, 31, 193, 0, 0, 0, 0, 0, 0, 0, 2, 160, 7, 227, 224, 0, 3, 72, 128, 168, 52, 7, 227, 0, 0, 0, 2, 160, 7, 227, 224, 0, 3, 72, 128, 168, 52, 7, 227, 0, 0, 0, 0, 0, 0, 0, 1, 64, 1, 255, 192, 0, 3, 232, 246, 245, 252, 1, 254, 0, 0, 0, 1, 64, 1, 255, 192, 0, 3, 232, 246, 245, 252, 1, 254, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 194, 0, 16, 2, 199, 40, 138, 44, 0, 195, 0, 0, 0, 128, 0, 0, 194, 0, 16, 2, 199, 40, 138, 44, 0, 195, 0, 0, 0, 128, 0, 0, 2, 160, 0, 3, 137, 0, 40, 2, 64, 24, 6, 36, 3, 138, 0, 0, 2, 160, 0, 3, 137, 0, 40, 2, 64, 24, 6, 36, 3, 138, 0, 0, 2, 160, 0, 0, 1, 64, 0, 2, 44, 128, 40, 2, 64, 0, 0, 36, 2, 46, 0, 0, 1, 64, 0, 2, 44, 128, 40, 2, 64, 0, 0, 36, 2, 46, 0, 0, 1, 64, 0, 0, 0, 0, 0, 3, 238, 64, 68, 2, 192, 0, 0, 44, 3, 238, 0, 0, 0, 0, 0, 3, 238, 64, 68, 2, 192, 0, 0, 44, 3, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 192, 68, 3, 192, 63, 192, 60, 0, 79, 0, 0, 0, 0, 0, 0, 73, 192, 68, 3, 192, 63, 192, 60, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 56, 3, 64, 124, 32, 52, 0, 119, 0, 0, 0, 0, 0, 0, 112, 0, 56, 3, 64, 124, 32, 52, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 64, 80, 32, 52, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 64, 80, 32, 52, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 64, 248, 16, 36, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 64, 248, 16, 36, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 192, 192, 16, 44, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 192, 192, 16, 44, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 192, 255, 240, 44, 8, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 192, 255, 240, 44, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 3, 192, 41, 64, 60, 48, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 3, 192, 41, 64, 60, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 3, 192, 41, 64, 60, 32, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 3, 192, 41, 64, 60, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 16, 3, 64, 47, 64, 52, 56, 0, 0, 0, 0, 0, 8, 0, 0, 8, 16, 3, 64, 47, 64, 52, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 42, 40, 2, 127, 224, 127, 230, 47, 7, 0, 0, 0, 0, 42, 0, 0, 42, 40, 2, 127, 224, 127, 230, 47, 7, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 20, 40, 3, 118, 227, 109, 180, 97, 159, 0, 0, 0, 0, 20, 0, 0, 20, 40, 3, 118, 227, 109, 180, 97, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 3, 64, 32, 64, 52, 97, 227, 0, 0, 0, 0, 0, 0, 0, 0, 68, 3, 64, 32, 64, 52, 97, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 3, 255, 255, 255, 252, 115, 130, 0, 0, 0, 0, 0, 0, 0, 0, 124, 3, 255, 255, 255, 252, 115, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 192, 0, 0, 60, 127, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 192, 0, 0, 60, 127, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 112, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 132, 0, 0, 112, 195, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 132, 0, 0, 112, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 126, 0, 0, 120, 0, 0, 57, 129, 0, 0, 0, 0, 0, 0, 0, 40, 126, 0, 0, 120, 0, 0, 57, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 252, 0, 0, 3, 240, 0, 31, 193, 0, 0, 0, 0, 0, 0, 0, 43, 252, 0, 0, 3, 240, 0, 31, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 134, 0, 0, 2, 16, 0, 7, 227, 0, 0, 0, 0, 0, 0, 0, 21, 134, 0, 0, 2, 16, 0, 7, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 6, 0, 0, 1, 224, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 23, 6, 0, 0, 1, 224, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 62, 0, 0, 252, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 15, 62, 0, 0, 252, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 250, 0, 0, 132, 0, 0, 3, 138, 0, 0, 0, 0, 0, 0, 0, 14, 250, 0, 0, 132, 0, 0, 3, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 190, 0, 0, 120, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 6, 190, 0, 0, 120, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 156, 0, 0, 3, 240, 0, 3, 238, 0, 0, 0, 0, 0, 0, 0, 3, 156, 0, 0, 3, 240, 0, 3, 238, 0, 0, 0, 0 }; - -static const uint8_t screen[460] = { 0, 0, 0, 2, 0, 23, 224, 15, 0, 0, 0, 0, 0, 2, 16, 127, 192, 31, 192, 0, 0, 0, 0, 1, 144, 127, 128, 24, 39, 0, 0, 0, 0, 7, 216, 127, 128, 56, 24, 128, 0, 0, 14, 4, 28, 127, 128, 48, 0, 0, 0, 0, 49, 4, 30, 127, 128, 112, 0, 0, 0, 0, 65, 28, 63, 127, 129, 240, 0, 0, 0, 0, 128, 224, 31, 127, 135, 240, 0, 0, 0, 1, 0, 0, 7, 95, 255, 224, 0, 0, 0, 1, 0, 0, 3, 64, 255, 224, 0, 0, 0, 0, 128, 0, 3, 0, 127, 224, 0, 0, 0, 0, 128, 0, 3, 192, 31, 224, 0, 0, 0, 1, 0, 0, 3, 128, 15, 224, 0, 0, 0, 2, 0, 0, 3, 192, 15, 224, 0, 0, 0, 4, 0, 0, 7, 192, 31, 240, 0, 0, 0, 200, 0, 0, 15, 192, 71, 240, 32, 0, 1, 48, 0, 15, 255, 192, 131, 252, 48, 0, 2, 0, 0, 48, 127, 64, 131, 255, 48, 0, 2, 0, 0, 192, 127, 65, 195, 255, 240, 0, 4, 0, 3, 128, 127, 65, 255, 159, 240, 0, 4, 0, 6, 128, 111, 73, 255, 15, 240, 0, 4, 0, 12, 128, 111, 33, 255, 15, 208, 0, 6, 0, 24, 128, 111, 9, 255, 31, 24, 0, 1, 0, 16, 64, 111, 97, 255, 254, 28, 0, 1, 0, 62, 32, 110, 75, 195, 252, 63, 128, 1, 0, 33, 16, 110, 239, 131, 248, 127, 128, 1, 0, 64, 139, 174, 207, 135, 248, 193, 128, 2, 0, 64, 68, 108, 175, 129, 241, 4, 128, 2, 0, 64, 36, 44, 175, 192, 242, 9, 0, 2, 0, 128, 36, 36, 191, 192, 112, 18, 0, 14, 0, 128, 38, 64, 191, 224, 48, 4, 0, 8, 0, 128, 115, 229, 190, 48, 32, 0, 0, 8, 0, 128, 142, 61, 248, 6, 32, 0, 128, 8, 0, 129, 14, 71, 192, 7, 224, 3, 128, 8, 0, 130, 8, 199, 140, 7, 224, 7, 0, 14, 0, 130, 0, 195, 140, 15, 224, 12, 0, 9, 0, 159, 0, 195, 252, 31, 240, 96, 0, 17, 128, 225, 128, 195, 192, 127, 63, 0, 128, 17, 224, 193, 225, 195, 255, 252, 56, 0, 128, 33, 248, 193, 135, 103, 255, 224, 112, 1, 128, 161, 135, 199, 156, 127, 131, 128, 240, 3, 128, 65, 3, 255, 184, 102, 3, 193, 240, 15, 128, 67, 15, 14, 188, 78, 3, 255, 240, 63, 128, 231, 30, 28, 96, 124, 7, 255, 252, 127, 128, 241, 252, 28, 97, 252, 63, 223, 255, 31, 128, 224, 255, 135, 224, 255, 135, 143, 254, 15, 128 }; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wparentheses" -#pragma GCC diagnostic ignored "-Wshift-negative-value" -#pragma GCC push_options -#pragma GCC optimize 0 - -#define ML_vram_adress display_getCurrentVRAM -__attribute__((optimize("0"))) -void ML_bmp_or_cl(const unsigned char *bmp, int x, int y, int width, int height) -{ - uint16_t line; - char shift, *screen; - uint8_t *p; - int i, j, real_width, begin_x, end_x, begin_y, end_y; - int bool1=1, bool2=1, bool3; - if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 - || width<1) return; - p = (uint8_t *)&line; - real_width = (width-1>>3<<3)+8; - if(y < 0) begin_y = -y; - else begin_y = 0; - if(y+height > 64) end_y = 64-y; - else end_y = height; - shift = 8-(x&7); - if(x<0) - { - begin_x = -x>>3; - if(shift != 8) bool1 = 0; - } else begin_x = 0; - if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0; - else end_x = real_width-1>>3; - bool3 = (end_x == real_width-1>>3); - screen = (char *)ML_vram_adress()+(y+begin_y<<4)+(x>>3); - - for(i=begin_y ; i>3)+begin_x] << shift; - if(bool1) screen[begin_x] |= *p; - if(shift!=8) screen[begin_x+1] |= *(p+1); - for(j=begin_x+1 ; j>3)+j] << shift; - screen[j] |= *p; - if(shift!=8) screen[j+1] |= *(p+1); - } - } - line = bmp[i*(real_width>>3)+end_x]; - if(bool3) line &= -1<TCNT; - timer_stop(t); - time1 = 0xffffffff - time1; - - dclear(); - dtext(2, 2, "gint..."); - dupdate(); - - t = htimer_setup(timer_user, 0xffffffff, timer_Po_4, 1); - timer_start(t); - for(i = 0; i < 1000; i++) dimage(x, y, img); - time2 = TMU.timers[timer_user]->TCNT; - timer_stop(t); - time2 = 0xffffffff - time2; - - dclear(); - print(1, 1, " ML: %08x", time1); - print(1, 2, "gint: %08x", time2); - print(1, 3, ">> \x04%d", time1 / time2); - dupdate(); - getkey(); -} diff --git a/demo/resources/bopti_thumbs.bmp b/demo/resources/bopti_thumbs.bmp deleted file mode 100644 index 923b77e..0000000 Binary files a/demo/resources/bopti_thumbs.bmp and /dev/null differ diff --git a/demo/resources/clock_7305.bmp b/demo/resources/clock_7305.bmp deleted file mode 100644 index 6e7170b..0000000 Binary files a/demo/resources/clock_7305.bmp and /dev/null differ diff --git a/demo/resources/clock_7705.bmp b/demo/resources/clock_7705.bmp deleted file mode 100644 index d711160..0000000 Binary files a/demo/resources/clock_7705.bmp and /dev/null differ diff --git a/demo/resources/clock_chars.bmp b/demo/resources/clock_chars.bmp deleted file mode 100644 index 6edc348..0000000 Binary files a/demo/resources/clock_chars.bmp and /dev/null differ diff --git a/demo/resources/font_modern.bmp b/demo/resources/font_modern.bmp deleted file mode 100644 index 1286f30..0000000 Binary files a/demo/resources/font_modern.bmp and /dev/null differ diff --git a/demo/resources/isometric.bmp b/demo/resources/isometric.bmp deleted file mode 100644 index 5241b60..0000000 Binary files a/demo/resources/isometric.bmp and /dev/null differ diff --git a/demo/resources/items.bmp b/demo/resources/items.bmp deleted file mode 100644 index c57f934..0000000 Binary files a/demo/resources/items.bmp and /dev/null differ diff --git a/demo/resources/opt_bitmap.bmp b/demo/resources/opt_bitmap.bmp deleted file mode 100644 index d810717..0000000 Binary files a/demo/resources/opt_bitmap.bmp and /dev/null differ diff --git a/demo/resources/opt_gray.bmp b/demo/resources/opt_gray.bmp deleted file mode 100644 index 80e5c36..0000000 Binary files a/demo/resources/opt_gray.bmp and /dev/null differ diff --git a/demo/resources/opt_menu.bmp b/demo/resources/opt_menu.bmp deleted file mode 100644 index 09fd37d..0000000 Binary files a/demo/resources/opt_menu.bmp and /dev/null differ diff --git a/demo/resources/opt_rtc.bmp b/demo/resources/opt_rtc.bmp deleted file mode 100644 index 7fdd764..0000000 Binary files a/demo/resources/opt_rtc.bmp and /dev/null differ diff --git a/demo/resources/opt_tales.bmp b/demo/resources/opt_tales.bmp deleted file mode 100644 index 8f34e47..0000000 Binary files a/demo/resources/opt_tales.bmp and /dev/null differ diff --git a/demo/resources/opt_timer.bmp b/demo/resources/opt_timer.bmp deleted file mode 100644 index 1d7cb9c..0000000 Binary files a/demo/resources/opt_timer.bmp and /dev/null differ diff --git a/demo/resources/rtc_segments.bmp b/demo/resources/rtc_segments.bmp deleted file mode 100644 index 958d83f..0000000 Binary files a/demo/resources/rtc_segments.bmp and /dev/null differ diff --git a/demo/resources/screen.bmp b/demo/resources/screen.bmp deleted file mode 100644 index c6fb2c3..0000000 Binary files a/demo/resources/screen.bmp and /dev/null differ diff --git a/demo/resources/sprites.bmp b/demo/resources/sprites.bmp deleted file mode 100644 index 2cbe277..0000000 Binary files a/demo/resources/sprites.bmp and /dev/null differ diff --git a/demo/resources/swords.bmp b/demo/resources/swords.bmp deleted file mode 100644 index 8aa6416..0000000 Binary files a/demo/resources/swords.bmp and /dev/null differ diff --git a/demo/resources/town.bmp b/demo/resources/town.bmp deleted file mode 100644 index 6a2e6ff..0000000 Binary files a/demo/resources/town.bmp and /dev/null differ diff --git a/demo/resources/zelda.bmp b/demo/resources/zelda.bmp deleted file mode 100644 index 03440dd..0000000 Binary files a/demo/resources/zelda.bmp and /dev/null differ diff --git a/demo/test_bopti.c b/demo/test_bopti.c deleted file mode 100644 index de1c083..0000000 --- a/demo/test_bopti.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include - -#include - -#include - -/* - test_bopti() - Displays and moves many kinds of bitmaps. Here are the images used: - - Name Size Color Alpha - --------------------------------------------------------- - items.bmp 266 * 124 Gray - - sprites.bmp 66 * 33 Gray - - swords.bmp 88 * 16 Gray Full - --------------------------------------------------------- - zelda.bmp 86 * 280 Mono - - isometric.bmp 37 * 27 Mono Full - - - Mono Greater - --------------------------------------------------------- -*/ - -static void getwh(image_t *img, int *width, int *height) -{ - const uint8_t *data; - - if(!img) - { - *width = 0; - *height = 0; - return; - } - *width = img->width; - *height = img->height; - if(*width && *height) return; - - data = (uint8_t *)img->data; - *width = (data[0] << 8) | data[1]; - *height = (data[2] << 8) | data[3]; -} - -static void getxy(image_t *img, int *x, int *y) -{ - int width, height; - - getwh(img, &width, &height); - *x = 64 - (width >> 1); - *y = 28 - (height >> 1); -} - -static image_t *select(image_t *current) -{ - extern image_t res_bopti_thumbs; - extern image_t - res_items, - res_sprites, - res_swords, - res_zelda, - res_isometric; - extern image_t res_screen; - - struct { - image_t *img; - const char *name; - const char *info; - } images[] = { - { &res_items, "Items", "Gray" }, - { &res_sprites, "Sprites", "Gray" }, - { &res_swords, "Swords", "Gray Alpha" }, - { &res_zelda, "Zelda", "Mono" }, - { &res_isometric, "Isometric", "Mono Alpha" }, - { &res_screen, "TLT", "Mono" }, - { NULL, NULL, NULL } - }; - - image_t *thumbs = &res_bopti_thumbs; - int items = 0; - static int row = 0; - int leave = 1, i; - - while(images[items].img) items++; - - keyboard_setRepeatRate(625, 125); - gray_start(); - - while(1) - { - gclear(); - locate(1, 1, "Select an image:"); - - for(i = 0; i < items && i < 7; i++) - { - locate(2, 2 + i + (i > row), images[i].name); - gimage_part(100, 8 + 8 * (i + (i > row)), thumbs, 0, - 8 * i, 7, 7); - if(i == row) - { - int width, height; - getwh(images[i].img, &width, &height); - print(2, 2 + i + 1, "%d\x04%d", width, height); - locate(10, 2 + i + 1, images[i].info); - } - } - - grect(0, 8 * row + 8, 128, 8 * row + 23, color_invert); - gupdate(); - - do - { - leave = 1; - - switch(getkey()) - { - case KEY_UP: - row = (row + items - 1) % items; - break; - case KEY_DOWN: - row = (row + 1) % items; - break; - case KEY_EXE: - return images[row].img; - case KEY_EXIT: - return current; - default: - leave = 0; - break; - } - } - while(!leave); - } - - gray_stop(); -} - -void test_bopti(void) -{ - extern image_t res_opt_bitmap; - image_t *img = NULL; - - int leave = 1; - int black_bg = 0; - int x = 0, y = 0; - - - while(1) - { - keyboard_setRepeatRate(25, 25); - if(img && (img->format & channel_light)) - { - gray_start(); - gclear(); - - if(black_bg) grect(0, 0, 127, 63, color_invert); - if(img) gimage(x, y, img); - - grect(0, 55, 127, 63, color_white); - gimage_part(0, 56, &res_opt_bitmap, 0, 0, 96, 8); - } - else if(img) - { - gray_stop(); - dclear(); - - if(black_bg) drect(0, 0, 127, 63, color_invert); - if(img) dimage(x, y, img); - - drect(0, 55, 127, 63, color_white); - dimage_part(0, 56, &res_opt_bitmap, 0, 0, 96, 8); - } - else - { - gray_stop(); - - dclear(); - locate(3, 3, "No image selected"); - - dimage_part(0, 56, &res_opt_bitmap, 0, 0, 96, 8); - dupdate(); - } - - if(img) - { - int width, height; - getwh(img, &width, &height); - - if(x < 0) print(1, 4, "\x01"); - if(x + width > 128) print(21, 4, "\x02"); - - if(img->format & channel_light) - { - if(y < 0) gimage_part(61, 0, &res_opt_bitmap, - 122, 0, 6, 8); - if(y + height > 64) gimage_part(61, 48, - &res_opt_bitmap, 116, 0, 6, 8); - gupdate(); - } - else - { - if(y < 0) dimage_part(61, 0, &res_opt_bitmap, - 122, 0, 6, 8); - if(y + height > 64) dimage_part(61, 48, - &res_opt_bitmap, 116, 0, 6, 8); - dupdate(); - } - } - - do - { - leave = 1; - - switch(getkey()) - { - case KEY_EXIT: - keyboard_setRepeatRate(625, 125); - gray_stop(); - return; - - case KEY_F1: - img = select(img); - getxy(img, &x, &y); - break; - case KEY_F2: - black_bg = !black_bg; - break; - - case KEY_UP: y++; break; - case KEY_DOWN: y--; break; - case KEY_LEFT: x++; break; - case KEY_RIGHT: x--; break; - - default: - leave = 0; - } - } - while(!leave); - } - - keyboard_setRepeatRate(625, 125); - gray_stop(); - return; -} diff --git a/demo/test_gray.c b/demo/test_gray.c deleted file mode 100644 index 86d7f35..0000000 --- a/demo/test_gray.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include - -/* - test_gray() - Lets the user set the gray delays and see the results. -*/ - -static void draw(int delay1, int delay2, int selected, int gran) -{ - extern image_t res_opt_gray; - uint32_t *vl = gray_lightVRAM(); - uint32_t *vd = gray_darkVRAM(); - - gclear(); - locate(1, 1, "Gray engine"); - - for(int i = 0; i < 64; i++) - { - int offset = (i << 2) + 3; - vl[offset] = -(!(i & 16)); - vd[offset] = -(i < 32); - } - - print(2, 3, "light %d", delay1); - print(2, 4, " dark %d", delay2); - print(2, 6, "Mode: \x04%d", gran); - - int lengths[2] = { - 4 - (delay1 < 1000), - 4 - (delay2 < 1000) - }; - print(8, 3 + selected, "\x01"); - print(9 + lengths[selected], 3 + selected, "\x02"); - - gimage(0, 56, &res_opt_gray); - gupdate(); -} - -void test_gray(void) -{ - int delays[2]; // { light, dark } - int key, changed = 1; - int selected = 0; - int gran = 1; - - gray_getDelays(delays, delays + 1); - gray_start(); - - while(1) - { - if(changed) - { - gray_setDelays(delays[0], delays[1]); - draw(delays[0], delays[1], selected, gran); - } - changed = 0; - - key = getkey_opt(getkey_default, 25); - if(key == KEY_EXIT) break; - - changed = 1; - - switch(key) - { - case KEY_F1: - delays[0] = 912; - delays[1] = 1343; - break; - case KEY_F2: - delays[0] = 993; - delays[1] = 1609; - break; - case KEY_F3: - delays[0] = 860; - delays[1] = 1298; - break; - case KEY_F5: - if(gran >= 100) gran = 1; - else gran *= 10; - case KEY_UP: - selected = 0; - break; - case KEY_DOWN: - selected = 1; - break; - case KEY_LEFT: - if(delays[selected] - gran >= 100) - delays[selected] -= gran; - break; - case KEY_RIGHT: - if(delays[selected] + gran < 10000) - delays[selected] += gran; - break; - default: - changed = 0; - break; - } - } - - gray_stop(); -} diff --git a/demo/test_keyboard.c b/demo/test_keyboard.c deleted file mode 100644 index 59f0471..0000000 --- a/demo/test_keyboard.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include -#include - -static void draw_keyboard(volatile uint8_t *state) -{ - int i, j, k, l; - int x, y; - - for(i = 0; i < 10; i++) for(j = 1; j < 8; j++) - { - // Eliminating keys that do not exist. - if(!i && j != 7) continue; - if(i && j == 7) continue; - if(i <= 4 && j == 6) continue; - if(i == 4 && j == 5) continue; - - x = 5 * j + 1; - y = 59 - 5 * i; - - // Space for the horizontal line. - y += 3 * (i < 7); - - // Moving the [AC/ON] key. - if(!i) x = 5 * (5) + 1, y = 61 - 5 * (4) + 1; - - // Drawing a filled shape when the key is pressed. - if(state[i] & (0x80 >> j)) - { - for(k = -2; k <= 2; k++) for(l = -2; l <= 2; l++) - if(abs(k) + abs(l) <= 2) - dpixel(x + k, y + l, color_black); - } - // Drawing a square border otherwise. - else - { - for(k = -1; k <= 1; k++) for(l = -1; l <= 1; l++) - if(k || l) dpixel(x + k, y + l, color_black); - } - } - - // Binding the arrow keys together for a more visual thing. - dpixel(28, 19, color_black); dpixel(29, 19, color_black); - dpixel(28, 24, color_black); dpixel(29, 24, color_black); - dpixel(26, 21, color_black); dpixel(26, 22, color_black); - dpixel(31, 21, color_black); dpixel(31, 22, color_black); - - // An horizontal line to separate parts of the keyboard. - dline(5, 28, 32, 28, color_black); -} - -typedef struct { - uint32_t key; - int repeats; -} history_key_t; - -typedef struct { - history_key_t *data; - int size; - int pressed; -} history_t; - -static int pressed_keys = 0; -static int releases = 0; - -static void history_push(history_t *h, event_t event) -{ - // Only reset the number of pressed keys in the history when the actual - // number of pressed keys reaches 0. - - if(event.type == event_key_release) - { - pressed_keys--; - if(!pressed_keys) h->pressed = 0; - return; - } - - // Now we're sure a key was pressed or repeated. Check if it's in the - // last pressed elements of the history array, if so, update it. - // Otherwise make space for a new entry and add it. - - if(event.type == event_key_press) pressed_keys++; - - for(int i = h->size - h->pressed; i < h->size; i++) - { - if(h->data[i].key == event.key.code) - { - h->data[i].repeats++; - return; - } - } - - // If there are already h->size keys pressed, do not add more. - if(event.type == event_key_press) h->pressed++; - if(h->pressed > h->size) return; - - for(int i = 0; i < h->size - 1; i++) h->data[i] = h->data[i + 1]; - h->data[h->size - 1].key = event.key.code; - h->data[h->size - 1].repeats = 1; -} - -static void draw_events(history_t *h) -{ - const char *key_names[] = { - "F1", "F2", "F3", "F4", "F5", "F6", - "SHIFT", "OPTN", "VARS", "MENU", "Left", "Up", - "ALPHA", "x^2", "^", "EXIT", "Down", "Right", - "X,\x1d,T", "log", "ln", "sin", "cos", "tan", - "[frac]", "F\x0f\x09" "D", "(", ")", ",", "\x09", - "7", "8", "9", "DEL", "AC/ON", NULL, - "4", "5", "6", "\x04", "\x05", NULL, - "1", "2", "3", "+", "-", NULL, - "0", ".", "\x08", "(-)", "EXE", NULL - }; - - int y = 3; - int y_limit = 8 - (h->pressed > h->size); - - extern font_t res_font_modern; - text_configure(&res_font_modern, color_black); - dtext(49, 12, "Key"); - dtext(89, 12, "Rep."); - // dprint(49, 7, "%d %d %d", h->pressed, pressed_keys, releases); - text_configure(NULL, color_black); - dline(45, 18, 120, 18, color_black); - - for(int i = 0; i < h->size && y < y_limit; i++) if(h->data[i].key) - { - dtext(49, y * 8 - 4, key_names[key_id(h->data[i].key)]); - if(h->data[i].repeats > 1) - dprint(89, y * 8 - 4, "%d", h->data[i].repeats); - y++; - } - - if(h->pressed > h->size) dtext(49, 52, "(more)"); -} - -/* - test_keyboard_events() - Real-time keyboard management with events. -*/ -void test_keyboard_events(void) -{ - history_key_t history_data[5] = { 0 }; - history_t history = { - .data = history_data, - .size = 5, - .pressed = 0, - }; - event_t event; - - // There may be keys pressed when this test starts. We need to detect - // which and create a valid history for them. - volatile const uint8_t *buffer = keyboard_stateBuffer(); - - // For the purpose of this function we don't need to calculate the - // other fields. - event_t push_event = { - .type = event_key_press, - .key.code = KEY_AC_ON, - }; - - // Finding all the pressed keys and pushing them in the history. - if(buffer[0] & 1) history_push(&history, push_event); - for(int row = 1; row <= 9; row++) for(int col = 0; col < 8; col++) - { - // Eliminate non-existing keys. - if(col > 6 || col <= (row <= 4)) continue; - - if(buffer[row] & (1 << col)) - { - push_event.key.code = (col << 4) | row; - history_push(&history, push_event); - } - } - - while(1) - { - dclear(); - locate(1, 1, "Keyboard and events"); - - draw_keyboard(keyboard_stateBuffer()); - - draw_events(&history); - dupdate(); - - event = waitevent(); - if(event.type == event_key_release) releases++; - if(event.type == event_key_press && event.key.code == KEY_EXIT) - break; - history_push(&history, event); - } -} diff --git a/demo/test_rtc.c b/demo/test_rtc.c deleted file mode 100644 index 4b8fa65..0000000 --- a/demo/test_rtc.c +++ /dev/null @@ -1,260 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include - -#include -#include - -/* - test_rtc() - Just a clock. Of course using all this RTCTime conversion and this / 10 - is awfully un-optimized, but it's a test case so it's made to check the - values in the structure are correct. -*/ - -#include -#include -#include - -static void draw(rtc_time_t *time) -{ - extern image_t res_rtc_segments; - - const char *days[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }, *months[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", - "Oct", "Nov", "Dec" - }; - int x[6] = { 20, 33, 52, 65, 84, 97 }; - int digits[6]; - int i; - - digits[0] = time->hours / 10; - digits[1] = time->hours % 10; - digits[2] = time->minutes / 10; - digits[3] = time->minutes % 10; - digits[4] = time->seconds / 10; - digits[5] = time->seconds % 10; - - // Drawing digits. - for(i = 0; i < 6; i++) dimage_part(x[i], 8, &res_rtc_segments, - 12 * digits[i], 0, 11, 19); - // Drawing ':' between pairs of digits. - for(i = 0; i < 16; i++) dpixel(47 + 32 * (i >= 8) + (i & 1), - 14 + 5 * !!(i & 4) + !!(i & 2), color_black); - - // This should print time.year + 1900 but for the sake of this demo we - // have tweaked the field so that it already contains time.year + 1900. - print(4, 6, "%s %s %02d %4d", days[time->week_day], - months[time->month], time->month_day, time->year); -} - -static void callback(void) -{ - extern image_t res_opt_rtc; - rtc_time_t time; - rtc_getTime(&time); - - dclear(); - draw(&time); - dimage_part(0, 56, &res_opt_rtc, 0, 0, 19, 8); - dupdate(); -} - -static void set_region(rtc_time_t *time, int region, int value) -{ - switch(region) - { - case 0: - time->hours = 10 * value + (time->hours % 10); - break; - case 1: - time->hours = time->hours - (time->hours % 10) + value; - break; - case 2: - time->minutes = 10 * value + (time->minutes % 10); - break; - case 3: - time->minutes = time->minutes - (time->minutes % 10) + value; - break; - case 4: - time->seconds = 10 * value + (time->seconds % 10); - break; - case 5: - time->seconds = time->seconds - (time->seconds % 10) + value; - break; - case 6: - time->week_day = value; - break; - case 7: - time->month = value; - break; - case 8: - time->month_day = 10 * value + (time->month_day % 10); - break; - case 9: - time->month_day = time->month_day - (time->month_day % 10) - + value; - break; - case 10: - time->year = 1000 * value + (time->year % 1000); - break; - case 11: - time->year = time->year - (time->year % 1000) + 100 * value - + (time->year % 100); - break; - case 12: - time->year = time->year - (time->year % 100) + 10 * value - + (time->year % 10); - break; - case 13: - time->year = time->year - (time->year % 10) + value; - break; - } -} - -static void set(void) -{ - extern image_t res_opt_rtc; - image_t *opt = &res_opt_rtc; - - struct { - int x, y; - int w, h; - } regions[] = { - { 19, 7, 13, 21 }, { 32, 7, 13, 21 }, { 51, 7, 13, 21 }, - { 64, 7, 13, 21 }, { 83, 7, 13, 21 }, { 96, 7, 13, 21 }, - { 18, 39, 19, 9 }, { 42, 39, 19, 9 }, { 66, 39, 7, 9 }, - { 72, 39, 7, 9 }, { 84, 39, 7, 9 }, { 90, 39, 7, 9 }, - { 96, 39, 7, 9 }, { 102, 39, 7, 9 }, - }; - rtc_time_t time; - int region_count = 14; - int n = 0, slide = 0, key, leave; - - rtc_getTime(&time); - - while(1) - { - dclear(); - draw(&time); - drect(regions[n].x, regions[n].y, regions[n].x + regions[n].w - - 1, regions[n].y + regions[n].h - 1, color_invert); - - if(n == 6) dimage_part(0, 56, opt, 0, 9 * (1 + slide), 128, 8); - if(n == 7) dimage_part(0, 56, opt, 0, 9 * (3 + slide), 128, 8); - else dimage_part(0, 56, opt, 22 + 22 * (n == region_count - 1), - 0, 19, 8); - - dupdate(); - - do - { - leave = 1; - key = getkey(); - if(key == KEY_EXIT) return; - - else if(key == KEY_F1 || key == KEY_EXE) - { - slide = 0; - if(++n == region_count) - { - rtc_setTime(&time); - return; - } - } - - else if(key == KEY_F6) - { - if(n == 6) slide = (slide + 1) % 2; - if(n == 7) slide = (slide + 1) % 3; - } - - else if((key & 0x0f) == 9) // Other F-keys - { - int k = 7 - (key >> 4); // Number of F-key - - if(n == 7) - { - int month = k + 4 * slide - 2; - set_region(&time, n, month); - n++; - slide = 0; - } - - else if(n == 6 && (slide != 1 || k != 5)) - { - int day = (k + 4 * slide - 1) % 7; - set_region(&time, n, day); - n++; - slide = 0; - } - - else leave = 0; - } - - else if(isdigit(key_char(key))) // Numbers - { - int val = key_char(key) - '0'; - int ok = 1; - - if(n == 0) ok = (val <= 2); - if(n == 1) - { - int max = time.hours >= 20 ? 3 : 9; - ok = (val <= max); - } - if(n == 2 || n == 4) ok = (val <= 5); - if(n == 8) ok = (val <= 3); - if(n == 9) - { - int max = time.month_day >= 30 ? 1 : 9; - ok = (val <= max); - } - - if(ok) - { - set_region(&time, n, val); - n++; - if(n == region_count) - { - rtc_setTime(&time); - return; - } - slide = 0; - } - else leave = 0; - } - - else leave = 0; - } while(!leave); - } - - while(getkey() != KEY_EXIT); -} - -void test_rtc(void) -{ - int key, cb_id; - - cb_id = rtc_cb_add(rtc_freq_1Hz, callback, 0); - callback(); - - while(1) - { - key = getkey(); - - if(key == KEY_EXIT) break; - if(key == KEY_F1) - { - rtc_cb_edit(cb_id, rtc_freq_none, NULL); - set(); - callback(); - rtc_cb_edit(cb_id, rtc_freq_1Hz, callback); - } - } - - rtc_cb_end(cb_id); -} diff --git a/demo/test_tales.c b/demo/test_tales.c deleted file mode 100644 index 1ad6a48..0000000 --- a/demo/test_tales.c +++ /dev/null @@ -1,158 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include - -#include - -/* - test_tales() - Displays some text using different modes and clipping options. -*/ - -static font_t *select(font_t *current) -{ - extern font_t res_font_modern; - struct { - font_t *font; - const char *name; - } fonts[] = { - { NULL, "gint default" }, - { &res_font_modern, "Modern" }, - }; - int font_number = 2; - - static int row = 0; - int i, leave; - - while(1) - { - text_configure(NULL, color_black); - - dclear(); - locate(1, 1, "Select a font:"); - - for(i = 0; i < font_number && i < 6; i++) - { - if(fonts[i].font) - { - int height = fonts[i].font->line_height; - int y = (i + 2) * 8 - 8 + ((7 - height) >> 1); - - text_configure(fonts[i].font, color_black); - dtext(7, y, fonts[i].name); - } - else - { - text_configure(NULL, color_black); - locate(2, i + 2, fonts[i].name); - } - - } - - drect(0, 8 * row + 8, 128, 8 * row + 15, color_invert); - dupdate(); - - do - { - leave = 1; - - switch(getkey()) - { - case KEY_UP: - row = (row + font_number - 1) % font_number; - break; - case KEY_DOWN: - row = (row + 1) % font_number; - break; - case KEY_EXE: - return fonts[row].font; - case KEY_EXIT: - return current; - default: - leave = 0; - break; - } - } - while(!leave); - } -} - -void test_tales(void) -{ - color_t colors[] = { color_black, color_dark, color_light, color_white, - color_invert }; - extern image_t res_opt_tales; - font_t *font = NULL; - - int black_bg = 0; - int color = 0; - int i, x, height; - int leave; - - gray_start(); - while(1) - { - gclear(); - if(black_bg) grect(0, 0, 127, 54, color_invert); - - if(font) - { - text_configure(font, colors[color]); - height = font->line_height + 1; - } - else - { - text_configure(NULL, colors[color]); - height = 8; - } - - for(i = 0; i < 6 && 2 + (i + 1) * height < 56; i++) - { - char str[17]; - for(int j = 0; j < 16; j++) str[j] = 32 + (i << 4) + j; - str[16] = 0; - - gtext(1, 1 + i * height, str); - } - - gimage(0, 56, &res_opt_tales); - - x = 45 + 8 * color; - gline(x, 57, x + 5, 57, color_black); - gline(x, 57, x, 62, color_black); - gline(x + 5, 57, x + 5, 62, color_black); - gline(x, 62, x + 5, 62, color_black); - - gupdate(); - - do - { - leave = 1; - - switch(getkey()) - { - case KEY_F1: - gray_stop(); - font = select(font); - gray_start(); - break; - case KEY_F2: - color = (color + 1) % 5; - break; - case KEY_F5: - black_bg = !black_bg; - break; - - case KEY_EXIT: - gray_stop(); - text_configure(NULL, color_black); - return; - default: - leave = 0; - break; - } - } - while (!leave); - } -} diff --git a/demo/test_timer.c b/demo/test_timer.c deleted file mode 100644 index 011f365..0000000 --- a/demo/test_timer.c +++ /dev/null @@ -1,273 +0,0 @@ -#include "gintdemo.h" -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static void draw(int new_tab); -static clock_config_t conf; - -//--- -// Timer-RTC comparison. -// The precision of the timer is measured by comparing it to the RTC. -//--- - -static volatile int elapsed_timer = -1; -static volatile int elapsed_rtc = -1; -static int cb_id = -1; -static timer_t *htimer = NULL; - -static void timing_rtc(void) -{ - elapsed_rtc++; -} - -static void timing_timer(void) -{ - elapsed_timer++; -} - -static void timing_start(void) -{ - uint32_t delay = clock_setting(64, clock_Hz); - htimer = htimer_setup(timer_user, delay, timer_Po_4, 0); - timer_attach(htimer, timing_timer, NULL); - timer_start(htimer); - - rtc_cb_edit(cb_id, rtc_freq_64Hz, timing_rtc); - - elapsed_timer = 0; - elapsed_rtc = 0; -} - - - -//--- -// Drawing. -//--- - -/* - small_text() - Renders small text using a minimalist bitmap-based font. -*/ -static void small_text(int x, int y, const char *text, int alignment) -{ - extern image_t res_clock_chars; - image_t *chars = &res_clock_chars; - const char *table = "0123456789kMHz*/"; - - if(alignment) x -= 2 * strlen(text) - 1, y -= 2; - int c; - - while(*text) - { - const char *ptr = strchr(table, *text++); - if(!ptr) continue; - c = ptr - table; - - dimage_part(x, y, chars, c << 2, 0, 3, 5); - x += 4; - } -} - -/* - getFreq() - Prints the given frequency in a string on the form: - 332kHz - There are 1, 2 or 3 characters for the value, and 2 or 3 - characters for the unit. The string is compacted. -*/ -void getFreq(char *str, int freq) -{ - if(freq < 1000) sprintf(str, "%dHz", freq); - else if(freq < 1000000) sprintf(str, "%dkHz", (freq + 500) / 1000); - else sprintf(str, "%dMHz", (freq + 500000) / 1000000); -} - -/* - dislay_freq() - Displays a frequency value a unit, in an simple form. -*/ -static void display_freq(int x, int y, int freq) -{ - int ratio, letter, dot, i; - char buffer[10]; - - if(freq <= 0) - { - dtext(x, y, "Unknown"); - return; - } - if(freq < 10000) - { - dprint(x, y, "%5d", freq); - small_text(x + 31, y + 2, "Hz", 0); - return; - } - - if(freq < 10000000) ratio = 1, letter = 'k'; - else ratio = 1000, letter = 'M'; - - dot = 1 + (freq >= 10000 * ratio) + (freq >= 100000 * ratio); - freq += (ratio * (1 + 9 * (dot >= 2) + 90 * (dot >= 3))) / 2; - snprintf(buffer, 6, "%d", freq); - - for(i = 4; i > dot; i--) buffer[i] = buffer[i - 1]; - buffer[dot] = '.'; - - dprint(x, y, buffer); - sprintf(buffer, "%cHz", letter); - small_text(x + 31, y + 2, buffer, 0); -} - -/* - draw() - Draws the test interface. -*/ -static void draw(int tab) -{ - extern image_t res_opt_timer; - extern image_t res_clock_7705; - extern image_t res_clock_7305; - - char buffer[16]; - - dclear(); - dimage(0, 56, &res_opt_timer); - - if(!tab) - { - locate(1, 1, "Clock frequency"); - dtext(7, 20, "B\x1e"); - display_freq(24, 20, conf.Bphi_f); - dtext(7, 28, "I\x1e"); - display_freq(24, 28, conf.Iphi_f); - dtext(7, 36, "P\x1e"); - display_freq(24, 36, conf.Pphi_f); - - if(isSH3()) - { - dimage(64, 0, &res_clock_7705); - - getFreq(buffer, conf.CKIO_f); - small_text(84, 16, buffer, 1); - - sprintf(buffer, "*%d", conf.PLL1); - small_text(84, 34, buffer, 1); - - if(conf.Iphi_div1 == 1) - dline(85, 43, 99, 43, color_black); - else - { - sprintf(buffer, "/%d", conf.Iphi_div1); - small_text(89, 41, buffer, 0); - } - if(conf.Pphi_div1 == 1) - dline(85, 50, 99, 50, color_black); - else - { - sprintf(buffer, "/%d", conf.Pphi_div1); - small_text(89, 48, buffer, 0); - } - } - else - { - dimage(64, 0, &res_clock_7305); - - getFreq(buffer, conf.RTCCLK_f); - small_text(82, 13, buffer, 1); - - sprintf(buffer, "*%d", conf.FLL); - small_text(82, 23, buffer, 1); - - sprintf(buffer, "*%d", conf.PLL); - small_text(82, 33, buffer, 1); - - sprintf(buffer, "/%d", conf.Bphi_div1); - small_text(87, 40, buffer, 0); - sprintf(buffer, "/%d", conf.Iphi_div1); - small_text(87, 47, buffer, 0); - sprintf(buffer, "/%d", conf.Pphi_div1); - small_text(87, 54, buffer, 0); - } - } - else - { - int timer = elapsed_timer, rtc = elapsed_rtc; // just in case - - locate(1, 1, "Timer/RTC comparison"); - - locate(2, 3, "Timer"); - if(timer >= 0) print(12, 3, "%04x", timer); - else locate(12, 3, "..."); - - locate(2, 4, "RTC"); - if(rtc >= 0) print(12, 4, "%04x", rtc); - else locate(12, 4, "..."); - - // We define the accuracy of the timer as the ratio between the - // two counters. - locate(2, 5, "Accuracy"); - if(rtc > 0 && timer > 0) - { - int ratio; - if(timer <= rtc) ratio = (10000 * timer) / rtc; - else ratio = (10000 * rtc) / timer; - - print(12, 5, "%d.%02d%%", ratio / 100, ratio % 100); - } - else locate(12, 5, "..."); - } - - dupdate(); -} - - - -//--- -// Timer/clock test. -//--- - -/* - test_timer() - Clock timer and timer precision. -*/ -void test_timer(void) -{ - int tab = 0; - - conf = clock_config(); - - elapsed_timer = -1; - elapsed_rtc = -1; - cb_id = rtc_cb_add(rtc_freq_64Hz, timing_start, 0); - - text_configure(NULL, color_black); - - while(1) - { - draw(tab); - - switch(getkey_opt(getkey_none, 25)) - { - case KEY_EXIT: - rtc_cb_end(cb_id); - timer_stop(htimer); - return; - - case KEY_F1: - tab = 0; - break; - case KEY_F2: - tab = 1; - break; - } - } -} diff --git a/include/7305.h b/include/7305.h deleted file mode 100644 index a34420f..0000000 --- a/include/7305.h +++ /dev/null @@ -1,673 +0,0 @@ -#ifndef _7305_H -#define _7305_H 1 - -/* - Double-underscore prefixed structures (e.g. __st_rtc_counter) are used - internally but are not meant to be used in user programs. - - Underscore-prefixed names (e.g. _R64CNT) are used to avoid name - conflicts (e.g. STRUCTURE.RTC would expand to STRUCTURE.((T *)0x...)). -*/ - -#pragma pack(push, 1) -#define gap(n) unsigned: n << 3 - -//--- -// Interrupt controller, part 1. -//--- - -struct _st_intc -{ - union { - unsigned short WORD; - struct { - unsigned const NMIL :1; - unsigned MAI :1; - unsigned :4; - unsigned NMIB :1; - unsigned NMIE :1; - unsigned :2; - unsigned LVLMODE :1; - unsigned :5; - }; - } ICR0; - - char gap1[14]; - - union { - unsigned int LONG; - struct { - unsigned IRQ0 :4; - unsigned IRQ1 :4; - unsigned IRQ2 :4; - unsigned IRQ3 :4; - unsigned IRQ4 :4; - unsigned IRQ5 :4; - unsigned IRQ6 :4; - unsigned IRQ7 :4; - }; - } INTPRI00; - - char gap2[8]; - - union { - unsigned short WORD; - struct { - unsigned IRQ0S :2; - unsigned IRQ1S :2; - unsigned IRQ2S :2; - unsigned IRQ3S :2; - unsigned IRQ4S :2; - unsigned IRQ5S :2; - unsigned IRQ6S :2; - unsigned IRQ7S :2; - }; - } ICR1; - - char gap3[6]; - - union { - unsigned char BYTE; - struct { - unsigned IRQ0 :1; - unsigned IRQ1 :1; - unsigned IRQ2 :1; - unsigned IRQ3 :1; - unsigned IRQ4 :1; - unsigned IRQ5 :1; - unsigned IRQ6 :1; - unsigned IRQ7 :1; - }; - } INTREQ00; - - char gap4[31]; - - union { - unsigned char BYTE; - struct { - unsigned IRQ0 :1; - unsigned IRQ1 :1; - unsigned IRQ2 :1; - unsigned IRQ3 :1; - unsigned IRQ4 :1; - unsigned IRQ5 :1; - unsigned IRQ6 :1; - unsigned IRQ7 :1; - }; - } INTMSK00; - - char gap5[31]; - - union { - unsigned char BYTE; - struct { - unsigned _IRQ0 :1; - unsigned _IRQ1 :1; - unsigned _IRQ2 :1; - unsigned _IRQ3 :1; - unsigned _IRQ4 :1; - unsigned _IRQ5 :1; - unsigned _IRQ6 :1; - unsigned _IRQ7 :1; - }; - } INTMSKCLR00; - - char gap6[91]; - - union { - unsigned short WORD; - struct { - unsigned const NMIL :1; - unsigned :14; - unsigned NMIFL :1; - }; - } NMIFCR; - - char gap7[6029118]; - - union { - unsigned int LONG; - struct { - unsigned HEXA_A5 :8; - unsigned :16; - unsigned UIMASK :4; - unsigned :4; - }; - } USERIMSK; - -} __attribute__((packed)); - - - -//--- -// Interrupt controller, part 2. -//--- - -struct _st_intx -{ - union { - unsigned short WORD; - struct { - unsigned TMU0_0 :4; - unsigned TMU0_1 :4; - unsigned TMU0_2 :4; - unsigned IrDA :4; - }; - } IPRA; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned JPU :4; - unsigned LCDC :4; - unsigned DMAC1A :4; - unsigned BEU2_1 :4; - }; - } IPRB; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned TMU1_0 :4; - unsigned TMU1_1 :4; - unsigned TMU1_2 :4; - unsigned SPU :4; - }; - } IPRC; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned :4; - unsigned MMCIF :4; - unsigned :4; - unsigned ATAPI :4; - }; - } IPRD; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned DMAC0A :4; - unsigned VARIOUS :4; - unsigned SCIFA3 :4; - unsigned VPU5F :4; - }; - } IPRE; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned _KEYSC :4; - unsigned DMAC0B :4; - unsigned USB01 :4; - unsigned CMT :4; - }; - } IPRF; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned SCIF0 :4; - unsigned SCIF1 :4; - unsigned SCIF2 :4; - unsigned VEU3F0 :4; - }; - } IPRG; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned MSIOF0 :4; - unsigned MSIOF1 :4; - unsigned I2C1 :4; - unsigned I2C0 :4; - }; - } IPRH; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned SCIFA4 :4; - unsigned ICB :4; - unsigned TSIF :4; - unsigned _2DG_ICB :4; - }; - } IPRI; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned CEU2_1 :4; - unsigned EtherMAC :4; - unsigned FSI :4; - unsigned SDHI1 :4; - }; - } IPRJ; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned _RTC :4; - unsigned DMAC1B :4; - unsigned ICB :4; - unsigned SDHI0 :4; - }; - } IPRK; - gap(2); - - union { - unsigned short WORD; - struct { - unsigned SCIFA5 :4; - unsigned :4; - unsigned TPU :4; - unsigned _2DDMAC :4; - }; - } IPRL; - char gap1[82]; - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned TUNI2 :1; - unsigned TUNI1 :1; - unsigned TUNI0 :1; - unsigned SDHII3 :1; - unsigned SDHII2 :1; - unsigned SDHII1 :1; - unsigned SDHII0 :1; - }; - } IMR0; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned VOUI :1; - unsigned VEU1I :1; - unsigned BEU0I :1; - unsigned CEUOI :1; - unsigned DEI3 :1; - unsigned DEI2 :1; - unsigned DEI1 :1; - unsigned DEI0 :1; - }; - } IMR1; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :3; - unsigned VPUI :1; - unsigned ATAPI :1; - unsigned EtherMAC :1; - unsigned :1; - unsigned SCIFA0 :1; - }; - } IMR2; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned DEI3 :1; - unsigned DEI2 :1; - unsigned DEI1 :1; - unsigned DEI0 :1; - unsigned :3; - unsigned IRDAI :1; - }; - } IMR3; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned TUNI2 :1; - unsigned TUNI1 :1; - unsigned TUNI0 :1; - unsigned JPUI :1; - unsigned :2; - unsigned LCDCI :1; - }; - } IMR4; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned KEYI :1; - unsigned DADERR :1; - unsigned DEI5 :1; - unsigned DEI4 :1; - unsigned VEU0I :1; - unsigned SCIF2 :1; - unsigned SCIF1 :1; - unsigned SCIF0 :1; - }; - } IMR5; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :2; - unsigned ICBI :1; - unsigned SCIFA4 :1; - unsigned CEU1I :1; - unsigned :1; - unsigned MSIOFI0 :1; - unsigned MSIOFI1 :1; - }; - } IMR6; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned DTE0I :1; - unsigned WAITOI :1; - unsigned TACK0I :1; - unsigned AL0I :1; - unsigned DTE1I :1; - unsigned WAIT1I :1; - unsigned TACK1I :1; - unsigned AL1I :1; - }; - } IMR7; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned SDHII3 :1; - unsigned SDHII2 :1; - unsigned SDHII1 :1; - unsigned SDHII0 :1; - unsigned :2; - unsigned SCFIA5 :1; - unsigned FSI :1; - }; - } IMR8; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :3; - unsigned CMTI :1; - unsigned :1; - unsigned USI1 :1; - unsigned USI0 :1; - unsigned :1; - }; - } IMR9; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned DADERR :1; - unsigned DEI5 :1; - unsigned DEI4 :1; - unsigned :1; - unsigned ATI :1; - unsigned PRI :1; - unsigned CUI :1; - }; - } IMR10; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned BRK :1; - unsigned CEI :1; - unsigned INI :1; - unsigned TRI :1; - unsigned :1; - unsigned TPUI :1; - unsigned LMBI :1; - unsigned TSIFI :1; - }; - } IMR11; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :7; - unsigned _2DDMAC :1; - }; - } IMR12; - char gap2[15]; - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned TUNI2 :1; - unsigned TUNI1 :1; - unsigned TUNI0 :1; - unsigned SDHII3 :1; - unsigned SDHII2 :1; - unsigned SDHII1 :1; - unsigned SDHII0 :1; - }; - } _IMCR0; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned VOUI :1; - unsigned VEU1I :1; - unsigned BEU0I :1; - unsigned CEUOI :1; - unsigned DEI3 :1; - unsigned DEI2 :1; - unsigned DEI1 :1; - unsigned DEI0 :1; - }; - } _IMCR1; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :3; - unsigned VPUI :1; - unsigned ATAPI :1; - unsigned EtherMAC :1; - unsigned :1; - unsigned SCIFA0 :1; - }; - } _IMCR2; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned DEI3 :1; - unsigned DEI2 :1; - unsigned DEI1 :1; - unsigned DEI0 :1; - unsigned :3; - unsigned IRDAI :1; - }; - } _IMCR3; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned TUNI2 :1; - unsigned TUNI1 :1; - unsigned TUNI0 :1; - unsigned JPUI :1; - unsigned :2; - unsigned LCDCI :1; - }; - } _IMCR4; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned KEYI :1; - unsigned DADERR :1; - unsigned DEI5 :1; - unsigned DEI4 :1; - unsigned VEU0I :1; - unsigned SCIF2 :1; - unsigned SCIF1 :1; - unsigned SCIF0 :1; - }; - } _IMCR5; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :2; - unsigned ICBI :1; - unsigned SCIFA4 :1; - unsigned CEU1I :1; - unsigned :1; - unsigned MSIOFI0 :1; - unsigned MSIOFI1 :1; - }; - } _IMCR6; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned DTE0I :1; - unsigned WAITOI :1; - unsigned TACK0I :1; - unsigned AL0I :1; - unsigned DTE1I :1; - unsigned WAIT1I :1; - unsigned TACK1I :1; - unsigned AL1I :1; - }; - } _IMCR7; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned SDHII3 :1; - unsigned SDHII2 :1; - unsigned SDHII1 :1; - unsigned SDHII0 :1; - unsigned :2; - unsigned SCFIA5 :1; - unsigned FSI :1; - }; - } _IMCR8; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :3; - unsigned CMTI :1; - unsigned :1; - unsigned USI1 :1; - unsigned USI0 :1; - unsigned :1; - }; - } _IMCR9; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :1; - unsigned DADERR :1; - unsigned DEI5 :1; - unsigned DEI4 :1; - unsigned :1; - unsigned ATI :1; - unsigned PRI :1; - unsigned CUI :1; - }; - } _IMCR10; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned BRK :1; - unsigned CEI :1; - unsigned INI :1; - unsigned TRI :1; - unsigned :1; - unsigned TPUI :1; - unsigned LMBI :1; - unsigned TSIFI :1; - }; - } _IMCR11; - gap(3); - - union - { - unsigned char BYTE; - struct { - unsigned :7; - unsigned _2DDMAC :1; - }; - } _IMCR12; - -} __attribute__((packed)); - - - -#define INTC (*(volatile struct _st_intc *)0xa4140000) -#define INTX (*(volatile struct _st_intx *)0xa4080000) - -#pragma pack(pop) -#endif // _7305_H diff --git a/include/7705.h b/include/7705.h deleted file mode 100644 index 3282d34..0000000 --- a/include/7705.h +++ /dev/null @@ -1,1099 +0,0 @@ -#ifndef _7705_H -#define _7705_H 1 - - -// Internal Control Registers definition : - -struct st_cpg { /* struct CPG */ - union { /* FRQCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :3; /* */ - unsigned short CKOEN:1; /* CKOEN */ - unsigned short :2; /* */ - unsigned short STC :2; /* STC */ - unsigned short :2; /* */ - unsigned short IFC :2; /* IFC */ - unsigned short :2; /* */ - unsigned short _PFC :2; /* PFC */ - } BIT; /* */ - } FRQCR; /* */ -}; /* */ -struct st_wdt { /* struct WDT */ - union { /* WTCNT */ - unsigned char READ; /* Read Access*/ - unsigned short WRITE; /* Write Access*/ - } WTCNT; /* */ - union { /* WTCSR */ - union { /* Read Access*/ - unsigned char BYTE; /* Byte Access*/ - struct { /* Bit Access*/ - unsigned char TME :1; /* TME */ - unsigned char WTIT:1; /* WT/IT */ - unsigned char RSTS:1; /* RSTS */ - unsigned char WOVF:1; /* WOVF */ - unsigned char IOVF:1; /* IOVF */ - unsigned char CKS :3; /* CKS */ - } BIT; /* */ - } READ; /* */ - unsigned short WRITE; /* Write Access*/ - } WTCSR; /* */ -}; - -struct st_pa { /* struct PA */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pb { /* struct PB */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pc { /* struct PC */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pd { /* struct PD */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pe { /* struct PE */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pf { /* struct PF */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pg { /* struct PG */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_ph { /* struct PH */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pj { /* struct PJ */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pk { /* struct PK */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pl { /* struct PL */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :4; /* Bit 7-4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_scp { /* struct SCP */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :2; /* Bit 7,6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pm { /* struct PM */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char :1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ -struct st_pn { /* struct PN */ - union { /* */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char B7:1; /* Bit 7 */ - unsigned char B6:1; /* Bit 6 */ - unsigned char B5:1; /* Bit 5 */ - unsigned char B4:1; /* Bit 4 */ - unsigned char B3:1; /* Bit 3 */ - unsigned char B2:1; /* Bit 2 */ - unsigned char B1:1; /* Bit 1 */ - unsigned char B0:1; /* Bit 0 */ - } BIT; /* */ - } DR; /* */ -}; /* */ - -struct st_usb { /* struct USB */ - union { /* UCLKCR */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char USSCS:2; /* USSCS */ - unsigned char USBEN:1; /* USBEN */ - } BIT; /* */ - } UCLKCR; /* */ - char wk1[4063223]; /* */ - unsigned char EPDR0i; /* EPDR0i */ - char wk2[3]; /* */ - unsigned char EPDR0o; /* EPDR0o */ - char wk3[3]; /* */ - unsigned char EPDR0s; /* EPDR0s */ - char wk4[3]; /* */ - unsigned char EPDR1; /* EPDR1 */ - char wk5[3]; /* */ - unsigned char EPDR2; /* EPDR2 */ - char wk6[3]; /* */ - unsigned char EPDR3; /* EPDR3 */ - char wk7[3]; /* */ - union { /* IFR0 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char BRST :1; /* BRST */ - unsigned char EP1FULL :1; /* EP1FULL */ - unsigned char EP2TR :1; /* EP2TR */ - unsigned char EP2EMPTY:1; /* EP2EMPTY */ - unsigned char SETUPTS :1; /* SETUPTS */ - unsigned char EP0oTS :1; /* EP0oTS */ - unsigned char EP0iTR :1; /* EP0iTR */ - unsigned char EP0iTS :1; /* EP0iTS */ - } BIT; /* */ - } IFR0; /* */ - char wk8[3]; /* */ - union { /* IFR1 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :4; /* */ - unsigned char VBUSMN:1; /* VBUSMN */ - unsigned char EP3TS :1; /* EP3TS */ - unsigned char EP3TR :1; /* EP3TR */ - unsigned char VBUS :1; /* VBUS */ - } BIT; /* */ - } IFR1; /* */ - char wk9[3]; /* */ - union { /* TRG */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* */ - unsigned char EP3PKTE :1; /* EP3PKTE */ - unsigned char EP1RDFN :1; /* EP1RDFN */ - unsigned char EP2PKTE :1; /* EP2PKTE */ - unsigned char :1; /* */ - unsigned char EP0sRDFN:1; /* EP0sRDFN */ - unsigned char EP0oRDFN:1; /* EP0oRDFN */ - unsigned char EP0iPKTE:1; /* EP0iPKTE */ - } BIT; /* */ - } TRG; /* */ - char wk10[3]; /* */ - union { /* FCLR */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* */ - unsigned char EP3CLR :1; /* EP3CLR */ - unsigned char EP1CLR :1; /* EP1CLR */ - unsigned char EP2CLR :1; /* EP2CLR */ - unsigned char :2; /* */ - unsigned char EP0oCLR:1; /* EP0oCLR */ - unsigned char EP0iCLR:1; /* EP0iCLR */ - } BIT; /* */ - } FCLR; /* */ - char wk11[3]; /* */ - unsigned char EPSZ0o; /* EPSZ0o */ - char wk12[3]; /* */ - union { /* DASTS */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :2; /* */ - unsigned char EP3DE :1; /* EP3DE */ - unsigned char EP2DE :1; /* EP2DE */ - unsigned char :3; /* */ - unsigned char EP0iDE:1; /* EP0iDE */ - } BIT; /* */ - } DASTS; /* */ - char wk13[3]; /* */ - union { /* EPSTL */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :4; /* */ - unsigned char EP3STL:1; /* EP3STL */ - unsigned char EP2STL:1; /* EP2STL */ - unsigned char EP1STL:1; /* EP1STL */ - unsigned char EP0STL:1; /* EP0STL */ - } BIT; /* */ - } EPSTL; /* */ - char wk14[3]; /* */ - union { /* IER0 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char BRST :1; /* BRST */ - unsigned char EP1FULL :1; /* EP1FULL */ - unsigned char EP2TR :1; /* EP2TR */ - unsigned char EP2EMPTY:1; /* EP2EMPTY */ - unsigned char SETUPTS :1; /* SETUPTS */ - unsigned char EP0oTS :1; /* EP0oTS */ - unsigned char EP0iTR :1; /* EP0iTR */ - unsigned char EP0iTS :1; /* EP0iTS */ - } BIT; /* */ - } IER0; /* */ - char wk15[3]; /* */ - union { /* IER1 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :5; /* */ - unsigned char EP3TS:1; /* EP3TS */ - unsigned char EP3TR:1; /* EP3TR */ - unsigned char VBUS :1; /* VBUS */ - } BIT; /* */ - } IER1; /* */ - char wk16[3]; /* */ - unsigned char EPSZ1; /* EPSZ1 */ - char wk17[3]; /* */ - union { /* DMAR */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :6; /* */ - unsigned char EP2DMAE:1; /* EP2DMAE */ - unsigned char EP1DMAE:1; /* EP1DMAE */ - } BIT; /* */ - } DMAR; /* */ - char wk18[3]; /* */ - union { /* ISR0 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char BRST :1; /* BRST */ - unsigned char EP1FULL :1; /* EP1FULL */ - unsigned char EP2TR :1; /* EP2TR */ - unsigned char EP2EMPTY:1; /* EP2EMPTY */ - unsigned char SETUPTS :1; /* SETUPTS */ - unsigned char EP0oTS :1; /* EP0oTS */ - unsigned char EP0iTR :1; /* EP0iTR */ - unsigned char EP0iTS :1; /* EP0iTS */ - } BIT; /* */ - } ISR0; /* */ - char wk19[3]; /* */ - union { /* ISR1 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :5; /* */ - unsigned char EP3TS:1; /* EP3TS */ - unsigned char EP3TR:1; /* EP3TR */ - unsigned char VBUS :1; /* VBUS */ - } BIT; /* */ - } ISR1; /* */ - char wk20[23]; /* */ - union { /* XVERCR */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :6; /* */ - unsigned char XVEROFF:1; /* XVEROFF */ - } BIT; /* */ - } XVERCR; /* */ -}; -struct st_intc { /* struct INTC */ - union { /* ICR0 */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short NMIL:1; /* NMIL */ - unsigned short :6; /* */ - unsigned short NMIE:1; /* NMIE */ - } BIT; /* */ - } ICR0; /* */ - union { /* IPRA */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _TMU0:4; /* TMU0 */ - unsigned short _TMU1:4; /* TMU1 */ - unsigned short _TMU2:4; /* TMU2 */ - unsigned short _RTC :4; /* RTC */ - } BIT; /* */ - } IPRA; /* */ - union { /* IPRB */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _WDT:4; /* WDT */ - unsigned short _REF:4; /* REF */ - } BIT; /* */ - } IPRB; /* */ - char wk[234]; /* */ - unsigned int TRA; /* TRA */ - unsigned int EXPEVT; /* EXPEVT */ - unsigned int INTEVT; /* INTEVT */ -}; -struct st_intx { /* struct INTX */ - unsigned int INTEVT2; /* INTEVT2 */ - union { /* IRR0 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char PINT0R:1; /* PINT0R */ - unsigned char PINT1R:1; /* PINT1R */ - unsigned char IRQ5R :1; /* IRQ5R */ - unsigned char IRQ4R :1; /* IRQ4R */ - unsigned char IRQ3R :1; /* IRQ3R */ - unsigned char IRQ2R :1; /* IRQ2R */ - unsigned char IRQ1R :1; /* IRQ1R */ - unsigned char IRQ0R :1; /* IRQ0R */ - } BIT; /* */ - } IRR0; /* */ - char wk1; /* */ - union { /* IRR1 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char TXI0R:1; /* TXI0R */ - unsigned char :1; /* */ - unsigned char RXI0R:1; /* RXI0R */ - unsigned char ERI0R:1; /* ERI0R */ - unsigned char DEI3R:1; /* DEI3R */ - unsigned char DEI2R:1; /* DEI2R */ - unsigned char DEI1R:1; /* DEI1R */ - unsigned char DEI0R:1; /* DEI0R */ - } BIT; /* */ - } IRR1; /* */ - char wk2; /* */ - union { /* IRR2 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :3; /* */ - unsigned char ADIR :1; /* ADIR */ - unsigned char TXI2R:1; /* TXI2R */ - unsigned char :1; /* */ - unsigned char RXI2R:1; /* RXI2R */ - unsigned char ERI2R:1; /* ERI2R */ - } BIT; /* */ - } IRR2; /* */ - char wk3[7]; /* */ - union { /* ICR1 */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short MAI :1; /* MAI */ - unsigned short IRQLVL:1; /* IRQLVL */ - unsigned short BLMSK :1; /* BLMSK */ - unsigned short :1; /* */ - unsigned short IRQ5S :2; /* IRQ5S */ - unsigned short IRQ4S :2; /* IRQ4S */ - unsigned short IRQ3S :2; /* IRQ3S */ - unsigned short IRQ2S :2; /* IRQ2S */ - unsigned short IRQ1S :2; /* IRQ1S */ - unsigned short IRQ0S :2; /* IRQ0S */ - } BIT; /* */ - } ICR1; /* */ - union { /* ICR2 */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PINT15S:1; /* PINT15S */ - unsigned short PINT14S:1; /* PINT14S */ - unsigned short PINT13S:1; /* PINT13S */ - unsigned short PINT12S:1; /* PINT12S */ - unsigned short PINT11S:1; /* PINT11S */ - unsigned short PINT10S:1; /* PINT10S */ - unsigned short PINT9S :1; /* PINT9S */ - unsigned short PINT8S :1; /* PINT8S */ - unsigned short PINT7S :1; /* PINT7S */ - unsigned short PINT6S :1; /* PINT6S */ - unsigned short PINT5S :1; /* PINT5S */ - unsigned short PINT4S :1; /* PINT4S */ - unsigned short PINT3S :1; /* PINT3S */ - unsigned short PINT2S :1; /* PINT2S */ - unsigned short PINT1S :1; /* PINT1S */ - unsigned short PINT0S :1; /* PINT0S */ - } BIT; /* */ - } ICR2; /* */ - union { /* PINTER */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PINT15E:1; /* PINT15E */ - unsigned short PINT14E:1; /* PINT14E */ - unsigned short PINT13E:1; /* PINT13E */ - unsigned short PINT12E:1; /* PINT12E */ - unsigned short PINT11E:1; /* PINT11E */ - unsigned short PINT10E:1; /* PINT10E */ - unsigned short PINT9E :1; /* PINT9E */ - unsigned short PINT8E :1; /* PINT8E */ - unsigned short PINT7E :1; /* PINT7E */ - unsigned short PINT6E :1; /* PINT6E */ - unsigned short PINT5E :1; /* PINT5E */ - unsigned short PINT4E :1; /* PINT4E */ - unsigned short PINT3E :1; /* PINT3E */ - unsigned short PINT2E :1; /* PINT2E */ - unsigned short PINT1E :1; /* PINT1E */ - unsigned short PINT0E :1; /* PINT0E */ - } BIT; /* */ - } PINTER; /* */ - union { /* IPRC */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _IRQ3:4; /* IRQ3 */ - unsigned short _IRQ2:4; /* IRQ2 */ - unsigned short _IRQ1:4; /* IRQ1 */ - unsigned short _IRQ0:4; /* IRQ0 */ - } BIT; /* */ - } IPRC; /* */ - union { /* IPRD */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _PINT0_7 :4; /* PINT0-7 */ - unsigned short _PINT8_15:4; /* PINT8-15 */ - unsigned short _IRQ5 :4; /* IRQ5 */ - unsigned short _IRQ4 :4; /* IRQ4 */ - } BIT; /* */ - } IPRD; /* */ - union { /* IPRE */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _DMAC :4; /* DMAC */ - unsigned short _SCIF0:4; /* SCIF0 */ - unsigned short _SCIF2:4; /* SCIF2 */ - unsigned short _ADC :4; /* ADC */ - } BIT; /* */ - } IPRE; /* */ - char wk4[524260]; /* */ - union { /* IPRF */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :8; /* */ - unsigned short _USB:4; /* USB */ - } BIT; /* */ - } IPRF; /* */ - union { /* IPRG */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _TPU0:4; /* TPU0 */ - unsigned short _TPU1:4; /* TPU1 */ - } BIT; /* */ - } IPRG; /* */ - union { /* IPRH */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short _TPU2:4; /* TPU2 */ - unsigned short _TPU3:4; /* TPU3 */ - } BIT; /* */ - } IPRH; /* */ -}; -struct st_scif { /* struct SCIF */ - union { /* SCSMR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :5; /* */ - unsigned short SRC :3; /* SRC */ - unsigned short CA :1; /* CA */ - unsigned short CHR :1; /* CHR */ - unsigned short _PE :1; /* PE */ - unsigned short OE :1; /* O/E */ - unsigned short STOP:1; /* STOP */ - unsigned short :1; /* */ - unsigned short CKS :2; /* CKS */ - } BIT; /* */ - } SCSMR; /* */ - char wk1[2]; /* */ - unsigned char SCBRR; /* SCBRR */ - char wk2[3]; /* */ - union { /* SCSCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :4; /* */ - unsigned short TSIE:1; /* TSIE */ - unsigned short ERIE:1; /* ERIE */ - unsigned short BRIE:1; /* BRIE */ - unsigned short DRIE:1; /* DRIE */ - unsigned short TIE :1; /* TIE */ - unsigned short RIE :1; /* RIE */ - unsigned short TE :1; /* TE */ - unsigned short RE :1; /* RE */ - unsigned short :2; /* */ - unsigned short CKE :2; /* CKE */ - } BIT; /* */ - } SCSCR; /* */ - char wk3[2]; /* */ - unsigned char SCTDSR; /* SCTDSR */ - char wk4[3]; /* */ - union { /* SCFER */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :2; /* */ - unsigned short PER:6; /* PER */ - unsigned short :2; /* */ - unsigned short FER:6; /* FER */ - } BIT; /* */ - } SCFER; /* */ - char wk5[2]; /* */ - union { /* SCSSR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :6; /* */ - unsigned short ORER:1; /* ORER */ - unsigned short TSF :1; /* TSF */ - unsigned short ER :1; /* ER */ - unsigned short TEND:1; /* TEND */ - unsigned short TDFE:1; /* TDFE */ - unsigned short BRK :1; /* BRK */ - unsigned short FER :1; /* FER */ - unsigned short PER :1; /* PER */ - unsigned short RDF :1; /* RDF */ - unsigned short DR :1; /* DR */ - } BIT; /* */ - } SCSSR; /* */ - char wk6[2]; /* */ - union { /* SCFCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short TSE :1; /* TSE */ - unsigned short TCRST:1; /* TCRST */ - unsigned short :3; /* */ - unsigned short RSTRG:3; /* RSTRG */ - unsigned short RTRG :2; /* RTRG */ - unsigned short TTRG :2; /* TTRG */ - unsigned short MCE :1; /* MCE */ - unsigned short TFRST:1; /* TFRST */ - unsigned short RFRST:1; /* RFRST */ - unsigned short LOOP :1; /* LOOP */ - } BIT; /* */ - } SCFCR; /* */ - char wk7[2]; /* */ - union { /* SCFDR */ - unsigned short WORD; /* Word Access */ - struct { /* Byte Access */ - unsigned short :1; /* */ - unsigned short T:7; /* T */ - unsigned short :1; /* */ - unsigned short R:7; /* R */ - } BIT; /* */ - } SCFDR; /* */ - char wk8[2]; /* */ - unsigned char SCFTDR; /* SCFTDR */ - char wk9[3]; /* */ - unsigned char SCFRDR; /* SCFRDR */ -}; /* */ -union un_stbcr3 { /* union STBCR3 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char _USB :1; /* USB */ - unsigned char :1; /* */ - unsigned char _CMT :1; /* CMT */ - unsigned char _TPU :1; /* TPU */ - unsigned char _ADC :1; /* ADC */ - unsigned char _IrDA :1; /* IrDA */ - unsigned char _SCIF2:1; /* SCIF2 */ - unsigned char _SCIF0:1; /* SCIF0 */ - } BIT; /* */ -}; /* */ -struct st_pfc { /* struct PFC */ - union { /* PACR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PA7MD:2; /* PA7MD */ - unsigned short PA6MD:2; /* PA6MD */ - unsigned short PA5MD:2; /* PA5MD */ - unsigned short PA4MD:2; /* PA4MD */ - unsigned short PA3MD:2; /* PA3MD */ - unsigned short PA2MD:2; /* PA2MD */ - unsigned short PA1MD:2; /* PA1MD */ - unsigned short PA0MD:2; /* PA0MD */ - } BIT; /* */ - } PACR; /* */ - union { /* PBCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PB7MD:2; /* PB7MD */ - unsigned short PB6MD:2; /* PB6MD */ - unsigned short PB5MD:2; /* PB5MD */ - unsigned short PB4MD:2; /* PB4MD */ - unsigned short PB3MD:2; /* PB3MD */ - unsigned short PB2MD:2; /* PB2MD */ - unsigned short PB1MD:2; /* PB1MD */ - unsigned short PB0MD:2; /* PB0MD */ - } BIT; /* */ - } PBCR; /* */ - union { /* PCCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PC7MD:2; /* PC7MD */ - unsigned short PC6MD:2; /* PC6MD */ - unsigned short PC5MD:2; /* PC5MD */ - unsigned short PC4MD:2; /* PC4MD */ - unsigned short PC3MD:2; /* PC3MD */ - unsigned short PC2MD:2; /* PC2MD */ - unsigned short PC1MD:2; /* PC1MD */ - unsigned short PC0MD:2; /* PC0MD */ - } BIT; /* */ - } PCCR; /* */ - union { /* PDCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PD7MD:2; /* PD7MD */ - unsigned short PD6MD:2; /* PD6MD */ - unsigned short PD5MD:2; /* PD5MD */ - unsigned short PD4MD:2; /* PD4MD */ - unsigned short PD3MD:2; /* PD3MD */ - unsigned short PD2MD:2; /* PD2MD */ - unsigned short PD1MD:2; /* PD1MD */ - unsigned short PD0MD:2; /* PD0MD */ - } BIT; /* */ - } PDCR; /* */ - union { /* PECR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PE7MD:2; /* PE7MD */ - unsigned short PE6MD:2; /* PE6MD */ - unsigned short PE5MD:2; /* PE5MD */ - unsigned short PE4MD:2; /* PE4MD */ - unsigned short PE3MD:2; /* PE3MD */ - unsigned short PE2MD:2; /* PE2MD */ - unsigned short PE1MD:2; /* PE1MD */ - unsigned short PE0MD:2; /* PE0MD */ - } BIT; /* */ - } PECR; /* */ - union { /* PFCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PF7MD:2; /* PF7MD */ - unsigned short PF6MD:2; /* PF6MD */ - unsigned short PF5MD:2; /* PF5MD */ - unsigned short PF4MD:2; /* PF4MD */ - unsigned short PF3MD:2; /* PF3MD */ - unsigned short PF2MD:2; /* PF2MD */ - unsigned short PF1MD:2; /* PF1MD */ - unsigned short PF0MD:2; /* PF0MD */ - } BIT; /* */ - } PFCR; /* */ - union { /* PGCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PG7MD:2; /* PG7MD */ - unsigned short PG6MD:2; /* PG6MD */ - unsigned short PG5MD:2; /* PG5MD */ - unsigned short PG4MD:2; /* PG4MD */ - unsigned short PG3MD:2; /* PG3MD */ - unsigned short PG2MD:2; /* PG2MD */ - unsigned short PG1MD:2; /* PG1MD */ - unsigned short PG0MD:2; /* PG0MD */ - } BIT; /* */ - } PGCR; /* */ - union { /* PHCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :2; /* */ - unsigned short PH6MD:2; /* PH6MD */ - unsigned short PH5MD:2; /* PH5MD */ - unsigned short PH4MD:2; /* PH4MD */ - unsigned short PH3MD:2; /* PH3MD */ - unsigned short PH2MD:2; /* PH2MD */ - unsigned short PH1MD:2; /* PH1MD */ - unsigned short PH0MD:2; /* PH0MD */ - } BIT; /* */ - } PHCR; /* */ - union { /* PJCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PJ7MD:2; /* PJ7MD */ - unsigned short PJ6MD:2; /* PJ6MD */ - unsigned short PJ5MD:2; /* PJ5MD */ - unsigned short PJ4MD:2; /* PJ4MD */ - unsigned short PJ3MD:2; /* PJ3MD */ - unsigned short PJ2MD:2; /* PJ2MD */ - unsigned short PJ1MD:2; /* PJ1MD */ - unsigned short PJ0MD:2; /* PJ0MD */ - } BIT; /* */ - } PJCR; /* */ - union { /* PKCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PK7MD:2; /* PK7MD */ - unsigned short PK6MD:2; /* PK6MD */ - unsigned short PK5MD:2; /* PK5MD */ - unsigned short PK4MD:2; /* PK4MD */ - unsigned short PK3MD:2; /* PK3MD */ - unsigned short PK2MD:2; /* PK2MD */ - unsigned short PK1MD:2; /* PK1MD */ - unsigned short PK0MD:2; /* PK0MD */ - } BIT; /* */ - } PKCR; /* */ - union { /* PLCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :8; /* */ - unsigned short PL3MD:2; /* PL3MD */ - unsigned short PL2MD:2; /* PL2MD */ - unsigned short PL1MD:2; /* PL1MD */ - unsigned short PL0MD:2; /* PL0MD */ - } BIT; /* */ - } PLCR; /* */ - union { /* SCPCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :4; /* */ - unsigned short SCP5MD:2; /* SCP5MD */ - unsigned short SCP4MD:2; /* SCP4MD */ - unsigned short SCP3MD:2; /* SCP3MD */ - unsigned short SCP2MD:2; /* SCP2MD */ - unsigned short SCP1MD:2; /* SCP1MD */ - unsigned short SCP0MD:2; /* SCP0MD */ - } BIT; /* */ - } SCPCR; /* */ - union { /* PMCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short :2; /* */ - unsigned short PM6MD:2; /* PM6MD */ - unsigned short :2; /* */ - unsigned short PM4MD:2; /* PM4MD */ - unsigned short PM3MD:2; /* PM3MD */ - unsigned short PM2MD:2; /* PM2MD */ - unsigned short PM1MD:2; /* PM1MD */ - unsigned short PM0MD:2; /* PM0MD */ - } BIT; /* */ - } PMCR; /* */ - union { /* PNCR */ - unsigned short WORD; /* Word Access */ - struct { /* Bit Access */ - unsigned short PN7MD:2; /* PN7MD */ - unsigned short PN6MD:2; /* PN6MD */ - unsigned short PN5MD:2; /* PN5MD */ - unsigned short PN4MD:2; /* PN4MD */ - unsigned short PN3MD:2; /* PN3MD */ - unsigned short PN2MD:2; /* PN2MD */ - unsigned short PN1MD:2; /* PN1MD */ - unsigned short PN0MD:2; /* PN0MD */ - } BIT; /* */ - } PNCR; /* */ - char wk1[327724]; /* */ - union { /* PECR2 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* */ - unsigned char PE6MD:1; /* PE6MD */ - unsigned char PE5MD:1; /* PE5MD */ - unsigned char PE4MD:1; /* PE4MD */ - } BIT; /* */ - } PECR2; /* */ - char wk2; /* */ - union { /* PFCR2 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :4; /* */ - unsigned char PF3MD:1; /* PF3MD */ - unsigned char PF2MD:1; /* PF2MD */ - unsigned char PF1MD:1; /* PF1MD */ - unsigned char PF0MD:1; /* PF0MD */ - } BIT; /* */ - } PFCR2; /* */ - char wk3[15]; /* */ - union { /* PNCR2 */ - unsigned char BYTE; /* Byte Access */ - struct { /* Bit Access */ - unsigned char :1; /* */ - unsigned char PN6MD:1; /* PN6MD */ - unsigned char PN5MD:1; /* PN5MD */ - unsigned char PN4MD:1; /* PN4MD */ - unsigned char PN3MD:1; /* PN3MD */ - unsigned char PN2MD:1; /* PN2MD */ - unsigned char PN1MD:1; /* PN1MD */ - unsigned char PN0MD:1; /* PN0MD */ - } BIT; /* */ - } PNCR2; /* */ -}; /* */ - -struct st_mmu { - union { - unsigned int LONG; - struct { - unsigned int :23; - unsigned char SV :1; - unsigned char :2; - unsigned char RC :2; - unsigned char :1; - unsigned char TF :1; - unsigned char IX :1; - unsigned char AT :1; - } BIT; - } MMUCR; - - char wk1[12]; - union { - unsigned int LONG; - struct { - unsigned int VPN :22; - unsigned char :2; - unsigned char ASID :8; - } BIT; - } PTEH; - - union { - unsigned int LONG; - struct { - unsigned char :3; - unsigned int :19; - unsigned char :1; - unsigned char V :1; - unsigned char :1; - unsigned char PR :2; - unsigned char SZ :1; - unsigned char C :1; - unsigned char D :1; - unsigned char SH :1; - unsigned char :1; - } BIT; - } PTEL; - - unsigned int TTB; -}; - - -struct st_ubc { - unsigned int BDRB; - - unsigned int BDMRB; - - union { - unsigned int LONG; - struct { - unsigned short :10; - unsigned int BASMA :1; - unsigned int BASMB :1; - unsigned int :4; - unsigned int SCMFCA :1; - unsigned int SCMFCB :1; - unsigned int SCMFDA :1; - unsigned int SCMFDB :1; - unsigned int PCTE :1; - unsigned int PCBA :1; - unsigned int :2; - unsigned int DBEB :1; - unsigned int PCBB :1; - unsigned int :2; - unsigned int SEQ :1; - unsigned int :2; - unsigned int ETBE :1; - } BIT; - } BRCR; - - unsigned short BETR; - - char wk1[2]; - - unsigned int BARB; - - unsigned int BAMRB; - - union { - unsigned short WORD; - struct { - unsigned short :8; - unsigned short CDB :2; - unsigned short IDB :2; - unsigned short RWB :2; - unsigned short SZB :2; - } BIT; - } BBRB; - - char wk2[2]; - - union { - unsigned int LONG; - struct { - unsigned int SVF :1; - unsigned char :3; - unsigned int BSA :28; - } BIT; - } BRSR; - - unsigned int BARA; - - unsigned int BAMRA; - - union { - unsigned short WORD; - struct { - unsigned short :8; - unsigned short CDA :2; - unsigned short IDA :2; - unsigned short RWA :2; - unsigned short SZA :2; - } BIT; - } BBRA; - - char wk3[2]; - - union { - unsigned int LONG; - struct { - unsigned int DVF :1; - unsigned char :3; - unsigned int BDA :28; - } BIT; - } BRDR; - - char wk4[36]; - - unsigned char BASRA; - - char wk5[3]; - - unsigned char BASRB; -}; - - -union un_stbcr2 { - unsigned char BYTE; - struct { - unsigned char _UDI :1; - unsigned char _UBC :1; - unsigned char _DMAC :1; - unsigned char :1; - unsigned char _TLB :1; - unsigned char _CACHE :1; - unsigned char :2; - } BIT; -}; - - - -#define CPG (*(volatile struct st_cpg *)0xffffff80) -#define WDT (*(volatile struct st_wdt *)0xffffff84) -#define INTC (*(volatile struct st_intc *)0xfffffee0) -#define INTX (*(volatile struct st_intx *)0xa4000000) -#define PA (*(volatile struct st_pa *)0xa4000120) -#define PB (*(volatile struct st_pb *)0xa4000122) -#define PC (*(volatile struct st_pc *)0xa4000124) -#define PD (*(volatile struct st_pd *)0xa4000126) -#define PE (*(volatile struct st_pe *)0xa4000128) -#define PF (*(volatile struct st_pf *)0xa400012a) -#define PG (*(volatile struct st_pg *)0xa400012c) -#define PH (*(volatile struct st_ph *)0xa400012e) -#define PJ (*(volatile struct st_pj *)0xa4000130) -#define PK (*(volatile struct st_pk *)0xa4000132) -#define PL (*(volatile struct st_pl *)0xa4000134) -#define SCP (*(volatile struct st_scp *)0xa4000136) -#define PM (*(volatile struct st_pm *)0xa4000138) -#define PN (*(volatile struct st_pn *)0xa400013a) -#define USB (*(volatile struct st_usb *)0xa40a0008) -#define SCIF0 (*(volatile struct st_scif *)0xa4400000) -#define SCIF2 (*(volatile struct st_scif *)0xa4410000) -#define STBCR3 (*(volatile union un_stbcr3 *)0xa40a0000) -#define PFC (*(volatile struct st_pfc *)0xa4000100) -#define TEA (*(volatile unsigned int *)0xfffffffc) -#define MMU (*(volatile struct st_mmu *)0xffffffe0) -#define UBC (*(volatile struct st_ubc *)0xffffff90) -#define STBCR2 (*(volatile union un_stbcr2 *)0xffffff88) - -#endif // _7705_H diff --git a/include/alloca.h b/include/alloca.h deleted file mode 100644 index 2011266..0000000 --- a/include/alloca.h +++ /dev/null @@ -1,25 +0,0 @@ -//--- -// -// standard library module: alloca -// -// Allows dynamic memory allocation on the stack. Memory is automatically -// freed when the calling function exits, but this function suffers from -// risks of stack overflow; make sure you don't inline functions that use -// alloca or allocate more than a few hundred bytes with it. -// -//--- - -#ifndef _ALLOCA_H -#define _ALLOCA_H - -#include - -/* - alloca() - Allocates a memory block on the stack. -*/ -void *alloca(size_t size); - -#define alloca(size) __builtin_alloca(size) - -#endif // _ALLOCA_H diff --git a/include/bfile.h b/include/bfile.h deleted file mode 100644 index 81c0599..0000000 --- a/include/bfile.h +++ /dev/null @@ -1,74 +0,0 @@ -//--- -// -// gint core module: BFile interface -// -// Syscall-based interface to the BFile driver (which I would never dare -// to re-write considering how much the storage memory filesystem is an -// awful mess). -// -//--- - -#ifndef _BFILE_H -#define _BFILE_H - -/* - BFile_Remove() - Remove a file from the filesystem. The path must be encoded as two-byte - fontcharacters! -*/ -int BFile_Remove(const uint16_t *file); - -/* - BFile_Create() - Creates an entry in the filesystem (two-byte fontcharacter path) of the - given type. The size pointer must point to the file size for files, and - may be NULL for folders. -*/ -enum BFile_EntryType -{ - BFile_File = 1, - BFile_Folder = 5, -}; -int BFile_Create(const uint16_t *file, enum BFile_EntryType type, int *size); - -/* - BFile_Open() - Opens an existing file (two-byte fontcharacter path) with the required - mode, and returns a handle (positive integer) on success, or an - negative integer on error. -*/ -enum BFile_OpenMode -{ - BFile_ReadOnly = 0x01, - BFile_WriteOnly = 0x02, - BFile_ReadWrite = BFile_ReadOnly | BFile_WriteOnly, -}; -int BFile_Open(const uint16_t *file, enum BFile_OpenMode mode); - -/* - BFile_Close() - Closes an open file. -*/ -int BFile_Close(int handle); - -/* - BFile_Write() - Writes data to a file. The data is taken from the second-argument - buffer. The size to write is given as third argument. - WARNING: Always write an even number of bytes or you're in for trouble! -*/ -int BFile_Write(int handle, const void *ram_buffer, int even_size); - -/* - BFile_Read() - Reads from an open file. The second and third arguments indicate where - to store data and how much to read. The location from where the data is - read depends on the value of `whence`: - - If `whence` >= 0, it is considered as the absolute location (in - bytes) of the requested data in the file; - - If `whence` == -1, BFile_Read() reads from the current virtual - position in the file. -*/ -int BFile_Read(int handle, void *ram_buffer, int size, int whence); - -#endif // _BFILE_H diff --git a/include/bopti.h b/include/bopti.h deleted file mode 100644 index 95465c7..0000000 --- a/include/bopti.h +++ /dev/null @@ -1,73 +0,0 @@ -//--- -// -// gint drawing module: bopti -// -// This module is a powerful bitmap renderer. It *heavily* relies on the -// line-based structure of the video RAM as well as the high density of -// information. A single CPU access (longword operation) can affect 32 -// pixels at once, which is crucial for performance. The same goes for all -// other drawing modules, but this one typically has 350 lines of code -// just to wrap these longword accesses -- and it's blazingly fast. -// -//--- - -#ifndef _BOPTI_H -#define _BOPTI_H - -/* - image_t - This structure holds meta-data of a bitmap encoded with fxconv. Data is - accessed using longword operations for performance considerations, - which requires that the all fields of the structure be properly aligned - and of a correct size. -*/ -typedef struct -{ - uint8_t magic; - uint8_t format; - - uint8_t width; - uint8_t height; - - const uint32_t data[]; - -} __attribute__((packed, aligned(4))) image_t; - -/* - dimage() - Displays a monochrome image in the vram. This function does a real lot - of optimization. -*/ -void dimage(int x, int y, image_t *image); - -/* - dimage_part() - Draws a portion of an image, defined by its bounding rectangle. - Point (left, top) is included, but (left + width, top + height) is - excluded. -*/ -void dimage_part( - int x, int y, - image_t *img, - int left, int top, int width, int height -); - -/* - gimage() - Displays a gray image in the dual-vram. -*/ -void gimage(int x, int y, image_t *image); - -/* - gimage_part() - Draws a portion of a gray image, defined by its bounding rectangle. - Point (left, top) is included, but (left + width, top + height) is - excluded. -*/ -void gimage_part( - int x, int y, - image_t *image, - int left, int top, int width, int height -); - -#endif // _BOPTI_H diff --git a/include/clock.h b/include/clock.h deleted file mode 100644 index 571b56c..0000000 --- a/include/clock.h +++ /dev/null @@ -1,121 +0,0 @@ -//--- -// -// gint core module: clock -// -// This module interfaces with the MPU clocks and is used to measure the -// clock frequencies at the beginning of execution. At this stage, it -// assumes that clock mode 3 is used on SH7305 (as does FTune), because -// there doesn't seem to be a way of getting this information. -// -// It also provides some sleep and time conversion functions, and access -// to how the clocks are configured. In the future, it would be the module -// that supports overclock. -// -//--- - -#ifndef _CLOCK_H -#define _CLOCK_H - -#include - -//--- -// Sleep functions. -//--- - -/* - sleep() - Puts the processor to sleep until an interrupt request is accepted. - This function should be called every time the program because idle - because it doesn't have anything to do -- between two game frames or - while waiting for a keyboard event. - This function is called by getkey_opt(), getkey(), waitevent(), this - module's sleep functions among others. -*/ -void sleep(void); - -/* - sleep_ms() - Sleeps for the given number of milliseconds using a virtual timer. -*/ -void sleep_ms(int ms_delay); - -/* - sleep_us() - Sleeps for the given number of microseconds using the hardware timer - timer_user. -*/ -void sleep_us(int us_delay); - - - -//--- -// Clock management. -//--- - -/* - clock_unit_t - Enumerated type used by the time conversion functions. It indicates the - type (delay or frequency) of a parameter. -*/ -typedef enum -{ - clock_us = 0, - clock_ms = 1, - clock_s = 2, - - clock_Hz = 10, - clock_kHz = 11, - clock_MHz = 12, - -} clock_unit_t; - -/* - clock_config_t - A copy of the Clock Pulse Generator (CPG) configuration. Be sure to - check which MPU the program is running on (using ) to access the - right fields. -*/ -typedef struct -{ - union - { - int PLL1; // SH7705 - int FLL; // SH7305 - }; - union - { - int PLL2; // SH7705 - int PLL; // SH7305 - }; - - int Bphi_div1; - int Iphi_div1; - int Pphi_div1; - - union - { - int CKIO_f; // SH7705 - int RTCCLK_f; // SH7305 - }; - - int Bphi_f; // Bus clock frequency - int Iphi_f; // Processor clock frequency - int Pphi_f; // Peripheral clock frequency - -} clock_config_t; - -/* - clock_setting() - Returns the P_phi / 4 timer setting that will last for the given time. - Several units can be used. Be aware that the result is approximate, and - very high frequencies or very short delays will yield important errors. -*/ -uint32_t clock_setting(int duration, clock_unit_t unit); - -/* - clock_config() - Returns a copy of what the library knows about the clocks. -*/ -clock_config_t clock_config(void); - -#endif // _CLOCK_H diff --git a/include/ctype.h b/include/ctype.h deleted file mode 100644 index 3037ccd..0000000 --- a/include/ctype.h +++ /dev/null @@ -1,35 +0,0 @@ -//--- -// -// standard library module: ctype -// -// Some character manipulation. -// -//--- - -#ifndef _CTYPE_H -#define _CTYPE_H - -#include - -extern uint8_t ctype_classes[0x80]; - -// Character classes. -#define isalnum(c) (ctype_classes[(int)(c)] & 0xf0) -#define isalpha(c) (ctype_classes[(int)(c)] & 0x30) -#define iscntrl(c) (ctype_classes[(int)(c)] & 0x01) -#define isdigit(c) (ctype_classes[(int)(c)] & 0x40) -#define isgraph(c) (ctype_classes[(int)(c)] & 0xf4) -#define islower(c) (ctype_classes[(int)(c)] & 0x10) -#define isprint(c) (ctype_classes[(int)(c)] & 0x08) -#define ispunct(c) (ctype_classes[(int)(c)] & 0x04) -#define isspace(c) (ctype_classes[(int)(c)] & 0x02) -#define isupper(c) (ctype_classes[(int)(c)] & 0x20) -#define isxdigit(c) (ctype_classes[(int)(c)] & 0x80) -#define isascii(c) ((unsigned)c <= 0x7f) -#define isblank(c) (c == '\t' || c == ' ') - -// Character manipulation. -#define tolower(c) ((c) | isupper(c)) -#define toupper(c) ((c) & ~(islower(c) << 1)) - -#endif // _CTYPE_H diff --git a/include/display.h b/include/display.h deleted file mode 100644 index 924c6dc..0000000 --- a/include/display.h +++ /dev/null @@ -1,156 +0,0 @@ -//--- -// -// gint drawing module: display -// -// This module does most of the monochrome drawing. It manages the video -// memory although image rendering and text rendering, as complex tasks, -// are left to other modules (bopti and tales, respectively). -// -//--- - -#ifndef _DISPLAY_H -#define _DISPLAY_H - -#include -#include - -//--- -// Drawing-related types and constants. -//--- - -#define DWIDTH 128 /* Width of the screen */ -#define DHEIGHT 64 /* Height of the screen */ - -/* - color_t - Defines all colors that the library knows about: - - white is exactly what you think it is; - - light is a light gray used by the gray module; - - dark is a dark gray, also used by the gray engine; - - black is nothing more than black; (sorry) - - none means transparent, but is shorter to write. - There are also some transformation-associated colors: - - invert reverses the intensity of the color (white -> black, dark -> - light, etc); - - lighten is some kind of partially-transparent white. It lightens the - color which it is drawn onto (black -> dark, light -> light); - - lighten2 is the same as lighten, except it lightens more (black -> - light, light -> white); - - darken is the exact opposite of lighten (light -> dark, black -> - black). - - darken2 is the same to darken as lighten2 to lighten (white -> dark, - dark -> black); - All transformations except invert only operate when the gray engine is - running. -*/ -typedef enum -{ - color_white = 0, - color_light = 1, - color_dark = 2, - color_black = 3, - color_none = 4, - - color_invert = 5, - color_lighten = 6, - color_lighten2 = 7, - color_darken = 8, - color_darken2 = 9, - -} color_t; - -// The bopti module provides bitmap rendering functions. -#include - -// The tales module provides text rendering functions but requires the color_t -// type definition. -#include - - - -//--- -// Video RAM management. -//--- - -/* - display_getLocalVRAM() - Returns gint's local video RAM address. Gint does not use the system's - buffer because it is misaligned. This function always returns the same - address. Both the display and the gray module heavily use this buffer; - make sure you don't interfere with them if you access it. - This function does not necessarily returns the video ram that is - currently in use; call display_getCurrentVRAM() for this. -*/ -uint32_t *display_getLocalVRAM(void); - -/* - display_getCurrentVRAM() - Returns the current monochrome video ram buffer. This function usually - returns the parameter of the last call to display_useVRAM(), or the - local vram address (which is default when the library starts). - The return value of this function is undefined if the gray engine is - running. -*/ -uint32_t *display_getCurrentVRAM(void); - -/* - display_useVRAM() - Changes the current monochrome video ram address. The argument must be - a 4-aligned 1024-byte buffer because the library's design requires it. - This function refuses misaligned buffers but trusts that enough space - is available; failing to provide enough memory may crash the program. - This function will most likely have no effect when running the gray - engine. -*/ -void display_useVRAM(uint32_t *vram); - - - -//--- -// Global drawing functions. -//--- - -/* - dupdate() - Pushes the video RAM to the physical screen. This function also works - when the gray engine is running, but that's probably not what you want. -*/ -void dupdate(void); - -/* - dclear() - Clears the whole video ram, making all pixels white. -*/ -void dclear(void); - -/* - drect() - Draws a rectangle on the screen. This function can use any color which - is not associated with the gray engine, including the reverse operator. - Both end points (x1, y1) and (x2, y2) are affected as well. -*/ -void drect(int x1, int y1, int x2, int y2, color_t operator); - - - -//--- -// Local drawing functions. -//--- - -/* - dpixel() - Changes a pixel's color in the video ram. The result may depend on the - current color of the pixel. -*/ -void dpixel(size_t x, size_t y, color_t operator); - -/* - dline() - Draws a line in the vram. Automatically optimizes horizontal and - vertical lines. - - Uses an algorithm written by PierrotLL for MonochromeLib. -*/ -void dline(int x1, int y1, int x2, int y2, color_t operator); - -#endif // _DISPLAY_H diff --git a/include/events.h b/include/events.h deleted file mode 100644 index b4bce55..0000000 --- a/include/events.h +++ /dev/null @@ -1,113 +0,0 @@ -//--- -// -// gint core module: events -// -// Finally some user-friendly API. This module is in charge of managing -// the event queue. The waitevent() function should be particularly useful -// in program main loops to record key presses and releases in real-time -// games. -// -// Other functions such as the getkey() of the keyboard module provide -// more advanced features such as SHIFT and ALPHA modifiers, backlight -// control for instance; these functions rely on this module and they -// ignore all events that they do not handle. If you want to catch several -// types of events (eg. keyboard and serial communication), then you need -// to use directly this module. -// -//--- - -#ifndef _EVENTS_H -#define _EVENTS_H - -#include - -/* - event_type_t - Something user programs will surely use most often. -*/ -typedef enum -{ - // Specific events. - event_none = 0, - event_user = 1, - - // Keyboard events. - event_key_press = 2, - event_key_repeat = 3, - event_key_release = 4, - - // Other events. - event_timer_underflow = 5, - -} event_type_t; - -/* - key_event_t - Keyboard events. "I think the user wants something." -*/ -typedef struct -{ - // This is the key code as defined in (a matrix code), and - // probably what you need. - uint16_t code; - // This is a "compact id" which can be used for array subscript. There - // are only a few holes in the "compact id" numbering. - uint16_t id; - // Character associated with the event key. - int character; - -} __attribute__((packed, aligned(4))) key_event_t; - -/* - event_t - Wake up, something's going on. The union member that holds information - about the event is specified by the type attribute. -*/ -typedef struct -{ - event_type_t type; - - union - { - // For event_user. - void *data; - // For event_key_press, event_key_repeat and event_key_release. - key_event_t key; - // For event_timer_underflow. - timer_t *timer; - }; - -} __attribute__((packed, aligned(4))) event_t; - - - -//--- -// Event management. -//--- - -/* - event_push() - Queues a user-defined event, allowing it to be retrieved by getevent() - or pollevent() later. Most often you will not need to use this, as - system events are automatically queued. Pushing ET_None events is not - allowed. - Returns non-zero on error. -*/ -int event_push(event_t event); - -/* - waitevent() - Returns the next event. If no one is available, waits for something to - happen. This function uses low-level sleep and should be preferred to - active waiting using loops. -*/ -event_t waitevent(void); - -/* - pollevent() - Returns the next event. If no one is available, returns an event whose - type is ET_None. This function always returns immediately. -*/ -event_t pollevent(void); - -#endif // _EVENTS_H diff --git a/include/extended/endian.h b/include/extended/endian.h deleted file mode 100644 index b6f5d6f..0000000 --- a/include/extended/endian.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _ENDIAN_H -#define _ENDIAN_H - -#include - -//--- -// Assembler-optimized byte-ordering functions. -//--- - -__attribute__((always_inline)) static inline uint16_t swap16(uint16_t word) -{ - uint16_t result; - __asm__("swap.b %1, %0": "=r"(result): "r"(word)); - return result; -} - -__attribute__((always_inline)) static inline uint32_t swap32(uint32_t longw) -{ - uint32_t result; - __asm__( - "swap.b %1, r0 \n\t" - "swap.w r0, r0 \n\t" - "swap.b r0, %0 \n\t" - : "=r"(result) - : "r"(longw) - : "r0" - ); - return result; -} - - - -//--- -// Conversion of values of different endianness. -//--- - -#define htobe16(host16) (host16) -#define htole16(host16) (swap16(host16)) -#define be16toh(be16) (be16) -#define le16toh(le16) (swap16(le16)) - -#define htobe32(host32) (host32) -#define htole32(host32) (swap32(host32)) -#define be32toh(be32) (be32) -#define le32toh(le32) (swap32(le32)) - -#endif // _ENDIAN_H diff --git a/include/extended/inttypes.h b/include/extended/inttypes.h deleted file mode 100644 index 5864d31..0000000 --- a/include/extended/inttypes.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef _INTTYPES_H -#define _INTTYPES_H - -// Decimal notation. -#define PRId8 "d" -#define PRId16 "d" -#define PRId32 "d" -#define PRId64 "lld" - -#define PRIdLEAST8 "d" -#define PRIdLEAST16 "d" -#define PRIdLEAST32 "d" -#define PRIdLEAST64 "lld" - -#define PRIdFAST8 "d" -#define PRIdFAST16 "d" -#define PRIdFAST32 "d" -#define PRIdFAST64 "lld" - -// Decimal notation, again. -#define PRIi8 "i" -#define PRIi16 "i" -#define PRIi32 "i" -#define PRIi64 "lli" - -#define PRIiLEAST8 "i" -#define PRIiLEAST16 "i" -#define PRIiLEAST32 "i" -#define PRIiLEAST64 "lli" - -#define PRIiFAST8 "i" -#define PRIiFAST16 "i" -#define PRIiFAST32 "i" -#define PRIiFAST64 "lli" - -// Octal notation. -#define PRIo8 "o" -#define PRIo16 "o" -#define PRIo32 "o" -#define PRIo64 "llo" - -#define PRIoLEAST8 "o" -#define PRIoLEAST16 "o" -#define PRIoLEAST32 "o" -#define PRIoLEAST64 "llo" - -#define PRIoFAST8 "o" -#define PRIoFAST16 "o" -#define PRIoFAST32 "o" -#define PRIoFAST64 "llo" - -// Unsigned integers. -#define PRIu8 "u" -#define PRIu16 "u" -#define PRIu32 "u" -#define PRIu64 "llu" - -#define PRIuLEAST8 "u" -#define PRIuLEAST16 "u" -#define PRIuLEAST32 "u" -#define PRIuLEAST64 "llu" - -#define PRIuFAST8 "u" -#define PRIuFAST16 "u" -#define PRIuFAST32 "u" -#define PRIuFAST64 "llu" - -// Lowercase hexadecimal notation. -#define PRIx8 "x" -#define PRIx16 "x" -#define PRIx32 "x" -#define PRIx64 "llx" - -#define PRIxLEAST8 "x" -#define PRIxLEAST16 "x" -#define PRIxLEAST32 "x" -#define PRIxLEAST64 "llx" - -#define PRIxFAST8 "x" -#define PRIxFAST16 "x" -#define PRIxFAST32 "x" -#define PRIxFAST64 "llx" - -// Uppercase hexadecimal notation. -#define PRIX8 "X" -#define PRIX16 "X" -#define PRIX32 "X" -#define PRIX64 "llX" - -#define PRIXLEAST8 "X" -#define PRIXLEAST16 "X" -#define PRIXLEAST32 "X" -#define PRIXLEAST64 "llX" - -#define PRIXFAST8 "X" -#define PRIXFAST16 "X" -#define PRIXFAST32 "X" -#define PRIXFAST64 "llX" - -// Format specifiers of intmax_t and uintmax_t. -#define PRIdMAX "lld" -#define PRIiMAX "lli" -#define PRIoMAX "llo" -#define PRIuMAX "llu" -#define PRIxMAX "llx" -#define PRIXMAX "llX" - -// Format specifiers of intptr_t and uintptr_t. -#define PRIdPTR "d" -#define PRIiPTR "i" -#define PRIoPTR "o" -#define PRIuPTR "u" -#define PRIxPTR "x" -#define PRIXPTR "X" - -#endif // _INTTYPES_H diff --git a/include/gint.h b/include/gint.h deleted file mode 100644 index 3060a89..0000000 --- a/include/gint.h +++ /dev/null @@ -1,251 +0,0 @@ -//--- -// -// gint core module: interrupt handler -// -// This module is the core of the gint library. It controls the interrupt -// handler, allows the user to customize interrupt management, provides -// peripheral register access and some information about the runtime -// environment. -// -//--- - -#ifndef _GINT_H -#define _GINT_H - -#include -#include - -// The version symbol is defined through the linker and consists of four -// fields: -// - Version type, an ascii char ('a'lpha, 'b'eta, 'd'ev, 'r'elease), 8 bits -// - Major version number, 4 bits -// - Minor version number, 4 bits -// - Build number, 16 bits -// Please note that the version number is the *ADDRESS* of GINT_VERSION, which -// you definitely want to cast to uint32_t. Evaluating GINT_VERSION is illegal -// (dereferencing a pointer which is actually a four-field version number just -// cannot work) and will certainly crash your program. -extern uint32_t GINT_VERSION; - -//--- -// System info provided by the library -//--- - -typedef struct -{ - /* Returns the current VBR address. */ - uint32_t (*vbr)(void); - /* Gint's VBR address. */ - uint32_t gint_vbr; - /* The system's VBR address, saved when gint was initialized. */ - uint32_t system_vbr; -} gint_info_t; - -extern gint_info_t gint; - - - -//--- -// Exception and interrupt handlers -//--- - -typedef enum -{ - //--- - // Resets - // Obviously there will be no handler for these ones. - //--- - - /* Power-on reset: raised when power is supplied */ - exc_poweron_reset = 0, - /* Manual reset: probably when RESET button is pressed */ - exc_manual_reset = 0, - /* TLB multihit: more than one entry matches the requested address - (SH7305 only) */ - exc_tlb_multihit = 0, - - //--- - // General exceptions - //--- - - /* - Address error: an invalid address was accessed - - Location of instruction - - Address at fault - - Access type - 1: Instruction or data read access - 2: Data write access - */ - exc_address_error = 1, - - /* - TLB protection violation: address access is prevented by TLB - - Location of instruction - - Address at fault - - Access type - 1: Instruction or data read access - 2: Data write access - */ - exc_tlb_protection_violation = 2, - - /* - TLB invalid: entry was found but valid bit is cleared (SH7705 only) - - Location of instruction - - Address at fault - - Access type - 1: Instruction or data read access - 2: Data write access - */ - exc_tlb_invalid = 3, - - /* - Illegal instruction: current instruction is not a valid opcode - - Location of instruction - - Opcode at fault - */ - exc_illegal_instruction = 4, - - /* - Illegal slot: doing something illegal within a delayed slot - - Location of instruction - - Opcode at fault - */ - exc_illegal_slot = 5, - - /* User break: a user break request was fulfilled */ - exc_user_break = 6, - /* Initial page write: trying to write while dirty bit is reset */ - exc_initial_page_write = 7, - - /* - Unconditional trap: a 'trapa' instruction was executed - - Location of instruction - - Trap number - */ - exc_trap = 8, - - /* DMA address error: the DMAC violated word or long memory access - alignments (SH7705 only) */ - exc_dma_address = 9, - - //--- - // TLB misses - //--- - - /* - TLB miss: no match found in TLB for requested address - - Location of instruction - - Address at fault - - Access type - 1: Instruction or data read access - 2: Data write access - */ - exc_tlb_miss = 10, - - //--- - // Interrupt requests - //--- - - /* - Non-Maskable Interrupt: triggered by an external pin - */ - int_nmi = 11, - - /* - Timer underflow: a timer's counter reached zero - - Timer channel - 0: Channel 0 - 1: Channel 1 - 2: Channel 2 - */ - int_timer_underflow = 12, - - /* - Timer input capture: a capture of timer channel 2 has been requested - by the external clock (SH7705 only) - - Captured value - */ - int_timer_input_capture = 13, - - /* - Real-time clock alarm interrupt: configured alarm registers and - current time match - */ - int_rtc_alarm = 14, - - /* - Real-time clock periodic interrupt: various possible frequencies - - Current interrupt frequency - */ - int_rtc_periodic = 15, - - /* - Real-time clock carry interrupt: when a carry occurs while you're - reading time - */ - int_rtc_carry = 16, - - //--- - // Other flags - //--- - - // Maximum valid value for this type. - exc_type_max, - -} gint_interrupt_type_t; - -/* - gint_install() - Installs an exception or interrupt handler for one of gint's recognized - interrupts. The type signature of the handler function depends on the - particular signal it's answering. Please refer to the documentation to - know what parameters each handler function is provided with. -*/ -void gint_install(gint_interrupt_type_t signal, void *function); - -/* - gint_uninstall() - Uninstalls the exception or interrupt handler that was used for the - given interrupt, falling back to gint's default handler. -*/ -void gint_uninstall(gint_interrupt_type_t signal); - - - -//--- -// Register access -//--- - -typedef enum -{ - register_expevt = 0, - register_intevt = 1, - register_mmucr = 2, - register_tea = 3, - register_tra = 4, - -} gint_register_t; - -/* - gint_register() - Returns the address of a platform-shared register. All these registers - exist on both platforms but they may hold different values for the same - kind of information (f.i the periodic RTC interrupt will change the - value of INTEVT to 0x4a0 on SH7705, and 0xaa0 on SH7305). Higher-level - interfaces may provide platform-independent information in such cases. -*/ -volatile void *gint_reg(gint_register_t reg); - - - -//--- -// Other functions -//--- - -/* - gint_switch() - Temporarily returns to the system's main menu. -*/ -void gint_switch(void); - -#endif // _GINT_H diff --git a/include/gray.h b/include/gray.h deleted file mode 100644 index 86fa721..0000000 --- a/include/gray.h +++ /dev/null @@ -1,139 +0,0 @@ -//--- -// -// gint core/drawing module: gray -// -// Runs the gray engine and handles drawing for the dual-buffer system. -// -//--- - -#ifndef _GRAY_H -#define _GRAY_H - -#include -#include - -// This module provides bitmap rendering. -#include - -//--- -// Engine control. -//--- - -/* - gray_runs() - Returns 1 if the gray engine is running, 0 otherwise. -*/ -int gray_runs(void); - -/* - gray_start() - Starts the gray engine. The control of the screen is transferred to the - gray engine. -*/ -void gray_start(void); - -/* - gray_stop() - Stops the gray engine. The monochrome display system takes control of - the video ram. -*/ -void gray_stop(void); - -/* - gray_lightVRAM() - Returns the module's light gray vram address. -*/ -uint32_t *gray_lightVRAM(void); - -/* - gray_darkVRAM() - Returns the module's dark gray vram address. -*/ -uint32_t *gray_darkVRAM(void); - -/* - gray_currentVRAM() - Returns the currently displayed video ram (if the engine runs). Used - internally, but has no interest for the user. You don't want to draw to - this vram. -*/ -uint32_t *gray_currentVRAM(void); - -/* - gray_getDelays() - Returns the gray engine delays. Pointers are not set if NULL. -*/ -void gray_getDelays(int *light, int *dark); - -/* - gray_setDelays() - Changes the gray engine delays. Usually you don't need to call this, - because the engine has its default values. - Finding values that give proper grays is quite the hard part of the - gray engine. Usual values are about 1000, with light being between 75 - and 90% of dark. - - Typical values: - - values stability stripes colors - --------------------------------------------------------- - 860, 1298 excellent worst static good - 912, 1343 bad none very good (default) - 993, 1609 medium light fast good - 1325, 1607 bad light fast excellent - --------------------------------------------------------- -*/ -void gray_setDelays(int light, int dark); - - - -//--- -// Global drawing functions. -//--- - -/* - gupdate() - Swaps the vram buffer sets. You need to call this function each time - you finish drawing something in the video ram. Unlike the monochrome - function dupdate(), gupdate() only does a quick operation indicating - that drawing and exposed buffers have been swapped, but nothing on the - screen will change until the gray timer fires. -*/ -void gupdate(void); - -/* - gclear() - Clears the gray video ram, making all pixels white. -*/ -void gclear(void); - -/* - grect() - Draws a rectangle in the gray video ram; this function accepts all - values of the color_t type, including gray operators. -*/ -void grect(int x1, int y1, int x2, int y2, color_t operator); - - - -//--- -// Local drawing functions. -//--- - -/* - gpixel() - Puts a pixel in the vram. This function accepts all values of the - color_t type, including gray operators. -*/ -void gpixel(size_t x, size_t y, color_t operator); - -/* - gline() - Draws a line in the vram while automatically optimizing special cases. - This function supports all plain colors from the color_t type, but not - the gray operators. If you need them for horizontal or vertical lines, - you may want to use grect() as a replacement. -*/ -void gline(int x1, int y1, int x2, int y2, color_t operator); - -#endif // _GRAY_H diff --git a/include/internals/bopti.h b/include/internals/bopti.h deleted file mode 100644 index e1b11dd..0000000 --- a/include/internals/bopti.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef _INTERNALS_BOPTI_H -#define _INTERNALS_BOPTI_H - -#include -#include - -/* - channel_t - Indicates what operation a layer is made for. Each operation affects - the video ram differently (setting or clearing pixels, transparency, - etc). An image is made of several layers. -*/ -typedef enum -{ - channel_full_alpha = 0x01, - channel_light_alpha = 0x02, - channel_dark_alpha = 0x04, - - channel_mono = 0x08, - channel_light = 0x10, - channel_dark = 0x20, - -} channel_t; - -/* - format_t - Describes the various combination of layer channels that are allowed by - bopti. Technically one could try other formats but they're not of much - use (transparent gray is even totally useless). -*/ -typedef enum -{ - format_mono = channel_mono, - format_mono_alpha = format_mono | channel_full_alpha, - format_gray = channel_light | channel_dark, - format_gray_alpha = format_gray | channel_full_alpha, - format_greater_alpha = format_mono | channel_light_alpha | - channel_dark_alpha -} format_t; - -/* - structure_t - Basically an image's dimensions, data pointer, and a few other useful - information such as the pitch in bytes. -*/ -typedef struct -{ - int width, height; - int layer_size; - - const uint8_t *data; - int columns; - int end_size, end_bytes; - -} structure_t; - -/* - command_t - The parameters of a drawing operation. A pointer to such a structure is - created by the public functions and passed down to the module's - sub-functions during rendering. -*/ -typedef struct command_t -{ - // Channel being drawn. - channel_t channel; - // Operation used (whether bopti_op_mono() or bopti_op_gray()). - void (*op)(int offset, uint32_t operator, struct command_t *command); - // Portion of the bitmap which is drawn. 'top' and 'bottom' refer to - // lines where 'left' and 'right' refer to column ids. - int left, right, top, bottom; - // Position of the bitmap on the screen. - int x, y; - // Rectangle masks that define the drawing area. - uint32_t masks[4]; - // Video rams being used. - union { - // "Different names, same fate." (Kingdom Hearts II) - uint32_t *vram; - uint32_t *v1; - }; - uint32_t *v2; - -} command_t; - -// The video ram addresses are set by the public functions and used internally -// by the module. -// Monochrome video ram, light and dark buffers (in this order). -extern uint32_t *bopti_vram, *bopti_v1, *bopti_v2; - - - -//--- -// Internal bopti routines. -//--- - -/* - bopti_op() - Operates on a vram long. The operator will often not contain 32 bits of - image information. Since neutral bits are not the same for all - operations, a mask is used to indicate which bits should be used for - the operation. This mask is taken for the image's rectangle masks (see - the 'display' module internal header for more information on rectangle - masks). Which operation is performed is determined by the channel - setting of the command argument. -*/ -void bopti_op_mono(int offset, uint32_t operator, command_t *c); -void bopti_op_gray(int offset, uint32_t operator, command_t *c); - -/* - bopti_grid() -- general form - bopti_grid_a32() -- when x is a multiple of 32 - - Draws the grid at the beginning of a layer's data. The length of this - grid is always a multiple of 32. - The need for bopti_grid_a32() is not only linked to optimization, - because bopti_grid() will perform a 32-bit shift when x is a multiple - of 32, which is undefined behavior. - bopti_grid() automatically calls bopti_grid_a32() when required. -*/ -void bopti_grid_a32(const uint32_t *layer, int columns, int height, - command_t *c); -void bopti_grid(const uint32_t *layer, int columns, int height, command_t *c); -/* - bopti_end_get() - Returns an operator for the end of a line, whose width is lower than 32 - (by design: otherwise, it would have been a column). The given pointer - is read and updated so that it points to the next line at the end of - the operation. -*/ -uint32_t bopti_end_get1(const unsigned char **data); -uint32_t bopti_end_get2(const unsigned char **data); - -/* - bopti_rest() -- general form - bopti_rest_nover() -- when the end does not overlap two vram longs - - Draws the end of a layer, which can be considered as a whole layer - whose with is lower than 32. (Actually is it lower or equal to 16; - otherwise it would have been a column and the end would be empty). The - 'size' arguments is in bytes, thus 1 or 2. - Unlike bopti_grid_a32(), bopti_end_nover() is not called automatically - by bopti_end(). -*/ -void bopti_end_nover(const unsigned char *end, int size, command_t *c); -void bopti_end(const unsigned char *end, int size, command_t *c); - -/* - bopti() - Draws a layer's data in the video ram areas specified in the command - argument. -*/ -void bopti(const unsigned char *layer, structure_t *s, command_t *c); - -/* - getStructure() - Determines the image size (large images have a somehow different - structure), the data pointer and a few dimensions inside the image. -*/ -void getStructure(image_t *img, structure_t *structure); - -#endif // _INTERNALS_BOPTI_H diff --git a/include/internals/clock.h b/include/internals/clock.h deleted file mode 100644 index 6de2c43..0000000 --- a/include/internals/clock.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _INTERNALS_CLOCK_H -#define _INTERNALS_CLOCK_H - -/* - clock_measure() - Begins the frequency measurements. The measurements will end - automatically. While doing measurements, do not use the RTC interrupt - or the user timer. - Call clock_measure_end() to wait until the measurements are finished. - It is possible to execute code during the measurements, so that less - time is spent. -*/ -void clock_measure(void); - -/* - clock_measure_end() - Waits until the measurements are finished. This may be immediate. -*/ -void clock_measure_end(void); - -#endif // _INTERNALS_CLOCK_H diff --git a/include/internals/display.h b/include/internals/display.h deleted file mode 100644 index 8157b5b..0000000 --- a/include/internals/display.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _INTERNALS_DISPLAY_H -#define _INTERNALS_DISPLAY_H - -#include -#include - -extern uint32_t *vram; - -//--- -// Rectangle masks. -// -// The concept of 'rectangle masks' is used several times in this module. -// It relies on the fact that operations affecting a rectangle act the -// same for all lines, and line operation is very optimized. A rectangle -// mask is a set of integers, where each bit indicate whether a specific -// pixel is affected (1) by the operation, or not (0). -// -// For example to clear a rectangle such as (14, 16, 112, 48), the masks -// will need to hold 0003ffff ffffffff ffffffff ffff0000. Bitwise- -// combining them with video ram long entries yields very good performance -// as compared to operation on single pixels. Each bitwise operation will -// produce different results, which is very flexible. -// -// This technique can also be used in subtle cases with patterns more -// complicated than rectangles, but within this module this is unlikely to -// happen. -//--- - -/* - adjustRectangle() - Adjusts the given rectangle coordinates to ensure that : - - the rectangle is entirely contained in the screen; - - x1 < x2; - - y1 < y2, - which is needed when working with screen rectangles. Returns non-zero - if the rectangle is outside the screen, which usually means there is - nothing to do. -*/ -int adjustRectangle(int *x1, int *y1, int *x2, int *y2); - -/* - getMasks() - Computes the rectangle masks needed to affect pixels located between x1 - and x2 (both included). The four masks are stored in the third argument - (seen as an array). -*/ -void getMasks(size_t x1, size_t x2, uint32_t *masks); - -#endif // _INTERNALS_DISPLAY_H diff --git a/include/internals/events.h b/include/internals/events.h deleted file mode 100644 index ac8b7ee..0000000 --- a/include/internals/events.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _INTERNALS_EVENTS_H -#define _INTERNALS_EVENTS_H - -#include - -#ifndef EVENTS_QUEUE_SIZE -#define EVENTS_QUEUE_SIZE 64 -#endif - -/* - This module is just a circular-array queue that pushes and pops events - like any other queue. Trying to add an event when the queue is full - fails, and the operation is ignored. -*/ -extern volatile event_t event_queue[]; -extern volatile int queue_start; -extern volatile int queue_size; - -#endif // _INTERNALS_EVENT_H diff --git a/include/internals/exceptions.h b/include/internals/exceptions.h deleted file mode 100644 index 80b4b38..0000000 --- a/include/internals/exceptions.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _INTERNALS_EXCEPTIONS_H -#define _INTERNALS_EXCEPTIONS_H - -#include - -/* - exch_address_error() - CPU address error, e.g. alignment issues. -*/ -void exch_address_error(uint32_t pc, uint32_t tea, uint32_t access); - -/* - exch_tlb_protection_violation() - You don't have the right to access this address. -*/ -void exch_tlb_protection_violation(uint32_t pc, uint32_t tea, uint32_t access); - -/* - exch_tlb_invalid() - The translation info for this address is marked as invalid. -*/ -void exch_tlb_invalid(uint32_t pc, uint32_t tea, uint32_t access); - -/* - exch_illegal_instruction() - What's this opcode anyway? -*/ -void exch_illegal_instruction(uint32_t pc, uint32_t opcode); - -/* - exch_illegal_slot() - You can't execute this in a delay slot. -*/ -void exch_illegal_slot(uint32_t pc, uint32_t opcode); - -/* - exch_user_break() - One of the user break conditions you requested was fulfilled. -*/ -void exch_user_break(void); - -/* - exch_initial_page_write() - You can't write to this memory page, it's too early. -*/ -void exch_initial_page_write(void); - -/* - exch_trap() - You asked for it. -*/ -void exch_trap(uint32_t pc, uint32_t trap); - -/* - exch_dma_address() - The DMAC is accessing badly-aligned addresses. -*/ -void exch_dma_address(void); - -/* - exch_tlb_miss() - This virtual address points nowhere. -*/ -void exch_tlb_miss(uint32_t pc, uint32_t tea, uint32_t access); - -#endif // _INTERNALS_EXCEPTIONS_H diff --git a/include/internals/gint.h b/include/internals/gint.h deleted file mode 100644 index 6e7ed83..0000000 --- a/include/internals/gint.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef _INTERNALS_GINT_H -#define _INTERNALS_GINT_H - -#include -#include -#include - -//--- -// Interrupt handlers. -//--- - -// General exception handler. -void gint_exc(void); -// TLB miss handler. -void gint_tlb(void); -// Interrupt handler. -void gint_int(void); - - - -//--- -// Assembler-level VBR management. -//--- - -/* - gint_getvbr() - Retrieves the current VBR address. -*/ -uint32_t gint_getvbr(void); - -/* - gint_setvbr() - Sets the VBR address and calls the configuration function while - interrupts are disabled. -*/ -void gint_setvbr(uint32_t vbr, void (*setup)(void)); - - - -//--- -// Initialization and termination routines, environment saves. -//--- - -/* - gint_init() - Initializes gint. Loads the interrupt handler into the memory and sets - the new vbr address. -*/ -void gint_init(mpu_t mpu); - -/* - gint_quit() - Stops gint. Restores the system's configuration and vbr address. -*/ -void gint_quit(void); - -#include -#include - -/* - environment_t - Structure where all registers used by gint are saved by default to - ensure that the operating system is not disturbed. -*/ -typedef struct -{ - // Interrupt controller. - uint16_t IPR[8]; - - // Real-Time Clock. - uint8_t RCR1, RCR2; - - // Timer Unit. - mod_tmu_timer_t TMU0, TMU1, TMU2; - uint8_t TSTR; - - // I/O ports for the keyboard driver. - uint16_t PACR, PBCR, PMCR; - uint8_t PADR, PBDR, PMDR; - -} environment_7705_t; - -typedef struct -{ - // Interrupt controller. - uint16_t IPR[12]; - - // Real-Time Clock. - uint8_t RCR1, RCR2; - - // Timer Unit. - mod_tmu_timer_t TMU0, TMU1, TMU2; - uint8_t TSTR; - - // I/O ports for the keyboard driver. - uint16_t PMCR, PNCR, PZCR; - uint8_t PMDR, PNDR, PZDR; - uint8_t key; - -} environment_7305_t; - -typedef union -{ - environment_7705_t env_7705; - environment_7305_t env_7305; - -} environment_t; - -/* - gint_save() - Saves many registers into an internal environment buffer. -*/ -void gint_save_7705(environment_7705_t *env); -void gint_save_7305(environment_7305_t *env); - -/* - gint_lock_and_setup() - Locks all interrupts (ie. disables them by default) and sets initial - values to all registers, allows specific interrupts, etc. -*/ -void gint_lock_and_setup_7705(void); -void gint_lock_and_setup_7305(void); - -/* - gint_restore_and_unlock() - Restores the parameters saved in the environment buffer to give back - the interrupt control to the system. -*/ -void gint_restore_and_unlock_7705(environment_7705_t *env); -void gint_restore_and_unlock_7305(environment_7305_t *env); - -/* - gint_reg() - Returns the address of a platform-shared register. -*/ -volatile void *gint_reg_7705(gint_register_t reg); -volatile void *gint_reg_7305(gint_register_t reg); - -#endif // _INTERNALS_GINT_H diff --git a/include/internals/init.h b/include/internals/init.h deleted file mode 100644 index f6b7f47..0000000 --- a/include/internals/init.h +++ /dev/null @@ -1,29 +0,0 @@ -//--- -// gint core module: init -// Program initialization and display manipulation for the startup logs. -//--- - -#ifndef _INTERNALS_INIT_H -#define _INTERNALS_INIT_H - -#include - -/* init_version() -- get a version string */ -const char *init_version(void); - -/* init_stage() -- change the current init stage */ -void init_stage(const char *name); - -/* init_halt() -- halt the program */ -void init_halt(void); - -/* print() -- print text on a 21*8 grid */ -#define print(x, y, str) dtext((x) * 6 - 5, (y) * 8 - 8, (str)) - -/* print_dec() -- print a number in base 10 */ -void print_dec(int x, int y, int n, int digits); - -/* print_hex() -- print a number in base 16 */ -void print_hex(int x, int y, uint32_t n, int digits); - -#endif // _INTERNALS_INIT_H diff --git a/include/internals/interrupt_maps.h b/include/internals/interrupt_maps.h deleted file mode 100644 index a1d716b..0000000 --- a/include/internals/interrupt_maps.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef _INTERRUPT_MAPS -#define _INTERRUPT_MAPS - -#include -#include - -//--- -// Interrupt handlers. -//--- - -/* - gint_interrupt_arg_t - 8-bit integer representing an argument to pass as uint32_t to an - exception or interrupt handler. -*/ -typedef enum -{ - // Empty argument (always at end of list). - arg_none = 0x00, - // Signal subtype (f.i address error subtypes: code, read, write). - arg_subtype = 0x01, - // Value of register SPC is passed. - arg_pc = 0x02, - // Instruction pointed at by SPC is passed (re-execution types). - arg_opcode = 0x03, - // Address indicated in register TEA is passed. - arg_tea = 0x04, - // Trap number is passed. - arg_trap = 0x05, - // Timer channel 2 captured input (SH7705 only). - arg_timer_capt = 0x06, - -} gint_interrupt_arg_t; - -/* - gint_interrupt_handler_t - Contains both static and dynamic information of interrupt handlers: - the current handler is stored there, as well as the type signature - information through an array of parameters. -*/ -typedef struct -{ - // Current handler function. The type signature may vary, hence the - // void * pointer. - void *function; - // Default handler and fallback if the current handler is un-installed. - void *default_function; - // Default interrupt priorities (interrupts only). - uint8_t priority; - // Arguments passed to the handler (these are values of type arg_t). - // This array is the only thing that defines the type signature of the - // two functions above. - uint8_t args[3]; - -} gint_interrupt_handler_t; - -// Handler array. -extern gint_interrupt_handler_t gint_handlers[]; - - - -//--- -// Interrupt maps. -//--- - -/* - gint_interrupt_map_t - Maps an event code to an interrupt type and subtype. The subtypes allow - group-handling similar interrupts (for instance TLB misses for code and - data accesses, or timer underflows from various channels). -*/ -typedef struct -{ - uint8_t type; - uint8_t subtype; - -} __attribute__((packed)) gint_interrupt_map_t; - -/* - gint_map_7705() - TLB misses and TLB invalid have the same event code though they are - handled by different functions in the VBR space. The offset argument - expects values 0x100, 0x400 or 0x600 to distinguish between them. -*/ -gint_interrupt_map_t gint_map_7705(uint32_t event_code, uint32_t offset); - -/* - gint_map_7305() - Maps an event code to an interrupt type. The SH7305 does not have TLB - invalid exceptions so no event codes overlap. -*/ -gint_interrupt_map_t gint_map_7305(uint32_t event_code); - -/* - gint_invoke() - Invokes an interrupt or exception handler, given its type and subtype. -*/ -void gint_invoke(uint8_t type, uint8_t subtype); - -#endif // _INTERRUPT_MAPS diff --git a/include/internals/interrupts.h b/include/internals/interrupts.h deleted file mode 100644 index 0957d11..0000000 --- a/include/internals/interrupts.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _INTERNALS_INTERRUPTS_H -#define _INTERNALS_INTERRUPTS_H - -#include - -/* - inth_timer_underflow() - Wake up, your timer has expired! -*/ -void inth_timer_underflow(uint32_t channel); - -/* - inth_rtc_periodic() - Don't you forget to execute the periodic tasks. -*/ -void inth_rtc_periodic(void); - -#endif // _INTERNALS_INTERRUPTS_H diff --git a/include/internals/keyboard.h b/include/internals/keyboard.h deleted file mode 100644 index 01d24eb..0000000 --- a/include/internals/keyboard.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _INTERNALS_KEYBOARD_H -#define _INTERNALS_KEYBOARD_H - -#include -#include -#include - -// Current keyboard state and keyboard interrupt flag. -extern volatile uint8_t keyboard_state[10]; -extern volatile int interrupt_flag; - -// Delays (milliseconds) before repetitions, last key pressed, how many times -// it has been repeated already, time elapsed since last repetition (ms). -extern int repeat_first, repeat_next; -extern int last_key, last_repeats, last_time; - -// Virtual timer object. -extern timer_t *vtimer; - -/* - getPressedKey() - Finds a pressed key in the keyboard state and returns it. -*/ -int getPressedKey(volatile uint8_t *keyboard_state); - -/* - getPressedKeys() - Find 'count' pressed keys in the keyboard state and fills the 'keys' - array. Returns the number of keys found. - WARNING: keyboard artifacts make this function read as pressed keys - that aren't (typically, LEFT + DOWN + SHIFT => ALPHA). -*/ -int getPressedKeys(volatile uint8_t *keyboard_state, int *keys, int count); - -/* - keyboard_updateState() - Updates the keyboard state. -*/ -void keyboard_updateState_7705(volatile uint8_t *state); -void keyboard_updateState_7305(volatile uint8_t *state); - -/* - keyboard_interrupt() - Answers an interrupt event by updating the keyboard state and - generating the associated keyboard events. -*/ -void keyboard_interrupt(void); - -#endif // _INTERNALS_KEYBOARD_H diff --git a/include/internals/mmu.h b/include/internals/mmu.h deleted file mode 100644 index 1fcf6ac..0000000 --- a/include/internals/mmu.h +++ /dev/null @@ -1,21 +0,0 @@ -//--- -// -// gint core module: mmu -// -// A wise application should avoid tampering with the system's -// configuration of the MMU and the TLB. This module implicitly forces the -// system to load the required pages but does not interact with the TLB. -// -//--- - -#ifndef _INTERNALS_MMU_H -#define _INTERNALS_MMU_H - -/* - mmu_pseudoTLBInit() - Tries to have the system load enough data into TLB to allow add-in to - execute. -*/ -void mmu_pseudoTLBInit(void); - -#endif // _MMU_H diff --git a/include/internals/modules.h b/include/internals/modules.h deleted file mode 100644 index c96e770..0000000 --- a/include/internals/modules.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _INTERNALS_MODULES_H -#define _INTERNALS_MODULES_H - -/* - mod_init() - Initializes the module data to make register access cross-platform. The - MPU needs to have been detected or this function will yield wrong - results. -*/ -void mod_init(void); - -#endif // _INTERNALS_MODULES_H diff --git a/include/internals/rtc.h b/include/internals/rtc.h deleted file mode 100644 index 4b9f9e0..0000000 --- a/include/internals/rtc.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _INTERNALS_RTC_H -#define _INTERNALS_RTC_H - -#include -#include - -#ifndef RTC_CB_ARRAY_SIZE -#define RTC_CB_ARRAY_SIZE 5 -#endif - -/* - rtc_callback_t - An RTC callback with a unique id. -*/ -typedef struct -{ - rtc_frequency_t freq; - int id; - - void (*callback)(void); - int repeats; - -} rtc_callback_t; - -// The callback array. -rtc_callback_t cb_array[RTC_CB_ARRAY_SIZE]; - -/* - rtc_perodic_interrupt() - Handles periodic interrupts and calls the callbacks. -*/ -void rtc_periodic_interrupt(void); - -/* - rtc_cb_interrupt() - Calls the RTC callbacks if necessary, and updates the repeat counts. - Should only be called when RTC periodic interrupts occur. -*/ -void rtc_cb_interrupt(void); - -#endif // _INTERNALS_RTC_H diff --git a/include/internals/stdio.h b/include/internals/stdio.h deleted file mode 100644 index 7a67647..0000000 --- a/include/internals/stdio.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _INTERNALS_STDIO_H -#define _INTERNALS_STDIO_H - -#include -#include - -//--- -// Formatted printing. -//--- - -#ifndef __stdio_buffer_size -#define __stdio_buffer_size 256 -#endif - -extern char __stdio_buffer[]; - -/* - __printf() - Formatted printing to the stdio buffer. -*/ -int __printf(size_t size, const char *format, va_list args); - -#endif // _INTERNALS_STDIO_H diff --git a/include/internals/syscalls.h b/include/internals/syscalls.h deleted file mode 100644 index 594c50b..0000000 --- a/include/internals/syscalls.h +++ /dev/null @@ -1,29 +0,0 @@ -//--- -// -// gint core module: syscalls -// -// Some of the functionality still requires interacting with the system. -// -//--- - -#ifndef _INTERNALS_SYSCALLS_H -#define _INTERNALS_SYSCALLS_H - -#include - -/* malloc() -- allocate data in heap */ -void *__malloc(size_t size); - -/* free() -- free data allocated by malloc(), calloc() or realloc() */ -void __free(void *ptr); - -/* realloc() -- reallocate a chunk of memory */ -void *__realloc(void *chunk, size_t new_size); - -/* get_os_version() -- write the OS version in format MM.mm.pppp to a string */ -void __get_os_version(char *str); - -/* system_menu() -- go back to menu, assuming the system has the control */ -void __system_menu(const void *vram); - -#endif // _INTERNALS_SYSCALLS_H diff --git a/include/internals/tales.h b/include/internals/tales.h deleted file mode 100644 index 455246d..0000000 --- a/include/internals/tales.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _INTERNALS_TALES_H -#define _INTERNALS_TALES_H - -#include -#include -#include - -#define OPERATE_ARGS uint32_t *operators, int height, int x, int y - -extern font_t *font; -extern color_t operator; - -/* - getCharacterIndex() - Returns the index of a character in a font data area depending on the - font format and the size of the characters. Returns the index in the - data area, as long array, or -1 when the character does not belong to - the font format set. -*/ -int getCharacterIndex(int c); - -/* - operate() - Operates on the vram using the given operators. The x-coordinate should - be a multiple of 32. There should be `height` operators. -*/ -void operate_mono(OPERATE_ARGS); -void operate_gray(OPERATE_ARGS); - -/* - update() - Updates the operators using the given glyph. The operation will not be - complete if there are not enough bits available in the operator data. - In this case the offset will become negative, which means that the - calling procedure has to call operate() and re-call update(). - `available` represents the number of free bits in the operators (lower - bits). - Returns the number of bits available after the operation. If it's - negative, call operate() and update() again. -*/ -int update(uint32_t *operators, int height, int available, uint32_t *glyph); - -/* - render() - Renders text without any formatting analysis, using the given operation - function. -*/ -void render(int x, int y, const char *str, void (*op)(OPERATE_ARGS)); - -#endif // _INTERNALS_TALES_H diff --git a/include/internals/time.h b/include/internals/time.h deleted file mode 100644 index aef910b..0000000 --- a/include/internals/time.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _INTERNALS_TIME_H -#define _INTERNALS_TIME_H - -/* - isLeap() - Determines whether the given year is a leap year. -*/ -int isLeap(int year); - -/* - daysInMonth() - Returns number of days for the given month (between 0 and 11) and year. -*/ -int daysInMonth(int month, int year); - -#endif // _INTERNALS_TIME_H diff --git a/include/internals/timer.h b/include/internals/timer.h deleted file mode 100644 index 8e4feec..0000000 --- a/include/internals/timer.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _INTERNALS_TIMER_H -#define _INTERNALS_TIMER_H - -#include -#include - -/* - timer_t - A virtual or hardware timer. We need to declare the struct timer_t name - so that we can forward-reference it. -*/ -typedef struct timer_t -{ - // Current delay, how much time elapsed since last interrupt occurred. - uint32_t ms_delay; - uint32_t ms_elapsed; - - // Is the virtual slot free? Is the virtual timer active? - uint8_t used :1; - uint8_t active :1; - // Is this a virtual timer? Is this the virtual timer support? - uint8_t virtual :1; - uint8_t vsupport :1; - // How many events do I have received but not executed? - uint8_t events :4; - // How many repeats are left. - uint32_t repeats_left :24; - - // Callback function (NULL for event-firing timers) and its argument. - void *callback; - void *argument; - -} __attribute__((packed, aligned(4))) timer_t; - -// Hardware timers. -extern timer_t htimers[3]; -// Virtual timers. -extern timer_t vtimers[TIMER_SLOTS]; - -/* - timer_interrupt() - Handles the interrupt for the given timer channel. -*/ -void timer_interrupt(int channel); - -/* - timer_callback_event() - Executes the callback of a timer, or pushes a new timer event depending - on the timer configuration. Also reduces the amount of repeats left and - clears the active flag (or stops the hardware timer) if this number - falls from one to zero. -*/ -void timer_callback_event(timer_t *timer); - -/* - vtimer_interrupt() - Interrupt handling subsystem for the virtual timers. -*/ -void vtimer_interrupt(void); - -/* - vtimer_updateOne() - Update the virtual timer hardware support timer, knowing that a virtual - timer with the given delay has been started. -*/ -void vtimer_updateOne(int additional_delay_ms); - -/* - vtimer_updateAll() - Updates the virtual timer hardware support after computing the GCD of - all virtual timers delays. This is rather long so avoid calling this - when possible. -*/ -void vtimer_updateAll(void); - -#endif // _INTERNALS_TIMER_H diff --git a/include/keyboard.h b/include/keyboard.h deleted file mode 100644 index 4acb419..0000000 --- a/include/keyboard.h +++ /dev/null @@ -1,329 +0,0 @@ -//--- -// -// gint core module: keyboard analyzer -// -// Probably the most difficult hardware interaction. There is very few -// documentation on how the system actually analyzes the keyboard. While -// disassembling syscalls reveals the following procedure (which was -// already documented by SimonLothar), there is nothing about the -// detection problems of the multi-getkey system. -// -//--- - -#ifndef _KEYBOARD_H -#define _KEYBOARD_H - -#include -#include - -//--- -// Keycodes and related. -//--- - -/* - key_t - The following codes are gint matrix codes. They are not compatible with - the system's. Some keycodes are special event codes; all others are - made of a key identifier and possibly one or more modifiers. - Binary-and a keycode with MOD_CLEAR to remove the modifiers; this will - not work with special event codes. -*/ -typedef enum -{ - // Special events codes. - KEY_NONE = 0x00, - KEY_NOEVENT = 0xff, - - // Key modifiers. - MOD_SHIFT = 0x80, - MOD_ALPHA = 0x100, - MOD_CLEAR = ~(MOD_SHIFT | MOD_ALPHA), - - // Key identifiers. - - KEY_F1 = 0x69, - KEY_F2 = 0x59, - KEY_F3 = 0x49, - KEY_F4 = 0x39, - KEY_F5 = 0x29, - KEY_F6 = 0x19, - - KEY_SHIFT = 0x68, - KEY_OPTN = 0x58, - KEY_VARS = 0x48, - KEY_MENU = 0x38, - KEY_LEFT = 0x28, - KEY_UP = 0x18, - - KEY_ALPHA = 0x67, - KEY_SQUARE = 0x57, - KEY_POWER = 0x47, - KEY_EXIT = 0x37, - KEY_DOWN = 0x27, - KEY_RIGHT = 0x17, - - KEY_XOT = 0x66, - KEY_LOG = 0x56, - KEY_LN = 0x46, - KEY_SIN = 0x36, - KEY_COS = 0x26, - KEY_TAN = 0x16, - - KEY_FRAC = 0x65, - KEY_FD = 0x55, - KEY_LEFTP = 0x45, - KEY_RIGHTP = 0x35, - KEY_COMMA = 0x25, - KEY_ARROW = 0x15, - - KEY_7 = 0x64, - KEY_8 = 0x54, - KEY_9 = 0x44, - KEY_DEL = 0x34, - KEY_AC_ON = 0x24, - - KEY_4 = 0x63, - KEY_5 = 0x53, - KEY_6 = 0x43, - KEY_MUL = 0x33, - KEY_DIV = 0x23, - - KEY_1 = 0x62, - KEY_2 = 0x52, - KEY_3 = 0x42, - KEY_PLUS = 0x32, - KEY_MINUS = 0x22, - - KEY_0 = 0x61, - KEY_DOT = 0x51, - KEY_EXP = 0x41, - KEY_NEG = 0x31, - KEY_EXE = 0x21, - -} key_t; - - - -//--- -// Keyboard configuration. -//--- - -/* - keyboard_setAnalysisDelay() - Sets the keyboard analysis delay, that is, the delay (in ms) between - two keyboard analyzes. If a key is pressed then released in the lapse - between two analyzes, the program won't notice anything. On the other - hand, if the program spends too much time reading the keyboard, it will - lose a bit of execution power. - The default frequency is about 40 Hz; very few programs will need to - change this setting. Please note that the repeat delays should be - multiples of the analysis delay for better accuracy. -*/ -void keyboard_setAnalysisDelay(int analysis_delay_ms); - -/* - keyboard_setRepeatRate() - Sets the default repeat rate for key events. The delay before the first - repeat may have a different value (usually longer). The unit for the - argument is ms, but the repeat events themselves may only be fired when - a keyboard analysis is performed; which means that for better accuracy, - these delays should be a multiple of the keyboard period. The keyboard - period may be changed by calling keyboard_setAnalysisDelay(). - For instance, delays of (625 ms, 125 ms) will imitate the system's - default setting. - You can disable repetitions by passing 0 as arguments: - - if first = 0, no repetition will ever occur; - - if first != 0 and next = 0, only one repetition will occur. -*/ -void keyboard_setRepeatRate(int first, int next); - - - -//--- -// Keyboard access. -//--- - -/* - getkey_opt_t - Options available to customize the behavior of the getkey_opt() - function. -*/ -typedef enum -{ - getkey_none = 0x00, - - // Consider [SHIFT] and [ALPHA] as modifiers. Returns key identifiers - // with MOD_SHIFT and MOD_ALPHA flags instead of returning KEY_SHIFT - // and KEY_ALPHA. - getkey_shift_modifier = 0x01, - getkey_alpha_modifier = 0x02, - - // Allow changing the backlight status on [SHIFT] + [OPTN] on - // compatible models. - getkey_manage_backlight = 0x04, - - // Allow returning to menu using the [MENU] key. (This operation is not - // absolutely safe.) - getkey_task_switch = 0x08, - - // Allow key repetition. This option does not control the generation of - // repeat events (use keyboard_setRepeatRate() for this) but filters - // them. Please note that modifiers will never be repeated, even when - // pressed continuously. - getkey_repeat_arrow_keys = 0x10, - getkey_repeat_char_keys = 0x20, - getkey_repeat_ctrl_keys = 0x40, - getkey_repeat_func_keys = 0x80, - // Shorthand for the four previous properties. - getkey_repeat_all_keys = 0xf0, - - // Default combination of getkey(). - getkey_default = 0x1f, - -} getkey_option_t; - -/* - getkey() - Blocking function with auto-repeat that heeds for the SHIFT and ALPHA - modifiers. In short, this function reproduces the behavior of the - system's GetKey() function. It returns a matrix code, possibly with - modifier bits. - This function does not return until a key is pressed. -*/ -int getkey(void); - -/* - getkey_opt() - Enhances getkey() with more general functionalities. An OR-combination - of options of type getkey_option_t may be given as first argument. - If delay is non-zero and positive, getkey_opt() will return KEY_NOEVENT - if no event occurs during the given delay. Please note that this - function can only ever return after a keyboard analysis is performed; - the actual delay may exceed the requested time if it's not a multiple - of the keyboard period (which can be changed by calling - keyboard_setAnalysisDelay()). - Like getkey(), returns the pressed key matrix code, possibly with - modifiers depending on the options. -*/ -int getkey_opt(getkey_option_t options, int delay_ms); - -/* - multigetkey() - - Listens the keyboard for simultaneous key hits. This functions fills - the 'keys' array with 'count' keycodes, padding with KEY_NONE values at - the end if less that 'count' keys are detected. - If 'delay_ms' is positive and nothing happens during this delay, this - function returns an array of KEY_NONE. Please note that the delay - detection suffers the same limitation as getkey_opt(). - - This function suffers from severe limitations and may not be very - convenient to use. For more accuracy, consider using the event system. - - WARNING: - Because of hardware limitations, this function generally yields poor - results. Rectangle and column effects make it read unpressed keys as - pressed (see documentation for more information). The more pressed - keys, the more errors. - - The results are guaranteed to be exact if two keys or less are pressed. - With three keys or more, column effects (on SH4) and rectangle effects - (on both platforms) mess up the results by making this function think - that some keys, which are actually released, are pressed. - - This function is designed to make combinations of one or two arrow keys - with another key as viable as possible. On SH4, this works pretty well - even if combinations like Left + Down + SHIFT trigger ALPHA sometimes. - On SH3, rectangle effects are *always* present, making it impossible to - use Left + Down or Up + Right with any other key in their rows without - having this function return junk. - - Any other combination of keys may quite randomly result in variably - incorrect results. Please do not expect multigetkey() to work as an - ideal multi-key analyzer. -*/ -void multigetkey(int *keys, int count, int delay_ms); - -/* - keyboard_stateBuffer() - - Returns the address of the keyboard state array. The keyboard state - consists in 10 bytes, in which every key is represented as a bit. - The returned address is the original buffer address. You should avoid - editing the array. It wouldn't influence the behavior of the keyboard - functions, but the buffer data is very volatile and any data written to - it could be replaced anytime without prior notice. - - If the user wishes to do really advanced keyboard management that they - can't achieve it using the library, they can access this buffer. - Updates of this buffer's contents can be detected by watching the - 'interrupt_flag' variable defined in internals/keyboard.h. However, the - library will continue firing events so the user needs to catch them and - ignore them. -*/ -volatile uint8_t *keyboard_stateBuffer(void); - - - -//--- -// Key analysis. -//--- - -/* - keyid() - Transforms a key identifier and returns a key code that is more - convenient for array subscript that the original matrix codes. The new - codes are laid out the following way: - - +0 +1 +2 +3 +4 +5 - ------------------------------------ - +0 | F1 F2 F3 F4 F5 F6 - +6 | SHIFT OPTN VARS MENU Left Top - +12 | ALPHA x^2 ^ EXIT Down Right - +18 | X,O,T log ln sin cos tan - +24 | Frac F<>D ( ) , -> - +30 | 7 8 9 DEL AC/ON - +36 | 4 5 6 * / - +42 | 1 2 3 + - - +48 | 0 . x10^ (-) EXE - - The returned key code is the sum of the line and column headings. For - instance key_id(KEY_SIN) would be 18 + 3 = 21. Please note that there - are a few holes in the numbering. - This function ignores modifiers and returns -1 on error. -*/ -int key_id(int matrix_key); - -/* - key_char() - Returns the ASCII character associated with a character key, and 0 for - other keys. This function expects a matrix code and not a key_id() - code, and heeds for the ALPHA modifier. -*/ -int key_char(int matrix_key); - -/* - key_type_t - Categorizes the keyboard's keys into several types: - - Arrow keys only include the REPLAY pad; - - Function keys only include the F1 .. F6 keys; - - Character keys are those which input characters; - - Control characters are all others. -*/ -typedef enum -{ - key_type_arrow = 1, - key_type_character = 2, - key_type_control = 4, - key_type_function = 8, - -} key_type_t; - -/* - key_type() - Returns a key's type. This functions ignores modifiers and expects - matrix codes as argument, not key_id() codes. -*/ -key_type_t key_type(int matrix_key); - -#endif // _KEYBOARD_H diff --git a/include/math.h b/include/math.h deleted file mode 100644 index 1bcbbcb..0000000 --- a/include/math.h +++ /dev/null @@ -1,41 +0,0 @@ -//--- -// -// gint libc module: math -// -// Provides mathematical functions as well as a few useful extensions. -// -//--- - -#ifndef _MATH_H -#define _MATH_H - -#include - -//--- -// Function extensions -//--- - -/* - qdiv() - Quickly divides by predefined integers using a 64-bit multiplication - technique. These functions should be ~10 times faster than dividing - using opeator "/". -*/ - -typedef struct qdiv_t -{ - uint32_t q; /* Quotient */ - uint32_t r; /* Remainer */ - -} __attribute__((packed, aligned(4))) qdiv_t; - -qdiv_t qdiv(uint32_t n, uint32_t divider, uint32_t reciprocal); - -/* Predefined magic numbers */ -#define qdiv_3(n) qdiv(n, 3, 0x55555556) -#define qdiv_5(n) qdiv(n, 5, 0x33333334) -#define qdiv_10(n) qdiv(n, 10, 0x1999999a) -#define qdiv_100(n) qdiv(n, 100, 0x028f5c29) -#define qdiv_1000(n) qdiv(n, 1000, 0x00418938) - -#endif // _MATH_H diff --git a/include/modules/interrupts.h b/include/modules/interrupts.h deleted file mode 100644 index 3ffd9d1..0000000 --- a/include/modules/interrupts.h +++ /dev/null @@ -1,688 +0,0 @@ -#ifndef _MODULES_INTERRUPTS_H -#define _MODULES_INTERRUPTS_H - -#include -#include - -//--- -// Interrupt controller. -// This part is difficult to handle, because the interrupt controllers of -// SH7705 and SH7305 MPUs have virtually nothing in common. I eventually -// decided to completely split it up into two kinds of structures and -// types. -// Use the gint API, not this module, for platform-independent interrupt -// management. -//--- - -//--- -// SH7705-related definitions. -//--- - -/* - mod_intc_ipc_7705_t - Interrupt priority controller. Just a bunch of 16-bit-registers that - handle the interrupt priority of all interrupt sources. - - Please note that because the interrupt priority controller of the - SH7705 MPU has registers scattered everywhere in the memory, its - structure below has a different pointer for each register. On the - opposite, the SH7305 registers are all in a contiguous area thus there - is only one pointer for the whole group. -*/ -typedef struct -{ - volatile word_union(*IPRA, - uint TMU0 :4; /* Timer 0 */ - uint TMU1 :4; /* Timer 1 */ - uint TMU2 :4; /* Timer 2 */ - uint RTC :4; /* Real-Time Clock */ - ); - - volatile word_union(*IPRB, - uint WDT :4; /* Watchdog Timer */ - uint REF :4; /* BSC Refresh Request, SDRAM (?) */ - uint :4; - uint :4; - ); - - volatile word_union(*IPRC, - uint IRQ3 :4; /* Interrupt request 3 */ - uint IRQ2 :4; /* Interrupt request 2 */ - uint IRQ1 :4; /* Interrupt request 1 */ - uint IRQ0 :4; /* Interrupt request 0 */ - ); - - volatile word_union(*IPRD, - uint PINT0_7 :4; /* External interrupt pins 0 to 7 */ - uint PINT8_15 :4; /* External interrupt pins 8 to 15 */ - uint IRQ5 :4; /* Interrupt request 5 */ - uint IRQ4 :4; /* Interrupt request 4 */ - ); - - volatile word_union(*IPRE, - uint DMAC :4; /* Direct Memory Access Controller */ - uint SCIF0 :4; /* Serial Communication Interface 0 */ - uint SCIF2 :4; /* Serial Communication Interface 2 */ - uint ADC :4; /* Analog/Decimal Converter */ - ); - - volatile word_union(*IPRF, - uint :4; - uint :4; - uint USB :4; /* USB Controller */ - uint :4; - ); - - volatile word_union(*IPRG, - uint TPU0 :4; /* Timer Pulse Unit 0 */ - uint TPU1 :4; /* Timer Pulse Unit 1 */ - uint :4; - uint :4; - ); - - volatile word_union(*IPRH, - uint TPU2 :4; /* Timer Pulse Unit 2 */ - uint TPU3 :4; /* Timer Pulse Unit 3 */ - uint :4; - uint :4; - ); - -} __attribute__((packed)) mod_intc_ipc_7705_t; - -/* - mod_intc_icr0_7705_t - Interrupt control register 0: configuration of the NMI interrupt. -*/ -typedef struct -{ - word_union(, - uint const NMIL :1; /* NMI Input Level */ - uint :6; - uint NMIE :1; /* NMI Edge Select */ - uint :8; - ); - -} __attribute__((packed, aligned(2))) mod_intc_icr0_7705_t; - -/* - mod_intc_icr1_7705_t - Interrupt control register 1: general interrupt configuration. -*/ -typedef struct -{ - word_union(, - uint MAI :1; /* Mask All Interrupts */ - uint IRQLVL :1; /* Interrupt Request Level Detect */ - uint BLMSK :1; /* Enable NMI when BL is set */ - uint :1; - uint IRQ5E :2; /* IRQ 5 Edge Detection */ - uint IRQ4E :2; - uint IRQ3E :2; - uint IRQ2E :2; - uint IRQ1E :2; - uint IRQ0E :2; - ); - -} __attribute__((packed, aligned(2))) mod_intc_icr1_7705_t; - -/* - mod_intc_icr2_7705_t - Interrupt control register 2: individual PINT interrupt management. -*/ -typedef struct -{ - word_union(, - uint PINT15 :1; /* PINT15 interrupt detection level */ - uint PINT14 :1; - uint PINT13 :1; - uint PINT12 :1; - uint PINT11 :1; - uint PINT10 :1; - uint PINT9 :1; - uint PINT8 :1; - uint PINT7 :1; - uint PINT6 :1; - uint PINT5 :1; - uint PINT4 :1; - uint PINT3 :1; - uint PINT2 :1; - uint PINT1 :1; - uint PINT0 :1; - ); - -} __attribute__((packed, aligned(2))) mod_intc_icr2_7705_t; - -/* - mod_intc_pinter_7705_t - PINTER register: individual masks for all PINT interrupts. -*/ -typedef struct -{ - word_union(, - uint PINT15 :1; /* PINT15 interrupt enable */ - uint PINT14 :1; - uint PINT13 :1; - uint PINT12 :1; - uint PINT11 :1; - uint PINT10 :1; - uint PINT9 :1; - uint PINT8 :1; - uint PINT7 :1; - uint PINT6 :1; - uint PINT5 :1; - uint PINT4 :1; - uint PINT3 :1; - uint PINT2 :1; - uint PINT1 :1; - uint PINT0 :1; - ); - -} __attribute__((packed, aligned(2))) mod_intc_pinter_7705_t; - -/* - mod_intc_irr0_7705_t - Interrupt Request Register 0: Indicates whether interrupt requests are - being input to the various interrupt lines. Also allows to clear the - IRQ request bits in edge-detection mode. -*/ -typedef struct -{ - byte_union(, - uint const PINT0_7R :1; /* PINT0-7 state */ - uint const PINT8_15R :1; /* PINT8-15 state */ - uint IRQ5 :1; /* IRQ5 request pin state */ - uint IRQ4 :1; - uint IRQ3 :1; - uint IRQ2 :1; - uint IRQ1 :1; - uint IRQ0 :1; - ); - -} __attribute__((packed)) mod_intc_irr0_7705_t; - -/* - mod_intc_irr1_7705_t - Interrupt Request Register 1: State of SCIF0 and DMAC requests. -*/ -typedef struct -{ - const byte_union(, - uint TXIOR :1; /* SCIF0 TXI interrupt */ - uint :1; - uint RXI0R :1; /* SCIF0 RXI interrupt */ - uint ERI0R :1; /* SCIF0 ERI interrupt */ - uint DEI3R :1; /* DMAC DEI3 interrupt */ - uint DEI2R :1; /* DMAC DEI2 interrupt */ - uint DEI1R :1; /* DMAC DEI1 interrupt */ - uint DEI0R :1; /* DMAC DEI0 interrupt */ - ); - -} __attribute__((packed)) mod_intc_irr1_7705_t; - -/* - mod_intc_irr2_7705_t - Interrupt Request Register 2: State of SCIF2 and ADC requests. -*/ -typedef struct -{ - const byte_union(, - uint :3; - uint ADIR :1; /* AD/C ADI interrupt */ - uint TXI2R :1; /* SCIF2 TXI interrupt */ - uint :1; - uint RXI2R :1; /* SCIF2 RXI interrupt */ - uint ERI2R :1; /* SCIF2 ERI interrupt */ - ); - -} __attribute__((packed, aligned(2))) mod_intc_irr2_7705_t; - -/* - mod_intc_7705_t - Finally the SH7705 interrupt controller. -*/ -typedef struct -{ - /* All interrupt priority registers */ - mod_intc_ipc_7705_t iprs; - - /* Control registers */ - volatile mod_intc_icr0_7705_t *ICR0; - volatile mod_intc_icr1_7705_t *ICR1; - volatile mod_intc_icr2_7705_t *ICR2; - - /* PINTER register */ - volatile mod_intc_pinter_7705_t *PINTER; - - /* Interrupt request registers */ - volatile mod_intc_irr0_7705_t *IRR0; - volatile mod_intc_irr1_7705_t *IRR1; - volatile mod_intc_irr2_7705_t *IRR2; - -} __attribute__((packed)) mod_intc_7705_t; - - - -//--- -// SH7305-related definitions. -//--- - -/* - mod_intc_ipc_7305_t - Interrupt priority controller, same idea as the previous one. - - Some of the interrupt fields of the SH7305 registers, the contents of - which have been directly taken from the SH7724 documentation, have been - left unnamed because the related peripheral modules are *very* unlikely - to even exist in the SH7305, let alone be of any use to us. -*/ -typedef struct -{ - word_union(IPRA, - uint TMU0_0 :4; /* TMU0 Channel 0 */ - uint TMU0_1 :4; /* TMU0 Channel 1 */ - uint TMU0_2 :4; /* TMU0 Channel 2 */ - uint IrDA :4; /* Infrared Communication */ - ); - pad(2); - - word_union(IPRB, - uint :4; /* JPEG Processing Unit */ - uint LCDC :4; /* LCD Controller */ - uint DMAC1A :4; /* Direct Memory Access Controller 1 */ - uint :4; /* Blending Engine Unit */ - ); - pad(2); - - word_union(IPRC, - uint TMU1_0 :4; /* TMU1 Channel 0 */ - uint TMU1_1 :4; /* TMU1 Channel 1 */ - uint TMU1_2 :4; /* TMU1 Channel 2 */ - uint :4; /* Sound Processing Unit */ - ); - pad(2); - - word_union(IPRD, - uint :4; - uint MMCIF :4; /* MultiMedia Card Interface */ - uint :4; - uint :4; /* ATAPI Interface */ - ); - pad(2); - - word_union(IPRE, - uint DMAC0A :4; /* Direct Memory Access Controller 0 */ - uint :4; /* Various graphical engines */ - uint SCIFA3 :4; /* SCIFA channel 3 interrupt */ - uint :4; /* Video Processing Unit */ - ); - pad(2); - - word_union(IPRF, - uint KEYSC :4; /* Key Scan Interface */ - uint DMACOB :4; /* DMAC0 transfer/error info */ - uint USB0_1 :4; /* USB controller */ - uint CMT :4; /* Compare Match Timer */ - ); - pad(2); - - word_union(IPRG, - uint SCIF0 :4; /* SCIF0 transfer/error info */ - uint SCIF1 :4; /* SCIF1 transfer/error info */ - uint SCIF2 :4; /* SCIF2 transfer/error info */ - uint :4; /* Video Engine Unit */ - ); - pad(2); - - word_union(IPRH, - uint MSIOF0 :4; /* Clock-synchronized SCIF channel 0 */ - uint MSIOF1 :4; /* Clock-synchronized SCIF channel 1 */ - uint :4; /* I2C Interface channel 0 */ - uint :4; /* I2C Interface channel 1 */ - ); - pad(2); - - word_union(IPRI, - uint SCIFA4 :4; /* SCIFA channel 4 interrupt */ - uint :4; /* MediaRAM InterConnected Buffers */ - uint :4; /* Transport Stream Interface */ - uint :4; /* 2D Graphics Accelerator & ICB */ - ); - pad(2); - - word_union(IPRJ, - uint :4; /* Capture Engine Unit */ - uint :4; /* Ethernet Memory Access Controller */ - uint FSI :4; /* FIFO-Buffered Serial Interface */ - uint SDHI1 :4; /* SD Card Host Interface channel 1 */ - ); - pad(2); - - word_union(IPRK, - uint RTC :4; /* Real-Time Clock */ - uint DMAC1B :4; /* DMAC1 transfer/error info */ - uint :4; /* MediaRAM InterConnected Buffers */ - uint SDHI0 :4; /* SD Card Host Interface channel 0 */ - ); - pad(2); - - word_union(IPRL, - uint SCIFA5 :4; /* SCIFA channel 5 interrupt */ - uint :4; - uint TPU :4; /* Timer-Pulse Unit */ - uint :4; /* Image Extraction DMAC */ - ); - pad(2); - -} __attribute((packed, aligned(4))) mod_intc_ipc_7305_t; - -/* - mod_intc_icr0_7305_t - Interrupt Control Register 0: Detection mode of external pins. -*/ -typedef struct -{ - word_union(, - uint const NMIL :1; /* NMI Input Level */ - uint MAI :1; /* Mask All Interrupts */ - uint :4; - uint NMIB :1; /* Enable NMI when BL is set */ - uint NMIE :1; /* NMI Edge Selection */ - uint :2; - uint LVLMODE :1; /* Level-Sensed IRQ Retention Mode */ - uint :5; - ); - -} __attribute__((packed, aligned(2))) mod_intc_icr0_7305_t; - -/* - mod_intc_icr1_7305_t - Interrupt Control Register 1: Manages detection of IRQ interrupts -*/ -typedef struct -{ - word_union(, - uint IRQ0 :2; /* IRQ0 Sense (Edge) Select */ - uint IRQ1 :2; - uint IRQ2 :2; - uint IRQ3 :2; - uint IRQ4 :2; - uint IRQ5 :2; - uint IRQ6 :2; - uint IRQ7 :2; - ); - -} __attribute__((packed, aligned(2))) mod_intc_icr1_7305_t; - -/* - mod_intc_intpri00_7305_t - Interrupt Priority 00: Priority settings for IRQ interrupts. -*/ -typedef struct -{ - lword_union(, - uint IRQ0 :4; /* IRQ0 Interrupt Priority */ - uint IRQ1 :4; - uint IRQ2 :4; - uint IRQ3 :4; - uint IRQ4 :4; - uint IRQ5 :4; - uint IRQ6 :4; - uint IRQ7 :4; - ); - -} __attribute((packed, aligned(4))) mod_intc_intpri00_7305_t; - -/* - mod_intc_intreq00_7305_t - Interrupt Request 00: Request information of IRQ interrupts. Each of - these bits indicates whether an interrupt is being input. - - mod_intc_intmsk00_7305_t - Interrupt Mask 00: Set interrupt mask for IRQ interrupts. Writing 0 to - these bits is ignored, writing 1 masks the interrupt. - - mod_intc_intmskclr00_7305_t - Interrupt Mask Clear 00: Clear interrupt mask for IRQ interrupts. - Writing 0 to these bits is ignored, writing 1 clears the mask. -*/ -typedef struct -{ - byte_union(, - uint IRQ0 :1; - uint IRQ1 :1; - uint IRQ2 :1; - uint IRQ3 :1; - uint IRQ4 :1; - uint IRQ5 :1; - uint IRQ6 :1; - uint IRQ7 :1; - ); - -} __attribute__((packed)) mod_intc_irq_7305_t; - -typedef mod_intc_irq_7305_t mod_intc_intreq00_7305_t; -typedef mod_intc_irq_7305_t mod_intc_intmsk00_7305_t; -typedef mod_intc_irq_7305_t mod_intc_intmskclr00_7305_t; - -/* - mod_intc_masks_7305_t - A set of bits to mask individual interrupts. - - Masking interrupts is realized by writing 1 to IMRs ; - - Clearing masks is realized by writing 1 to IMCRs ; - Using the wrong register set, such as writing 0 to IMRs to clear a - mask, will be ignored and have no effect. Reading from IMCRs yields an - undefined value. -*/ -typedef struct -{ - byte_union(IMR0, - uint :1; - uint TUNI1_2 :1; /* TMU1 overflow interrupts */ - uint TUNI1_1 :1; - uint TUNI1_0 :1; - uint SDHII3 :1; /* SD Card Host 1 interrupts */ - uint SDHII2 :1; - uint SDHII1 :1; - uint SDHII0 :1; - ); - pad(3); - - byte_union(IMR1, - uint :4; - uint DEI3 :1; /* DMAC0A interrupts */ - uint DEI2 :1; - uint DEI1 :1; - uint DEI0 :1; - ); - pad(3); - - byte_union(IMR2, - uint :7; - uint SCIFA0 :1; /* Asynchronous Serial interrupts */ - ); - pad(3); - - byte_union(IMR3, - uint DEI3 :1; /* DMAC1A interrupts */ - uint DEI2 :1; - uint DEI1 :1; - uint DEI0 :1; - uint :4; - ); - pad(3); - - byte_union(IMR4, - uint :1; - uint TUNI0_2 :1; /* TMU0 overflow interrupts */ - uint TUNI0_1 :1; - uint TUNI0_0 :1; - uint :3; - uint LCDCI :1; /* LCD Controller Interrupt */ - ); - pad(3); - - byte_union(IMR5, - uint KEYI :1; /* Key Interface */ - uint DADERR :1; /* DMAC0B interrupts */ - uint DEI5 :1; - uint DEI4 :1; - uint :1; - uint SCIF2 :1; /* Serial Communication Interface */ - uint SCIF1 :1; - uint SCIF0 :1; - ); - pad(3); - - byte_union(IMR6, - uint :2; - uint :1; - uint SCIFA4 :1; /* SCIFA4 interrupt */ - uint :1; - uint :1; - uint MSIOFI0 :1; /* Clock-synchronized SCIF channel 0 */ - uint MSIOFI1 :1; /* Clock-synchronized SCIF channel 1 */ - ); - pad(3); - - uint8_t IMR7; - pad(3); - - byte_union(IMR8, - uint SDHII3 :1; /* SD Card Host 0 interrupts */ - uint SDHII2 :1; - uint SDHII1 :1; - uint SDHII0 :1; - uint :2; - uint SCFIA5 :1; /* SCIFA5 interrupt */ - uint FSI :1; /* FIFO-Buffered Serial Interface */ - ); - pad(3); - - byte_union(IMR9, - uint :3; - uint CMTI :1; /* Compare Match Timer Interrupt */ - uint :1; - uint USI1 :1; /* USB1 */ - uint USI0 :1; /* USB0 */ - uint :1; - ); - pad(3); - - byte_union(IMR10, - uint :1; - uint DADERR :1; /* DMAC1B interrupts */ - uint DEI5 :1; - uint DEI4 :1; - uint :1; - uint ATI :1; /* RTC Alarm interrupt */ - uint PRI :1; /* RTC Periodic interrupt */ - uint CUI :1; /* RTC Carry interrupt */ - ); - pad(3); - - byte_union(IMR11, - uint :5; - uint TPUI :1; /* Timer-Pulse Unit */ - uint :2; - ); - pad(3); - - uint8_t IMR12; - char gap2[15]; - -} __attribute__((packed, aligned(4))) mod_intc_masks_7305_t; - -/* - mod_intc_userimask_7305_t - User Interrupt Mask: Specifies the minimum required level for - interrupts to be accepted. - - WARNING: Writing to this register requires the eight upper bits of the - operand (ie. the new value of USERIMASK) to be 0xa5; otherwise, the - write is ignored. To modify the value of this register, do not access - the bit field directly, backup the variable and modify it: - - void set_user_imask(int new_level) - { - mod_intc_userimask_7305_t mask = *(INTC._7305.USERIMASK); - mask._0xa5 = 0xa5; - mask.UIMASK = new_level & 0x0f; - *(INTC._7305.USERIMASK) = mask; - } -*/ -typedef struct -{ - lword_union(, - uint _0xa5 :8; /* Always set to 0xa5 before writing */ - uint :16; - uint UIMASK :4; /* User Interrupt Mask Level */ - uint :4; - ); - -} __attribute__((packed, aligned(4))) mod_intc_userimask_7305_t; - -/* - mod_intc_nmifcr_7305_t - NMI Flag Control Register: Indicates the state of the NMI pin and the - NMI interrupt request. -*/ -typedef struct -{ - word_union(, - uint const NMIL :1; /* NMI Interupt Level */ - uint :14; - uint NMIFL :1; /* NMI Interrupt Request Flag */ - ); - -} __attribute__((packed, aligned(2))) mod_intc_nmifcr_7305_t; - -/* - mod_intc_7305_t - Finally the whole interrupt controller. -*/ -typedef struct -{ - /* Control registers */ - volatile mod_intc_icr0_7305_t *ICR0; - volatile mod_intc_icr1_7305_t *ICR1; - - /* Interrupt priority registers */ - volatile mod_intc_intpri00_7305_t *INTPRI00; - volatile mod_intc_ipc_7305_t *iprs; - - /* Interrupt mask & mask clear registers */ - volatile mod_intc_intmsk00_7305_t *INTMSK00; - volatile mod_intc_masks_7305_t *masks; - volatile mod_intc_intmskclr00_7305_t *INTMSKCLR00; - volatile mod_intc_masks_7305_t *masks_clear; - - /* Other registers */ - volatile mod_intc_intreq00_7305_t *INTREQ00; - volatile mod_intc_userimask_7305_t *USERIMASK; - volatile mod_intc_nmifcr_7305_t *NMIFCR; - -} mod_intc_7305_t; - - - -//--- -// Platform-independent structures. -// Unfortunately there is nothing here. Users willing to manage interrupts -// using the INTC register will have to handle explicitely both platforms. -//--- - -/* - mod_intc_t - Interrupt Controller. -*/ -typedef union -{ - mod_intc_7705_t _7705; - mod_intc_7305_t _7305; - -} __attribute__((packed)) mod_intc_t; - -// Here's what you'll need to use. -extern mod_intc_t INTC; - -#endif // _MODULE_INTERRUPTS_H diff --git a/include/modules/macros.h b/include/modules/macros.h deleted file mode 100644 index 327dde7..0000000 --- a/include/modules/macros.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _MODULES_MACROS_H -#define _MODULES_MACROS_H - -#include - -// Padding is just empty space, we don't want to give it a type. There's also -// some subtle preprocessor trick to automatically add a (supposedly) unique -// name to each padding member. For instance the substitution may operate as: -// name(__LINE__) -> namesub(78) -> _##78 -> _78 -#define namesub(x) _##x -#define name(x) namesub(x) -#define pad(bytes) \ - uint8_t name(__LINE__)[bytes] - -// Fixed-width types for bit field are totally meaningless. -typedef unsigned uint; - -/* - byte_union() - Union between an uint8_t 'byte' attribute and a provided bit-field - structure that describe the contents of the byte. -*/ -#define byte_union(name, fields) \ - union \ - { \ - uint8_t byte; \ - struct { fields } \ - __attribute__((packed)); \ - } __attribute__((packed)) name - -/* - word_union() - Union between an uint16_t 'word' attribute and a provided bit-field - structure that describe the contents of the word. -*/ -#define word_union(name, fields) \ - union \ - { \ - uint16_t word; \ - struct { fields } \ - __attribute__((packed)); \ - } __attribute__((packed, aligned(2))) name - -/* - lword_union() - Union between an uint32_t 'lword' attribute and a provided bit-field - structure that describe the contents of the longword. -*/ -#define lword_union(name, fields) \ - union \ - { \ - uint32_t lword; \ - struct { fields } \ - __attribute__((packed)); \ - } __attribute__((packed, aligned(4))) name - -#endif // _MODULES_MACROS_H diff --git a/include/modules/rtc.h b/include/modules/rtc.h deleted file mode 100644 index 7eb7ef0..0000000 --- a/include/modules/rtc.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef _MODULES_RTC_H -#define _MODULES_RTC_H - -#include -#include - -/* - mod_rtc_rcr1_t - First RTC configuration register. -*/ -typedef struct -{ - byte_union(, - uint CF :1; /* Carry flag */ - uint :2; - uint CIE :1; /* Carry interrupt enable */ - uint AIE :1; /* Alarm interrupt enable */ - uint :2; - uint AF :1; /* Alarm flag */ - ); - -} __attribute__((packed)) mod_rtc_rcr1_t; - -/* - mod_rtc_rcr2_t - Second RTC configuration register. -*/ -typedef struct -{ - byte_union(, - uint PEF :1; /* Periodic interrupt flag */ - uint PES :3; /* Periodic interrupt interval */ - uint :1; - uint ADJ :1; /* 30-second adjustment */ - uint RESET :1; /* Reset */ - uint START :1; /* Start bit */ - ); - -} __attribute__((packed)) mod_rtc_rcr2_t; - -/* - mod_rtc_rcr3_t - Third RTC configuration register. - -typedef struct -{ - byte_union(, - uint YAEN :1; - uint :7; - ); - -} __attribute__((packed)) mod_rtc_rcr3_t; -*/ - -/* - mod_rtc_time_t - A set of registers describing the current time in BCD format. -*/ -typedef struct -{ - const uint8_t R64CNT; /* More or less a 64-Hz counter */ - pad(1); - - byte_union(RSECCNT, /* Second count */ - uint :1; - uint TENS :3; - uint ONES :4; - ); - pad(1); - - byte_union(RMINCNT, /* Minute count */ - uint :1; - uint TENS :3; - uint ONES :4; - ); - pad(1); - - byte_union(RHRCNT, /* Hour count */ - uint :2; - uint TENS :2; - uint ONES :4; - ); - pad(1); - - /* 0 = Sunday .. 6 = Saturday, other settings are prohibited. */ - uint8_t RWKCNT; /* Day of week */ - pad(1); - - byte_union(RDAYCNT, /* Day count */ - uint :2; - uint TENS :2; - uint ONES :4; - ); - pad(1); - - byte_union(RMONCNT, /* Month count */ - uint :3; - uint TENS :1; - uint ONES :4; - ); - pad(1); - - word_union(RYRCNT, /* Year count */ - uint THOUSANDS :4; - uint HUNDREDS :4; - uint TENS :4; - uint ONES :4; - ); - -} __attribute__((packed, aligned(2))) mod_rtc_time_t; - -/* - mod_rtc_t (resides into gint memory) - Three control registers and timer information. -*/ -typedef struct -{ - /* RCR1, RCR2, and RCR3 are the same for both platforms. */ - volatile mod_rtc_rcr1_t *RCR1; - volatile mod_rtc_rcr2_t *RCR2; -// volatile mod_rtc_rcr3_t *RCR3; - /* Current time in register memory */ - volatile mod_rtc_time_t *time; - -} mod_rtc_t; - -// All you need to use is this structure, initialized by gint, which contains -// address that work with your execution platform. -extern mod_rtc_t RTC; - -#endif // _INTERNALS_RTC_H diff --git a/include/modules/timer.h b/include/modules/timer.h deleted file mode 100644 index 46657ae..0000000 --- a/include/modules/timer.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _MODULES_TIMER_H -#define _MODULES_TIMER_H - -#include -#include - -/* - mod_tmu_timer_t - Registers of a single timer. -*/ -typedef struct -{ - uint32_t TCOR; /* Timer constant register */ - uint32_t TCNT; /* Timer counter */ - - word_union(TCR, - uint :7; - uint UNF :1; /* Underflow flag */ - uint :2; - uint UNIE :1; /* Underflow interrupt enable */ - uint CKEG :2; /* Clock edge (SH7705) */ - uint TPSC :3; /* Timer prescaler */ - ); - - uint16_t :16; - -} __attribute__((packed, aligned(4))) mod_tmu_timer_t; - -/* - mod_tmu_tstr_t - The timer start register. -*/ -typedef struct -{ - byte_union(, - uint :5; - uint STR2 :1; /* Counter start 2 */ - uint STR1 :1; /* Counter start 1 */ - uint STR0 :1; /* Counter start 0 */ - ); - -} __attribute__((packed)) mod_tmu_tstr_t; - -/* - mod_tmu_t (resides into gint memory) - Basically three timer units and an additional register to control who's - running. -*/ -typedef struct -{ - /* Timer configurations */ - volatile mod_tmu_timer_t *timers[3]; - /* Timer start register */ - volatile mod_tmu_tstr_t *TSTR; - /* Timer input capture 2 (SH7705) */ - volatile const uint32_t *TCPR2; - -} mod_tmu_t; - -// The actual thing is there. It's initialized by gint at startup and contains -// addresses and information suitable for the current platform. -extern mod_tmu_t TMU; - -#endif // _MODULES_TIMER diff --git a/include/mpu.h b/include/mpu.h deleted file mode 100644 index 8b7219d..0000000 --- a/include/mpu.h +++ /dev/null @@ -1,71 +0,0 @@ -//--- -// -// gint core module: mpu -// -// Determines which kind of MPU is running the program. This module -// provides macro tests isSH3(), isSH4(), and the identifier of the MPU, -// which is stored in a global variable MPU_CURRENT and determined at -// startup. -// -// If you need to do MPU-dependent jobs, use isSH3() or (possibly) isSH4() -// instead of testing the value of MPU_CURRENT because these macros take -// care of assuming unknown MPUs are SH4, which is the more reasonable -// option. -// -// It is advised to always use the following alternative (which gint -// does): -// -// if(isSH3()) -// { -// ... -// } -// else -// { -// ... -// } -// -//--- - -#ifndef _MPU_H -#define _MPU_H - -/* - mpu_t - This type holds information about the calculator's MPU. -*/ -typedef enum -{ - mpu_unknown = 0, - // fx-9860G SH3. - mpu_sh7337 = 1, - // fx-9860G II SH3. - mpu_sh7355 = 2, - // fx-9860G II SH4. - mpu_sh7305 = 3, - // Just for reference (no calculator uses it). - mpu_sh7724 = 4, - -} mpu_t; - -// Global MPU variable, accessible for direct tests. Initialized at the -// beginning of execution. -extern const mpu_t MPU_CURRENT; - -// Quick SH3 test. It is safer to assume that an unknown model is SH4 because -// SH3-based models are not produced anymore. -#define isSH3() (MPU_CURRENT == mpu_sh7337 || MPU_CURRENT == mpu_sh7355) -#define isSH4() (!isSH3()) - - - -//--- -// Public API. -//--- - -/* - getMPU() - Determines the MPU type and returns it. MPU_CURRENT is not updated. -*/ -mpu_t getMPU(void); - -#endif // _MPU_H diff --git a/include/rtc.h b/include/rtc.h deleted file mode 100644 index 2c65876..0000000 --- a/include/rtc.h +++ /dev/null @@ -1,105 +0,0 @@ -//--- -// -// gint core module: rtc -// -// Manages the Real-Time Clock (RTC). This module provides access to the -// current time as well as regular callbacks at predefined frequencies, -// more or less like a timer. -// The standard time module is built upon this one. -// -//--- - -#ifndef _RTC_H -#define _RTC_H - -#include - -//--- -// Time access. -//--- - -/* - rtc_time_t - Defines a point in time. -*/ -typedef struct -{ - uint8_t seconds; // Seconds in range 0-59 - uint8_t minutes; // Minutes in range 0-59 - uint8_t hours; // Hours in range 0-23 - uint8_t month_day; // Day of month in range 1-31 - uint8_t month; // Month in range 0-11 - uint8_t week_day; // Day of week in range 0(Sunday)-6(Saturday). - uint16_t year; // Years (around 2000) - -} rtc_time_t; - -/* - rtc_getTime() - Reads the current time from the RTC. There is no guarantee that the - week day is correct (use the time API for that). -*/ -void rtc_getTime(rtc_time_t *time); - -/* - rtc_setTime() - Sets the time in the RTC registers. The week day is set to 0 if greater - than 6. Other fields are not checked. -*/ -void rtc_setTime(const rtc_time_t *time); - - - -//--- -// Callback API. -//--- - -/* - rtc_frequency_t - Describes the possible frequencies available for the real-time clock - interrupt. -*/ -typedef enum -{ - rtc_freq_500mHz = 7, - rtc_freq_1Hz = 6, - rtc_freq_2Hz = 5, - rtc_freq_4Hz = 4, - rtc_freq_16Hz = 3, - rtc_freq_64Hz = 2, - rtc_freq_256Hz = 1, - rtc_freq_none = 0, - -} rtc_frequency_t; - -/* - rtc_cb_add() - Registers a new callback for the RTC. Returns the callback id on - success (positive integer), or one of the following error codes: - -1 Array is full - -2 Invalid parameter - The number of repeats may be set to 0, in which case the callback is - called indefinitely unless the user calls rtc_cb_end(). -*/ -int rtc_cb_add(rtc_frequency_t freq, void (*function)(void), int repeats); - -/* - rtc_cb_end() - Removes the callback with the given id (as returned by rtc_cb_add()) - from the callback array. -*/ -void rtc_cb_end(int id); - -/* - rtc_cb_edit() - Changes information related to a callback. This function returns 0 on - success, or one of the following error codes: - -1 Callback does not exist - -2 Invalid parameters - This function never removes a callback. Call rtc_cb_end() for this. One - can set the function to NULL or the frequency to rtc_freq_none to - temporarily disable the callback. -*/ -int rtc_cb_edit(int id, rtc_frequency_t new_freq, void (*new_function)(void)); - -#endif // _RTC_H diff --git a/include/screen.h b/include/screen.h deleted file mode 100644 index ec459a5..0000000 --- a/include/screen.h +++ /dev/null @@ -1,35 +0,0 @@ -//--- -// -// gint display module: screen -// -// Interacts with the physical screen. See other display modules for video -// ram management and drawing. -// -// The screen basically has two input values, which are a register -// selector and the selected register's value. What this module does is -// essentially selecting registers by setting *selector and assigning them -// values by setting *data. -//--- - -#ifndef _SCREEN_H -#define _SCREEN_H - -/* - screen_display() - Displays contents on the full screen. Expects a 1024-byte buffer. -*/ -void screen_display(const void *vram); - -/* - screen_setBacklight() - On compatible models, turns on or turns off the backlight. -*/ -void screen_setBacklight(int on); - -/* - screen_toggleBacklight() - Changes the backlight state, regardless of its current state. -*/ -void screen_toggleBacklight(void); - -#endif diff --git a/include/setjmp.h b/include/setjmp.h deleted file mode 100644 index b3aa872..0000000 --- a/include/setjmp.h +++ /dev/null @@ -1,37 +0,0 @@ -//--- -// -// gint standard module: setjmp -// -// Long jumps. The register contents are saved in a buffer when setjmp() -// is called and restored at any time when longjmp() performs the jump. -// -//--- - -#ifndef _SETJMP_H -#define _SETJMP_H - -#include - -// There are 16 CPU registers that *must* be saved to ensure a basically -// safe jump. -typedef uint32_t jmp_buf[16]; - - - -//--- -// Long jump functions. -//--- - -/* - setjmp() O(1) - Configures a jump by saving data to the given jump buffer. -*/ -int setjmp(jmp_buf env); - -/* - longjmp() O(1) - Performs a long jump. -*/ -void longjmp(jmp_buf env, int value); - -#endif // _SETJMP_H diff --git a/include/stdio.h b/include/stdio.h deleted file mode 100644 index ba27de6..0000000 --- a/include/stdio.h +++ /dev/null @@ -1,44 +0,0 @@ -//--- -// -// standard library module: stdio -// -// Handles most input/output for the program. This module does not -// interact with the file system directly. -// -//--- - -#ifndef _STDIO_H -#define _STDIO_H - -#include -#include - -//--- -// Formatted printing. -//--- - -/* - sprintf() - Prints to a string. -*/ -int sprintf(char *str, const char *format, ...); - -/* - snprintf() - Prints to a string with a size limit. -*/ -int snprintf(char *str, size_t size, const char *format, ...); - -/* - vsprintf() - Prints to a string from an argument list. -*/ -int vsprintf(char *str, const char *format, va_list args); - -/* - vsnprintf() - The most generic formatted printing function around there. -*/ -int vsnprintf(char *str, size_t size, const char *format, va_list args); - -#endif // _STDIO_H diff --git a/include/stdlib.h b/include/stdlib.h deleted file mode 100644 index 59b6272..0000000 --- a/include/stdlib.h +++ /dev/null @@ -1,149 +0,0 @@ -//--- -// -// standard library module: stdlib -// -// Provides standard functionalities such as dynamic allocation, -// string/numeric conversion, and abort calls. -// -//--- - -#ifndef _STDLIB_H -#define _STDLIB_H - -//--- -// Common definitions. -//--- - -#include -#include - -// Common exit codes. -#define EXIT_SUCCESS 1 -#define EXIT_FAILURE 0 - -// Number of atexit() registrations guaranteed. -#ifndef ATEXIT_MAX -#define ATEXIT_MAX 16 -#endif - -// Maximum value returned by rand(). -#define RAND_MAX INT_MAX - -// Integer division result. -typedef struct -{ - int quot, rem; -} div_t; -typedef struct -{ - long quot, rem; -} ldiv_t; - - - -//--- -// Program exit functions. -//--- - -/* - abort() - Aborts the program execution without calling the exit handlers. -*/ -void abort(void); - -/* - exit() - Stops the program execution with the given status code, after calling - the exit handlers. -*/ -void exit(int status); - -/* - atexit() - Registers a function to be called at normal program termination. -*/ -int atexit(void (*function)(void)); - - - -//--- -// Dynamic storage allocation. -//--- - -/* - malloc() - Allocates 'size' bytes and returns a pointer to a free memory area. - Returns NULL on error. -*/ -void *malloc(size_t size); - -/* - calloc() - Allocates 'n' elements of size 'size' and wipes the memory area. - Returns NULL on error. -*/ -void *calloc(size_t n, size_t size); - -/* - realloc() - Reallocates a memory block and moves its data. -*/ -void *realloc(void *ptr, size_t size); - -/* - free() - Frees a memory block allocated by malloc(), calloc() or realloc(). -*/ -void free(void *ptr); - - - -//--- -// Random number generation. -//--- - -/* - rand() - Returns a pseudo-random number. -*/ -int rand(void); - -/* - srand() - Changes the seed used by rand(). -*/ -void srand(unsigned int seed); - -//--- -// Integer arithmetic. -//--- - -/* - abs() - Returns the absolute value of an integer. -*/ -int abs(int x); -// Use a macro instead, when possible. -#define abs(x) ((x) < 0 ? -(x) : (x)) - -/* - labs() - Returns the absolute value of a long integer. -*/ -long labs(long x); -// Use a macro instead. -#define labs(x) ((x) < 0 ? -(x) : (x)) - -/* - div() - Computes the integer division of numerator by denominator. -*/ -div_t div(int numerator, int denominator); - -/* - ldiv() - Computes the integer division of two long integers. -*/ -ldiv_t ldiv(long numerator, long denominator); - -#endif // _STDLIB_H diff --git a/include/string.h b/include/string.h deleted file mode 100644 index 70ac65a..0000000 --- a/include/string.h +++ /dev/null @@ -1,94 +0,0 @@ -//--- -// -// standard library module: string -// -// String manipulation using NUL-terminated byte arrays, without extended -// characters. -// -//--- - -#ifndef _STRING_H -#define _STRING_H - -#include - -//--- -// Memory manipulation. -//--- - -/* - memcpy() O(byte_count) - Copies a memory area. The two areas must not overlap (if they do, use - memmove()). A smart copy is performed when possible. To enhance - performance, make sure than destination and source are both 4-aligned. -*/ -void *memcpy(void *destination, const void *source, size_t byte_count); - -/* - memset() O(byte_count) - Sets the contents of a memory area. A smart copy is performed. -*/ -void *memset(void *destination, int byte, size_t byte_count); - -/* - memchr() O(byte_count) - Looks for a byte in a memory area. Returns the address of the first - occurrence if found, NULL otherwise. -*/ -void *memchr(const void *area, int byte, size_t byte_count); - -/* - memcmp() O(byte_count) - Compares two memory areas. Returns 0 if all bytes are equal in both - areas, a negative number if the first unequal byte is lower in the - first area, and a positive number otherwise. - A smart comparison is performed when possible. -*/ -int memcmp(const void *area1, const void *area2, size_t byte_count); - - - -//--- -// String manipulation. -//--- - -/* - strlen() O(len(str)) - Returns the length of a string. -*/ -size_t strlen(const char *str); - -/* - strnlen() O(len(str)) - Returns the minimum of the length of the string and n. This function - never access more than n bytes at the beginning of the string. -*/ -size_t strnlen(const char *str, size_t n); - -/* - strcpy() O(len(source)) - Copies a string to another. -*/ -char *strcpy(char *destination, const char *source); - -/* - strncpy() O(min(len(source), size)) - Copies part of a string to another. -*/ -char *strncpy(char *destination, const char *source, size_t size); - -/* - strchr() O(len(str)) - Searches a character in a string. -*/ -const char *strchr(const char *str, int value); - -/* - strcmp() O(max(len(str1), len(str2))) - Compares two strings. Returns 0 if they are identical, a negative - number if the first unequal byte is lower in str1 than in str2, and a - positive number otherwise. -*/ -int strcmp(const char *str1, const char *str2); - -#endif // _STRING_H diff --git a/include/tales.h b/include/tales.h deleted file mode 100644 index 2f189b7..0000000 --- a/include/tales.h +++ /dev/null @@ -1,128 +0,0 @@ -//--- -// -// gint drawing module: tales -// -// Text displaying. Does some pretty good optimization, though requires -// dynamic allocation. The stack is used. -// -//--- - -#ifndef _TALES_H -#define _TALES_H - -#include -#include -#include - -//--- -// Types and constants. -//--- - -/* - font_format_t - This type holds information about the characters in the font. Each bit - represents various characters, and the type itself is a combination of - several of those bits. - Bits represent the following characters (lsb right): - -- -- -- non-print | special capitals lower numbers -*/ -typedef enum -{ - font_format_unknown = 0x00, - font_format_numeric = 0x01, - font_format_lower = 0x02, - font_format_upper = 0x04, - font_format_letters = 0x06, - font_format_common = 0x07, - font_format_print = 0x0f, - font_format_ascii = 0x1f, - -} font_format_t; - -/* - font_glyph_t - Holds a glyph's data. The width is used for spacing, and the raw data - is encoded line after line, from to to bottom, by appending bits - without consideration of the byte boundaries. - This structure is actually never used, because data is read directly - as a longword array (hence the 4-byte alignment). -*/ -typedef struct -{ - uint8_t width; - const uint8_t data[]; - -} __attribute__((packed, aligned(4))) font_glyph_t; - -/* - font_t - Holds a font's data. Data is accessed using longword operations, hence - the 4-alignment attributes. The line height is the one given in the - font image header line, which may be used by applications that write - strings on several lines. The data height is the height of the biggest - glyph. Every glyph is encoded on 'data_height' lines, for optimization - considerations. - The index field is used to reduce character access time. - The name field may not be NUL-terminated when the name contains 28 - characters. When the name is shorter, the field is padded with zeros. -*/ -typedef struct -{ - uint8_t magic; - uint8_t format; - uint8_t line_height; - uint8_t data_height; - - // Warning : this field may not be NUL-terminated. - char name[28]; - - uint16_t index[16]; - - __attribute__((aligned(4))) const uint32_t glyphs[]; - -} __attribute__((packed, aligned(4))) font_t; - - - -//--- -// Generic functions. -//--- - -/* - text_configure() - Sets the font and color to use for subsequent text operations. Pass - font = NULL to use the default font. -*/ -void text_configure(font_t *font, color_t operator); - -/* - text_length() - Computes the length of a string using the currently configured font. -*/ -size_t text_length(const char *str); - -/* - dtext() - Prints the given string, without any analysis. -*/ -void dtext(int x, int y, const char *str); - -/* - gtext() - Prints the given raw string. -*/ -void gtext(int x, int y, const char *str); - -/* - dprint() - Prints a formatted string. Works the same as printf(). -*/ -void dprint(int x, int y, const char *format, ...); - -/* - gprint() - Prints a formatted string. Works the same as printf(). -*/ -void gprint(int x, int y, const char *format, ...); - -#endif // _TALES_H diff --git a/include/time.h b/include/time.h deleted file mode 100644 index 9ec8298..0000000 --- a/include/time.h +++ /dev/null @@ -1,126 +0,0 @@ -//--- -// -// standard library module: time -// -// Provides time manipulation and representation functions. -// -//--- - -#ifndef _TIME_H -#define _TIME_H - -#include - -//--- -// Some related types. -//--- - -/* - struct tm - Represents a point in time and gives some date information. -*/ -struct tm -{ - int tm_sec; // Seconds in range 0-59 - int tm_min; // Minutes in range 0-59 - int tm_hour; // Hours in range 0-23 - int tm_mday; // Day of month in range 1-31 - int tm_mon; // Month in range 0-11 - int tm_year; // Number of years since 1900 - int tm_wday; // Day of week in range 0(Sunday)-6(Saturday). - int tm_yday; // Day of the year in range 0-365. - int tm_isdst; // This will always be 0. -}; - -/* - clock_t - Only used by clock(). -*/ -typedef signed int clock_t; - -/* - time_t - Number of seconds elapsed since 1970-01-01 00:00:00. -*/ -typedef signed int time_t; - - - -//--- -// Time access. -//--- - -/* - clock() - Should return elapsed CPU time since beginning of program execution. - This is currently not implemented and returns -1. -*/ -clock_t clock(void); - -/* - time() - Returns the current time as calendar time. If you need a broken-down - time, either use the RTC API or gmtime(). However, this function is - already based on mktime() (for hardware reasons) so it would be much - faster to use the RTC API if possible. - If timeptr is not NULL, it is set to the current time, that is, the - value that is returned. -*/ -time_t time(time_t *timeptr); - -/* - difftime() - Returns the number of seconds between the given points. -*/ -double difftime(time_t end, time_t beginning); -// But this macro should do. -#define difftime(end, beginning) ((double)((end) - (beginning))) - - - -//--- -// Time representation. -//--- - -/* - asctime() - Converts broken-down time to string representation on the form - "Wed Jun 30 21:49:08 1993\n". The returned string is statically - allocated and may be overwritten by any subsequent call to a time - function. -*/ -char *asctime(const struct tm *time); - -/* - ctime() - Converts calendar time to string representation on the form - "Wed Jun 30 21:49:08 1993\n". The returned string is statically - allocated and may be overwritten by any subsequent call to a time - function. -*/ -char *ctime(const time_t *timer); - - - -//--- -// Time conversion. -//--- - -/* - mktime() - Converts broken-down time to calendar time. Computes structure fields - tm_wday and tm_yday using the other fields. Member structures outside - their range are normalized (e.g. 40 October becomes 9 November) and - tm_isdst is set. -*/ -time_t mktime(struct tm *time); - -/* - gmtime() - Converts calendar time to broken-down time. The returned pointer is - statically allocated and may be overwritten by any subsequent call to - a time function. -*/ -struct tm *gmtime(const time_t *t); - -#endif // _TIME_H diff --git a/include/timer.h b/include/timer.h deleted file mode 100644 index f6cad24..0000000 --- a/include/timer.h +++ /dev/null @@ -1,177 +0,0 @@ -//--- -// -// gint core module: timer -// -// Basic timer unit manipulation. Starts and stops timers with variable -// number of repeats, and allows timer reloads without pause. -// -//--- - -#ifndef _TIMER_H -#define _TIMER_H - -#include -#include -#include - -// The timer object is manipulated by the module; the user needs not access it -// directly. Its contents are defined in . -struct timer_t; -typedef struct timer_t timer_t; - -//--- -// Virtual timer API -// Gint allows users to create virtual timers with 1-ms precision to -// handle an important amount of timed events. The amount of virtual -// timers available is gapped by the TIMER_SLOTS parameter, but this -// parameter can be customized when building the library; thus, the -// amount of usable virtual timers is not limited. -//--- - -#ifndef TIMER_SLOTS -#define TIMER_SLOTS 16 -#endif - -/* - timer_create() - Basic timer configuration. This function creates a virtual timer and - configures its delay and repetition count. It returns a virtual timer - object that will be used by other functions. At most TIMER_SLOTS - virtual timers can be used at the same time: this function returns NULL - if there is no new slot available. - By default a virtual timer configured by timer_configure() will fire - ET_Timer events, which the user will need to catch. The user should - then execute some action. - There is another option: the user may call timer_attach() to attach a - callback to a virtual timer. A virtual timer which has a callback - attached will not fire any ET_Timer event and will call the callback - automatically instead. -*/ -timer_t *timer_create(int delay_ms, int repeats); - -/* - timer_reload() - Changes a virtual timer's delay. The timer is not stopped nor started: - it keeps running or waiting. Events that were waiting to be handled are - dropped and the number of repeats left is not changed. The timer - restarts counting from 0 regardless of how much time had elapsed since - it last fired. -*/ -void timer_reload(timer_t *timer, int new_ms_delay); - -/* - timer_destroy() - Destroys a virtual timer. This virtual timer pointer becomes invalid - and should not be used anymore. -*/ -void timer_destroy(timer_t *virtual_timer); - - - -//--- -// Hardware timer API -// Gint provides access to hardware timer. These timer offer more or less -// microsecond-level control. However, the user should ensure, when using -// hardware timers, that they are not overriding the configuration of -// timers that are already running -- gint won't check. -//--- - -/* - timer_hard_t - Available hardware timers. The user can use timer_user freely, but - timer_gray and timer_virtual should not be used as long as the gray - engine or virtual timers are running (respectively). -*/ -typedef enum -{ - timer_tmu0 = 0, - timer_virtual = timer_tmu0, - - timer_tmu1 = 1, - timer_gray = timer_tmu1, - - timer_tmu2 = 2, - timer_user = timer_tmu2, - -} timer_hard_t; - -/* - timer_input_t - Available input clocks for the hardware timer: - - Po/4 Peripheral clock (frequency divided by 4) - - Po/16 Peripheral clock (frequency divided by 16) - - Po/64 Peripheral clock (frequency divided by 64) - - Po/256 Peripheral clock (frequency divided by 256) - - TCLK External clock - I'm not totally sure there is any signal on the external clock, so - don't use it unless you know what you are doing. -*/ -typedef enum -{ - timer_Po_4 = 0, - timer_Po_16 = 1, - timer_Po_64 = 2, - timer_Po_256 = 3, - timer_tclk = 5, - -} timer_input_t; - -/* - htimer_setup() - Configures a hardware timer. By default hardware timers generates - ET_Timer events but catching them may take some time, especially if - there are other events waiting in the queue. For increased timing, and - for fast timers, the user should consider using callbacks instead. - Returns a hardware timer object. - Returns the correct timer structure if the requested timer is free and - NULL otherwise. -*/ -timer_t *htimer_setup(timer_hard_t id, uint32_t constant, timer_input_t input, - int repeats); - -/* - htimer_reload() - Reloads a hardware timer without starting or stopping it. -*/ -void htimer_reload(timer_hard_t id, uint32_t new_constant); - - - -//--- -// Common API -// The following functions work with both virtual and hardware timers. -//--- - -/* - timer_attach() - This function attaches a callback to a virtual or hardware timer. A - timer with a callback attached will stop firing ET_Timer events and - will call the callback function directly instead. - The type signature of the function should be as follows: - - void callback(void) if argument == NULL - - void callback(void *argument) if argument is non-NULL - In the latter case, the argument pointer will be passed to the callback - function. -*/ -void timer_attach(timer_t *timer, void *callback, void *argument); - -/* - timer_start() - Starts a virtual or hardware timer. If the timer has a callback - attached, then the callback function will start being called regularly; - otherwise, the timer will start pushing ET_Timer events to the event - queue. It is advised, not to change a timer's configuration while it's - running. -*/ -void timer_start(timer_t *timer); - -/* - timer_stop() - Stops a timer. If the argument is virtual timer, it is paused and can - be started again later. - If it's a hardware timer, it is freed and made accessible to other - uses. It should be set up again before being started. -*/ -void timer_stop(timer_t *timer); - -#endif // _TIMER_H diff --git a/src/bopti/bopti_internals.c b/src/bopti/bopti_internals.c deleted file mode 100644 index cfe5013..0000000 --- a/src/bopti/bopti_internals.c +++ /dev/null @@ -1,331 +0,0 @@ -#include - -// Monochrome video ram, light and dark buffers (in this order). -uint32_t *bopti_vram, *bopti_v1, *bopti_v2; - -/* - bopti_op() - Operates on a vram long. The operator will often not contain 32 bits of - image information. Since neutral bits are not the same for all - operations, a mask is used to indicate which bits should be used for - the operation. This mask is taken for the image's rectangle masks (see - module display for more information on rectangle masks). - Which operation is performed is determined by the channel setting. -*/ -void bopti_op_mono(int offset, uint32_t operator, command_t *c) -{ - operator &= c->masks[offset & 3]; - - switch(c->channel) - { - case channel_full_alpha: - bopti_vram[offset] &= ~operator; - break; - - case channel_mono: - bopti_vram[offset] |= operator; - break; - - default: - break; - } -} -void bopti_op_gray(int offset, uint32_t operator, command_t *c) -{ - operator &= c->masks[offset & 3]; - - switch(c->channel) - { - case channel_full_alpha: - bopti_v1[offset] &= ~operator; - bopti_v2[offset] &= ~operator; - break; - - case channel_light_alpha: - case channel_dark_alpha: - break; - - case channel_mono: - bopti_v1[offset] |= operator; - bopti_v2[offset] |= operator; - break; - - case channel_light: - bopti_v1[offset] |= operator; - break; - - case channel_dark: - bopti_v2[offset] |= operator; - break; - } -} - -/* - bopti_grid() -- general form - bopti_grid_a32() -- when x is a multiple of 32 - - Draws the grid at the beginning of a layer's data. The length of this - grid is always a multiple of 32. - The need for bopti_grid_a32() is not only linked to optimization, - because bopti_grid() will perform a 32-bit shift when x is a multiple - of 32, which is undefined behavior. -*/ -void bopti_grid_a32(const uint32_t *layer, int column_count, int height, - command_t *c) -{ - int vram_column_offset = (c->y << 2) + (c->x >> 5); - int vram_offset = vram_column_offset; - int column, row; - - for(column = 0; column < column_count; column++) - { - for(row = c->top; row < c->bottom; row++) - { - (c->op)(vram_offset, layer[row], c); - vram_offset += 4; - } - - vram_column_offset++; - vram_offset = vram_column_offset; - layer += height; - } -} -void bopti_grid(const uint32_t *layer, int column_count, int height, - command_t *c) -{ - if(!column_count) return; - if(!(c->x & 31)) - { - bopti_grid_a32(layer, column_count, height, c); - return; - } - - const uint32_t *p1, *p2; - uint32_t l1, l2, operator; - int right_column, line; - int actual_column_count; - - int vram_column_offset = (c->y << 2) + (c->x >> 5) + (c->x < 0); - int vram_offset = vram_column_offset; - - int shift2 = (c->x & 31); - int shift1 = 32 - shift2; - - // Initializing two pointers. They will read two adjacent columns at - // the same time (p2 is column ahead of p1). Since the columns are - // written one after another, incrementing them will suffice when - // reaching the end of two columns, to move them to the next ones. - p1 = layer - height; - p2 = layer; - - // We don't want to write the first vram column when x is negative - // because it's outside the screen. - if(c->x < 0) p1 += height, p2 += height; - right_column = (c->x < 0); - // For the same reason, we don't to draw the additional rightmost - // column when it begins after 96. - if(c->x + (column_count << 5) > 128) - actual_column_count = column_count - 1; - else - actual_column_count = column_count; - - // Drawing vram longwords, using pairs of columns. - while(right_column <= actual_column_count) - { - for(line = c->top; line < c->bottom; line++) - { - l1 = (right_column > 0) ? p1[line] : (0); - l2 = (right_column < column_count) ? p2[line] : (0); - - operator = (l1 << shift1) | (l2 >> shift2); - (c->op)(vram_offset, operator, c); - - vram_offset += 4; - } - - p1 += height; - p2 += height; - vram_column_offset++; - vram_offset = vram_column_offset; - right_column++; - } -} - -/* - bopti_end_get() - Returns an operator for the end of a line, whose width is lower than 32 - (by design: otherwise, it would have been a column). The given pointer - is read and updated so that it points to the next line at the end of - the operation. -*/ -uint32_t bopti_end_get1(const unsigned char **data) -{ - uint32_t operator = **data; - *data += 1; - return operator; -} -uint32_t bopti_end_get2(const unsigned char **data) -{ - uint32_t operator = *((uint16_t *)*data); - *data += 2; - return operator; -} - -/* - bopti_rest() -- general form - bopti_rest_nover() -- when the end does not overlap two vram longs - - Draws the end of a layer, which can be considered as a whole layer - whose with is lower than 32. (Actually is it lower or equal to 16; - otherwise it would have been a column and the end would be empty.) -*/ -void bopti_end_nover(const unsigned char *end, int size, command_t *c) -{ - uint32_t (*get)(const unsigned char **data) = - (size == 2) ? bopti_end_get2 : bopti_end_get1; - - // We *have* shift >= 0 because of this function's 'no overlap' - // requirement. - int shift = (32 - (size << 3)) - (c->x & 31); - int vram_offset = (c->y << 2) + (c->x >> 5); - uint32_t operator; - int row; - - // Skipping c->top lines (because get() function only allows sequential - // access). - end += c->top * size; - - for(row = c->top; row < c->bottom; row++) - { - operator = (*get)(&end); - operator <<= shift; - (c->op)(vram_offset, operator, c); - vram_offset += 4; - } -} -void bopti_end(const unsigned char *end, int size, command_t *c) -{ - uint32_t (*get)(const unsigned char **data) = - (size == 2) ? (bopti_end_get2) : (bopti_end_get1); - - int vram_offset = (c->y << 2) + (c->x >> 5); - uint32_t row_data; - int row; - - int shift_base = (32 - (size << 3)); - int shift1 = (c->x & 31) - shift_base; - int shift2 = shift_base + 32 - (c-> x & 31); - - // Skipping c->top lines (because get() function only allows sequential - // access). - end += c->top * size; - - for(row = c->top; row < c->bottom; row++) - { - row_data = (*get)(&end); - (c->op)(vram_offset, row_data >> shift1, c); - (c->op)(vram_offset + 1, row_data << shift2, c); - vram_offset += 4; - } -} - - - -//--- -// Wrappers and various functions. -//--- - -/* - bopti() - Draws a layer in the video ram. -*/ -void bopti(const unsigned char *layer, structure_t *s, command_t *c) -{ - const unsigned char *grid, *end; - int grid_columns, has_end; - - // Skipping columns at the beginning. - grid = layer + ((c->left * s->height) << 2); - - // Updating the command arguments to eliminate some information about - // parts that are not being drawn. - c->x += (c->left << 5); - c->y += c->top; - - // Columns are identified by ids 0 to s->columns - 1, and the end has - // id s->columns. So the end is drawn if this last column is included. - has_end = (c->right == s->columns); - // Computing number of grid columns to draw. - grid_columns = c->right - c->left + 1 - has_end; - - bopti_grid((const uint32_t *)grid, grid_columns, s->height, c); - - if(has_end) - { - end = layer + ((s->columns * s->height) << 2); - c->x += (grid_columns << 5); - - if((c->x & 31) + s->end_size <= 32) - bopti_end_nover(end, s->end_bytes, c); - else - bopti_end(end, s->end_bytes, c); - } -} - -/* - getStructure() - Determines the image size (large images have a somehow different - structure), the data pointer and a few dimensions inside the image. -*/ -void getStructure(image_t *img, structure_t *s) -{ - int column_count, end, end_bytes, layer; - - // Large images. - if(!img->width && !img->height) - { - s->width = img->data[0] >> 16; - s->height = img->data[0] & 0xffff; - s->data = (uint8_t *)img->data + 4; - - column_count = (s->width + 31) >> 5; - end = 0; - end_bytes = 0; - } - else - { - s->width = img->width; - s->height = img->height; - s->data = (uint8_t *)img->data; - - /* TODO This is the same as - column_count = (img->width + 15) >> 5; - end = (img->width & 0x0f); - end_bytes = (end + 7) >> 3; - */ - - column_count = img->width >> 5; - end = img->width & 31; - end_bytes = - !end ? 0 : - end <= 8 ? 1 : - end <= 16 ? 2 : - 4; - - if(end_bytes == 4) - { - column_count++; - end = 0; - end_bytes = 0; - } - } - - // The layer size must be rounded to a multiple of 4. - layer = s->height * ((column_count << 2) + end_bytes); - layer = (layer + 3) & ~3; - - s->columns = column_count; - s->end_bytes = end_bytes; - s->end_size = end; - s->layer_size = layer; -} diff --git a/src/bopti/dimage.c b/src/bopti/dimage.c deleted file mode 100644 index d32c09f..0000000 --- a/src/bopti/dimage.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include - -/* - dimage_part() - Draws a portion of an image, defined by its bounding rectangle. - Point (left, top) is included, but (left + width, top + height) is - excluded. -*/ -void dimage_part(int x, int y, image_t *img, int left, int top, int width, - int height) -{ - if(!img || img->magic != 0x01) return; - - structure_t s; - command_t command; - int actual_width, actual_height; - int format = img->format; - - if(format != format_mono && format != format_mono_alpha) return; - getStructure(img, &s); - if(width < 0) width = s.width; - if(height < 0) height = s.height; - - //--- - // Adjusting the bounding rectangle. - //--- - - // This is what happens when the bounding rectangle overflows from the - // image... - if(left < 0) left = 0; - if(top < 0) top = 0; - if(left + width > s.width) width = s.width - left; - if(top + height > s.height) height = s.height - top; - - if(x + width <= 0 || x > 127 || y + height <= 0 || y > 63 - || width <= 0 || height <= 0) - return; - - command.top = (y < 0) ? (top - y) : top; - actual_height = (y + height > 64) ? (64 - y) : height; - command.bottom = top + actual_height; - - command.left = ((x < 0) ? (left - x) : left) >> 5; - actual_width = (x + width > 128) ? (128 - x) : width; - command.right = (left + actual_width - 1) >> 5; - - command.op = bopti_op_mono; - - if(x >= 0) getMasks(x, x + actual_width - 1, command.masks); - else getMasks(0, actual_width + x - 1, command.masks); - - bopti_vram = display_getCurrentVRAM(); - - for(int i = 0; format; format >>= 1, i++) if(format & 1) - { - command.x = x - left; - command.y = y - top; - command.channel = (1 << i); - - bopti(s.data, &s, &command); - s.data += s.layer_size; - } -} - -/* - dimage() - Displays a monochrome image in the video ram. -*/ -void dimage(int x, int y, image_t *img) -{ - dimage_part(x, y, img, 0, 0, -1, -1); -} diff --git a/src/bopti/gimage.c b/src/bopti/gimage.c deleted file mode 100644 index 84dc241..0000000 --- a/src/bopti/gimage.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include - -/* - gimage_part() - Draws a portion of a gray image, defined by its bounding rectangle. - Point (left, top) is included, but (left + width, top + height) is - excluded. -*/ -void gimage_part(int x, int y, image_t *img, int left, int top, int width, - int height) -{ - if(!img || img->magic != 0x01) return; - - structure_t s; - command_t command; - int actual_width, actual_height; - int format = img->format; - - getStructure(img, &s); - if(width < 0) width = s.width; - if(height < 0) height = s.height; - - //--- - // Adjusting the bounding rectangle. - //--- - - // This is what happens when the bounding rectangle overflows from the - // image... - if(left < 0) left = 0; - if(top < 0) top = 0; - if(left + width > s.width) width = s.width - left; - if(top + height > s.height) height = s.height - top; - - if(x + width <= 0 || x > 127 || y + height <= 0 || y > 63 - || width <= 0 || height <= 0) - return; - - // command.bottom is excluded... - command.top = (y < 0) ? (top - y) : top; - actual_height = (y + height > 64) ? (64 - y) : height; - command.bottom = top + actual_height; - - // ... but command.right is included. Great. - command.left = ((x < 0) ? (left - x) : left) >> 5; - actual_width = (x + width > 128) ? (128 - x) : width; - command.right = (left + actual_width - 1) >> 5; - - command.op = bopti_op_gray; - - if(x >= 0) getMasks(x, x + actual_width - 1, command.masks); - else getMasks(0, actual_width + x - 1, command.masks); - - bopti_v1 = gray_lightVRAM(); - bopti_v2 = gray_darkVRAM(); - - for(int i = 0; format; format >>= 1, i++) if(format & 1) - { - command.x = x - left; - command.y = y - top; - command.channel = (1 << i); - - bopti(s.data, &s, &command); - s.data += s.layer_size; - } -} - -/* - gimage() - Displays a gray image in the video ram. -*/ -void gimage(int x, int y, image_t *img) -{ - gimage_part(x, y, img, 0, 0, -1, -1); -} diff --git a/src/clock/clock.c b/src/clock/clock.c deleted file mode 100644 index 8084c4d..0000000 --- a/src/clock/clock.c +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static clock_config_t conf = { - .FLL = -1, .PLL = -1, - .Bphi_div1 = -1, .Iphi_div1 = -1, .Pphi_div1 = -1, - .CKIO_f = -1, - .Bphi_f = -1, .Iphi_f = -1, .Pphi_f = -1 -}; - -/* - clock_setting() - Returns the P_phi / 4 timer setting that will last for the given time. - Several units can be used. Be aware that the result is approximate, and - very high frequencies or very short delays will yield important errors. -*/ -uint32_t clock_setting(int duration, clock_unit_t unit) -{ - if(conf.Pphi_f <= 0) return 0xffffffff; - uint64_t f = conf.Pphi_f >> 2; - uint64_t result; - - switch(unit) - { - case clock_us: - result = (duration * f) / 1000000; - break; - case clock_ms: - result = (duration * f) / 1000; - break; - case clock_s: - result = (duration * f); - break; - - case clock_Hz: - result = f / duration; - break; - case clock_kHz: - result = f / (duration * 1000); - break; - case clock_MHz: - result = f / (duration * 1000000); - break; - - default: - return -1; - } - - return (result > 0xffffffff) ? (0xffffffff) : (result); -} - -/* - clock_config() - Returns a copy of the clock configuration. -*/ -clock_config_t clock_config(void) -{ - return conf; -} - -/* - sleep() - Sleeps until an interrupt is accepted. -*/ -void sleep(void) -{ - __asm__( - "sleep" - ); -} - -static void sleep_callback(void *arg) -{ - int *flag = arg; - *flag = 1; -} - -/* - sleep_ms() - Sleeps for the given number of milliseconds using a virtual timer. -*/ -void sleep_ms(int ms_delay) -{ - volatile int sleep_done = 0; - - timer_t *timer = timer_create(ms_delay, 1); - timer_attach(timer, sleep_callback, (void *)&sleep_done); - timer_start(timer); - - while(!sleep_done) sleep(); -} - -/* - sleep_us() - Sleeps for the given number of microseconds using the hardware timer - timer_user. -*/ -void sleep_us(int us_delay) -{ - volatile int sleep_done = 0; - const uint32_t constant = clock_setting(us_delay, clock_us); - - timer_t *timer = htimer_setup(timer_user, constant, timer_Po_4, 1); - timer_attach(timer, sleep_callback, (void *)&sleep_done); - timer_start(timer); - - while(!sleep_done) sleep(); -} - - - -//--- -// Clock frequency measurements -- Public API. -//--- - -// Indicates whether the measurements are finished. -static volatile int clock_measure_done = 0; -// Once again SH7705 and SH7305 need different methods... -static timer_t *htimer_7705 = NULL; -static int cb_id_7705 = -1; -static void clock_measure_7705(void); -static void clock_compute_7305(void); - -/* - clock_measure() - Begins the frequency measurements. The measurements will end - automatically. While doing measurements, do not use the RTC interrupt - or the user timer. - Call clock_measure_end() to wait until the measurements are finished. - It is possible to execute code during the measurements, so that less - time is spent. -*/ -void clock_measure(void) -{ - // On SH7705 we cannot have the value of CKIO simply, so we measure - // P_phi using a timer/RTC combination, and we deduce CKIO. - if(isSH3()) - { - htimer_7705 = htimer_setup(timer_user, 0xffffffff, timer_Po_4, - 1); - cb_id_7705 = rtc_cb_add(rtc_freq_256Hz, clock_measure_7705, 0); - } - - // On SH7305, assuming clock mode 3, we can compute the clock - // frequencies because we know that RTC_CLK oscillates at 32768 Hz. - else - { - clock_compute_7305(); - clock_measure_done = 1; - } -} - -/* - clock_measure_end() - Waits until the measurements are finished. This may be immediate. -*/ -void clock_measure_end(void) -{ - while(!clock_measure_done) sleep(); -} - -//--- -// Clock frequency measurements -- SH7305. -//--- - -/* - clock_compute_7305() - Computes the clock frequencies according to the CPG parameters. -*/ -static void clock_compute_7305(void) -{ - volatile unsigned int *FRQCRA = (void *)0xa4150000; - volatile unsigned int *PLLCR = (void *)0xa4150024; - volatile unsigned int *FLLFRQ = (void *)0xa4150050; - - // Surely the documentation of SH7724 does not meet the specification - // of SH7305 for the PLL setting, because the register accepts other - // values than the ones specified for SH7724. The relation given by - // Sentaro21 (thanks again!) yields good results. - int pll = (*FRQCRA >> 24) & 0x3f; // Raw setting - pll = pll + 1; // Resulting multiplier - conf.PLL = pll; - - // This one is simpler. The FLL ratio is actually the setting value. - int fll = *FLLFRQ & 0x7ff; // Raw setting = multiplier - if(*FLLFRQ & (1 << 14)) fll >>= 1; // Halve-output flag - conf.FLL = fll; - - // The divider1 ratios are NOT those of SH7724. The relation between - // the values below and the divider ratios is given by Sentaro21 - // (thanks to him!) and satisfies ratio = 1 / (2 ** (setting + 1)). - int div1_bphi = (*FRQCRA >> 8) & 0xf; - int div1_iphi = (*FRQCRA >> 20) & 0xf; - int div1_pphi = (*FRQCRA ) & 0xf; - - conf.Bphi_div1 = 1 << (div1_bphi + 1); - conf.Iphi_div1 = 1 << (div1_iphi + 1); - conf.Pphi_div1 = 1 << (div1_pphi + 1); - - // Computing the frequency of the signal, which is input to divider 1. - int base = 32768; - if(*PLLCR & (1 << 12)) base *= fll; - if(*PLLCR & (1 << 14)) base *= pll; - - conf.RTCCLK_f = 32768; - conf.Bphi_f = base >> (div1_bphi + 1); - conf.Iphi_f = base >> (div1_iphi + 1); - conf.Pphi_f = base >> (div1_pphi + 1); -} - -//--- -// Clock frequency measurements -- SH7705. -//--- - -/* - clock_measure_7705_finalize() - Given the number of P_phi / 4 timer ticks elapsed between two RTC - 256 Hz interrupts, determines the clock configuration. -*/ -static void clock_measure_7705_finalize(uint32_t elapsed) -{ - volatile unsigned int *FRQCR = (void *)0xffffff80; - - conf.Pphi_f = elapsed * 4 * 256; - if(conf.Pphi_f <= 0) return; - - conf.PLL1 = ((*FRQCR >> 8) & 0x03) + 1; - conf.PLL2 = -1; - - conf.Bphi_div1 = 0; - conf.Iphi_div1 = ((*FRQCR >> 4) & 0x03) + 1; - conf.Pphi_div1 = ((*FRQCR ) & 0x03) + 1; - - conf.CKIO_f = (conf.Pphi_f * conf.Pphi_div1) / conf.PLL1; - conf.Bphi_f = conf.CKIO_f; - conf.Iphi_f = (conf.CKIO_f * conf.PLL1) / conf.Iphi_div1; -} - -/* - clock_measure_7705_callback() - Starts measurements. Measurements will end automatically. Do not use - RTC interrupt or the user timer will doing measurements. - Call clock_measure_end() when you need to use those, to ensure - measurements are finished. -*/ -static void clock_measure_7705_callback(void) -{ - timer_stop(htimer_7705); - rtc_cb_end(cb_id_7705); - - uint32_t elapsed = 0xffffffff - TMU.timers[timer_user]->TCNT; - clock_measure_7705_finalize(elapsed); - clock_measure_done = 1; -} - -/* - clock_measure_7705() - Programs the clock measurements. We need to have the user timer and the - RTC synchronized for this operation, so we wait for an RTC interrupt - and we prepare the timer beforehand to avoid losing processor time in - configuring the registers. -*/ -static void clock_measure_7705(void) -{ - timer_start(htimer_7705); - rtc_cb_edit(cb_id_7705, rtc_freq_256Hz, clock_measure_7705_callback); -} diff --git a/src/core/exceptions.c b/src/core/exceptions.c deleted file mode 100644 index ad2ac4a..0000000 --- a/src/core/exceptions.c +++ /dev/null @@ -1,172 +0,0 @@ -#include -#include -#include - -//--- -// On-screen error messages -//--- - -#define print(x, y, str) dtext(6 * (x) - 5, 8 * (y) - 7, str) - -static void print_hex(int x, int y, uint32_t n, int digits) -{ - #define hexdigit(n) ((n) + '0' + 39 * ((n) > 9)) - - char str[9]; - if(digits >= 8) digits = 8; - str[digits] = 0; - - while(digits) - { - str[digits - 1] = hexdigit(n & 0xf); - n >>= 4; - digits--; - } - - print(x, y, str); - - #undef hexdigit -} - -static void show_error(const char *name, uint32_t *access_mode, uint32_t *tea, - uint32_t *opcode) -{ - uint32_t *vram = display_getCurrentVRAM(); - uint32_t spc, ssr; - __asm__("stc spc, %0" : "=r"(spc)); - __asm__("stc ssr, %0" : "=r"(ssr)); - - dclear(); - text_configure(NULL, color_black); - - print(3, 1, "EXCEPTION RAISED!"); - for(int i = 0; i < 36; i++) vram[i] = ~vram[i]; - print(1 + ((21 - strlen(name)) >> 1), 2, name); - - print(4, 4, "PC"); - print_hex(7, 4, spc, 8); - print(4, 5, "SR"); - print_hex(7, 5, ssr, 8); - - int y = 6; - if(access_mode) - { - print(2, y, "Type"); - print(7, y++, *access_mode == 1 ? "Code/Data read" : - "Data write"); - } - if(tea) - { - print(3, y, "TEA"); - print_hex(7, y++, *tea, 8); - } - if(opcode) - { - print(2, y, "Code"); - print_hex(7, y++, *opcode, 4); - } - - dupdate(); - while(1); -} - -#undef print - - - -//--- -// Exception handlers -//--- - -#pragma GCC diagnostic ignored "-Wunused-parameter" - -/* - exch_address_error() - CPU address error, e.g. alignment issues. -*/ -void exch_address_error(uint32_t pc, uint32_t tea, uint32_t access) -{ - show_error("Address error", &access, &tea, NULL); -} - -/* - exch_tlb_protection_violation() - You don't have the right to access this address. -*/ -void exch_tlb_protection_violation(uint32_t pc, uint32_t tea, uint32_t access) -{ - show_error("TLB protection", &access, &tea, NULL); -} - -/* - exch_tlb_invalid() - The translation info for this address is marked as invalid. -*/ -void exch_tlb_invalid(uint32_t pc, uint32_t tea, uint32_t access) -{ - show_error("TLB invalid", &access, &tea, NULL); -} - -/* - exch_illegal_instruction() - What's this opcode anyway? -*/ -void exch_illegal_instruction(uint32_t pc, uint32_t opcode) -{ - show_error("Illegal instruction", NULL, NULL, &opcode); -} - -/* - exch_illegal_slot() - You can't execute this in a delay slot. -*/ -void exch_illegal_slot(uint32_t pc, uint32_t opcode) -{ - show_error("Illegal slot", NULL, NULL, &opcode); -} - -/* - exch_user_break() - One of the user break conditions you requested was fulfilled. -*/ -void exch_user_break(void) -{ - show_error("User break", NULL, NULL, NULL); -} - -/* - exch_initial_page_write() - You can't write to this memory page, it's too early. -*/ -void exch_initial_page_write(void) -{ - show_error("Initial page write", NULL, NULL, NULL); -} - -/* - exch_trap() - You asked for it. -*/ -void exch_trap(uint32_t pc, uint32_t trap) -{ -} - -/* - exch_dma_address() - The DMAC is accessing badly-aligned addresses. -*/ -void exch_dma_address(void) -{ - show_error("DMA address error", NULL, NULL, NULL); -} - -/* - exch_tlb_miss() - This virtual address points nowhere. -*/ -void exch_tlb_miss(uint32_t pc, uint32_t tea, uint32_t access) -{ - show_error("TLB miss", &access, &tea, NULL); -} - -#pragma GCC diagnostic pop diff --git a/src/core/gint.c b/src/core/gint.c deleted file mode 100644 index f213dcf..0000000 --- a/src/core/gint.c +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include -#include -#include - -// Referencing the interrupt handlers to force ld to link them in (there should -// be a better way of achieving this, but I can't seem to find it). -__attribute__((used)) static void (*_exc)(void) = &gint_exc; -__attribute__((used)) static void (*_tlb)(void) = &gint_tlb; -__attribute__((used)) static void (*_int)(void) = &gint_int; - - - -//--- -// Exception and interrupt handlers -//--- - -gint_interrupt_handler_t gint_handlers[] = { - - //--- - // Resets and non-events - //--- - - { NULL, NULL, 0, { 0x00, 0x00, 0x00 } }, - - //--- - // General exceptions - //--- - - // Address error. - { NULL, exch_address_error, 0, - { arg_pc, arg_tea, arg_subtype } }, - // TLB protection violation. - { NULL, exch_tlb_protection_violation, 0, - { arg_pc, arg_tea, arg_subtype } }, - // TLB Invalid (SH7705 only). - { NULL, exch_tlb_invalid, 0, - { arg_pc, arg_tea, arg_subtype } }, - // Illegal instruction. - { NULL, exch_illegal_instruction, 0, - { arg_pc, arg_opcode, 0x00 } }, - // Illegal opcode. - { NULL, exch_illegal_slot, 0, - { arg_pc, arg_opcode, 0x00 } }, - // User break. - { NULL, exch_user_break, 0, - { 0x00, 0x00, 0x00 } }, - // Initial page write. - { NULL, exch_initial_page_write, 0, - { 0x00, 0x00, 0x00 } }, - // Unconditional trap. - { NULL, exch_trap, 0, - { arg_pc, arg_trap, 0x00 } }, - // DMA address error. - { NULL, exch_dma_address, 0, - { 0x00, 0x00, 0x00 } }, - - //--- - // TLB misses - //--- - - { NULL, exch_tlb_miss, - 0, { arg_pc, arg_tea, arg_subtype } }, - - //--- - // Interrupt requests - //--- - - // Non-Maskable Interrupt. - { NULL, NULL, 0, - { 0x00, 0x00, 0x00 } }, - // Timer underflow. - { NULL, inth_timer_underflow, 12, - { arg_subtype, 0x00, 0x00 } }, - // Timer channel 2 input capture (SH7705 only) - { NULL, NULL, 0, - { arg_timer_capt, 0x00, 0x00 } }, - // Real-time clock alarm interrupt. - { NULL, NULL, 0, - { 0x00, 0x00, 0x00 } }, - // Real-time clock periodic interrupt. - { NULL, inth_rtc_periodic, 10, - { 0x00, 0x00, 0x00 } }, - // Real-time clock carry interrupt. - { NULL, NULL, 0, - { 0x00, 0x00, 0x00 } }, -}; - -/* - gint_invoke() - Invokes an interrupt or exception handler, given its type and subtype. -*/ -void gint_invoke(uint8_t type, uint8_t subtype) -{ - if(type >= exc_type_max || !gint_handlers[type].function) return; - - volatile uint32_t *tea, *tra, *tcpr_2; - uint32_t args[3]; - uint16_t *pc; - - // Getting some initial information to work with. - __asm__("stc spc, %0" : "=r"(pc)); - tea = gint_reg(register_tea); - tra = gint_reg(register_tra); - tcpr_2 = (void *)0xfffffeb8; /* SH7705 only */ - - // Building up the argument list. - for(int i = 0; i < 3; i++) switch(gint_handlers[type].args[i]) - { - case arg_none: args[i] = 0; break; - case arg_subtype: args[i] = subtype; break; - case arg_pc: args[i] = (uint32_t)pc; break; - case arg_opcode: args[i] = *pc; break; - case arg_tea: args[i] = *tea; break; - case arg_trap: args[i] = *tra >> 2; break; - case arg_timer_capt: args[i] = *tcpr_2; break; - } - - // Calling the function with the required amount of arguments. - if(gint_handlers[type].args[2]) - { - void (*handler)(uint32_t, uint32_t, uint32_t); - handler = gint_handlers[type].function; - (*handler)(args[0], args[1], args[2]); - } - else if(gint_handlers[type].args[1]) - { - void (*handler)(uint32_t, uint32_t); - handler = gint_handlers[type].function; - (*handler)(args[0], args[1]); - } - else if(gint_handlers[type].args[0]) - { - void (*handler)(uint32_t); - handler = gint_handlers[type].function; - (*handler)(args[0]); - } - else (*(void (*)(void))gint_handlers[type].function)(); -} - -/* - gint_install() - Installs an exception or interrupt handler for one of gint's recognized - interrupts. -*/ -void gint_install(gint_interrupt_type_t type, void *function) -{ - if((unsigned)type >= exc_type_max) return; - gint_handlers[type].function = function; -} - -/* - gint_uninstall() - Un-installs the exception or interrupt handler that was used for the - given interrupt, falling back to gint's default handler. -*/ -void gint_uninstall(gint_interrupt_type_t type) -{ - if((unsigned)type >= exc_type_max) return; - gint_handlers[type].function = gint_handlers[type].default_function; -} - - - -//--- -// Register access -//--- - -/* - gint_reg() - Returns the address of a common register. All common registers exist - on both platforms but they may hold different values for the same - information. -*/ -volatile void *gint_reg(gint_register_t reg) -{ - return isSH3() ? gint_reg_7705(reg) : gint_reg_7305(reg); -} diff --git a/src/core/gint_sh7305.c b/src/core/gint_sh7305.c deleted file mode 100644 index 9c54118..0000000 --- a/src/core/gint_sh7305.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include <7305.h> -#include - -/* - gint_reg() - Returns the address of a common register. All common registers exist - on both platforms but they may hold different values for the same - information (f.i. EXPEVT may not return the same value for a given - exception on both 7705 and 7305). -*/ -volatile void *gint_reg_7305(gint_register_t reg) -{ - switch(reg) - { - case register_tea: return (void *)0xff00000c; - case register_mmucr: return (void *)0xff000010; - case register_tra: return (void *)0xff000020; - case register_expevt: return (void *)0xff000024; - case register_intevt: return (void *)0xff000028; - default: return NULL; - } -} - - - -//--- -// Register saves, setup, interrupt locks, register restoration. -//--- - -void gint_save_7305(environment_7305_t *e) -{ - // Saving interrupt priorities. - e->IPR[0] = INTX.IPRA.WORD; - e->IPR[1] = INTX.IPRB.WORD; - e->IPR[2] = INTX.IPRC.WORD; - e->IPR[3] = INTX.IPRD.WORD; - e->IPR[4] = INTX.IPRE.WORD; - e->IPR[5] = INTX.IPRF.WORD; - e->IPR[6] = INTX.IPRG.WORD; - e->IPR[7] = INTX.IPRH.WORD; - e->IPR[8] = INTX.IPRI.WORD; - e->IPR[9] = INTX.IPRJ.WORD; - e->IPR[10] = INTX.IPRK.WORD; - e->IPR[11] = INTX.IPRL.WORD; - - // Saving RTC registers. - e->RCR1 = RTC.RCR1->byte; - e->RCR2 = RTC.RCR2->byte; - - // Saving TMU registers. - e->TMU0 = *(TMU.timers[0]); - e->TMU1 = *(TMU.timers[1]); - e->TMU2 = *(TMU.timers[2]); - e->TSTR = TMU.TSTR->byte; - - // Saving port data used to access the keyboard. - e->PMCR = *((volatile uint16_t *)0xa4050116); - e->PMDR = *((volatile uint8_t *)0xa4050136); - e->PNCR = *((volatile uint16_t *)0xa4050118); - e->PNDR = *((volatile uint8_t *)0xa4050138); - e->PZCR = *((volatile uint16_t *)0xa405014c); - e->PZDR = *((volatile uint8_t *)0xa405016c); - e->key = *((volatile uint8_t *)0xa40501c6); -} - -void gint_lock_and_setup_7305(void) -{ - // Disabling everything by default to avoid freezing on non-handled - // interrupts. - INTX.IPRA.WORD = 0x0000; - INTX.IPRB.WORD = 0x0000; - INTX.IPRC.WORD = 0x0000; - INTX.IPRD.WORD = 0x0000; - INTX.IPRE.WORD = 0x0000; - INTX.IPRF.WORD = 0x0000; - INTX.IPRG.WORD = 0x0000; - INTX.IPRH.WORD = 0x0000; - INTX.IPRI.WORD = 0x0000; - INTX.IPRJ.WORD = 0x0000; - INTX.IPRK.WORD = 0x0000; - INTX.IPRL.WORD = 0x0000; - - // Allowing RTC and timer to schedule automatic tasks such as keyboard - // analysis. - INTX.IPRK._RTC = 10; - INTX.IPRA.TMU0_0 = 12; - INTX.IPRA.TMU0_1 = 12; - INTX.IPRA.TMU0_2 = 12; - - // Don't enable the RTC interrupt by default. - RTC.RCR2->byte = 0x09; -} - -void gint_restore_and_unlock_7305(environment_7305_t *e) -{ - // Restoring the interrupt priorities. - INTX.IPRA.WORD = e->IPR[0]; - INTX.IPRB.WORD = e->IPR[1]; - INTX.IPRC.WORD = e->IPR[2]; - INTX.IPRD.WORD = e->IPR[3]; - INTX.IPRE.WORD = e->IPR[4]; - INTX.IPRF.WORD = e->IPR[5]; - INTX.IPRG.WORD = e->IPR[6]; - INTX.IPRH.WORD = e->IPR[7]; - INTX.IPRI.WORD = e->IPR[8]; - INTX.IPRJ.WORD = e->IPR[9]; - INTX.IPRK.WORD = e->IPR[10]; - INTX.IPRL.WORD = e->IPR[11]; - - // Restoring RTC registers. - RTC.RCR1->byte = e->RCR1; - RTC.RCR2->byte = e->RCR2; - - // Restoring TMU registers. - *(TMU.timers[0]) = e->TMU0; - *(TMU.timers[1]) = e->TMU1; - *(TMU.timers[2]) = e->TMU2; - TMU.TSTR->byte = e->TSTR; - - // Restoring keyboard-related I/O port registers. However the backlight - // pin is in PNDR and we would like the backlight to persist when we - // leave the application, so we just keep this bit. - *((volatile uint16_t *)0xa4050116) = e->PMCR; - *((volatile uint8_t *)0xa4050136) = e->PMDR; - *((volatile uint16_t *)0xa4050118) = e->PNCR; - *((volatile uint8_t *)0xa4050138) &= 0x10; - *((volatile uint8_t *)0xa4050138) |= (e->PNDR & ~0x10); - *((volatile uint16_t *)0xa405014c) = e->PZCR; - *((volatile uint8_t *)0xa405016c) = e->PZDR; - *((volatile uint8_t *)0xa40501c6) = e->key; -} diff --git a/src/core/gint_sh7705.c b/src/core/gint_sh7705.c deleted file mode 100644 index 80df397..0000000 --- a/src/core/gint_sh7705.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* - gint_reg() - Returns the address of a common register. All common registers exist - on both platforms but they may hold different values for the same - information (f.i. EXPEVT may not return the same value for a given - exception on both 7705 and 7305). -*/ -volatile void *gint_reg_7705(gint_register_t reg) -{ - switch(reg) - { - case register_intevt: return (void *)0xa4000000; - case register_tra: return (void *)0xffffffd0; - case register_expevt: return (void *)0xffffffd4; - case register_mmucr: return (void *)0xfffffff4; - case register_tea: return (void *)0xfffffffc; - default: return NULL; - } -} - - - -//--- -// Register saves, setup, interrupt locks, register restoration. -//--- - -void gint_save_7705(environment_7705_t *e) -{ - mod_intc_7705_t *intc = &INTC._7705; - mod_intc_ipc_7705_t *ipc = &intc->iprs; - - // Saving the interrupt masks from registers IPRA to IPRH. - e->IPR[0] = ipc->IPRA->word; - e->IPR[1] = ipc->IPRB->word; - e->IPR[2] = ipc->IPRC->word; - e->IPR[3] = ipc->IPRD->word; - e->IPR[4] = ipc->IPRE->word; - e->IPR[5] = ipc->IPRF->word; - e->IPR[6] = ipc->IPRG->word; - e->IPR[7] = ipc->IPRH->word; - - // Saving RTC registers. - e->RCR1 = RTC.RCR1->byte; - e->RCR2 = RTC.RCR2->byte; - - // Saving TMU registers. - e->TMU0 = *(TMU.timers[0]); - e->TMU1 = *(TMU.timers[1]); - e->TMU2 = *(TMU.timers[2]); - e->TSTR = TMU.TSTR->byte; - -/* // Saving port data used to access the keyboard. - e->PACR = PFC.PACR.WORD; - e->PADR = PA.DR.BYTE; - e->PBCR = PFC.PBCR.WORD; - e->PBDR = PB.DR.BYTE; - e->PMCR = PFC.PMCR.WORD; - e->PMDR = PM.DR.BYTE; -*/ -} - -void gint_lock_and_setup_7705(void) -{ - mod_intc_7705_t *intc = &INTC._7705; - mod_intc_ipc_7705_t *ipc = &intc->iprs; - - // Disabling everything by default to avoid receiving an interrupt that - // the handler doesn't handle, which would cause the user program to - // freeze. - ipc->IPRA->word = 0x0000; - ipc->IPRB->word = 0x0000; - ipc->IPRC->word = 0x0000; - ipc->IPRD->word = 0x0000; - ipc->IPRE->word = 0x0000; - ipc->IPRF->word = 0x0000; - ipc->IPRG->word = 0x0000; - ipc->IPRH->word = 0x0000; - - // Allowing RTC and timer (which handles keyboard and a whole bunch of - // other things). - ipc->IPRA->RTC = 10; - ipc->IPRA->TMU0 = 12; - ipc->IPRA->TMU1 = 12; - ipc->IPRA->TMU2 = 12; - - // Don't enable RTC periodic signals by default. - RTC.RCR2->byte = 0x09; -} - -void gint_restore_and_unlock_7705(environment_7705_t *e) -{ - mod_intc_7705_t *intc = &INTC._7705; - mod_intc_ipc_7705_t *ipc = &intc->iprs; - - // Restoring the saved states. - ipc->IPRA->word = e->IPR[0]; - ipc->IPRB->word = e->IPR[1]; - ipc->IPRC->word = e->IPR[2]; - ipc->IPRD->word = e->IPR[3]; - ipc->IPRE->word = e->IPR[4]; - ipc->IPRF->word = e->IPR[5]; - ipc->IPRG->word = e->IPR[6]; - ipc->IPRH->word = e->IPR[7]; - - // Restoring RTC registers. - RTC.RCR1->byte = e->RCR1; - RTC.RCR2->byte = e->RCR2; - - // Restoring TMU registers. - *(TMU.timers[0]) = e->TMU0; - *(TMU.timers[1]) = e->TMU1; - *(TMU.timers[2]) = e->TMU2; - TMU.TSTR->byte = e->TSTR; - -/* // Restoring keyboard-related I/O port registers. - PFC.PACR.WORD = e->PACR; - PA.DR.BYTE = e->PADR; - PFC.PBCR.WORD = e->PBCR; - PB.DR.BYTE = e->PBDR; - PFC.PMCR.WORD = e->PMCR; - PM.DR.BYTE = e->PMDR; -*/ -} diff --git a/src/core/gint_vbr.s b/src/core/gint_vbr.s deleted file mode 100644 index 067aadb..0000000 --- a/src/core/gint_vbr.s +++ /dev/null @@ -1,66 +0,0 @@ -/* - gint_vbr - - Some of the work, especially related to setting and un-setting the vbr - address needs to be done in assembler. -*/ - - .global _gint_getvbr - .global _gint_setvbr - - - -/* - gint_getvbr() - Returns the current vbr address. -*/ -_gint_getvbr: - rts - stc vbr, r0 - - - -/* - gint_setvbr() - - This is quite the hard part when modifying the vbr. We need to set - immediately the interrupt priorities of our own handler, or restore - the ones used by the system; otherwise we may receive interrupts - requests that the new handler doesn't handle, which will cause the - whole program to freeze. - - Therefore, we must set vbr *and* change interrupt priorities while - having disabled all the interrupts in the status register. That's why - this function takes as parameter the priority management function. -*/ -_gint_setvbr: - sts.l pr, @-r15 - - /* Blocking all interrupts. */ - mov.l sr_block, r0 - stc sr, r3 - or r0, r3 - ldc r3, sr - - /* Setting the vbr address. */ - ldc r4, vbr - - /* Calling the priority manager. */ - jsr @r5 - nop - - /* Enabling interrupts again. */ - mov.l sr_block, r0 - not r0, r0 - stc sr, r3 - and r0, r3 - ldc r3, sr - - lds.l @r15+, pr - rts - nop - - .align 4 - -sr_block: - .long (1 << 28) diff --git a/src/core/init_quit.c b/src/core/init_quit.c deleted file mode 100644 index 4d92d5c..0000000 --- a/src/core/init_quit.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include -#include - -gint_info_t gint; -static environment_t env; - -//--- -// Initialization routines -//--- - -/* - gint_init() - Initializes gint. Loads the interrupt handler into the memory and sets - the new vbr address. -*/ -static void setup(void) -{ - isSH3() ? gint_lock_and_setup_7705() - : gint_lock_and_setup_7305(); -} -void gint_init(mpu_t mpu) -{ - // Setting the MPU type. I don't like const-casting but this is still - // better than allowing the user to change the variable by mistake. - *((mpu_t *)&MPU_CURRENT) = mpu; - // Loading the register addresses of the current platform. - mod_init(); - - // Linker script symbols -- gint. - extern uint32_t - gint_vbr, - gint_data, - bgint, egint; - - uint32_t *ptr = &bgint; - uint32_t *src = &gint_data; - - // Loading the interrupt handler into the memory. - while(ptr < &egint) *ptr++ = *src++; - - isSH3() ? gint_save_7705(&env.env_7705) - : gint_save_7305(&env.env_7305); - - // Installing gint's default exception/interrupt handlers. - for(int i = 0; i < exc_type_max; i++) - { - gint_handlers[i].function = gint_handlers[i].default_function; - } - - // Filling the information structure for the user. - gint.vbr = gint_getvbr; - gint.system_vbr = gint_getvbr(); - gint.gint_vbr = (uint32_t)&gint_vbr; - - // Setting the VBR! - gint_setvbr(gint.gint_vbr, setup); -} - - - -//--- -// Context restoration routines -//--- - -/* - gint_quit() - Stops gint. Restores the system's configuration and vbr address. -*/ -static void stop(void) -{ - isSH3() ? gint_restore_and_unlock_7705(&env.env_7705) - : gint_restore_and_unlock_7305(&env.env_7305); -} -void gint_quit(void) -{ - // Restoring the system's VBR. - gint_setvbr(gint.system_vbr, stop); -} - - - -//--- -// System-switch technique -//--- - -#include -#include - -/* - __system_menu() - Updates the system's vram and triggers the calculator's main menu. -*/ -void __system_menu(void *vram); - -// Stores gint's configuration while the user visits the main menu. -static environment_t switch_env; - -/* - gint_switch() - Temporarily returns to the system's main menu. -*/ -static void restore(void) -{ - isSH3() ? gint_restore_and_unlock_7705(&switch_env.env_7705) - : gint_restore_and_unlock_7305(&switch_env.env_7305); -} -void gint_switch(void) -{ - isSH3() ? gint_save_7705(&switch_env.env_7705) - : gint_save_7305(&switch_env.env_7305); - - gint_setvbr(gint.system_vbr, stop); - - // When returning to the add-in from the menu, the system displays the - // add-in's video ram again, but it's often blank. We thus need to copy - // the contents of the gint video ram to the system's. - void *vram = gray_runs() - ? gray_currentVRAM() - : display_getCurrentVRAM(); - - // Use system calls to put KEY_MENU in the key buffer and invoke - // GetKeyWait(), triggering the main menu. - __system_menu(vram); - - // If the user came back, restore the gint working environment. - gint_setvbr(gint.gint_vbr, restore); -} diff --git a/src/core/interrupt_maps_7305.c b/src/core/interrupt_maps_7305.c deleted file mode 100644 index bf76fa9..0000000 --- a/src/core/interrupt_maps_7305.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include - -//--- -// Mapping hardware interrupts info to gint interrupts -- 7305 interrupts -//--- - -#define NO_EVENT (gint_interrupt_map_t){ .type = 0, .subtype = 0 } - -static gint_interrupt_map_t map0[16] = { - { exc_poweron_reset, 0 }, { exc_manual_reset, 0 }, - { exc_tlb_miss, 1 }, { exc_tlb_miss, 2 }, - { exc_initial_page_write, 0 }, { exc_tlb_protection_violation, 1 }, - { exc_tlb_protection_violation, 2 }, { exc_address_error, 1 }, -}; - -static gint_interrupt_map_t map1[16] = { - { exc_address_error, 2 }, NO_EVENT, /* FPU exception */ - { exc_tlb_multihit, 0 }, { exc_trap, 0 }, - { exc_illegal_instruction, 0 }, { exc_illegal_slot, 0 }, - { int_nmi, 0 }, { exc_user_break, 0 }, -}; - -static gint_interrupt_map_t map4[16] = { - { int_timer_underflow, 0 }, { int_timer_underflow, 1 }, - { int_timer_underflow, 2 }, NO_EVENT, - NO_EVENT, NO_EVENT, - NO_EVENT, NO_EVENT, /* SDHI1 [SDHII0] */ -}; - -static gint_interrupt_map_t mapa[16] = { - NO_EVENT, NO_EVENT, /* USB0 [USI0] */ - NO_EVENT, /* USB0 [USI1] */ NO_EVENT, - { int_rtc_alarm, 0 }, { int_rtc_periodic, 0 }, - { int_rtc_carry, 0 }, NO_EVENT, -}; - -static gint_interrupt_map_t *map[16] = { - map0, map1, NULL, NULL, map4, NULL, NULL, NULL, - NULL, NULL, mapa, NULL, NULL, NULL, NULL, NULL, -}; - -/* - gint_map() - Maps an event code to an exception/interrupt type and subtype. -*/ -gint_interrupt_map_t gint_map_7305(uint32_t event_code) -{ - int ctgy = event_code >> 8; - int event = (event_code & 0xff) >> 5; - - return map[ctgy] ? map[ctgy][event] : NO_EVENT; -} diff --git a/src/core/interrupt_maps_7705.c b/src/core/interrupt_maps_7705.c deleted file mode 100644 index d471d0a..0000000 --- a/src/core/interrupt_maps_7705.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include - -//--- -// Mapping hardware interrupt info to gint interrupts -- 7705 interrupts -//--- - -#define NO_EVENT (gint_interrupt_map_t){ .type = 0, .subtype = 0 } - -static gint_interrupt_map_t map0[16] = { - NO_EVENT, { exc_manual_reset, 0 }, - { exc_tlb_invalid, 1 }, { exc_tlb_invalid, 2 }, - { exc_initial_page_write, 0 }, { exc_tlb_protection_violation, 1 }, - { exc_tlb_protection_violation, 2 }, { exc_address_error, 1 }, -}; - -static gint_interrupt_map_t map1[16] = { - { exc_address_error, 2 }, NO_EVENT, - NO_EVENT, { exc_trap, 0 }, - { exc_illegal_instruction, 0 }, { exc_illegal_slot, 0 }, - { int_nmi, 0 }, { exc_user_break, 0 }, -}; - -static gint_interrupt_map_t map4[16] = { - { int_timer_underflow, 0 }, { int_timer_underflow, 1 }, - { int_timer_underflow, 2 }, { int_timer_input_capture, 0 }, - { int_rtc_alarm, 0 }, { int_rtc_periodic, 0 }, - { int_rtc_carry, 0 }, NO_EVENT, -}; - -static gint_interrupt_map_t *map[16] = { - map0, map1, NULL, NULL, map4, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -/* - gint_map() - Maps an event code and a VBR offset to an exception/interrupt type and - subtype. -*/ -gint_interrupt_map_t gint_map_7705(uint32_t event_code, uint32_t offset) -{ - // Handling TLB misses (only two events). - if(offset == 0x400) switch(event_code) - { - case 0x040: - return (gint_interrupt_map_t) { - .type = exc_tlb_miss, - .subtype = 1, - }; - case 0x060: - return (gint_interrupt_map_t) { - .type = exc_tlb_miss, - .subtype = 2, - }; - default: - return NO_EVENT; - } - - // Handling general exceptions and interrupts. - int ctgy = event_code >> 8; - int event = (event_code & 0xff) >> 5; - - return map[ctgy] ? map[ctgy][event] : NO_EVENT; -} diff --git a/src/core/interrupts.c b/src/core/interrupts.c deleted file mode 100644 index eff3d94..0000000 --- a/src/core/interrupts.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -/* - inth_timer_underflow() - Wake up, your timer has expired! -*/ -void inth_timer_underflow(uint32_t channel) -{ - timer_interrupt(channel); -} - -/* - inth_rtc_periodic() - Don't you forget to execute the periodic tasks. -*/ -void inth_rtc_periodic(void) -{ - rtc_periodic_interrupt(); -} diff --git a/src/core/modules.c b/src/core/modules.c deleted file mode 100644 index 9e5c429..0000000 --- a/src/core/modules.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include - -#include -#include - -//--- -// Structure information -// Here resides most of the platform-dependent register configuration. -// Module structures are arranged to mask as much as possible hardware -// differences to the user. When it becomes impossible to do so at -// compile-time, gint provides functions to ensure that the user does not -// confront to the hardware directly. -//--- - -mod_tmu_t TMU; -mod_rtc_t RTC; -mod_intc_t INTC; - - - -//--- -// Initializer -//--- - -static void mod_init_7705(void) -{ - INTC._7705.iprs.IPRA = (void *)0xfffffee2; - INTC._7705.iprs.IPRB = (void *)0xfffffee4; - INTC._7705.iprs.IPRC = (void *)0xa4000016; - INTC._7705.iprs.IPRD = (void *)0xa4000018; - INTC._7705.iprs.IPRE = (void *)0xa400001a; - INTC._7705.iprs.IPRF = (void *)0xa4080000; - INTC._7705.iprs.IPRG = (void *)0xa4080002; - INTC._7705.iprs.IPRH = (void *)0xa4080004; - - INTC._7705.ICR0 = (void *)0xfffffee0; - INTC._7705.ICR1 = (void *)0xa4000010; - INTC._7705.ICR2 = (void *)0xa4000012; - INTC._7705.PINTER = (void *)0xa4000014; - INTC._7705.IRR0 = (void *)0xa4000004; - INTC._7705.IRR1 = (void *)0xa4000006; - INTC._7705.IRR2 = (void *)0xa4000008; - - TMU.timers[0] = (void *)0xfffffe94; - TMU.timers[1] = (void *)0xfffffea0; - TMU.timers[2] = (void *)0xfffffeac; - TMU.TSTR = (void *)0xfffffe92; - TMU.TCPR2 = (void *)0xfffffeb8; - - RTC.RCR1 = (void *)0xfffffedc; - RTC.RCR2 = (void *)0xfffffede; - RTC.time = (void *)0xfffffec0; -} - -static void mod_init_7305(void) -{ - INTC._7305.ICR0 = (void *)0xa4140000; - INTC._7305.ICR1 = (void *)0xa414001c; - INTC._7305.INTPRI00 = (void *)0xa4140010; - INTC._7305.iprs = (void *)0xa4080000; - INTC._7305.INTMSK00 = (void *)0xa4140044; - INTC._7305.masks = (void *)0xa4080080; - INTC._7305.INTMSKCLR00 = (void *)0xa4140064; - INTC._7305.masks_clear = (void *)0xa40800c0; - INTC._7305.INTREQ00 = (void *)0xa4140024; - INTC._7305.USERIMASK = (void *)0xa4700000; - INTC._7305.NMIFCR = (void *)0xa41400c0; - - TMU.timers[0] = (void *)0xa4490008; - TMU.timers[1] = (void *)0xa4490014; - TMU.timers[2] = (void *)0xa4490020; - TMU.TSTR = (void *)0xa4490004; - TMU.TCPR2 = NULL; - - RTC.RCR1 = (void *)0xa413fedc; - RTC.RCR2 = (void *)0xa413fede; - RTC.time = (void *)0xa413fec0; -} - -/* - mod_init() - Initializes the module data to make register access cross-platform. The - MPU needs to have been detected or this function will yield wrong - results. -*/ -void mod_init(void) -{ - isSH3() ? mod_init_7705() : mod_init_7305(); -} diff --git a/src/core/mpu.c b/src/core/mpu.c deleted file mode 100644 index 73d0a46..0000000 --- a/src/core/mpu.c +++ /dev/null @@ -1,70 +0,0 @@ -//--- -// -// gint core module: mpu -// -// Determines which kind of MPU is running the program. -// -//--- - -#include -#include - -/* Located in gint's uninitialized bss section */ -__attribute__((section(".gint.bss"))) const mpu_t MPU_CURRENT; - -/* - getMPU() - - Returns the MPU identifier of the calculator. - Thanks to SimonLothar 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 getMPU(void) -{ - // Processor version register. - volatile uint32_t *pvr = (void *)0xff000030; - // Product version register. - volatile uint32_t *prr = (void *)0xff000044; - // Port L control register. - volatile uint16_t *plcr = (void *)0xa4000114; - // Saved value for PLCR. - uint16_t saved_plcr; - uint16_t tested_plcr; - - // Looking for SH-3-based MPUs by testing PLCR writing access. - saved_plcr = *plcr; - *plcr = 0xffff; - tested_plcr = *plcr; - *plcr = saved_plcr; - - // Checking whether we are working with an SH7337 or an SH7355. - if(tested_plcr == 0x00ff) return mpu_sh7337; - if(tested_plcr == 0x0fff) return mpu_sh7355; - - // Looking for SH-4-based MPUs by testing the version registers. This - // needs the three upper bytes of the processor version register to - // match 0x10300b : - if((*pvr & 0xffffff00) != 0x10300b00) return mpu_unknown; - - // Now that we have an SH-4-based MPU, checking whether it is SH7305 or - // SH7724, just for reference. - switch(*prr & 0xfffffff0) - { - case 0x00002c00: - return mpu_sh7305; - case 0x00002200: - return mpu_sh7724; - } - - // By default, the MPU is unknown. - return mpu_unknown; -} diff --git a/src/core/syscalls.s b/src/core/syscalls.s deleted file mode 100644 index 0ebf0d2..0000000 --- a/src/core/syscalls.s +++ /dev/null @@ -1,198 +0,0 @@ -/* - gint core module: syscalls - - System calls (and the like) used by the library. The library should - rely the least possible on the system, but sometimes using the syscalls - is nothing of a nuisance. - - For instance, using the malloc()-family syscalls is a bit annoying - because it "locks" many functionalities. On the other hand, getting the - SaveDisp() buffer addresses to store data here is not a problem since - such data can very easily be relocated to static RAM. -*/ - - /* Dynamic allocation */ - .global ___malloc - .global ___free - .global ___realloc - - /* OS version */ - .global ___get_os_version - - /* Return to menu */ - .global ___system_menu - - /* Storage memory filesystem */ - .global _BFile_Remove - .global _BFile_Create - .global _BFile_Open - .global _BFile_Close - .global _BFile_Write - .global _BFile_Read - - - -/* Dynamic memory allocation */ - -___malloc: - mov.l syscall_table, r2 - mov.l 1f, r0 - jmp @r2 - nop -1: .long 0xacd - -___free: - mov.l syscall_table, r2 - mov.l 1f, r0 - jmp @r2 - nop -1: .long 0xacc - -___realloc: - mov.l syscall_table, r2 - mov.l 1f, r0 - jmp @r2 - nop -1: .long 0xe6d - -/* OS version access */ - -___get_os_version: - mov.l syscall_table, r2 - mov.l 1f, r0 - jmp @r2 - nop -1: .long 0x02ee - -/* - __system_menu() - Brings one back to the system menu by putting KEY_MENU in the system's - key buffer and calling GetKeyWait(). Of course this needs to be - executed while under system control. -*/ -___system_menu: - sts.l pr, @-r15 - add #-4, r15 - - /* Copying gint's VRAM into the system's. */ - mov.l syscall_table, r1 - mov.l .syscall_vram, r0 - jsr @r1 - mov.l r4, @r15 /* gint video ram */ - mov r0, r4 - mov.l @r15, r5 - mov.w .vram_size, r6 - mov.l .memcpy, r1 - jsr @r1 - nop - - /* Putting the matrix code in the key buffer. */ - - mov r15, r4 - mov.w .matrix_menu, r2 - mov.w r2, @r4 - mov.l syscall_table, r1 - mov.l .syscall_putcode, r0 - jsr @r1 - nop - - /* Calling GetKeyWait() to display menu. */ - - mov r15, r4 /* column pointer */ - add #-4, r15 - mov r15, r5 /* row pointer */ - add #-4, r15 - mov r15, r1 /* keycode pointer */ - - mov #2, r6 /* type of waiting */ - mov #0, r7 /* timeout period */ - mov.l r1, @-r15 - mov #0, r2 /* allow return to menu */ - mov.l r2, @-r15 - - mov.l syscall_table, r1 - mov.l .syscall_getkeywait, r0 - jsr @r1 - nop - - /* If the program counter reaches this place, it means that the user - has come back to the program. Restore stack and leave. */ - - add #20, r15 - lds.l @r15+, pr - rts - nop - - .align 4 - -.syscall_getkeywait: - .long 0x0247 -.syscall_putcode: - .long 0x024f -.syscall_vram: - .long 0x0135 -.matrix_menu: - .word 0x0308 -.vram_size: - .word 1024 -.memcpy: - .long _memcpy - -/* BFile driver */ - - -# int BFile_Remove(const uint16_t *file) -_BFile_Remove: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - mov #0, r5 -1: .long 0x0439 - -# int BFile_Create(const uint16_t *file, enum { file = 1, folder = 5 }, -# int *size) -_BFile_Create: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - nop -1: .long 0x0434 - -# int BFile_Open(const uint16_t *file, int mode) -_BFile_Open: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - mov #0, r6 -1: .long 0x042c - -# int BFile_Close(int handle) -_BFile_Close: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - nop -1: .long 0x042d - -# int BFile_Write(int handle, const void *ram_buffer, int even_size) -_BFile_Write: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - nop -1: .long 0x0435 - -# int BFile_Read(int handle, void *ram_buffer, int size, int whence) -_BFile_Read: - mov.l 1f, r0 - mov.l syscall_table, r1 - jmp @r1 - nop -1: .long 0x0432 - - - - .align 4 - -syscall_table: - .long 0x80010070 diff --git a/src/core/vbr_space.c b/src/core/vbr_space.c deleted file mode 100644 index 2344854..0000000 --- a/src/core/vbr_space.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include - -// Compiler optimization of the interrupt handlers seems to cause crashes at -// some point. Some research showed that illegal slot exceptions were raised on -// rte; lds.l @r15+, mach, even though it's a legal slot. For now I just turn -// off optimization until I figure out where the true problem is. -#pragma GCC push_options -#pragma GCC optimize("O0") - -//--- -// VBR space -//--- - -#ifdef GINT_DIAGNOSTICS -static void register_interrupt(int offset) -{ - volatile gint_diagnostics_t *dg = gint_diagnostics(); - volatile uint32_t *expevt, *intevt, *tea; - uint32_t event_code, spc, ssr; - - // Getting the addresses of some registers. - expevt = gint_reg(register_expevt); - intevt = gint_reg(register_intevt); - tea = gint_reg(register_tea); - - // Adding an entry in the event history. - event_code = (offset == 0x600) ? (*intevt) : (*expevt); - size_t len = sizeof dg->except_vect; - dg->except_vect[dg->excepts++] = event_code >> 4; - if(dg->excepts >= len) dg->excepts -= len; - - // Updating some fields in the diagnostic record. - __asm__("stc spc, %0" : "=r"(spc)); - __asm__("stc ssr, %0" : "=r"(ssr)); - dg->spc = spc; - dg->ssr = ssr; - dg->expevt = event_code; - dg->tea = *tea; -} -#endif - -/* - gint_exc() - Handles exceptions. -*/ -__attribute__((section(".gint.exc"), interrupt_handler)) -void gint_exc(void) -{ - #ifdef GINT_DIAGNOSTICS - register_interrupt(0x100); - #endif - - uint32_t event = *(uint32_t *)gint_reg(register_expevt); - gint_interrupt_map_t map; - map = isSH3() ? gint_map_7705(event, 0x100) : gint_map_7305(event); - - gint_invoke(map.type, map.subtype); -} - -/* - gint_tlb() - Handles TLB misses. -*/ -__attribute__((section(".gint.tlb"), interrupt_handler)) -void gint_tlb(void) -{ - #ifdef GINT_DIAGNOSTICS - register_interrupt(0x400); - #endif - - uint32_t event = *(uint32_t *)gint_reg(register_expevt); - gint_interrupt_map_t map; - map = isSH3() ? gint_map_7705(event, 0x400) : gint_map_7305(event); - - gint_invoke(map.type, map.subtype); -} - -/* - gint_int() - Handles interrupts. -*/ -__attribute__((section(".gint.int"), interrupt_handler)) -void gint_int(void) -{ - #ifdef GINT_DIAGNOSTICS - register_interrupt(0x600); - #endif - - uint32_t event = *(uint32_t *)gint_reg(register_intevt); - gint_interrupt_map_t map; - map = isSH3() ? gint_map_7705(event, 0x600) : gint_map_7305(event); - - gint_invoke(map.type, map.subtype); -} - -#pragma GCC pop_options diff --git a/src/ctype/ctype_classes.c b/src/ctype/ctype_classes.c deleted file mode 100644 index 96ddd24..0000000 --- a/src/ctype/ctype_classes.c +++ /dev/null @@ -1,43 +0,0 @@ -#include - -// Let's save up some space and readability (that's Cake's idea, it's a bit of -// a preprocessor trick - but a rather nice trick). -#define r4(x) (x), (x), (x), (x) -#define r5(x) r4(x), (x) -#define r6(x) r5(x), (x) -#define r7(x) r6(x), (x) -#define r9(x) r7(x), (x), (x) -#define r10(x) r6(x), r4(x) -#define r15(x) r10(x), r4(x), (x) -#define r18(x) r9(x), r9(x) -#define r20(x) r10(x), r10(x) - -enum { - cntrl = 0x01, - space = 0x02, - punct = 0x04, - print = 0x08, - upper = 0x20, - lower = 0x10, - digit = 0x40, - xdigt = 0x80, -}; - -uint8_t ctype_classes[0x80] = { - // Control characters. - r9(cntrl), r5(cntrl | space), r18(cntrl), - // Space and some punctuation. - space | print, r15(punct | print), - // Decimal digits. - r10(digit | xdigt | print), - // Some punctuation. - r7(punct | print), - // Uppercase alphabet. - r6(upper | xdigt | print), r20(upper | print), - // Other punctuation symbols. - r6(punct | print), - // Lowercase alphabet. - r6(lower | xdigt | print), r20(lower | print), - // Last punctuation characters and DEL. - r4(punct | print), cntrl, -}; diff --git a/src/ctype/ctype_functions.c b/src/ctype/ctype_functions.c deleted file mode 100644 index ad1500b..0000000 --- a/src/ctype/ctype_functions.c +++ /dev/null @@ -1,73 +0,0 @@ -//--- -// Character type functions. -// Normally this functions need not be linked because there are macros to -// optimize performance, but we still need them to get some pointers. -//--- - -// We don't want to include because it defines all the macros... -#include -extern uint8_t ctype_classes[0x80]; - -#define _inline __attribute__((always_inline)) inline - -_inline int isalnum(int c) { - return ctype_classes[c] & 0xf0; -} - -_inline int isalpha(int c) { - return ctype_classes[c] & 0x30; -} - -_inline int iscntrl(int c) { - return ctype_classes[c] & 0x01; -} - -_inline int isdigit(int c) { - return ctype_classes[c] & 0x40; -} - -_inline int isgraph(int c) { - return ctype_classes[c] & 0xf4; -} - -_inline int islower(int c) { - return ctype_classes[c] & 0x10; -} - -_inline int isprint(int c) { - return ctype_classes[c] & 0x08; -} - -_inline int ispunct(int c) { - return ctype_classes[c] & 0x04; -} - -_inline int isspace(int c) { - return ctype_classes[c] & 0x02; -} - -_inline int isupper(int c) { - return ctype_classes[c] & 0x20; -} - -_inline int isxdigit(int c) { - return ctype_classes[c] & 0x80; -} - -_inline int isascii(int c) { - return ((unsigned)c <= 0x7f); -} - -_inline int isblank(int c) { - return (c == '\t' || c == ' '); -} - -_inline int tolower(int c) { - return c | isupper(c); -} - -_inline int toupper(int c) { - return c & ~(islower(c) << 1); -} - -#undef _inline diff --git a/src/display/adjustRectangle.c b/src/display/adjustRectangle.c deleted file mode 100644 index 5d2f482..0000000 --- a/src/display/adjustRectangle.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -/* - adjustRectangle() - Adjusts the given rectangle coordinates to ensure that : - - the rectangle is entirely contained in the screen - - x1 < x2 - - y1 < y2 - which is needed when working with screen rectangles. - Returns non-zero if the rectangle is entirely outside the screen. -*/ -int adjustRectangle(int *x1, int *y1, int *x2, int *y2) -{ - #define swap(a, b) tmp = a, a = b, b = tmp - int tmp; - - if(*x2 < *x1) swap(*x1, *x2); - if(*y2 < *y1) swap(*y1, *y2); - - if(*x1 > 127 || *y1 > 63 || *x2 < 0 || *y2 < 0) return 1; - - if(*x1 < 0) *x1 = 0; - if(*y1 < 0) *y1 = 0; - if(*x2 > 127) *x2 = 127; - if(*y2 > 63) *y2 = 63; - - return 0; - #undef swap -} diff --git a/src/display/dclear.c b/src/display/dclear.c deleted file mode 100644 index 6fadb5a..0000000 --- a/src/display/dclear.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -/* - dclear() - Clears the whole vram, making all pixels white. -*/ -void dclear(void) -{ - // I tend to use pre-decrement more than post-increment. - uint32_t *index = vram + 256; - - while(index > vram) - { - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - *--index = 0; - } -} diff --git a/src/display/display_vram.c b/src/display/display_vram.c deleted file mode 100644 index c0c48ed..0000000 --- a/src/display/display_vram.c +++ /dev/null @@ -1,47 +0,0 @@ -#include - -/* Add-in monochrome vram in gint's uninitialized bss section */ -__attribute__((section(".gint.bss"))) static uint32_t vram_local[256]; -__attribute__((section(".gint.bss"))) uint32_t *vram; - -/* - display_getLocalVRAM() - Returns gint's local video RAM address. Gint does not use the system's - buffer because it is misaligned. This function always returns the same - address. Both the display and the gray module heavily use this buffer; - make sure you don't interfere with them if you access it. - This function does not necessarily returns the video ram that is - currently in use; call display_getCurrentVRAM() for this. -*/ -inline uint32_t *display_getLocalVRAM(void) -{ - return vram_local; -} - -/* - display_getCurrentVRAM() - Returns the current monochrome video ram buffer. This function usually - returns the parameter of the last call to display_useVRAM(), or the - local vram address (which is default when the library starts). - The return value of this function is undefined if the gray engine is - running. -*/ -inline uint32_t *display_getCurrentVRAM(void) -{ - return vram; -} - -/* - display_useVRAM() - Changes the current monochrome video ram address. The argument must be - a 4-aligned 1024-byte buffer because the library's design requires it. - This function refuses misaligned buffers but trusts that enough space - is available; failing to provide enough memory may crash the program. - This function will most likely have no effect when running the gray - engine. -*/ -inline void display_useVRAM(uint32_t *ptr) -{ - if((uintptr_t)ptr & 3) return; - vram = ptr; -} diff --git a/src/display/dline.c b/src/display/dline.c deleted file mode 100644 index 95d57b6..0000000 --- a/src/display/dline.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include - -/* - dhline() - Optimized procedure for drawing an horizontal line. Uses a rectangle - mask. -*/ -static void dhline(size_t x1, size_t x2, int y, color_t operator) -{ - uint32_t masks[4]; - uint32_t *video = vram + (y << 2) + 4; - - // Swapping x1 and x2 if needed. - if(x1 > x2) x1 ^= x2, x2 ^= x1, x1 ^= x2; - getMasks(x1, x2, masks); - - switch(operator) - { - case color_white: - *--video &= ~masks[3]; - *--video &= ~masks[2]; - *--video &= ~masks[1]; - *--video &= ~masks[0]; - break; - - case color_black: - *--video |= masks[3]; - *--video |= masks[2]; - *--video |= masks[1]; - *--video |= masks[0]; - break; - - case color_invert: - *--video ^= masks[3]; - *--video ^= masks[2]; - *--video ^= masks[1]; - *--video ^= masks[0]; - break; - - default: - break; - } -} - -/* - dvline() - Optimized procedure for drawing a vertical line. This one is far less - powerful than dhline() because the video ram is essentially line- - oriented. It also uses a mask. -*/ -static void dvline(int y1, int y2, int x, color_t operator) -{ - uint32_t *base = vram + (y1 << 2) + (x >> 5); - uint32_t *video = vram + (y2 << 2) + (x >> 5) + 4; - uint32_t mask = 0x80000000 >> (x & 31); - - switch(operator) - { - case color_white: - while(video > base) video -= 4, *video &= ~mask; - break; - - case color_black: - while(video > base) video -= 4, *video |= mask; - break; - - case color_invert: - while(video > base) video -= 4, *video ^= mask; - break; - - default: - break; - } -} - -#define sgn(x) ((x) < 0 ? -1 : 1) -#define abs(x) ((x) < 0 ? -(x) : (x)) - -/* - dline() - Line drawing algorithm more or less directly taken for MonochromeLib. - Thanks PierrotLL for this. Relies on dhline() and dvline() for specific - cases. -*/ -void dline(int x1, int y1, int x2, int y2, color_t operator) -{ - if(adjustRectangle(&x1, &y1, &x2, &y2)) return; - - // Possible optimizations. - if(y1 == y2) - { - dhline(x1, x2, y1, operator); - return; - } - if(x1 == x2) - { - dvline(y1, y2, x1, operator); - return; - } - - int i, x = x1, y = y1, cumul; - int dx = x2 - x1, dy = y2 - y1; - int sx = sgn(dx), sy = sgn(dy); - - dx = abs(dx), dy = abs(dy); - - dpixel(x1, y1, operator); - - if(dx >= dy) - { - cumul = dx >> 1; - for(i = 1; i < dx; i++) - { - x += sx; - cumul += dy; - if(cumul > dx) cumul -= dx, y += sy; - dpixel(x, y, operator); - } - } - else - { - cumul = dy >> 1; - for(i = 1; i < dy; i++) - { - y += sy; - cumul += dx; - if(cumul > dy) cumul -= dy, x += sx; - dpixel(x, y, operator); - } - } - - dpixel(x2, y2, operator); -} diff --git a/src/display/dpixel.c b/src/display/dpixel.c deleted file mode 100644 index 8423bff..0000000 --- a/src/display/dpixel.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -/* - dpixel() - Changes a pixel's color in the video ram. The result may depend on the - current color of the pixel. -*/ -void dpixel(size_t x, size_t y, color_t operator) -{ - // Let's be honest, all this module's code *heavily* relies on the - // screen dimension in the end, so it's not that big a deal. - if(x > 127 || y > 63) return; - - uint32_t *video = vram + (y << 2) + (x >> 5); - uint32_t mask = 0x80000000 >> (x & 31); - - switch(operator) - { - case color_white: *video &= ~mask; break; - case color_black: *video |= mask; break; - case color_invert: *video ^= mask; break; - default: return; - } -} diff --git a/src/display/drect.c b/src/display/drect.c deleted file mode 100644 index 5e4d02b..0000000 --- a/src/display/drect.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include - -/* - drect() - Draws a rectangle on the screen. This function can use any color which - is not associated with the gray engine, including the reverse operator. -*/ -void drect(int x1, int y1, int x2, int y2, color_t operator) -{ - // Avoid wasting time if the requested operation is invalid here. - if(operator != color_white && operator != color_black - && operator != color_invert) return; - // Make sure the coordinates are in the right order, and that the - // requested rectangle crosses the screen. - if(adjustRectangle(&x1, &y1, &x2, &y2)) return; - - uint32_t masks[4]; - getMasks(x1, x2, masks); - - uint32_t *base = vram + (y1 << 2); - uint32_t *video = vram + (y2 << 2) + 4; - - switch(operator) - { - case color_white: - while(video > base) - { - *--video &= ~masks[3]; - *--video &= ~masks[2]; - *--video &= ~masks[1]; - *--video &= ~masks[0]; - } - break; - - case color_black: - while(video > base) - { - *--video |= masks[3]; - *--video |= masks[2]; - *--video |= masks[1]; - *--video |= masks[0]; - } - break; - - case color_invert: - while(video > base) - { - *--video ^= masks[3]; - *--video ^= masks[2]; - *--video ^= masks[1]; - *--video ^= masks[0]; - } - break; - - // Avoid some warnings. - default: return; - } -} diff --git a/src/display/dupdate.c b/src/display/dupdate.c deleted file mode 100644 index a6c92c9..0000000 --- a/src/display/dupdate.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include - -/* - dupdate() - Displays the vram on the physical screen. -*/ -void dupdate(void) -{ - screen_display((const void *)vram); -} diff --git a/src/display/font_system.bmp b/src/display/font_system.bmp deleted file mode 100644 index cee82be..0000000 Binary files a/src/display/font_system.bmp and /dev/null differ diff --git a/src/display/getMasks.c b/src/display/getMasks.c deleted file mode 100644 index 740d04b..0000000 --- a/src/display/getMasks.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/* - getMasks() - Computes the rectangle masks needed to affect pixels located between x1 - and x2 (both included). The four masks are stored in the third argument - (seen as an array). -*/ -void getMasks(size_t x1, size_t x2, uint32_t *masks) -{ - // Indexes of the first and last longs that are not empty. - size_t l1 = x1 >> 5; - size_t l2 = x2 >> 5; - size_t i = 0; - - // Setting the base masks. Those are the final values, except for the - // longs between indexes l1 and l2, that still need to be adjusted. - while(i < l1) masks[i++] = 0x00000000; - while(i <= l2) masks[i++] = 0xffffffff; - while(i < 4) masks[i++] = 0x00000000; - - // Removing the long number information in x1 and x2 (that is, the - // multiples of 32) to keep only the interesting information -- the - // number of null bits to add in l1 and l2. - x1 &= 31; - // Inverting x2 is here the same as computing 32 - x, since 32 is a - // power of 2 (positive bits at the left are removed by the mask). - x2 = ~x2 & 31; - - // Setting the first and last masks. - masks[l1] &= (0xffffffff >> x1); - masks[l2] &= (0xffffffff << x2); -} diff --git a/src/events/event_get.c b/src/events/event_get.c deleted file mode 100644 index 62b4c7f..0000000 --- a/src/events/event_get.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -/* - pollevent() - Returns the next event. If no one is available, returns an event whose - type is ET_None. This function always returns immediately. -*/ -event_t pollevent(void) -{ - event_t event = { - .type = event_none, - }; - if(queue_size <= 0) return event; - - event = event_queue[queue_start]; - - queue_size--; - if(queue_start == EVENTS_QUEUE_SIZE - 1) queue_start = 0; - else queue_start++; - - return event; -} - -/* - waitevent() - Returns the next event. If no one is available, waits for something to - happen. This function uses low-level sleep and should be preferred to - active waiting using loops. -*/ -event_t waitevent(void) -{ - event_t event; - - while((event = pollevent()).type == event_none) sleep(); - return event; -} diff --git a/src/events/event_push.c b/src/events/event_push.c deleted file mode 100644 index fc01a21..0000000 --- a/src/events/event_push.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -volatile event_t event_queue[EVENTS_QUEUE_SIZE]; -volatile int queue_start = 0; -volatile int queue_size = 0; - -/* - event_push() - Queues a user-defined event, allowing it to be retrieved by getevent() - or pollevent() later. Pushing ET_None events is not allowed. - Returns non-zero on error. -*/ -int event_push(event_t event) -{ - if(queue_size >= EVENTS_QUEUE_SIZE) return 1; - if(event.type == event_none) return 2; - - int index = queue_start + queue_size; - if(index >= EVENTS_QUEUE_SIZE) index -= EVENTS_QUEUE_SIZE; - - event_queue[index] = event; - queue_size++; - - return 0; -} diff --git a/src/gray/gclear.c b/src/gray/gclear.c deleted file mode 100644 index 60571ec..0000000 --- a/src/gray/gclear.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/* - gclear() - Clears the video ram. -*/ -void gclear(void) -{ - uint32_t *lbase = gray_lightVRAM(); - uint32_t *v1 = lbase + 256; - uint32_t *v2 = gray_darkVRAM() + 256; - - while(v1 > lbase) - { - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - *--v1 = 0; - - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - *--v2 = 0; - } -} diff --git a/src/gray/gline.c b/src/gray/gline.c deleted file mode 100644 index 1599f58..0000000 --- a/src/gray/gline.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -/* - gline() - Draws a line in the vram. Automatically optimizes special cases. This - function does not support the light operators. -*/ -void gline(int x1, int y1, int x2, int y2, color_t operator) -{ - color_t op1, op2; - - if(operator == color_invert) op1 = op2 = color_invert; - else if(operator >= color_none) return; - else - { - op1 = 3 * (operator & 1); - op2 = 3 * (operator >> 1); - } - - display_useVRAM(gray_lightVRAM()); - dline(x1, y1, x2, y2, op1); - display_useVRAM(gray_darkVRAM()); - dline(x1, y1, x2, y2, op2); -} diff --git a/src/gray/gpixel.c b/src/gray/gpixel.c deleted file mode 100644 index eae2460..0000000 --- a/src/gray/gpixel.c +++ /dev/null @@ -1,59 +0,0 @@ -#include - -/* - gpixel() - Puts a pixel in the vram. -*/ -void gpixel(size_t x, size_t y, color_t operator) -{ - if(x > 127 || y > 63) return; - - uint32_t *light = gray_lightVRAM() + (y << 2) + (x >> 5); - uint32_t *dark = gray_darkVRAM() + (y << 2) + (x >> 5); - uint32_t mask = 0x80000000 >> (x & 31); - - switch(operator) - { - case color_white: - *light &= ~mask; - *dark &= ~mask; - break; - case color_light: - *light |= mask; - *dark &= ~mask; - break; - case color_dark: - *light &= ~mask; - *dark |= mask; - break; - case color_black: - *light |= mask; - *dark |= mask; - break; - case color_none: - return; - - case color_invert: - *light ^= mask; - *dark ^= mask; - break; - case color_lighten:; - uint32_t old_light_1 = *light; - *light &= *dark | ~mask; - *dark = (old_light_1 | ~mask) & (mask ^ *dark); - break; - case color_lighten2: - *dark &= *light | ~mask; - *light &= ~mask; - break; - case color_darken:; - uint32_t old_light_2 = *light; - *light |= *dark & mask; - *dark = (old_light_2 & mask) | (mask ^ *dark); - break; - case color_darken2: - *dark |= *light | mask; - *light |= mask; - break; - } -} diff --git a/src/gray/gray_engine.c b/src/gray/gray_engine.c deleted file mode 100644 index 666b725..0000000 --- a/src/gray/gray_engine.c +++ /dev/null @@ -1,197 +0,0 @@ -//--- -// -// gint core/drawing module: gray -// -// Runs the gray engine and handles drawing for the dual-buffer system. -// -//--- - -#include -#include -#include -#include -#include - -// Additional video rams used by the gray engine. -#ifdef GINT_STATIC_GRAY -static uint32_t internals_vrams[3][256]; -#endif -static uint32_t *vrams[4]; - -// Current vram set (0 or 1), delays of the light and dark frames respectively. -static int current = 0; -static int delays[2]; - -// Is the engine currently running? -static int runs = 0; - -// Hardware timer used to run the engine. -static timer_t *gray_timer = NULL; - - - -//--- -// Interrupt control and initialization. -//--- - -/* gray_interrupt() -- switch buffers and update the screen */ -void gray_interrupt(void) -{ - htimer_reload(timer_gray, delays[(~current) & 1]); - - screen_display(vrams[current]); - current ^= 1; -} - -/* gray_init() -- setup the video ram buffers and timer delays */ -__attribute__((constructor)) static void gray_init(void) -{ - vrams[0] = display_getLocalVRAM(); -#ifdef GINT_STATIC_GRAY - vrams[1] = internal_vrams[0]; - vrams[2] = internal_vrams[1]; - vrams[3] = internal_vrams[2]; -#else - vrams[1] = NULL; - vrams[2] = NULL; - vrams[3] = NULL; -#endif - delays[0] = 912; - delays[1] = 1343; -} - -/* gray_quit() -- Free the gray engine's heap-allocated video rams */ -__attribute__((destructor)) static void gray_quit(void) -{ -#ifndef GINT_STATIC_GRAY - free(vrams[1]); - free(vrams[2]); - free(vrams[3]); -#endif -} - - - -//--- -// Engine control. -//--- - -/* - gray_start() - Starts the gray engine. The control of the screen is transferred to the - gray engine. -*/ -void gray_start(void) -{ -#ifndef GINT_STATIC_GRAY - for(int i = 0; i < 4; i++) - { - if(!vrams[i]) vrams[i] = malloc(1024); - /* Don't continue if any of the buffer is missing */ - if(!vrams[i]) return; - } -#endif - if(runs) return; - - gray_timer = htimer_setup(timer_gray, delays[0], timer_Po_64, 0); - timer_attach(gray_timer, gray_interrupt, NULL); - timer_start(gray_timer); - - current &= 1; - runs = 1; -} - -/* - gray_stop() - Stops the gray engine. The monochrome display system takes control of - the video ram. -*/ -void gray_stop(void) -{ - timer_stop(gray_timer); - runs = 0; - - /* TODO This may not be very wise considering the fact that the user - may have specified another monochrome vram address. This raises again - the idea of a parameter stack. */ - display_useVRAM(display_getLocalVRAM()); -} - -/* - gray_setDelays() - Changes the gray engine delays. -*/ -void gray_setDelays(int light, int dark) -{ - delays[0] = light; - delays[1] = dark; -} - - - -//--- -// Engine information. -//--- - -/* - gray_runs() - Returns 1 if the gray engine is running, 0 otherwise. -*/ -inline int gray_runs(void) -{ - return runs; -} - -/* - gray_lightVRAM() - Returns the module's gray vram address. -*/ -uint32_t *gray_lightVRAM(void) -{ - return vrams[~current & 2]; -} - -/* - gray_lightVRAM() - Returns the module's dark vram address. -*/ -uint32_t *gray_darkVRAM(void) -{ - return vrams[(~current & 2) | 1]; -} - -/* - gray_currentVRAM() - Returns the currently displayed video ram (if the engine runs). Used - internally, but has no interest for the user. You don't want to draw to - this vram. -*/ -uint32_t *gray_currentVRAM(void) -{ - return vrams[current ^ 1]; -} - -/* - gray_getDelays() - Returns the gray engine delays. Pointers are not set if NULL. -*/ -void gray_getDelays(int *light, int *dark) -{ - if(light) *light = delays[0]; - if(dark) *dark = delays[1]; -} - - - -//--- -// Drawing. -//--- - -/* - gupdate() - Swaps the vram buffer sets. -*/ -inline void gupdate(void) -{ - current ^= 2; -} diff --git a/src/gray/grect.c b/src/gray/grect.c deleted file mode 100644 index a123d94..0000000 --- a/src/gray/grect.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -/* - grect() - Draws a rectangle on the screen. This function can use all colors. -*/ -void grect(int x1, int y1, int x2, int y2, color_t operator) -{ - if(operator == color_none) return; - if(adjustRectangle(&x1, &y1, &x2, &y2)) return; - - uint32_t masks[4]; - getMasks(x1, x2, masks); - - uint32_t *lbase = gray_lightVRAM() + (y1 << 2); - uint32_t *lvideo = gray_lightVRAM() + (y2 << 2) + 4; - uint32_t *dvideo = gray_darkVRAM() + (y2 << 2) + 4; - - // Doing things in this order will be slower, but man, I can't stand - // writing that many lines of code for such a simple task. It will be - // terribly heavy in the binary file... - while(lvideo > lbase) for(int i = 3; i >= 0; i--) switch(operator) - { - case color_white: - *--lvideo &= ~masks[i]; - *--dvideo &= ~masks[i]; - break; - case color_light: - *--lvideo |= masks[i]; - *--dvideo &= ~masks[i]; - break; - case color_dark: - *--lvideo &= ~masks[i]; - *--dvideo |= masks[i]; - break; - case color_black: - *--lvideo |= masks[i]; - *--dvideo |= masks[i]; - break; - case color_none: return; - - case color_invert: - *--lvideo ^= masks[i]; - *--dvideo ^= masks[i]; - break; - case color_lighten:; - uint32_t light_1 = *lvideo; - dvideo--; - *--lvideo &= *dvideo | ~masks[i]; - *dvideo = (light_1 | ~masks[i]) & (masks[i] ^ *dvideo); - break; - case color_lighten2: - lvideo--; - *--dvideo &= *lvideo | ~masks[i]; - *lvideo &= ~masks[i]; - break; - case color_darken:; - uint32_t light_2 = *lvideo; - dvideo--; - *--lvideo |= *dvideo & masks[i]; - *dvideo = (light_2 & masks[i]) | (masks[i] ^ *dvideo); - break; - case color_darken2: - lvideo--; - *--dvideo |= *lvideo | masks[i]; - *lvideo |= masks[i]; - break; - } -} diff --git a/src/init/crt0.c b/src/init/crt0.c deleted file mode 100644 index 712fd3c..0000000 --- a/src/init/crt0.c +++ /dev/null @@ -1,306 +0,0 @@ -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -/* We need some more functionality to generate these */ -#ifdef GINT_STARTUP_LOG - #include - #include - #include - #include - - #ifndef GINT_NO_SYSCALLS - #include - #endif -#endif - -int main(void); - -static void init(void); -static void fini(void); - -// Symbols provided by the linker script. -extern uint32_t - bdata, sdata, // Location of .data section - bbss, sbss, // Location of .bss section - bgint, egint, // Location of interrupt handler and gint data - bgbss, egbss, // Location of interrupt handler and gint data - gint_vbr, // VBR address - romdata, // ROM address of .data section contents - gint_data; // ROM address of .gint section contents -extern void - (*bctors)(void), (*ectors)(void), // Constructors - (*bdtors)(void), (*edtors)(void); // Destructors - -// This variable should be overwritten before being returned, so the default -// value doesn't matter much. -static int exit_code = EXIT_SUCCESS; -static jmp_buf env; - -// Exit handlers. -static void (*atexit_handlers[ATEXIT_MAX])(void); -static int atexit_index = 0; - -#include - -/* - start() - Program entry point. Loads the data section into the memory and invokes - main(). Also prepares the execution environment by initializing all the - modules. -*/ -__attribute__((section(".pretext.entry"))) int start(void) -{ - /* Configure the display output or we won't get anywhere - this is also - needed for the add-in even if the startup logs are disabled */ - display_useVRAM(display_getLocalVRAM()); - text_configure(NULL, color_black); - -#ifdef GINT_STARTUP_LOG - /* Start outputting information on the screen so that we can quickly - debug anything that would fail */ - uint32_t rom_size = ((uint32_t)&romdata - 0x00300000) >> 10; - uint32_t ram_size = ((uint32_t)&gint_data - (uint32_t)&romdata) - + ((uint32_t)&sbss); - uint32_t rram_size = ((uint32_t)&egbss - (uint32_t)&gint_vbr); - - dclear(); - init_stage("Startup"); - dupdate(); - - print(1, 1, init_version()); - print(1, 2, "ROM RAM RRAM"); - print(4, 3, "k c d"); - print_dec(1, 3, rom_size, 3); - print_dec(6, 3, ram_size, 4); - print_dec(11, 3, rram_size, 4); - print_dec(17, 3, &ectors - &bctors, 2); - print_dec(20, 3, &edtors - &bdtors, 2); - dupdate(); -#endif - - /* Determining the processor type */ - mpu_t mpu = getMPU(); - -#ifdef GINT_STARTUP_LOG - const char *mpu_names[] = { "SH7337", "SH7355", "SH7305", "SH7724" }; - if(mpu >= 1 && mpu <= 4) print(16, 2, mpu_names[mpu - 1]); - else print_dec(16, 2, mpu, 6); - dupdate(); -#endif - - /* Make sure the MPU is of a valid type */ - if(!mpu || mpu > 4) init_halt(); - -#ifdef GINT_STARTUP_LOG - init_stage(" MMU"); - dupdate(); -#endif - - /* Try to get the TLB filled by the system by accessing all the pages - while the system still answers TLB misses */ - mmu_pseudoTLBInit(); - -#ifdef GINT_STARTUP_LOG - /* Read the TLB and count how much memory has been mapped */ - /* TODO: Debug TLB at startup */ - print(1, 4, "MMU ROM:???k RAM:???k"); - - init_stage("Section"); - dupdate(); -#endif - - /* Copying the data section, then clearing the bss section. This - doesn't affect the previously used variables, which are stored in - another section for this purpose */ - volatile uint32_t *data = &bdata; - volatile uint32_t *data_end = (void *)&bdata + (int)&sdata; - volatile uint32_t *src = &romdata; - while(data < data_end) *data++ = *src++; - volatile uint32_t *bss = &bbss; - volatile uint32_t *bss_end = (void *)&bbss + (int)&sbss; - while(bss < bss_end) *bss++ = 0; - -#ifdef GINT_STARTUP_LOG - init_stage("Handler"); - dupdate(); -#endif - - /* Initialize gint and debug all the interrupt priorities */ - gint_init(mpu); - -#ifdef GINT_STARTUP_LOG - if(isSH3()) - { - print(1, 5, "ABCD"); - print_hex( 6, 5, INTC._7705.iprs.IPRA->word, 4); - print_hex(10, 5, INTC._7705.iprs.IPRB->word, 4); - print_hex(14, 5, INTC._7705.iprs.IPRC->word, 4); - print_hex(18, 5, INTC._7705.iprs.IPRD->word, 4); - print(1, 6, "EFGH"); - print_hex( 6, 6, INTC._7705.iprs.IPRE->word, 4); - print_hex(10, 6, INTC._7705.iprs.IPRF->word, 4); - print_hex(14, 6, INTC._7705.iprs.IPRG->word, 4); - print_hex(18, 6, INTC._7705.iprs.IPRH->word, 4); - } - else - { - print(1, 5, "ACFG"); - print_hex( 6, 5, INTC._7305.iprs->IPRA.word, 4); - print_hex(10, 5, INTC._7305.iprs->IPRC.word, 4); - print_hex(14, 5, INTC._7305.iprs->IPRF.word, 4); - print_hex(18, 5, INTC._7305.iprs->IPRG.word, 4); - print(1, 6, "HJKL"); - print_hex( 6, 6, INTC._7305.iprs->IPRH.word, 4); - print_hex(10, 6, INTC._7305.iprs->IPRJ.word, 4); - print_hex(14, 6, INTC._7305.iprs->IPRK.word, 4); - print_hex(18, 6, INTC._7305.iprs->IPRL.word, 4); - } -#endif - - /* Checking that at least the required interrupts are enabled */ - if(isSH3() - ? (!INTC._7705.iprs.IPRA->word) - : (!INTC._7305.iprs->IPRA.word || !INTC._7305.iprs->IPRK.word) - ) init_halt(); - -#ifdef GINT_STARTUP_LOG - init_stage(" Clocks"); - dupdate(); -#endif - - /* Measuring the clock speed */ - clock_measure(); - clock_measure_end(); - -#ifdef GINT_STARTUP_LOG - clock_config_t clock = clock_config(); - print(1, 7, "Clock I B P"); - print_dec( 8, 7, clock.Iphi_f / 1000000, 2); - print_dec(12, 7, clock.Bphi_f / 1000000, 2); - print_dec(16, 7, clock.Pphi_f / 1000000, 2); - - init_stage("Boot OK"); - dupdate(); - - /* Displaying some interrupt controller config */ - if(isSH3()) - { - print(1, 8, "INTC:0"); - print_hex(7, 8, INTC._7705.ICR1->word, 4); - } - else - { - print(1, 8, "INTC:"); - print_hex(6, 8, INTC._7305.ICR0->word, 4); - print_hex(10, 8, (INTC._7305.USERIMASK->lword >> 4) & 0xf, 1); - } - - #ifndef GINT_NO_SYSCALLS - /* Print the OS version */ - char version[11]; - __get_os_version(version); - version[2] = version[3]; - version[3] = version[4]; - version[4] = version[6]; - version[5] = version[7]; - version[6] = version[8]; - version[7] = version[9]; - version[8] = 0; - print(12, 8, "OS"); - print(14, 8, version); - #endif - - dupdate(); -#endif - - /* Call the global constructors */ - init(); - -#ifdef GINT_STARTUP_LOG - /* Keep this visible if a key is kept pressed */ - keyboard_interrupt(); - if(pollevent().type != event_none) getkey(); -#endif - - /* Otherwise, call main() and get the show on the road! */ - int x = setjmp(env); - if(!x) exit_code = main(); - - while(atexit_index > 0) (*atexit_handlers[--atexit_index])(); - fini(); - - gint_quit(); - - return exit_code; -} - -/* init() -- call the constructors */ -static void init(void) -{ - extern void - (*bctors)(void), - (*ectors)(void); - void (**func)(void) = &bctors; - - while(func < &ectors) (*(*func++))(); -} - -/* fini() -- call the destructors */ -static void fini(void) -{ - extern void - (*bdtors)(void), - (*edtors)(void); - void (**func)(void) = &bdtors; - - while(func < &edtors) (*(*func++))(); -} - - - -/* - abort() - Immediately ends the program without invoking the exit handlers. -*/ -void abort(void) -{ - exit_code = EXIT_FAILURE; - // Avoiding any exit handler call. - atexit_index = 0; - longjmp(env, 1); -} - -/* - exit() - Ends the program and returns the given exit code status. Calls exit - handlers before returning. - Usually exit() would ask the operating system to stop the process but - the fx-9860G executes only one program at a time and calls it as a - function. Reaching the program end point thus efficiently exits. -*/ -void exit(int status) -{ - exit_code = status; - longjmp(env, 1); -} - -/* - atexit() - Registers a function to be called at normal program termination. -*/ -int atexit(void (*function)(void)) -{ - if(atexit_index >= ATEXIT_MAX) return 1; - - atexit_handlers[atexit_index++] = function; - return 0; -} diff --git a/src/init/util.c b/src/init/util.c deleted file mode 100644 index bb2ad40..0000000 --- a/src/init/util.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include - -/* init_version() -- get a version string */ -const char *init_version(void) -{ - static char data[14]; - uint32_t s = (uint32_t)&GINT_VERSION; - - /* Force the string constant to reside in ROM because we haven't - initialized the data section yet */ - memcpy(data, "gint #0.0-000", 14); - - /* Quickly get the three digits of the build number */ - qdiv_t x = qdiv_10(s & 0xffff); - qdiv_t y = qdiv_10(x.q); - - data[5] = (s & 0xff000000) >> 24; - data[6] += ((s & 0x00f00000) >> 20); - data[8] += ((s & 0x000f0000) >> 16); - data[10] += y.q; - data[11] += y.r; - data[12] += x.r; - - return data; -} - -/* init_stage() -- change the current init stage */ -void init_stage(const char *name) -{ - drect(85, 0, 127, 7, color_white); - print(15, 1, name); -} - -/* init_halt() -- halt the program */ -void init_halt(void) -{ - while(1) sleep(); -} - -/* print_dec() -- print a number in base 10 */ -void print_dec(int x, int y, int n, int digits) -{ - char str[20]; - str[digits] = 0; - - while(--digits >= 0) - { - qdiv_t d = qdiv_10(n); - str[digits] = '0' + d.r; - n = d.q; - } - - print(x, y, str); -} - -/* print_hex() -- print a number in base 16 */ -void print_hex(int x, int y, uint32_t n, int digits) -{ - char str[20]; - str[digits] = 0; - - while(--digits >= 0) - { - str[digits] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9); - n >>= 4; - } - - print(x, y, str); -} diff --git a/src/keyboard/getPressedKeys.c b/src/keyboard/getPressedKeys.c deleted file mode 100644 index c3b21f1..0000000 --- a/src/keyboard/getPressedKeys.c +++ /dev/null @@ -1,53 +0,0 @@ -#include - -/* - getPressedKeys() - Find 'count' pressed keys in the keyboard state and fills the 'keys' - array. Returns the number of actually-pressed keys found. -*/ -int getPressedKeys(volatile uint8_t *keyboard_state, int *keys, int count) -{ - int row = 1, column; - int found = 0, actually_pressed; - int state; - if(count <= 0) return 0; - - if(keyboard_state[0] & 1) - { - keys[found++] = KEY_AC_ON; - count--; - } - - while(count && row <= 9) - { - while(row <= 9 && !keyboard_state[row]) row++; - if(row > 9) break; - - state = keyboard_state[row]; - column = 0; - - while(count && column < 8) - { - if(state & 1) - { - keys[found++] = (column << 4) | row; - count--; - } - - state >>= 1; - column++; - } - - row++; - } - - actually_pressed = found; - - while(count) - { - keys[found++] = KEY_NONE; - count--; - } - - return actually_pressed; -} diff --git a/src/keyboard/getkey.c b/src/keyboard/getkey.c deleted file mode 100644 index 9b1f38b..0000000 --- a/src/keyboard/getkey.c +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* - getkey() - Blocking function with auto-repeat and SHIFT modifying functionalities. - Roughly reproduces the behavior of the system's GetKey(). -*/ -int getkey(void) -{ - return getkey_opt(getkey_default, 0); -} - -/* - getkey_opt() - Enhances getkey() with more general functionalities. - If delay_ms is non-zero and positive, getkey_opt() will return - KEY_NOEVENT if no event occurs before delay_ms. -*/ -static void getkey_opt_wait(int *delay_ms) -{ - while(!interrupt_flag) sleep(); - interrupt_flag = 0; - - if(*delay_ms > 0) - { - (*delay_ms) -= vtimer->ms_delay; - if(*delay_ms < 0) *delay_ms = 0; - } -} -int getkey_opt(getkey_option_t options, int delay_ms) -{ - event_t event; - int modifier = 0, key; - key_type_t type; - - if(delay_ms <= 0) delay_ms = -1; - - while(delay_ms != 0) switch((event = pollevent()).type) - { - case event_none: - getkey_opt_wait(&delay_ms); - break; - - case event_key_press: - key = event.key.code; - - if(options & getkey_manage_backlight && key == KEY_OPTN - && (modifier & MOD_SHIFT)) - { - screen_toggleBacklight(); - modifier &= ~MOD_SHIFT; - continue; - } - if((options & getkey_task_switch) && key == KEY_MENU - && !modifier) - { - continue; - } - if(options & getkey_shift_modifier && key == KEY_SHIFT) - { - modifier ^= MOD_SHIFT; - continue; - } - if(options & getkey_alpha_modifier && key == KEY_ALPHA) - { - modifier ^= MOD_ALPHA; - continue; - } - - last_key = key; - last_repeats = 0; - last_time = 0; - return key | modifier; - - case event_key_repeat: - key = event.key.code; - if(key != last_key) continue; - - // Checking that this type of repetition is allowed. - type = key_type(key); - if(!(options & (type << 4))) break; - - last_time += vtimer->ms_delay; - int cmp = last_repeats ? repeat_next : repeat_first; - - if(last_time >= cmp) - { - last_repeats++; - last_time -= cmp; - return last_key; - } - break; - - case event_key_release: -#ifndef GINT_NO_SYSCALLS - if((options & getkey_task_switch) && event.key.code == KEY_MENU - && !modifier) - { - gint_switch(); - continue; - } -#endif - - if((int)event.key.code != last_key) break; - last_key = KEY_NONE; - last_repeats = 0; - last_time = 0; - break; - - default: - break; - } - - last_key = KEY_NONE; - last_repeats = 0; - last_time = 0; - return KEY_NONE; -} diff --git a/src/keyboard/key_char.c b/src/keyboard/key_char.c deleted file mode 100644 index 1e1ccd1..0000000 --- a/src/keyboard/key_char.c +++ /dev/null @@ -1,36 +0,0 @@ -#include - -/* - key_char() - Returns the ASCII character associated with a character key, and 0 for - other keys. This function expects a matrix code and not a key_id() - code, and heeds for the ALPHA modifier. -*/ -int key_char(int matrix_key) -{ - char flat[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, '2', '^', 0x0, 0x0, 0x0, - 'X', 'L', 'l', 's', 'c', 't', - 0x0, 0x0, '(', ')', ',', '>', - '7', '8', '9', 0x0, 0x0, 0x0, - '4', '5', '6', '*', '/', 0x0, - '1', '2', '3', '+', '-', 0x0, - '0', '.', 'e', '_', 0x0, 0x0 - }; - char alpha[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 'r', 'o', 0x0, 0x0, 0x0, - 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 0x0, 0x0, 0x0, - 'P', 'Q', 'R', 'S', 'T', 0x0, - 'U', 'V', 'W', 'X', 'Y', 0x0, - 'Z', ' ', '"', 0x0, 0x0, 0x0 - }; - - int id = key_id(matrix_key); - return (matrix_key & MOD_ALPHA) ? alpha[id] : flat[id]; -} diff --git a/src/keyboard/key_id.c b/src/keyboard/key_id.c deleted file mode 100644 index 152208c..0000000 --- a/src/keyboard/key_id.c +++ /dev/null @@ -1,19 +0,0 @@ -#include - -/* - keyid() - Transforms a key identifier and returns a key code that is more - convenient for array subscript that the original matrix codes. Please - note that there are a few holes in the numbering. - This function ignores modifiers and returns -1 on error. -*/ -int key_id(int matrix_key) -{ - if(matrix_key < 0) return -1; - matrix_key &= MOD_CLEAR; - - int row = 9 - (matrix_key & 0x0f); - int column = 6 - ((matrix_key & 0xf0) >> 4); - - return 6 * row + column; -} diff --git a/src/keyboard/key_type.c b/src/keyboard/key_type.c deleted file mode 100644 index b29e617..0000000 --- a/src/keyboard/key_type.c +++ /dev/null @@ -1,24 +0,0 @@ -#include - -/* - key_type() - Returns a key's type. This functions ignores modifiers and expects - matrix codes as argument, not key_id() codes. -*/ -key_type_t key_type(int matrix_key) -{ - matrix_key &= MOD_CLEAR; - - // Arrow keys. - if(matrix_key == KEY_UP || matrix_key == KEY_RIGHT - || matrix_key == KEY_DOWN || matrix_key == KEY_LEFT) - { - return key_type_arrow; - } - - // Function keys (F1 .. F6) are ton only keys of the ninth row. - if((matrix_key & 0x0f) == 0x09) return key_type_function; - - // Then character keys are those that have an associated character. =p - return key_char(matrix_key) ? key_type_character : key_type_control; -} diff --git a/src/keyboard/keyboard_core.c b/src/keyboard/keyboard_core.c deleted file mode 100644 index 530b5fc..0000000 --- a/src/keyboard/keyboard_core.c +++ /dev/null @@ -1,178 +0,0 @@ -#include -#include -#include -#include -#include -#include - -//--- -// Keyboard variables. -//--- - -// Current keyboard state: each element represents a row, and each bit a key, -// but not all bits are used. -volatile uint8_t keyboard_state[10] = { 0 }; -// Interrupt flag: set when an interrupt occurs, and cleared by functions such -// as getkey() that watch it (because such functions will wake up every time an -// interrupt occurs, and they need to know whether it was the keyboard). -volatile int interrupt_flag = 0; - -// Delays, in milliseconds, before repeating keys (the first repetition may -// have a different delay). -int repeat_first = 625, repeat_next = 125; - -// Which key was pressed last, how many times it has been repeated, and how -// much time (in milliseconds) has elapsed since it was last repeated. -int last_key = KEY_NONE, last_repeats = 0, last_time = 0; - -// Virtual timer object. -timer_t *vtimer = NULL; - - - -//--- -// Interrupt management. -//--- - -/* - keyboard_interrupt() - Callback function for keyboard update; called by the timer manager when - the keyboard's virtual timer fires. Ideally this function should be - interrupt-driven but the PINT interrupts seem to fire continuously, - which is annoying. -*/ -void keyboard_interrupt(void) -{ - // This procedure is critical for speed. If there's anything that could - // be optimized, please tell me. - - // New keyboard state. - uint8_t state[10] = { 0 }; - isSH3() ? keyboard_updateState_7705(state) - : keyboard_updateState_7305(state); - - // Event types associated with each old/new state pair (see later). - uint8_t events[4] = { - event_none, - event_key_release, - event_key_press, - event_key_repeat, - }; - - // AC/ON has not a matrix code that corresponds to its location in the - // buffer, so we need to check it independently. - if(keyboard_state[0] | state[0]) - { - int kind = (state[0] << 1) | keyboard_state[0]; - - if(kind) - { - event_t event = { - .type = events[kind], - .key.code = KEY_AC_ON, - .key.id = key_id(KEY_AC_ON), - .key.character = key_char(KEY_AC_ON) - }; - event_push(event); - } - } - keyboard_state[0] = state[0]; - - for(int row = 1; row <= 9; row++) - { - // Shifting the new state will allow us to make up a 2-bit - // value for each key more easily, improving efficiency. - uint16_t old = keyboard_state[row]; - uint16_t new = state[row] << 1; - - if(!new && !old) continue; - keyboard_state[row] = state[row]; - - for(uint8_t code = row; code < (row | 0x80); code += 0x10) - { - int kind = (new & 2) | (old & 1); - old >>= 1; - new >>= 1; - - if(!kind) continue; - - event_t event = { - .type = events[kind], - .key.code = code, - .key.id = key_id(code), - .key.character = key_char(code) - }; - event_push(event); - } - } - - // Signal the interrupt to the higher-level functions. - interrupt_flag = 1; -} - - - -//--- -// Keyboard configuration. -//--- - -/* - keyboard_init() - Starts the keyboard timer. -*/ -__attribute__((constructor)) void keyboard_init(void) -{ - keyboard_setRepeatRate(625, 125); - - vtimer = timer_create(25, 0); - timer_attach(vtimer, keyboard_interrupt, NULL); - timer_start(vtimer); -} - -/* - keyboard_setAnalysisDelay() - Sets the keyboard analysis delay, that is, the delay (in ms) between - two keyboard analyzes. Please note that the repeat delays should be - multiples of the analysis delay for better accuracy. -*/ -void keyboard_setAnalysisDelay(int analysis_delay_ms) -{ - if(analysis_delay_ms <= 0) return; - timer_reload(vtimer, analysis_delay_ms); -} - -/* - keyboard_setRepeatRate() - Sets the default repeat rate for key events. The delay before the first - repeat may have a different value (usually longer). The unit for the - argument is ms, but the repeat events themselves may only be fired when - a keyboard analysis is performed; which means that for better accuracy, - these delays should be a multiple of the keyboard period. - For instance, delays of (625 ms, 125 ms) will imitate the system's - default setting. -*/ -void keyboard_setRepeatRate(int first, int next) -{ - repeat_first = (first > 0) ? first : 0; - repeat_next = (next > 0) ? next : 0; -} - -/* - keyboard_quit() - Stops the keyboard timer. -*/ -__attribute__((destructor)) void keyboard_quit(void) -{ - timer_destroy(vtimer); - vtimer = NULL; -} - -/* - keyboard_stateBuffer() - Returns the address of the keyboard state array. The returned address - is the handler's buffer, therefore it contains volatile data. -*/ -volatile uint8_t *keyboard_stateBuffer(void) -{ - return keyboard_state; -} diff --git a/src/keyboard/keyboard_sh7305.c b/src/keyboard/keyboard_sh7305.c deleted file mode 100644 index f1647d4..0000000 --- a/src/keyboard/keyboard_sh7305.c +++ /dev/null @@ -1,146 +0,0 @@ -//--- -// -// gint core module: keyboard analyzer -// -// Probably the most difficult hardware interaction. There is very few -// documentation on how the system actually analyzes the keyboard. While -// disassembling syscalls reveals the following procedure (which was -// already documented by SimonLothar), there is nothing about the -// detection problems of the multi-getkey system. -// -//--- - -#include -#include -#include <7305.h> - -//--- -// Keyboard management. -//--- - -/* - kdelay() - Should sleep during a few milliseconds. Well... - This delay has a great influence on key detection. Here are a few - observations of what happens with common numbers of "nop" (without - overclock). Take care of the effect of overclock! - - Column effects - May have something to do with register HIZCRB not being used here. When - many keys on the same column are pressed, other keys of the same column - may be triggered. - - (The following values do not apply to the latest tests, but the trend - remains the same.) - - Less Bad key detection. - - 8 Very few column effects. Most often, three keys may be pressed - simultaneously. However, [UP] has latencies and is globally not - detected. - - 12 Seems best. Every individual key is detected well. No column - effect observed before four keys. - - 16 Every single key is detected correctly. Pressing two keys on a - same column does not usually create a column effect. Three keys - almost always. - - More Does not improve single key detection, and increase column - effects. At 256 every single key press create a whole column - effect. -*/ -static void kdelay(void) -{ - #define r4(str) str str str str - - __asm__ - ( - r4(r4("nop\n\t")) - r4(r4("nop\n\t")) - ); - - #undef r4 -} - -/* - krow() - Reads a keyboard row. Works like krow() for SH7705; see source file - keyboard_7705.c for more details. -*/ -static uint8_t krow(int row) -{ - volatile uint16_t *injector1 = (void *)0xa4050116; - volatile uint8_t *data1 = (void *)0xa4050136; - - volatile uint16_t *injector2 = (void *)0xa4050118; - volatile uint8_t *data2 = (void *)0xa4050138; - - volatile uint16_t *detector = (void *)0xa405014c; - volatile uint8_t *keys = (void *)0xa405016c; - - volatile uint8_t *key_register = (void *)0xa40501c6; -// volatile uint16_t *hizcrb = (void *)0xa405015a; - - uint16_t smask; - uint8_t cmask; - uint8_t result = 0; - - if(row < 0 || row > 9) return 0x00; - - // Additional configuration for SH7305. - *detector = 0xaaaa; - *key_register = 0xff; - *injector1 = (*injector1 & 0xf000) | 0x0555; - *injector2 = (*injector2 & 0xff00) | 0x0055; - *data1 |= 0x3f; - *data2 |= 0x0f; - kdelay(); - - if(row < 6) - { - smask = 0x0003 << (row * 2); - cmask = ~(1 << row); - - *injector1 = ((*injector1 & 0xf000) | 0x0aaa) ^ smask; - *injector2 = (*injector2 & 0xff00) | 0x00aa; - kdelay(); - - *data1 = (*data1 & 0xc0) | (cmask & 0x3f); - *data2 |= 0x0f; - kdelay(); - } - else - { - smask = 0x0003 << ((row - 6) * 2); - cmask = ~(1 << (row - 6)); - - *injector1 = (*injector1 & 0xf000) | 0x0aaa; - *injector2 = ((*injector2 & 0xff00) | 0x00aa) ^ smask; - kdelay(); - - *data1 |= 0x3f; - *data2 = (*data2 & 0xf0) | (cmask & 0x0f); - kdelay(); - } - - // Reading the keyboard row. - result = ~*keys; - kdelay(); - - // Re-initializing the port configuration and data. - *injector1 = (*injector1 & 0xf000) | 0x0aaa; - *injector2 = (*injector2 & 0xff00) | 0x00aa; - kdelay(); - *injector1 = (*injector1 & 0xf000) | 0x0555; - *injector2 = (*injector2 & 0xff00) | 0x0055; - kdelay(); - *data1 &= 0xc0; - *data2 &= 0xf0; - - return result; -} - -/* - keyboard_updateState() - Updates the keyboard state. -*/ -void keyboard_updateState_7305(volatile uint8_t *keyboard_state) -{ - for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i); -} diff --git a/src/keyboard/keyboard_sh7705.c b/src/keyboard/keyboard_sh7705.c deleted file mode 100644 index a7fb0a3..0000000 --- a/src/keyboard/keyboard_sh7705.c +++ /dev/null @@ -1,135 +0,0 @@ -//--- -// -// gint core module: keyboard analyzer -// -// Probably the most difficult hardware interaction. There is very few -// documentation on how the system actually analyzes the keyboard. While -// disassembling syscalls reveals the following procedure (which was -// already documented by SimonLothar), there is nothing about the -// detection problems of the multi-getkey system. -// -//--- - -#include -#include <7705.h> - -//--- -// Keyboard management. -//--- - -/* - kdelay() - Used to be a low-level sleep using the watchdog, as in the system. This - way seems OK at least, and it doesn't create column effects as for - SH7305. -*/ -static void kdelay(void) -{ - #define r4(str) str str str str - - __asm__ - ( - r4("nop\n\t") - ); - - #undef r4 - - /* Watchdog delay version. - const int delay = 0xf4; - - // Disabling the watchdog timer interrupt and resetting the - // configuration. Setting the delay. - INTC.IPRB.BIT._WDT = 0; - WDT.WTCSR.WRITE = 0xa500; - WDT.WTCNT.WRITE = 0x5a00 | (delay & 0xff); - - // Counting on Po/256. - WDT.WTCSR.WRITE = 0xa505; - // Starting the timer (sets again to Po/256). - WDT.WTCSR.WRITE = 0xa585; - - // Waiting until it overflows (delaying), then clearing the overflow - // flag. - while((WDT.WTCSR.READ.BYTE & 0x08) == 0); - WDT.WTCSR.WRITE = 0xa500 | (WDT.WTCSR.READ.BYTE & 0xf7); - - // Resetting the configuration and the counter. - WDT.WTCSR.WRITE = 0xa500; - WDT.WTCSR.WRITE = 0x5a00; - - // Enabling back the watchdog timer interrupt. - INTC.IPRB.BIT._WDT = GINT_INTP_WDT; - */ -} - -/* - krow() - Reads a keyboard row. -*/ -static uint8_t krow(int row) -{ - // '11' on the active row, '00' everywhere else. - uint16_t smask = 0x0003 << ((row % 8) * 2); - // '0' on the active row, '1' everywhere else. - uint8_t cmask = ~(1 << (row % 8)); - // Line results. - uint8_t result = 0; - - if(row < 0 || row > 9) return 0x00; - - // Initial configuration. - PFC.PBCR.WORD = 0xaaaa; - PFC.PMCR.WORD = (PFC.PMCR.WORD & 0xff00) | 0x0055; - kdelay(); - - if(row < 8) - { - // Configuring port B/M as input except for the row to check, - // which has to be an output. This sets '01' (output) on the - // active row, '10' (input) everywhere else. - PFC.PBCR.WORD = 0xaaaa ^ smask; - PFC.PMCR.WORD = (PFC.PMCR.WORD & 0xff00) | 0x00aa; - kdelay(); - - // Every bit set to 1 except the active row bit. - PB.DR.BYTE = cmask; - PM.DR.BYTE = (PM.DR.BYTE & 0xf0) | 0x0f; - kdelay(); - } - else - { - // The same, but deals with port M. - PFC.PBCR.WORD = 0xaaaa; - PFC.PMCR.WORD = ((PFC.PMCR.WORD & 0xff00) | 0x00aa) ^ smask; - kdelay(); - - PB.DR.BYTE = 0xff; - PM.DR.BYTE = (PM.DR.BYTE & 0xf0) | cmask; - kdelay(); - } - - // Reading the keyboard row. - result = ~PA.DR.BYTE; - kdelay(); - - // Re-initializing the port configuration and data. - PFC.PBCR.WORD = 0xaaaa; - PFC.PMCR.WORD = (PFC.PMCR.WORD & 0xff00) | 0x00aa; - kdelay(); - PFC.PBCR.WORD = 0x5555; - PFC.PMCR.WORD = (PFC.PMCR.WORD & 0xff00) | 0x0055; - kdelay(); - PB.DR.BYTE = 0x00; - PM.DR.BYTE &= 0xf0; - - return result; -} - -/* - keyboard_updateState() - Updates the keyboard state. -*/ -void keyboard_updateState_7705(volatile uint8_t *keyboard_state) -{ - for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i); -} diff --git a/src/math/math_qdiv.c b/src/math/math_qdiv.c deleted file mode 100644 index be7b59c..0000000 --- a/src/math/math_qdiv.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -/* - Quickly divides by predefined integers using a 64-bit multiplication - technique. These functions should be ~10 times faster than dividing - using opeator "/". -*/ -__attribute__((always_inline)) -inline qdiv_t qdiv(uint32_t n, uint32_t divider, uint32_t magic) -{ - qdiv_t result; - - __asm__( - "dmuls.l %1, %2 \n\t" - "sts mach, %0 " - : "=r"(result.q) - : "r"(n), "r"(magic) - : "macl", "mach" - ); - - result.r = n - divider * result.q; - return result; -} diff --git a/src/mmu/pseudoTLBInit.c b/src/mmu/pseudoTLBInit.c deleted file mode 100644 index c947651..0000000 --- a/src/mmu/pseudoTLBInit.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -/* - mmu_pseudoTLBInit() - We need the system to fill the TLB for us, so that it knows what - happens to its contents. We don't want to edit the TLB ourselves, so - we'll just read random data from every 4k-page in the rom area to have - the system virtualize it entirely. - The index system for TLB entries ensures this process will work for - 128-k or less add-ins. On SH7705 there is a limit, which is 384-k (it - does probably not exist on SH7305) but there is no guarantee that the - system will not go wild after 128-k. -*/ -void mmu_pseudoTLBInit(void) -{ - extern uint32_t romdata; - uint32_t limit = (uint32_t)&romdata; - - uint32_t address = 0x00300000; - - // Access every page to make the system load everything in the TLB (and - // just hope it works and the add-in fits in). - while(address <= limit) - { - *((volatile uint32_t *)address); - address += 0x1000; - } -} diff --git a/src/rtc/rtc_callback.c b/src/rtc/rtc_callback.c deleted file mode 100644 index 775910d..0000000 --- a/src/rtc/rtc_callback.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include -#include - -// Array holding callback informations. -rtc_callback_t cb_array[RTC_CB_ARRAY_SIZE] = { 0 }; -// Callback identifier (unique). -static int unique_id = 1; -// Current RTC interrupt frequency. -static rtc_frequency_t rtc_freq = rtc_freq_none; -// 256-Hz tick count. This counter is stopped when no callback is registered. -static unsigned elapsed256 = 0; - -/* - rtc_cb_update() - After successful registration or deletion of a callback, updates the - RTC interrupt frequency stored in register RCR2. After update, the - interrupt frequency is high enough to handle all callbacks, but nothing - more (so that no time is wasted handling interrupts that occur too - often). -*/ -static void rtc_cb_update(void) -{ - rtc_frequency_t max = rtc_freq_none; - int n; - - for(n = 0; n < RTC_CB_ARRAY_SIZE; n++) if(cb_array[n].id) - { - if(!max || (cb_array[n].freq && cb_array[n].freq < max)) - max = cb_array[n].freq; - } - - if(rtc_freq == max) return; - rtc_freq = max; - - RTC.RCR2->byte = (rtc_freq << 4) | 0x09; -} - -/* - rtc_cb_add() - Registers a new callback for the RTC. Returns the callback id on - success (positive integer), or one of the following error codes: - -1 Array is full - -2 Invalid parameter - The number of repeats may be set to 0, in which case the callback is - called indefinitely until the user calls rtc_cb_end(). -*/ -int rtc_cb_add(rtc_frequency_t freq, void (*function)(void), int repeats) -{ - int n = 0; - if(freq == rtc_freq_none || !function || repeats < 0) return -2; - - while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id) n++; - if(n >= RTC_CB_ARRAY_SIZE) return -1; - - cb_array[n].freq = freq; - cb_array[n].callback = function; - cb_array[n].repeats = repeats; - cb_array[n].id = unique_id++; - - rtc_cb_update(); - - return cb_array[n].id; -} - -/* - rtc_cb_end() - Removes the callback with the given id (as returned by rtc_cb_add()) - from the callback array. -*/ -void rtc_cb_end(int id) -{ - int n = 0; - - while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id != id) n++; - if(n >= RTC_CB_ARRAY_SIZE) return; - - cb_array[n].id = 0; - cb_array[n].freq = rtc_freq_none; - cb_array[n].callback = NULL; - cb_array[n].repeats = 0; - - rtc_cb_update(); -} - -/* - rtc_cb_edit() - Changes information related to a callback. This function returns 0 on - success, or one of the following error codes: - -1 Callback does not exist - -2 Invalid parameters - This function never removes a callback. Call rtc_cb_end() for this. -*/ -int rtc_cb_edit(int id, rtc_frequency_t new_freq, - void (*new_function)(void)) -{ - if(new_freq < 0 || new_freq > 7) return -2; - int n = 0; - - while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id != id) n++; - if(n >= RTC_CB_ARRAY_SIZE) return -1; - - cb_array[n].freq = new_freq; - cb_array[n].callback = new_function; - rtc_cb_update(); - - return 0; -} - -/* - rtc_cb_interrupt() - Handles an RTC interrupt. Calls the RTC callbacks if necessary, and - updates the repeat counts. -*/ -void rtc_cb_interrupt(void) -{ - int n; - - int scales[] = { - 1, // 256 Hz - 4, // 64 Hz - 16, // 16 Hz - 64, // 4 Hz - 128, // 2 Hz - 256, // 1 Hz - 512, // 0.5 Hz - }; - // Adding to elapsed256 the number of 256-Hz ticks that correspond to - // the current interrupt frequency, and rounding the result to a - // multiple of this tick number. - elapsed256 += scales[rtc_freq - 1]; - elapsed256 &= ~(scales[rtc_freq - 1] - 1); - - for(n = 0; n < RTC_CB_ARRAY_SIZE; n++) - { - rtc_callback_t *cb = &cb_array[n]; - if(!cb->id || !cb->freq) continue; - - // Only execute callback when the number of elapsed 256-Hz - // ticks reach a multiple that correspond to the callback - // frequency. - if(elapsed256 & (scales[cb->freq - 1] - 1)) continue; - - if(cb->callback) (*cb->callback)(); - if(cb->repeats) - { - if(cb->repeats == 1) rtc_cb_end(cb->id); - else cb->repeats--; - } - } -} diff --git a/src/rtc/rtc_getTime.c b/src/rtc/rtc_getTime.c deleted file mode 100644 index dab7074..0000000 --- a/src/rtc/rtc_getTime.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include - -/* - integer8(), integer16() [static] - Converts a BCD value to an integer. -*/ -static int integer8(uint8_t bcd) -{ - return (bcd & 0x0f) + 10 * (bcd >> 4); -} -static int integer16(uint16_t bcd) -{ - return (bcd & 0xf) + 10 * ((bcd >> 4) & 0xf) + 100 * ((bcd >> 8) & 0xf) - + 1000 * (bcd >> 12); -} - -/* - rtc_getTime() - Reads the current time from the RTC. There is no guarantee that the - week day will contain a correct value (use the time API for that). -*/ -void rtc_getTime(rtc_time_t *time) -{ - if(!time) return; - - do - { - RTC.RCR1->CF = 0; - - time->seconds = integer8(RTC.time->RSECCNT.byte); - time->minutes = integer8(RTC.time->RMINCNT.byte); - time->hours = integer8(RTC.time->RHRCNT .byte); - time->month_day = integer8(RTC.time->RDAYCNT.byte); - time->month = integer8(RTC.time->RMONCNT.byte); - time->year = integer16(RTC.time->RYRCNT.word); - time->week_day = RTC.time->RWKCNT; - } - while(RTC.RCR1->CF != 0); -} diff --git a/src/rtc/rtc_interrupt.c b/src/rtc/rtc_interrupt.c deleted file mode 100644 index c3e0df6..0000000 --- a/src/rtc/rtc_interrupt.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include -#include - -/* - rtc_periodic_interrupt() - Handles an RTC interrupt by calling the callback. -*/ -void rtc_periodic_interrupt(void) -{ - rtc_cb_interrupt(); - - RTC.RCR2->PEF = 0; -} diff --git a/src/rtc/rtc_setTime.c b/src/rtc/rtc_setTime.c deleted file mode 100644 index 27c8a3a..0000000 --- a/src/rtc/rtc_setTime.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include - -/* - bcd8(), bcd16() [static] - Converts an integer to a BCD value. -*/ -static uint8_t bcd8(int integer) -{ - integer %= 100; - return ((integer / 10) << 4) | (integer % 10); -} -static uint16_t bcd16(int integer) -{ - integer %= 10000; - return (bcd8(integer / 100) << 8) | bcd8(integer % 100); -} - -/* - rtc_setTime() - Sets the time in the RTC registers. The week day is set to 0 if greater - than 6. Other fields are not checked. -*/ -void rtc_setTime(const rtc_time_t *time) -{ - if(!time) return; - int wday = (time->week_day < 7) ? (time->week_day) : (0); - - do - { - RTC.RCR1->CF = 0; - - RTC.time->RSECCNT.byte = bcd8(time->seconds); - RTC.time->RMINCNT.byte = bcd8(time->minutes); - RTC.time->RHRCNT .byte = bcd8(time->hours); - RTC.time->RDAYCNT.byte = bcd8(time->month_day); - RTC.time->RMONCNT.byte = bcd8(time->month); - RTC.time->RYRCNT .word = bcd16(time->year); - RTC.time->RWKCNT = wday; - } - while(RTC.RCR1->CF != 0); -} diff --git a/src/screen/screen_backlight.c b/src/screen/screen_backlight.c deleted file mode 100644 index e344212..0000000 --- a/src/screen/screen_backlight.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include - -/* - screen_setBacklight() - On compatible models, turns on or turns off the backlight. -*/ -void screen_setBacklight(int on) -{ - if(isSH3()) - { - volatile uint8_t *PGDR = (void *)0xa400012c; - if(on) *PGDR |= 0x80; - else *PGDR &= ~0x80; - } - else - { - volatile uint8_t *PNDR = (void *)0xa4050138; - if(on) *PNDR |= 0x10; - else *PNDR &= ~0x10; - } -} - -/* - screen_toggleBacklight() - Changes the backlight state, regardless of its current state. -*/ -void screen_toggleBacklight(void) -{ - if(isSH3()) - { - volatile uint8_t *PGDR = (void *)0xa400012c; - *PGDR ^= 0x80; - } - else - { - volatile uint8_t *PNDR = (void *)0xa4050138; - *PNDR ^= 0x10; - } -} diff --git a/src/screen/screen_display.c b/src/screen/screen_display.c deleted file mode 100644 index 0d76d0e..0000000 --- a/src/screen/screen_display.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -/* - screen_display() - - Displays the given vram on the screen. Only bytes can be transferred - through the screen registers, which is unfortunate because most of the - vram-related operations use longword-base operations. -*/ -void screen_display(const void *ptr) -{ - volatile uint8_t *selector = (void *)0xb4000000; - volatile uint8_t *data = (void *)0xb4010000; - const uint8_t *vram = ptr; - - for(int line = 0; line < 64; line++) - { - // Setting the x-address register. - *selector = 4; - *data = line + 0xc0; - - // Setting Y-Up mode. - *selector = 1; - *data = 1; - - // Setting y-address. - *selector = 4; - *data = 0; - - // Selecting data write register 7 and sending a line's bytes. - // We could loop but I suspect it will be faster to iterate. - *selector = 7; - - /* TODO Manually load the video-ram line into the cache? */ - - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - *data = *vram++; - } -} diff --git a/src/setjmp/setjmp.s b/src/setjmp/setjmp.s deleted file mode 100644 index 463673e..0000000 --- a/src/setjmp/setjmp.s +++ /dev/null @@ -1,76 +0,0 @@ - - .global _setjmp - .global _longjmp - -/* - setjmp() - - This function is implemented using a trick that changes the value of - pr (so that it points just after the call to setjmp()) within the - longjmp() function, which lets the rts function perform the actual - jump. This value is obtained from the save buffer. - - setjmp() returns 0 when called to set up the jump point and a non-zero - value when invoked through a long jump. If 0 is provided as argument to - longjmp(), 1 is returned instead. -*/ -_setjmp: - /* Getting some free space. */ - add #64, r4 - - /* Saving general-purpose registers. */ - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - - /* Saving control and system registers. */ - stc.l sr, @-r4 - stc.l ssr, @-r4 - stc.l spc, @-r4 - stc.l gbr, @-r4 - stc.l vbr, @-r4 - sts.l mach, @-r4 - sts.l macl, @-r4 - sts.l pr, @-r4 - - /* This function always return 0. The cases where setjmp() seems to - return non-zero values, when a long jump has just been performed, are - those when the longjmp() function returns. */ - rts - mov #0, r0 - - - -_longjmp: - /* Restoring the system and control registers. Restoring pr is actually - what performs the jump -- and makes the user program think that - setjmp() has just returned. */ - lds.l @r4+, pr - lds.l @r4+, macl - lds.l @r4+, mach - ldc.l @r4+, vbr - ldc.l @r4+, gbr - ldc.l @r4+, spc - ldc.l @r4+, ssr - ldc.l @r4+, sr - - /* Restoring the general-purpose registers. */ - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - - /* Preventing return value from being 0 (must be at least 1). */ - tst r5, r5 - movt r0 - rts - add r5, r0 diff --git a/src/stdio/snprintf.c b/src/stdio/snprintf.c deleted file mode 100644 index 20c9c9b..0000000 --- a/src/stdio/snprintf.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -/* - snprintf() - Prints to a string with a size limit. -*/ -int snprintf(char *str, size_t size, const char *format, ...) -{ - va_list args; - va_start(args, format); - - int x = __printf(size, format, args); - memcpy(str, __stdio_buffer, x + 1); - - va_end(args); - return x; -} diff --git a/src/stdio/sprintf.c b/src/stdio/sprintf.c deleted file mode 100644 index f0a018e..0000000 --- a/src/stdio/sprintf.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -/* - sprintf() - Prints to a string. -*/ -int sprintf(char *str, const char *format, ...) -{ - va_list args; - va_start(args, format); - - int x = __printf(0, format, args); - memcpy(str, __stdio_buffer, x + 1); - - va_end(args); - return x; -} diff --git a/src/stdio/stdio_format.c b/src/stdio/stdio_format.c deleted file mode 100644 index 5a8ecfb..0000000 --- a/src/stdio/stdio_format.c +++ /dev/null @@ -1,895 +0,0 @@ -#include -#include - -#include -#include -#include - -/* - Internal buffer. - - Using a buffer *really* simplifies everything. But it also has - disadvantages, such as some memory loss and limited output size. - - So, in case we find a possibility to get rid of this buffer, we will - just have to change function character(), which is for now the only - function that directly accesses the buffer. -*/ -char __stdio_buffer[__stdio_buffer_size]; - - - -/* - Composed types for format definition. - - The Format structure handles everything in a format: data type, value, - alternative forms, alignment and character number, precision... there - are mainly a data type (altered by a size option), a value to print - and a number of characters. - - Other options are handled by The FormatFlags enumeration. See the - description of functions __printf() for further description on option - precedence and influence. -*/ - -enum FormatFlags -{ - // Alternatives forms add '0' and '0x' prefixes in octal and - // hexadecimal bases. (#) - Alternative = 1, - // Under specific conditions, zero-padding may be used instead of - // whitespace-padding. (0) - ZeroPadded = 2, - // Left alignment specifies that additional spaces should be added - // after the value instead of before. (-) - LeftAlign = 4, - // In numeric display, this forces a blank sign to be written before - // positive values. ( ) - BlankSign = 8, - // In numeric display, this forces an explicit sign in all cases. This - // option overrides BlankSign. (+) - ForceSign = 16 -}; - -struct Format -{ - // Format type, one of 'diouxXcs' ('eEfFgGaApnm' still to add). - char type; - // Format size, one of 'l', 'h', 'i' ('i' means 'hh'). - char size; - - // Number of characters printed. - int characters; - // Number of digits after the dot. - int precision; - - // Various flags. - enum FormatFlags flags; - - // Value to output. - union - { - // Signed int with formats %c, %d and %i. - signed int _int; - // Unsigned int with formats %o, %u, %x and %X. - unsigned int _unsigned; - // Double with formats %f, %F, %e, %E, %g and %G. -// double _double; - // String pointer with format %s. - const char *_pointer; - }; -}; - - - -//--- -// Static declarations. -//--- - -// Outputs a character in the buffer. Updates counters. -static void character(int c); -// Outputs n timers the given character. -static void character_n(int c, int n); -// Reads a format from the given string pointer address (must begin with '%'). -static struct Format get_format(const char **pointer); -// Computes the number of spaces and zeros to add to the bare output. -static void get_spacing(struct Format format, int *begin_spaces, int *sign, - int *zeros, int length, int *end_spaces); - -static void format_di (struct Format format); -static void format_u (struct Format format); -static void format_oxX (struct Format format); -// static void format_e (struct Format format); -static void format_c (struct Format format); -static void format_s (struct Format format); -static void format_p (struct Format format); - -#define abs(x) ((x) < 0 ? -(x) : (x)) - -// Number of characters currently written. -static size_t written = 0; -// Total number of function calls (characters theoretically written). -static size_t total = 0; -// Maximum number of characters to output. -static size_t max = 0; - - - -/* - character() - Outputs a character to the buffer. This function centralizes all the - buffer interface, so that if we come to remove it for property reasons, - we would just have to edit this function. - - Static variables written and total are both needed, because the - terminating NUL character may be written after the maximum has been - reached. - In other words, when the function ends, we need to have a variable - counting the current position in the buffer (written), and one other - containing the total number of theoretic characters (total) because - these two values may be different. - - Of course the three variables need to be initialized before using this - function. -*/ -static void character(int c) -{ - // If there is space left in the buffer. - if(written < max - 1) __stdio_buffer[written++] = c; - total++; -} - -/* - character_n() - Outputs n times the same character. Thought to be used to output spaces - or zeros without heavy loops. -*/ -static void character_n(int c, int n) -{ - int i = 0; - while(i++ < n) character(c); -} - -/* - get_format() - Reads the format from the given string pointer and returns a - corresponding Format structure. The string pointer points to is also - modified, so that is points to the first character after the format. - This function expects **pointer == '%'. -*/ -static struct Format get_format(const char **pointer) -{ - const char *convspec = "diouxXeEfFgGaAcspnm"; - struct Format format; - - const char *string = *pointer, *ptr; - int c, i; - - // Moving the string pointer after the '%' character. - string++; - - // Initializing structure. - format.type = 0; - format.size = 0; - format.flags = 0; - // Initializing digit counts. - format.characters = -1; - format.precision = -1; - - // Parsing the format string. Testing each character until a - // conversion specifier is found. - while((c = *string)) - { - // Looking for a conversion specifier. - ptr = strchr(convspec, c); - if(ptr) - { - format.type = *ptr; - break; - } - - // Looking for a left precision string (number of digits before - // the dot), introduced by a non-null digit. - if(c >= '1' && c <= '9') - { - format.characters = 0; - for(i = 0; i < 9 && isdigit(*string); string++) - { - format.characters *= 10; - format.characters += *string - '0'; - } - - // As pointer is now pointing to the next character, - // we want to try tests again from the beginning. - continue; - } - - // Looking for a right precision string (number of digits after - // the dot), introduced by a point. - if(c == '.') - { - string++; - if(!isdigit(*string)) continue; - - format.precision = 0; - for(i = 0; i < 9 && isdigit(*string); string++) - { - format.precision *= 10; - format.precision += *string - '0'; - } - - // As pointer is now pointing on the next character, - // we want to try tests again from the beginning. - continue; - } - - // Handling predefined characters. - switch(*string) - { - // Length modifiers. - case 'h': - format.size = 'h' + (format.size == 'h'); - break; - case 'l': - case 'L': - case 'z': - case 't': - format.size = *string; - break; - - // Flags. - case '#': - format.flags |= Alternative; - break; - case '0': - format.flags |= ZeroPadded; - break; - case '-': - format.flags |= LeftAlign; - break; - case ' ': - format.flags |= BlankSign; - break; - case '+': - format.flags |= ForceSign; - break; - } - - string++; - } - - // If the format hasn't ended, the type attribute is left to zero and - // the main loop will handle failure and break. Nothing has to be done - // here. - - *pointer = string + 1; - return format; -} - -/* - get_spacing() - Computes the arrangement of beginning spaces, sign, zeros, pure value - and ending spaces in formats. - This formatting follows a recurrent model which is centralized in this - function. Note that you can't have `begin_spaces` and `end_spaces` - both non-zero: at least one is null. -*/ -static void get_spacing(struct Format format, int *begin_spaces, int *sign, - int *zeros, int length, int *end_spaces) -{ - // Using a list of types involving a sign. - const char *signed_types = "dieEfFgGaA"; - int spaces; - // Digits represents pure output + zeros (don't mix up with the *real* - // displayed digits). - int digits; - int left = format.flags & LeftAlign; - - // Getting the total number of digits. - switch(format.type) - { - // In integer display, the number of digits output is specified in the - // precision. - case 'd': - case 'i': - case 'u': - digits = format.precision; - if(digits < length) digits = length; - break; - - // Binary display has prefixes such as '0' and '0x'. - case 'o': - case 'x': - case 'X': - digits = format.precision; - if(digits == -1) digits = length; - - if(format.flags & Alternative) - { - int hexa = (format.type == 'x' || format.type == 'X'); - digits += 1 + hexa; - length += 1 + hexa; - } - if(digits < length) digits = length; - break; - - // Other formats do not have additional zeros. - default: - digits = length; - break; - } - - if(sign) - { - if(strchr(signed_types, format.type)) - { - if(format.flags & BlankSign) *sign = ' '; - // Option '+' overrides option ' '. - if(format.flags & ForceSign) *sign = '+'; - // And of course negative sign overrides everything! - if(format.type == 'd' || format.type == 'i') - { - if(format._int < 0) *sign = '-'; - } -// else if(format._double < 0) *sign = '-'; - - } - else *sign = 0; - } - - // Computing the number of spaces. - spaces = format.characters - digits; - // Computing the number of zeros. - *zeros = digits - length; - - // Removing a space when a sign appears. - if(sign && *sign) spaces--; - - // Option '0' translates spaces to zeros, but only if no precision is - // specified; additionally, left alignment overrides zero-padding. - if(!left && format.precision == -1 && format.flags & ZeroPadded) - { - *zeros += spaces; - spaces = 0; - } - - // Setting the correct spaces number to the computed value, depending - // on the left alignment parameter. - *begin_spaces = left ? 0 : spaces; - *end_spaces = left ? spaces : 0; -} - -/* - __printf() - - Basic buffered formatted printing function. Fully-featured, so that - any call to a printf()-family function can be performed by __printf(). - - It always returns the number of characters of the theoretic formatted - output. The real output may be limited in size by the given size - argument when working with nprintf()-family functions, or the internal - buffer itself. - - The Flags structure isn't necessary, but it simplifies a lot format - argument handling (because flag effects depend on format type, which - is unknown when the flags are read). Also, length modifiers 'hh' is - stored as 'i' to simplify structure handling. 'll' is not supported. - Support for format '%lf' (C99) is planned. - - Generic information on options precedence and influence. - - Number of characters and precision represent different lengths - depending on the data type. - - '#' is independent. - - '+' overrides ' '. - - In integer display, '0' replaces spaces to zeros, only if no - precision (decimal digit number) is specified. - - '-' also overrides it, forcing whitespaces to be written at the end. - - Limits of function. - - Internal buffer size (there should be a loop to allow larger data). - - Precision values (format %a.b) are limited to 127. - - Unsupported features. - - ''' (single quote) (thousands grouping) - - 'I' (outputs locale's digits (glibc 2.2)) - - Length modifiers 'll' and 'q' (libc 5 and 4.4 BSD) - - This is not really a feature but incorrect characters in formats are - ignored and don't invalidate the format. -*/ -int __printf(size_t size, const char *string, va_list args) -{ - struct Format format; - - // Avoiding overflow by adjusting the size argument. - if(!size || size > __stdio_buffer_size) size = __stdio_buffer_size; - - // Initializing character() variables. - written = 0; - total = 0; - max = size; - - // Parsing the format string. At each iteration, a literal character, a - // '%%' identifier or a format is parsed. - while(*string) - { - // Literal text. - if(*string != '%') - { - character(*string++); - continue; - } - - // Literal '%'. - if(string[1] == '%') - { - string += 2; - character('%'); - continue; - } - - // Getting the format. - format = get_format(&string); - if(!format.type) break; - - /* Some debugging... - printf( - "Format found :%s%c%c, options %d, and %d.%d " - "digits\n", - format.size ? " " : "", - format.size ? format.size : ' ', - format.type, - format.flags, - format.digits, - format.mantissa - ); */ - - switch(format.type) - { - // Signed integers. - case 'd': - case 'i': - format._int = va_arg(args, signed int); - - // Reducing value depending on format size. - if(format.size == 'h') format._int &= 0x0000ffff; - if(format.size == 'i') format._int &= 0x000000ff; - - format_di(format); - break; - - // Unsigned integers. - case 'u': - format._unsigned = va_arg(args, unsigned int); - format_u(format); - break; - case 'o': - case 'x': - case 'X': - format._unsigned = va_arg(args, unsigned int); - format_oxX(format); - break; - -/* // Exponent notation. - case 'e': - case 'E': - format._double = va_arg(args, double); - format_e(format); - break; -*/ - // Characters. - case 'c': - format._int = va_arg(args, signed int) & 0xff; - format_c(format); - break; - - // Strings. - case 's': - format._pointer = va_arg(args, const char *); - format_s(format); - break; - - // Pointers. - case 'p': - format._unsigned = va_arg(args, unsigned int); - format_p(format); - break; - - // Character counter. - case 'n': - *va_arg(args, int *) = written; - break; - } - } - - // Adding a terminating NUL character. Function character() should have - // left an empty byte for that. - __stdio_buffer[written] = 0; - return total; -} - -/* - format_di() - - Subroutine itoa(). Writes the given signed integer to the internal - buffer, trough function character(). - It is used by conversion specifiers 'd' and 'i'. - Options '#' and '0' have no effect. -*/ -static void format_di(struct Format format) -{ - // In integer display, character number includes pure digits and - // additional zeros and spacing. - // The precision represents the number of digits (pure digits and - // zeros) to print. - // For example: ' 0004', pure digits: 1, digits: 4, characters: 5. - - int sign = 0; - signed int x = format._int; - // Using integers to store the number pure digits and additional spaces - // and zeros. - int bspaces, zeros, digits = 0, espaces; - // Using a multiplier to output digit in the correct order. - int multiplier = 1; - - // Returning if the argument is null with an explicit precision of - // zero, but only if there are no spaces. - if(!x && format.characters == -1 && !format.precision) return; - - - - //--- - // Computations. - //--- - - // Computing the number of digits and the multiplier. - x = abs(format._int); - if(!x) digits = 1; - else while(x) - { - digits++; - x /= 10; - if(x) multiplier *= 10; - } - - // Getting the corresponding spacing. - get_spacing(format, &bspaces, &sign, &zeros, digits, &espaces); - - - - //--- - // Output. - //--- - - character_n(' ', bspaces); - if(sign) character(sign); - character_n('0', zeros); - - x = abs(format._int); - // Writing the pure digits, except if the value is null with an - // explicit precision of zero. - if(x || format.precision) while(multiplier) - { - character((x / multiplier) % 10 + '0'); - multiplier /= 10; - } - - character_n(' ', espaces); -} - -/* - format_u() - Unsigned integers in base 10. Options ' ', '+' and '#' have no effect. -*/ -static void format_u(struct Format format) -{ - int bspaces, zeros, digits = 0, espaces; - int x = format._unsigned; - int multiplier = 1; - - // Computing number of digits. - if(!x) digits = 1; - else while(x) - { - digits++; - x /= 10; - if(x) multiplier *= 10; - } - - get_spacing(format, &bspaces, NULL, &zeros, digits, &espaces); - - //--- - // Output. - //--- - - character_n(' ', bspaces); - character_n('0', zeros); - - x = format._unsigned; - while(multiplier) - { - character('0' + (x / multiplier) % 10); - multiplier /= 10; - } - - character_n(' ', espaces); -} - -/* - format_oxX() - Unsigned integers in base 8 or 16. - Since the argument is unsigned, options ' ' and '+' have no effect. - Option '#' adds prefix '0' in octal or '0x' in hexadecimal. -*/ -static void format_oxX(struct Format format) -{ - // In unsigned display, the digit number specifies the minimal number - // of characters that should be output. If the prefix (alternative - // form) is present, it is part of this count. - // Integer part and decimal part digit numbers behave the same way as - // in signed integer display. - - // Using integers to store the number of digits, zeros and spaces. - int bspaces, zeros, digits = 0, espaces; - unsigned int x = format._unsigned; - int multiplier = 0, shift, mask; - int c, disp; - - - - //--- - // Computations. - //--- - - shift = (format.type == 'o') ? (3) : (4); - mask = (1 << shift) - 1; - disp = (format.type == 'x') ? (39) : (7); - - // Computing number of digits. - if(!x) digits = 1; - else while(x) - { - digits++; - x >>= shift; - if(x) multiplier += shift; - } - - // Getting the spacing distribution. - get_spacing(format, &bspaces, NULL, &zeros, digits, &espaces); - - - - //--- - // Output. - //--- - - character_n(' ', bspaces); - x = format._unsigned; - - // Writing the alternative form prefix. - if(format.flags & Alternative && x) - { - character('0'); - if(format.type != 'o') character(format.type); - } - - character_n('0', zeros); - - // Extracting the digits. - while(multiplier >= 0) - { - c = (x >> multiplier) & mask; - c += '0' + (c > 9) * disp; - - character(c); - multiplier -= shift; - } - - character_n(' ', espaces); -} - -/* - format_e() - Exponent notation. Option '#' has no effect. - -static void format_e(struct Format format) -{ - // In exponent display, the precision is the number of digits after the - // dot. - - // Using an integer to store the number exponent. - int exponent = 0; - // Using a double value for temporary computations, and another to - // store the format parameter. - double tmp = 1, x = format._double; - // Using spacing variables. Default length is for '0.e+00'; - int bspaces, zeros, sign, length = 6, espaces; - // Using an iterator and a multiplier. - int i, mul; - - - - //--- - // Computations. - //--- - - // Computing the exponent. For positive exponents, increasing until - // the temporary value gets greater than x. - if(x > 1) - { - // Looping until we haven't reached a greater exponent. - while(tmp < x) - { - // Incrementing the exponent. - exponent++; - // Multiplying the test value. - tmp *= 10; - } - // Removing an additional incrementation. - exponent--; - } - // For negative exponents, decreasing until it's lower. - else while(tmp > x) - { - // Decrementing the exponent. - exponent--; - // Dividing the test value. - tmp *= 0.1; - } - - // Adding a character if the exponent is greater that 100. - if(exponent >= 100) length++; - // Adding another one if it's greater than 1000. - if(exponent >= 1000) length++; - - // Adjusting the format precision, defaulting to 6. - if(format.precision == -1) format.precision = 6; - // Adding the decimal digits. - length += format.precision; - - // Getting the space repartition. - get_spacing(format, &bspaces, &sign, &zeros, length, &espaces); - - - - //--- - // Output. - //--- - - // Writing the beginning whitespaces. - character_n(' ', bspaces); - // Writing the sign if existing. - if(sign) character(sign); - // Writing the zeros. - character_n('0', zeros); - - // Initializing x. - x = abs(format._double) / tmp; - // Writing the first digit. - character(x + '0'); - character('.'); - - // Writing the decimal digits. - for(i = 0; i < format.precision; i++) - { - // Multiplying x by 10 and getting rid of the previous digit. - x = (x - (int)x) * 10; - // Writing the current digit. - character(x + '0'); - } - - // Writing the exponent letter and its sign. - character(format.type); - character(exponent < 0 ? '-' : '+'); - - // Getting a positive exponent. - exponent = abs(exponent); - - // Using a multiplier for the exponent. - if(exponent >= 1000) mul = 1000; - else if(exponent >= 100) mul = 100; - else mul = 10; - - // Writing the exponent characters. - while(mul) - { - // Writing the next character. - character((exponent / mul) % 10 + '0'); - // Dividing the multiplier. - mul *= 0.1; - } - - // Writing the ending whitespaces if left-aligned. - character_n(' ', espaces); -} -*/ - -/* - format_c() - Character output. Only handles left alignment and spacing. - Options '#', '0', ' ' and '+', as well as mantissa digit number, have - no effect. -*/ -static void format_c(struct Format format) -{ - // In character display, the digit number represents the number of - // characters written, including the argument and additional - // whitespaces. - - int spaces = format.characters - 1; - int left = format.flags & LeftAlign; - - if(!left) character_n(' ', spaces); - character(format._int & 0xff); - if(left) character_n(' ', spaces); -} - -/* - format_s() - String output. Spaces if needed. -*/ -void format_s(struct Format format) -{ - // In string display, the character number specify the minimum size of - // output (padded with whitespaces if needed) and the precision - // specify the maximum number of string characters output. - - int string = format.precision; - int spaces; - - const char *str = format._pointer; - int length, i; - int left = format.flags & LeftAlign; - - // Computing length of string and number of whitespaces. - length = strlen(str); - if(string > length || string == -1) string = length; - spaces = format.characters - string; - - if(!left) character_n(' ', spaces); - for(i = 0; i < string; i++) character(str[i]); - if(left) character_n(' ', spaces); -} - -/* - format_p() - Pointer output. Simple hexadecimal dump. Prints "(nil)" if pointer is - NULL. -*/ -void format_p(struct Format format) -{ - // Pointer display falls back to %#08x in the pointer is non-null, - // "(nil)" otherwise. - - unsigned int x = format._unsigned; - int bspaces, zeros, digits = 0, espaces; - int c, i; - - digits = x ? 10 : 5; - get_spacing(format, &bspaces, NULL, &zeros, digits, &espaces); - - character_n(' ', bspaces); - character_n('0', zeros); - - if(x) - { - character('0'); - character('x'); - for(i = 0; i < 8; i++) - { - c = x >> 28; - c += '0' + 39 * (c > 9); - character(c); - x <<= 4; - } - } - else - { - character('('); - character('n'); - character('i'); - character('l'); - character(')'); - } - - character_n(' ', espaces); -} diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c deleted file mode 100644 index 0bfafd4..0000000 --- a/src/stdio/vsnprintf.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include - -/* - vsnprintf() - The most generic formatted printing function around there. -*/ -int vsnprintf(char *str, size_t size, const char *format, va_list args) -{ - int x = __printf(size, format, args); - memcpy(str, __stdio_buffer, x + 1); - - return x; -} diff --git a/src/stdio/vsprintf.c b/src/stdio/vsprintf.c deleted file mode 100644 index 0571fc0..0000000 --- a/src/stdio/vsprintf.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include - -/* - vsprintf() - Prints to a string from an argument list. -*/ -int vsprintf(char *str, const char *format, va_list args) -{ - int x = __printf(0, format, args); - memcpy(str, __stdio_buffer, x + 1); - - return x; -} diff --git a/src/stdlib/calloc.c b/src/stdlib/calloc.c deleted file mode 100644 index e1b9ac9..0000000 --- a/src/stdlib/calloc.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include - -/* - calloc() - Allocates 'n' elements of size 'size' and wipes the memory area. - Returns NULL on error. -*/ -void *calloc(size_t n, size_t size) -{ - void *ptr = malloc(n * size); - return ptr ? memset(ptr, 0, n * size) : NULL; -} diff --git a/src/stdlib/free.c b/src/stdlib/free.c deleted file mode 100644 index b967fda..0000000 --- a/src/stdlib/free.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#pragma GCC diagnostic ignored "-Wunused-parameter" - -#ifndef GINT_NO_SYSCALLS -#include -#endif - -/* - free() - Frees a memory block allocated by malloc(), calloc() or realloc(). -*/ -void free(void *ptr) -{ - // Just to be sure. - if(!ptr) return; - - #ifndef GINT_NO_SYSCALLS - __free(ptr); - #endif -} - -#pragma GCC diagnostic pop diff --git a/src/stdlib/malloc.c b/src/stdlib/malloc.c deleted file mode 100644 index 3b7724a..0000000 --- a/src/stdlib/malloc.c +++ /dev/null @@ -1,27 +0,0 @@ -#include - -/* - malloc() - Allocates 'size' bytes and returns a pointer to a free memory area. - Returns NULL on error. -*/ - -#ifndef GINT_NO_SYSCALLS -#include - -void *malloc(size_t size) -{ - return __malloc(size); -} - -#else - -#pragma GCC diagnostic ignored "-Wunused-parameter" -void *malloc(size_t size) -{ - return NULL; -} -#pragma GCC diagnostic pop - -#endif - diff --git a/src/stdlib/realloc.c b/src/stdlib/realloc.c deleted file mode 100644 index 7c30537..0000000 --- a/src/stdlib/realloc.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -/* - realloc() - Reallocates a memory block and moves its data. -*/ - -#ifndef GINT_NO_SYSCALLS -#include - -void *realloc(void *ptr, size_t size) -{ - return __realloc(ptr, size); -} - -#else - -#pragma GCC diagnostic ignored "-Wunused-parameter" -void *realloc(void *ptr, size_t size) -{ - return NULL; -} -#pragma GCC diagnostic pop - -#endif diff --git a/src/stdlib/stdlib_abs.c b/src/stdlib/stdlib_abs.c deleted file mode 100644 index 3e4c4f8..0000000 --- a/src/stdlib/stdlib_abs.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#undef abs -#undef labs - -int abs(int x) -{ - return (x < 0) ? (-x) : x; -} - -long labs(long x) -{ - return (x < 0) ? (-x) : x; -} diff --git a/src/stdlib/stdlib_div.c b/src/stdlib/stdlib_div.c deleted file mode 100644 index 77f22a1..0000000 --- a/src/stdlib/stdlib_div.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -/* - div() - Computes the integer division of numerator by denominator. -*/ -div_t div(int numerator, int denominator) -{ - div_t result; - - result.quot = numerator / denominator; - result.rem = numerator - result.quot * denominator; - - return result; -} - -/* - ldiv() - Computes the integer division of two long integers. -*/ -ldiv_t ldiv(long numerator, long denominator) -{ - ldiv_t result; - - result.quot = numerator / denominator; - result.rem = numerator - result.quot * denominator; - - return result; -} diff --git a/src/stdlib/stdlib_rand.c b/src/stdlib/stdlib_rand.c deleted file mode 100644 index 6afcc10..0000000 --- a/src/stdlib/stdlib_rand.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -static uint32_t seed = 1; - -void srand(unsigned int new_seed) -{ - seed = new_seed; -} - -int rand(void) -{ - seed = 16807 * seed; - uint32_t top = ((uint32_t)1 << 31) - 1; - while(seed >= top) seed -= top; - /* TODO Or maybe seed = (16807 * seed) % ((1 << 31) - 1); */ -// seed = seed * 1103515245 + 12345; - return seed & 0x7fffffff; -} diff --git a/src/string/memchr.c b/src/string/memchr.c deleted file mode 100644 index e7ad19a..0000000 --- a/src/string/memchr.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -/* - memchr() O(byte_count) - Looks for a byte in a memory area. Returns the address of the first - occurrence if found, NULL otherwise. -*/ -void *memchr(const void *area, int byte, size_t byte_count) -{ - const uint8_t *mem = area; - - while(byte_count--) - { - if(*mem == byte) return (void *)mem; - mem++; - } - - return NULL; -} diff --git a/src/string/memcmp.c b/src/string/memcmp.c deleted file mode 100644 index a862d3b..0000000 --- a/src/string/memcmp.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include - -int raw_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t byte_count); - -/* - memcmp() O(byte_count) - Compares two memory areas. Returns 0 if all bytes are equal in both - areas, a negative number if the first unequal byte is lower in the - first area, and a positive number otherwise. - A smart comparison is performed when possible. -*/ -int memcmp(const void *area1, const void *area2, size_t byte_count) -{ - const uint8_t *mem1 = (const uint8_t *)area1; - const uint8_t *mem2 = (const uint8_t *)area2; - - // Trying to do long-based comparisons. - if(((intptr_t)area1 & 3) == ((intptr_t)area2 & 3)) - { - // Getting to a 4-byte offset. - while((intptr_t)mem1 & 3) - { - if(*mem1 != *mem2) return *mem1 - *mem2; - mem1++, mem2++; - byte_count--; - } - - // Testing groups of four bytes. - while(byte_count >= 4) - { - uint32_t long1 = *((uint32_t *)mem1); - uint32_t long2 = *((uint32_t *)mem2); - if(long1 != long2) return raw_cmp(mem1, mem2, 4); - mem1 += 4, mem2 += 4; - byte_count -= 4; - } - - // Testing the last bytes. - return raw_cmp(mem1, mem2, byte_count); - } - - // Well, maybe we can do a word-based operation? - else if(((intptr_t)area1 & 1) == ((intptr_t)area2 & 3)) - { - // Getting to the word offset. - if((intptr_t)mem1 & 1) - { - if(*mem1 != *mem2) return *mem1 - *mem2; - mem1++, mem2++; - byte_count--; - } - - // Testing groups of two bytes. - while(byte_count >= 2) - { - uint16_t word1 = *((uint16_t *)mem1); - uint16_t word2 = *((uint16_t *)mem2); - if(word1 != word2) return raw_cmp(mem1, mem2, 2); - mem1 += 2, mem2 += 2; - byte_count -= 2; - } - - // Testing the last byte. - if(!byte_count) return 0; - return *mem1 - *mem2; - } - - // That's too bad, we'll have to compare everything manually. - else return raw_cmp(mem1, mem2, byte_count); -} - -int raw_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t byte_count) -{ - while(byte_count) - { - if(*mem1 != *mem2) return *mem1 - *mem2; - mem1++; - mem2++; - byte_count--; - } - - return 0; -} diff --git a/src/string/memcpy.c b/src/string/memcpy.c deleted file mode 100644 index 28a5da1..0000000 --- a/src/string/memcpy.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -/* - memcpy() O(n) - Copies a memory area. A smart copy is performed if possible. -*/ -void *memcpy(void *d, const void *s, size_t n) -{ - uint8_t *dest = (uint8_t *)d; - const uint8_t *src = (const uint8_t *)s; - - // A long-based copy needs the source and destination to be 4-aligned - // at the same time. - if(((intptr_t)dest & 3) == ((intptr_t)src & 3)) - { - // Getting to a long offset. - while((intptr_t)dest & 3) - { - *dest++ = *src++; - n--; - } - - // Copying groups of four bytes. - while(n >= 4) - { - *((uint32_t *)dest) = *((const uint32_t *)src); - - dest += 4, src += 4; - n -= 4; - } - - // Ending the copy. - while(n) - { - *dest++ = *src++; - n--; - } - } - - // Or we could try a word-based copy. - else if(((intptr_t)dest & 1) == ((intptr_t)src & 1)) - { - // Getting to a word offset. - if((intptr_t)dest & 1) - { - *dest++ = *src++; - n--; - } - - // Copying groups of two bytes. - while(n >= 2) - { - *((uint16_t *)dest) = *((const uint16_t *)src); - - dest += 2, src += 2; - n -= 2; - } - - // Ending the copy. - while(n) - { - *dest++ = *src++; - n--; - } - } - - // In some cases we can just perform a raw copy. - else while(n) - { - *dest++ = *src++; - n--; - } - - return d; -} diff --git a/src/string/memset.c b/src/string/memset.c deleted file mode 100644 index 4843e3a..0000000 --- a/src/string/memset.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -/* - memset() O(byte_count) - Sets the contents of a memory area. A smart copy is performed. -*/ -void *memset(void *d, int byte, size_t byte_count) -{ - uint8_t *dest = (uint8_t *)d; - unsigned short word = (byte << 8) | byte; - unsigned int longword = (word << 16) | word; - - // When the area is small, simply copying using byte operations. The - // minimum length used for long operations must be at least 3. - if(byte_count < 8) - { - while(byte_count) - { - *dest++ = byte; - byte_count--; - } - - return d; - } - - // Reaching a long offset. - while((intptr_t)dest & 3) - { - *dest++ = byte; - byte_count--; - } - // Copying using long operations. - while(byte_count >= 4) - { - *((uint32_t *)dest) = longword; - dest += 4; - byte_count -= 4; - } - // Ending the copy. - while(byte_count) - { - *dest++ = byte; - byte_count--; - } - - return d; -} diff --git a/src/string/strchr.c b/src/string/strchr.c deleted file mode 100644 index 7954fcf..0000000 --- a/src/string/strchr.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -/* - strchr - Searches a character in a string. -*/ -const char *strchr(const char *str, int value) -{ - while(*str && *str != value) str++; - return *str ? str : NULL; -} diff --git a/src/string/strcmp.c b/src/string/strcmp.c deleted file mode 100644 index 36971a4..0000000 --- a/src/string/strcmp.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -/* - strcmp() O(max(len(str1), len(str2))) - Compares two strings. Returns 0 if they are identical, a negative - number if the first unequal byte is lower in str1 than in str2, and a - positive number otherwise. -*/ -int strcmp(const char *str1, const char *str2) -{ - while(*str1 && *str2 && *str1 == *str2) - { - str1++; - str2++; - } - - return *str1 - *str2; -} diff --git a/src/string/strcpy.c b/src/string/strcpy.c deleted file mode 100644 index 7659120..0000000 --- a/src/string/strcpy.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -/* - strcpy() - Copies a string to another. -*/ -char *strcpy(char *destination, const char *source) -{ - size_t length = strlen(source); - return memcpy(destination, source, length); -} diff --git a/src/string/strlen.c b/src/string/strlen.c deleted file mode 100644 index 7b5a9a1..0000000 --- a/src/string/strlen.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -/* - strlen() - Returns the length of a string. -*/ -size_t strlen(const char *str) -{ - int len = 0; - while(str[len]) len++; - return len; -} diff --git a/src/string/strncpy.c b/src/string/strncpy.c deleted file mode 100644 index 98422fa..0000000 --- a/src/string/strncpy.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -/* - strncpy() - Copies part of a string to another. -*/ -char *strncpy(char *destination, const char *source, size_t size) -{ - size_t length = strlen(source); - - if(length >= size) - { - return memcpy(destination, source, size); - } - else - { - memset(destination + length, 0, size - length); - return memcpy(destination, source, length); - } -} diff --git a/src/string/strnlen.c b/src/string/strnlen.c deleted file mode 100644 index 57d1344..0000000 --- a/src/string/strnlen.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -/* - strnlen() O(len(str)) - Returns the minimum of the length of the string and n. This function - never access more than n bytes at the beginning of the string. -*/ -size_t strnlen(const char *str, size_t n) -{ - size_t len = 0; - while(len < n && str[len]) len++; - return len; -} diff --git a/src/tales/dprint.c b/src/tales/dprint.c deleted file mode 100644 index cf3c4e8..0000000 --- a/src/tales/dprint.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include - -/* - dprint() - Prints a formatted string. Works the same as printf(). -*/ -void dprint(int x, int y, const char *format, ...) -{ - va_list args; - - va_start(args, format); - __printf(0, format, args); - va_end(args); - - dtext(x, y, __stdio_buffer); -} diff --git a/src/tales/dtext.c b/src/tales/dtext.c deleted file mode 100644 index 22e7b59..0000000 --- a/src/tales/dtext.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -/* - dtext() - Prints the given string, without any analysis. -*/ -void dtext(int x, int y, const char *str) -{ - render(x, y, str, operate_mono); -} diff --git a/src/tales/gprint.c b/src/tales/gprint.c deleted file mode 100644 index 8f58f29..0000000 --- a/src/tales/gprint.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include - -/* - gprint() - Prints a formatted string. Works the same as printf(). -*/ -void gprint(int x, int y, const char *format, ...) -{ - va_list args; - - va_start(args, format); - __printf(0, format, args); - va_end(args); - - gtext(x, y, __stdio_buffer); -} diff --git a/src/tales/gtext.c b/src/tales/gtext.c deleted file mode 100644 index 118aafd..0000000 --- a/src/tales/gtext.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -/* - gtext() - Prints the given raw string. -*/ -void gtext(int x, int y, const char *str) -{ - render(x, y, str, operate_gray); -} diff --git a/src/tales/tales_configuration.c b/src/tales/tales_configuration.c deleted file mode 100644 index 6f099cc..0000000 --- a/src/tales/tales_configuration.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -/* - text_configure() - Sets the font and mode to use for the following print operations. -*/ -void text_configure(font_t *next_font, color_t next_operator) -{ - extern font_t gint_font_system; - if(next_font) font = next_font; - else font = &gint_font_system; - - operator = next_operator; -} diff --git a/src/tales/tales_gray.c b/src/tales/tales_gray.c deleted file mode 100644 index 10589b1..0000000 --- a/src/tales/tales_gray.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include - -void operate_gray(OPERATE_ARGS) -{ - if(x < 0) return; - - int start = (y < 0) ? (-y) : (0); - size_t vram_offset = (x >> 5) + ((y + start) << 2); - uint32_t *light = (uint32_t *)gray_lightVRAM() + vram_offset; - uint32_t *dark = (uint32_t *)gray_darkVRAM() + vram_offset; - uint32_t op, old_light; - - for(int i = start; i < height; i++) - { - op = operators[i]; - - switch(operator) - { - case color_white: - *light &= ~op; - *dark &= ~op; - break; - case color_light: - *light |= op; - *dark &= ~op; - break; - case color_dark: - *light &= ~op; - *dark |= op; - break; - case color_black: - *light |= op; - *dark |= op; - break; - case color_none: - return; - - case color_invert: - *light ^= op; - *dark ^= op; - break; - case color_lighten: - old_light = *light; - *light &= *dark | ~op; - *dark = (old_light | ~op) & (op ^ *dark); - break; - case color_lighten2: - *dark &= *light | ~op; - *light &= ~op; - break; - case color_darken: - old_light = *light; - *light |= *dark & op; - *dark = (old_light & op) | (op ^ *dark); - break; - case color_darken2: - *dark |= *light | op; - *light |= op; - break; - } - - light += 4; - dark += 4; - } -} diff --git a/src/tales/tales_internals.c b/src/tales/tales_internals.c deleted file mode 100644 index f1d6a99..0000000 --- a/src/tales/tales_internals.c +++ /dev/null @@ -1,283 +0,0 @@ -#include -#include -#include -#include -#include - -/* Put these in gint's uninitialized bss section so that text rendering can be - used before the library is fully initialized */ -__attribute__((section(".gint.bss"))) font_t *font = NULL; -__attribute__((section(".gint.bss"))) color_t operator; - -/* - getCharacterIndex() - Returns the index of a character in a font data area depending on the - font format and the size of the characters. Returns the index in the - data area, as long array, or -1 when the character does not belong to - the font format set. -*/ -int getCharacterIndex(int c) -{ - const char *data = (const char *)&font->glyphs; - int index, current; - int width, bits; - size_t offset; - - c &= 0x7f; - - - - // Getting the character index in the glyph array. - - if(font->format == font_format_ascii) index = c; - else if(font->format == font_format_print) index = c - 32; - - else switch(font->format) - { - case font_format_numeric: - if(!isdigit(c)) return -1; - index = c - '0'; - break; - case font_format_lower: - if(!islower(c)) return -1; - index = c - 'a'; - break; - case font_format_upper: - if(!isupper(c)) return -1; - index = c - 'A'; - break; - case font_format_letters: - if(!isalpha(c)) return -1; - index = c - 'A' - ('a' - 'Z') * (c >= 'a'); - break; - case font_format_common: - if(!isalnum(c)) return -1; - index = c - '0' - ('A' - '9') * (c >= 'A') - - ('a' - 'Z') * (c >= 'a'); - break; - case font_format_unknown: - default: - return -1; - } - - - - // Reaching the character offset. - - current = index & ~7; - offset = font->index[current >> 3]; - - while(current < index) - { - width = data[offset << 2]; - bits = font->data_height * width + 8; - - offset += (bits + 31) >> 5; - current++; - } - - return offset; -} - -/* - operate() - Operates on the vram using the given operators. The x-coordinate should - be a multiple of 32. There should be `height` operators. -*/ -void operate_mono(OPERATE_ARGS) -{ - if(x < 0) return; - - uint32_t *vram = display_getCurrentVRAM(); - int start = (y < 0) ? (-y) : (0); - uint32_t *video = vram + (x >> 5) + ((y + start) << 2); - - switch(operator) - { - case color_white: - for(int i = start; i < height; i++) - { - *video &= ~operators[i]; - video += 4; - } - break; - - case color_black: - for(int i = start; i < height; i++) - { - *video |= operators[i]; - video += 4; - } - break; - - case color_invert: - for(int i = start; i < height; i++) - { - *video ^= operators[i]; - video += 4; - } - break; - - default: return; - } -} - -/* - update() - Updates the operators using the given glyph. The operation will not be - complete if there are not enough bits available in the operator data. - In this case the offset will become negative, which means that the - calling procedure has to call operate() and re-call update(). - `available` represents the number of free bits in the operators (lower - bits). - Returns the number of bits available after the operation. If it's - negative, call operate() and update() again. -*/ -int update(uint32_t *operators, int height, int available, uint32_t *glyph) -{ - // Glyph width. - int width = glyph[0] >> 24; - int i; - - // The glyph mask extracts 'width' bits at the left. The partial mask - // is used when there are less than 'width' bits available in the - // current data longword. - uint32_t glyph_mask = 0xffffffff << (32 - width); - uint32_t partial_mask; - - int shift; - uint32_t line; - - // Current data longword, next data array index, and number of bits - // still available in 'data'. - uint32_t data = glyph[0] << 8; - int data_index = 1; - int bits_available = 24; - - for(i = 0; i < height; i++) - { - shift = 32 - available; - - // Getting the next 'width' bits. In some cases these bits will - // intersect two different longs... - line = data & glyph_mask; - line = (shift >= 0) ? (line >> shift) : (line << -shift); - operators[i] |= line; - - data <<= width; - bits_available -= width; - - // ... continue looping until they do. - if(bits_available >= 0) continue; - - // Computing a special mask that extracts just the number of - // bits missing, and loading a new data longword. - partial_mask = 0xffffffff << (32 + bits_available); - data = glyph[data_index++]; - shift += width + bits_available; - - // In case this condition is not verified, the program invokes - // undefined behavior because of the bit shift. Anyway, it - // means that the end of the end of the operators was reached, - // in which case the function should not continue writing. - if(shift <= 31) - { - line = data & partial_mask; - line = (shift >= 0) ? (line >> shift) : - (line << -shift); - operators[i] |= line; - } - - data <<= -bits_available; - bits_available += 32; - } - - return available - width; -} - -/* - render() - Renders text without any formatting analysis, using the given operation - function. -*/ -void render(int x, int y, const char *str, void (*op)(OPERATE_ARGS)) -{ - if(!font || font->magic != 0x01) return; - - // Operator data, and number of available bits in the operators (which - // is the same for all operators, since they are treated equally). - uint32_t *operators; - int available; - - // Raw glyph data, each glyph being represented as one or several - // longwords, and an index in this array. - uint32_t *data = (uint32_t *)font->glyphs; - int index; - - // Storage height of each glyph. This is a constant for all glyphs - // because the format required it. It makes this routine consequently - // faster. - int height = font->data_height; - - - - // Allocating data. There will be one operator for each line. - if(x > 127 || y > 63 || y <= -height) return; - if(y + height > 64) height = 64 - y; - - operators = alloca(height * sizeof(uint32_t)); - if(!operators) return; - for(int i = 0; i < height; i++) operators[i] = 0; - - // Computing the initial operator offset to have 32-aligned operators. - // This allows to write directly video ram longs instead of having to - // shift operators, and do all the vram operation twice. - // I double-checked that this operation is still valid when x is - // negative. - available = 32 - (x & 31); - x &= ~31; - - // Displaying character after another. - while(*str) - { - index = getCharacterIndex(*str++); - if(index < 0) continue; - - // Updating the operators. - available = update(operators, height, available, data + index); - - // Continue until operators are full (this includes an - // additional bit to add a space between each character). - if(available > 1) - { - available--; - continue; - } - - // When operators are full, updating the video ram and - // preparing the operators for another row. - - if(x >= 0) (*op)(operators, height, x, y); - x += 32; - if(x > 96) break; - - for(int i = 0; i < height; i++) operators[i] = 0; - if(available >= 0) - { - available += 31; - continue; - } - - // Finishing update, in cases where it has been only partially - // done because there was not enough bits available to fit all - // the information. Also adding a space, assuming that - // characters aren't more than 30 bits wide. (=p) - available += 32 + (data[index] >> 24); - available = update(operators, height, available, data + index); - available--; - } - - // Final operation. This condition allows a single bit of the operators - // to be used - that's because the loop will add a final spacing pixel. - if(x <= 96 && available < 31) (*op)(operators, height, x, y); -} diff --git a/src/tales/text_length.c b/src/tales/text_length.c deleted file mode 100644 index 2add43e..0000000 --- a/src/tales/text_length.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -/* - text_length() - Computes the length of a string using the currently configured font. -*/ -size_t text_length(const char *str) -{ - if(!str) return 0; - size_t len = 0; - - while(*str) - { - int index = getCharacterIndex(*str); - len += font->glyphs[index] >> 24; - if(*++str) len++; - } - - return len; -} diff --git a/src/time/asctime.c b/src/time/asctime.c deleted file mode 100644 index ed3d0a3..0000000 --- a/src/time/asctime.c +++ /dev/null @@ -1,57 +0,0 @@ -#include - -static char str[26]; - -/* - asctime() - Converts broken-down time to string representation on the form - "Wed Jun 30 21:49:08 1993\n". The returned string is statically - allocated and may be overwritten by any subsequent call to a time - function. -*/ -char *asctime(const struct tm *time) -{ - const char *days[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }, *months[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" - }; - int year = time->tm_year + 1900; - - str[0] = days[time->tm_wday][0]; - str[1] = days[time->tm_wday][1]; - str[2] = days[time->tm_wday][2]; - str[3] = ' '; - - str[4] = months[time->tm_mon][0]; - str[5] = months[time->tm_mon][1]; - str[6] = months[time->tm_mon][2]; - str[7] = ' '; - - str[8] = '0' + (time->tm_mday / 10); - str[9] = '0' + (time->tm_mday % 10); - str[10] = ' '; - - str[11] = '0' + (time->tm_hour / 10); - str[12] = '0' + (time->tm_hour % 10); - str[13] = ':'; - str[14] = '0' + (time->tm_min / 10); - str[15] = '0' + (time->tm_min % 10); - str[16] = ':'; - str[17] = '0' + (time->tm_sec / 10); - str[18] = '0' + (time->tm_sec % 10); - str[19] = ' '; - - str[20] = '0' + (year / 1000); - year %= 1000; - str[21] = '0' + (year / 100); - year %= 100; - str[22] = '0' + (year / 10); - str[23] = '0' + (year % 10); - - str[24] = '\n'; - str[25] = 0; - - return str; -} diff --git a/src/time/ctime.c b/src/time/ctime.c deleted file mode 100644 index f3768e0..0000000 --- a/src/time/ctime.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -/* - ctime() - Converts calendar time to string representation on the form - "Wed Jun 30 21:49:08 1993\n". The returned string is statically - allocated and may be overwritten by any subsequent call to a time - function. -*/ -char *ctime(const time_t *timer) -{ - return asctime(gmtime(timer)); -} diff --git a/src/time/gmtime.c b/src/time/gmtime.c deleted file mode 100644 index 4d84587..0000000 --- a/src/time/gmtime.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include - -static struct tm tm; - -/* - gmtime() - Converts calendar time to broken-down time. The returned pointer is - statically allocated and may be overwritten by any subsequent call to - a time function. -*/ -struct tm *gmtime(const time_t *timeptr) -{ - time_t t = *timeptr; - div_t d; - int sec; - - tm.tm_year = 1970; - tm.tm_mon = 0; - - sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600; - while(t >= sec) - { - t -= sec; - if(++tm.tm_mon == 12) - { - tm.tm_year++; - tm.tm_mon = 0; - } - sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600; - } - tm.tm_year -= 1900; - - d = div(sec, 24 * 3600); - tm.tm_mday = d.quot; - d = div(d.rem, 3600); - tm.tm_hour = d.quot; - d = div(d.rem, 60); - tm.tm_min = d.quot; - tm.tm_sec = d.rem; - - mktime(&tm); - return &tm; -} diff --git a/src/time/mktime.c b/src/time/mktime.c deleted file mode 100644 index 0ea26a9..0000000 --- a/src/time/mktime.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -/* - mktime() - Converts broken-down time to calendar time. Computes structure fields - tm_wday and tm_yday using the other fields. Member structures outside - their range are normalized (e.g. 40 October becomes 9 November) and - tm_isdst is set. -*/ -time_t mktime(struct tm *time) -{ - int leaps, yr; - int days, i; - - // Normalizing time. - time->tm_min += (time->tm_sec / 60); - time->tm_hour += (time->tm_min / 60); - time->tm_mday += (time->tm_hour / 24); - time->tm_sec %= 60; - time->tm_min %= 60; - time->tm_hour %= 24; - - // Normalizing date. - days = daysInMonth(time->tm_mon, time->tm_year + 1900); - while(time->tm_mday >= days) - { - time->tm_mday -= days; - if(++time->tm_mon == 12) - { - time->tm_mon = 0; - time->tm_year++; - } - days = daysInMonth(time->tm_mon, time->tm_year + 1900); - } - - // Setting the year day. - days = 0; - for(i = 0; i < time->tm_mon; i++) - days += daysInMonth(i, time->tm_year + 1900); - time->tm_yday = days + time->tm_mday; - - // Setting the week day. The calendar is periodic over 400 years and - // 1601-01-01 was a Monday. - - // Years completely elapsed since last 400n + 1 year (1601-2001-etc). - yr = (time->tm_year + 1900 - 1) % 400; - // Leap years in these yr years. - leaps = (yr / 4) - (yr >= 100) - (yr >= 200) - (yr >= 300); - // Days completely elapsed since last 400n + 1 year, 01-01. - days = 365 * yr + leaps + time->tm_yday; - // Current day of week (1 means Monday 1601-01-01). - time->tm_wday = (1 + days) % 7; - - // This RTC does not seem to have any DST feature. - time->tm_isdst = 0; - - if(time->tm_year + 1900 < 1970) return (time_t)-1; - - // 134774 is the number of days between 1601-01-01 and 1970-01-01. Thus - // days become the number of days elapsed since 1970-01-01. - days -= 134774; - // days may become negative, so add the calendar period. - if(days < 0) days += 146097; - - return (time_t)((24 * 3600) * days + 3600 * time->tm_hour + - 60 * time->tm_min + time->tm_sec); -} diff --git a/src/time/time.c b/src/time/time.c deleted file mode 100644 index e3edd16..0000000 --- a/src/time/time.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -/* - time() - Returns the current time as calendar time. If you need a broken-down - time, either use the RTC API or gmtime(). However, this function is - already based on mktime() (for hardware reasons) so it would be much - faster to use the RTC API if possible. - If timeptr is not NULL, it is set to the current time, that is, the - value that is returned. -*/ -time_t time(time_t *timeptr) -{ - rtc_time_t rtc; - struct tm tm; - time_t calendar; - - rtc_getTime(&rtc); - tm.tm_sec = rtc.seconds; - tm.tm_min = rtc.minutes; - tm.tm_hour = rtc.hours; - tm.tm_mday = rtc.month_day; - tm.tm_mon = rtc.month; - tm.tm_year = rtc.year - 1900; - - calendar = mktime(&tm); - if(timeptr) *timeptr = calendar; - return calendar; -} diff --git a/src/time/time_misc.c b/src/time/time_misc.c deleted file mode 100644 index 88e01fc..0000000 --- a/src/time/time_misc.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#undef difftime - -/* - clock() - Should return elapsed CPU time since beginning of program execution. - This is currently not implemented and returns -1. -*/ -clock_t clock(void) -{ - return (clock_t)-1; -} - -/* - difftime() - Returns the number of seconds between the given points. -*/ -double difftime(time_t end, time_t beginning) -{ - return (double)(end - beginning); -} diff --git a/src/time/time_util.c b/src/time/time_util.c deleted file mode 100644 index 11c7048..0000000 --- a/src/time/time_util.c +++ /dev/null @@ -1,28 +0,0 @@ -#include - -/* - isLeap() - Determines whether the given year is a leap year. -*/ -int isLeap(int year) -{ - int leap = !(year & 3); // Take multiples of 4 - if(!(year % 100)) leap = 0; // Remove multiples of 100 - if(!(year % 400)) leap = 1; // Take multiples of 400 - - return leap; -} - -/* - daysInMonth() - Returns number of days for the given month (between 0 and 11) and year. -*/ -int daysInMonth(int month, int year) -{ - int days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - if(month != 1) return days[month]; - return days[month] + isLeap(year); -} diff --git a/src/timer/common_api.c b/src/timer/common_api.c deleted file mode 100644 index d403e57..0000000 --- a/src/timer/common_api.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include - -/* - timer_attach() - Attaches a callback to a virtual or hardware timer. -*/ -void timer_attach(timer_t *timer, void *callback, void *argument) -{ - if(!timer) return; - - timer->callback = callback; - timer->argument = argument; -} - -/* - timer_start() - Starts a virtual or hardware timer. If the timer has a callback - attached, then the callback function will start being called regularly; - otherwise, the timer will start pushing ET_Timer events to the event - queue. It is advised, not to change a timer's configuration while it's - running. -*/ -void timer_start(timer_t *timer) -{ - if(!timer) return; - timer->active = 1; - - if(timer->virtual) vtimer_updateOne(timer->ms_delay); - else TMU.TSTR->byte |= (1 << (timer - htimers)); -} - -/* - timer_stop() - Pauses a virtual or hardware timer. The timer stops counting and can be - started again later. -*/ -void timer_stop(timer_t *timer) -{ - if(!timer) return; - timer->active = 0; - - if(timer->virtual) vtimer_updateAll(); - else - { - TMU.TSTR->byte &= ~(1 << (timer - htimers)); - timer->used = 0; - } -} - -/* - timer_interrupt() - Handles the interrupt for the given timer channel. -*/ -void timer_interrupt(int channel) -{ - // Is this the virtual timer support? - if(htimers[channel].vsupport) vtimer_interrupt(); - else timer_callback_event(&htimers[channel]); - - // Clearing the interrupt flag. - TMU.timers[channel]->TCR.UNF = 0; -} - -/* - timer_callback_event() - Executes the callback of a timer, or pushes a new timer event depending - on the timer configuration. Also reduces the amount of repeats left and - clears the active flag (or stops the hardware timer) if this number - falls from one to zero. -*/ -void timer_callback_event(timer_t *timer) -{ - if(!timer) return; - - // Callback-type timers. - if(timer->callback) - { - if(!timer->argument) - { - void (*fun)(void) = timer->callback; - fun(); - } - else - { - void (*fun)(void *arg) = timer->callback; - fun(timer->argument); - } - } - - // Event-type timers. - else - { - event_t event = { - .type = event_timer_underflow, - .timer = timer - }; - event_push(event); - } - - // Reducing the number of repeats and stopping the timer if required. - if(timer->repeats_left > 0) - { - if(!--timer->repeats_left) - { - if(timer->virtual) timer->active = 0; - else timer_stop(timer); - } - } -} diff --git a/src/timer/hardware_timers.c b/src/timer/hardware_timers.c deleted file mode 100644 index 57e247f..0000000 --- a/src/timer/hardware_timers.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include - -//--- -// Public API -//--- - -timer_t htimers[3] = { 0 }; - -/* - htimer_setup() - Configures a hardware timer. -*/ -timer_t *htimer_setup(timer_hard_t id, uint32_t constant, timer_input_t input, - int repeats) -{ - if(id < 0 || id >= 3 || htimers[id].used) return NULL; - timer_t *timer = &htimers[id]; - - // We don't care about this. - timer->ms_delay = 0; - timer->ms_elapsed = 0; - - timer->repeats_left = repeats; - - timer->used = 1; - timer->active = 0; - timer->virtual = 0; - timer->vsupport = 0; - timer->events = 0; - - timer->callback = NULL; - timer->argument = NULL; - - // Time to set up the real thing. - volatile mod_tmu_timer_t *tmu = TMU.timers[id]; - - tmu->TCOR = constant; - tmu->TCNT = constant; - tmu->TCR.TPSC = input; - - tmu->TCR.UNF = 0; // Clear the interrupt flag. - tmu->TCR.UNIE = 1; // Enable underflow interrupt. - tmu->TCR.CKEG = 0; // Count on rising edge (SH7705). - - return timer; -} - -/* - htimer_reload() - Reloads a hardware timer without starting or stopping it. -*/ -void htimer_reload(timer_hard_t id, uint32_t new_constant) -{ - volatile mod_tmu_timer_t *tmu = TMU.timers[id]; - - // This is not much but we want to make the transition as swift as - // possible and I can prove that at least one cycle will be lost in - // processor operation. Thus... - tmu->TCNT = new_constant - 1; - tmu->TCOR = new_constant; -} diff --git a/src/timer/virtual_timers.c b/src/timer/virtual_timers.c deleted file mode 100644 index b250065..0000000 --- a/src/timer/virtual_timers.c +++ /dev/null @@ -1,241 +0,0 @@ -#include -#include -#include -#include - -//--- -// Public API -//--- - -timer_t vtimers[TIMER_SLOTS] = { 0 }; - -/* - timer_create() - Creates a virtual timer and configures its delay and repetition count. -*/ -timer_t *timer_create(int ms_delay, int repeats) -{ - if(ms_delay <= 0) return NULL; - timer_t *timer = vtimers; - - // Finding an available virtual slot. - while(timer < vtimers + TIMER_SLOTS && timer->used) timer++; - if(timer >= vtimers + TIMER_SLOTS) return NULL; - - timer->ms_delay = ms_delay; - timer->ms_elapsed = 0; - timer->repeats_left = repeats; - - timer->used = 1; - timer->active = 0; - timer->virtual = 1; - timer->vsupport = 0; - timer->events = 0; - - timer->callback = NULL; - timer->argument = NULL; - - return timer; -} - -/* - timer_reload() - Changes a virtual timer's delay. The timer is not stopped nor started: - it keeps running or waiting. Events that were waiting to be handled are - dropped and the number of repeats left is not changed. The timer - restarts counting from 0 regardless of how much time had elapsed since - it last fired. -*/ -void timer_reload(timer_t *timer, int new_ms_delay) -{ - if(!timer->virtual) return; - - timer->ms_delay = new_ms_delay; - timer->ms_elapsed = 0; - - vtimer_updateAll(); -} - -/* - timer_destroy() - Destroys a virtual timer. This virtual timer pointer becomes invalid - and should not be used anymore. -*/ -void timer_destroy(timer_t *timer) -{ - timer->events = 0; - timer->active = 0; - timer->used = 0; - - vtimer_updateAll(); -} - - - -//--- -// Virtual timers management -//--- - -static int current_delay = 0; -static uint32_t current_constant = 0; - -/* - vtimer_interrupt() - Interrupt handling subsystem for the virtual timers. -*/ -void vtimer_interrupt(void) -{ - // Do we need to recompute the hardware support frequency? - int recalc = 0; - - // No timer is running. - if(!current_delay) return; - - // Update them all and call the required callbacks. Stop the ones that - // have been running for long enough. - for(timer_t *timer = vtimers; timer < vtimers + TIMER_SLOTS; timer++) - if(timer->used) - { - timer->ms_elapsed += current_delay; - - // This should happen only once but in case there is a problem, - // this loop will ensure that at least the correct amount of - // callbacks is executed. - // We could divide but it would be slower. - while(timer->ms_elapsed >= timer->ms_delay) - { - // We don't call the callbacks now because we may need - // to update the timer frequency later and we want to - // get there asap. - timer->events++; - timer->ms_elapsed -= timer->ms_delay; - } - - // We would need to stop one virtual timer. - if(timer->repeats_left > 0 && timer->repeats_left <= - timer->events) recalc = 1; - } - - if(recalc) vtimer_updateAll(); - - for(timer_t *timer = vtimers; timer < vtimers + TIMER_SLOTS; timer++) - if(timer->used) - { - while(timer->active && timer->events) - { - timer_callback_event(timer); - timer->events--; - } - timer->used = timer->active; - } -} - -/* - vtimer_update() - Swiftly updates the hardware support counter and constant to keep up - with new kinds of timers being added while disturbing the counting flow - as little as possible. -*/ -static void vtimer_update(int new_delay) -{ - volatile mod_tmu_timer_t *tmu = TMU.timers[timer_virtual]; - timer_t *timer = &htimers[timer_virtual]; - - if(new_delay == current_delay) return; - - if(!new_delay) - { - current_delay = 0; - current_constant = 0; - - // At this point the virtual support timer was running and has - // been stopped, thus the hardware timer structure is filled - // properly so we can use this function. - timer_stop(timer); - return; - } - uint32_t new_constant = clock_setting(new_delay, clock_ms); - - // The transition needs to be as smooth as possible. We have probably - // spent a lot of time calculating this new GCD delay so we want to - // take into consideration the current value of the timer counter. - // The -1 is here to take into account the time between reading and - // writing the new constant (~10 I_phi cycles thus usually 5 P_phi - // cycles; given this timer runs on P_phi / 4 this makes 1 unit). - // Here we suppose that the new TCNT is positive, i.e that the update - // happened in less than 1 ms. This is reasonable as long as this - // happens *before* calling callbacks. - tmu->TCNT = new_constant - (current_constant - tmu->TCNT - 1); - tmu->TCOR = new_constant; - - if(!current_delay) - { - // Ups, we've been using a random counter; the timer's not - // running. - tmu->TCNT = tmu->TCOR; - // Set it up then. - tmu->TCR.TPSC = timer_Po_4; - tmu->TCR.UNF = 0; - tmu->TCR.UNIE = 1; - tmu->TCR.CKEG = 0; - // Tell them that the virtual timer support is running there. - timer->used = 1; - timer->active = 0; - timer->virtual = 0; - timer->vsupport = 1; - timer->events = 0; - // And let's roll! - timer_start(timer); - } - - current_delay = new_delay; - current_constant = new_constant; -} - -/* - gcd() - Well, the Euclidean algorithm. That's O(ln(max(a, b))) FWIW. -*/ -static int gcd(int a, int b) -{ - while(b) - { - int r = a % b; - a = b; - b = r; - } - - return a; -} - -/* - vtimer_updateOne() - Update the virtual timer hardware support timer, knowing that a virtual - timer with the given delay has been started. -*/ -void vtimer_updateOne(int additional_delay) -{ - vtimer_update(gcd(current_delay, additional_delay)); -} - -/* - vtimer_updateAll() - Updates the virtual timer hardware support after computing the GCD of - all virtual timers delays. This computation is rather long (especially - this modulo can afaik only be achieved using division on SuperH and - it's a 70-cycle operation) so it should be avoided when possible. -*/ - -void vtimer_updateAll(void) -{ - int gcd_delay = 0; - - for(timer_t *timer = vtimers; timer < vtimers + TIMER_SLOTS; timer++) - if(timer->used && timer->active && (timer->repeats_left <= 0 || - timer->repeats_left > timer->events)) - { - gcd_delay = gcd(gcd_delay, timer->ms_delay); - } - - vtimer_update(gcd_delay); -} diff --git a/version b/version deleted file mode 100644 index 3bada75..0000000 --- a/version +++ /dev/null @@ -1 +0,0 @@ -beta-0.9-585