Reported TLB issues. Moved internal headers files, added rtc module and alloca.
39
Makefile
|
@ -12,7 +12,8 @@
|
|||
#---
|
||||
|
||||
# Modules
|
||||
modules-gint = bopti core display gray keyboard mpu screen tales timer
|
||||
modules-gint = core keyboard mmu mpu rtc screen timer \
|
||||
bopti display gray tales
|
||||
modules-libc = setjmp string
|
||||
|
||||
# Targets
|
||||
|
@ -28,7 +29,7 @@ ob = sh3eb-elf-objcopy
|
|||
wr = g1a-wrapper
|
||||
|
||||
# Flags
|
||||
cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11
|
||||
cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os
|
||||
|
||||
# Demo application (could be done better)
|
||||
demo-src = $(notdir $(wildcard demo/*.[cs]))
|
||||
|
@ -40,6 +41,10 @@ demo-elf = build/gintdemo.elf
|
|||
demo-bin = build/gintdemo.bin
|
||||
demo-libs = -lgcc -L. -lgint -lc
|
||||
|
||||
# Specific objects
|
||||
obj-lib-spec = build/display_font_system.bmp.o
|
||||
obj-std-spec =
|
||||
|
||||
|
||||
|
||||
#---
|
||||
|
@ -58,14 +63,16 @@ endef
|
|||
$(foreach mod, $(modules), $(eval \
|
||||
mod-$(mod)-c = $(notdir $(wildcard src/$(mod)/*.c)) $n\
|
||||
mod-$(mod)-asm = $(notdir $(wildcard src/$(mod)/*.s)) $n\
|
||||
mod-$(mod)-dep = $(wildcard include/*.h src/$(mod)/*.h) $n\
|
||||
mod-$(mod)-src = $$(mod-$(mod)-c)$$(mod-$(mod)-asm) $n\
|
||||
mod-$(mod)-obj = $$(patsubst %,build/$(mod)_%.o,$$(mod-$(mod)-src)) \
|
||||
))
|
||||
|
||||
# Target-scope variables.
|
||||
obj-std = $(foreach mod,$(modules-libc),$(mod-$(mod)-obj))
|
||||
obj-lib = $(foreach mod,$(modules-gint),$(mod-$(mod)-obj))
|
||||
obj-std = $(foreach mod,$(modules-libc),$(mod-$(mod)-obj)) $(obj-std-spec)
|
||||
obj-lib = $(foreach mod,$(modules-gint),$(mod-$(mod)-obj)) $(obj-lib-spec)
|
||||
|
||||
# Dependencies
|
||||
hdr-dep = $(wildcard include/*.h include/internals/*.h)
|
||||
|
||||
|
||||
|
||||
|
@ -77,8 +84,8 @@ obj-lib = $(foreach mod,$(modules-gint),$(mod-$(mod)-obj))
|
|||
# $1 module name
|
||||
# $2 filename
|
||||
define rule-c-source
|
||||
build/$1_$2.o: src/$1/$2 $(mod-$1-dep)
|
||||
$(cc) -c $$< -o $$@ $(cflags) -I src/$1 -O2
|
||||
build/$1_$2.o: src/$1/$2 $(hdr-dep)
|
||||
$(cc) -c $$< -o $$@ $(cflags) -I src/$1
|
||||
endef
|
||||
|
||||
# asm source file template:
|
||||
|
@ -98,21 +105,24 @@ endef
|
|||
# Generic rules
|
||||
|
||||
all: build $(target-std) $(target-lib) $(target-g1a)
|
||||
@ echo 'All done!'
|
||||
@echo "[ \033[32;1mOK\033[0m ] All done!"
|
||||
|
||||
build:
|
||||
mkdir -p $@
|
||||
|
||||
$(target-std): $(obj-std)
|
||||
$(ar) rcs $@ $^
|
||||
@echo "[ \033[32;1mOK\033[0m ] libc: `stat -c %s $@` bytes"
|
||||
|
||||
$(target-lib): $(target-std) $(obj-lib)
|
||||
$(ar) rcs $@ $(obj-lib)
|
||||
@echo "[ \033[32;1mOK\033[0m ] libgint: `stat -c %s $@` bytes"
|
||||
|
||||
$(target-g1a): $(target-std) $(target-lib) $(demo-obj)
|
||||
$(cc) -o $(demo-elf) $(cflags) -T $(demo-ld) $(demo-obj) $(demo-libs)
|
||||
$(ob) -R .comment -R .bss -O binary $(demo-elf) $(demo-bin)
|
||||
$(wr) $(demo-bin) -o $@ -i $(demo-icon)
|
||||
@echo "[ \033[32;1mOK\033[0m ] demo app: `stat -c %s $@` bytes"
|
||||
|
||||
# Automated rules
|
||||
|
||||
|
@ -123,22 +133,27 @@ $(foreach mod,$(modules), \
|
|||
$(call rule-asm-source,$(mod),$(source)))) \
|
||||
)
|
||||
|
||||
# Specific rules
|
||||
|
||||
# This one should not be optimized. It makes __attribute__((interrupt_handler))
|
||||
# buggy... maybe. Anyway there's a bug in this file.
|
||||
build/core_gint.c.o: src/core/gint.c $(mod-core-dep)
|
||||
$(cc) -c $< -o $@ $(cflags) -I src/core
|
||||
$(cc) -c $< -o $@ $(cflags) -I src/core -O0
|
||||
|
||||
build/display_font_system.bmp.o: src/display/font_system.bmp
|
||||
fxconv $< -o $@ --font -n gint_font_system
|
||||
|
||||
# Demo application
|
||||
|
||||
build/demo_%.c.o: demo/%.c
|
||||
$(cc) -c $< -o $@ $(cflags)
|
||||
|
||||
build/demo_font_%.bmp.o: demo/resources/font_%.bmp
|
||||
fxconv $< -o $@ --font -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
||||
|
||||
build/demo_%.bmp.o: demo/resources/%.bmp
|
||||
fxconv $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
||||
|
||||
build/demo_font.bmp.o: demo/resources/font.bmp
|
||||
fxconv $< -o $@ --font -n res_font
|
||||
|
||||
|
||||
|
||||
#---
|
||||
|
|
15
TODO
|
@ -10,24 +10,21 @@
|
|||
|
||||
|
||||
@ vram overflow
|
||||
@ keyboard test threading interface
|
||||
@ keyboard test threaded interface
|
||||
|
||||
+ full and partial transparency
|
||||
+ gint vs. ML with 248x124 at (-60, -28)
|
||||
+ use alloca() for tales
|
||||
+ call exit handlers
|
||||
+ compute frequencies
|
||||
+ gray text
|
||||
+ effective rtc callback
|
||||
+ properly test gray drawing
|
||||
+ upgraded blending modes
|
||||
+ blending modes for text
|
||||
+ information masks for text
|
||||
+ test all font encodings
|
||||
+ font clipping
|
||||
+ bitmap parts
|
||||
+ bitmap clipping
|
||||
|
||||
- install critical failure handler to prevent failing resets
|
||||
- improve exception handler debugging information (if possible)
|
||||
- write and test gray engine
|
||||
- full rtc driver (time)
|
||||
- callbacks and complete user API
|
||||
|
@ -35,7 +32,7 @@
|
|||
~ shadowy rectangle effect for Shift + Alpha + Left + Down
|
||||
~ exhaustive save for setjmp()
|
||||
~ registers that need to be saved when configuring gint
|
||||
~ possible bug when -O2 __attribute__((interrupt_handler))
|
||||
~ possible bug when -O2'ing __attribute__((interrupt_handler))
|
||||
|
||||
|
||||
|
||||
|
@ -43,8 +40,8 @@ Some notes
|
|||
----------
|
||||
|
||||
Test cases for bitmap drawing:
|
||||
- aligned 32 / non-aligned 32
|
||||
- 32-alignment
|
||||
- monochrome / gray
|
||||
- small / large
|
||||
- does not overflow / overflows
|
||||
- clipping
|
||||
# blending modes
|
||||
|
|
475
demo/gintdemo.c
|
@ -2,6 +2,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <mpu.h>
|
||||
#include <gint.h>
|
||||
#include <keyboard.h>
|
||||
#include <display.h>
|
||||
#include <timer.h>
|
||||
|
@ -10,62 +11,67 @@
|
|||
#include <stdint.h>
|
||||
#include <7305.h>
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// A few ugly procedures for displaying text. Will have to enhance this
|
||||
// soon -- which means printf().
|
||||
//---
|
||||
|
||||
void print(const char *str, int x, int y)
|
||||
void locate(const char *str, int x, int y)
|
||||
{
|
||||
dtext(str, x, y);
|
||||
if(x < 1 || x > 21 || y < 1 || y > 8) return;
|
||||
if(gray_runs()) gtext(str, x * 6 - 5, y * 8 - 7);
|
||||
else dtext(str, x * 6 - 5, y * 8 - 7);
|
||||
}
|
||||
void print_hex(unsigned int n, int x, int y)
|
||||
|
||||
void locate_hex(unsigned int n, int x, int y)
|
||||
{
|
||||
char ch[11] = "0x";
|
||||
char str[11] = "0x";
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
ch[9 - i] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9);
|
||||
str[9 - i] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9);
|
||||
n >>= 4;
|
||||
}
|
||||
ch[10] = 0;
|
||||
print(ch, x, y);
|
||||
str[10] = 0;
|
||||
locate(str, x, y);
|
||||
}
|
||||
void print_bin(unsigned char n, int x, int y)
|
||||
void locate_bin(unsigned char n, int x, int y)
|
||||
{
|
||||
char ch[9];
|
||||
char str[9];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 8;i ++)
|
||||
{
|
||||
ch[7 - i] = (n & 1) + '0';
|
||||
str[7 - i] = (n & 1) + '0';
|
||||
n >>= 1;
|
||||
}
|
||||
ch[8] = 0;
|
||||
print(ch, x, y);
|
||||
str[8] = 0;
|
||||
locate(str, x, y);
|
||||
}
|
||||
void print_hexa(unsigned int n, int digits, int x, int y)
|
||||
void locate_hexa(unsigned int n, int digits, int x, int y)
|
||||
{
|
||||
char ch[20];
|
||||
char str[20];
|
||||
int i;
|
||||
|
||||
for(i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
ch[i] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9);
|
||||
str[i] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9);
|
||||
n >>= 4;
|
||||
}
|
||||
|
||||
ch[digits] = 0;
|
||||
print(ch, x, y);
|
||||
str[digits] = 0;
|
||||
locate(str, x, y);
|
||||
}
|
||||
void print_int(int n, int x, int y)
|
||||
void locate_int(int n, int x, int y)
|
||||
{
|
||||
char str[20] = { 0 };
|
||||
int i, o = 0;
|
||||
int digits = 0, copy = n;
|
||||
|
||||
if(!n) { str[o++] = '0'; print(str, x, y); return; }
|
||||
if(!n) { str[o++] = '0'; locate(str, x, y); return; }
|
||||
if(n < 0) str[o++] = '-', n = -n;
|
||||
while(copy) digits++, copy /= 10;
|
||||
|
||||
|
@ -75,7 +81,7 @@ void print_int(int n, int x, int y)
|
|||
n /= 10;
|
||||
}
|
||||
|
||||
gtext(str, x, y);
|
||||
locate(str, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,17 +103,17 @@ void keyboard_test_timer(void)
|
|||
|
||||
dclear_area(5, 10, 71, 34);
|
||||
|
||||
print_bin(state[0], 5, 10);
|
||||
print_bin(state[1], 5, 16);
|
||||
print_bin(state[2], 5, 22);
|
||||
print_bin(state[3], 5, 28);
|
||||
print_bin(state[4], 5, 34);
|
||||
locate_bin(state[0], 5, 10);
|
||||
locate_bin(state[1], 5, 16);
|
||||
locate_bin(state[2], 5, 22);
|
||||
locate_bin(state[3], 5, 28);
|
||||
locate_bin(state[4], 5, 34);
|
||||
|
||||
print_bin(state[5], 40, 10);
|
||||
print_bin(state[6], 40, 16);
|
||||
print_bin(state[7], 40, 22);
|
||||
print_bin(state[8], 40, 28);
|
||||
print_bin(state[9], 40, 34);
|
||||
locate_bin(state[5], 40, 10);
|
||||
locate_bin(state[6], 40, 16);
|
||||
locate_bin(state[7], 40, 22);
|
||||
locate_bin(state[8], 40, 28);
|
||||
locate_bin(state[9], 40, 34);
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
@ -127,8 +133,8 @@ void keyboard_test(void)
|
|||
timer_start(TIMER_USER, 1700, TIMER_Po_256, keyboard_test_timer, 0);
|
||||
|
||||
dclear();
|
||||
print("Keyboard state:", 0, 0);
|
||||
print("multi-getkey ^^", 50, 55);
|
||||
locate("Keyboard state:", 0, 0);
|
||||
locate("multi-getkey ^^", 50, 55);
|
||||
dupdate();
|
||||
|
||||
while(1)
|
||||
|
@ -142,14 +148,14 @@ void keyboard_test(void)
|
|||
x = (x + 1) & 15;
|
||||
str[0] = hexa(x);
|
||||
str[1] = 0;
|
||||
print(str, 100, 0);
|
||||
locate(str, 100, 0);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
str[0] = hexa((keys[i] >> 4) & 0x0f);
|
||||
str[1] = hexa(keys[i] & 0x0f);
|
||||
str[2] = 0;
|
||||
print(str, 100, 16 + 10 * i);
|
||||
locate(str, 100, 16 + 10 * i);
|
||||
}
|
||||
|
||||
#undef hexa
|
||||
|
@ -160,10 +166,12 @@ void keyboard_test(void)
|
|||
timer_stop(TIMER_USER);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bitmap_test()
|
||||
Displays various bitmaps to ensure bopti is working correctly.
|
||||
*/
|
||||
/*
|
||||
void bitmap_test(void)
|
||||
{
|
||||
extern Image res_bitmap_opt_start;
|
||||
|
@ -171,12 +179,14 @@ void bitmap_test(void)
|
|||
extern Image res_symbol2_start;
|
||||
extern Image res_sprites_start;
|
||||
extern Image res_swords_start;
|
||||
extern Image res_items_start;
|
||||
|
||||
Image *opt = &res_bitmap_opt_start;
|
||||
Image *sybl = &res_symbol_start;
|
||||
Image *sybl2 = &res_symbol2_start;
|
||||
Image *sprites = &res_sprites_start;
|
||||
Image *swords = &res_swords_start;
|
||||
Image *items = &res_items_start;
|
||||
|
||||
uint32_t a32 = 0xffffffff;
|
||||
int black_bg = 0, gray = 0;
|
||||
|
@ -191,10 +201,9 @@ void bitmap_test(void)
|
|||
gclear();
|
||||
|
||||
if(black_bg) greverse_area(0, 0, 127, 63);
|
||||
gimage(opt, 0, 57);
|
||||
gimage(swords, 0, 57);
|
||||
|
||||
gimage(sprites, x, y);
|
||||
gimage(swords, x, y + 35);
|
||||
gimage(items, x, y);
|
||||
|
||||
gupdate();
|
||||
}
|
||||
|
@ -229,29 +238,28 @@ void bitmap_test(void)
|
|||
gray_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
text_test()
|
||||
Renders text.
|
||||
*/
|
||||
|
||||
void text_test(void)
|
||||
{
|
||||
extern Font res_font_start;
|
||||
Font *font = &res_font_start;
|
||||
extern Font res_font_modern_start;
|
||||
Font *font = &res_font_modern_start;
|
||||
|
||||
text_configure(font);
|
||||
|
||||
dclear();
|
||||
|
||||
print(" !\"#$%&'()*+,-./", 10, 10);
|
||||
print("0123456789:;<=>?", 10, 16);
|
||||
print("@ABCDEFGHIJKLMNO", 10, 22);
|
||||
print("PQRSTUVWXYZ[\\]^_", 10, 28);
|
||||
print("`abcdefghijklmno", 10, 34);
|
||||
print("pqrstuvwxyz{|}~", 10, 40);
|
||||
dtext(" !\"#$%&'()*+,-./", 10, 10);
|
||||
dtext("0123456789:;<=>?", 10, 16);
|
||||
dtext("@ABCDEFGHIJKLMNO", 10, 22);
|
||||
dtext("PQRSTUVWXYZ[\\]^_", 10, 28);
|
||||
dtext("`abcdefghijklmno", 10, 34);
|
||||
dtext("pqrstuvwxyz{|}~", 10, 40);
|
||||
|
||||
dupdate();
|
||||
|
||||
|
@ -264,11 +272,9 @@ void text_test(void)
|
|||
gray_test()
|
||||
Runs the gray engine.
|
||||
*/
|
||||
|
||||
void gray_test(void)
|
||||
{
|
||||
extern Image res_illustration_start;
|
||||
Image *illustration = &res_illustration_start;
|
||||
extern Image res_opt_gray_start;
|
||||
|
||||
int *v1, *v2;
|
||||
|
||||
|
@ -297,16 +303,15 @@ void gray_test(void)
|
|||
-(i < 32);
|
||||
}
|
||||
|
||||
// gimage(illustration, 0, 0);
|
||||
// gclear_area(64, 0, 127, 63);
|
||||
locate("light", 15, 2);
|
||||
locate_int(delays[0], 15, 3);
|
||||
|
||||
gtext("light", 78, 6);
|
||||
print_int(delays[0], 103, 6);
|
||||
locate("dark", 15, 5);
|
||||
locate_int(delays[1], 15, 6);
|
||||
|
||||
gtext("dark", 78, 15);
|
||||
print_int(delays[1], 103, 15);
|
||||
locate("\x02", 14, selected ? 6 : 3);
|
||||
|
||||
gtext(">", 70, selected ? 15 : 6);
|
||||
gimage(&res_opt_gray_start, 0, 56);
|
||||
gupdate();
|
||||
}
|
||||
|
||||
|
@ -320,19 +325,15 @@ void gray_test(void)
|
|||
switch(key)
|
||||
{
|
||||
case KEY_F1:
|
||||
delays[0] = 860;
|
||||
delays[1] = 1298;
|
||||
selected = !selected;
|
||||
break;
|
||||
case KEY_F2:
|
||||
delays[0] = 912;
|
||||
delays[1] = 1343;
|
||||
break;
|
||||
case KEY_F3:
|
||||
delays[0] = 993;
|
||||
delays[1] = 1609;
|
||||
break;
|
||||
case KEY_F6:
|
||||
selected = !selected;
|
||||
case KEY_F3:
|
||||
delays[0] = 860;
|
||||
delays[1] = 1298;
|
||||
break;
|
||||
case KEY_UP:
|
||||
delays[selected] += 10;
|
||||
|
@ -356,56 +357,6 @@ void gray_test(void)
|
|||
}
|
||||
|
||||
/*
|
||||
main_menu()
|
||||
Displays the main menu and returns user's choice.
|
||||
|
||||
@return User choice. 0 means EXIT, other numbers are applications.
|
||||
*/
|
||||
int main_menu(void)
|
||||
{
|
||||
extern unsigned int bgint, egint;
|
||||
const char *mpu_names[] = {
|
||||
"MPU_Unkown",
|
||||
"MPU_SH7337",
|
||||
"MPU_SH7355",
|
||||
"MPU_SH7305",
|
||||
"MPU_SH7724",
|
||||
"MPU Error !"
|
||||
};
|
||||
int key;
|
||||
|
||||
dclear();
|
||||
|
||||
print("gint test application", 19, 1);
|
||||
dline(19, 8, 107, 8, Color_Black);
|
||||
|
||||
print("[1] Keyboard", 10, 17);
|
||||
print("[2] Bitmap drawing", 10, 24);
|
||||
print("[3] Text rendering", 10, 31);
|
||||
print("[4] Gray engine", 10, 38);
|
||||
|
||||
print("mpu type:", 2, 49);
|
||||
print(mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 50, 48);
|
||||
print("gint size:", 2, 56);
|
||||
print_hex(&egint - &bgint, 50, 56);
|
||||
|
||||
dupdate();
|
||||
|
||||
while(1)
|
||||
{
|
||||
key = getkey();
|
||||
if(key == KEY_EXIT) return 0;
|
||||
|
||||
if(key == KEY_1) return 1;
|
||||
if(key == KEY_2) return 2;
|
||||
if(key == KEY_3) return 3;
|
||||
if(key == KEY_4) return 4;
|
||||
if(key == KEY_5) return 5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char 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,
|
||||
|
@ -505,7 +456,7 @@ void ML_bmp_or_cl(const unsigned char *bmp, int x, int y, int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
#include <../src/timer/timer_internals.h>
|
||||
#include <internals/timer.h>
|
||||
void debug(void)
|
||||
{
|
||||
extern Image res_screen_start;
|
||||
|
@ -551,32 +502,292 @@ void debug(void)
|
|||
dupdate();
|
||||
while(getkey() != KEY_EXIT);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
main()
|
||||
Handles application calls.
|
||||
|
||||
@return 0.
|
||||
tlb_debug()
|
||||
Displays the TLB contents and some information. Only available for
|
||||
SH7705, because the SH7305's TLB is much more complicated.
|
||||
*/
|
||||
int main(void)
|
||||
void tlb_debug(void)
|
||||
{
|
||||
extern Font res_font_start;
|
||||
Font *font = &res_font_start;
|
||||
// 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;
|
||||
|
||||
text_configure(font);
|
||||
int i, r, key = 0;
|
||||
int way = 0, entry = 0;
|
||||
int pointer_base;
|
||||
|
||||
int app;
|
||||
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();
|
||||
|
||||
locate("TLB", 1, 1);
|
||||
locate("way=", 8, 1);
|
||||
locate("0\0001\0002\0003" + (way << 1), 12, 1);
|
||||
locate_int(entry, 16 + (entry < 10), 1);
|
||||
locate("-", 18, 1);
|
||||
locate_int((entry + 2 > 31) ? (31) : (entry + 2) , 19, 1);
|
||||
|
||||
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;
|
||||
locate_hexa(pointer_base, 8, 1, r);
|
||||
locate(":", 11, r);
|
||||
locate_hexa(ppn << 10, 8, 12, r);
|
||||
|
||||
r++;
|
||||
locate((d & 0x08) ? "4k" : "1k", 1, r);
|
||||
locate("pr=", 5, r);
|
||||
locate(protection[(d >> 5) & 3], 8, r);
|
||||
locate((d & 0x02) ? "shared" : "exclusive", 13, r);
|
||||
}
|
||||
|
||||
if(entry == 32) entry = 0, way++;
|
||||
|
||||
dupdate();
|
||||
key = getkey();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 res_opt_menu_start;
|
||||
|
||||
const char *mpu, *mpu_names[] = {
|
||||
"Unknown",
|
||||
"SH7337",
|
||||
"SH7355",
|
||||
"SH7305",
|
||||
"SH7724",
|
||||
"[error]"
|
||||
};
|
||||
|
||||
const char *list_tests[] = {
|
||||
"Keyboard",
|
||||
"Gray engine",
|
||||
"Image rendering",
|
||||
"Text rendering",
|
||||
"Real-time clock",
|
||||
NULL
|
||||
};
|
||||
const char *list_perfs[] = {
|
||||
"Image rendering",
|
||||
"Text rendering",
|
||||
NULL
|
||||
};
|
||||
const char *list_debug[] = {
|
||||
"View TLB (SH3 only)",
|
||||
NULL
|
||||
};
|
||||
const char **list;
|
||||
|
||||
extern unsigned int bgint, egint;
|
||||
extern unsigned int romdata;
|
||||
int gint_size = &egint - &bgint;
|
||||
|
||||
|
||||
|
||||
static int tab = 0, index = 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_default();
|
||||
|
||||
while(1)
|
||||
{
|
||||
app = main_menu();
|
||||
if(!app) break;
|
||||
//---
|
||||
// Displaying the current tab.
|
||||
//---
|
||||
|
||||
if(app == 1) keyboard_test();
|
||||
if(app == 2) bitmap_test();
|
||||
if(app == 3) text_test();
|
||||
if(app == 4) gray_test();
|
||||
if(app == 5) debug();
|
||||
dclear();
|
||||
dupdate();
|
||||
|
||||
switch(tab)
|
||||
{
|
||||
case 0:
|
||||
locate("Demo application", 1, 1);
|
||||
locate("gint version:", 2, 3);
|
||||
locate(GINT_VERSION_STR, 16, 3);
|
||||
locate("handler size:", 2, 4);
|
||||
locate_int(gint_size, (gint_size < 1000 ? 18 : 17), 4);
|
||||
locate("mpu type:", 2, 5);
|
||||
locate(mpu, 21 - strlen(mpu), 5);
|
||||
locate("romdata:", 2, 6);
|
||||
locate_hex((unsigned int)&romdata, 11, 6);
|
||||
|
||||
list = NULL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
locate("Test list", 1, 1);
|
||||
list = list_tests;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
locate("Performance", 1, 1);
|
||||
list = list_perfs;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
locate("Debug", 1, 1);
|
||||
list = list_debug;
|
||||
break;
|
||||
|
||||
default:
|
||||
locate("Tab ", 1, 1);
|
||||
locate_int(tab, 5, 1);
|
||||
break;
|
||||
}
|
||||
dimage(&res_opt_menu_start, 0, 56);
|
||||
|
||||
if(list)
|
||||
{
|
||||
for(i = 0; list[i]; i++) locate(list[i], 2, i + 2);
|
||||
dreverse_area(0, 8 * index + 9, 127, 8 * index + 16);
|
||||
}
|
||||
dupdate();
|
||||
|
||||
//---
|
||||
// Waiting for events.
|
||||
//---
|
||||
|
||||
do
|
||||
{
|
||||
leave = 1;
|
||||
|
||||
switch(getkey())
|
||||
{
|
||||
case KEY_F1:
|
||||
tab = 0;
|
||||
index = 0;
|
||||
break;
|
||||
case KEY_F2:
|
||||
tab = 1;
|
||||
index = 0;
|
||||
break;
|
||||
case KEY_F3:
|
||||
tab = 2;
|
||||
index = 0;
|
||||
break;
|
||||
case KEY_F4:
|
||||
tab = 3;
|
||||
index = 0;
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
if(list && index) index--;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if(list && list[index + 1]) index++;
|
||||
break;
|
||||
|
||||
case KEY_EXE:
|
||||
if(!tab) break;
|
||||
if(category) *category = tab;
|
||||
if(app) *app = index + 1;
|
||||
return;
|
||||
|
||||
case KEY_EXIT:
|
||||
case KEY_MENU:
|
||||
if(category) *category = 0;
|
||||
if(app) *app = 0;
|
||||
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:
|
||||
keyboard_test();
|
||||
break;
|
||||
case 0x0102:
|
||||
gray_test();
|
||||
break;
|
||||
case 0x0103:
|
||||
// bitmap_test();
|
||||
break;
|
||||
case 0x0104:
|
||||
text_test();
|
||||
break;
|
||||
case 0x0105:
|
||||
// rtc_test();
|
||||
break;
|
||||
|
||||
case 0x0301:
|
||||
if(isSH3()) tlb_debug();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -17,9 +17,8 @@ ENTRY(_start)
|
|||
MEMORY
|
||||
{
|
||||
rom : o = 0x00300200, l = 512k
|
||||
ram : o = 0x08100000, l = 64k
|
||||
/* The "real ram" accessible length remains unknown because some parts
|
||||
are used by the system. At least 12k seem accessible. Use with care. */
|
||||
/* 0x0810000 is apparently mapped to 0x8801c0000. */
|
||||
ram : o = 0x08100000, l = 8k
|
||||
realram : o = 0x8800d000, l = 12k
|
||||
}
|
||||
|
||||
|
@ -46,6 +45,7 @@ SECTIONS
|
|||
} > rom
|
||||
|
||||
.rodata : {
|
||||
*(.rodata.fxconv);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
|
||||
|
@ -84,16 +84,25 @@ SECTIONS
|
|||
|
||||
|
||||
/*
|
||||
Real RAM : interrupt handler.
|
||||
Real RAM : interrupt, exception and TLB miss handlers.
|
||||
*/
|
||||
|
||||
.gint_int : AT(_gint_data) ALIGN(4) {
|
||||
.gint : AT(_gint_data) ALIGN(4) {
|
||||
/* The vbr needs to be 0x100-aligned because of an ld issue. */
|
||||
. = ALIGN(0x100) ;
|
||||
_gint_vbr = . ;
|
||||
|
||||
_bgint = . ;
|
||||
|
||||
/* Exception handler. */
|
||||
. = _gint_vbr + 0x100 ;
|
||||
*(.gint.exc.entry)
|
||||
*(.gint.exc)
|
||||
|
||||
/* TLB miss handler. */
|
||||
. = _gint_vbr + 0x400 ;
|
||||
*(.gint.tlb.entry)
|
||||
*(.gint.tlb)
|
||||
|
||||
/* Interrupt handler. */
|
||||
. = _gint_vbr + 0x600 ;
|
||||
*(.gint.int.entry)
|
||||
|
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 32 KiB |
BIN
demo/resources/items.bmp
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
demo/resources/opt_gray.bmp
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
demo/resources/opt_menu.bmp
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
gintdemo.g1a
23
include/alloca.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
//---
|
||||
//
|
||||
// gint core module: alloca
|
||||
//
|
||||
// Allows dynamic memory allocation on the stack. Memory is automatically
|
||||
// freed when the calling function exits.
|
||||
//
|
||||
//---
|
||||
|
||||
#ifndef _ALLOCA_H
|
||||
#define _ALLOCA_H 1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
alloca()
|
||||
Allocates a memory block on the stack.
|
||||
*/
|
||||
void *alloca(size_t size);
|
||||
|
||||
#define alloca(size) __builtin_alloca(size)
|
||||
|
||||
#endif // _ALLOCA_H
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef _CTYPE_H
|
||||
#define _CTYPE_H 1
|
||||
#ifndef _CTYPE_H
|
||||
#define _CTYPE_H 1
|
||||
|
||||
// Character definition macros.
|
||||
#define isalnum(c) (isdigit(c) || isalpha(c))
|
||||
|
@ -24,4 +24,4 @@
|
|||
#define tolower(c) (isupper(c) ? (c) | 32 : (c))
|
||||
#define toupper(c) (islower(c) ? (c) & ~32 : (c))
|
||||
|
||||
#endif // _CTYPE_H
|
||||
#endif // _CTYPE_H
|
||||
|
|
130
include/gint.h
|
@ -10,6 +10,9 @@
|
|||
#ifndef _GINT_H
|
||||
#define _GINT_H 1
|
||||
|
||||
#define GINT_VERSION 0x01000000
|
||||
#define GINT_VERSION_STR "01.00"
|
||||
|
||||
//---
|
||||
// Interrupt handler control.
|
||||
//---
|
||||
|
@ -29,42 +32,6 @@ unsigned int gint_systemVBR(void);
|
|||
|
||||
|
||||
|
||||
//---
|
||||
// Callback API.
|
||||
//---
|
||||
|
||||
/*
|
||||
enum RTCFrequency
|
||||
Describes the possible frequencies available for the real-time clock
|
||||
interrupt.
|
||||
*/
|
||||
enum RTCFrequency
|
||||
{
|
||||
RTCFreq_500mHz = 7,
|
||||
RTCFreq_1Hz = 6,
|
||||
RTCFreq_2Hz = 5,
|
||||
RTCFreq_4Hz = 4,
|
||||
RTCFreq_16Hz = 3,
|
||||
RTCFreq_64Hz = 2,
|
||||
RTCFreq_256Hz = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
gint_setRTCCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
*/
|
||||
void gint_setRTCCallback(void (*callback)(void), enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
gint_getRTCCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*gint_getRTCCallback(enum RTCFrequency *frequency))(void);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
// Referenced here for documentation purposes only.
|
||||
|
@ -108,33 +75,86 @@ void gint_setup_7305(void);
|
|||
void gint_stop_7705(void);
|
||||
void gint_stop_7305(void);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Exception handling.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint()
|
||||
gint_exc()
|
||||
Handles exceptions.
|
||||
*/
|
||||
void gint_exc(void) __attribute__((section(".gint.exc.entry"),
|
||||
interrupt_handler));
|
||||
void gint_exc_7705(void) __attribute__((section(".gint.exc")));
|
||||
void gint_exc_7305(void) __attribute__((section(".gint.exc")));
|
||||
|
||||
/*
|
||||
gint_tlb()
|
||||
Handles TLB misses.
|
||||
*/
|
||||
void gint_tlb(void) __attribute__((section(".gint.tlb.entry"),
|
||||
interrupt_handler));
|
||||
void gint_tlb_7705(void) __attribute__((section(".gint.tlb")));
|
||||
void gint_tlb_7305(void) __attribute__((section(".gint.tlb")));
|
||||
|
||||
/*
|
||||
gint_int()
|
||||
Handles interrupts.
|
||||
*/
|
||||
void gint(void) __attribute__((section(".gint.int.entry"),
|
||||
void gint_int(void) __attribute__((section(".gint.int.entry"),
|
||||
interrupt_handler));
|
||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void gint_setRTCFrequency_7705(enum RTCFrequency frequency);
|
||||
void gint_setRTCFrequency_7305(enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7705(void);
|
||||
enum RTCFrequency gint_getRTCFrequency_7305(void);
|
||||
void gint_int_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_int_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal priority definitions.
|
||||
// Register access.
|
||||
//---
|
||||
|
||||
/*
|
||||
enum Register
|
||||
Represents common registers. Used as identifiers to retrieve their
|
||||
values using gint_register().
|
||||
*/
|
||||
enum Register
|
||||
{
|
||||
Register_EXPEVT,
|
||||
Register_MMUCR,
|
||||
Register_TEA,
|
||||
};
|
||||
|
||||
/*
|
||||
gint_register()
|
||||
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(enum Register reg);
|
||||
volatile void *gint_reg_7705(enum Register reg);
|
||||
volatile void *gint_reg_7305(enum Register reg);
|
||||
|
||||
/*
|
||||
gint_strerror()
|
||||
Returns a string that describe the error set in EXPEVT in case of
|
||||
general exception of TLB miss exception. This string is platform-
|
||||
independent.
|
||||
Some exception codes represent different errors when invoked inside the
|
||||
general exception handler and the TLB error handler. Parameter 'is_tlb'
|
||||
should be set to zero for general exception meanings, and anything non-
|
||||
zero for TLB error meanings.
|
||||
*/
|
||||
const char *gint_strerror(int is_tlb);
|
||||
const char *gint_strerror_7705(int is_tlb);
|
||||
const char *gint_strerror_7305(int is_tlb);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal platform-independent definitions.
|
||||
//---
|
||||
|
||||
#define GINT_INTP_WDT 4
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#ifndef _BOPTI_INTERNALS_H
|
||||
#define _BOPTI_INTERNALS_H 1
|
||||
#ifndef _INTERNALS_BOPTI_H
|
||||
#define _INTERNALS_BOPTI_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <display.h>
|
||||
|
@ -157,4 +157,4 @@ void bopti(const unsigned char *layer, struct Structure *s, struct Command *c);
|
|||
*/
|
||||
void getStructure(struct Image *img, struct Structure *structure);
|
||||
|
||||
#endif // _BOPTI_INTERNALS_H
|
||||
#endif // _INTERNALS_BOPTI_H
|
|
@ -6,9 +6,9 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#ifndef _DISPLAY_INTERNALS_H
|
||||
#define _DISPLAY_INTERNALS_H
|
||||
#ifndef _INTERNALS_DISPLAY_H
|
||||
#define _INTERNALS_DISPLAY_H 1
|
||||
|
||||
extern int *vram;
|
||||
|
||||
#endif // _DISPLAY_INTERNALS_H
|
||||
#endif // _INTERNALS_DISPLAY_H
|
30
include/internals/gint.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef _INTERNALS_GINT_H
|
||||
#define _INTERNALS_GINT_H 1
|
||||
|
||||
//---
|
||||
// Exception code strings.
|
||||
//---
|
||||
|
||||
extern const char *gint_str[];
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Register access.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_spc()
|
||||
Returns the saved program counter, which is the last state of execution
|
||||
saved by interrupt processing.
|
||||
*/
|
||||
unsigned int gint_spc(void);
|
||||
|
||||
/*
|
||||
gint_ssr()
|
||||
Returns the saved status register, which is the last configuration
|
||||
saved by interrupt processing.
|
||||
*/
|
||||
unsigned int gint_ssr(void);
|
||||
|
||||
#endif // _INTERNALS_GINT_H
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef _KEYBOARD_INTERNALS_H
|
||||
#define _KEYBOARD_INTERNALS_H 1
|
||||
#ifndef _INTERNALS_KEYBOARD_H
|
||||
#define _INTERNALS_KEYBOARD_H 1
|
||||
|
||||
#include <keyboard.h>
|
||||
|
||||
|
@ -31,4 +31,4 @@ int getPressedKey(volatile unsigned char *keyboard_state);
|
|||
int getPressedKeys(volatile unsigned char *keyboard_state, int *keys,
|
||||
int count);
|
||||
|
||||
#endif // _KEYBOARD_INTERNALS_H
|
||||
#endif // _INTERNALS_KEYBOARD_H
|
21
include/internals/mmu.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
//---
|
||||
//
|
||||
// gint core module: mmu
|
||||
//
|
||||
// A wise application should avoid tampering with the system's
|
||||
// configuration of the MMU and the TLB. This module implicitly calls the
|
||||
// system but does nothing by itself.
|
||||
//
|
||||
//---
|
||||
|
||||
#ifndef _MMU_H
|
||||
#define _MMU_H 1
|
||||
|
||||
/*
|
||||
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
|
|
@ -7,8 +7,8 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#ifndef _TALES_INTERNALS_H
|
||||
#define _TALES_INTERNALS_H 1
|
||||
#ifndef _INTERNALS_TALES_H
|
||||
#define _INTERNALS_TALES_H 1
|
||||
|
||||
#include <tales.h>
|
||||
#include <stdint.h>
|
||||
|
@ -44,4 +44,4 @@ void operate(uint32_t *operators, int height, int x, int y);
|
|||
*/
|
||||
int update(uint32_t *operators, int height, int available, uint32_t *glyph);
|
||||
|
||||
#endif // _TALES_INTERNALS_H
|
||||
#endif // _INTERNALS_TALES_H
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef _TIMER_INTERNALS_H
|
||||
#define _TIMER_INTERNALS_H
|
||||
#ifndef _INTERNALS_TIMER_H
|
||||
#define _INTERNALS_TIMER_H 1
|
||||
|
||||
/*
|
||||
struct Timer
|
||||
|
@ -51,4 +51,4 @@ struct mod_tmu
|
|||
*/
|
||||
void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr);
|
||||
|
||||
#endif // _TIMER_INTERNALS_H
|
||||
#endif // _INTERNALS_TIMER_H
|
76
include/rtc.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
//---
|
||||
//
|
||||
// gint core module: rtc
|
||||
//
|
||||
// Manages RTC. This module is used behind standard module time.
|
||||
//
|
||||
//---
|
||||
|
||||
#ifndef _RTC_H
|
||||
#define _RTC_H 1
|
||||
|
||||
//---
|
||||
// Callback API.
|
||||
//---
|
||||
|
||||
/*
|
||||
enum RTCFrequency
|
||||
Describes the possible frequencies available for the real-time clock
|
||||
interrupt.
|
||||
*/
|
||||
enum RTCFrequency
|
||||
{
|
||||
RTCFreq_500mHz = 7,
|
||||
RTCFreq_1Hz = 6,
|
||||
RTCFreq_2Hz = 5,
|
||||
RTCFreq_4Hz = 4,
|
||||
RTCFreq_16Hz = 3,
|
||||
RTCFreq_64Hz = 2,
|
||||
RTCFreq_256Hz = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
rtc_setCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-zero, the clock frequency is set to the given value.
|
||||
Set the callback to NULL to deactivate an existing callback.
|
||||
*/
|
||||
void rtc_setCallback(void (*callback)(void), enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
rtc_getCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*rtc_getCallback(enum RTCFrequency *frequency))(void);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
// Referenced here for documentation purposes only. Do not call.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt(void) __attribute__((section(".gint.int")));
|
||||
void rtc_interrupt_7705(void) __attribute__((section(".gint.int")));
|
||||
void rtc_interrupt_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void rtc_setFrequency_7705(enum RTCFrequency frequency);
|
||||
void rtc_setFrequency_7305(enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency rtc_getFrequency_7705(void);
|
||||
enum RTCFrequency rtc_getFrequency_7305(void);
|
||||
|
||||
#endif // _RTC_H
|
|
@ -8,7 +8,7 @@
|
|||
//---
|
||||
|
||||
/*
|
||||
memcpy()
|
||||
memcpy() O(byte_number)
|
||||
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.
|
||||
|
@ -16,9 +16,21 @@
|
|||
void *memcpy(void *destination, const void *source, size_t byte_number);
|
||||
|
||||
/*
|
||||
memset()
|
||||
memset() O(byte_number)
|
||||
Sets the contents of a memory area. A smart copy is performed.
|
||||
*/
|
||||
void *memset(void *destination, int byte, size_t byte_number);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// String manipulation.
|
||||
//---
|
||||
|
||||
/*
|
||||
strlen() O(length)
|
||||
Returns the length of a string.
|
||||
*/
|
||||
size_t strlen(const char *str);
|
||||
|
||||
#endif // _STRING_H
|
||||
|
|
|
@ -95,6 +95,12 @@ typedef struct Font Font;
|
|||
*/
|
||||
void text_configure(struct Font *font);
|
||||
|
||||
/*
|
||||
text_configure_default()
|
||||
Configures tales with the default font (which is part of gint).
|
||||
*/
|
||||
void text_configure_default(void) __attribute__((constructor));
|
||||
|
||||
/*
|
||||
dtext()
|
||||
Prints the given string, without any analysis.
|
||||
|
|
BIN
libc.a
BIN
libgint.a
|
@ -1,4 +1,4 @@
|
|||
#include <bopti_internals.h>
|
||||
#include <internals/bopti.h>
|
||||
|
||||
// Monochrome video ram, light and dark buffers (in this order).
|
||||
int *vram, *v1, *v2;
|
||||
|
@ -103,6 +103,7 @@ void bopti_grid(const uint32_t *layer, int column_count, int height,
|
|||
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;
|
||||
|
@ -117,12 +118,19 @@ void bopti_grid(const uint32_t *layer, int column_count, int height,
|
|||
p1 = layer - height;
|
||||
p2 = layer;
|
||||
|
||||
// We don't want to write the first vram column when x is negative.
|
||||
// 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 <= column_count)
|
||||
while(right_column <= actual_column_count)
|
||||
{
|
||||
for(line = c->top; line < c->bottom; line++)
|
||||
{
|
||||
|
@ -311,7 +319,7 @@ void getStructure(struct Image *img, struct Structure *s)
|
|||
}
|
||||
|
||||
// The layer size must be rounded to a multiple of 4.
|
||||
layer = img->height * ((column_count << 2) + end_bytes);
|
||||
layer = s->height * ((column_count << 2) + end_bytes);
|
||||
if(layer & 3) layer += 4 - (layer & 3);
|
||||
|
||||
s->columns = column_count;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <bopti_internals.h>
|
||||
#include <internals/bopti.h>
|
||||
#include <display.h>
|
||||
|
||||
/*
|
||||
|
@ -29,11 +29,10 @@ void dimage(struct Image *img, int x, int y)
|
|||
actual_width = (x + s.width > 128) ? (128 - x) : (s.width);
|
||||
command.right = ((actual_width + 31) >> 5) - 1;
|
||||
|
||||
command.x = x;
|
||||
command.y = y;
|
||||
command.op = bopti_op_mono;
|
||||
|
||||
getMasks(x, x + actual_width - 1, command.masks);
|
||||
if(x >= 0) getMasks(x, x + actual_width - 1, command.masks);
|
||||
else getMasks(0, actual_width + x - 1, command.masks);
|
||||
|
||||
vram = display_getCurrentVRAM();
|
||||
|
||||
|
@ -42,7 +41,11 @@ void dimage(struct Image *img, int x, int y)
|
|||
// Drawing every layer, in order of formats.
|
||||
if(format & 1)
|
||||
{
|
||||
// These members are modified by bopti()!
|
||||
command.x = x;
|
||||
command.y = y;
|
||||
command.channel = (1 << i);
|
||||
|
||||
bopti(s.data, &s, &command);
|
||||
s.data += s.layer_size;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <bopti_internals.h>
|
||||
#include <internals/bopti.h>
|
||||
#include <display.h>
|
||||
#include <gray.h>
|
||||
|
||||
|
@ -20,7 +20,7 @@ void gimage(struct Image *img, int x, int y)
|
|||
//---
|
||||
// Adjusting image parameters.
|
||||
//---
|
||||
//-65:-68
|
||||
|
||||
if(x + s.width < 0 || x > 127 || y + s.height < 0 || y > 63) return;
|
||||
|
||||
command.top = (y < 0) ? (-y) : (0);
|
||||
|
@ -54,5 +54,4 @@ void gimage(struct Image *img, int x, int y)
|
|||
format >>= 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <gint.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <gint.h>
|
||||
#include <internals/mmu.h>
|
||||
|
||||
void __Hmem_SetMMU(unsigned int, unsigned int, int);
|
||||
void __GLibAddinAplExecutionCheck(int, int, int);
|
||||
int main(void);
|
||||
|
@ -42,9 +44,6 @@ int start(void)
|
|||
unsigned int *data = &bdata, *src = &romdata;
|
||||
int x;
|
||||
|
||||
// Setting up the TLB.
|
||||
__Hmem_SetMMU(0x08102000, 0x8801e000, 108);
|
||||
|
||||
// Clearing the .bss section.
|
||||
while(bss < &ebss) *bss++ = 0;
|
||||
// Copying the .data section.
|
||||
|
@ -52,6 +51,8 @@ int start(void)
|
|||
|
||||
__GLibAddinAplExecutionCheck(0, 1, 1);
|
||||
|
||||
mmu_pseudoTLBInit();
|
||||
|
||||
// Initializing everything.
|
||||
gint_init();
|
||||
init();
|
||||
|
|
155
src/core/gint.c
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#include <internals/gint.h>
|
||||
#include <gint.h>
|
||||
#include <mpu.h>
|
||||
#include <stddef.h>
|
||||
|
@ -63,18 +64,6 @@ inline unsigned int gint_systemVBR(void)
|
|||
return sys_vbr;
|
||||
}
|
||||
|
||||
/*
|
||||
gint()
|
||||
Handles interrupts.
|
||||
*/
|
||||
void gint(void)
|
||||
{
|
||||
if(isSH3())
|
||||
gint_7705();
|
||||
else
|
||||
gint_7305();
|
||||
}
|
||||
|
||||
/*
|
||||
gint_init()
|
||||
Initializes gint. Loads the interrupt handler into the memory and sets
|
||||
|
@ -113,3 +102,145 @@ void gint_quit(void)
|
|||
{
|
||||
gint_setVBR(sys_vbr, gint_stop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// VBR space.
|
||||
//---
|
||||
|
||||
#include <display.h>
|
||||
#define print(str, x, y) dtext(str, 6 * (x) - 5, 8 * (y) - 7)
|
||||
#define hexdigit(n) ((n) + '0' + 39 * ((n) > 9))
|
||||
|
||||
void hex(unsigned int x, int digits, char *str)
|
||||
{
|
||||
str[0] = '0';
|
||||
str[1] = 'x';
|
||||
str[digits + 2] = 0;
|
||||
|
||||
while(digits)
|
||||
{
|
||||
str[digits + 1] = hexdigit(x & 0xf);
|
||||
x >>= 4;
|
||||
digits--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
gint_exc()
|
||||
Handles exceptions.
|
||||
*/
|
||||
void gint_exc(void)
|
||||
{
|
||||
volatile unsigned int *expevt = gint_reg(Register_EXPEVT);
|
||||
volatile unsigned int *tea = gint_reg(Register_TEA);
|
||||
unsigned int spc;
|
||||
char str[11];
|
||||
|
||||
text_configure_default();
|
||||
|
||||
__asm__("\tstc spc, %0" : "=r"(spc));
|
||||
|
||||
dclear();
|
||||
print("Exception raised!", 3, 1);
|
||||
dreverse_area(0, 0, 127, 8);
|
||||
print(gint_strerror(0), 2, 3);
|
||||
|
||||
print("expevt", 2, 4);
|
||||
hex(*expevt, 3, str);
|
||||
print(str, 16, 4);
|
||||
|
||||
print("pc", 2, 5);
|
||||
hex(spc, 8, str);
|
||||
print(str, 11, 5);
|
||||
|
||||
print("tea", 2, 6);
|
||||
hex(*tea, 8, str);
|
||||
print(str, 11, 6);
|
||||
|
||||
print("Please reset.", 2, 7);
|
||||
dupdate();
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
gint_tlb()
|
||||
Handles TLB misses.
|
||||
*/
|
||||
void gint_tlb(void)
|
||||
{
|
||||
volatile unsigned int *expevt = gint_reg(Register_EXPEVT);
|
||||
volatile unsigned int *tea = gint_reg(Register_TEA);
|
||||
unsigned int spc;
|
||||
char str[11];
|
||||
|
||||
text_configure_default();
|
||||
|
||||
__asm__("\tstc spc, %0" : "=r"(spc));
|
||||
|
||||
dclear();
|
||||
print("TLB error!", 6, 1);
|
||||
dreverse_area(0, 0, 127, 8);
|
||||
print(gint_strerror(1), 2, 3);
|
||||
|
||||
print("expevt", 2, 4);
|
||||
hex(*expevt, 3, str);
|
||||
print(str, 16, 4);
|
||||
|
||||
print("pc", 2, 5);
|
||||
hex(spc, 8, str);
|
||||
print(str, 11, 5);
|
||||
|
||||
print("tea", 2, 6);
|
||||
hex(*tea, 8, str);
|
||||
print(str, 11, 6);
|
||||
|
||||
print("Please reset.", 2, 7);
|
||||
dupdate();
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
gint_int()
|
||||
Handles interrupts.
|
||||
*/
|
||||
void gint_int(void)
|
||||
{
|
||||
if(isSH3())
|
||||
gint_int_7705();
|
||||
else
|
||||
gint_int_7305();
|
||||
}
|
||||
|
||||
/*
|
||||
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).
|
||||
*/
|
||||
inline volatile void *gint_reg(enum Register reg)
|
||||
{
|
||||
if(isSH3())
|
||||
return gint_reg_7705(reg);
|
||||
else
|
||||
return gint_reg_7305(reg);
|
||||
}
|
||||
|
||||
/*
|
||||
gint_strerror()
|
||||
Returns a string that describe the error set in EXPEVT. This string is
|
||||
not platform-dependent.
|
||||
Some exception codes represent different errors when invoked inside the
|
||||
general exception handler and the TLB error handler. Parameter 'is_tlb'
|
||||
should be set to zero for general exception meanings, and anything non-
|
||||
zero for TLB error meanings.
|
||||
*/
|
||||
const char *gint_strerror(int is_tlb)
|
||||
{
|
||||
if(isSH3())
|
||||
return gint_strerror_7705(is_tlb);
|
||||
else
|
||||
return gint_strerror_7305(is_tlb);
|
||||
}
|
||||
|
|
37
src/core/gint_str.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <internals/gint.h>
|
||||
|
||||
const char *gint_str[] = {
|
||||
"Unknown",
|
||||
|
||||
// User breaks.
|
||||
"User break (before)",
|
||||
"User break (after)",
|
||||
"User breakpoint",
|
||||
|
||||
// General.
|
||||
"Inst. address error",
|
||||
"Data access error",
|
||||
"Illegal instruction",
|
||||
"Illegal slot",
|
||||
"Data address (r)",
|
||||
"Data address (w)",
|
||||
|
||||
// Instruction TLB.
|
||||
"Inst. TLB miss",
|
||||
"Inst. TLB invalid",
|
||||
"Inst. TLB protect.",
|
||||
|
||||
// Data TLB.
|
||||
"Data TLB miss",
|
||||
"Data TLB miss (r)",
|
||||
"Data TLB miss (w)",
|
||||
"Data TLB protection",
|
||||
"Data TLB prot. (r)",
|
||||
"Data TLB prot. (w)",
|
||||
"Data TLB invalid",
|
||||
|
||||
// Others.
|
||||
"Initial page write",
|
||||
"Trap",
|
||||
"DMA address error",
|
||||
};
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
gint core module: syscalls
|
||||
|
||||
All the system calls used by the library. Let's hope one day we won't
|
||||
depend on them anymore.
|
||||
All the system calls used by the library. Somehow "the less, the
|
||||
better".
|
||||
*/
|
||||
|
||||
.global ___Hmem_SetMMU
|
||||
.global ___GLibAddinAplExecutionCheck
|
||||
.global _malloc
|
||||
.global _calloc
|
||||
|
@ -13,13 +12,6 @@
|
|||
|
||||
|
||||
|
||||
___Hmem_SetMMU:
|
||||
mov.l syscall_table, r2
|
||||
mov.l 1f, r0
|
||||
jmp @r2
|
||||
nop
|
||||
1: .long 0x3fa
|
||||
|
||||
___GLibAddinAplExecutionCheck:
|
||||
mov.l syscall_table, r2
|
||||
mov #0x13, r0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
|
||||
/*
|
||||
adjustRectangle()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
|
||||
#define sgn(x) ((x) < 0 ? -1 : 1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <display_internals.h>
|
||||
#include <internals/display.h>
|
||||
#include <display.h>
|
||||
#include <screen.h>
|
||||
#include <gray.h>
|
||||
|
|
BIN
src/display/font_system.bmp
Normal file
After Width: | Height: | Size: 32 KiB |
|
@ -1,4 +1,4 @@
|
|||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
/*
|
||||
getPressedKey()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
/*
|
||||
getPressedKeys()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/keyboard.h>
|
||||
#include <keyboard.h>
|
||||
#include <keyboard_internals.h>
|
||||
|
||||
/*
|
||||
getkey()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/keyboard.h>
|
||||
#include <keyboard.h>
|
||||
#include <keyboard_internals.h>
|
||||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <timer.h>
|
||||
#include <mpu.h>
|
||||
|
||||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
//---
|
||||
// Keyboard variables.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <keyboard.h>
|
||||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
/*
|
||||
keylast()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <keyboard.h>
|
||||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
/*
|
||||
multigetkey()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <keyboard_internals.h>
|
||||
#include <internals/keyboard.h>
|
||||
|
||||
/*
|
||||
sleep()
|
||||
|
|
25
src/mmu/pseudoTLBInit.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <internals/mmu.h>
|
||||
|
||||
/*
|
||||
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 unsigned int romdata;
|
||||
unsigned int address = 0x00300000;
|
||||
unsigned int x;
|
||||
|
||||
while(address <= (unsigned int)&romdata)
|
||||
{
|
||||
x = *((volatile unsigned int *)address);
|
||||
address += 0x1000;
|
||||
}
|
||||
}
|
|
@ -8,9 +8,13 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#include <internals/gint.h>
|
||||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <7305.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// Interrupt codes.
|
||||
|
@ -25,10 +29,10 @@
|
|||
|
||||
|
||||
//---
|
||||
// Interrupt handler.
|
||||
// Exception handling.
|
||||
//---
|
||||
|
||||
void gint_7305(void)
|
||||
void gint_int_7305(void)
|
||||
{
|
||||
volatile unsigned int *intevt = (unsigned int *)0xff000028;
|
||||
unsigned int code = *intevt;
|
||||
|
@ -36,7 +40,7 @@ void gint_7305(void)
|
|||
switch(code)
|
||||
{
|
||||
case IC_RTC_PRI:
|
||||
RTC.RCR2.PEF = 0;
|
||||
rtc_interrupt();
|
||||
break;
|
||||
|
||||
case IC_TMU0_TUNI0:
|
||||
|
@ -53,6 +57,58 @@ void gint_7305(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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(enum Register reg)
|
||||
{
|
||||
volatile unsigned int *expevt = (unsigned int *)0xff000024;
|
||||
volatile unsigned int *tea = (unsigned int *)0xff00000c;
|
||||
volatile unsigned int *mmucr = (unsigned int *)0xff000010;
|
||||
|
||||
switch(reg)
|
||||
{
|
||||
case Register_EXPEVT: return expevt;
|
||||
case Register_TEA: return tea;
|
||||
case Register_MMUCR: return mmucr;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
gint_strerror()
|
||||
Returns a string that describe the error set in EXPEVT. This string is
|
||||
not platform-dependent.
|
||||
Some exception codes represent different errors when invoked inside the
|
||||
general exception handler and the TLB error handler. Parameter 'is_tlb'
|
||||
should be set to zero for general exception meanings, and anything non-
|
||||
zero for TLB error meanings.
|
||||
*/
|
||||
const char *gint_strerror_7305(int is_tlb)
|
||||
{
|
||||
volatile unsigned int *expevt = gint_reg_7305(Register_EXPEVT);
|
||||
|
||||
switch(*expevt)
|
||||
{
|
||||
case 0x1e0: return gint_str[3];
|
||||
case 0x0e0: return gint_str[8];
|
||||
case 0x040: return gint_str[14];
|
||||
case 0x0a0: return gint_str[17];
|
||||
case 0x180: return gint_str[6];
|
||||
case 0x1a0: return gint_str[7];
|
||||
case 0x100: return gint_str[9];
|
||||
case 0x060: return gint_str[15];
|
||||
case 0x0c0: return gint_str[18];
|
||||
case 0x080: return gint_str[20];
|
||||
case 0x160: return gint_str[21];
|
||||
}
|
||||
return gint_str[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#include <internals/gint.h>
|
||||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <7705.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// Interrupt codes.
|
||||
|
@ -25,10 +29,10 @@
|
|||
|
||||
|
||||
//---
|
||||
// Interrupt handler.
|
||||
// Exception handling.
|
||||
//---
|
||||
|
||||
void gint_7705(void)
|
||||
void gint_int_7705(void)
|
||||
{
|
||||
volatile unsigned int *intevt2 = (unsigned int *)0xa4000000;
|
||||
unsigned int code = *intevt2;
|
||||
|
@ -36,7 +40,7 @@ void gint_7705(void)
|
|||
switch(code)
|
||||
{
|
||||
case IC_RTC_PRI:
|
||||
RTC.RCR2.BIT.PEF = 0;
|
||||
rtc_interrupt();
|
||||
break;
|
||||
|
||||
case IC_TMU0_TUNI0:
|
||||
|
@ -53,6 +57,59 @@ void gint_7705(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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(enum Register reg)
|
||||
{
|
||||
volatile unsigned int *expevt = (unsigned int *)0xffffffd4;
|
||||
volatile unsigned int *mmucr = (unsigned int *)0xfffffff4;
|
||||
volatile unsigned int *tea = (unsigned int *)0xfffffffc;
|
||||
|
||||
switch(reg)
|
||||
{
|
||||
case Register_EXPEVT: return expevt;
|
||||
case Register_MMUCR: return mmucr;
|
||||
case Register_TEA: return tea;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
gint_strerror()
|
||||
Returns a string that describe the error set in EXPEVT. This string is
|
||||
not platform-dependent.
|
||||
Some exception codes represent different errors when invoked inside the
|
||||
general exception handler and the TLB error handler. Parameter 'is_tlb'
|
||||
should be set to zero for general exception meanings, and anything non-
|
||||
zero for TLB error meanings.
|
||||
*/
|
||||
const char *gint_strerror_7705(int is_tlb)
|
||||
{
|
||||
volatile unsigned int *expevt = gint_reg_7705(Register_EXPEVT);
|
||||
|
||||
switch(*expevt)
|
||||
{
|
||||
case 0x1e0: return gint_str[3];
|
||||
case 0x0e0: return gint_str[4];
|
||||
case 0x040: return gint_str[is_tlb ? 10 : 11];
|
||||
case 0x0a0: return gint_str[12];
|
||||
case 0x180: return gint_str[6];
|
||||
case 0x1a0: return gint_str[7];
|
||||
case 0x100: return gint_str[5];
|
||||
case 0x060: return gint_str[is_tlb ? 13 : 19];
|
||||
case 0x0c0: return gint_str[16];
|
||||
case 0x080: return gint_str[20];
|
||||
case 0x160: return gint_str[21];
|
||||
case 0x5c0: return gint_str[22];
|
||||
}
|
||||
return gint_str[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <keyboard.h>
|
||||
#include <7305.h>
|
||||
#include <rtc.h>
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void gint_setRTCFrequency_7305(enum RTCFrequency frequency)
|
||||
void rtc_setFrequency_7305(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7305(void)
|
||||
enum RTCFrequency rtc_getFrequency_7305(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt_7305(void)
|
||||
{
|
||||
RTC.RCR2.PEF = 0;
|
||||
}
|
|
@ -1,27 +1,34 @@
|
|||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <keyboard.h>
|
||||
#include <7705.h>
|
||||
#include <rtc.h>
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void gint_setRTCFrequency_7705(enum RTCFrequency frequency)
|
||||
void rtc_setFrequency_7705(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7705(void)
|
||||
enum RTCFrequency rtc_getFrequency_7705(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt_7705(void)
|
||||
{
|
||||
RTC.RCR2.BIT.PEF = 0;
|
||||
}
|
|
@ -1,31 +1,32 @@
|
|||
#include <gint.h>
|
||||
#include <rtc.h>
|
||||
#include <mpu.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
static void (*rtc_callback)(void) = NULL;
|
||||
|
||||
//---
|
||||
// Callback API.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_setRTCCallback()
|
||||
rtc_setCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
|
||||
@arg callback Callback function.
|
||||
@arg frequency Interrupt frequency.
|
||||
*/
|
||||
void gint_setRTCCallback(void (*callback)(void), enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
rtc_callback = callback;
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
|
||||
if(isSH3())
|
||||
gint_setRTCFrequency_7705(frequency);
|
||||
rtc_setFrequency_7705(frequency);
|
||||
else
|
||||
gint_setRTCFrequency_7305(frequency);
|
||||
rtc_setFrequency_7305(frequency);
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCCallback()
|
||||
rtc_getCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
|
@ -34,9 +35,29 @@ void (*gint_getRTCCallback(enum RTCFrequency *frequency))(void)
|
|||
if(!frequency) return rtc_callback;
|
||||
|
||||
if(isSH3())
|
||||
*frequency = gint_getRTCFrequency_7705();
|
||||
*frequency = rtc_getFrequency_7705();
|
||||
else
|
||||
*frequency = gint_getRTCFrequency_7305();
|
||||
*frequency = rtc_getFrequency_7305();
|
||||
|
||||
return rtc_callback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt management.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt(void)
|
||||
{
|
||||
if(rtc_callback) (*rtc_callback)();
|
||||
|
||||
if(isSH3())
|
||||
rtc_interrupt_7705();
|
||||
else
|
||||
rtc_interrupt_7305();
|
||||
}
|
12
src/string/strlen.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
strlen()
|
||||
Returns the length of a string.
|
||||
*/
|
||||
size_t strlen(const char *str)
|
||||
{
|
||||
int len = 0;
|
||||
while(str[len]) len++;
|
||||
return len;
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
#include <tales_internals.h>
|
||||
#include <internals/tales.h>
|
||||
#include <tales.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
/*
|
||||
dtext()
|
||||
|
@ -24,6 +25,8 @@ void dtext(const char *str, int x, int y)
|
|||
// format requires it: it allows greater optimization.
|
||||
int height;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
if(!font) return;
|
||||
|
@ -32,7 +35,8 @@ void dtext(const char *str, int x, int y)
|
|||
height = font->data_height;
|
||||
if(x > 127 || y > 63 || y <= -height) return;
|
||||
|
||||
operators = calloc(height, sizeof(uint32_t));
|
||||
operators = alloca(height * sizeof(uint32_t));
|
||||
for(i = 0; i < height; i++) operators[i] = 0;
|
||||
if(!operators) return;
|
||||
|
||||
// Computing the initial operator offset to have 32-aligned operators.
|
||||
|
@ -84,5 +88,5 @@ void dtext(const char *str, int x, int y)
|
|||
// Final operation.
|
||||
if(x <= 96 && available < 32) operate(operators, height, x, y);
|
||||
|
||||
free(operators);
|
||||
// free(operators);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <tales_internals.h>
|
||||
#include <internals/tales.h>
|
||||
#include <tales.h>
|
||||
|
||||
/*
|
||||
|
@ -9,3 +9,13 @@ void text_configure(struct Font *next_font)
|
|||
{
|
||||
font = next_font;
|
||||
}
|
||||
|
||||
/*
|
||||
text_configure_default()
|
||||
Configures tales with the default font (which is part of gint).
|
||||
*/
|
||||
void text_configure_default(void)
|
||||
{
|
||||
extern Font gint_font_system_start;
|
||||
text_configure(&gint_font_system_start);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <tales_internals.h>
|
||||
#include <internals/tales.h>
|
||||
#include <ctype.h>
|
||||
|
||||
struct Font *font;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <timer_internals.h>
|
||||
#include <internals/timer.h>
|
||||
#include <mpu.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/timer.h>
|
||||
#include <timer.h>
|
||||
#include <timer_internals.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/timer.h>
|
||||
#include <timer.h>
|
||||
#include <timer_internals.h>
|
||||
|
||||
/*
|
||||
timer_reload()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/timer.h>
|
||||
#include <timer.h>
|
||||
#include <timer_internals.h>
|
||||
|
||||
/*
|
||||
timer_start()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <internals/timer.h>
|
||||
#include <timer.h>
|
||||
#include <timer_internals.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|