mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
First gray tests. Added text module, 'tales'.
This commit is contained in:
parent
f27ba1129a
commit
aa0f4b7285
24 changed files with 765 additions and 198 deletions
15
Makefile
15
Makefile
|
@ -37,23 +37,25 @@ lib = -lgcc -L. -lgint -lc
|
|||
# Gint library.
|
||||
src-lib = crt0.c syscalls.s \
|
||||
gint.c gint_vbr.s gint_7705.c gint_7305.c \
|
||||
mpu.c keyboard.c screen.c display.c bopti.c gray.c timer.c
|
||||
mpu.c keyboard.c screen.c display.c gray.c timer.c tales.c \
|
||||
bopti.c
|
||||
hea-lib = 7305.h 7705.h gint.h \
|
||||
stdlib.h \
|
||||
mpu.h keyboard.h screen.h display.h gray.h timer.h
|
||||
mpu.h keyboard.h screen.h display.h gray.h timer.h tales.h
|
||||
obj-lib = $(addprefix build/, $(addsuffix .o, $(src-lib)))
|
||||
hdr-lib = $(addprefix include/, $(hea-lib))
|
||||
|
||||
# Standard library.
|
||||
src-std = setjmp.s string.c
|
||||
hea-std = setjmp.h string.h
|
||||
hea-std = setjmp.h string.h ctype.h
|
||||
obj-std = $(addprefix build/, $(addsuffix .o, $(src-std)))
|
||||
hdr-std = $(addprefix include/, $(hea-std))
|
||||
|
||||
# Test application.
|
||||
src-app = ginttest.c
|
||||
img-app = bitmap_opt.bmp swords.bmp sprites.bmp symbol.bmp symbol2.bmp
|
||||
res-app = $(addprefix build/, $(addsuffix .o, $(img-app)))
|
||||
img-app = bitmap_opt.bmp swords.bmp sprites.bmp symbol.bmp symbol2.bmp \
|
||||
illustration.bmp
|
||||
res-app = build/font.o $(addprefix build/, $(addsuffix .o, $(img-app)))
|
||||
|
||||
|
||||
#
|
||||
|
@ -97,6 +99,9 @@ build/%.s.o: src/%.s
|
|||
build/%.bmp.o: resources/%.bmp
|
||||
fxconv $^ -o $@
|
||||
|
||||
build/font.o: resources/font.bmp
|
||||
fxconv --font $^ -o $@
|
||||
|
||||
# File gint.c should not be optimized... looks like attribute((interrupt_
|
||||
# handler)) doesn't like it. (It could be a gint bug also, I should check.)
|
||||
build/gint.c.o: src/gint.c $(hdr-lib) $(hdr-std)
|
||||
|
|
16
TODO
16
TODO
|
@ -1,3 +1,15 @@
|
|||
@ vram overflow
|
||||
@ keyboard interface
|
||||
|
||||
- upgraded blending modes
|
||||
- blending modes for text
|
||||
- information masks for text
|
||||
- test all font encodings
|
||||
- font clipping
|
||||
|
||||
- bitmap parts
|
||||
- bitmap clipping
|
||||
|
||||
- multi-getkey repeats (if possible, which doesn't seem likely)
|
||||
- it appears that multi-getkey does not always trigger rectangle effects on
|
||||
sh7305
|
||||
|
@ -11,5 +23,5 @@
|
|||
|
||||
- check possible bug for optimization of __attribute__((interrupt_handler))
|
||||
|
||||
_ 7305.h
|
||||
_ libc
|
||||
- 7305.h
|
||||
- libc
|
||||
|
|
318
ginttest.c
318
ginttest.c
|
@ -4,6 +4,11 @@
|
|||
#include <keyboard.h>
|
||||
#include <display.h>
|
||||
#include <timer.h>
|
||||
#include <gray.h>
|
||||
#include <tales.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <7305.h>
|
||||
|
||||
extern unsigned int bgint, egint;
|
||||
|
||||
|
@ -11,17 +16,9 @@ extern unsigned int bgint, egint;
|
|||
// A few procedures for displaying text in the system's vram.
|
||||
//---
|
||||
|
||||
extern void __Print(const char *msg, int x, int y);
|
||||
|
||||
void print_clear(void)
|
||||
{
|
||||
char *empty_line = " ";
|
||||
int i = 0;
|
||||
while(i < 8) __Print(empty_line, 0, i++);
|
||||
}
|
||||
void print(const char *str, int x, int y)
|
||||
{
|
||||
__Print(str, x, y);
|
||||
print_raw(str, x, y);
|
||||
}
|
||||
void print_hex(unsigned int n, int x, int y)
|
||||
{
|
||||
|
@ -34,7 +31,7 @@ void print_hex(unsigned int n, int x, int y)
|
|||
n >>= 4;
|
||||
}
|
||||
ch[10] = 0;
|
||||
__Print(ch, x, y);
|
||||
print(ch, x, y);
|
||||
}
|
||||
void print_bin(unsigned char n, int x, int y)
|
||||
{
|
||||
|
@ -47,7 +44,7 @@ void print_bin(unsigned char n, int x, int y)
|
|||
n >>= 1;
|
||||
}
|
||||
ch[8] = 0;
|
||||
__Print(ch, x, y);
|
||||
print(ch, x, y);
|
||||
}
|
||||
void print_hexa(unsigned int n, int digits, int x, int y)
|
||||
{
|
||||
|
@ -61,31 +58,48 @@ void print_hexa(unsigned int n, int digits, int x, int y)
|
|||
}
|
||||
|
||||
ch[digits] = 0;
|
||||
__Print(ch, x, y);
|
||||
print(ch, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
Keyboard tests.
|
||||
The user timer reproduces the parameters of the keyboard timer.
|
||||
*/
|
||||
|
||||
|
||||
//---
|
||||
// Test applications.
|
||||
//---
|
||||
|
||||
/*
|
||||
keyboard_test_timer()
|
||||
Displays a keyboard test. The keyboard state is displayed as well, but
|
||||
there is a timer artifact. The keyboard state timer uses the same
|
||||
period as the (internal) keyboard analysis timer, but there is a time
|
||||
gap between a keyboard analysis and an update on the screen.
|
||||
*/
|
||||
void keyboard_test_timer(void)
|
||||
{
|
||||
volatile unsigned char *state = keystate();
|
||||
|
||||
print_bin(state[0], 0, 1);
|
||||
print_bin(state[1], 0, 2);
|
||||
print_bin(state[2], 0, 3);
|
||||
print_bin(state[3], 0, 4);
|
||||
print_bin(state[4], 0, 5);
|
||||
dclear_area(5, 10, 71, 34);
|
||||
|
||||
print_bin(state[5], 9, 1);
|
||||
print_bin(state[6], 9, 2);
|
||||
print_bin(state[7], 9, 3);
|
||||
print_bin(state[8], 9, 4);
|
||||
print_bin(state[9], 9, 5);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
/*
|
||||
keyboard_test()
|
||||
Displays a multi-getkey test as well as the keyboard state in real
|
||||
time.
|
||||
*/
|
||||
void keyboard_test(void)
|
||||
{
|
||||
int x = 0;
|
||||
|
@ -95,37 +109,40 @@ void keyboard_test(void)
|
|||
|
||||
timer_start(TIMER_USER, 1700, TIMER_Po_256, keyboard_test_timer, 0);
|
||||
|
||||
print_clear();
|
||||
print("Keyboard state:", 0, 0);
|
||||
print("multi-getkey ^^", 6, 7);
|
||||
|
||||
while(1)
|
||||
{
|
||||
multigetkey(keys, 4, 0);
|
||||
|
||||
if(keys[0] == KEY_EXIT && keys[1] == KEY_NONE) break;
|
||||
|
||||
dclear();
|
||||
print("Keyboard state:", 0, 0);
|
||||
print("multi-getkey ^^", 50, 55);
|
||||
|
||||
#define hexa(h) ('0' + (h) + 39 * ((h) > 9))
|
||||
|
||||
x = (x + 1) & 15;
|
||||
str[0] = hexa(x);
|
||||
str[1] = 0;
|
||||
print(str, 20, 0);
|
||||
print(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, 19, i + 3);
|
||||
print(str, 100, 16 + 10 * i);
|
||||
}
|
||||
|
||||
#undef hexa
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
timer_stop(TIMER_USER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
const unsigned char data[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,
|
||||
|
@ -180,114 +197,16 @@ const unsigned char data[1024] = {
|
|||
255, 15, 31, 252, 31 };
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
static const unsigned char icon[76] = {
|
||||
0, 0, 0, 0, 51, 156, 10, 68, 74, 82, 11, 68, 74, 82, 234, 196, 122, 82, 10,
|
||||
68, 75, 156, 10, 68, 0, 0, 0, 4, 0, 254, 0, 4, 0, 130, 124, 4, 0, 130, 68, 4,
|
||||
0, 2, 4, 4, 3, 238, 196, 4, 2, 170, 93, 252, 0, 254, 65, 252, 7, 40, 65, 252,
|
||||
5, 232, 65, 252, 7, 15, 193, 252, 0, 0, 1, 252, 127, 255, 255, 252 };
|
||||
|
||||
char *ML_vram_adress(void)
|
||||
{
|
||||
return display_getVRAM();
|
||||
}
|
||||
|
||||
void ML_bmp_or_cl(const unsigned char *bmp, int x, int y, int width, int height)
|
||||
{
|
||||
unsigned short line;
|
||||
char shift, *screen, *p;
|
||||
int i, j, real_width, begin_x, end_x, begin_y, end_y;
|
||||
char bool1=1, bool2=1, bool3;
|
||||
if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
|
||||
p = (char*)&line;
|
||||
real_width = (width-1>>3<<3)+8;
|
||||
if(y < 0) begin_y = -y;
|
||||
else begin_y = 0;
|
||||
if(y+height > 64) end_y = 64-y;
|
||||
else end_y = height;
|
||||
shift = 8-(x&7);
|
||||
if(x<0)
|
||||
{
|
||||
begin_x = -x>>3;
|
||||
if(shift != 8) bool1 = 0;
|
||||
} else begin_x = 0;
|
||||
if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
|
||||
else end_x = real_width-1>>3;
|
||||
bool3 = (end_x == real_width-1>>3);
|
||||
screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
|
||||
|
||||
for(i=begin_y ; i<end_y ; i++)
|
||||
{
|
||||
if(begin_x < end_x)
|
||||
{
|
||||
line = bmp[i*(real_width>>3)+begin_x] << shift;
|
||||
if(bool1) screen[begin_x] |= *p;
|
||||
if(shift!=8) screen[begin_x+1] |= *(p+1);
|
||||
for(j=begin_x+1 ; j<end_x ; j++)
|
||||
{
|
||||
line = bmp[i*(real_width>>3)+j] << shift;
|
||||
screen[j] |= *p;
|
||||
if(shift!=8) screen[j+1] |= *(p+1);
|
||||
}
|
||||
}
|
||||
line = bmp[i*(real_width>>3)+end_x];
|
||||
if(bool3) line &= -1<<real_width-width;
|
||||
line <<= shift;
|
||||
if(begin_x < end_x || bool1) screen[end_x] |= *p;
|
||||
if(bool2) screen[end_x+1] |= *(p+1);
|
||||
screen += 16;
|
||||
}
|
||||
}
|
||||
bitmap_test()
|
||||
Displays various bitmaps to ensure bopti is working correctly.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <7305.h>
|
||||
|
||||
/*
|
||||
unsigned int exec(void (*f)(void))
|
||||
{
|
||||
int t, s, dt, ds;
|
||||
|
||||
t = (int)RTC.R64CNT;
|
||||
s = 10 * (RTC.RSECCNT.TENS) + RTC.RSECCNT.ONES;
|
||||
|
||||
(*f)();
|
||||
|
||||
dt = (int)RTC.R64CNT - t;
|
||||
ds = (10 * (RTC.RSECCNT.TENS) + RTC.RSECCNT.ONES) - s;
|
||||
if(dt < 0) ds--, dt += 64;
|
||||
|
||||
return (ds << 8) | dt;
|
||||
}
|
||||
|
||||
void btest_ml_icon(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 5000; i++)
|
||||
{
|
||||
ML_bmp_or_cl(icon, 0, 30, 30, 19);
|
||||
}
|
||||
}
|
||||
void btest_gint_icon(void)
|
||||
{
|
||||
extern Image binary_icon_start;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 5000; i++)
|
||||
{
|
||||
dimage(&binary_icon_start, 0, 0, Blend_Or);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void bitmap_test(void)
|
||||
{
|
||||
extern Image binary_resources_bitmap_opt_start;
|
||||
extern Image binary_resources_symbol_start;
|
||||
extern Image binary_resources_symbol2_start;
|
||||
extern Image binary_resources_sprites_start;
|
||||
extern Image binary_resources_swords_start;
|
||||
|
||||
Image *opt = &binary_resources_bitmap_opt_start;
|
||||
Image *sprites = &binary_resources_sprites_start;
|
||||
|
@ -324,64 +243,78 @@ void bitmap_test(void)
|
|||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dclear();
|
||||
dreverse_area(0, 0, 127, 30);
|
||||
|
||||
dimage(sybl, 0, 0, Blend_Or);
|
||||
dimage(sybl, 20, 0, Blend_And);
|
||||
dimage(sybl, 40, 0, Blend_Or | Blend_And);
|
||||
dimage(sybl, 90, 0, Blend_Or | Blend_Invert);
|
||||
|
||||
dimage(sybl2, 0, 20, Blend_Or);
|
||||
dimage(sybl2, 20, 20, Blend_And);
|
||||
dimage(sybl2, 28, 20, Blend_And);
|
||||
dimage(sybl2, 40, 20, Blend_Or | Blend_And);
|
||||
dimage(sybl2, 90, 20, Blend_Or | Blend_Invert);
|
||||
|
||||
dreverse_area(35, 31, 127, 63);
|
||||
dimage(&binary_resources_sprites_start, 50, 31, Blend_And);
|
||||
|
||||
dupdate();
|
||||
/*
|
||||
do key = getkey();
|
||||
while(key != KEY_EXE && key != KEY_EXIT);
|
||||
if(key == KEY_EXIT) return 0;
|
||||
|
||||
print("h'sszz 64z=1s", 0, 0);
|
||||
print("ML", 14, 0);
|
||||
print("gint", 17, 0);
|
||||
print("---------------------", 0, 1);
|
||||
|
||||
print("30*19 icon", 0, 2);
|
||||
print(wait, 12, 2);
|
||||
print_hexa(exec(btest_ml_icon), 4, 12, 2);
|
||||
print(wait, 17, 2);
|
||||
print_hexa(exec(btest_gint_icon), 4, 17, 2);
|
||||
text_test()
|
||||
Renders text.
|
||||
*/
|
||||
while(getkey() != KEY_EXE);
|
||||
|
||||
void text_test(void)
|
||||
{
|
||||
extern Font binary_resources_font_start;
|
||||
Font *font = &binary_resources_font_start;
|
||||
|
||||
print_configure(font, Blend_Or);
|
||||
|
||||
dclear();
|
||||
dimage(&binary_resources_swords_start, 20, 20, Blend_Or);
|
||||
|
||||
print(" !\"#$%&'()*+,-./", 10, 10);
|
||||
print("0123456789:;<=>?", 10, 16);
|
||||
print("@ABCDEFGHIJKLMNO", 10, 22);
|
||||
print("PQRSTUVWXYZ[\\]^_", 10, 28);
|
||||
print("`abcdefghijklmno", 10, 34);
|
||||
print("pqrstuvwxyz{|}~", 10, 40);
|
||||
|
||||
dupdate();
|
||||
|
||||
while(getkey() != KEY_EXE);
|
||||
while(getkey() != KEY_EXIT);
|
||||
}
|
||||
|
||||
void test(void)
|
||||
|
||||
|
||||
/*
|
||||
gray_test()
|
||||
Runs the gray engine.
|
||||
*/
|
||||
|
||||
void gray_test(void)
|
||||
{
|
||||
static int x = 0;
|
||||
x++;
|
||||
extern Image binary_resources_illustration_start;
|
||||
Image *illustration = &binary_resources_illustration_start;
|
||||
|
||||
print_hex(x, 0, 0);
|
||||
int light, dark;
|
||||
int key;
|
||||
|
||||
gray_getDelays(&light, &dark);
|
||||
gray_start();
|
||||
dimage(illustration, 0, 0, Blend_Or);
|
||||
|
||||
while(1)
|
||||
{
|
||||
key = getkey();
|
||||
if(key == KEY_EXIT) break;
|
||||
|
||||
if(key == KEY_F1) gray_setDelays(--light, dark);
|
||||
if(key == KEY_F2) gray_setDelays(++light, dark);
|
||||
|
||||
if(key == KEY_F5) gray_setDelays(light, --dark);
|
||||
if(key == KEY_F6) gray_setDelays(light, ++dark);
|
||||
}
|
||||
|
||||
gray_stop();
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
/*
|
||||
Main menu.
|
||||
*/
|
||||
|
||||
const char *mpu_names[] = {
|
||||
"MPU_Unkown",
|
||||
"MPU_SH7337",
|
||||
|
@ -392,18 +325,22 @@ int main_menu(void)
|
|||
};
|
||||
int key;
|
||||
|
||||
print_clear();
|
||||
dclear();
|
||||
|
||||
print("gint test application", 0, 0);
|
||||
print("---------------------", 0, 1);
|
||||
print("gint test application", 19, 1);
|
||||
dline(19, 8, 107, 8, Color_Black);
|
||||
|
||||
print("[1] Keyboard test", 2, 3);
|
||||
print("[2] Drawing test", 2, 4);
|
||||
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:", 0, 6);
|
||||
print(mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 11, 6);
|
||||
print("gint size:", 0, 7);
|
||||
print_hex(&egint - &bgint, 11, 7);
|
||||
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)
|
||||
{
|
||||
|
@ -412,13 +349,26 @@ int main_menu(void)
|
|||
|
||||
if(key == KEY_1) return 1;
|
||||
if(key == KEY_2) return 2;
|
||||
if(key == KEY_3) return 3;
|
||||
if(key == KEY_4) return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
main()
|
||||
Handles application calls.
|
||||
|
||||
@return 0.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
extern Font binary_resources_font_start;
|
||||
Font *font = &binary_resources_font_start;
|
||||
|
||||
print_configure(font, Blend_Or);
|
||||
|
||||
int app;
|
||||
|
||||
while(1)
|
||||
|
@ -428,6 +378,8 @@ int main(void)
|
|||
|
||||
if(app == 1) keyboard_test();
|
||||
if(app == 2) bitmap_test();
|
||||
if(app == 3) text_test();
|
||||
if(app == 4) gray_test();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
BIN
ginttest.g1a
BIN
ginttest.g1a
Binary file not shown.
27
include/ctype.h
Normal file
27
include/ctype.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef _CTYPE_H
|
||||
#define _CTYPE_H 1
|
||||
|
||||
// Character definition macros.
|
||||
#define isalnum(c) (isdigit(c) || isalpha(c))
|
||||
#define isalpha(c) (islower(c) || isupper(c))
|
||||
|
||||
#define iscntrl(c) ((c) <= 0x1f || (c) == 0x7f)
|
||||
#define isdigit(c) ((c) >= '0' && (c) <= '9')
|
||||
#define isgraph(c) ((c) > ' ' && (c) < 0x7f)
|
||||
#define islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||
#define isprint(c) ((c) >= ' ' && (c) < 0x7f)
|
||||
#define ispunct(c) (((c) >= '!' && (c) <= '/') || \
|
||||
((c) >= ':' && (c) <= '@') || \
|
||||
((c) >= '[' && (c) <= '`') || \
|
||||
((c) >= '{' && (c) <= '~'))
|
||||
#define isspace(c) (((c) >= '\t' && (c) <= '\r') || (c) == ' ')
|
||||
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define isxdigit(c) (((c) >= '0' && (c) <= '9') || \
|
||||
((c) >= 'A' && (c) <= 'F') || \
|
||||
((c) >= 'a' && (c) <= 'f'))
|
||||
|
||||
// Character manipulation macros.
|
||||
#define tolower(c) (isupper(c) ? (c)|32 : (c))
|
||||
#define toupper(c) (islower(c) ? (c)&~32 : (c))
|
||||
|
||||
#endif // _CTYPE_H
|
|
@ -1,6 +1,14 @@
|
|||
#ifndef _DISPLAY_H
|
||||
#define _DISPLAY_H 1
|
||||
|
||||
//---
|
||||
// Included submodules.
|
||||
//---
|
||||
|
||||
#include <tales.h>
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Types and constants.
|
||||
//---
|
||||
|
@ -60,13 +68,12 @@ enum ImageFormat
|
|||
*/
|
||||
struct Image
|
||||
{
|
||||
unsigned char magic;
|
||||
|
||||
unsigned char width;
|
||||
unsigned char height;
|
||||
unsigned char format;
|
||||
|
||||
// Ensures data is 4-aligned.
|
||||
unsigned char gap;
|
||||
|
||||
const unsigned char __attribute__((aligned(4))) data[];
|
||||
|
||||
} __attribute__((aligned(4)));
|
||||
|
@ -205,4 +212,6 @@ void dline(int x1, int y1, int x2, int y2, enum Color color);
|
|||
*/
|
||||
void dimage(struct Image *image, int x, int y, enum BlendingMode mode);
|
||||
|
||||
|
||||
|
||||
#endif // _DISPLAY_H
|
||||
|
|
|
@ -31,6 +31,28 @@ void *gray_lightVRAM(void);
|
|||
*/
|
||||
void *gray_darkVRAM(void);
|
||||
|
||||
/*
|
||||
gray_getDelays()
|
||||
Returns the gray engine delays.
|
||||
|
||||
@arg light Will be set if non-NULL.
|
||||
@arg dark Will be set if non-NULL.
|
||||
*/
|
||||
void gray_getDelays(int *light, int *dark);
|
||||
|
||||
/*
|
||||
gray_setDelays()
|
||||
Changes the gray engine delays. Usually you don't need to call this,
|
||||
because the engine has its default values.
|
||||
Finding values that give proper grays is quite the hard part of the
|
||||
gray engine. Usual values are about 1000, with light being between 75
|
||||
and 90% of dark.
|
||||
|
||||
@arg light Light gray duration (the lower).
|
||||
@arg dark Dark gray duration (the higher).
|
||||
*/
|
||||
void gray_setDelays(int light, int dark);
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
// Referenced here for documentation purposes only. Do not call.
|
||||
|
|
|
@ -148,6 +148,7 @@ enum GetkeyOpt
|
|||
non-NULL, it is set to the number of repetitions.
|
||||
|
||||
@arg repeat_count
|
||||
|
||||
@return Key matrix code.
|
||||
*/
|
||||
int keylast(int *repeat_count);
|
||||
|
@ -223,6 +224,7 @@ enum KeyType
|
|||
Ignores modifiers.
|
||||
|
||||
@arg key
|
||||
|
||||
@return Modified keycode.
|
||||
*/
|
||||
int keyid(int key);
|
||||
|
@ -233,7 +235,8 @@ int keyid(int key);
|
|||
other keys.
|
||||
|
||||
@arg key
|
||||
@return Key character.
|
||||
|
||||
@return Associated character.
|
||||
*/
|
||||
int keychar(int key);
|
||||
|
||||
|
@ -242,6 +245,7 @@ int keychar(int key);
|
|||
Returns a key's type. Ignores modifiers.
|
||||
|
||||
@arg key
|
||||
|
||||
@return Key type.
|
||||
*/
|
||||
enum KeyType keytype(int key);
|
||||
|
|
|
@ -28,4 +28,43 @@ void abort(void);
|
|||
*/
|
||||
void exit(int status);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Dynamic storage allocation.
|
||||
//---
|
||||
|
||||
/*
|
||||
malloc()
|
||||
Allocs 'size' bytes and returns a pointer to a free memory area.
|
||||
Returns NULL on error.
|
||||
|
||||
@arg size Size to allocate, in bytes.
|
||||
|
||||
@return Memory area address, or NULL.
|
||||
*/
|
||||
void *malloc(size_t size);
|
||||
|
||||
/*
|
||||
calloc()
|
||||
Allocs 'n' elements of size 'size' and wipes the memory area. Returns
|
||||
NULL on error.
|
||||
|
||||
@arg n Element number.
|
||||
@arg size Element size.
|
||||
|
||||
@return Memory area address, or NULL.
|
||||
*/
|
||||
void *calloc(size_t n, size_t size);
|
||||
|
||||
/*
|
||||
free()
|
||||
Frees a memory block allocated with malloc().
|
||||
|
||||
@arg ptr Pointer to free.
|
||||
*/
|
||||
void free(void *ptr);
|
||||
|
||||
|
||||
|
||||
#endif // _STDLIB_H
|
||||
|
|
105
include/tales.h
Normal file
105
include/tales.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
#ifndef _TALES_H
|
||||
#define _TALES_H 1
|
||||
|
||||
#include <display.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//---
|
||||
// Types and constants.
|
||||
//---
|
||||
|
||||
enum BlendingMode;
|
||||
|
||||
/*
|
||||
enum ImageFormat
|
||||
This type holds information about the characters in the font. Each bit
|
||||
represents various characters, and the type itself is a combination of
|
||||
several of those bits.
|
||||
Bits represent the following characters (lsb right):
|
||||
-- -- -- non-print | special capitals lower numbers
|
||||
*/
|
||||
enum FontFormat
|
||||
{
|
||||
FontFormat_Unknown = 0x00,
|
||||
FontFormat_Numeric = 0x01,
|
||||
FontFormat_LowerCase = 0x02,
|
||||
FontFormat_UpperCase = 0x04,
|
||||
FontFormat_Letters = 0x06,
|
||||
FontFormat_Common = 0x07,
|
||||
FontFormat_Print = 0x0f,
|
||||
FontFormat_Ascii = 0x1f,
|
||||
};
|
||||
|
||||
/*
|
||||
struct FontGlyph
|
||||
Holds a glyph's data. The width is used for spacing, and the raw data
|
||||
is encoded line after line, from to to bottom, by appending bits
|
||||
without consideration of the byte boundaries.
|
||||
This structure is actually never used, because data is read directly
|
||||
as a longword array (hence the 4-byte alignment).
|
||||
*/
|
||||
struct FontGlyph
|
||||
{
|
||||
unsigned char width;
|
||||
|
||||
const unsigned char data[];
|
||||
} __attribute__((aligned(4)));
|
||||
|
||||
/*
|
||||
struct Font
|
||||
Holds a font's data. Data is accessed using longword operations, hence
|
||||
the 4-alignment attributes. The line height is the one given in the
|
||||
font image header line, which may be used by applications that write
|
||||
strings on several lines. The data height is the height of the biggest
|
||||
glyph. Every glyph is encoded on 'data_height' lines, for optimization
|
||||
considerations.
|
||||
The index field is used to reduce character access time.
|
||||
The name field may not be NUL-terminated when the name contains 28
|
||||
characters. When the name is shorter, the field is padded with zeros.
|
||||
*/
|
||||
struct Font
|
||||
{
|
||||
unsigned char magic;
|
||||
|
||||
unsigned char format;
|
||||
unsigned char line_height;
|
||||
unsigned char data_height;
|
||||
|
||||
// Warning : this field may not be NUL-terminated.
|
||||
char name[28];
|
||||
|
||||
uint16_t index[16];
|
||||
|
||||
__attribute__((aligned(4))) const struct FontGlyph glyphs[];
|
||||
|
||||
} __attribute__((aligned(4)));
|
||||
// Useful shorthand for user code.
|
||||
typedef struct Font Font;
|
||||
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Generic functions.
|
||||
//---
|
||||
|
||||
/*
|
||||
print_configure()
|
||||
Sets the font and mode to use for the following print operations.
|
||||
|
||||
@arg font
|
||||
@arg mode
|
||||
*/
|
||||
void print_configure(struct Font *font, enum BlendingMode mode);
|
||||
|
||||
/*
|
||||
print_raw()
|
||||
Prints the given string, without any analysis.
|
||||
|
||||
@arg str
|
||||
@arg x
|
||||
@arg y
|
||||
*/
|
||||
void print_raw(const char *str, int x, int y);
|
||||
|
||||
#endif // _TALES_H
|
|
@ -56,6 +56,16 @@ void timer_start(int timer, int delay, int prescaler, void (*callback)(void),
|
|||
*/
|
||||
void timer_stop(int timer);
|
||||
|
||||
/*
|
||||
timer_reload()
|
||||
Reloads the given timer with the given constant. Starts the timer if
|
||||
it was stopped.
|
||||
|
||||
@arg timer Timer identifier.
|
||||
@arg new_delay
|
||||
*/
|
||||
void timer_reload(int timer, int new_delay);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
BIN
resources/font.bmp
Normal file
BIN
resources/font.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
resources/illustration.bmp
Normal file
BIN
resources/illustration.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
@ -286,6 +286,8 @@ void dimage(struct Image *image, int x, int y, enum BlendingMode mode)
|
|||
int height = image->height;
|
||||
const unsigned char *data = (const unsigned char *)&(image->data);
|
||||
|
||||
if(image->magic != 0xb7) return;
|
||||
|
||||
// Computing the layer size.
|
||||
int columns = image->width >> 5;
|
||||
int rest = image->width & 31;
|
||||
|
|
|
@ -93,6 +93,7 @@ static void kdelay(void)
|
|||
more details.
|
||||
|
||||
@arg row Row to check (0 <= row <= 9).
|
||||
|
||||
@return Bit-based representation of pressed keys in the checked row.
|
||||
*/
|
||||
static int krow(int row)
|
||||
|
|
|
@ -100,6 +100,7 @@ static void kdelay(void)
|
|||
Reads a keyboard row.
|
||||
|
||||
@arg row Row to check (0 <= row <= 9).
|
||||
|
||||
@return Bit-based representation of pressed keys in the checked row.
|
||||
*/
|
||||
static int krow(int row)
|
||||
|
|
44
src/gray.c
44
src/gray.c
|
@ -1,11 +1,15 @@
|
|||
#include <display.h>
|
||||
#include <gray.h>
|
||||
#include <screen.h>
|
||||
#include <timer.h>
|
||||
|
||||
static int internal_vrams[3][256];
|
||||
const void *vrams[4];
|
||||
|
||||
static int current = 0;
|
||||
static int delays[2];
|
||||
|
||||
#define GRAY_PRESCALER TIMER_Po_64
|
||||
|
||||
/*
|
||||
gray_start()
|
||||
|
@ -14,6 +18,7 @@ static int current = 0;
|
|||
*/
|
||||
void gray_start(void)
|
||||
{
|
||||
timer_start(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -23,6 +28,7 @@ void gray_start(void)
|
|||
*/
|
||||
void gray_stop(void)
|
||||
{
|
||||
timer_stop(TIMER_GRAY);
|
||||
display_useVRAM(display_getLocalVRAM());
|
||||
}
|
||||
|
||||
|
@ -44,6 +50,38 @@ void *gray_darkVRAM(void)
|
|||
return (void *)vrams[current + 1];
|
||||
}
|
||||
|
||||
/*
|
||||
gray_getDelays()
|
||||
Returns the gray engine delays.
|
||||
|
||||
@arg light Will be set if non-NULL.
|
||||
@arg dark Will be set if non-NULL.
|
||||
*/
|
||||
void gray_getDelays(int *light, int *dark)
|
||||
{
|
||||
if(light) *light = delays[0];
|
||||
if(dark) *dark = delays[1];
|
||||
}
|
||||
|
||||
/*
|
||||
gray_setDelays()
|
||||
Changes the gray engine delays.
|
||||
|
||||
@arg light Light gray duration (the lower).
|
||||
@arg dark Dark gray duration (the higher).
|
||||
*/
|
||||
void gray_setDelays(int light, int dark)
|
||||
{
|
||||
delays[0] = light;
|
||||
delays[1] = dark;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
//---
|
||||
|
||||
/*
|
||||
gray_swap()
|
||||
Swaps the vram buffers.
|
||||
|
@ -55,10 +93,11 @@ void gray_swap(void)
|
|||
|
||||
/*
|
||||
gray_interrupt()
|
||||
Answers a timer interrupt. Swaps the two buffers.
|
||||
Answers a timer interrupt. Swaps the buffers.
|
||||
*/
|
||||
void gray_interrupt(void)
|
||||
{
|
||||
timer_reload(TIMER_GRAY, delays[current & 1]);
|
||||
screen_display(vrams[current]);
|
||||
current ^= 1;
|
||||
}
|
||||
|
@ -73,4 +112,7 @@ void gray_init(void)
|
|||
vrams[1] = (const void *)internal_vrams[0];
|
||||
vrams[2] = (const void *)internal_vrams[1];
|
||||
vrams[3] = (const void *)internal_vrams[2];
|
||||
|
||||
delays[0] = 3269;
|
||||
delays[1] = 6987;
|
||||
}
|
||||
|
|
|
@ -201,6 +201,7 @@ void keyboard_setRepeatRate(int first, int next)
|
|||
non-NULL, it is set to the number of repetitions.
|
||||
|
||||
@arg repeat_count
|
||||
|
||||
@return Key matrix code.
|
||||
*/
|
||||
int keylast(int *repeat_count)
|
||||
|
@ -426,6 +427,7 @@ void multigetkey(int *keys, int count, int max_cycles)
|
|||
Ignores modifiers.
|
||||
|
||||
@arg key
|
||||
|
||||
@return Modified keycode.
|
||||
*/
|
||||
int keyid(int key)
|
||||
|
@ -445,6 +447,8 @@ int keyid(int key)
|
|||
keys.
|
||||
|
||||
@arg key
|
||||
|
||||
@return Associated character.
|
||||
*/
|
||||
int keychar(int key)
|
||||
{
|
||||
|
@ -482,6 +486,7 @@ int keychar(int key)
|
|||
Returns a key's type. Ignores modifiers.
|
||||
|
||||
@arg key
|
||||
|
||||
@return Key type.
|
||||
*/
|
||||
enum KeyType keytype(int key)
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
.global ___Hmem_SetMMU
|
||||
.global ___GLibAddinAplExecutionCheck
|
||||
.global ___Print
|
||||
.global _malloc
|
||||
.global _calloc
|
||||
.global _free
|
||||
|
||||
|
||||
|
||||
|
@ -22,12 +24,26 @@ ___GLibAddinAplExecutionCheck:
|
|||
jmp @r2
|
||||
nop
|
||||
|
||||
___Print:
|
||||
_malloc:
|
||||
mov.l syscall_table, r2
|
||||
mov.l 1f, r0
|
||||
jmp @r2
|
||||
nop
|
||||
1: .long 0x15d
|
||||
1: .long 0xacd
|
||||
|
||||
_calloc:
|
||||
mov.l syscall_table, r2
|
||||
mov.l 1f, r0
|
||||
jmp @r2
|
||||
nop
|
||||
1: .long 0xe6b
|
||||
|
||||
_free:
|
||||
mov.l syscall_table, r2
|
||||
mov.l 1f, r0
|
||||
jmp @r2
|
||||
nop
|
||||
1: .long 0xacc
|
||||
|
||||
|
||||
|
||||
|
|
292
src/tales.c
Normal file
292
src/tales.c
Normal file
|
@ -0,0 +1,292 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tales.h>
|
||||
|
||||
static struct Font *font;
|
||||
static enum BlendingMode mode;
|
||||
|
||||
//---
|
||||
// Local functions.
|
||||
//---
|
||||
|
||||
/*
|
||||
getCharacterIndex()
|
||||
Returns the index of a character in a font data area depending on the
|
||||
font format and the size of the characters.
|
||||
|
||||
@arg character
|
||||
|
||||
@return Index in data area (as long array). Returns -1 when the
|
||||
character does not belong to the font format set.
|
||||
*/
|
||||
static int getCharacterIndex(int c)
|
||||
{
|
||||
const char *data = (const char *)&font->glyphs;
|
||||
int index, current;
|
||||
int offset;
|
||||
int width, bits;
|
||||
|
||||
c &= 0x7f;
|
||||
|
||||
|
||||
|
||||
// Getting the character index in the glyph array.
|
||||
|
||||
if(font->format == FontFormat_Ascii) index = c;
|
||||
else if(font->format == FontFormat_Print) index = c - 32;
|
||||
|
||||
else switch(font->format)
|
||||
{
|
||||
case FontFormat_Numeric:
|
||||
if(!isdigit(c)) return -1;
|
||||
index = c - '0';
|
||||
break;
|
||||
case FontFormat_LowerCase:
|
||||
if(!islower(c)) return -1;
|
||||
index = c - 'a';
|
||||
break;
|
||||
case FontFormat_UpperCase:
|
||||
if(!isupper(c)) return -1;
|
||||
index = c - 'A';
|
||||
break;
|
||||
case FontFormat_Letters:
|
||||
if(!isalpha(c)) return -1;
|
||||
index = c - 'A' - ('a' - 'z') * (c >= 'a');
|
||||
break;
|
||||
case FontFormat_Common:
|
||||
if(!isalnum(c)) return -1;
|
||||
index = c - '0' - ('A' - '9') * (c >= 'A') -
|
||||
('a' - 'z') * (c >= 'a');
|
||||
break;
|
||||
case FontFormat_Unknown:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reaching the character offset.
|
||||
|
||||
current = index & ~7;
|
||||
offset = font->index[current >> 3];
|
||||
|
||||
while(current < index)
|
||||
{
|
||||
width = data[offset << 2];
|
||||
bits = font->data_height * width + 8;
|
||||
|
||||
offset += (bits + 31) >> 5;
|
||||
current++;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*
|
||||
operate()
|
||||
Operates on the vram using the given operators. The x-coordinate should
|
||||
be a multiple of 32.
|
||||
|
||||
@arg operators Operator array.
|
||||
@arg height Number of operators (height of text).
|
||||
@arg x
|
||||
@arg y
|
||||
*/
|
||||
static void operate(uint32_t *operators, int height, int x, int y)
|
||||
{
|
||||
int *vram = display_getCurrentVRAM();
|
||||
int vram_offset = (x >> 5) + (y << 2);
|
||||
int i;
|
||||
|
||||
for(i = 0; i < height; i++)
|
||||
{
|
||||
// TODO BLENDING MODES //
|
||||
vram[vram_offset] |= operators[i];
|
||||
|
||||
vram_offset += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
update()
|
||||
Updates the operators using the given glyph. The operation will not be
|
||||
complete if there are not enough bits available in the operator data.
|
||||
In this case the offset will become negative, which means that the
|
||||
calling procedure has to call operate() and re-call update().
|
||||
|
||||
@arg operators Operator array.
|
||||
@arg height Number of operators.
|
||||
@arg available Number of free bits in the operators (lower
|
||||
bits).
|
||||
@arg glyph Glyph data, including meta-data.
|
||||
|
||||
@return Number of bits available after the operation. May be negative:
|
||||
in this case, call operate() and update() again.
|
||||
*/
|
||||
static int update(uint32_t *operators, int height, int available,
|
||||
uint32_t *glyph)
|
||||
{
|
||||
// Glyph width.
|
||||
int width = glyph[0] >> 24;
|
||||
int i;
|
||||
|
||||
// The glyph mask extracts 'width' bits at the left. The partial mask
|
||||
// is used when there are less than 'width' bits available in the
|
||||
// current data longword.
|
||||
uint32_t glyph_mask = 0xffffffff << (32 - width);
|
||||
uint32_t partial_mask;
|
||||
|
||||
int shift;
|
||||
uint32_t line;
|
||||
|
||||
// Current data longword, next data array index, and number of bits
|
||||
// still available in 'data'.
|
||||
uint32_t data = glyph[0] << 8;
|
||||
int data_index = 1;
|
||||
int bits_available = 24;
|
||||
|
||||
for(i = 0; i < height; i++)
|
||||
{
|
||||
shift = 32 - available;
|
||||
|
||||
// Getting the next 'width' bits. In some cases these bits will
|
||||
// intersect two different longs.
|
||||
line = data & glyph_mask;
|
||||
line = (shift >= 0) ? (line >> shift) : (line << -shift);
|
||||
operators[i] |= line;
|
||||
|
||||
data <<= width;
|
||||
bits_available -= width;
|
||||
|
||||
// Continue until they do.
|
||||
if(bits_available >= 0) continue;
|
||||
|
||||
// Computing a special mask that extracts just the number of
|
||||
// bits missing, and loading a new data longword.
|
||||
partial_mask = 0xffffffff << (32 + bits_available);
|
||||
data = glyph[data_index++];
|
||||
shift += width + bits_available;
|
||||
|
||||
if(shift <= 31)
|
||||
{
|
||||
line = data & partial_mask;
|
||||
line = (shift >= 0) ? (line >> shift) :
|
||||
(line << -shift);
|
||||
operators[i] |= line;
|
||||
}
|
||||
|
||||
data <<= -bits_available;
|
||||
bits_available += 32;
|
||||
}
|
||||
|
||||
return available - width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Public API.
|
||||
//---
|
||||
|
||||
/*
|
||||
print_configure()
|
||||
Sets the font and mode to use for the following print operations.
|
||||
|
||||
@arg font
|
||||
@arg mode
|
||||
*/
|
||||
void print_configure(struct Font *next_font, enum BlendingMode next_mode)
|
||||
{
|
||||
font = next_font;
|
||||
mode = next_mode;
|
||||
}
|
||||
|
||||
/*
|
||||
print_raw()
|
||||
Prints the given string, without any analysis.
|
||||
|
||||
@arg str
|
||||
@arg x
|
||||
@arg y
|
||||
*/
|
||||
void print_raw(const char *str, int x, int y)
|
||||
{
|
||||
// Operator data, and number of available bits in the operators (which
|
||||
// is the same for all operators, since they are treated equally).
|
||||
uint32_t *operators;
|
||||
int available;
|
||||
|
||||
// Raw glyph data, each glyph being represented by one or several
|
||||
// longwords, and an index in this array.
|
||||
uint32_t *data = (uint32_t *)font->glyphs;
|
||||
int index;
|
||||
|
||||
// Height of each glyph. This value is constant because the storage
|
||||
// format requires it: it allows greater optimization.
|
||||
int height;
|
||||
|
||||
|
||||
|
||||
if(!font) return;
|
||||
|
||||
// Allocating data. There will be one operator for each line.
|
||||
height = font->data_height;
|
||||
if(x > 127 || y > 63 || y <= -height) return;
|
||||
|
||||
operators = calloc(height, sizeof(uint32_t));
|
||||
if(!operators) return;
|
||||
|
||||
// Computing the initial operator offset to have 32-aligned operators.
|
||||
// This allows to write directly video ram longs instead of having to
|
||||
// shift operators, and do all the vram operation twice.
|
||||
available = 32 - (x & 31);
|
||||
x &= ~31;
|
||||
|
||||
// Displaying character after another.
|
||||
while(*str)
|
||||
{
|
||||
index = getCharacterIndex(*str++);
|
||||
if(index < 0) continue;
|
||||
|
||||
// Updating the operators.
|
||||
available = update(operators, height, available, data + index);
|
||||
|
||||
// Continue until operators are full (this includes an
|
||||
// additional bit to add a space between each character).
|
||||
if(available > 1)
|
||||
{
|
||||
available--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// When operators are full, updating the video ram and
|
||||
// preparing the operators for another row.
|
||||
|
||||
operate(operators, height, x, y);
|
||||
x += 32;
|
||||
if(x > 96) break;
|
||||
|
||||
memset(operators, 0, height << 2);
|
||||
if(available >= 0)
|
||||
{
|
||||
available = 31 + available;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Finishing update, in case it has been only partially done,
|
||||
// because there was not enough bits available to fit all the
|
||||
// information. Also adding a space, assuming that characters
|
||||
// aren't more than 30 bits wide.
|
||||
available += 32 + (data[index] >> 24);
|
||||
available = update(operators, height, available, data + index);
|
||||
available--;
|
||||
}
|
||||
|
||||
// Final operation.
|
||||
if(x <= 96 && available < 32) operate(operators, height, x, y);
|
||||
|
||||
free(operators);
|
||||
}
|
23
src/timer.c
23
src/timer.c
|
@ -176,3 +176,26 @@ void timer_stop(int timer)
|
|||
// Stopping the timer.
|
||||
*tstr &= ~byte;
|
||||
}
|
||||
|
||||
/*
|
||||
timer_reload()
|
||||
Reloads the given timer with the given constant. Starts the timer if
|
||||
it was stopped.
|
||||
|
||||
@arg timer Timer identifier.
|
||||
@arg new_delay
|
||||
*/
|
||||
void timer_reload(int timer, int new_delay)
|
||||
{
|
||||
struct mod_tmu *tmu;
|
||||
unsigned char *tstr;
|
||||
int byte = (1 << timer);
|
||||
timer_get(timer, &tmu, &tstr);
|
||||
|
||||
// Setting the constant and the delay.
|
||||
(*tmu).TCOR = new_delay;
|
||||
(*tmu).TCNT = new_delay;
|
||||
|
||||
// Starting the timer.
|
||||
*tstr |= byte;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue