vxBoot - 1.0.0 : GUI
@add <> src/gui : add GUI menu <> src/loader/kernel : move kernel image list interaction <> assets-cg/fonts : add font for fxcg50 device <> include/vxBoot/config : add VXBOOT_VERSION macro @update <> src/cli/entry : move CLI main loop here <> src/main : link GUI en move CLI @fix <> src/loader/scan : fix file type check for emulator
This commit is contained in:
parent
f90c07132a
commit
ce1f594a53
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(vxBoot VERSION 0.0.3 LANGUAGES C)
|
||||
project(vxBoot VERSION 1.0.0 LANGUAGES C)
|
||||
|
||||
include(GenerateG1A)
|
||||
include(GenerateG3A)
|
||||
|
@ -8,7 +8,11 @@ find_package(Gint 2.1 REQUIRED)
|
|||
|
||||
set(SOURCES
|
||||
src/main.c
|
||||
src/gui/entry.c
|
||||
src/gui/fx9860g.c
|
||||
src/gui/fxcg50.c
|
||||
src/cli/parser.c
|
||||
src/cli/entry.c
|
||||
src/fs/smemfs/mount.c
|
||||
src/fs/smemfs/pread.c
|
||||
src/terminal/close.c
|
||||
|
@ -25,6 +29,7 @@ set(SOURCES
|
|||
src/loader/elf/image.c
|
||||
src/loader/error.c
|
||||
src/loader/entry.c
|
||||
src/loader/kernel.c
|
||||
src/hardware/get_info.c
|
||||
)
|
||||
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets
|
||||
|
@ -35,13 +40,13 @@ set(ASSETS_fx
|
|||
assets-fx/fonts/hexa.png
|
||||
)
|
||||
set(ASSETS_cg
|
||||
# ...
|
||||
assets-cg/fonts/font8x9.png
|
||||
)
|
||||
|
||||
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
|
||||
|
||||
add_executable(vxBoot ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
|
||||
target_compile_options(vxBoot PRIVATE -Wall -Wextra -Os)
|
||||
target_compile_options(vxBoot PRIVATE -Wall -Wextra -Os -DVXBOOT_VERSION="${PROJECT_VERSION}")
|
||||
target_include_directories(vxBoot PRIVATE include/)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,8 @@
|
|||
font8x9.png:
|
||||
type: font
|
||||
name: font_fxcg50
|
||||
charset: print
|
||||
grid.size: 8x11
|
||||
grid.padding: 1
|
||||
grid.border: 0
|
||||
height: 9
|
|
@ -4,6 +4,10 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* cli_main() : main entry for the CLI */
|
||||
extern void cli_main(void);
|
||||
|
||||
extern int cli_parser_strtotab(int *argc, char ***argv, char const *str);
|
||||
extern void cli_parser_strtotab_quit(int *argc, char ***argv);
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef VXBOOT_CONFIG
|
||||
# define VXBOOT_CONFIG 1
|
||||
|
||||
/* vxBoot version */
|
||||
#ifndef VXBOOT_VERSION
|
||||
# define VXBOOT_VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#endif /* VXBOOT_CONFIG */
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __VXBOOT_GUI_H__
|
||||
# define __VXBOOT_GUI_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* internal GUI information */
|
||||
struct gui_meta {
|
||||
struct {
|
||||
int anchor;
|
||||
int select;
|
||||
int count;
|
||||
int line;
|
||||
} list;
|
||||
struct {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int offset;
|
||||
} scroll;
|
||||
};
|
||||
|
||||
/* gui_main() : main entry for the GUI */
|
||||
extern void gui_main(void);
|
||||
|
||||
/* gui_fx9860g_display() : fx9860-specific display */
|
||||
extern void gui_fx9860g_display(struct gui_meta *gui);
|
||||
|
||||
/* gui_fxcg50_display() : fxcg50-specific display */
|
||||
extern void gui_fxcg50_display(struct gui_meta *gui);
|
||||
|
||||
#endif /*__VXBOOT_GUI_H__*/
|
|
@ -114,6 +114,14 @@ struct ldimg {
|
|||
/* loader_scan() : scan the storage memory and try to find ELF PIE file */
|
||||
extern int loader_scan(void);
|
||||
|
||||
/* loader_kernel_img_get() : get the image ID information */
|
||||
extern struct ldimg *loader_kernel_img_get(int id);
|
||||
|
||||
/* loader_kernel_img_count() : count the number of kernel image found */
|
||||
extern int loader_kernel_img_count(void);
|
||||
|
||||
|
||||
|
||||
/* loader() : try to load a ELF PIE file */
|
||||
#define LOADER_DEFAULT 0
|
||||
#define LOADER_DUMP 1
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#include "vxBoot/cli.h"
|
||||
#include "vxBoot/builtin.h"
|
||||
#include "vxBoot/terminal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//TODO: better API for the command-line parser
|
||||
|
||||
/* internal builtin list */
|
||||
struct {
|
||||
const char *name;
|
||||
int (*f)(int argc, char **argv);
|
||||
} cmd_list[] = {
|
||||
{.name = "ls", &ls_main},
|
||||
{.name = "ld", &ld_main},
|
||||
{.name = "hw", &hw_main},
|
||||
{.name = "help", &help_main},
|
||||
{.name = NULL, NULL}
|
||||
};
|
||||
|
||||
/* try to find the appropriate command */
|
||||
static int (*check_cmd(char *cmd))(int, char**)
|
||||
{
|
||||
for (int i = 0; cmd_list[i].name != NULL; ++i) {
|
||||
if (strcmp(cmd, cmd_list[i].name) != 0)
|
||||
continue;
|
||||
if (cmd_list[i].f == NULL)
|
||||
terminal_write("command exist but not implemented\n");
|
||||
return (cmd_list[i].f);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void cli_main(void)
|
||||
{
|
||||
int (*builtin)(int, char**);
|
||||
const char *usrline;
|
||||
char buff[128];
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
/* CLI loop */
|
||||
ret = 0;
|
||||
while (1) {
|
||||
/* get user command */
|
||||
usrline = (ret != 0) ? "/[%d]>" : "/>";
|
||||
terminal_write(usrline, ret);
|
||||
ret = 0;
|
||||
if (terminal_read(buff, 128) <= 1)
|
||||
continue;
|
||||
|
||||
/* parse and try to find the command */
|
||||
if (cli_parser_strtotab(&argc, &argv, buff) != 0) {
|
||||
terminal_write("error when processing \"%s\"", buff);
|
||||
ret = 255;
|
||||
continue;
|
||||
}
|
||||
builtin = check_cmd(argv[0]);
|
||||
if (builtin == NULL) {
|
||||
terminal_write("command \"%s\" not found\n", argv[0]);
|
||||
ret = 127;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* execute the command and free'd allocated memories */
|
||||
ret = builtin(argc, argv);
|
||||
cli_parser_strtotab_quit(&argc, &argv);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
#include "vxBoot/gui.h"
|
||||
#include "vxBoot/loader.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
//---
|
||||
// Private
|
||||
//---
|
||||
|
||||
|
||||
|
||||
|
||||
//--
|
||||
// Public
|
||||
//---
|
||||
|
||||
|
||||
/* gui_main() : main loop for the GUI display */
|
||||
void gui_main(void)
|
||||
{
|
||||
struct gui_meta disp;
|
||||
void (*display)(struct gui_meta*);
|
||||
int key;
|
||||
|
||||
|
||||
disp.list.anchor = 0;
|
||||
disp.list.select = 0;
|
||||
disp.list.count = loader_kernel_img_count();
|
||||
#ifdef FX9860G
|
||||
disp.list.line = 5;
|
||||
disp.scroll.y = 10;
|
||||
disp.scroll.offset = 0;
|
||||
if (disp.list.count - 6 > 0) {
|
||||
disp.scroll.width = (6 * 48) / disp.list.count;
|
||||
disp.scroll.offset = (38 - disp.scroll.width);
|
||||
disp.scroll.offset /= (disp.list.count - 6);
|
||||
}
|
||||
display = &gui_fx9860g_display;
|
||||
#endif
|
||||
#ifdef FXCG50
|
||||
disp.list.line = 11;
|
||||
disp.scroll.y = 21;
|
||||
disp.scroll.offset = 0;
|
||||
if (disp.list.count - 11 > 0) {
|
||||
disp.scroll.width = 167 / (disp.list.count - 11);
|
||||
disp.scroll.offset = (167 - disp.scroll.width);
|
||||
disp.scroll.offset /= (disp.list.count - 11);
|
||||
}
|
||||
display = &gui_fxcg50_display;
|
||||
#endif
|
||||
while (1) {
|
||||
dclear(C_BLACK);
|
||||
(*display)(&disp);
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
if (key == KEY_F6)
|
||||
break;
|
||||
if (key == KEY_EXE || key == KEY_SHIFT) {
|
||||
loader(
|
||||
loader_kernel_img_get(disp.list.select)->inode,
|
||||
LOADER_DEFAULT
|
||||
);
|
||||
}
|
||||
if (key == KEY_UP) {
|
||||
disp.list.select -= 1;
|
||||
if (disp.list.select < 0)
|
||||
disp.list.select = 0;
|
||||
if (disp.list.select < disp.list.anchor)
|
||||
disp.list.anchor -= 1;
|
||||
}
|
||||
if (key != KEY_DOWN)
|
||||
continue;
|
||||
disp.list.select += 1;
|
||||
if (disp.list.select >= disp.list.count)
|
||||
disp.list.select = disp.list.count - 1;
|
||||
if (disp.list.select - disp.list.anchor >= disp.list.line)
|
||||
disp.list.anchor += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* gui_main() : main loop for the GUI display */
|
||||
void gui_main(void)
|
||||
{
|
||||
int select_height;
|
||||
int disp_start;
|
||||
int max_line;
|
||||
int offsetW;
|
||||
int offsetH;
|
||||
int selected;
|
||||
int lheight;
|
||||
int loffset;
|
||||
int lrest;
|
||||
int count;
|
||||
int key;
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
selected = 0;
|
||||
disp_start = 0;
|
||||
offsetW = (DWIDTH * 5) / 100;
|
||||
offsetH = (DHEIGHT * 5) / 100;
|
||||
select_height = DHEIGHT - (offsetH * 3) - 6;
|
||||
select_height = select_height - (offsetH * 2) - 6;
|
||||
max_line = (select_height / (FHEIGHT + 6)) + 1;
|
||||
count = loader_kernel_img_count();
|
||||
lheight = (max_line * select_height) / count;
|
||||
lrest = select_height - lheight;
|
||||
while (1) {
|
||||
dclear(C_BLACK);
|
||||
dupdate();
|
||||
|
||||
key = getkey().key;
|
||||
if (key == KEY_F6)
|
||||
break;
|
||||
if (key == KEY_EXE || key == KEY_SHIFT) {
|
||||
loader(
|
||||
loader_kernel_img_get(selected)->inode,
|
||||
LOADER_DEFAULT
|
||||
);
|
||||
}
|
||||
if (key == KEY_UP) {
|
||||
selected -= 1;
|
||||
if (selected < 0) selected = 0;
|
||||
if (selected < disp_start) disp_start -= 1;
|
||||
}
|
||||
if (key == KEY_DOWN) {
|
||||
selected += 1;
|
||||
if (selected >= count) selected = count - 1;
|
||||
if (selected - disp_start >= max_line) disp_start += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
#include "vxBoot/gui.h"
|
||||
#include "vxBoot/loader.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
|
||||
#if FX9860G
|
||||
/* fx9860g_display() : Hardcoded display for the fx9860g */
|
||||
void gui_fx9860g_display(struct gui_meta *disp)
|
||||
{
|
||||
char const * name;
|
||||
int posy;
|
||||
int tmp;
|
||||
int sy;
|
||||
int i;
|
||||
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 1,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_TOP,
|
||||
"VxBoot version %s",
|
||||
VXBOOT_VERSION
|
||||
);
|
||||
drect_border(8, 8, 120, 50, C_NONE, 1, C_WHITE);
|
||||
if (disp->scroll.offset > 0) {
|
||||
sy = disp->scroll.y + (disp->list.anchor * disp->scroll.offset);
|
||||
dline(118, sy, 118, sy + disp->scroll.width, C_WHITE);
|
||||
}
|
||||
i = disp->list.anchor - 1;
|
||||
while (++i < disp->list.count && i - disp->list.anchor < 6) {
|
||||
posy = 10 + ((i - disp->list.anchor) * 7);
|
||||
name = loader_kernel_img_get(i)->inode->name;
|
||||
dtext(11, posy + 1, C_WHITE, name);
|
||||
if (i != disp->list.select)
|
||||
continue;
|
||||
tmp = (disp->scroll.offset > 0) ? 116 : 118;
|
||||
drect(10, posy, tmp, posy + 6, C_INVERT);
|
||||
}
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 54,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_MIDDLE,
|
||||
"Use arrows to select"
|
||||
);
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 60,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_MIDDLE,
|
||||
"Press [EXE] to boot"
|
||||
);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
#include "vxBoot/gui.h"
|
||||
#include "vxBoot/loader.h"
|
||||
#include "vxBoot/config.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
|
||||
/* fxcg50_display() : Hardcoded display for the fxcg50 */
|
||||
void gui_fxcg50_display(struct gui_meta *disp)
|
||||
{
|
||||
char const * name;
|
||||
int posy;
|
||||
int tmp;
|
||||
int sy;
|
||||
int i;
|
||||
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 5,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_TOP,
|
||||
"VxBoot version %s",
|
||||
VXBOOT_VERSION
|
||||
);
|
||||
drect_border(17, 18, 378, 189, C_NONE, 1, C_WHITE);
|
||||
if (disp->scroll.offset > 0) {
|
||||
sy = disp->scroll.y + (disp->list.anchor * disp->scroll.offset);
|
||||
dline(375, sy, 375, sy + disp->scroll.width, C_WHITE);
|
||||
}
|
||||
i = disp->list.anchor - 1;
|
||||
while (++i < disp->list.count && i - disp->list.anchor < 11) {
|
||||
posy = 22 + ((i - disp->list.anchor) * 15);
|
||||
name = loader_kernel_img_get(i)->inode->name;
|
||||
dtext(22, posy + 2, C_WHITE, name);
|
||||
if (i != disp->list.select)
|
||||
continue;
|
||||
tmp = (disp->scroll.offset > 0) ? 373 : 375;
|
||||
drect(20, posy, tmp, posy + 13, C_INVERT);
|
||||
}
|
||||
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 200,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_MIDDLE,
|
||||
"Use arrows keys to select entry"
|
||||
);
|
||||
dprint_opt(
|
||||
DWIDTH / 2, 212,
|
||||
C_WHITE, C_BLACK,
|
||||
DTEXT_CENTER, DTEXT_MIDDLE,
|
||||
"Press [EXE] to boot the selected OS"
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include "vxBoot/loader.h"
|
||||
|
||||
|
||||
/* kernel image list */
|
||||
struct ldimg *kernel_img_list = NULL;
|
||||
|
||||
|
||||
/* loader_kernel_img_get() : get the image ID information */
|
||||
struct ldimg *loader_kernel_img_get(int id)
|
||||
{
|
||||
struct ldimg *img;
|
||||
|
||||
img = kernel_img_list;
|
||||
while (--id >= 0) {
|
||||
if (img == NULL)
|
||||
return NULL;
|
||||
img = img->next;
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
/* loader_kernel_img_count() : count the number of kernel image found */
|
||||
int loader_kernel_img_count(void)
|
||||
{
|
||||
struct ldimg *img;
|
||||
int counter;
|
||||
|
||||
counter = 0;
|
||||
img = kernel_img_list;
|
||||
while (img != NULL) {
|
||||
counter = counter + 1;
|
||||
img = img->next;
|
||||
}
|
||||
return counter;
|
||||
}
|
|
@ -6,18 +6,23 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* internal kernel image list */
|
||||
struct ldimg *kernel_img_list = NULL;
|
||||
extern struct ldimg *kernel_img_list;
|
||||
|
||||
|
||||
/* hypervisor_get_image_list(): Dump all ELF file stored into the SMEM */
|
||||
/* hypervisor_get_image_list(): Dump all ELF file stored into the SMEM
|
||||
*
|
||||
* @note:
|
||||
* on real calculator, all file transfered using USB are concidered to be
|
||||
* 'archived', but on emulator they are concidered like file. */
|
||||
static int loader_list_img(struct ldimg **image, struct smemfs_inode *inode)
|
||||
{
|
||||
if (inode == NULL)
|
||||
return (0);
|
||||
|
||||
int counter = 0;
|
||||
if (inode->type != BFile_Type_Archived) {
|
||||
if (inode->type != BFile_Type_Archived
|
||||
&& inode->type != BFile_Type_File) {
|
||||
counter += loader_list_img(image, inode->child);
|
||||
goto anchor;
|
||||
}
|
||||
|
|
75
src/main.c
75
src/main.c
|
@ -1,56 +1,24 @@
|
|||
#include "vxBoot/terminal.h"
|
||||
#include "vxBoot/cli.h"
|
||||
#include "vxBoot/builtin.h"
|
||||
#include "vxBoot/fs/smemfs.h"
|
||||
#include "vxBoot/loader.h"
|
||||
#include "vxBoot/gui.h"
|
||||
#include "vxBoot/cli.h"
|
||||
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//TODO: better API for the command-line parser
|
||||
|
||||
/* internal builtin list */
|
||||
struct {
|
||||
const char *name;
|
||||
int (*f)(int argc, char **argv);
|
||||
} cmd_list[] = {
|
||||
{.name = "ls", &ls_main},
|
||||
{.name = "ld", &ld_main},
|
||||
{.name = "hw", &hw_main},
|
||||
{.name = "help", &help_main},
|
||||
{.name = NULL, NULL}
|
||||
};
|
||||
|
||||
/* try to find the appropriate command */
|
||||
static int (*check_cmd(char *cmd))(int, char**)
|
||||
{
|
||||
for (int i = 0; cmd_list[i].name != NULL; ++i) {
|
||||
if (strcmp(cmd, cmd_list[i].name) != 0)
|
||||
continue;
|
||||
if (cmd_list[i].f == NULL)
|
||||
terminal_write("command exist but not implemented\n");
|
||||
return (cmd_list[i].f);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* entry of the bootloader */
|
||||
int main(void)
|
||||
{
|
||||
int (*builtin)(int, char**);
|
||||
const char *usrline;
|
||||
char buff[128];
|
||||
char **argv;
|
||||
int argc;
|
||||
int ret;
|
||||
|
||||
/* change default font on fx9860 */
|
||||
#ifdef FX9860G
|
||||
extern font_t font_hexa;
|
||||
dfont(&font_hexa);
|
||||
#endif
|
||||
#ifdef FXCG50
|
||||
extern font_t font_fxcg50;
|
||||
dfont(&font_fxcg50);
|
||||
#endif
|
||||
|
||||
/* early log */
|
||||
terminal_open();
|
||||
|
@ -64,32 +32,9 @@ int main(void)
|
|||
smemfs_mount();
|
||||
loader_scan();
|
||||
|
||||
/* CLI loop */
|
||||
ret = 0;
|
||||
while (1) {
|
||||
/* get user command */
|
||||
usrline = (ret != 0) ? "/[%d]>" : "/>";
|
||||
terminal_write(usrline, ret);
|
||||
ret = 0;
|
||||
if (terminal_read(buff, 128) <= 1)
|
||||
continue;
|
||||
|
||||
/* parse and try to find the command */
|
||||
if (cli_parser_strtotab(&argc, &argv, buff) != 0) {
|
||||
terminal_write("error when processing \"%s\"", buff);
|
||||
ret = 255;
|
||||
continue;
|
||||
}
|
||||
builtin = check_cmd(argv[0]);
|
||||
if (builtin == NULL) {
|
||||
terminal_write("command \"%s\" not found\n", argv[0]);
|
||||
ret = 127;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* execute the command and free'd allocated memories */
|
||||
ret = builtin(argc, argv);
|
||||
cli_parser_strtotab_quit(&argc, &argv);
|
||||
}
|
||||
/* GUI Loop */
|
||||
if (loader_kernel_img_count() >= 1)
|
||||
gui_main();
|
||||
cli_main();
|
||||
return (1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue