mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
Added a configure script with some options, made Makefile output pretty. Set up an event system (used by keyboard).
This commit is contained in:
parent
98fdbbc333
commit
eedec2b124
27 changed files with 604 additions and 150 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,3 +15,6 @@ LIBC
|
||||||
libc.a
|
libc.a
|
||||||
libgint.a
|
libgint.a
|
||||||
gintdemo.g1a
|
gintdemo.g1a
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
gcc.cfg
|
||||||
|
|
87
Makefile
Normal file → Executable file
87
Makefile
Normal file → Executable file
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
modules-gint = core clock keyboard mmu mpu rtc screen timer \
|
modules-gint = core clock keyboard mmu mpu rtc screen timer \
|
||||||
bopti display gray tales
|
bopti display gray tales events
|
||||||
modules-libc = setjmp string stdio stdlib time
|
modules-libc = setjmp string stdio stdlib time
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
|
@ -30,7 +30,7 @@ wr = g1a-wrapper
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os \
|
cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os \
|
||||||
-W -Wall -Wextra -pedantic
|
-W -Wall -Wextra -pedantic @gcc.cfg
|
||||||
|
|
||||||
# Demo application (could be done better)
|
# Demo application (could be done better)
|
||||||
demo-src = $(notdir $(wildcard demo/*.[cs]))
|
demo-src = $(notdir $(wildcard demo/*.[cs]))
|
||||||
|
@ -47,7 +47,8 @@ demo-libs = -L. -lgint -lc -lgcc
|
||||||
obj-lib-spec = build/display_font_system.bmp.o
|
obj-lib-spec = build/display_font_system.bmp.o
|
||||||
obj-std-spec =
|
obj-std-spec =
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
config = gcc.cfg
|
||||||
|
|
||||||
#---
|
#---
|
||||||
# Automatic variables.
|
# Automatic variables.
|
||||||
|
@ -61,6 +62,10 @@ define n
|
||||||
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
ifeq ("$(wildcard $(config))","")
|
||||||
|
$(error "Configuration files are missing. Did you ./configure?")
|
||||||
|
endif
|
||||||
|
|
||||||
# Module-scope variables.
|
# Module-scope variables.
|
||||||
$(foreach mod, $(modules), $(eval \
|
$(foreach mod, $(modules), $(eval \
|
||||||
mod-$(mod)-c = $(notdir $(wildcard src/$(mod)/*.c)) $n\
|
mod-$(mod)-c = $(notdir $(wildcard src/$(mod)/*.c)) $n\
|
||||||
|
@ -82,21 +87,28 @@ hdr-dep = $(wildcard include/*.h include/internals/*.h)
|
||||||
# Rule templates.
|
# Rule templates.
|
||||||
#---
|
#---
|
||||||
|
|
||||||
|
#ifndef VERBOSE
|
||||||
|
#$(note "default full log")
|
||||||
|
#VERBOSE =
|
||||||
|
#endif
|
||||||
|
|
||||||
# C source file template:
|
# C source file template:
|
||||||
# $1 module name
|
# $1 module name
|
||||||
# $2 filename
|
# $2 filename
|
||||||
# $3 dependencies
|
# $3 dependencies
|
||||||
define rule-c-source
|
define rule-c-source
|
||||||
build/$1_$2.o: src/$1/$2 $3
|
build/$1_$2.o: src/$1/$2 $3 $(config)
|
||||||
$(cc) -c $$< -o $$@ $(cflags) -I src/$1
|
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m cc $$<\n')
|
||||||
|
$(if $(VERBOSE),,@) $(cc) -c $$< -o $$@ $(cflags) -I src/$1
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# asm source file template:
|
# asm source file template:
|
||||||
# $1 module name
|
# $1 module name
|
||||||
# $2 filename
|
# $2 filename
|
||||||
define rule-asm-source
|
define rule-asm-source
|
||||||
build/$1_$2.o: src/$1/$2
|
build/$1_$2.o: src/$1/$2 $(config)
|
||||||
$(as) -c $$< -o $$@
|
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m as $$<\n')
|
||||||
|
$(if $(VERBOSE),,@) $(as) -c $$< -o $$@
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,25 +119,36 @@ endef
|
||||||
|
|
||||||
# Generic rules
|
# Generic rules
|
||||||
|
|
||||||
all: build $(target-std) $(target-lib) $(target-g1a)
|
all: $(config) build $(target-std) $(target-lib) $(target-g1a)
|
||||||
@echo "[ \033[32;1mOK\033[0m ] All done!"
|
@ printf '\e[32;1mmsg \u00bb\e[0m All done!\n'
|
||||||
|
|
||||||
build:
|
build:
|
||||||
mkdir -p $@
|
@ mkdir -p $@
|
||||||
|
|
||||||
$(target-std): $(obj-std)
|
$(target-std): $(config) $(obj-std)
|
||||||
$(ar) rcs $@ $^
|
$(if $(VERBOSE),,@ printf '\e[35;1mlib \u00bb\e[0m ar $@\n')
|
||||||
@echo "[ \033[32;1mOK\033[0m ] libc: `stat -c %s $@` bytes"
|
$(if $(VERBOSE),,@) $(ar) rcs $@ $(obj-std)
|
||||||
|
@ printf '\e[32;1mmsg \u00bb\e[0m Succesfully built libc ('
|
||||||
|
@ printf $$(stat -c %s $@)
|
||||||
|
@ printf ' bytes)\n\n'
|
||||||
|
|
||||||
$(target-lib): $(target-std) $(obj-lib)
|
$(target-lib): $(config) $(target-std) $(obj-lib)
|
||||||
$(ar) rcs $@ $(obj-lib)
|
$(if $(VERBOSE),,@ printf '\e[35;1mlib \u00bb\e[0m ar $@\n')
|
||||||
@echo "[ \033[32;1mOK\033[0m ] libgint: `stat -c %s $@` bytes"
|
$(if $(VERBOSE),,@) $(ar) rcs $@ $(obj-lib)
|
||||||
|
@ printf '\e[32;1mmsg \u00bb\e[0m Succesfully built libgint ('
|
||||||
|
@ printf $$(stat -c %s $@)
|
||||||
|
@ printf ' bytes)\n\n'
|
||||||
|
|
||||||
$(target-g1a): $(target-std) $(target-lib) $(demo-obj)
|
$(target-g1a): $(config) $(target-std) $(target-lib) $(demo-obj)
|
||||||
$(cc) -o $(demo-elf) $(cflags) -T $(demo-ld) $(demo-obj) $(demo-libs)
|
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m ld -o $(demo-elf)\n')
|
||||||
$(ob) -R .comment -R .bss -O binary $(demo-elf) $(demo-bin)
|
$(if $(VERBOSE),,@) $(cc) -o $(demo-elf) $(cflags) -T $(demo-ld) $(demo-obj) $(demo-libs)
|
||||||
$(wr) $(demo-bin) -o $@ -i $(demo-icon)
|
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m objcopy -o $(demo-bin)\n')
|
||||||
@echo "[ \033[32;1mOK\033[0m ] demo app: `stat -c %s $@` bytes"
|
$(if $(VERBOSE),,@) $(ob) -R .comment -R .bss -O binary $(demo-elf) $(demo-bin)
|
||||||
|
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m g1a-wrapper -o $@\n')
|
||||||
|
$(if $(VERBOSE),,@) $(wr) $(demo-bin) -o $@ -i $(demo-icon)
|
||||||
|
@ printf '\e[32;1mmsg \u00bb\e[0m Succesfully built demo application ('
|
||||||
|
@ printf $$(stat -c %s $@)
|
||||||
|
@ printf ' bytes)\n\n'
|
||||||
|
|
||||||
# Automated rules
|
# Automated rules
|
||||||
|
|
||||||
|
@ -139,23 +162,28 @@ $(foreach mod,$(modules), \
|
||||||
# Specific rules
|
# Specific rules
|
||||||
|
|
||||||
# This one should not be optimized. It makes __attribute__((interrupt_handler))
|
# This one should not be optimized. It makes __attribute__((interrupt_handler))
|
||||||
# buggy... maybe. Anyway there's a bug in this file.
|
# buggy... maybe. Anyway there's some bug in this file that I can't fix now.
|
||||||
build/core_gint.c.o: src/core/gint.c $(mod-core-dep)
|
build/core_gint.c.o: src/core/gint.c $(mod-core-dep) $(config)
|
||||||
$(cc) -c $< -o $@ $(cflags) -I src/core -O0
|
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m cc $<\n')
|
||||||
|
$(if $(VERBOSE),,@) $(cc) -c $< -o $@ $(cflags) -I src/core -O0
|
||||||
|
|
||||||
build/display_font_system.bmp.o: src/display/font_system.bmp
|
build/display_font_system.bmp.o: src/display/font_system.bmp
|
||||||
fxconv $< -o $@ --font -n gint_font_system
|
$(if $(VERBOSE),,@ printf '\e[36;1mres \u00bb\e[0m fxconv $<\n')
|
||||||
|
$(if $(VERBOSE),,@) fxconv $< -o $@ --font -n gint_font_system
|
||||||
|
|
||||||
# Demo application
|
# Demo application
|
||||||
|
|
||||||
build/demo_%.c.o: demo/%.c $(hdr-dep) $(demo-dep)
|
build/demo_%.c.o: demo/%.c $(hdr-dep) $(demo-dep) $(config)
|
||||||
$(cc) -c $< -o $@ $(cflags)
|
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m cc $<\n')
|
||||||
|
$(if $(VERBOSE),,@) $(cc) -c $< -o $@ $(cflags)
|
||||||
|
|
||||||
build/demo_font_%.bmp.o: demo/resources/font_%.bmp
|
build/demo_font_%.bmp.o: demo/resources/font_%.bmp
|
||||||
fxconv $< -o $@ --font -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
$(if $(VERBOSE),,@ printf '\e[36;1mres \u00bb\e[0m fxconv $<\n')
|
||||||
|
$(if $(VERBOSE),,@) fxconv $< -o $@ --font -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
||||||
|
|
||||||
build/demo_%.bmp.o: demo/resources/%.bmp
|
build/demo_%.bmp.o: demo/resources/%.bmp
|
||||||
fxconv $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
$(if $(VERBOSE),,@ printf '\e[36;1mres \u00bb\e[0m fxconv $<\n')
|
||||||
|
$(if $(VERBOSE),,@) fxconv $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,6 +197,7 @@ clean:
|
||||||
mrproper: clean
|
mrproper: clean
|
||||||
@ rm -f $(target-g1a) $(target-lib) $(target-std)
|
@ rm -f $(target-g1a) $(target-lib) $(target-std)
|
||||||
@ rm -rf build
|
@ rm -rf build
|
||||||
|
@ rm -f $(config)
|
||||||
|
|
||||||
distclean: mrproper
|
distclean: mrproper
|
||||||
|
|
||||||
|
|
6
TODO
6
TODO
|
@ -25,3 +25,9 @@ Things to investigate:
|
||||||
- Registers that may need to be saved within setjmp()
|
- Registers that may need to be saved within setjmp()
|
||||||
- Registers that may need to be saved and restored by gint
|
- Registers that may need to be saved and restored by gint
|
||||||
- Possible bug when optimizing __attribute__((interrupt_handler))
|
- Possible bug when optimizing __attribute__((interrupt_handler))
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
- ATEXIT_MAX (16)
|
||||||
|
- RTC_CB_ARRAY_SIZE (5)
|
||||||
|
- EVENTS_QUEUE_SIZE (64)
|
||||||
|
- GINT_NO_SYSCALLS (undefined)
|
||||||
|
|
78
configure
vendored
Executable file
78
configure
vendored
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
declare -A conf
|
||||||
|
conf[ATEXIT_MAX]=16
|
||||||
|
conf[RTC_CB_ARRAY_SIZE]=5
|
||||||
|
conf[EVENTS_QUEUE_SIZE]=64
|
||||||
|
conf[GINT_NO_SYSCALLS]=
|
||||||
|
fail=false
|
||||||
|
output="gcc.cfg"
|
||||||
|
|
||||||
|
help()
|
||||||
|
{
|
||||||
|
cat << EOF
|
||||||
|
Configuration script for the gint library.
|
||||||
|
|
||||||
|
Options that affect the behavior of the library:
|
||||||
|
--no-syscalls [default: false]
|
||||||
|
Never use syscalls. Expect some trouble with the malloc() function...
|
||||||
|
Do not trigger this option unless you know what you are doing.
|
||||||
|
|
||||||
|
Options that customize size limits:
|
||||||
|
--atexit-max=<integer> [default: 16]
|
||||||
|
Number of exit handlers that can be registered by atexit().
|
||||||
|
--rtc-callbacks=<integer> [default: 5]
|
||||||
|
Number of RTC callbacks that can be registered.
|
||||||
|
--events-queue-size=<integer> [default: 64]
|
||||||
|
Number of events simultaneously stored in the event queue.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg; do case "$arg" in
|
||||||
|
-h | --help) help;;
|
||||||
|
--no-syscalls) conf[GINT_NO_SYSCALLS]=true;;
|
||||||
|
|
||||||
|
--atexit-max=*)
|
||||||
|
size=${arg#*=}
|
||||||
|
if [[ $size == +([0-9]) ]]; then
|
||||||
|
conf[ATEXIT_MAX]=$size
|
||||||
|
else echo "error: --atexit-max expects an integer value"
|
||||||
|
fail=true; fi;;
|
||||||
|
--rtc-callbacks=*)
|
||||||
|
size=${arg#*=}
|
||||||
|
if [[ $size == +([0-9]) ]]; then
|
||||||
|
conf[RTC_CB_ARRAY_SIZE]=$size
|
||||||
|
else echo "error: --rtc-callbacks expects an integer value"
|
||||||
|
fail=true; fi;;
|
||||||
|
--events-queue-size=*)
|
||||||
|
size=${arg#*=}
|
||||||
|
if [[ $size == +([0-9]) ]]; then
|
||||||
|
conf[EVENTS_QUEUE_SIZE]=$size
|
||||||
|
else echo "error: --events-queue-size expects an integer value"
|
||||||
|
fail=true; fi;;
|
||||||
|
|
||||||
|
--atexit-max | --rtc-callbacks | --events-queue-size)
|
||||||
|
echo "error: syntax for $arg is $arg=<integer-value>";;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "error: unrecognized argument '$arg'"; fail=true;;
|
||||||
|
esac; done
|
||||||
|
|
||||||
|
output_config()
|
||||||
|
{
|
||||||
|
echo "-D ATEXIT_MAX=${conf[ATEXIT_MAX]}"
|
||||||
|
echo "-D RTC_CB_ARRAY_SIZE=${conf[RTC_CB_ARRAY_SIZE]}"
|
||||||
|
echo "-D EVENTS_QUEUE_SIZE=${conf[EVENTS_QUEUE_SIZE]}"
|
||||||
|
if [ "${conf[GINT_NO_SYSCALLS]}" != "" ]; then
|
||||||
|
echo "-D GINT_NO_SYSCALLS"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if $fail; then
|
||||||
|
echo "Configuration has not been modified."
|
||||||
|
else
|
||||||
|
output_config > $output
|
||||||
|
echo "Configuration details have been output to file $output."
|
||||||
|
fi
|
84
include/events.h
Normal file
84
include/events.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
//---
|
||||||
|
//
|
||||||
|
// gint core module: events
|
||||||
|
//
|
||||||
|
// Finally some user-friendly API.
|
||||||
|
//
|
||||||
|
//---
|
||||||
|
|
||||||
|
#ifndef _EVENTS_H
|
||||||
|
#define _EVENTS_H
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Type definitions.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum EventType
|
||||||
|
Something user programs will surely use most often.
|
||||||
|
*/
|
||||||
|
enum EventType
|
||||||
|
{
|
||||||
|
EventType_None = 0,
|
||||||
|
ET_None = EventType_None,
|
||||||
|
|
||||||
|
EventType_User = 1,
|
||||||
|
ET_User = EventType_User,
|
||||||
|
|
||||||
|
EventType_KeyPressed = 2,
|
||||||
|
ET_KeyPress = EventType_KeyPressed,
|
||||||
|
|
||||||
|
EventType_KeyReleased = 3,
|
||||||
|
ET_KeyRel = EventType_KeyReleased,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Event
|
||||||
|
Wake up, something's going on. The union member that holds information
|
||||||
|
about the event is implicitly defined by the type attribute.
|
||||||
|
*/
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
enum EventType type;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
// For ET_User.
|
||||||
|
void *data;
|
||||||
|
// For ET_KeyPress and ET_KeyRel.
|
||||||
|
int key;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// 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(struct Event event);
|
||||||
|
|
||||||
|
/*
|
||||||
|
getevent()
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
struct Event getevent(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
pollevent()
|
||||||
|
Returns the next event. If no one is available, returns an event whose
|
||||||
|
type is ET_None. This function always returns immediately.
|
||||||
|
*/
|
||||||
|
struct Event pollevent(void);
|
||||||
|
|
||||||
|
#endif // _EVENTS_H
|
|
@ -30,6 +30,18 @@ unsigned int gint_getVBR(void);
|
||||||
*/
|
*/
|
||||||
unsigned int gint_systemVBR(void);
|
unsigned int gint_systemVBR(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
gint_setDefaultHandler()
|
||||||
|
In case gint receives an interrupt it doesn't recognize, it can fall
|
||||||
|
back to a user-provided interrupt handler. Set it to NULL to disable
|
||||||
|
this feature.
|
||||||
|
Be aware that the event code passed to the default handler will either
|
||||||
|
be INTEVT2 (SH7705) or INTEVT (SH7305), but its value for each
|
||||||
|
interrupt source is completely platform-dependent. Remember to handle
|
||||||
|
both platforms for increased portability, if possible.
|
||||||
|
*/
|
||||||
|
void gint_setDefaultHandler(void (*default_handler)(int event_code));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -85,6 +97,12 @@ const char *gint_strerror(int is_tlb);
|
||||||
*/
|
*/
|
||||||
void gint_setVBR(unsigned int new_vbr_address, void (*setup)(void));
|
void gint_setVBR(unsigned int new_vbr_address, void (*setup)(void));
|
||||||
|
|
||||||
|
/*
|
||||||
|
gint_callDefaultHandler()
|
||||||
|
Calls the user-provided default interrupt handler.
|
||||||
|
*/
|
||||||
|
void gint_callDefaultHandler(int event_code);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gint_init()
|
gint_init()
|
||||||
Initializes gint. Loads the interrupt handler into the memory and sets
|
Initializes gint. Loads the interrupt handler into the memory and sets
|
||||||
|
|
19
include/internals/events.h
Normal file
19
include/internals/events.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef _INTERNALS_EVENTS_H
|
||||||
|
#define _INTERNALS_EVENTS_H
|
||||||
|
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
|
#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 struct Event event_queue[];
|
||||||
|
extern volatile int queue_start;
|
||||||
|
extern volatile int queue_size;
|
||||||
|
|
||||||
|
#endif // _INTERNALS_EVENT_H
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef _INTERNALS_KEYBOARD_H
|
#ifndef _INTERNALS_KEYBOARD_H
|
||||||
#define _INTERNALS_KEYBOARD_H 1
|
#define _INTERNALS_KEYBOARD_H
|
||||||
|
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#ifndef _INTERNALS_RTC_H
|
#ifndef _INTERNALS_RTC_H
|
||||||
#define _INTERNALS_RTC_H 1
|
#define _INTERNALS_RTC_H
|
||||||
|
|
||||||
#include <rtc.h>
|
#include <rtc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef RTC_CB_ARRAY_SIZE
|
||||||
#define RTC_CB_ARRAY_SIZE 5
|
#define RTC_CB_ARRAY_SIZE 5
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct rtc_cb
|
struct rtc_cb
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
//---
|
|
||||||
//
|
|
||||||
// gint drawing module: tales
|
|
||||||
//
|
|
||||||
// Text displaying. Does some good optimization, though requires dynamic
|
|
||||||
// allocation.
|
|
||||||
//
|
|
||||||
//---
|
|
||||||
|
|
||||||
#ifndef _INTERNALS_TALES_H
|
#ifndef _INTERNALS_TALES_H
|
||||||
#define _INTERNALS_TALES_H 1
|
#define _INTERNALS_TALES_H 1
|
||||||
|
|
||||||
|
|
|
@ -147,13 +147,10 @@ enum GetkeyOpt
|
||||||
{
|
{
|
||||||
Getkey_NoOption = 0x00,
|
Getkey_NoOption = 0x00,
|
||||||
|
|
||||||
// Return KEY_NONE when a key is released.
|
|
||||||
Getkey_ReleaseEvent = 0x01,
|
|
||||||
|
|
||||||
// Consider [SHIFT] and [ALPHA] as modifiers instead of returning
|
// Consider [SHIFT] and [ALPHA] as modifiers instead of returning
|
||||||
// KEY_SHIFT and KEY_ALPHA.
|
// KEY_SHIFT and KEY_ALPHA.
|
||||||
Getkey_ShiftModifier = 0x02,
|
Getkey_ShiftModifier = 0x01,
|
||||||
Getkey_AlphaModifier = 0x04,
|
Getkey_AlphaModifier = 0x02,
|
||||||
|
|
||||||
// Key repetition. Notice that modifiers will never be repeated.
|
// Key repetition. Notice that modifiers will never be repeated.
|
||||||
Getkey_RepeatArrowKeys = 0x10,
|
Getkey_RepeatArrowKeys = 0x10,
|
||||||
|
@ -219,7 +216,7 @@ int getkey_opt(enum GetkeyOpt options, int max_cycles);
|
||||||
The results are guaranteed to be exact if two keys or less are pressed.
|
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
|
With three keys or more, column effects (on SH4) and rectangle effects
|
||||||
(on both platforms) mess up the results by making this function think
|
(on both platforms) mess up the results by making this function think
|
||||||
that some keys that are actually unpressed, are pressed.
|
that some keys, which are actually unpressed, are pressed.
|
||||||
|
|
||||||
This function is designed to make combinations of one or two arrow keys
|
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
|
with another key as viable as possible. On SH4, this works pretty well
|
||||||
|
@ -257,7 +254,7 @@ int keyid(int key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
keychar()
|
keychar()
|
||||||
Returns the ASCII character associated with a character key ; 0 for
|
Returns the ASCII character associated with a character key; 0 for
|
||||||
other keys.
|
other keys.
|
||||||
*/
|
*/
|
||||||
int keychar(int key);
|
int keychar(int key);
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
#define EXIT_FAILURE 0
|
#define EXIT_FAILURE 0
|
||||||
|
|
||||||
// Number of atexit() registrations guaranteed.
|
// Number of atexit() registrations guaranteed.
|
||||||
|
#ifndef ATEXIT_MAX
|
||||||
#define ATEXIT_MAX 16
|
#define ATEXIT_MAX 16
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maximum value returned by rand().
|
// Maximum value returned by rand().
|
||||||
#define RAND_MAX INT_MAX
|
#define RAND_MAX INT_MAX
|
||||||
|
|
|
@ -189,9 +189,9 @@ static void clock_compute_7305(void)
|
||||||
volatile unsigned int *FLLFRQ = (void *)0xa4150050;
|
volatile unsigned int *FLLFRQ = (void *)0xa4150050;
|
||||||
|
|
||||||
// Surely the documentation of SH7724 does not meet the specification
|
// Surely the documentation of SH7724 does not meet the specification
|
||||||
// if SH7305 for the PLL setting, because the register accepts other
|
// of SH7305 for the PLL setting, because the register accepts other
|
||||||
// values than the ones specified by SH7724. The formula given by
|
// values than the ones specified for SH7724. The relation given by
|
||||||
// Sentaro21 (thanks again!) yields good results though.
|
// Sentaro21 (thanks again!) yields good results.
|
||||||
int pll = (*FRQCRA >> 24) & 0x3f; // Raw setting
|
int pll = (*FRQCRA >> 24) & 0x3f; // Raw setting
|
||||||
pll = pll + 1; // Resulting multiplier
|
pll = pll + 1; // Resulting multiplier
|
||||||
conf.PLL = pll;
|
conf.PLL = pll;
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include <clock.h>
|
#include <clock.h>
|
||||||
#include <internals/mmu.h>
|
#include <internals/mmu.h>
|
||||||
|
|
||||||
void __Hmem_SetMMU(unsigned int, unsigned int, int);
|
|
||||||
void __GLibAddinAplExecutionCheck(int, int, int);
|
|
||||||
int main(void);
|
int main(void);
|
||||||
|
|
||||||
static void init(void);
|
static void init(void);
|
||||||
|
@ -54,8 +52,6 @@ int start(void)
|
||||||
// Copying the .data section.
|
// Copying the .data section.
|
||||||
while(data < &edata) *data++ = *src++;
|
while(data < &edata) *data++ = *src++;
|
||||||
|
|
||||||
__GLibAddinAplExecutionCheck(0, 1, 1);
|
|
||||||
|
|
||||||
mmu_pseudoTLBInit();
|
mmu_pseudoTLBInit();
|
||||||
|
|
||||||
// Initializing gint.
|
// Initializing gint.
|
||||||
|
|
|
@ -16,6 +16,8 @@ static unsigned int
|
||||||
new_vbr,
|
new_vbr,
|
||||||
sys_vbr;
|
sys_vbr;
|
||||||
|
|
||||||
|
static void (*default_handler)(int event_code) = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -64,6 +66,21 @@ inline unsigned int gint_systemVBR(void)
|
||||||
return sys_vbr;
|
return sys_vbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
gint_setDefaultHandler()
|
||||||
|
In case gint receives an interrupt it doesn't recognize, it can fall
|
||||||
|
back to a user-provided interrupt handler. Set it to NULL to disable
|
||||||
|
this feature.
|
||||||
|
Be aware that the event code passed to the default handler will either
|
||||||
|
be INTEVT2 (SH7705) or INTEVT (SH7305), but its value for each
|
||||||
|
interrupt case is completely platform-dependent. Remember to handle
|
||||||
|
both platforms for increased portability, if possible.
|
||||||
|
*/
|
||||||
|
void gint_setDefaultHandler(void (*new_handler)(int event_code))
|
||||||
|
{
|
||||||
|
default_handler = new_handler;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gint_init()
|
gint_init()
|
||||||
Initializes gint. Loads the interrupt handler into the memory and sets
|
Initializes gint. Loads the interrupt handler into the memory and sets
|
||||||
|
@ -220,6 +237,21 @@ void gint_int(void)
|
||||||
gint_int_7305();
|
gint_int_7305();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Internal API.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
gint_callDefaultHandler()
|
||||||
|
Calls the user-provided default interrupt handler.
|
||||||
|
*/
|
||||||
|
void gint_callDefaultHandler(int event_code)
|
||||||
|
{
|
||||||
|
if(default_handler) default_handler(event_code);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gint_reg()
|
gint_reg()
|
||||||
Returns the address of a common register. All common registers exist
|
Returns the address of a common register. All common registers exist
|
||||||
|
|
|
@ -3,35 +3,31 @@
|
||||||
|
|
||||||
All the system calls used by the library. Somehow "the less, the
|
All the system calls used by the library. Somehow "the less, the
|
||||||
better".
|
better".
|
||||||
|
We have finally gotten rid of every obscure system-related syscalls!
|
||||||
|
Looks like an important step towards being completely free-standing :)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.global ___GLibAddinAplExecutionCheck
|
.global ___malloc
|
||||||
.global _malloc
|
.global ___free
|
||||||
.global _free
|
.global ___realloc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
___GLibAddinAplExecutionCheck:
|
___malloc:
|
||||||
mov.l syscall_table, r2
|
|
||||||
mov #0x13, r0
|
|
||||||
jmp @r2
|
|
||||||
nop
|
|
||||||
|
|
||||||
_malloc:
|
|
||||||
mov.l syscall_table, r2
|
mov.l syscall_table, r2
|
||||||
mov.l 1f, r0
|
mov.l 1f, r0
|
||||||
jmp @r2
|
jmp @r2
|
||||||
nop
|
nop
|
||||||
1: .long 0xacd
|
1: .long 0xacd
|
||||||
|
|
||||||
_free:
|
___free:
|
||||||
mov.l syscall_table, r2
|
mov.l syscall_table, r2
|
||||||
mov.l 1f, r0
|
mov.l 1f, r0
|
||||||
jmp @r2
|
jmp @r2
|
||||||
nop
|
nop
|
||||||
1: .long 0xacc
|
1: .long 0xacc
|
||||||
|
|
||||||
_realloc:
|
___realloc:
|
||||||
mov.l syscall_table, r2
|
mov.l syscall_table, r2
|
||||||
mov.l 1f, r0
|
mov.l 1f, r0
|
||||||
jmp @r2
|
jmp @r2
|
||||||
|
|
38
src/events/event_get.c
Normal file
38
src/events/event_get.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <internals/events.h>
|
||||||
|
#include <events.h>
|
||||||
|
#include <clock.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
pollevent()
|
||||||
|
Returns the next event. If no one is available, returns an event whose
|
||||||
|
type is ET_None. This function always returns immediately.
|
||||||
|
*/
|
||||||
|
struct Event pollevent(void)
|
||||||
|
{
|
||||||
|
struct Event event = {
|
||||||
|
.type = ET_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
getevent()
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
struct Event getevent(void)
|
||||||
|
{
|
||||||
|
struct Event event;
|
||||||
|
|
||||||
|
while((event = pollevent()).type == ET_None) sleep();
|
||||||
|
return event;
|
||||||
|
}
|
26
src/events/event_push.c
Normal file
26
src/events/event_push.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <internals/events.h>
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
|
volatile struct Event 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(struct Event event)
|
||||||
|
{
|
||||||
|
if(queue_size >= EVENTS_QUEUE_SIZE) return 1;
|
||||||
|
if(event.type == ET_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;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include <internals/keyboard.h>
|
#include <internals/keyboard.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getkey()
|
getkey()
|
||||||
|
@ -18,96 +19,113 @@ int getkey(void)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getkey_opt()
|
getkey_opt()
|
||||||
Enhances getkey() with most general functionalities.
|
Enhances getkey() with more general functionalities.
|
||||||
If max_cycles is non-zero and positive, getkey_opt() will return
|
If max_cycles is non-zero and positive, getkey_opt() will return
|
||||||
KEY_NOEVENT if no event occurs during max_cycle analysis.
|
KEY_NOEVENT if no event occurs during max_cycle analysis.
|
||||||
*/
|
*/
|
||||||
int getkey_opt(enum GetkeyOpt options, int max_cycles)
|
void getkey_opt_wait(int *cycles)
|
||||||
{
|
{
|
||||||
int key;
|
|
||||||
enum KeyType type;
|
|
||||||
int modifier = 0, last_modifier = KEY_NONE;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if(!max_cycles) max_cycles = -1;
|
|
||||||
|
|
||||||
while(max_cycles != 0)
|
|
||||||
{
|
|
||||||
while(!interrupt_flag) sleep();
|
while(!interrupt_flag) sleep();
|
||||||
interrupt_flag = 0;
|
interrupt_flag = 0;
|
||||||
if(max_cycles > 0) max_cycles--;
|
|
||||||
|
|
||||||
// Getting key and adding modifiers.
|
if(*cycles > 0) (*cycles)--;
|
||||||
key = getPressedKey(keyboard_state);
|
}
|
||||||
|
int getkey_opt(enum GetkeyOpt options, int cycles)
|
||||||
|
{
|
||||||
|
struct Event event;
|
||||||
|
int modifier = 0;
|
||||||
|
static int event_ref = 0;
|
||||||
|
|
||||||
// Handling "no_key" event;
|
if(cycles <= 0) cycles = -1;
|
||||||
if(key == KEY_NONE)
|
while(cycles != 0)
|
||||||
{
|
{
|
||||||
// Condition for returning.
|
event = pollevent();
|
||||||
r = (last_key != KEY_NONE &&
|
switch(event.type)
|
||||||
options & Getkey_ReleaseEvent);
|
{
|
||||||
|
case ET_None:
|
||||||
last_key = KEY_NONE;
|
if(last_key == KEY_NONE)
|
||||||
last_modifier = KEY_NONE;
|
{
|
||||||
last_repeats = 0;
|
getkey_opt_wait(&cycles);
|
||||||
last_events = 0;
|
continue;
|
||||||
|
|
||||||
if(r) return KEY_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handling "new key" events.
|
// Handling repetitions.
|
||||||
else if(key != last_key)
|
enum KeyType type = keytype(last_key);
|
||||||
|
if(!(options & (type << 4))) break;
|
||||||
|
|
||||||
|
if(event_ref <= 0)
|
||||||
{
|
{
|
||||||
|
getkey_opt_wait(&cycles);
|
||||||
|
event_ref++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_events++;
|
||||||
|
event_ref--;
|
||||||
|
|
||||||
|
if(last_events >= (last_repeats ? repeat_next :
|
||||||
|
repeat_first))
|
||||||
|
{
|
||||||
|
last_repeats++;
|
||||||
|
last_events = 0;
|
||||||
|
return last_key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ET_KeyPress:
|
||||||
|
;
|
||||||
|
int key = event.key;
|
||||||
if(options & Getkey_ShiftModifier && key == KEY_SHIFT)
|
if(options & Getkey_ShiftModifier && key == KEY_SHIFT)
|
||||||
{
|
{
|
||||||
if(last_modifier != KEY_SHIFT)
|
|
||||||
modifier ^= MOD_SHIFT;
|
modifier ^= MOD_SHIFT;
|
||||||
last_modifier = KEY_SHIFT;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(options & Getkey_AlphaModifier && key == KEY_ALPHA)
|
if(options & Getkey_AlphaModifier && key == KEY_ALPHA)
|
||||||
{
|
{
|
||||||
if(last_modifier != KEY_ALPHA)
|
|
||||||
modifier ^= MOD_ALPHA;
|
modifier ^= MOD_ALPHA;
|
||||||
last_modifier = KEY_ALPHA;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_key = key;
|
last_key = key;
|
||||||
last_repeats = 0;
|
last_repeats = 0;
|
||||||
last_events = 0;
|
last_events = 0;
|
||||||
|
event_ref = 0;
|
||||||
return key | modifier;
|
return key | modifier;
|
||||||
|
|
||||||
|
case ET_KeyRel:
|
||||||
|
if(event.key != last_key) break;
|
||||||
|
last_key = KEY_NONE;
|
||||||
|
last_repeats = 0;
|
||||||
|
last_events = 0;
|
||||||
|
event_ref = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_key = KEY_NONE;
|
||||||
|
last_repeats = 0;
|
||||||
|
last_events = 0;
|
||||||
|
event_ref = 0;
|
||||||
|
return KEY_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int getkey_opt(enum GetkeyOpt options, int max_cycles)
|
||||||
|
{
|
||||||
|
while(max_cycles != 0)
|
||||||
|
{
|
||||||
|
// Handling "new key" events.
|
||||||
|
|
||||||
// Handling key repetitions.
|
// Handling key repetitions.
|
||||||
else
|
|
||||||
{
|
|
||||||
type = keytype(key);
|
|
||||||
|
|
||||||
// Checking whether this key type is repeated.
|
|
||||||
if(options & (type << 4))
|
|
||||||
{
|
|
||||||
last_events++;
|
|
||||||
r = last_repeats ? repeat_next : repeat_first;
|
|
||||||
|
|
||||||
if(last_events >= r)
|
|
||||||
{
|
|
||||||
last_repeats++;
|
|
||||||
last_events = 0;
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When no key was pressed during the given delay...
|
// When no key was pressed during the given delay...
|
||||||
return KEY_NOEVENT;
|
return KEY_NOEVENT;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
#include <internals/keyboard.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <mpu.h>
|
#include <mpu.h>
|
||||||
#include <clock.h>
|
#include <clock.h>
|
||||||
|
#include <events.h>
|
||||||
#include <internals/keyboard.h>
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Keyboard variables.
|
// Keyboard variables.
|
||||||
|
@ -26,6 +26,24 @@ unsigned cb_id;
|
||||||
// Interrupt management.
|
// Interrupt management.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
|
static void push_press(int keycode)
|
||||||
|
{
|
||||||
|
struct Event event = {
|
||||||
|
.type = ET_KeyPress,
|
||||||
|
.key = keycode,
|
||||||
|
};
|
||||||
|
event_push(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void push_release(int keycode)
|
||||||
|
{
|
||||||
|
struct Event event = {
|
||||||
|
.type = ET_KeyRel,
|
||||||
|
.key = keycode,
|
||||||
|
};
|
||||||
|
event_push(event);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
keyboard_interrupt()
|
keyboard_interrupt()
|
||||||
Callback for keyboard update. Allows keyboard analysis functions to
|
Callback for keyboard update. Allows keyboard analysis functions to
|
||||||
|
@ -33,10 +51,42 @@ unsigned cb_id;
|
||||||
*/
|
*/
|
||||||
void keyboard_interrupt(void)
|
void keyboard_interrupt(void)
|
||||||
{
|
{
|
||||||
if(isSH3())
|
unsigned char state[10] = { 0 };
|
||||||
keyboard_updateState_7705(keyboard_state);
|
|
||||||
else
|
isSH3() ? keyboard_updateState_7705(state)
|
||||||
keyboard_updateState_7305(keyboard_state);
|
: keyboard_updateState_7305(state)
|
||||||
|
;
|
||||||
|
|
||||||
|
// Try to minimize number of operations in common cases... this handles
|
||||||
|
// AC/ON.
|
||||||
|
if(keyboard_state[0] ^ state[0])
|
||||||
|
{
|
||||||
|
unsigned char pressed = ~keyboard_state[0] & state[0];
|
||||||
|
unsigned char released = keyboard_state[0] & ~state[0];
|
||||||
|
|
||||||
|
if(pressed & 1) push_press(KEY_AC_ON);
|
||||||
|
if(released & 1) push_release(KEY_AC_ON);
|
||||||
|
}
|
||||||
|
keyboard_state[0] = state[0];
|
||||||
|
|
||||||
|
for(int row = 1; row <= 9; row++)
|
||||||
|
{
|
||||||
|
unsigned char pressed = ~keyboard_state[row] & state[row];
|
||||||
|
unsigned char released = keyboard_state[row] & ~state[row];
|
||||||
|
keyboard_state[row] = state[row];
|
||||||
|
|
||||||
|
// Fasten this a bit.
|
||||||
|
if(!pressed && !released) continue;
|
||||||
|
|
||||||
|
for(int column = 0; column < 8; column++)
|
||||||
|
{
|
||||||
|
if(pressed & 1) push_press ((column << 4) | row);
|
||||||
|
if(released & 1) push_release((column << 4) | row);
|
||||||
|
|
||||||
|
pressed >>= 1;
|
||||||
|
released >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interrupt_flag = 1;
|
interrupt_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,12 +138,5 @@ static int krow(int row)
|
||||||
*/
|
*/
|
||||||
void keyboard_updateState_7305(volatile unsigned char *keyboard_state)
|
void keyboard_updateState_7305(volatile unsigned char *keyboard_state)
|
||||||
{
|
{
|
||||||
int i;
|
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
|
|
||||||
keyboard_state[8] = krow(8);
|
|
||||||
for(i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
if(i != 7 && i != 8) keyboard_state[i] = krow(i);
|
|
||||||
}
|
|
||||||
keyboard_state[7] = krow(7);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,5 @@ static int krow(int row)
|
||||||
*/
|
*/
|
||||||
void keyboard_updateState_7705(volatile unsigned char *keyboard_state)
|
void keyboard_updateState_7705(volatile unsigned char *keyboard_state)
|
||||||
{
|
{
|
||||||
int i;
|
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
|
|
||||||
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,9 @@ void gint_int_7305(void)
|
||||||
case IC_TMU0_TUNI2:
|
case IC_TMU0_TUNI2:
|
||||||
timer_interrupt(TIMER_TMU2);
|
timer_interrupt(TIMER_TMU2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gint_callDefaultHandler(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ void gint_int_7705(void)
|
||||||
case IC_TMU2_TUNI2:
|
case IC_TMU2_TUNI2:
|
||||||
timer_interrupt(TIMER_TMU2);
|
timer_interrupt(TIMER_TMU2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gint_callDefaultHandler(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/stdlib/free.c
Normal file
20
src/stdlib/free.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
|
#ifndef GINT_NO_SYSCALLS
|
||||||
|
void __free(void *ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
free()
|
||||||
|
Frees a memory block allocated by malloc(), calloc() or realloc().
|
||||||
|
*/
|
||||||
|
void free(void *ptr)
|
||||||
|
{
|
||||||
|
#ifndef GINT_NO_SYSCALLS
|
||||||
|
__free(ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
27
src/stdlib/malloc.c
Normal file
27
src/stdlib/malloc.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
malloc()
|
||||||
|
Allocates 'size' bytes and returns a pointer to a free memory area.
|
||||||
|
Returns NULL on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GINT_NO_SYSCALLS
|
||||||
|
|
||||||
|
void *__malloc(size_t size);
|
||||||
|
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
|
||||||
|
|
25
src/stdlib/realloc.c
Normal file
25
src/stdlib/realloc.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
realloc()
|
||||||
|
Reallocates a memory block and moves its data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GINT_NO_SYSCALLS
|
||||||
|
|
||||||
|
void *__realloc(void *ptr, size_t size);
|
||||||
|
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
|
Loading…
Reference in a new issue