Startup logs instead of diagnostics, created .gint_bss, updated demo.

This commit is contained in:
lephe 2017-07-05 21:38:12 +02:00
parent 5e66efc560
commit f6133c26fc
45 changed files with 689 additions and 1710 deletions

View file

@ -11,7 +11,7 @@ include Makefile.cfg
#---
# Modules
modules-gint = bopti clock core display events gray keyboard mmu rtc \
modules-gint = bopti clock core display events gray init keyboard mmu rtc \
screen tales timer
modules-libc = ctype setjmp stdio stdlib string time
@ -19,7 +19,6 @@ modules-libc = ctype setjmp stdio stdlib string time
target-lib = libgint.a
target-std = libc.a
target-g1a = gintdemo.g1a
target-dbg = gintdbg.g1a
# Tools
cc = sh3eb-elf-gcc
@ -44,17 +43,6 @@ demo-ldflags = $(demo-cflags) -T demo/gintdemo.ld -L. -lgint -lc -lgcc
demo-cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11 -Os \
-Wall -Wextra
# Debugger application (displays past diagnostics without running gint)
debug-src = $(notdir $(wildcard debug/*.[cs]))
debug-dep = $(wildcard debug/*.h)
debug-icon = debug/icon.bmp
debug-obj = $(debug-src:%=build/debug_%.o)
debug-elf = build/gintdbg.elf
debug-bin = build/gintdbg.bin
debug-ldflags = $(debug-cflags) -T debug/addin.ld -L debug -lfx -lgcc
debug-cflags = -m3 -mb -nostdlib -ffreestanding -I debug/include -I \
include -std=c11 -Os -Wall -Wextra
# Specific objects
obj-lib-spec = build/display_font_system.bmp.o
obj-std-spec =
@ -159,7 +147,7 @@ debug-ldflags += -Wl,--defsym,_GINT_VERSION=$(version_symbol)
all-lib: $(config) $(target-std) $(target-lib)
all: $(config) $(target-std) $(target-lib) $(target-g1a) $(target-dbg)
all: $(config) $(target-std) $(target-lib) $(target-g1a)
build:
$(if $(VERBOSE),,@ printf '\e[35;1mdir \u00bb\e[0m mkdir $@\n')
@ -196,17 +184,6 @@ $(target-g1a): $(config) $(target-std) $(target-lib) $(demo-obj)
@ printf $$(stat -c %s $@)
@ printf ' bytes)\n\n'
$(target-dbg): $(config) $(debug-obj)
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m ld -o $(debug-elf)\n')
$(if $(VERBOSE),,@) $(cc) -o $(debug-elf) $(debug-obj) $(debug-ldflags)
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m objcopy -o $(debug-bin)\n')
$(if $(VERBOSE),,@) $(ob) -R .comment -R .bss -O binary $(debug-elf) $(debug-bin)
$(if $(VERBOSE),,@ printf '\e[35;1mexe \u00bb\e[0m g1a-wrapper -o $@\n')
$(if $(VERBOSE),,@) $(wr) $(debug-bin) -o $@ -i $(debug-icon)
@ printf '\e[32;1mmsg \u00bb\e[0m Succesfully built debug application ('
@ printf $$(stat -c %s $@)
@ printf ' bytes)\n\n'
# Automated rules
$(foreach mod,$(modules), \
@ -244,16 +221,6 @@ build/demo_%.bmp.o: demo/resources/%.bmp
$(if $(VERBOSE),,@ printf '\e[36;1mres \u00bb\e[0m fxconv $<\n')
$(if $(VERBOSE),,@) fxconv $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<)
# Debug application
build/debug_%.s.o: debug/%.s $(config)
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m as $<\n')
$(if $(VERBOSE),,@) $(as) -c $< -o $@
build/debug_%.c.o: debug/%.c $(hdr-dep) $(debug-dep) $(config)
$(if $(VERBOSE),,@ printf '\e[34;1msrc \u00bb\e[0m cc $<\n')
$(if $(VERBOSE),,@) $(cc) -c $< -o $@ $(debug-cflags)
#---
@ -282,9 +249,7 @@ endif
install-demo: all
p7 send -f $(target-g1a)
install-debug: all
p7 send -f $(target-dbg)
.PHONY: all-lib all help
.PHONY: clean mrproper distclean
.PHONY: install install-demo install-debug
.PHONY: install install-demo

14
TODO
View file

@ -1,10 +1,11 @@
Bugs to fix:
- A few key hits ignored after leaving the application (could not reproduce)
- Lost keyboard control at startup (could not reproduce)
- Alignment of ALL .data / .rodata files is required to ensure converted data
is properly aligned
- Unpreditcable crap happens when more than 10 keys are pressed simultaneously
- Ensure heap data is freed when a task-switch results in leaving the app
Things to do before 1.0:
- init: Move qdiv10() somewhere else
- bopti: Test partial transparency
- demo: Try 284x124 at (-60, -28) (all disadvantages)
- project: Check size of *all* library structures
@ -33,8 +34,15 @@ Things to do later:
- usb: Implement a driver
Things to investigate:
- Packed bit fields alignment
- Registers that may need to be saved within setjmp()
- Optimizing core/gint.c leads to raising of an illegal slot exception when
running the interrupt handler, although it ends on rte; lds.l @r15+, mach,
which is totally not an illegal slot.
Possibly useful modules:
- DMAC
- SCIF, SCIFA
- TPU
- USB
- CMT on SH7305, WDT on SH7705
- ACD (SH7705 only)

24
configure vendored
View file

@ -7,9 +7,10 @@
declare -A conf
# Behavior
conf[GINT_DIAGNOSTICS]=
conf[GINT_STARTUP_LOG]=
conf[GINT_NO_SYSCALLS]=
conf[GINT_EXTENDED_LIBC]=
conf[GINT_STATIC_GRAY]=
# Size limits
conf[ATEXIT_MAX]=16
@ -37,15 +38,18 @@ help()
Configuration script for the gint library.
Options that affect the behavior of the library:
$Cr--diagnostics $Cg[default:$Cp false$Cg]$C0
Use gint in debug mode, where the library outputs some diagnostics in
memory or briefly on screen to diagnose incompatibilites or crashes.
$Cr--startup-log $Cg[default:$Cp false$Cg]$C0
Enable a on-screen log at startup if a key is kept pressed while launching
the add-in, allowing easy debug and crash diagnoses.
$Cr--no-syscalls $Cg[default:$Cp false$Cg]$C0
Never use syscalls. Expect some trouble with the malloc() function... do
Never use syscalls. Expect trouble with malloc() and the gray engine. Do
not trigger this switch unless you know what you are doing.
$Cr--extended-libc $Cg[default:$Cp false$Cg]$C0
Enable specific C99 headers/features that are normally not required by
calculator programs. This may allow porting programs from other platforms.
$Cr--static-gray-engine $Cg[default:$Cp false$Cg]$C0
Place the gray engine vram in static ram instead of using the heap. Always
use this option when using both the gray engine and --no-syscalls.
Options that customize size limits:
$Cr--atexit-max$C0=$Cy<integer>$Cg [default:$Cp 16$Cg]$C0
@ -66,9 +70,10 @@ EOF
fail=false
for arg; do case "$arg" in
-h | --help) help;;
--diagnostics) conf[GINT_DIAGNOSTICS]=true;;
--no-syscalls) conf[GINT_NO_SYSCALLS]=true;;
--extended-libc) conf[GINT_EXTENDED_LIBC]=true;;
--startup-log) conf[GINT_STARTUP_LOG]=true;;
--no-syscalls) conf[GINT_NO_SYSCALLS]=true;;
--extended-libc) conf[GINT_EXTENDED_LIBC]=true;;
--static-gray-engine) conf[GINT_STATIC_GRAY]=true;;
--atexit-max=*)
size=${arg#*=}
@ -103,9 +108,10 @@ esac; done
output_config_gcc()
{
[ "${conf[GINT_DIAGNOSTICS]}" != "" ] && echo "-D GINT_DIAGNOSTICS"
[ "${conf[GINT_STARTUP_LOG]}" != "" ] && echo "-D GINT_STARTUP_LOG"
[ "${conf[GINT_NO_SYSCALLS]}" != "" ] && echo "-D GINT_NO_SYSCALLS"
[ "${conf[GINT_EXTENDED_LIBC]}" != "" ] && echo "-D GINT_EXTENDED_LIBC"
[ "${conf[GINT_STATIC_GRAY]}" != "" ] && echo "-D GINT_STATIC_GRAY"
echo "-D ATEXIT_MAX=${conf[ATEXIT_MAX]}"
echo "-D TIMER_SLOTS=${conf[TIMER_SLOTS]}"

View file

@ -1,31 +0,0 @@
OUTPUT_ARCH(sh3)
ENTRY(initialize)
MEMORY
{
rom : o = 0x00300200, l = 512k
ram : o = 0x08100000, l = 64k /* pretty safe guess */
}
SECTIONS
{
.text : {
*(.pretext) /* init stuff */
*(.text)
} > rom
.rodata : {
*(.rodata)
*(.rodata.str1.4)
_romdata = . ; /* symbol for initialization data */
} > rom
.bss : {
_bbss = . ;
_bssdatasize = . ;
LONG(0); /* bssdatasize */
*(.bss) *(COMMON);
_ebss = . ;
} > ram
.data : AT(_romdata) {
_bdata = . ;
*(.data);
_edata = . ;
} > ram
}

View file

@ -1,172 +0,0 @@
.section .pretext
.global initialize
initialize:
sts.l pr, @-r15
! set up TLB
mov.l Hmem_SetMMU, r3
mov.l address_one, r4 ! 0x8102000
mov.l address_two, r5 ! 0x8801E000
jsr @r3 ! _Hmem_SetMMU
mov #108, r6
! clear the BSS
mov.l bbss, r4 ! start
mov.l ebss, r5 ! end
bra L_check_bss
mov #0, r6
L_zero_bss:
mov.l r6, @r4 ! zero and advance
add #4, r4
L_check_bss:
cmp/hs r5, r4
bf L_zero_bss
! Copy the .data
mov.l bdata, r4 ! dest
mov.l edata, r5 ! dest limit
mov.l romdata, r6 ! source
bra L_check_data
nop
L_copy_data:
mov.l @r6+, r3
mov.l r3, @r4
add #4, r4
L_check_data:
cmp/hs r5, r4
bf L_copy_data
mov.l bbss, r4
mov.l edata, r5
sub r4, r5 ! size of .bss and .data sections
add #4, r5
mov.l bssdatasize, r4
mov.l r5, @r4
mov.l GLibAddinAplExecutionCheck, r2
mov #0, r4
mov #1, r5
jsr @r2 ! _GLibAddinAplExecutionCheck(0,1,1);
mov r5, r6
mov.l CallbackAtQuitMainFunction, r3
mov.l exit_handler, r4
jsr @r3 ! _CallbackAtQuitMainFunction(&exit_handler)
nop
mov.l main, r3
jmp @r3 ! _main()
lds.l @r15+, pr
_exit_handler:
mov.l r14, @-r15
mov.l r13, @-r15
mov.l r12, @-r15
sts.l pr, @-r15
mov.l Bdel_cychdr, r14
jsr @r14 ! _Bdel_cychdr
mov #6, r4
jsr @r14 ! _Bdel_cychdr
mov #7, r4
jsr @r14 ! _Bdel_cychdr
mov #8, r4
jsr @r14 ! _Bdel_cychdr
mov #9, r4
jsr @r14 ! _Bdel_cychdr
mov #10, r4
mov.l BfileFLS_CloseFile, r12
mov #4, r14
mov #0, r13
L_close_files:
jsr @r12 ! _BfileFLS_CloseFile
mov r13, r4
add #1, r13
cmp/ge r14, r13
bf L_close_files
mov.l flsFindClose, r12
mov #0, r13
L_close_finds:
jsr @r12 ! _flsFindClose
mov r13, r4
add #1, r13
cmp/ge r14, r13
bf L_close_finds
lds.l @r15+, pr
mov.l @r15+, r12
mov.l @r15+, r13
mov.l Bkey_Set_RepeatTime_Default, r2
jmp @r2 ! _Bkey_Set_RepeatTime_Default
mov.l @r15+, r14
.align 4
address_two: .long 0x8801E000
address_one: .long 0x8102000
Hmem_SetMMU: .long _Hmem_SetMMU
GLibAddinAplExecutionCheck: .long _GLibAddinAplExecutionCheck
CallbackAtQuitMainFunction: .long _CallbackAtQuitMainFunction
Bdel_cychdr: .long _Bdel_cychdr
BfileFLS_CloseFile: .long _BfileFLS_CloseFile
flsFindClose: .long _flsFindClose
Bkey_Set_RepeatTime_Default: .long _Bkey_Set_RepeatTime_Default
bbss: .long _bbss
ebss: .long _ebss
edata: .long _edata
bdata: .long _bdata
romdata: .long _romdata
bssdatasize: .long _bssdatasize
exit_handler: .long _exit_handler
main: .long _main
_Hmem_SetMMU:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x3FA
_Bdel_cychdr:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x119
_BfileFLS_CloseFile:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x1E7
_Bkey_Set_RepeatTime_Default:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x244
_CallbackAtQuitMainFunction:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x494
_flsFindClose:
mov.l sc_addr, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x218
_GLibAddinAplExecutionCheck:
mov.l sc_addr, r2
mov #0x13, r0
jmp @r2
nop
sc_addr: .long 0x80010070
.end

View file

@ -1,178 +0,0 @@
//---
//
// gintdbg
//
// A simple debugger for gint applications, providing diagnoses to
// determine what went bad.
//
//---
// Just for structure definitions, gint does not run here.
#define GINT_DIAGNOSTICS
#include <internals/gint.h>
#include <mpu.h>
#include <fxlib.h>
#include <stdarg.h>
#include <stddef.h>
// Some functions from other files...
int vsprintf(char *buffer, const char *format, va_list args);
int sprintf(char *buffer, const char *format, ...);
//---
// Some util...
//---
static int print_row = 1;
void print(int col, const char *format, ...)
{
int row = print_row;
print_row++;
if(row < 1 || row > 8) return;
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
locate(col, row);
Print((unsigned char *)buffer);
}
void newline(void)
{
print_row++;
}
void nothing_found(void)
{
unsigned int key;
Bdisp_AllClr_VRAM();
PopUpWin(6);
print_row = 2;
print(3, "Apparently there");
print(3, "is no diagnostic.");
print(3, "");
print(3, "Show anyway?");
print(3, " Yes:[F1]");
print(3, " No :[MENU]");
do GetKey(&key);
while(key != KEY_CTRL_F1);
}
void show_diagnostics(void)
{
volatile gint_diagnostics_t *dg = gint_diagnostics();
const char *stages[] = {
"Startup", "Sections", "MMU", "Gint", "Clock", "Constructors",
"Running", "Leaving", "Destructors", "Terminated",
};
const char *mpus[] = {
"Unknown", "SH7337", "SH7355", "SH7305", "SH7724",
};
print(1, "Gint debugger (%d)", dg->counter);
newline();
print(1, "General information");
print(2, "Magic 0x%02x", dg->magic);
print(2, "Stage %s", dg->stage <= 9 ? stages[dg->stage] : "-");
if(dg->stage >= stage_gint)
{
print(2, "MPU %s", dg->mpu <= 4 ? mpus[dg->mpu] : "-");
}
print(2, "Version %08x", dg->version);
newline();
print(1, "Memory map");
print(2, "%08x romdata", dg->romdata);
print(2, "%08x vbr", dg->vbr_address);
print(2, "%08x:%05x text", dg->section_text.address,
dg->section_text.length);
print(2, "%08x:%05x data", dg->section_data.address,
dg->section_data.length);
print(2, "%08x:%05x bss", dg->section_bss.address,
dg->section_bss.length);
print(2, "%08x:%05x gint", dg->section_gint.address,
dg->section_gint.length);
newline();
print(1, "Exception records");
size_t len = sizeof dg->except_vect;
char line[19];
for(size_t i = 0; i < len; i += 6)
{
for(size_t n = 0; n < 6 && i + n < len; n++)
{
size_t index = (dg->excepts + i + n) % len;
sprintf(line + 3 * n, " %02x", dg->except_vect[index]);
}
print(1, "%s", line);
}
print(2, "SPC %08x", dg->spc);
print(2, "SSR %08x", dg->ssr);
print(2, "EXPEVT %08x", dg->expevt);
print(2, "TEA %08x", dg->tea);
newline();
if(dg->stage >= stage_clock)
{
print(1, "Clock frequencies");
print(2, "Bus clock %d MHz", dg->Bphi_f);
print(2, "Peripheral %d MHz", dg->Pphi_f);
print(2, "Processor %d MHz", dg->Iphi_f);
newline();
}
}
/*
main()
Let's do this!
*/
int main(void)
{
volatile gint_diagnostics_t *dg = gint_diagnostics();
unsigned int key;
if(dg->magic != GINT_DIAGNOSTICS_MAGIC
|| dg->stage > 9
|| dg->mpu > 4
) nothing_found();
int total_height = -1;
int y = 0;
while(1)
{
Bdisp_AllClr_VRAM();
print_row = 1 - y;
show_diagnostics();
if(total_height < 0) total_height = print_row - 1;
// Drawing a scrollbar.
if(total_height > 8)
{
int base = (64 * y) / total_height;
int height = (64 * 8) / total_height;
Bdisp_DrawLineVRAM(127, base, 127, base + height);
}
Bdisp_PutDisp_DD();
do GetKey(&key);
while(key != KEY_CTRL_UP && key != KEY_CTRL_DOWN);
if(key == KEY_CTRL_UP && y > 0) y--;
else if(key == KEY_CTRL_DOWN && y + 8 < total_height) y++;
}
return 1;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,97 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : dispbios.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __DISPBIOS_H__
#define __DISPBIOS_H__
// Defines
#define IM_VRAM_WIDTH 128
#define IM_VRAM_HEIGHT 64
#define IM_VRAM_SIZE 1024
#define IM_CHARACTERS_MAX_LINE 21
#define IM_BYTES_MAX_LINE (IM_CHARACTERS_MAX_LINE*2)
#define SAVEDISP_PAGE1 1
#define SAVEDISP_PAGE2 5
#define SAVEDISP_PAGE3 6
#define MINI_OVER 0x10
#define MINI_OR 0x11
#define MINI_REV 0x12
#define MINI_REVOR 0x13
#define IM_BIOS_DD_WIDTH IM_VRAM_WIDTH
#define IM_BIOS_DD_HEIGHT IM_VRAM_HEIGHT
#define WRITEKIND unsigned char
#define IMB_WRITEKIND_OVER 0x01
#define IMB_WRITEKIND_OR 0x02
#define IMB_WRITEKIND_AND 0x03
#define IMB_WRITEKIND_XOR 0x04
#define WRITEMODIFY unsigned char
#define IMB_WRITEMODIFY_NORMAL 0x01
#define IMB_WRITEMODIFY_REVERCE 0x02
#define IMB_WRITEMODIFY_MESH 0x03
#define AREAKIND unsigned char
#define IMB_AREAKIND_OVER 0x01
#define IMB_AREAKIND_MESH 0x02
#define IMB_AREAKIND_CLR 0x03
#define IMB_AREAKIND_REVERSE 0x04
#define EFFECTWIN unsigned char
#define IMB_EFFECTWIN_OK 0x01
#define IMB_EFFECTWIN_NG 0x02
// Structs
typedef struct tag_DISPBOX{
int left;
int top;
int right;
int bottom;
} DISPBOX;
typedef struct tag_GRAPHDATA{
int width;
int height;
unsigned char *pBitmap;
} GRAPHDATA;
typedef struct tag_RECTANGLE{
DISPBOX LineArea;
AREAKIND AreaKind;
EFFECTWIN EffectWin;
} RECTANGLE;
typedef struct tag_DISPGRAPH{
int x;
int y;
GRAPHDATA GraphData;
WRITEMODIFY WriteModify;
WRITEKIND WriteKind;
} DISPGRAPH;
#endif
#ifdef __cplusplus
}
#endif

View file

@ -1,31 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : endian.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __ENDIAN_H__
#define __ENDIAN_H__
// Macros
#define UtlSwapWord(w) (unsigned short)((((w) & 0x00ff) << 8) | (((w) & 0xff00) >> 8))
#define UtlSwapDword(l) (unsigned long)((((l) & 0x000000ff) << 24) | (((l) & 0x0000ff00) << 8) | (((l) & 0xff000000) >> 24) | (((l) & 0x00ff0000) >> 8))
#define UtlSwapInteger(i) UtlSwapDword(i)
#define UtlSwapPointer(p) (void*)((((unsigned long)(p) & 0x000000ff) << 24) | (((unsigned long)(p) & 0x0000ff00) << 8) | (((unsigned long)(p) & 0xff000000) >> 24) | (((unsigned long)(p) & 0x00ff0000) >> 8))
#endif
#ifdef __cplusplus
}
#endif

View file

@ -1,116 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : filebios.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __FILEBIOS_H__
#define __FILEBIOS_H__
// Defines
#define FONTCHARACTER unsigned short
#define _OPENMODE_READ 0x01
#define _OPENMODE_READ_SHARE 0x80
#define _OPENMODE_WRITE 0x02
#define _OPENMODE_READWRITE 0x03
#define _OPENMODE_READWRITE_SHARE 0x83
#define _CREATEMODE_BINARY 1
#define _CREATEMODE_DIRECTORY 5
enum DEVICE_TYPE{
DEVICE_MAIN_MEMORY,
DEVICE_STORAGE,
DEVICE_SD_CARD, // only fx-9860G SD model
};
// File system standard error code
#define IML_FILEERR_NOERROR 0
#define IML_FILEERR_ENTRYNOTFOUND -1
#define IML_FILEERR_ILLEGALPARAM -2
#define IML_FILEERR_ILLEGALPATH -3
#define IML_FILEERR_DEVICEFULL -4
#define IML_FILEERR_ILLEGALDEVICE -5
#define IML_FILEERR_ILLEGALFILESYS -6
#define IML_FILEERR_ILLEGALSYSTEM -7
#define IML_FILEERR_ACCESSDENYED -8
#define IML_FILEERR_ALREADYLOCKED -9
#define IML_FILEERR_ILLEGALTASKID -10
#define IML_FILEERR_PERMISSIONERROR -11
#define IML_FILEERR_ENTRYFULL -12
#define IML_FILEERR_ALREADYEXISTENTRY -13
#define IML_FILEERR_READONLYFILE -14
#define IML_FILEERR_ILLEGALFILTER -15
#define IML_FILEERR_ENUMRATEEND -16
#define IML_FILEERR_DEVICECHANGED -17
//#define IML_FILEERR_NOTRECORDFILE -18 // Not used
#define IML_FILEERR_ILLEGALSEEKPOS -19
#define IML_FILEERR_ILLEGALBLOCKFILE -20
//#define IML_FILEERR_DEVICENOTEXIST -21 // Not used
//#define IML_FILEERR_ENDOFFILE -22 // Not used
#define IML_FILEERR_NOTMOUNTDEVICE -23
#define IML_FILEERR_NOTUNMOUNTDEVICE -24
#define IML_FILEERR_CANNOTLOCKSYSTEM -25
#define IML_FILEERR_RECORDNOTFOUND -26
//#define IML_FILEERR_NOTDUALRECORDFILE -27 // Not used
#define IML_FILEERR_NOTALARMSUPPORT -28
#define IML_FILEERR_CANNOTADDALARM -29
#define IML_FILEERR_FILEFINDUSED -30
#define IML_FILEERR_DEVICEERROR -31
#define IML_FILEERR_SYSTEMNOTLOCKED -32
#define IML_FILEERR_DEVICENOTFOUND -33
#define IML_FILEERR_FILETYPEMISMATCH -34
#define IML_FILEERR_NOTEMPTY -35
#define IML_FILEERR_BROKENSYSTEMDATA -36
#define IML_FILEERR_MEDIANOTREADY -37
#define IML_FILEERR_TOOMANYALARMITEM -38
#define IML_FILEERR_SAMEALARMEXIST -39
#define IML_FILEERR_ACCESSSWAPAREA -40
#define IML_FILEERR_MULTIMEDIACARD -41
#define IML_FILEERR_COPYPROTECTION -42
#define IML_FILEERR_ILLEGALFILEDATA -43
// FILE_INFO.type
#define DT_DIRECTORY 0x0000 // Directory
#define DT_FILE 0x0001 // File
#define DT_ADDIN_APP 0x0002 // Add-In application
#define DT_EACT 0x0003 // eActivity
#define DT_LANGUAGE 0x0004 // Language
#define DT_BITMAP 0x0005 // Bitmap
#define DT_MAINMEM 0x0006 // Main Memory data
#define DT_TEMP 0x0007 // Temporary data
#define DT_DOT 0x0008 // . (Current directory)
#define DT_DOTDOT 0x0009 // .. (Parent directory)
#define DT_VOLUME 0x000A // Volume label
// Structs
typedef struct tag_FILE_INFO
{
unsigned short id;
unsigned short type;
unsigned long fsize; // File size
unsigned long dsize; // Data size
unsigned int property; // The file has not been completed, except when property is 0.
unsigned long address;
} FILE_INFO;
#endif
#ifdef __cplusplus
}
#endif

View file

@ -1,100 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : fxlib.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __FXLIB_H__
#define __FXLIB_H__
#include "dispbios.h"
#include "filebios.h"
#include "keybios.h"
// Prototypes
void Bdisp_AllClr_DD(void);
void Bdisp_AllClr_VRAM(void);
void Bdisp_AllClr_DDVRAM(void);
void Bdisp_AreaClr_DD(const DISPBOX *pArea);
void Bdisp_AreaClr_VRAM(const DISPBOX *pArea);
void Bdisp_AreaClr_DDVRAM(const DISPBOX *pArea);
void Bdisp_AreaReverseVRAM(int x1, int y1, int x2, int y2);
void Bdisp_GetDisp_DD(unsigned char *pData);
void Bdisp_GetDisp_VRAM(unsigned char *pData);
void Bdisp_PutDisp_DD(void);
void Bdisp_PutDispArea_DD(const DISPBOX *PutDispArea);
void Bdisp_SetPoint_DD(int x, int y, unsigned char point);
void Bdisp_SetPoint_VRAM(int x, int y, unsigned char point);
void Bdisp_SetPoint_DDVRAM(int x, int y, unsigned char point);
int Bdisp_GetPoint_VRAM(int x, int y);
void Bdisp_WriteGraph_DD(const DISPGRAPH *WriteGraph);
void Bdisp_WriteGraph_VRAM(const DISPGRAPH *WriteGraph);
void Bdisp_WriteGraph_DDVRAM(const DISPGRAPH *WriteGraph);
void Bdisp_ReadArea_DD(const DISPBOX *ReadArea, unsigned char *ReadData);
void Bdisp_ReadArea_VRAM(const DISPBOX *ReadArea, unsigned char *ReadData);
void Bdisp_DrawLineVRAM(int x1, int y1, int x2, int y2);
void Bdisp_ClearLineVRAM(int x1, int y1, int x2, int y2);
void locate(int x, int y);
void Print(const unsigned char *str);
void PrintRev(const unsigned char *str);
void PrintC(const unsigned char *c);
void PrintRevC(const unsigned char *str);
void PrintLine(const unsigned char *str, int max);
void PrintRLine(const unsigned char *str, int max);
void PrintXY(int x, int y, const unsigned char *str, int type);
int PrintMini(int x, int y, const unsigned char *str, int type);
void SaveDisp(unsigned char num);
void RestoreDisp(unsigned char num);
void PopUpWin(int n);
int Bfile_OpenFile(const FONTCHARACTER *filename, int mode);
int Bfile_OpenMainMemory(const unsigned char *name);
int Bfile_ReadFile(int HANDLE, void *buf, int size, int readpos);
int Bfile_WriteFile(int HANDLE, const void *buf, int size);
int Bfile_SeekFile(int HANDLE, int pos);
int Bfile_CloseFile(int HANDLE);
int Bfile_GetMediaFree(enum DEVICE_TYPE devicetype, int *freebytes);
int Bfile_GetFileSize(int HANDLE);
int Bfile_CreateFile(const FONTCHARACTER *filename, int size);
int Bfile_CreateDirectory(const FONTCHARACTER *pathname);
int Bfile_CreateMainMemory(const unsigned char *name);
int Bfile_RenameMainMemory(const unsigned char *oldname, const unsigned char *newname);
int Bfile_DeleteFile(const FONTCHARACTER *filename);
int Bfile_DeleteDirectory(const FONTCHARACTER *pathname);
int Bfile_DeleteMainMemory(const unsigned char *name);
int Bfile_FindFirst(const FONTCHARACTER *pathname, int *FindHandle, FONTCHARACTER *foundfile, FILE_INFO *fileinfo);
int Bfile_FindNext(int FindHandle, FONTCHARACTER *foundfile, FILE_INFO *fileinfo);
int Bfile_FindClose(int FindHandle);
void Bkey_Set_RepeatTime(long FirstCount, long NextCount);
void Bkey_Get_RepeatTime(long *FirstCount, long *NextCount);
void Bkey_Set_RepeatTime_Default(void);
int GetKeyWait(int sel, int time, int menu, unsigned int *keycode);
int IsKeyDown(int keycode);
int IsKeyUp(int keycode);
int GetKey(unsigned int *keycode);
int SetTimer(int ID, int elapse, void (*hander)(void));
int KillTimer(int ID);
void Sleep(int millisecond);
void SetQuitHandler(void (*callback)(void));
int INIT_ADDIN_APPLICATION(int isAppli, unsigned short OptionNum);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -1,158 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : keybios.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __KEYBIOS_H__
#define __KEYBIOS_H__
// Defines
// Character codes
#define KEY_CHAR_0 0x30
#define KEY_CHAR_1 0x31
#define KEY_CHAR_2 0x32
#define KEY_CHAR_3 0x33
#define KEY_CHAR_4 0x34
#define KEY_CHAR_5 0x35
#define KEY_CHAR_6 0x36
#define KEY_CHAR_7 0x37
#define KEY_CHAR_8 0x38
#define KEY_CHAR_9 0x39
#define KEY_CHAR_DP 0x2e
#define KEY_CHAR_EXP 0x0f
#define KEY_CHAR_PMINUS 0x87
#define KEY_CHAR_PLUS 0x89
#define KEY_CHAR_MINUS 0x99
#define KEY_CHAR_MULT 0xa9
#define KEY_CHAR_DIV 0xb9
#define KEY_CHAR_FRAC 0xbb
#define KEY_CHAR_LPAR 0x28
#define KEY_CHAR_RPAR 0x29
#define KEY_CHAR_COMMA 0x2c
#define KEY_CHAR_STORE 0x0e
#define KEY_CHAR_LOG 0x95
#define KEY_CHAR_LN 0x85
#define KEY_CHAR_SIN 0x81
#define KEY_CHAR_COS 0x82
#define KEY_CHAR_TAN 0x83
#define KEY_CHAR_SQUARE 0x8b
#define KEY_CHAR_POW 0xa8
#define KEY_CHAR_IMGNRY 0x7f50
#define KEY_CHAR_LIST 0x7f51
#define KEY_CHAR_MAT 0x7f40
#define KEY_CHAR_EQUAL 0x3d
#define KEY_CHAR_PI 0xd0
#define KEY_CHAR_ANS 0xc0
#define KEY_CHAR_LBRCKT 0x5b
#define KEY_CHAR_RBRCKT 0x5d
#define KEY_CHAR_LBRACE 0x7b
#define KEY_CHAR_RBRACE 0x7d
#define KEY_CHAR_CR 0x0d
#define KEY_CHAR_CUBEROOT 0x96
#define KEY_CHAR_RECIP 0x9b
#define KEY_CHAR_ANGLE 0x7f54
#define KEY_CHAR_EXPN10 0xb5
#define KEY_CHAR_EXPN 0xa5
#define KEY_CHAR_ASIN 0x91
#define KEY_CHAR_ACOS 0x92
#define KEY_CHAR_ATAN 0x93
#define KEY_CHAR_ROOT 0x86
#define KEY_CHAR_POWROOT 0xb8
#define KEY_CHAR_SPACE 0x20
#define KEY_CHAR_DQUATE 0x22
#define KEY_CHAR_VALR 0xcd
#define KEY_CHAR_THETA 0xce
#define KEY_CHAR_A 0x41
#define KEY_CHAR_B 0x42
#define KEY_CHAR_C 0x43
#define KEY_CHAR_D 0x44
#define KEY_CHAR_E 0x45
#define KEY_CHAR_F 0x46
#define KEY_CHAR_G 0x47
#define KEY_CHAR_H 0x48
#define KEY_CHAR_I 0x49
#define KEY_CHAR_J 0x4a
#define KEY_CHAR_K 0x4b
#define KEY_CHAR_L 0x4c
#define KEY_CHAR_M 0x4d
#define KEY_CHAR_N 0x4e
#define KEY_CHAR_O 0x4f
#define KEY_CHAR_P 0x50
#define KEY_CHAR_Q 0x51
#define KEY_CHAR_R 0x52
#define KEY_CHAR_S 0x53
#define KEY_CHAR_T 0x54
#define KEY_CHAR_U 0x55
#define KEY_CHAR_V 0x56
#define KEY_CHAR_W 0x57
#define KEY_CHAR_X 0x58
#define KEY_CHAR_Y 0x59
#define KEY_CHAR_Z 0x5a
// Control codes
#define KEY_CTRL_NOP 0
#define KEY_CTRL_EXE 30004
#define KEY_CTRL_DEL 30025
#define KEY_CTRL_AC 30015
#define KEY_CTRL_FD 30046
#define KEY_CTRL_XTT 30001
#define KEY_CTRL_EXIT 30002
#define KEY_CTRL_SHIFT 30006
#define KEY_CTRL_ALPHA 30007
#define KEY_CTRL_OPTN 30008
#define KEY_CTRL_VARS 30016
#define KEY_CTRL_UP 30018
#define KEY_CTRL_DOWN 30023
#define KEY_CTRL_LEFT 30020
#define KEY_CTRL_RIGHT 30021
#define KEY_CTRL_F1 30009
#define KEY_CTRL_F2 30010
#define KEY_CTRL_F3 30011
#define KEY_CTRL_F4 30012
#define KEY_CTRL_F5 30013
#define KEY_CTRL_F6 30014
#define KEY_CTRL_CATALOG 30100
#define KEY_CTRL_CAPTURE 30055
#define KEY_CTRL_CLIP 30050
#define KEY_CTRL_PASTE 30036
#define KEY_CTRL_INS 30033
#define KEY_CTRL_MIXEDFRAC 30054
#define KEY_CTRL_FRACCNVRT 30026
#define KEY_CTRL_QUIT 30029
#define KEY_CTRL_PRGM 30028
#define KEY_CTRL_SETUP 30037
#define KEY_CTRL_PAGEUP 30052
#define KEY_CTRL_PAGEDOWN 30053
#define KEY_CTRL_MENU 30003
#define KEY_CTRL_RESERVE1 30060
#define KEY_CTRL_RESERVE2 30061
#define KEY_CTRL_RESERVE3 30062
// in Bkey_GetKeyWait function
#define KEYWAIT_HALTON_TIMEROFF 0
#define KEYWAIT_HALTOFF_TIMEROFF 1
#define KEYWAIT_HALTON_TIMERON 2
#define KEYREP_NOEVENT 0
#define KEYREP_KEYEVENT 1
#define KEYREP_TIMEREVENT 2
#endif
#ifdef __cplusplus
}
#endif

View file

@ -1,31 +0,0 @@
/*****************************************************************/
/* */
/* CASIO fx-9860G SDK Library */
/* */
/* File name : timer.h */
/* */
/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */
/* */
/*****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __TIMER_H__
#define __TIMER_H__
// Defines
#define ID_USER_TIMER1 1
#define ID_USER_TIMER2 2
#define ID_USER_TIMER3 3
#define ID_USER_TIMER4 4
#define ID_USER_TIMER5 5
#endif
#ifdef __cplusplus
}
#endif

Binary file not shown.

View file

@ -1,160 +0,0 @@
//---
// vsprintf()
//
// Unfortunately this function, which is part of fxlib, was broken by a
// terribly un-professional port (incidentally, I am responsible for
// this, so I can't complain). So we'll need something simple...
//
// Format Flags Character count
// %d none no
// %x 0 yes
// %p none no
// %c none no
// %s none no
//---
#include <stdarg.h>
#include <stdint.h>
void vsprintf_int(char **buffer_ptr, int n)
{
char *buffer = *buffer_ptr;
if(!n)
{
*buffer++ = '0';
*buffer_ptr = buffer;
return;
}
if(n < 0)
{
*buffer++ = '-';
n = -n;
}
int digits = 0, x = n, copy;
while(x) digits++, x /= 10;
copy = digits;
while(digits)
{
buffer[--digits] = n % 10 + '0';
n /= 10;
}
*buffer_ptr = buffer + copy;
}
void vsprintf_hexa(char **buffer_ptr, uint32_t val, int digits, int zero)
{
char *buffer = *buffer_ptr;
if(!val)
{
while(digits-- > 1) *buffer++ = (zero) ? '0' : ' ';
*buffer++ = '0';
*buffer_ptr = buffer;
return;
}
if(digits <= 0)
{
uint32_t x = val;
while(x) digits++, x >>= 4;
}
int copy = digits;
while(val && digits)
{
buffer[--digits] = (val & 15) + '0' + 39 * ((val & 15) > 9);
val >>= 4;
}
while(digits)
{
buffer[--digits] = (zero) ? '0': ' ';
}
*buffer_ptr = buffer + copy;
}
void vsprintf_ptr(char **buffer_ptr, void *ptr)
{
vsprintf_hexa(buffer_ptr, (uint32_t)ptr, 8, 1);
}
void vsprintf_char(char **buffer_ptr, int c)
{
char *buffer = *buffer_ptr;
*buffer++ = c;
*buffer_ptr = buffer;
}
void vsprintf_str(char **buffer_ptr, const char *str)
{
char *buffer = *buffer_ptr;
while(*str) *buffer++ = *str++;
*buffer_ptr = buffer;
}
int vsprintf(char *buffer, const char *format, va_list args)
{
char *save = buffer;
int zero, count;
while(*format)
{
if(*format != '%')
{
*buffer++ = *format++;
continue;
}
if(!*++format) break;
zero = 0;
count = 0;
if(*format == '0') zero = 1, format++;
while(*format >= '0' && *format <= '9')
{
count *= 10;
count += (*format++ - '0');
}
if(!*format) break;
switch(*format)
{
case 'd':
vsprintf_int(&buffer, va_arg(args, int));
break;
case 'x':
vsprintf_hexa(&buffer, va_arg(args, uint32_t), count,
zero);
break;
case 'p':
vsprintf_ptr(&buffer, va_arg(args, void *));
break;
case 'c':
vsprintf_char(&buffer, va_arg(args, int));
break;
case 's':
vsprintf_str(&buffer, va_arg(args, const char *));
break;
default:
*buffer++ = *format;
break;
}
format++;
}
*buffer = 0;
return buffer - save;
}
int sprintf(char *buffer, const char *format, ...)
{
va_list args;
va_start(args, format);
int x = vsprintf(buffer, format, args);
va_end(args);
return x;
}

View file

@ -277,8 +277,7 @@ void tlb_debug(void)
}
*/
#include <modules/rtc.h>
#include <modules/interrupts.h>
#include <internals/timer.h>
/*
main_menu()
@ -435,14 +434,11 @@ void main_menu(int *category, int *app)
index = 0;
scroll = 0;
break;
case KEY_F5:
gint_switch();
break;
case KEY_F6:;
/* case KEY_F6:;
void screen(void);
screen();
break;
*/
case KEY_UP:
if(list && list_len > 1)
{
@ -484,11 +480,6 @@ void main_menu(int *category, int *app)
if(app) *app = index + 1;
return;
/* case KEY_MENU:
if(category) *category = 0;
if(app) *app = 0;
return;
*/
default:
leave = 0;
}
@ -533,7 +524,7 @@ int main(void)
return 0;
}
void crash(void)
static void crash(void)
{
__asm__(
"mov #0, r0 \n\t"
@ -542,7 +533,7 @@ void crash(void)
);
}
void screen(void)
static void screen(void)
{
enum { File = 1, Folder = 5 };
enum { Read = 0x01, Write = 0x02, ReadWrite = Read | Write };

View file

@ -13,36 +13,32 @@ ENTRY(_start)
MEMORY
{
/* System-managed mappings map this area into the add-in data */
rom : o = 0x00300200, l = 512k
/* 0x0810000 is apparently mapped to 0x8801c0000. */
/* 0x0810000 is apparently mapped to 0x8801c0000 */
ram : o = 0x08100000, l = 8k
/* RAM section from P1 area, no MMU involved */
realram : o = 0x8800d000, l = 12k
}
SECTIONS
{
/*
ROM sections : binary code and read-only data.
*/
/* ROM sections: binary code and read-only data */
.text : {
_btext = . ;
/* Initialization code. */
*(.pretext.entry)
*(.pretext)
_bctors = . ;
_bctors = ABSOLUTE(.);
*(.ctors)
_ectors = . ;
_bdtors = . ;
_ectors = ABSOLUTE(.);
_bdtors = ABSOLUTE(.);
*(.dtors)
_edtors = . ;
_edtors = ABSOLUTE(.);
*(.text)
*(.text.*)
_etext = . ;
} > rom
.rodata : {
@ -55,26 +51,23 @@ SECTIONS
_romdata = ALIGN(4) ;
} > rom
/*
RAM sections : bss section and read/write data.
The BSS section is meant to be stripped from the ELF file (to
reduce the binary size) and initialized with zeros in the
initialization routine, therefore its location is undefined.
*/
/* RAM sections: bss section and read/write data
The .bss section is to be stripped from the ELF file and wiped at
startup, hence its location is undefined */
.bss : {
_bbss = . ;
_bbss = ABSOLUTE(.);
_sbss = ABSOLUTE(SIZEOF(.bss));
*(.bss)
_ebss = . ;
} > ram
.data : AT(_romdata) ALIGN(4) {
_bdata = . ;
_bdata = ABSOLUTE(.);
_sdata = ABSOLUTE(SIZEOF(.data));
*(.data)
*(.data.*)
_edata = . ;
} > ram
.cc : AT(_romdata + SIZEOF(.data)) ALIGN(4) {
@ -82,33 +75,39 @@ SECTIONS
*(.jcr)
. = ALIGN(4);
_gint_data = _romdata + SIZEOF(.data) + SIZEOF(.cc) ;
} > ram
/* Real RAM sections: interrupt handlers and some *uninitialized* gint
data */
/*
Real RAM : interrupt, exception and TLB miss handlers.
*/
_gint_data = _romdata + SIZEOF(.data) + SIZEOF(.cc) ;
.gint : AT(_gint_data) ALIGN(4) {
/* The vbr needs to be 0x100-aligned because of an ld issue. */
/* The vbr needs to be 0x100-aligned because of an ld issue */
. = ALIGN(0x100) ;
_gint_vbr = . ;
_bgint = . ;
/* Exception handler. */
_gint_vbr = . ;
_bgint = ABSOLUTE(.) ;
/* Exception handler */
. = _gint_vbr + 0x100 ;
*(.gint.exc)
/* TLB miss handler. */
/* TLB miss handler */
. = _gint_vbr + 0x400 ;
*(.gint.tlb)
/* Interrupt handler. */
/* Interrupt handler */
. = _gint_vbr + 0x600 ;
*(.gint.int)
_egint = . ;
. = ALIGN(4);
_egint = ABSOLUTE(.) ;
} > realram
.gint_bss : AT(_gint_data + SIZEOF(.gint)) ALIGN(4) {
_bgbss = ABSOLUTE(.) ;
*(.gint.bss)
_egbss = ABSOLUTE(.) ;
} > realram
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -11,27 +11,26 @@
static void draw(int delay1, int delay2, int selected)
{
extern image_t res_opt_gray;
extern font_t res_font_modern;
uint32_t *vl = gray_lightVRAM();
uint32_t *vd = gray_darkVRAM();
gclear();
locate(1, 1, "Gray engine");
for(int i = 0; i < 36; i++)
for(int i = 0; i < 64; i++)
{
int o = ((i + 12) << 2) + 2;
unsigned light = -((i % 24) < 12);
unsigned dark = -(i < 24);
vl[o] = light >> 8;
vl[o + 1] = light << 8;
vd[o] = dark >> 8;
vd[o + 1] = dark << 8;
int offset = (i << 2) + 3;
vl[offset] = -(!(i & 16));
vd[offset] = -(i < 32);
}
locate(3, 3, "light");
print(4, 4, "%d", delay1);
text_configure(&res_font_modern, color_black);
gtext(13, 17, "light");
gtext(13, 31, "dark");
locate(3, 5, "dark");
text_configure(NULL, color_black);
print(4, 4, "%d", delay1);
print(4, 6, "%d", delay2);
locate(3, selected ? 6 : 4, "\x02");

View file

@ -4,9 +4,8 @@
#include <stdlib.h>
#include <events.h>
static int draw_keyboard(volatile uint8_t *state)
static void draw_keyboard(volatile uint8_t *state)
{
int pressed_keys = 0;
int i, j, k, l;
int x, y;
@ -30,7 +29,6 @@ static int draw_keyboard(volatile uint8_t *state)
// Drawing a filled shape when the key is pressed.
if(state[i] & (0x80 >> j))
{
pressed_keys++;
for(k = -2; k <= 2; k++) for(l = -2; l <= 2; l++)
if(abs(k) + abs(l) <= 2)
dpixel(x + k, y + l, color_black);
@ -51,8 +49,6 @@ static int draw_keyboard(volatile uint8_t *state)
// An horizontal line to separate parts of the keyboard.
dline(5, 28, 32, 28, color_black);
return pressed_keys;
}
typedef struct {
@ -66,7 +62,7 @@ typedef struct {
int pressed;
} history_t;
static int pressed_keys = -1;
static int pressed_keys = 0;
static int releases = 0;
static void history_push(history_t *h, event_t event)
@ -120,19 +116,25 @@ static void draw_events(history_t *h)
};
int y = 3;
int y_limit = 8 - (h->pressed > h->size);
print(8, 2, "%d %d %d", pressed_keys, h->pressed, releases);
extern font_t res_font_modern;
text_configure(&res_font_modern, color_black);
dtext(49, 12, "Key");
dtext(89, 12, "Rep.");
// dprint(49, 7, "%d %d %d", h->pressed, pressed_keys, releases);
text_configure(NULL, color_black);
dline(45, 18, 120, 18, color_black);
for(int i = 0; i < h->size; i++)
for(int i = 0; i < h->size && y < y_limit; i++) if(h->data[i].key)
{
if(!h->data[i].key) continue;
print(8, y, "%s", key_names[key_id(h->data[i].key)]);
dtext(49, y * 8 - 4, key_names[key_id(h->data[i].key)]);
if(h->data[i].repeats > 1)
print(18, y, "%d", h->data[i].repeats);
dprint(89, y * 8 - 4, "%d", h->data[i].repeats);
y++;
}
if(h->pressed > h->size) print(8, 8, "(more)");
if(h->pressed > h->size) dtext(49, 52, "(more)");
}
/*
@ -149,15 +151,37 @@ void test_keyboard_events(void)
};
event_t event;
// There may be keys pressed when this test starts. We need to detect
// which and create a valid history for them.
volatile const uint8_t *buffer = keyboard_stateBuffer();
// For the purpose of this function we don't need to calculate the
// other fields.
event_t push_event = {
.type = event_key_press,
.key.code = KEY_AC_ON,
};
// Finding all the pressed keys and pushing them in the history.
if(buffer[0] & 1) history_push(&history, push_event);
for(int row = 1; row <= 9; row++) for(int col = 0; col < 8; col++)
{
// Eliminate non-existing keys.
if(col > 6 || col <= (row <= 4)) continue;
if(buffer[row] & (1 << col))
{
push_event.key.code = (col << 4) | row;
history_push(&history, push_event);
}
}
while(1)
{
dclear();
locate(1, 1, "Keyboard and events");
// There may be more than zero keys pressed when this test
// starts. We need to detect this count automatically.
int x = draw_keyboard(keyboard_stateBuffer());
if(pressed_keys < 0) pressed_keys = x;
draw_keyboard(keyboard_stateBuffer());
draw_events(&history);
dupdate();

View file

@ -49,14 +49,14 @@ typedef struct
{
// This is the key code as defined in <keyboard.h> (a matrix code), and
// probably what you need.
uint32_t code;
uint16_t code;
// This is a "compact id" which can be used for array subscript. There
// are only a few holes in the "compact id" numbering.
uint32_t id;
uint16_t id;
// Character associated with the event key.
int character;
} key_event_t;
} __attribute__((packed, aligned(4))) key_event_t;
/*
event_t
@ -77,7 +77,7 @@ typedef struct
timer_t *timer;
};
} event_t;
} __attribute__((packed, aligned(4))) event_t;

View file

@ -2,6 +2,7 @@
#define _INTERNALS_GINT_H
#include <stdint.h>
#include <mpu.h>
#include <gint.h>
//---
@ -45,7 +46,7 @@ void gint_setvbr(uint32_t vbr, void (*setup)(void));
Initializes gint. Loads the interrupt handler into the memory and sets
the new vbr address.
*/
void gint_init(void);
void gint_init(mpu_t mpu);
/*
gint_quit()
@ -135,101 +136,4 @@ void gint_restore_and_unlock_7305(environment_7305_t *env);
volatile void *gint_reg_7705(gint_register_t reg);
volatile void *gint_reg_7305(gint_register_t reg);
//---
// Diagnostics
// When diagnostics are enabled, gint saves runtime information to a
// buffer in RAM, which by chance is held if the application crashes (I
// don't really know why). This allows deeper debugging.
//---
#ifdef GINT_DIAGNOSTICS
#include <mpu.h>
// Determining whether the SaveDisp() buffer actually contains gint diagnostics
// is performed by checking a magic number (1/256 chance of failure) and the
// validity of all fields in the diagnostic information. Formally, a picture
// taken by SaveDisp() could fool the checks but this is *very* unlikely and
// the diagnostics should only be read just after gint crashes or stops anyway.
#define GINT_DIAGNOSTICS_MAGIC 0xb7
typedef enum
{
stage_startup = 0,
stage_sections = 1,
stage_mmu = 2,
stage_gint = 3,
stage_clock = 4,
stage_ctors = 5,
stage_running = 6,
stage_leaving = 7,
stage_dtors = 8,
stage_terminated = 9,
} gint_stage_t;
typedef struct
{
uint32_t address;
uint32_t length;
} gint_memsection_t;
typedef struct
{
// Magic number to check whether there is a diagnostic.
uint8_t magic :8;
// Unique counter that is incremented at each execution, allowing to
// distinguish diagnostics output at different times if the application
// crashes repeatedly.
uint8_t counter :8;
// How many work of initialization had been successfully done before
// the application crashed.
gint_stage_t stage :8;
// What kind of MPU the library detected (undefined if the
// initialization stage does not reach stage_gint).
mpu_t mpu :8;
// Frequency of the main clocks, in MHz.
uint8_t Bphi_f :8;
uint8_t Iphi_f :8;
uint8_t Pphi_f :8;
// What kind of exceptions occurred last.
uint8_t excepts :8;
uint8_t except_vect[12];
// Last values held by registers SPC, SSR, EXPEVT / INTEVT2 / INTEVT,
// and TEA.
uint32_t spc;
uint32_t ssr;
uint32_t expevt;
uint32_t tea;
// Gint version number, on the form 0xMMmmbbbb, where MM is the major
// version, mm the minor version and bbbb the build number.
uint32_t version;
// Location of the VBR at the time of execution.
uint32_t vbr_address;
// Memory map.
uint32_t romdata;
gint_memsection_t section_text;
gint_memsection_t section_data;
gint_memsection_t section_bss;
gint_memsection_t section_gint;
} gint_diagnostics_t;
// This is somewhere inside the buffers of SaveDisp(), 3 bytes inside the first
// buffer to be exact (that's to be 4-aligned).
// This buffer is 1024-byte long so the logs must fit in 1021 bytes to be safe.
// It looks like that this RAM area is generally not cleared when the
// calculator reboots after a crash, even though it does not seem to work with
// manual resets. Maybe it can provide useful information in some cases.
#define gint_diagnostics() ((volatile gint_diagnostics_t *)0x88004d90)
#endif // GINT_DIAGNOSTICS
#endif // _INTERNALS_GINT_H

37
include/internals/init.h Normal file
View file

@ -0,0 +1,37 @@
//---
// gint core module: init
// Program initialization and display manipulation for the startup logs.
//---
#ifndef _INTERNALS_INIT_H
#define _INTERNALS_INIT_H
#include <display.h>
struct qdiv
{
uint32_t q, r;
};
/* qdiv10() -- quickly divide by 10 */
struct qdiv qdiv10(uint32_t n);
/* init_version() -- get a version string */
const char *init_version(void);
/* init_stage() -- change the current init stage */
void init_stage(const char *name);
/* init_halt() -- halt the program */
void init_halt(void);
/* print() -- print text on a 21*8 grid */
#define print(x, y, str) dtext((x) * 6 - 5, (y) * 8 - 8, (str))
/* print_dec() -- print a number in base 10 */
void print_dec(int x, int y, int n, int digits);
/* print_hex() -- print a number in base 16 */
void print_hex(int x, int y, uint32_t n, int digits);
#endif // _INTERNALS_INIT_H

View file

@ -39,4 +39,11 @@ int getPressedKeys(volatile uint8_t *keyboard_state, int *keys, int count);
void keyboard_updateState_7705(volatile uint8_t *state);
void keyboard_updateState_7305(volatile uint8_t *state);
/*
keyboard_interrupt()
Answers an interrupt event by updating the keyboard state and
generating the associated keyboard events.
*/
void keyboard_interrupt(void);
#endif // _INTERNALS_KEYBOARD_H

View file

@ -0,0 +1,26 @@
//---
// gint core module: syscalls
// Some of the functionality still requires interacting with the system.
//---
#ifndef _INTERNALS_SYSCALLS_H
#define _INTERNALS_SYSCALLS_H
#include <stddef.h>
/* malloc() -- allocate data in heap */
void *__malloc(size_t size);
/* free() -- free data allocated by malloc(), calloc() or realloc() */
void __free(void *ptr);
/* realloc() -- reallocate a chunk of memory */
void *__realloc(void *chunk, size_t new_size);
/* get_os_version() -- write the OS version in format MM.mm.pppp to a string */
void __get_os_version(char *str);
/* system_menu() -- go back to menu, assuming the system has the control */
void __system_menu(const void *vram);
#endif // _INTERNALS_SYSCALLS_H

View file

@ -10,13 +10,6 @@
extern font_t *font;
extern color_t operator;
/*
tales_init()
Configures tales with the default font (which is part of gint).
*/
__attribute__((constructor))
void tales_init(void);
/*
getCharacterIndex()
Returns the index of a character in a font data area depending on the

View file

@ -11,11 +11,9 @@
*/
typedef struct timer_t
{
// Current delay, how much time elapsed since last interrupt occurred,
// and how many repeats are left.
int ms_delay;
int ms_elapsed;
int repeats_left;
// Current delay, how much time elapsed since last interrupt occurred.
uint32_t ms_delay;
uint32_t ms_elapsed;
// Is the virtual slot free? Is the virtual timer active?
uint8_t used :1;
@ -25,12 +23,14 @@ typedef struct timer_t
uint8_t vsupport :1;
// How many events do I have received but not executed?
uint8_t events :4;
// How many repeats are left.
uint32_t repeats_left :24;
// Callback function (NULL for event-firing timers) and its argument.
void *callback;
void *argument;
} timer_t;
} __attribute__((packed, aligned(4))) timer_t;
// Hardware timers.
extern timer_t htimers[3];

View file

@ -12,8 +12,8 @@
// care of assuming unknown MPUs are SH4, which is the more reasonable
// option.
//
// In a general way, it is advised to always use the following
// alternative (which gint does):
// It is advised to always use the following alternative (which gint
// does):
//
// if(isSH3())
// {
@ -54,7 +54,7 @@ extern const mpu_t MPU_CURRENT;
// Quick SH3 test. It is safer to assume that an unknown model is SH4 because
// SH3-based models are not produced anymore.
#define isSH3() (MPU_CURRENT == mpu_sh7337 || MPU_CURRENT == mpu_sh7355)
#define isSH4() !isSH3()
#define isSH4() (!isSH3())

View file

@ -1,253 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <stdint.h>
#include <internals/gint.h>
#include <internals/mmu.h>
#include <internals/clock.h>
#include <clock.h>
#include <gint.h>
#include <internals/modules.h>
int main(void);
static void init(void);
static void fini(void);
// Symbols provided by the linker script.
extern uint32_t
etext, btext, // Location of .text section
bdata, edata, // Location of .data section
bbss, ebss, // Location of .bss section
bgint, egint, // Location of interrupt handler and gint data
gint_vbr, // VBR address
romdata; // ROM address of .data section contents
// This variable should be overwritten before being returned, so the default
// value doesn't matter much.
static int exit_code = EXIT_SUCCESS;
static jmp_buf env;
// Exit handlers.
void (*atexit_handlers[ATEXIT_MAX])(void);
int atexit_index = 0;
/*
start()
Program entry point. Loads the data section into the memory and invokes
main(). Also prepares the execution environment by initializing all the
modules.
*/
__attribute__((section(".pretext.entry"))) int start(void)
{
#ifdef GINT_DIAGNOSTICS
// OK, so fill as much information as possible so that in case anything
// goes wrong we can try to analyze what's been going on.
volatile gint_diagnostics_t *dg = gint_diagnostics();
// All that follows is "safe" information that can be saved immediately
// because it will never change anyway.
// Basic environment description.
dg->magic = GINT_DIAGNOSTICS_MAGIC;
dg->counter = dg->counter + 1;
dg->mpu = mpu_unknown;
dg->version = (uint32_t)&GINT_VERSION;
dg->stage = stage_startup;
// Exception records: what kind of exceptions / TLB faults / interrupts
// occurred last to get some trace in case of crash.
dg->excepts = 0;
for(size_t i = 0; i < sizeof dg->except_vect; i++)
dg->except_vect[i] = 0;
dg->spc = 0x00000000;
dg->ssr = 0x00000000;
dg->expevt = 0x00000000;
dg->tea = 0x00000000;
// Memory map: provides information about alignment and the relative
// size and position of each section, as well as read-only / read-write
// types of addresses.
dg->section_text.address = (uint32_t)&btext;
dg->section_text.length = (uint32_t)&etext - (uint32_t)&btext;
dg->section_data.address = (uint32_t)&bdata;
dg->section_data.length = (uint32_t)&edata - (uint32_t)&bdata;
dg->section_bss.address = (uint32_t)&bbss;
dg->section_bss.length = (uint32_t)&ebss - (uint32_t)&bbss;
dg->romdata = (uint32_t)&romdata;
// Basic information about the running library.
dg->vbr_address = (uint32_t)&gint_vbr;
dg->section_gint.address = (uint32_t)&bgint;
dg->section_gint.length = (uint32_t)&egint - (uint32_t)&bgint;
#endif
// Clearing the .bss section.
uint32_t *bss = &bbss;
while(bss < &ebss) *bss++ = 0;
// Copying the .data section.
uint32_t *data = &bdata, *src = &romdata;
while(data < &edata) *data++ = *src++;
#ifdef GINT_DIAGNOSTICS
dg->stage = stage_sections;
#endif
// Trying to get the system to fill the TLB without editing it
// directly, so that it does not go on rampage when finding out.
mmu_pseudoTLBInit();
#ifdef GINT_DIAGNOSTICS
// At this point it would be wise to include a copy of the TLB, but
// it's already a huge array. Maybe later...
/* TODO Debug TLB? */
dg->stage = stage_mmu;
#endif
// Initializing gint, which does several things:
// - Detect the MPU and platform
// - Initialize register addresses in a platform-independent way
// - Save the current environment information in a large buffer
// - Set up the interrupt handler and configure everything gint needs
gint_init();
#ifdef GINT_DIAGNOSTICS
dg->mpu = MPU_CURRENT;
dg->stage = stage_gint;
#endif
// Measuring clock frequencies.
clock_measure();
clock_measure_end();
#ifdef GINT_DIAGNOSTICS
clock_config_t clock = clock_config();
dg->Bphi_f = clock.Bphi_f / 1000000;
dg->Iphi_f = clock.Iphi_f / 1000000;
dg->Pphi_f = clock.Pphi_f / 1000000;
dg->stage = stage_clock;
#endif
// Calling global constructors.
init();
#ifdef GINT_DIAGNOSTICS
dg->stage = stage_ctors;
dg->stage = stage_running;
#endif
// Saving the execution state there.
int x = setjmp(env);
// If the program has just started, executing main(). Otherwise, the
// exit code has already been set by abort() or similar.
if(!x) exit_code = main();
#ifdef GINT_DIAGNOSTICS
dg->stage = stage_leaving;
#endif
/* TODO Flush and close opened streams. */
// Calling exit handlers and destructors.
while(atexit_index > 0) (*atexit_handlers[--atexit_index])();
fini();
#ifdef GINT_DIAGNOSTICS
dg->stage = stage_dtors;
#endif
// Un-initializing gint.
gint_quit();
#ifdef GINT_DIAGNOSTICS
dg->stage = stage_terminated;
#endif
return exit_code;
}
/*
init()
Calls the constructors.
*/
static void init(void)
{
extern void
(*bctors)(void),
(*ectors)(void);
void (**func)(void) = &bctors;
while(func < &ectors)
{
(*(*func))();
func++;
}
}
/*
fini()
Calls the destructors.
*/
static void fini(void)
{
extern void
(*bdtors)(void),
(*edtors)(void);
void (**func)(void) = &bdtors;
while(func < &edtors)
{
(*(*func))();
func++;
}
}
/*
abort()
Immediately ends the program without invoking the exit handlers.
*/
void abort(void)
{
exit_code = EXIT_FAILURE;
// Avoiding any exit handler call.
atexit_index = 0;
longjmp(env, 1);
}
/*
exit()
Ends the program and returns the given exit code status. Calls exit
handlers before returning.
Usually exit() would ask the operating system to stop the process but
the fx-9860G executes only one program at a time and calls it as a
function. Reaching the program end point is therefore an efficient way
of achieving this goal while minimizing interaction with the operating
system.
*/
void exit(int status)
{
exit_code = status;
longjmp(env, 1);
}
/*
atexit()
Registers a function to be called at normal program termination.
*/
int atexit(void (*function)(void))
{
if(atexit_index >= ATEXIT_MAX) return 1;
atexit_handlers[atexit_index++] = function;
return 0;
}

View file

@ -21,11 +21,11 @@ static void setup(void)
isSH3() ? gint_lock_and_setup_7705()
: gint_lock_and_setup_7305();
}
void gint_init(void)
void gint_init(mpu_t mpu)
{
// Detecting the MPU type. I don't like const-casting but this is still
// Setting the MPU type. I don't like const-casting but this is still
// better than allowing the user to change the variable by mistake.
*((mpu_t *)&MPU_CURRENT) = getMPU();
*((mpu_t *)&MPU_CURRENT) = mpu;
// Loading the register addresses of the current platform.
mod_init();
@ -89,23 +89,29 @@ void gint_quit(void)
#include <display.h>
#include <gray.h>
/*
__system_menu()
Updates the system's vram and triggers the calculator's main menu.
*/
void __system_menu(void *vram);
// Stores gint's configuration while the user visits the main menu.
static environment_t switch_env;
/*
gint_switch()
Temporarily returns to the system's main menu.
*/
static environment_t switch_env;
static void switch_(void)
static void restore(void)
{
isSH3() ? gint_restore_and_unlock_7705(&switch_env.env_7705)
: gint_restore_and_unlock_7305(&switch_env.env_7305);
}
void gint_switch(void)
{
// Save the current environment in a special buffer, so that we can
// restore it if we ever come back to gint.
isSH3() ? gint_save_7705(&switch_env.env_7705)
: gint_save_7305(&switch_env.env_7305);
// Give the control back to the system.
gint_setvbr(gint.system_vbr, stop);
// When returning to the add-in from the menu, the system displays the
@ -120,5 +126,5 @@ void gint_switch(void)
__system_menu(vram);
// If the user came back, restore the gint working environment.
gint_setvbr(gint.gint_vbr, switch_);
gint_setvbr(gint.gint_vbr, restore);
}

View file

@ -9,7 +9,8 @@
#include <mpu.h>
#include <stdint.h>
const mpu_t MPU_CURRENT;
/* Located in gint's uninitialized bss section */
__attribute__((section(".gint.bss"))) const mpu_t MPU_CURRENT;
/*
getMPU()

View file

@ -1,14 +1,25 @@
/*
gint core module: syscalls
All the system calls used by the library. Somehow "the less, the
better".
We have finally gotten rid of every obscure system-related syscalls!
System calls (and the like) used by the library. The library should
rely the least possible on the system, but sometimes using the syscalls
is nothing of a nuisance.
For instance, using the malloc()-family syscalls is a bit annoying
because it "locks" many functionalities. On the other hand, getting the
SaveDisp() buffer addresses to store data here is not a problem since
such data can very easily be relocated to static RAM.
*/
/* Dynamic allocation */
.global ___malloc
.global ___free
.global ___realloc
/* OS version */
.global ___get_os_version
/* Return to menu */
.global ___system_menu
@ -34,6 +45,13 @@ ___realloc:
nop
1: .long 0xe6d
___get_os_version:
mov.l syscall_table, r2
mov.l 1f, r0
jmp @r2
nop
1: .long 0x02ee
/*
__system_menu()
Brings one back to the system menu by putting KEY_MENU in the system's

View file

@ -1,9 +1,8 @@
#include <display.h>
// Program video ram. It resides in BSS section, therefore it is cleared at
// program initialization and stripped from the executable file.
static uint32_t local_vram[256];
uint32_t *vram = local_vram;
/* Add-in monochrome vram in gint's uninitialized bss section */
__attribute__((section(".gint.bss"))) static uint32_t vram_local[256];
__attribute__((section(".gint.bss"))) uint32_t *vram;
/*
display_getLocalVRAM()
@ -16,7 +15,7 @@ uint32_t *vram = local_vram;
*/
inline uint32_t *display_getLocalVRAM(void)
{
return local_vram;
return vram_local;
}
/*
@ -43,6 +42,6 @@ inline uint32_t *display_getCurrentVRAM(void)
*/
inline void display_useVRAM(uint32_t *ptr)
{
if((intptr_t)ptr & 3) return;
if((uintptr_t)ptr & 3) return;
vram = ptr;
}

View file

@ -10,9 +10,12 @@
#include <screen.h>
#include <timer.h>
#include <mpu.h>
#include <stdlib.h>
// Additional video rams used by the gray engine.
static uint32_t internal_vrams[3][256];
#ifdef GINT_STATIC_GRAY
static uint32_t internals_vrams[3][256];
#endif
static uint32_t *vrams[4];
// Current vram set (0 or 1), delays of the light and dark frames respectively.
@ -31,10 +34,7 @@ static timer_t *gray_timer = NULL;
// Interrupt control and initialization.
//---
/*
gray_interrupt()
Answers a timer interrupt. Swaps the buffers.
*/
/* gray_interrupt() -- switch buffers and update the screen */
void gray_interrupt(void)
{
htimer_reload(timer_gray, delays[(~current) & 1]);
@ -43,21 +43,33 @@ void gray_interrupt(void)
current ^= 1;
}
/*
gray_init()
Initializes the gray engine.
*/
__attribute__((constructor)) void gray_init(void)
/* gray_init() -- setup the video ram buffers and timer delays */
__attribute__((constructor)) static void gray_init(void)
{
vrams[0] = display_getLocalVRAM();
#ifdef GINT_STATIC_GRAY
vrams[1] = internal_vrams[0];
vrams[2] = internal_vrams[1];
vrams[3] = internal_vrams[2];
#else
vrams[1] = NULL;
vrams[2] = NULL;
vrams[3] = NULL;
#endif
delays[0] = 912;
delays[1] = 1343;
}
/* gray_quit() -- Free the gray engine's heap-allocated video rams */
__attribute__((destructor)) static void gray_quit(void)
{
#ifndef GINT_STATIC_GRAY
free(vrams[1]);
free(vrams[2]);
free(vrams[3]);
#endif
}
//---
@ -71,6 +83,14 @@ __attribute__((constructor)) void gray_init(void)
*/
void gray_start(void)
{
#ifndef GINT_STATIC_GRAY
for(int i = 0; i < 4; i++)
{
if(!vrams[i]) vrams[i] = malloc(1024);
/* Don't continue if any of the buffer is missing */
if(!vrams[i]) return;
}
#endif
if(runs) return;
gray_timer = htimer_setup(timer_gray, delays[0], timer_Po_64, 0);

306
src/init/crt0.c Normal file
View file

@ -0,0 +1,306 @@
#include <stdlib.h>
#include <setjmp.h>
#include <internals/gint.h>
#include <internals/mmu.h>
#include <internals/clock.h>
#include <display.h>
#include <internals/init.h>
#include <internals/modules.h>
/* We need some more functionality to generate these */
#ifdef GINT_STARTUP_LOG
#include <gint.h>
#include <clock.h>
#include <events.h>
#include <internals/keyboard.h>
#include <modules/interrupts.h>
#ifndef GINT_NO_SYSCALLS
#include <internals/syscalls.h>
#endif
#endif
int main(void);
static void init(void);
static void fini(void);
// Symbols provided by the linker script.
extern uint32_t
bdata, sdata, // Location of .data section
bbss, sbss, // Location of .bss section
bgint, egint, // Location of interrupt handler and gint data
bgbss, egbss, // Location of interrupt handler and gint data
gint_vbr, // VBR address
romdata, // ROM address of .data section contents
gint_data; // ROM address of .gint section contents
extern void
(*bctors)(void), (*ectors)(void), // Constructors
(*bdtors)(void), (*edtors)(void); // Destructors
// This variable should be overwritten before being returned, so the default
// value doesn't matter much.
static int exit_code = EXIT_SUCCESS;
static jmp_buf env;
// Exit handlers.
static void (*atexit_handlers[ATEXIT_MAX])(void);
static int atexit_index = 0;
#include <internals/display.h>
/*
start()
Program entry point. Loads the data section into the memory and invokes
main(). Also prepares the execution environment by initializing all the
modules.
*/
__attribute__((section(".pretext.entry"))) int start(void)
{
/* Configure the display output or we won't get anywhere - this is also
needed for the add-in even if the startup logs are disabled */
display_useVRAM(display_getLocalVRAM());
text_configure(NULL, color_black);
#ifdef GINT_STARTUP_LOG
/* Start outputting information on the screen so that we can quickly
debug anything that would fail */
uint32_t rom_size = ((uint32_t)&romdata - 0x00300000) >> 10;
uint32_t ram_size = ((uint32_t)&gint_data - (uint32_t)&romdata)
+ ((uint32_t)&sbss);
uint32_t rram_size = ((uint32_t)&egbss - (uint32_t)&gint_vbr);
dclear();
init_stage("Startup");
dupdate();
print(1, 1, init_version());
print(1, 2, "ROM RAM RRAM");
print(4, 3, "k c d");
print_dec(1, 3, rom_size, 3);
print_dec(6, 3, ram_size, 4);
print_dec(11, 3, rram_size, 4);
print_dec(17, 3, &ectors - &bctors, 2);
print_dec(20, 3, &edtors - &bdtors, 2);
dupdate();
#endif
/* Determining the processor type */
mpu_t mpu = getMPU();
#ifdef GINT_STARTUP_LOG
const char *mpu_names[] = { "SH7337", "SH7355", "SH7305", "SH7724" };
if(mpu >= 1 && mpu <= 4) print(16, 2, mpu_names[mpu - 1]);
else print_dec(16, 2, mpu, 6);
dupdate();
#endif
/* Make sure the MPU is of a valid type */
if(!mpu || mpu > 4) init_halt();
#ifdef GINT_STARTUP_LOG
init_stage(" MMU");
dupdate();
#endif
/* Try to get the TLB filled by the system by accessing all the pages
while the system still answers TLB misses */
mmu_pseudoTLBInit();
#ifdef GINT_STARTUP_LOG
/* Read the TLB and count how much memory has been mapped */
/* TODO: Debug TLB at startup */
print(1, 4, "MMU ROM:???k RAM:???k");
init_stage("Section");
dupdate();
#endif
/* Copying the data section, then clearing the bss section. This
doesn't affect the previously used variables, which are stored in
another section for this purpose */
volatile uint32_t *data = &bdata;
volatile uint32_t *data_end = (void *)&bdata + (int)&sdata;
volatile uint32_t *src = &romdata;
while(data < data_end) *data++ = *src++;
volatile uint32_t *bss = &bbss;
volatile uint32_t *bss_end = (void *)&bbss + (int)&sbss;
while(bss < bss_end) *bss++ = 0;
#ifdef GINT_STARTUP_LOG
init_stage("Handler");
dupdate();
#endif
/* Initialize gint and debug all the interrupt priorities */
gint_init(mpu);
#ifdef GINT_STARTUP_LOG
if(isSH3())
{
print(1, 5, "ABCD");
print_hex( 6, 5, INTC._7705.iprs.IPRA->word, 4);
print_hex(10, 5, INTC._7705.iprs.IPRB->word, 4);
print_hex(14, 5, INTC._7705.iprs.IPRC->word, 4);
print_hex(18, 5, INTC._7705.iprs.IPRD->word, 4);
print(1, 6, "EFGH");
print_hex( 6, 6, INTC._7705.iprs.IPRE->word, 4);
print_hex(10, 6, INTC._7705.iprs.IPRF->word, 4);
print_hex(14, 6, INTC._7705.iprs.IPRG->word, 4);
print_hex(18, 6, INTC._7705.iprs.IPRH->word, 4);
}
else
{
print(1, 5, "ACFG");
print_hex( 6, 5, INTC._7305.iprs->IPRA.word, 4);
print_hex(10, 5, INTC._7305.iprs->IPRC.word, 4);
print_hex(14, 5, INTC._7305.iprs->IPRF.word, 4);
print_hex(18, 5, INTC._7305.iprs->IPRG.word, 4);
print(1, 6, "HJKL");
print_hex( 6, 6, INTC._7305.iprs->IPRH.word, 4);
print_hex(10, 6, INTC._7305.iprs->IPRJ.word, 4);
print_hex(14, 6, INTC._7305.iprs->IPRK.word, 4);
print_hex(18, 6, INTC._7305.iprs->IPRL.word, 4);
}
#endif
/* Checking that at least the required interrupts are enabled */
if(isSH3()
? (!INTC._7705.iprs.IPRA->word)
: (!INTC._7305.iprs->IPRA.word || !INTC._7305.iprs->IPRK.word)
) init_halt();
#ifdef GINT_STARTUP_LOG
init_stage(" Clocks");
dupdate();
#endif
/* Measuring the clock speed */
clock_measure();
clock_measure_end();
#ifdef GINT_STARTUP_LOG
clock_config_t clock = clock_config();
print(1, 7, "Clock I B P");
print_dec( 8, 7, clock.Iphi_f / 1000000, 2);
print_dec(12, 7, clock.Bphi_f / 1000000, 2);
print_dec(16, 7, clock.Pphi_f / 1000000, 2);
init_stage("Boot OK");
dupdate();
/* Displaying some interrupt controller config */
if(isSH3())
{
print(1, 8, "INTC:0");
print_hex(7, 8, INTC._7705.ICR1->word, 4);
}
else
{
print(1, 8, "INTC:");
print_hex(6, 8, INTC._7305.ICR0->word, 4);
print_hex(10, 8, (INTC._7305.USERIMASK->lword >> 4) & 0xf, 1);
}
#ifndef GINT_NO_SYSCALLS
/* Print the OS version */
char version[11];
__get_os_version(version);
version[2] = version[3];
version[3] = version[4];
version[4] = version[6];
version[5] = version[7];
version[6] = version[8];
version[7] = version[9];
version[8] = 0;
print(12, 8, "OS");
print(14, 8, version);
#endif
dupdate();
#endif
/* Call the global constructors */
init();
#ifdef GINT_STARTUP_LOG
/* Keep this visible for a second or so */
keyboard_interrupt();
if(pollevent().type != event_none) getkey();
#endif
/* Otherwise, call main() and get the show on the road! */
int x = setjmp(env);
if(!x) exit_code = main();
while(atexit_index > 0) (*atexit_handlers[--atexit_index])();
fini();
gint_quit();
return exit_code;
}
/* init() -- call the constructors */
static void init(void)
{
extern void
(*bctors)(void),
(*ectors)(void);
void (**func)(void) = &bctors;
while(func < &ectors) (*(*func++))();
}
/* fini() -- call the destructors */
static void fini(void)
{
extern void
(*bdtors)(void),
(*edtors)(void);
void (**func)(void) = &bdtors;
while(func < &edtors) (*(*func++))();
}
/*
abort()
Immediately ends the program without invoking the exit handlers.
*/
void abort(void)
{
exit_code = EXIT_FAILURE;
// Avoiding any exit handler call.
atexit_index = 0;
longjmp(env, 1);
}
/*
exit()
Ends the program and returns the given exit code status. Calls exit
handlers before returning.
Usually exit() would ask the operating system to stop the process but
the fx-9860G executes only one program at a time and calls it as a
function. Reaching the program end point thus efficiently exits.
*/
void exit(int status)
{
exit_code = status;
longjmp(env, 1);
}
/*
atexit()
Registers a function to be called at normal program termination.
*/
int atexit(void (*function)(void))
{
if(atexit_index >= ATEXIT_MAX) return 1;
atexit_handlers[atexit_index++] = function;
return 0;
}

90
src/init/util.c Normal file
View file

@ -0,0 +1,90 @@
#include <internals/init.h>
#include <string.h>
#include <clock.h>
#include <gint.h>
/* qdiv10() -- quickly divide by 10 */
struct qdiv qdiv10(uint32_t n)
{
uint32_t magic10 = 0x1999999a;
struct qdiv result;
__asm__(
"dmuls.l %1, %2 \n\t"
"sts mach, %0 "
: "=r"(result.q)
: "r"(n), "r"(magic10)
: "macl", "mach"
);
result.r = n - 10 * result.q;
return result;
}
/* init_version() -- get a version string */
const char *init_version(void)
{
static char data[14];
uint32_t s = (uint32_t)&GINT_VERSION;
/* Force the string constant to reside in ROM because we haven't
initialized the data section yet */
memcpy(data, "gint #0.0-000", 14);
/* Quickly get the three digits of the build number */
struct qdiv x = qdiv10(s & 0xffff);
struct qdiv y = qdiv10(x.q);
data[5] = (s & 0xff000000) >> 24;
data[6] += ((s & 0x00f00000) >> 20);
data[8] += ((s & 0x000f0000) >> 16);
data[10] += y.q;
data[11] += y.r;
data[12] += x.r;
return data;
}
/* init_stage() -- change the current init stage */
void init_stage(const char *name)
{
drect(85, 0, 127, 7, color_white);
print(15, 1, name);
}
/* init_halt() -- halt the program */
void init_halt(void)
{
while(1) sleep();
}
/* print_dec() -- print a number in base 10 */
void print_dec(int x, int y, int n, int digits)
{
char str[20];
str[digits] = 0;
while(--digits >= 0)
{
struct qdiv d = qdiv10(n);
str[digits] = '0' + d.r;
n = d.q;
}
print(x, y, str);
}
/* print_hex() -- print a number in base 16 */
void print_hex(int x, int y, uint32_t n, int digits)
{
char str[20];
str[digits] = 0;
while(--digits >= 0)
{
str[digits] = (n & 0xf) + '0' + 39 * ((n & 0xf) > 9);
n >>= 4;
}
print(x, y, str);
}

View file

@ -16,7 +16,9 @@ int getkey(void)
getkey_shift_modifier |
getkey_alpha_modifier |
getkey_manage_backlight |
#ifndef GINT_NO_SYSCALLS
getkey_task_switch |
#endif
getkey_repeat_arrow_keys,
0
@ -105,12 +107,14 @@ int getkey_opt(getkey_option_t options, int delay_ms)
break;
case event_key_release:
#ifndef GINT_NO_SYSCALLS
if((options & getkey_task_switch) && event.key.code == KEY_MENU
&& !modifier)
{
gint_switch();
continue;
}
#endif
if((int)event.key.code != last_key) break;
last_key = KEY_NONE;

View file

@ -34,45 +34,6 @@ timer_t *vtimer = NULL;
// Interrupt management.
//---
static inline void push_press(int keycode)
{
uint32_t id = key_id(keycode);
event_t event = {
.type = event_key_press,
.key.code = keycode,
.key.id = id,
.key.character = key_char(keycode),
};
event_push(event);
}
static inline void push_repeat(int keycode)
{
uint32_t id = key_id(keycode);
event_t event = {
.type = event_key_repeat,
.key.code = keycode,
.key.id = id,
.key.character = key_char(keycode),
};
event_push(event);
}
static inline void push_release(int keycode)
{
uint32_t id = key_id(keycode);
event_t event = {
.type = event_key_release,
.key.code = keycode,
.key.id = id,
.key.character = key_char(keycode),
};
event_push(event);
}
/*
keyboard_interrupt()
Callback function for keyboard update; called by the timer manager when

View file

@ -1,54 +0,0 @@
#include <keyboard.h>
#include <internals/keyboard.h>
#include <events.h>
/*
multigetkey()
Listens the keyboard for simultaneous key hits. Uses the same options
as getkey_opt().
multigetkey() fills the 'keys' array with 'count' key codes, adding
KEY_NOKEY if less than 'count' keys are pressed.
Be aware that rectangle and column effects can make multigetkey() read
unpressed keys as pressed (see documentation for more information).
Setting count = 3 is generally safe.
The function returns after 'max_cycles' if no key is pressed.
*/
static void multigetkey_wait(int *cycles)
{
while(!interrupt_flag) sleep();
interrupt_flag = 0;
if(*cycles > 0) (*cycles)--;
}
void multigetkey(int *keys, int count, int cycles)
{
event_t event;
int number = 0;
if(count <= 0) return;
if(cycles <= 0) cycles = -1;
while(cycles != 0)
{
number = getPressedKeys(keyboard_state, keys, count);
// We want to update the last key data when multigetkey()
// returns a single key, because getkey() could be called a
// short time after we return, and send a new event for this
// key.
if(number == 1)
{
last_key = keys[0];
last_repeats = 0;
last_time = 0;
}
if(number) break;
multigetkey_wait(&cycles);
}
do event = pollevent();
while(event.type != event_none);
return;
}

View file

@ -3,7 +3,7 @@
#pragma GCC diagnostic ignored "-Wunused-parameter"
#ifndef GINT_NO_SYSCALLS
void __free(void *ptr);
#include <internals/syscalls.h>
#endif
/*
@ -12,6 +12,9 @@ void __free(void *ptr);
*/
void free(void *ptr)
{
// Just to be sure.
if(!ptr) return;
#ifndef GINT_NO_SYSCALLS
__free(ptr);
#endif

View file

@ -7,8 +7,8 @@
*/
#ifndef GINT_NO_SYSCALLS
#include <internals/syscalls.h>
void *__malloc(size_t size);
void *malloc(size_t size)
{
return __malloc(size);

View file

@ -6,8 +6,8 @@
*/
#ifndef GINT_NO_SYSCALLS
#include <internals/syscalls.h>
void *__realloc(void *ptr, size_t size);
void *realloc(void *ptr, size_t size)
{
return __realloc(ptr, size);

View file

@ -4,17 +4,10 @@
#include <ctype.h>
#include <gray.h>
font_t *font = NULL;
color_t operator;
/*
tales_init()
Configures tales with the default font (which is part of gint).
*/
void tales_init(void)
{
text_configure(NULL, color_black);
}
/* Put these in gint's uninitialized bss section so that text rendering can be
used before the library is fully initialized */
__attribute__((section(".gint.bss"))) font_t *font = NULL;
__attribute__((section(".gint.bss"))) color_t operator;
/*
getCharacterIndex()

View file

@ -1 +1 @@
beta-0.9-410
beta-0.9-566