diff --git a/Makefile b/Makefile index 94fd233..118cc6b 100644 --- a/Makefile +++ b/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 diff --git a/assets-cg/fonts/font8x9_bold.png b/assets-cg/fonts/font8x9_bold.png new file mode 100644 index 0000000..47b4010 Binary files /dev/null and b/assets-cg/fonts/font8x9_bold.png differ diff --git a/assets-cg/img/applejack_31x27.png b/assets-cg/img/applejack_31x27.png new file mode 100644 index 0000000..eaab186 Binary files /dev/null and b/assets-cg/img/applejack_31x27.png differ diff --git a/assets-cg/img/applejack_36x25.png b/assets-cg/img/applejack_36x25.png new file mode 100644 index 0000000..d97574b Binary files /dev/null and b/assets-cg/img/applejack_36x25.png differ diff --git a/assets-cg/img/kbd_pressed.png b/assets-cg/img/kbd_pressed.png new file mode 100644 index 0000000..05ad40c Binary files /dev/null and b/assets-cg/img/kbd_pressed.png differ diff --git a/assets-cg/img/kbd_released.png b/assets-cg/img/kbd_released.png new file mode 100644 index 0000000..3dfd6e6 Binary files /dev/null and b/assets-cg/img/kbd_released.png differ diff --git a/assets-cg/img/libimg_even_odd.png b/assets-cg/img/libimg_even_odd.png new file mode 100644 index 0000000..9123979 Binary files /dev/null and b/assets-cg/img/libimg_even_odd.png differ diff --git a/assets-cg/img/libimg_odd_even.png b/assets-cg/img/libimg_odd_even.png new file mode 100644 index 0000000..a4b7fa6 Binary files /dev/null and b/assets-cg/img/libimg_odd_even.png differ diff --git a/assets-cg/img/libimg_sq_even.png b/assets-cg/img/libimg_sq_even.png new file mode 100644 index 0000000..e366184 Binary files /dev/null and b/assets-cg/img/libimg_sq_even.png differ diff --git a/assets-cg/img/libimg_sq_odd.png b/assets-cg/img/libimg_sq_odd.png new file mode 100644 index 0000000..3ec4605 Binary files /dev/null and b/assets-cg/img/libimg_sq_odd.png differ diff --git a/assets-cg/img/libimg_train.png b/assets-cg/img/libimg_train.png new file mode 100644 index 0000000..a31c31b Binary files /dev/null and b/assets-cg/img/libimg_train.png differ diff --git a/assets-cg/img/potion_17x22.png b/assets-cg/img/potion_17x22.png new file mode 100644 index 0000000..3b025a1 Binary files /dev/null and b/assets-cg/img/potion_17x22.png differ diff --git a/assets-cg/img/potion_18x22.png b/assets-cg/img/potion_18x22.png new file mode 100644 index 0000000..fb2d049 Binary files /dev/null and b/assets-cg/img/potion_18x22.png differ diff --git a/assets-cg/img/potion_21x22.png b/assets-cg/img/potion_21x22.png new file mode 100644 index 0000000..305a61f Binary files /dev/null and b/assets-cg/img/potion_21x22.png differ diff --git a/assets-cg/img/swords.png b/assets-cg/img/swords.png index 03493f9..1349d3f 100644 Binary files a/assets-cg/img/swords.png and b/assets-cg/img/swords.png differ diff --git a/assets-fx/img/keypress.png b/assets-fx/img/keypress.png new file mode 100644 index 0000000..2555c4d Binary files /dev/null and b/assets-fx/img/keypress.png differ diff --git a/assets-fx/img/keyrelease.png b/assets-fx/img/keyrelease.png new file mode 100644 index 0000000..2b19fb9 Binary files /dev/null and b/assets-fx/img/keyrelease.png differ diff --git a/assets-fx/img/libimg_swords.png b/assets-fx/img/libimg_swords.png new file mode 100644 index 0000000..40164c0 Binary files /dev/null and b/assets-fx/img/libimg_swords.png differ diff --git a/assets-fx/img/opt_gint_timers.png b/assets-fx/img/opt_gint_timers.png index 7e54142..00af5be 100644 Binary files a/assets-fx/img/opt_gint_timers.png and b/assets-fx/img/opt_gint_timers.png differ diff --git a/assets-fx/img/opt_main.png b/assets-fx/img/opt_main.png index d6c17ce..3083554 100644 Binary files a/assets-fx/img/opt_main.png and b/assets-fx/img/opt_main.png differ diff --git a/assets-fx/img/opt_mem.png b/assets-fx/img/opt_mem.png index f8de1f3..8079c10 100644 Binary files a/assets-fx/img/opt_mem.png and b/assets-fx/img/opt_mem.png differ diff --git a/assets-fx/img/opt_perf_libprof.png b/assets-fx/img/opt_perf_libprof.png index 9259a6f..b0edafa 100644 Binary files a/assets-fx/img/opt_perf_libprof.png and b/assets-fx/img/opt_perf_libprof.png differ diff --git a/assets-fx/img/opt_perf_render.png b/assets-fx/img/opt_perf_render.png index 9259a6f..29e9d92 100644 Binary files a/assets-fx/img/opt_perf_render.png and b/assets-fx/img/opt_perf_render.png differ diff --git a/assets-fx/img/opt_switch.png b/assets-fx/img/opt_switch.png new file mode 100644 index 0000000..8d4d0aa Binary files /dev/null and b/assets-fx/img/opt_switch.png differ diff --git a/assets-fx/img/opt_switch_ctx.png b/assets-fx/img/opt_switch_ctx.png new file mode 100644 index 0000000..138baac Binary files /dev/null and b/assets-fx/img/opt_switch_ctx.png differ diff --git a/include/gintctl/gint.h b/include/gintctl/gint.h index f584df2..efcf302 100644 --- a/include/gintctl/gint.h +++ b/include/gintctl/gint.h @@ -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 diff --git a/include/gintctl/libs.h b/include/gintctl/libs.h new file mode 100644 index 0000000..f986220 --- /dev/null +++ b/include/gintctl/libs.h @@ -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 */ diff --git a/project.cfg b/project.cfg index aca2c74..aafffec 100644 --- a/project.cfg +++ b/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 diff --git a/src/gint/bopti.c b/src/gint/bopti.c index 73b5b9f..bf3404b 100644 --- a/src/gint/bopti.c +++ b/src/gint/bopti.c @@ -1,7 +1,9 @@ #define GINT_NEED_VRAM #include #include + #include +#include /* 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 } diff --git a/src/gint/dma.c b/src/gint/dma.c index 4781e1f..f78ae0f 100644 --- a/src/gint/dma.c +++ b/src/gint/dma.c @@ -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(); diff --git a/src/gint/hardware.c b/src/gint/hardware.c index d91cda3..8ad1a5e 100644 --- a/src/gint/hardware.c +++ b/src/gint/hardware.c @@ -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]; diff --git a/src/gint/keyboard.c b/src/gint/keyboard.c new file mode 100644 index 0000000..e475a83 --- /dev/null +++ b/src/gint/keyboard.c @@ -0,0 +1,150 @@ +#include +#include + +#include + +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; + } + } +} diff --git a/src/gint/ram.c b/src/gint/ram.c index bde689b..3c910c8 100644 --- a/src/gint/ram.c +++ b/src/gint/ram.c @@ -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"); diff --git a/src/gint/switch.c b/src/gint/switch.c new file mode 100644 index 0000000..bfc744a --- /dev/null +++ b/src/gint/switch.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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(); + } +} diff --git a/src/gint/timer.c b/src/gint/timer.c index 0af9d4d..8013bf8 100644 --- a/src/gint/timer.c +++ b/src/gint/timer.c @@ -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(); } } diff --git a/src/gintctl.c b/src/gintctl.c index 8a7e098..26d3ef2 100644 --- a/src/gintctl.c +++ b/src/gintctl.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -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) diff --git a/src/libs/libimg.c b/src/libs/libimg.c new file mode 100644 index 0000000..baae8e3 --- /dev/null +++ b/src/libs/libimg.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include + +#ifdef FX9860G +#include +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 diff --git a/src/mem/mem.c b/src/mem/mem.c index 5b2db95..8bd0c24 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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, diff --git a/src/perf/render.c b/src/perf/render.c index 7cf8c55..2d8c214 100644 --- a/src/perf/render.c +++ b/src/perf/render.c @@ -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; diff --git a/src/util.c b/src/util.c index 0b6ce8d..eaabdd4 100644 --- a/src/util.c +++ b/src/util.c @@ -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