The Ungodly Update
* Added the switch menu * Added the keyboard menu on fx-CG 50 * Added a (currently unused) bold 8x9 font on fx-CG 50 * Displayed something decent in the "Image Rendering" test on fx-CG 50 * Changed F-keys all around to unify the semantics * Improved the layout of the RAM detection test * Adapted TMU/ETMU display to the new mpu/timer.h definitions * Added a timer selector in the F-key bar in the timer test * Added an "external libraries" tab that will also test libc features * Added a libimg test
10
Makefile
|
@ -136,10 +136,10 @@ build-cg/%.S.o: %.S
|
|||
# Images
|
||||
build-fx/assets/img/%.o: assets-fx/img/%
|
||||
@ mkdir -p $(dir $@)
|
||||
fxconv -i $< -o $@ $(FXCONVFX) name:img_$(basename $*) $(IMG.$*)
|
||||
fxconv --bopti-image $< -o $@ $(FXCONVFX) name:img_$(basename $*) $(IMG.$*)
|
||||
build-cg/assets/img/%.o: assets-cg/img/%
|
||||
@ mkdir -p $(dir $@)
|
||||
fxconv -i $< -o $@ $(FXCONVCG) name:img_$(basename $*) $(IMG.$*)
|
||||
fxconv --bopti-image $< -o $@ $(FXCONVCG) name:img_$(basename $*) $(IMG.$*)
|
||||
|
||||
# Fonts
|
||||
build-fx/assets/fonts/%.o: assets-fx/fonts/%
|
||||
|
@ -184,11 +184,9 @@ distclean: distclean-fx distclean-cg
|
|||
install-fx: $(TARGET_FX)
|
||||
p7 send -f $<
|
||||
install-cg: $(TARGET_CG)
|
||||
@ while [[ ! -h /dev/Prizm1 ]]; do sleep 0.25; done
|
||||
@ while ! mount /dev/Prizm1; do sleep 0.25; done
|
||||
@ prizm-mount
|
||||
@ rm -f /mnt/prizm/$<
|
||||
@ cp $< /mnt/prizm
|
||||
@ umount /dev/Prizm1
|
||||
@- eject /dev/Prizm1
|
||||
@ prizm-eject
|
||||
|
||||
.PHONY: all all-fx all-cg clean distclean install-fx install-cg
|
||||
|
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 919 B |
After Width: | Height: | Size: 877 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 407 B |
After Width: | Height: | Size: 555 B |
After Width: | Height: | Size: 484 B |
After Width: | Height: | Size: 428 B |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 166 B |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.0 KiB |
|
@ -14,6 +14,12 @@ void gintctl_gint_ram(void);
|
|||
/* gintctl_gint_dump(): Dump memory to filesystem */
|
||||
void gintctl_gint_dump(void);
|
||||
|
||||
/* gintctl_gint_switch(): Test the gint switch-in-out procedures */
|
||||
void gintctl_gint_switch(void);
|
||||
|
||||
/* gintct_gint_keybaord: Real-time keyboard visualization */
|
||||
void gintctl_gint_keyboard(void);
|
||||
|
||||
/* gintctl_gint_timer(): Show the timer status in real-time */
|
||||
void gintctl_gint_timer(void);
|
||||
|
||||
|
@ -25,7 +31,7 @@ void gintctl_gint_bopti(void);
|
|||
/* gintctl_gint_dma(): Test the Direct Access Memory Controller */
|
||||
void gintctl_gint_dma(void);
|
||||
|
||||
#endif
|
||||
#endif /* FXCG50 */
|
||||
|
||||
#ifdef FX9860G
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
//---
|
||||
// gintctl:libs - External libraries
|
||||
//---
|
||||
|
||||
#ifndef GINTCTL_LIBS
|
||||
#define GINTCTL_LIBS
|
||||
|
||||
/* gintctl_libs_libimg(): libimg-based rendering and image transform */
|
||||
void gintctl_libs_libimg(void);
|
||||
|
||||
#endif /* GINTCTL_LIBS */
|
20
project.cfg
|
@ -61,11 +61,12 @@ INCLUDE := -I include
|
|||
# Libraries. Add one -l option for each library you are using, and also
|
||||
# suitable -L options if you have library files in custom folders. To use
|
||||
# fxlib, add libfx.a to the project directory and use "-L . -lfx".
|
||||
LIBS := -lprof
|
||||
LIBS_FX := -lprof -limg-fx
|
||||
LIBS_CG := -lprof -limg-cg
|
||||
|
||||
# Base linker flags for the fxSDK, you usually want to keep these.
|
||||
LDFLAGS_FX := -T fx9860g.ld -lgint-fx $(LIBS) -lgint-fx -lgcc
|
||||
LDFLAGS_CG := -T fxcg50.ld -lgint-cg $(LIBS) -lgint-cg -lgcc
|
||||
LDFLAGS_FX := -T fx9860g.ld -lgint-fx $(LIBS_FX) -lgint-fx -lgcc
|
||||
LDFLAGS_CG := -T fxcg50.ld -lgint-cg $(LIBS_CG) -lgint-cg -lgcc
|
||||
|
||||
# Additional linker flags, if you need any.
|
||||
LDFLAGS :=
|
||||
|
@ -80,6 +81,19 @@ LDFLAGS_CG += -Wl,-Map=build-cg/map
|
|||
|
||||
# Parameters for the hexadecimal font on fx9860g
|
||||
FONT.hexa.png = charset:print grid.size:3x5 grid.padding:1
|
||||
FONT.font8x9_bold.png = charset:print grid.size:8x11 grid.padding:1 \
|
||||
grid.border:0 proportional:true
|
||||
|
||||
IMG.swift.png = profile:p4
|
||||
IMG.swords.png = profile:p8
|
||||
|
||||
IMG.kbd_pressed.png = profile:p4
|
||||
IMG.kbd_released.png = profile:p4
|
||||
|
||||
IMG.libimg_even_odd.png = type:libimg-image
|
||||
IMG.libimg_odd_even.png = type:libimg-image
|
||||
IMG.libimg_sq_even.png = type:libimg-image
|
||||
IMG.libimg_sq_odd.png = type:libimg-image
|
||||
IMG.libimg_train.png = type:libimg-image
|
||||
|
||||
IMG.libimg_swords.png = type:libimg-image
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#define GINT_NEED_VRAM
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
#include <gintctl/gint.h>
|
||||
#include <gintctl/util.h>
|
||||
|
||||
/* gintctl_gint_bopti(): Test image rendering */
|
||||
void gintctl_gint_bopti(void)
|
||||
|
@ -9,25 +11,56 @@ void gintctl_gint_bopti(void)
|
|||
#ifdef FXCG50
|
||||
extern image_t img_swift;
|
||||
extern image_t img_swords;
|
||||
|
||||
int x = 396 - img_swords.width - 16;
|
||||
int y = 16;
|
||||
|
||||
int key = 0;
|
||||
extern image_t img_potion_17x22, img_potion_18x22, img_potion_21x22;
|
||||
extern image_t img_applejack_31x27, img_applejack_36x25;
|
||||
int key = 0, x, y;
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
dimage(0, 0, &img_swift);
|
||||
dimage(x, y, &img_swords);
|
||||
row_title("Image rendering");
|
||||
|
||||
x=51, y=25;
|
||||
dtext(x, y, "E.E", C_BLACK, C_NONE);
|
||||
dtext(x+35, y, "E.O", C_BLACK, C_NONE);
|
||||
dtext(x+70, y, "O.E", C_BLACK, C_NONE);
|
||||
dtext(x+105, y, "O.O", C_BLACK, C_NONE);
|
||||
|
||||
x=52, y=40;
|
||||
dtext(10, y+6, "OxE", C_BLACK, C_NONE);
|
||||
dimage(x, y, &img_potion_17x22);
|
||||
dimage(x+35, y+1, &img_potion_17x22);
|
||||
dimage(x+71, y, &img_potion_17x22);
|
||||
dimage(x+106, y+1, &img_potion_17x22);
|
||||
|
||||
x=52, y=67;
|
||||
dtext(10, y+6, "ExE", C_BLACK, C_NONE);
|
||||
dimage(x, y, &img_potion_18x22);
|
||||
dimage(x+35, y+1, &img_potion_18x22);
|
||||
dimage(x+71, y, &img_potion_18x22);
|
||||
dimage(x+106, y+1, &img_potion_18x22);
|
||||
|
||||
x=44, y=95;
|
||||
dtext(10, y+9, "OxO", C_BLACK, C_NONE);
|
||||
dimage(x, y, &img_applejack_31x27);
|
||||
dimage(x+35, y+1, &img_applejack_31x27);
|
||||
dimage(x+71, y, &img_applejack_31x27);
|
||||
dimage(x+106, y+1, &img_applejack_31x27);
|
||||
|
||||
x=40, y=127;
|
||||
dtext(10, y+9, "ExO", C_BLACK, C_NONE);
|
||||
dimage(x, y, &img_applejack_36x25);
|
||||
dimage(x+35, y+1, &img_applejack_36x25);
|
||||
dimage(x+71, y, &img_applejack_36x25);
|
||||
dimage(x+106, y+1, &img_applejack_36x25);
|
||||
|
||||
dimage(190, 35, &img_swords);
|
||||
|
||||
dtext(67, 210, "Some images by Pix3M (deviantart.com/pix3m)",
|
||||
C_BLACK, C_NONE);
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
|
||||
if(key == KEY_UP) y--;
|
||||
if(key == KEY_DOWN) y++;
|
||||
if(key == KEY_LEFT) x--;
|
||||
if(key == KEY_RIGHT) x++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -96,11 +96,11 @@ void gintctl_gint_dma(void)
|
|||
dprint(6, 158, "Source");
|
||||
dprint(96, 158, "%s", source ? "IL" : "RAM");
|
||||
|
||||
fkey_button(1, "RUN");
|
||||
fkey_action(1, "RUN");
|
||||
|
||||
fkey_action(4, "CHANNEL");
|
||||
fkey_action(5, "INT");
|
||||
fkey_action(6, "SOURCE");
|
||||
fkey_button(4, "CHANNEL");
|
||||
fkey_button(5, "INT");
|
||||
fkey_button(6, "SOURCE");
|
||||
#endif
|
||||
|
||||
dupdate();
|
||||
|
|
|
@ -82,7 +82,7 @@ static void hw_cpg(int *row)
|
|||
}
|
||||
|
||||
/* Direct Memory Access Controller */
|
||||
static void hw_dma(int *row)
|
||||
static GUNUSED void hw_dma(GUNUSED int *row)
|
||||
{
|
||||
#ifdef FXCG50
|
||||
int dma = gint[HWDMA];
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
#include <gintctl/util.h>
|
||||
|
||||
void position(int row, int col, int *x, int *y, GUNUSED int *w, GUNUSED int *h)
|
||||
{
|
||||
#ifdef FX9860G
|
||||
*y = 10 + 6 * row;
|
||||
if(row <= 4) *x = 5 + 6 * col;
|
||||
if(row >= 5) *x = 6 + 7 * col;
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
if(row == 0) *y=2, *x=7+29*col, *w=16, *h=16;
|
||||
if(row >= 5) *y=108+23*(row-5), *x=2+35*col, *w=30, *h=17;
|
||||
if(row >= 1 && row <= 4)
|
||||
{
|
||||
*y=28+18*(row-1), *x=2+29*col, *w=25, *h=18;
|
||||
if(row == 1 && col == 4) *x=127, *y=37, *w=12, *h=12;
|
||||
if(row == 1 && col == 5) *x=140, *y=24, *w=12, *h=12;
|
||||
if(row == 2 && col == 4) *x=140, *y=50, *w=12, *h=12;
|
||||
if(row == 2 && col == 5) *x=153, *y=37, *w=12, *h=12;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void render_keyboard(void)
|
||||
{
|
||||
GUNUSED int x, y, w, h;
|
||||
|
||||
#ifdef FXCG50
|
||||
extern image_t img_kbd_pressed;
|
||||
extern image_t img_kbd_released;
|
||||
dimage(15, 21, &img_kbd_released);
|
||||
#endif
|
||||
|
||||
for(int row = 0; row < 9; row++)
|
||||
{
|
||||
int major = (9-row);
|
||||
int key_count = (major >= 5) ? 6 : 5;
|
||||
|
||||
for(int col = 0; col < key_count; col++)
|
||||
{
|
||||
int code = (major << 4) | (col + 1);
|
||||
if(code == 0x45) code = 0x07;
|
||||
|
||||
#ifdef FXCG50
|
||||
if(!keydown(code)) continue;
|
||||
|
||||
position(row, col, &x, &y, &w, &h);
|
||||
dsubimage(15+x, 21+y, &img_kbd_pressed, x,y,w,h, 0);
|
||||
#endif
|
||||
|
||||
#ifdef FX9860G
|
||||
extern image_t img_keypress;
|
||||
extern image_t img_keyrelease;
|
||||
position(row, col, &x, &y, &w, &h);
|
||||
if(keydown(code)) dimage(x, y, &img_keypress);
|
||||
else dimage(x, y, &img_keyrelease);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void render(key_event_t *last_events, int counter)
|
||||
{
|
||||
char const *key_names[] = {
|
||||
"F1", "F2", "F3", "F4", "F5", "F6",
|
||||
"SHIFT", "OPTN", "VARS", "MENU", "Left", "Up",
|
||||
"ALPHA", "x^2", "^", "EXIT", "Down", "Right",
|
||||
"X,O,T", "log", "ln", "sin", "cos", "tan",
|
||||
"frac", "F<>D", "(", ")", ",", "->",
|
||||
"7", "8", "9", "DEL", "AC/ON", "0x46",
|
||||
"4", "5", "6", "*", "/", "0x47",
|
||||
"1", "2", "3", "+", "-", "0x48",
|
||||
"0", ".", "x10^", "(-)", "EXE", "0x49",
|
||||
};
|
||||
|
||||
key_event_t ev;
|
||||
dclear(C_WHITE);
|
||||
|
||||
#ifdef FXCG50
|
||||
row_title("Keyboard state visualizer");
|
||||
int y0=190, dy=14, maxev=12;
|
||||
int x1=230, x2=248;
|
||||
#endif
|
||||
|
||||
#ifdef FX9860G
|
||||
row_print(1, 1, "Keyboard state");
|
||||
int y0=52, dy=8, maxev=6;
|
||||
int x1=55, x2=67;
|
||||
#endif
|
||||
|
||||
for(int i=0, y=y0; i < maxev; i++, y-=dy)
|
||||
{
|
||||
ev = last_events[(counter+15 - i) % 16];
|
||||
if(ev.type == KEYEV_NONE) continue;
|
||||
|
||||
int key = (ev.key == KEY_ACON ? 0x45 : ev.key);
|
||||
int row = 9 - (key >> 4);
|
||||
int col = (key & 15) - 1;
|
||||
char const *name = key_names[6*row + col];
|
||||
|
||||
if(ev.type == KEYEV_UP)
|
||||
dprint(x2, y, C_BLACK, C_NONE, "Up %s", name);
|
||||
if(ev.type == KEYEV_DOWN)
|
||||
dprint(x1, y, C_BLACK,C_NONE,"Down %s", name);
|
||||
}
|
||||
|
||||
render_keyboard();
|
||||
}
|
||||
|
||||
int handle_event(key_event_t *last_events, int counter)
|
||||
{
|
||||
key_event_t ev = last_events[(counter + 15) % 16];
|
||||
|
||||
if(ev.type != KEYEV_DOWN) return 0;
|
||||
if(ev.key == KEY_EXIT) return 1;
|
||||
if(ev.key == KEY_MENU) render(last_events, counter), dupdate(), gint_osmenu();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* gintct_gint_keybaord: Real-time keyboard visualization */
|
||||
void gintctl_gint_keyboard(void)
|
||||
{
|
||||
/* All initialized with type=KEYEV_NONE */
|
||||
key_event_t last_events[16] = { 0 };
|
||||
key_event_t ev;
|
||||
int counter = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
render(last_events, counter);
|
||||
dupdate();
|
||||
|
||||
/* Redraw at each event if needed */
|
||||
last_events[counter] = waitevent(NULL);
|
||||
counter = (counter+1) % 16;
|
||||
if(handle_event(last_events, counter)) return;
|
||||
|
||||
while((ev = pollevent()).type != KEYEV_NONE)
|
||||
{
|
||||
last_events[counter] = ev;
|
||||
counter = (counter+1) % 16;
|
||||
if(handle_event(last_events, counter)) return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -74,8 +74,8 @@ void gintctl_gint_ram(void)
|
|||
|
||||
GUNUSED char const *reasons[] = {
|
||||
"Not tested yet",
|
||||
"Not writable past %d bytes",
|
||||
"Wraps around after %d bytes",
|
||||
"%d bytes (not writable)",
|
||||
"%d bytes (wraps around)",
|
||||
};
|
||||
|
||||
int key = 0;
|
||||
|
@ -102,14 +102,20 @@ void gintctl_gint_ram(void)
|
|||
row_print(2, 1, "memory sections by checking how far it can "
|
||||
"write.");
|
||||
|
||||
dprint(6, 78, C_BLACK, C_NONE, "ILRAM:");
|
||||
dprint(6, 92, C_BLACK, C_NONE, "XRAM:");
|
||||
dprint(6, 106, C_BLACK, C_NONE, "YRAM:");
|
||||
dprint(6, 120, C_BLACK, C_NONE, "MERAM:");
|
||||
dprint(61, 78, C_BLACK, C_NONE, reasons[ILr], IL);
|
||||
dprint(61, 92, C_BLACK, C_NONE, reasons[Xr], X);
|
||||
dprint(61, 106, C_BLACK, C_NONE, reasons[Yr], Y);
|
||||
dprint(61, 120, C_BLACK, C_NONE, reasons[MEr], ME);
|
||||
row_print(4, 2, "ILRAM:");
|
||||
row_print(5, 2, "XRAM:");
|
||||
row_print(6, 2, "YRAM:");
|
||||
row_print(7, 2, "MERAM:");
|
||||
|
||||
row_print(4, 10, "E5200000");
|
||||
row_print(5, 10, "E5007000");
|
||||
row_print(6, 10, "E5017000");
|
||||
row_print(7, 10, "E8080000");
|
||||
|
||||
row_print(4, 21, reasons[ILr], IL);
|
||||
row_print(5, 21, reasons[Xr], X);
|
||||
row_print(6, 21, reasons[Yr], Y);
|
||||
row_print(7, 21, reasons[MEr], ME);
|
||||
|
||||
fkey_button(1, "ILRAM");
|
||||
fkey_button(2, "XRAM");
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
#include <gint/gint.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/clock.h>
|
||||
#include <gint/mpu/tmu.h>
|
||||
#include <gint/std/string.h>
|
||||
|
||||
#include <gintctl/gint.h>
|
||||
#include <gintctl/util.h>
|
||||
|
||||
static int switches = 0;
|
||||
static int fast = 0;
|
||||
static int menus = 0;
|
||||
|
||||
static void switch_function(void)
|
||||
{
|
||||
switches++;
|
||||
}
|
||||
|
||||
//---
|
||||
// Saved system context visualizer
|
||||
//---
|
||||
|
||||
void *driver_ctx(char const *name)
|
||||
{
|
||||
extern gint_driver_t bdrv, edrv;
|
||||
for(gint_driver_t *drv = &bdrv; drv < &edrv; drv++)
|
||||
{
|
||||
if(!strcmp(drv->name, name)) return drv->sys_ctx;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef FX9860G
|
||||
static void ctx_tmu()
|
||||
{
|
||||
tmu_t *t = driver_ctx("TMU");
|
||||
uint8_t *TSTR = (void *)t + 3 * sizeof(tmu_t) + 6 * sizeof(etmu_t);
|
||||
|
||||
for(int i = 0; i < 3; i++, t++)
|
||||
{
|
||||
row_print(2*i+1, 1, "TMU%d=%d CNT:%08x", i,
|
||||
(*TSTR & (1 << i)) != 0, t->TCNT);
|
||||
row_print(2*i+2, 1, "TCR:%04x COR:%08x", t->TCR.word, t->TCOR);
|
||||
}
|
||||
}
|
||||
static void ctx_dd()
|
||||
{
|
||||
uint8_t *STRD = driver_ctx("T6K11");
|
||||
|
||||
row_print(1, 1, "STRD:%02x", *STRD);
|
||||
row_print(2, 2, "RESET:%d", (*STRD & 0x08) != 0);
|
||||
row_print(3, 2, "N/F:%d", (*STRD & 0x04) != 0);
|
||||
row_print(4, 2, "X/Y:%d", (*STRD & 0x02) != 0);
|
||||
row_print(5, 2, "U/D:%d", (*STRD & 0x01) != 0);
|
||||
}
|
||||
static void ctx_rtc()
|
||||
{
|
||||
uint8_t *ctx = driver_ctx("RTC");
|
||||
uint8_t RCR1=ctx[0], RCR2=ctx[1];
|
||||
|
||||
row_print(1, 1, "RCR1:%02x", RCR1);
|
||||
row_print(2, 1, "RCR2:%02x", RCR2);
|
||||
}
|
||||
static void show_etmu(int line, int id, etmu_t *t)
|
||||
{
|
||||
row_print(line, 1, "ETMU%d=%-3dCNT:%08x", id, t->TSTR, t->TCNT);
|
||||
row_print(line+1, 1, "TCR:%02x COR:%08x", t->TCR.byte, t->TCOR);
|
||||
}
|
||||
static void ctx_etmu(int start)
|
||||
{
|
||||
etmu_t *t = driver_ctx("TMU") + 3 * sizeof(tmu_t);
|
||||
t += start;
|
||||
|
||||
for(int i = 0; i < 3; i++, t++)
|
||||
{
|
||||
show_etmu(2*i+1, i+start, t);
|
||||
}
|
||||
}
|
||||
#endif /* FX9860G */
|
||||
|
||||
#ifdef FXCG50
|
||||
static void ctx_tmu()
|
||||
{
|
||||
}
|
||||
static void ctx_dd()
|
||||
{
|
||||
}
|
||||
static void ctx_rtc()
|
||||
{
|
||||
}
|
||||
#endif /* FXCG50 */
|
||||
|
||||
static void system_contexts(void)
|
||||
{
|
||||
int key=0, tab=0;
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
|
||||
#ifdef FX9860G
|
||||
extern image_t img_opt_switch_ctx;
|
||||
dimage(0, 56, &img_opt_switch_ctx);
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
row_title("System context visualizer");
|
||||
fkey_button(1, "TMU");
|
||||
fkey_button(2, "R61524");
|
||||
fkey_button(3, "RTC");
|
||||
#endif
|
||||
|
||||
if(tab == 0) ctx_tmu();
|
||||
if(tab == 1) ctx_dd();
|
||||
if(tab == 2) ctx_rtc();
|
||||
|
||||
#ifdef FX9860G
|
||||
if(tab == 3) ctx_etmu(0);
|
||||
if(tab == 4) ctx_etmu(3);
|
||||
#endif
|
||||
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
if(key == KEY_F1) tab = 0;
|
||||
if(key == KEY_F2) tab = 1;
|
||||
if(key == KEY_F3) tab = 2;
|
||||
|
||||
#ifdef FX9860G
|
||||
if(key == KEY_F4) tab = 3;
|
||||
if(key == KEY_F5) tab = 4;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Interactive in-out switching
|
||||
//---
|
||||
|
||||
/* Render VRAM for this screen, used when returning to menu */
|
||||
void render(void)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
|
||||
#ifdef FX9860G
|
||||
extern image_t img_opt_switch;
|
||||
row_print(1, 1, "Switch to OS");
|
||||
row_print(3, 1, "Switches done: %d", switches);
|
||||
row_print(4, 1, "Fast done: %d", fast);
|
||||
row_print(5, 1, "Menus done: %d", menus);
|
||||
|
||||
dimage(0, 56, &img_opt_switch);
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
row_title("Hot switching between gint and OS");
|
||||
row_print(2, 1, "Switches done: %d", switches);
|
||||
row_print(3, 1, "Fast done: %d", fast);
|
||||
row_print(4, 1, "Menus done: %d", menus);
|
||||
fkey_button(1, "SWITCH");
|
||||
fkey_button(2, "FAST");
|
||||
fkey_button(3, "MENU");
|
||||
fkey_action(6, "SYSTEM");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* gintctl_gint_switch(): Test the gint switch-in-out procedures */
|
||||
void gintctl_gint_switch(void)
|
||||
{
|
||||
int key = 0;
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
{
|
||||
render();
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
if(key == KEY_F1) gint_switch(switch_function);
|
||||
/* TODO: Fast gint switch in gintctl */
|
||||
if(key == KEY_F2) {}
|
||||
/* Wait for F3 to be released before calling next getkey() */
|
||||
if(key == KEY_F3)
|
||||
{
|
||||
/* Render next frame in advance. When we return from
|
||||
the main menu, our VRAM will be displayed but
|
||||
GetKeyWait() will not give control back until a key
|
||||
is pressed. This will make it look like we render a
|
||||
new frame right away. */
|
||||
menus++;
|
||||
render();
|
||||
dupdate();
|
||||
|
||||
gint_osmenu();
|
||||
while(keydown(KEY_F3)) waitevent(NULL);
|
||||
}
|
||||
if(key == KEY_F6) system_contexts();
|
||||
}
|
||||
}
|
|
@ -54,30 +54,38 @@ static int y[] = { 24, 24, 24, 84, 84, 84, 144, 144, 144 };
|
|||
|
||||
void show_tmu(void)
|
||||
{
|
||||
volatile uint8_t *TSTR;
|
||||
timer_address(0, &TSTR);
|
||||
tmu_t *TMU = SH7305_TMU.TMU;
|
||||
volatile uint8_t *TSTR = &SH7305_TMU.TSTR;
|
||||
|
||||
tmu_print(x[0], y[0], "TMU0", timer_address(0, NULL), *TSTR & 0x1);
|
||||
tmu_print(x[1], y[1], "TMU1", timer_address(1, NULL), *TSTR & 0x2);
|
||||
tmu_print(x[2], y[2], "TMU2", timer_address(2, NULL), *TSTR & 0x4);
|
||||
if(isSH3())
|
||||
{
|
||||
TMU = SH7705_TMU.TMU;
|
||||
TSTR = &SH7705_TMU.TSTR;
|
||||
}
|
||||
|
||||
tmu_print(x[0], y[0], "TMU0", &TMU[0], *TSTR & 0x1);
|
||||
tmu_print(x[1], y[1], "TMU1", &TMU[1], *TSTR & 0x2);
|
||||
tmu_print(x[2], y[2], "TMU2", &TMU[2], *TSTR & 0x4);
|
||||
}
|
||||
|
||||
void show_etmu_1(void)
|
||||
{
|
||||
etmu_print(x[3], y[3], "ETMU0", timer_address(3, NULL));
|
||||
etmu_t *ETMU = isSH3() ? SH7705_ETMU : SH7305_ETMU;
|
||||
etmu_print(x[3], y[3], "ETMU0", &ETMU[0]);
|
||||
|
||||
if(isSH3()) return;
|
||||
etmu_print(x[4], y[4], "ETMU1", timer_address(4, NULL));
|
||||
etmu_print(x[5], y[5], "ETMU2", timer_address(5, NULL));
|
||||
etmu_print(x[4], y[4], "ETMU1", &ETMU[1]);
|
||||
etmu_print(x[5], y[5], "ETMU2", &ETMU[2]);
|
||||
}
|
||||
|
||||
void show_etmu_2(void)
|
||||
{
|
||||
if(isSH3()) return;
|
||||
etmu_t *ETMU = SH7305_ETMU;
|
||||
|
||||
etmu_print(x[6], y[6], "ETMU3", timer_address(6, NULL));
|
||||
etmu_print(x[7], y[7], "ETMU4", timer_address(7, NULL));
|
||||
etmu_print(x[8], y[8], "ETMU5", timer_address(8, NULL));
|
||||
if(isSH3()) return;
|
||||
etmu_print(x[6], y[6], "ETMU3", &ETMU[3]);
|
||||
etmu_print(x[7], y[7], "ETMU4", &ETMU[4]);
|
||||
etmu_print(x[8], y[8], "ETMU5", &ETMU[5]);
|
||||
}
|
||||
|
||||
/* gintctl_gint_timer(): Show the timer status in real-time */
|
||||
|
@ -87,13 +95,14 @@ void gintctl_gint_timer(void)
|
|||
hence ask getkey() to never wait. (The processor is still sleeping
|
||||
during the DMA transfer to the screen on fxcg50, limiting the
|
||||
program to ~90 FPS.) */
|
||||
int key = 0, timeout = 1;
|
||||
int key=0, timeout=1;
|
||||
int tid=0;
|
||||
|
||||
#ifdef FX9860G
|
||||
int tab = 1;
|
||||
#endif
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
while(!keydown(KEY_EXIT))
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
|
||||
|
@ -104,6 +113,9 @@ void gintctl_gint_timer(void)
|
|||
|
||||
extern image_t img_opt_gint_timers;
|
||||
dimage(0, 56, &img_opt_gint_timers);
|
||||
|
||||
if(tid < 3) dprint(23, 56, C_BLACK, C_NONE, "TMU%d", tid);
|
||||
else dprint(23, 56, C_BLACK, C_NONE, "ETMU%d", tid-3);
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
|
@ -113,18 +125,19 @@ void gintctl_gint_timer(void)
|
|||
show_etmu_1();
|
||||
show_etmu_2();
|
||||
|
||||
fkey_button(1, "SLEEP");
|
||||
fkey_action(1, "SLEEP");
|
||||
|
||||
if(tid < 3) dprint(72, 210, C_BLACK, C_NONE, "TMU%d", tid);
|
||||
else dprint(72, 210, C_BLACK, C_NONE, "ETMU%d", tid-3);
|
||||
#endif
|
||||
|
||||
dupdate();
|
||||
key = getkey_opt(GETKEY_DEFAULT, &timeout).key;
|
||||
clearevents();
|
||||
|
||||
/* On F1, pretend to sleep and just see what happens */
|
||||
if(key == KEY_F1)
|
||||
if(keydown(KEY_F1))
|
||||
{
|
||||
volatile int flag = 0;
|
||||
int tid = 0;
|
||||
|
||||
int free = timer_setup(tid, timer_delay(tid, 1000000),
|
||||
0, timer_timeout, &flag);
|
||||
if(free == tid) timer_start(tid);
|
||||
|
@ -132,9 +145,12 @@ void gintctl_gint_timer(void)
|
|||
|
||||
#ifdef FX9860G
|
||||
/* On F4, F5 and F6, switch tabs */
|
||||
if(key == KEY_F4) tab = 1;
|
||||
if(key == KEY_F5) tab = 2;
|
||||
if(key == KEY_F6) tab = 3;
|
||||
if(keydown(KEY_F4)) tab = 1;
|
||||
if(keydown(KEY_F5)) tab = 2;
|
||||
if(keydown(KEY_F6)) tab = 3;
|
||||
#endif
|
||||
|
||||
if(key == KEY_UP) tid = (tid+timer_count()-1) % timer_count();
|
||||
if(key == KEY_DOWN) tid = (tid + 1) % timer_count();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <gintctl/gint.h>
|
||||
#include <gintctl/perf.h>
|
||||
#include <gintctl/libs.h>
|
||||
#include <gintctl/mem.h>
|
||||
|
||||
#include <libprof.h>
|
||||
|
@ -37,7 +38,8 @@ struct menu menu_gint = {
|
|||
{ "Hardware", gintctl_gint_hardware },
|
||||
{ "RAM discovery", gintctl_gint_ram },
|
||||
{ "Memory dump", gintctl_gint_dump },
|
||||
{ "Keyboard", NULL },
|
||||
{ "Switching to OS", gintctl_gint_switch },
|
||||
{ "Keyboard", gintctl_gint_keyboard },
|
||||
{ "Timers", gintctl_gint_timer },
|
||||
#ifdef FXCG50
|
||||
{ "DMA Control", gintctl_gint_dma },
|
||||
|
@ -62,6 +64,14 @@ struct menu menu_perf = {
|
|||
{ NULL, NULL },
|
||||
}};
|
||||
|
||||
/* External libraries */
|
||||
struct menu menu_libs = {
|
||||
_("Libraries", "External libraries"), .entries = {
|
||||
|
||||
{ "libimg", gintctl_libs_libimg },
|
||||
{ NULL, NULL },
|
||||
}};
|
||||
|
||||
//---
|
||||
// Main application
|
||||
//---
|
||||
|
@ -74,16 +84,22 @@ void gintctl_main(void)
|
|||
|
||||
row_print(3, 1, "F2:gint tests");
|
||||
row_print(4, 1, "F3:Performance");
|
||||
row_print(5, 1, "F5:MPU registers");
|
||||
row_print(6, 1, "F6:Memory map/dump");
|
||||
row_print(5, 1, "F4:Libraries");
|
||||
row_print(6, 1, "F5:MPU registers");
|
||||
row_print(7, 1, "F6:Memory map/dump");
|
||||
#endif /* FX9860G */
|
||||
|
||||
#ifdef FXCG50
|
||||
row_title("gint @%07x for fx-CG 50", GINT_VERSION);
|
||||
row_print(1, 1, "F2: gint features and driver tests");
|
||||
row_print(2, 1, "F3: Performance benchmarks");
|
||||
row_print(3, 1, "F5: MPU register browser");
|
||||
row_print(4, 1, "F6: Hexadecimal memory editor");
|
||||
row_print(1,1, "F2: gint features and driver tests");
|
||||
row_print(2,1, "F3: Performance benchmarks");
|
||||
row_print(3,1, "F4: External libraries");
|
||||
row_print(4,1, "F5: MPU register browser");
|
||||
row_print(5,1, "F6: Hexadecimal memory browser");
|
||||
|
||||
row_print(7,1, "This add-in is running a unikernel called gint by");
|
||||
row_print(8,1, "Lephe'. Information about the project is available");
|
||||
row_print(9,1, "on planet-casio.com.");
|
||||
|
||||
#ifdef GINT_BOOTLOG
|
||||
extern char gint_bootlog[22 * 8];
|
||||
|
@ -101,6 +117,7 @@ int main(GUNUSED int isappli, GUNUSED int optnum)
|
|||
int top = _(1, 0), bottom = _(1, 0);
|
||||
menu_init(&menu_gint, top, bottom);
|
||||
menu_init(&menu_perf, top, bottom);
|
||||
menu_init(&menu_libs, top, bottom);
|
||||
|
||||
/* Start the profiling library */
|
||||
prof_init(PROFCTX_COUNT, 2);
|
||||
|
@ -118,10 +135,13 @@ int main(GUNUSED int isappli, GUNUSED int optnum)
|
|||
#ifdef FX9860G
|
||||
extern image_t img_opt_main;
|
||||
dimage(0, 56, &img_opt_main);
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
fkey_action(1, "INFO");
|
||||
fkey_menu(2, "GINT");
|
||||
fkey_menu(3, "PERF");
|
||||
fkey_menu(4, "LIBS");
|
||||
fkey_button(5, "REGS");
|
||||
fkey_button(6, "MEMORY");
|
||||
#endif
|
||||
|
@ -135,6 +155,8 @@ int main(GUNUSED int isappli, GUNUSED int optnum)
|
|||
menu = &menu_gint;
|
||||
if(key == KEY_F3)
|
||||
menu = &menu_perf;
|
||||
if(key == KEY_F4)
|
||||
menu = &menu_libs;
|
||||
if(key == KEY_F5)
|
||||
gintctl_regs();
|
||||
if(key == KEY_F6)
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
#include <gintctl/libs.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <libimg.h>
|
||||
|
||||
#ifdef FX9860G
|
||||
#include <gint/gray.h>
|
||||
static void render(void)
|
||||
{
|
||||
extern img_t img_libimg_swords;
|
||||
|
||||
img_render_vram_gray(img_libimg_swords, 8, 8);
|
||||
}
|
||||
|
||||
void gintctl_libs_libimg(void)
|
||||
{
|
||||
int key = 0;
|
||||
gray_start();
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
{
|
||||
gclear(C_WHITE);
|
||||
render();
|
||||
gupdate();
|
||||
|
||||
key = getkey().key;
|
||||
}
|
||||
|
||||
gray_stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
static void render(void)
|
||||
{
|
||||
extern img_t img_libimg_sq_even;
|
||||
extern img_t img_libimg_sq_odd;
|
||||
extern img_t img_libimg_even_odd;
|
||||
extern img_t img_libimg_odd_even;
|
||||
extern img_t img_libimg_train;
|
||||
|
||||
#define sq_even img_libimg_sq_even
|
||||
#define sq_odd img_libimg_sq_odd
|
||||
#define even_odd img_libimg_even_odd
|
||||
#define odd_even img_libimg_odd_even
|
||||
#define train img_libimg_train
|
||||
|
||||
img_t in[4] = { sq_even, sq_odd, odd_even, even_odd };
|
||||
img_t out = img_vram();
|
||||
|
||||
img_fill(out, 0xffff);
|
||||
img_fill(img_sub(out, 138, 0, 28, -1), 0xc618);
|
||||
|
||||
for(int i=0, y=8; i<4; i++, y+=52)
|
||||
{
|
||||
img_rotate (in[i], img_at(out, 8, y), 90);
|
||||
img_rotate (in[i], img_at(out, 8, y+26), 0);
|
||||
img_rotate (in[i], img_at(out, 34, y), 180);
|
||||
img_rotate (in[i], img_at(out, 34, y+26), 270);
|
||||
img_upscale(in[i], img_at(out, 60, y+1), 2);
|
||||
img_hflip (in[i], img_at(out, 110, y));
|
||||
img_vflip (in[i], img_at(out, 110, y+26));
|
||||
img_render (in[i], img_at(out, 140, y+13));
|
||||
img_dye (in[i], img_at(out, 248, y), 0x25ff);
|
||||
img_dye (in[i], img_at(out, 248, y+26), 0xfd04);
|
||||
|
||||
img_t light = img_copy(in[i]);
|
||||
img_t dark = img_copy(in[i]);
|
||||
|
||||
for(int k=0, x=172; k<=2; k++, x+=26)
|
||||
{
|
||||
img_whiten(light, light);
|
||||
img_darken(dark, dark);
|
||||
|
||||
img_render(light, img_at(out, x, y));
|
||||
img_render(dark, img_at(out, x, y+26));
|
||||
}
|
||||
|
||||
img_destroy(light);
|
||||
img_destroy(dark);
|
||||
}
|
||||
|
||||
img_t light = img_lighten_create(train);
|
||||
img_t dark = img_darken_create(train);
|
||||
|
||||
img_render(light, img_at(out, 282, 24));
|
||||
img_render(train, img_at(out, 282, 56+24));
|
||||
img_render(dark, img_at(out, 282, 56+56+24));
|
||||
|
||||
img_destroy(light);
|
||||
img_destroy(dark);
|
||||
}
|
||||
|
||||
void gintctl_libs_libimg(void)
|
||||
{
|
||||
int key = 0;
|
||||
|
||||
while(key != KEY_EXIT)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
render();
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -92,7 +92,7 @@ void gintctl_mem(void)
|
|||
|
||||
for(int i = 0; i < lines; i++)
|
||||
{
|
||||
int status = line(mem, header, bytes, ascii, size);
|
||||
GUNUSED int status = line(mem,header,bytes,ascii,size);
|
||||
|
||||
#ifdef FX9860G
|
||||
dtext( 5, 6*i + 1, view_ascii ? ascii : header,
|
||||
|
|
|
@ -15,21 +15,16 @@ struct elapsed {
|
|||
uint32_t fs_r5g6b5;
|
||||
};
|
||||
|
||||
#define test(out, command) { \
|
||||
prof_clear(PROFCTX_RENDER); \
|
||||
prof_enter(PROFCTX_RENDER); \
|
||||
command; \
|
||||
prof_leave(PROFCTX_RENDER); \
|
||||
out = prof_time(PROFCTX_RENDER); \
|
||||
}
|
||||
|
||||
static void run_test(struct elapsed *time)
|
||||
{
|
||||
#define test(out, command) { \
|
||||
prof_clear(PROFCTX_RENDER); \
|
||||
prof_enter(PROFCTX_RENDER); \
|
||||
command; \
|
||||
prof_leave(PROFCTX_RENDER); \
|
||||
out = prof_time(PROFCTX_RENDER); \
|
||||
}
|
||||
|
||||
extern image_t img_swift;
|
||||
|
||||
test(time->update,
|
||||
dupdate()
|
||||
);
|
||||
test(time->clear,
|
||||
dclear(C_WHITE)
|
||||
);
|
||||
|
@ -44,12 +39,11 @@ static void run_test(struct elapsed *time)
|
|||
);
|
||||
|
||||
#ifdef FXCG50
|
||||
extern image_t img_swift;
|
||||
test(time->fs_r5g6b5,
|
||||
dimage(0, 0, &img_swift)
|
||||
);
|
||||
#endif
|
||||
|
||||
#undef test
|
||||
}
|
||||
|
||||
char *printtime(uint32_t us)
|
||||
|
@ -95,31 +89,32 @@ void gintctl_perf_render(void)
|
|||
|
||||
row_print(4, 1, "Press F1 to start the test.");
|
||||
|
||||
row_print(6, 2, "dclear():");
|
||||
row_print(7, 2, "dupdate():");
|
||||
row_print(8, 2, "drect() 32x32 (even position):");
|
||||
row_print(9, 2, "drect() 32x32 (odd position):");
|
||||
row_print(10, 2, "drect() 396x224:");
|
||||
row_print(11, 2, "dimage() 396x224 (p4):");
|
||||
|
||||
if(test)
|
||||
{
|
||||
print(6, 90, "dclear:");
|
||||
print(6, 105, "%s", printtime(time.clear));
|
||||
|
||||
print(83, 90, "dupdate:");
|
||||
print(83, 105, "%s", printtime(time.update));
|
||||
|
||||
print(160, 90, "rect1:");
|
||||
print(160, 105, "%s", printtime(time.rect1));
|
||||
|
||||
print(237, 90, "rect2:");
|
||||
print(237, 105, "%s", printtime(time.rect2));
|
||||
|
||||
print(314, 90, "rect3:");
|
||||
print(314, 105, "%s", printtime(time.rect3));
|
||||
|
||||
print(6, 130, "fullscreen img:");
|
||||
print(6, 145, "%s", printtime(time.fs_r5g6b5));
|
||||
row_print(6, 35, "%s", printtime(time.clear));
|
||||
row_print(7, 35, "%s", printtime(time.update));
|
||||
row_print(8, 35, "%s", printtime(time.rect1));
|
||||
row_print(9, 35, "%s", printtime(time.rect2));
|
||||
row_print(10, 35, "%s", printtime(time.rect3));
|
||||
row_print(11, 35, "%s", printtime(time.fs_r5g6b5));
|
||||
}
|
||||
|
||||
fkey_button(1, "START");
|
||||
#endif
|
||||
|
||||
dupdate();
|
||||
/* Make the test here as we don't want to re-update the screen.
|
||||
Because of triple buffering this would display an old
|
||||
frame such as the application's main menu. */
|
||||
test(time.update,
|
||||
dupdate()
|
||||
);
|
||||
key = getkey().key;
|
||||
|
||||
if(key == KEY_F1) run_test(&time), test = 1;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#ifdef FXCG50
|
||||
#define ROW_X 6
|
||||
#define ROW_W 0
|
||||
#define ROW_W 8
|
||||
#define ROW_Y 20
|
||||
#define ROW_YPAD 2
|
||||
#define ROW_H 14
|
||||
|
|