Huge Cleaning - NW modules on fxCG50 - Ready for PR

This commit is contained in:
Sylvain PILLOT 2024-02-02 20:32:15 +01:00
parent 96077c1653
commit 12565ba8d2
9 changed files with 464 additions and 452 deletions

View File

@ -5,7 +5,7 @@ SH_LDFLAGS := -T fx9860g.ld -ljustui-fx -lm -lgint-fx -lc -lgint-fx -lgcc
SH_ASSETS := \
img_fkeys_main.png img_modifier_states.png \
font_5x7.png font_4x4.png font_4x6.png PoliceNW.png
font_5x7.png font_4x4.png font_4x6.png
SH_METADATA := fxconv-metadata.txt
SH_CONVFLAGS := --fx

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -31,12 +31,3 @@ font_4x6.png:
grid.padding: 1
grid.border: 0
proportional: true
PoliceNW.png:
name: numworks
type: font
charset: print
grid.size: 10x16
grid.padding: 0
grid.border: 0
proportional: false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -4,59 +4,60 @@
//.-'` `---` ' License: MIT (except some files; see LICENSE) //
//---------------------------------------------------------------------------//
#include "py/builtin.h"
#include "py/compile.h"
#include "py/gc.h"
#include "py/stackctrl.h"
#include "py/builtin.h"
#include "py/mphal.h"
#include "py/repl.h"
#include "py/stackctrl.h"
#include "pyexec.h"
#include "shared/runtime/gchelper.h"
#include "pyexec.h"
#include <gint/display.h>
#include <gint/drivers/keydev.h>
#include <gint/fs.h>
#include <gint/keyboard.h>
#include <gint/kmalloc.h>
#include <gint/fs.h>
#include <gint/timer.h>
#include <justui/jfileselect.h>
#include <justui/jfkeys.h>
#include <justui/jlabel.h>
#include <justui/jpainted.h>
#include <justui/jscene.h>
#include <justui/jlabel.h>
#include <justui/jfkeys.h>
#include <justui/jfileselect.h>
#include <justui/jpainted.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "console.h"
#include "debug.h"
#include "mpconfigport.h"
#include "console.h"
#include "widget_shell.h"
#include "debug.h"
//=== Application globals ===//
struct pe_globals {
/* The terminal data structure (with lines, editing functions, etc). */
console_t *console;
/* The global JustUI scene. */
jscene *scene;
/* The widget shell (which connects the GUI to `console`). */
widget_shell *shell;
/* The file selection widget. */
jfileselect *fileselect;
/* Title widget and whether to show it in the shell. */
jlabel *title;
bool show_title_in_shell;
/* The terminal data structure (with lines, editing functions, etc). */
console_t *console;
/* The global JustUI scene. */
jscene *scene;
/* The widget shell (which connects the GUI to `console`). */
widget_shell *shell;
/* The file selection widget. */
jfileselect *fileselect;
/* Title widget and whether to show it in the shell. */
jlabel *title;
bool show_title_in_shell;
};
// TODO: Put pe_globals in a header for use by the loop hook in mpconfigport.h
widget_shell *pe_shell;
struct pe_globals PE = {0};
struct pe_globals PE = { 0 };
// TODO : make this more clean by putting these globals into pe_globals and
// making this accessible to modules
@ -64,12 +65,14 @@ bool is_dwindowed = false;
bool is_timered = false;
unsigned int timer_altered[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
//=== Hook for redirecting stdout/stderr to the shell ===//
static ssize_t stdouterr_write(void *data, void const *buf, size_t size) {
console_t *cons = data;
console_write(cons, buf, size);
return size;
static ssize_t stdouterr_write(void *data, void const *buf, size_t size)
{
console_t *cons = data;
console_write(cons, buf, size);
return size;
}
fs_descriptor_type_t stdouterr_type = {
@ -81,67 +84,72 @@ fs_descriptor_type_t stdouterr_type = {
//=== File filter for the selection dialog ===//
static bool strendswith(char const *str, char const *suffix) {
size_t l1 = strlen(str);
size_t l2 = strlen(suffix);
static bool strendswith(char const *str, char const *suffix)
{
size_t l1 = strlen(str);
size_t l2 = strlen(suffix);
return l1 >= l2 && strcmp(str + l1 - l2, suffix) == 0;
return l1 >= l2 && strcmp(str + l1 - l2, suffix) == 0;
}
static bool py_file_filter(struct dirent const *ent) {
if (!jfileselect_default_filter(ent))
return false;
if (ent->d_type == DT_DIR)
return true;
return strendswith(ent->d_name, ".py");
static bool py_file_filter(struct dirent const *ent)
{
if(!jfileselect_default_filter(ent))
return false;
if(ent->d_type == DT_DIR)
return true;
return strendswith(ent->d_name, ".py");
}
//=== Module loading utilities ===//
static char *path_to_module(char const *path) {
if (path[0] == '/')
path++;
static char *path_to_module(char const *path)
{
if(path[0] == '/')
path++;
int i, n = strlen(path);
char *module = malloc(n + 1);
if (!module)
return NULL;
int i, n = strlen(path);
char *module = malloc(n + 1);
if(!module)
return NULL;
for (i = 0; i < n; i++) {
if (i == n - 3 && !strcmp(path + i, ".py"))
break;
module[i] = (path[i] == '/') ? '.' : path[i];
}
module[i] = 0;
return module;
for(i = 0; i < n; i++) {
if(i == n - 3 && !strcmp(path + i, ".py"))
break;
module[i] = (path[i] == '/') ? '.' : path[i];
}
module[i] = 0;
return module;
}
//=== AC/ON interrupt mechanism ===//
/* Filter AC/ON push events asynchronously from the keyboard driver and
interrupt MicroPython instead. */
static bool async_filter(key_event_t ev) {
/* Gobble all events related to AC/ON to make sure that the keyboard driver
treats them as handled. Otherwise, we'd run the risk of filling the
event queue (if the user doesn't read from it) thus preventing the
driver from handling AC/ON releases, which disables further presses. */
if (mp_interrupt_char >= 0 && ev.key == KEY_ACON) {
/* This function supports asynchronous calls, by design. */
if (ev.type == KEYEV_DOWN)
mp_sched_keyboard_interrupt();
return false;
}
static bool async_filter(key_event_t ev)
{
/* Gobble all events related to AC/ON to make sure that the keyboard driver
treats them as handled. Otherwise, we'd run the risk of filling the
event queue (if the user doesn't read from it) thus preventing the
driver from handling AC/ON releases, which disables further presses. */
if(mp_interrupt_char >= 0 && ev.key == KEY_ACON) {
/* This function supports asynchronous calls, by design. */
if(ev.type == KEYEV_DOWN)
mp_sched_keyboard_interrupt();
return false;
}
return true;
return true;
}
void pe_after_python_exec(int input_kind, int exec_flags, void *ret_val,
int *ret) {
(void)input_kind;
(void)exec_flags;
(void)ret_val;
(void)ret;
clearevents();
int *ret)
{
(void)input_kind;
(void)exec_flags;
(void)ret_val;
(void)ret;
clearevents();
}
//=== Rendering ===//
@ -156,343 +164,355 @@ extern bopti_image_t const img_modifier_states;
#define _(fx, cg) (cg)
#endif
void pe_enter_graphics_mode(void) {
/* Cancel any pending update of the shell */
PE.console->render_needed = false;
PE.shell->widget.update = 0;
void pe_enter_graphics_mode(void)
{
/* Cancel any pending update of the shell */
PE.console->render_needed = false;
PE.shell->widget.update = 0;
}
void pe_draw(void) {
dclear(C_WHITE);
jscene_render(PE.scene);
void pe_draw(void)
{
dclear(C_WHITE);
jscene_render(PE.scene);
/* Render shell modifiers above the scene in a convenient spot */
int shift, alpha, layer;
bool instant;
widget_shell_get_modifiers(PE.shell, &shift, &alpha);
widget_shell_modifier_info(shift, alpha, &layer, &instant);
int icon = 2 * layer + !instant;
/* Render shell modifiers above the scene in a convenient spot */
int shift, alpha, layer;
bool instant;
widget_shell_get_modifiers(PE.shell, &shift, &alpha);
widget_shell_modifier_info(shift, alpha, &layer, &instant);
int icon = 2 * layer + !instant;
#ifdef FX9860G
dsubimage(118, 58, &img_modifier_states, 9 * icon + 1, 1, 8, 6, DIMAGE_NONE);
dsubimage(118, 58, &img_modifier_states, 9*icon+1, 1, 8, 6,
DIMAGE_NONE);
#else
dsubimage(377, 207, &img_modifier_states, 16 * icon, 0, 15, 14, DIMAGE_NONE);
dsubimage(377, 207, &img_modifier_states, 16*icon, 0, 15, 14,
DIMAGE_NONE);
#endif
dupdate();
dupdate();
}
//=== Application control functions ===//
void pe_restore_window_and_timer(void) {
if (is_dwindowed) {
struct dwindow win;
win.left = 0;
win.top = 0;
win.right = DWIDTH;
win.bottom = DHEIGHT;
dwindow_set(win);
is_dwindowed = false; // we mark as not windowed
}
void pe_restore_window_and_timer(void)
{
if (is_dwindowed)
{
struct dwindow win;
win.left = 0;
win.top = 0;
win.right = DWIDTH;
win.bottom = DHEIGHT;
if (is_timered) {
for (int u = 0; u < 9; u++)
if (timer_altered[u] == 1)
timer_stop(u);
is_timered = false;
}
dwindow_set(win);
is_dwindowed = false; // we mark as not windowed
}
if (is_timered)
{
for (int u = 0; u < 9; u++)
if (timer_altered[u] == 1)
timer_stop(u);
is_timered = false;
}
}
static void pe_reset_micropython(void) {
gc_sweep_all();
mp_deinit();
mp_init();
static void pe_reset_micropython(void)
{
gc_sweep_all();
mp_deinit();
mp_init();
#ifdef FX9860G
char const *msg = "**SHELL INIT.**\n";
char const *msg = "**SHELL INIT.**\n";
#else
char const *msg = "*** SHELL INITIALIZED ***\n";
char const *msg = "*** SHELL INITIALIZED ***\n";
#endif
console_newline(PE.console);
console_write(PE.console, msg, -1);
pyexec_event_repl_init();
console_newline(PE.console);
console_write(PE.console, msg, -1);
pyexec_event_repl_init();
}
static void pe_print_prompt(int which) {
char const *prompt = NULL;
if (which == 2)
prompt = mp_repl_get_ps2();
else
prompt = mp_repl_get_ps1();
static void pe_print_prompt(int which)
{
char const *prompt = NULL;
if(which == 2)
prompt = mp_repl_get_ps2();
else
prompt = mp_repl_get_ps1();
console_write(PE.console, prompt, -1);
console_lock_prefix(PE.console);
console_write(PE.console, prompt, -1);
console_lock_prefix(PE.console);
}
/* Handle a GUI event. If `shell_bound` is true, only actions that have an
effect on the shell are allowed and the return value is any full line that
is entered in the shell. Otherwise, the full GUI is available and the return
value is NULL. */
static char *pe_handle_event(jevent e, bool shell_bound) {
if (e.type == JSCENE_PAINT)
pe_draw();
static char *pe_handle_event(jevent e, bool shell_bound)
{
if(e.type == JSCENE_PAINT)
pe_draw();
if (e.type == WIDGET_SHELL_MOD_CHANGED)
PE.scene->widget.update = true;
if(e.type == WIDGET_SHELL_MOD_CHANGED)
PE.scene->widget.update = true;
if (e.type == WIDGET_SHELL_INPUT) {
char *line = (char *)e.data;
if (shell_bound) {
return line;
} else {
pyexec_repl_execute(line);
free(line);
pe_print_prompt(1);
if(e.type == WIDGET_SHELL_INPUT) {
char *line = (char *)e.data;
if(shell_bound) {
return line;
}
else {
pyexec_repl_execute(line);
free(line);
pe_print_prompt(1);
}
}
}
if (!shell_bound && e.type == JFILESELECT_VALIDATED) {
char const *path = jfileselect_selected_file(PE.fileselect);
char *module = path_to_module(path);
if (module) {
jscene_show_and_focus(PE.scene, PE.shell);
jwidget_set_visible(PE.title, PE.show_title_in_shell);
if(!shell_bound && e.type == JFILESELECT_VALIDATED) {
char const *path = jfileselect_selected_file(PE.fileselect);
char *module = path_to_module(path);
if(module) {
jscene_show_and_focus(PE.scene, PE.shell);
jwidget_set_visible(PE.title, PE.show_title_in_shell);
pe_reset_micropython();
pe_reset_micropython();
char *str = malloc(8 + strlen(module) + 1);
if (str) {
strcpy(str, "import ");
strcat(str, module);
pyexec_repl_execute(str);
free(str);
}
free(module);
char *str = malloc(8 + strlen(module) + 1);
if(str) {
strcpy(str, "import ");
strcat(str, module);
pyexec_repl_execute(str);
free(str);
}
free(module);
pe_restore_window_and_timer();
pe_restore_window_and_timer();
pe_print_prompt(1);
pe_print_prompt(1);
}
}
if(e.type != JWIDGET_KEY || e.key.type == KEYEV_UP)
return NULL;
int key = e.key.key;
if(key == KEY_SQUARE && !e.key.shift && e.key.alpha)
pe_debug_screenshot();
if(key == KEY_TAN)
pe_debug_kmalloc();
if(!shell_bound && key == KEY_F1) {
jscene_show_and_focus(PE.scene, PE.fileselect);
jwidget_set_visible(PE.title, true);
}
if(!shell_bound && key == KEY_F2) {
jscene_show_and_focus(PE.scene, PE.shell);
jwidget_set_visible(PE.title, PE.show_title_in_shell);
}
}
if (e.type != JWIDGET_KEY || e.key.type == KEYEV_UP)
return NULL;
int key = e.key.key;
}
if (key == KEY_SQUARE && !e.key.shift && e.key.alpha)
pe_debug_screenshot();
if (key == KEY_TAN)
int pe_readline(vstr_t *line, char const *prompt)
{
console_write(PE.console, prompt, -1);
console_lock_prefix(PE.console);
int c = mp_interrupt_char;
mp_hal_set_interrupt_char(-1);
char *text = NULL;
while(!text) {
jevent e = jscene_run(PE.scene);
text = pe_handle_event(e, true);
}
mp_hal_set_interrupt_char(c);
vstr_reset(line);
vstr_add_str(line, text);
free(text);
return 0; // TODO: return CHAR_CTRL_C on AC/ON instead
}
int main(int argc, char **argv)
{
pe_debug_init();
pe_debug_kmalloc();
if (!shell_bound && key == KEY_F1) {
jscene_show_and_focus(PE.scene, PE.fileselect);
jwidget_set_visible(PE.title, true);
}
if (!shell_bound && key == KEY_F2) {
jscene_show_and_focus(PE.scene, PE.shell);
jwidget_set_visible(PE.title, PE.show_title_in_shell);
}
//=== Init sequence ===//
return NULL;
}
keydev_set_async_filter(keydev_std(), async_filter);
int pe_readline(vstr_t *line, char const *prompt) {
console_write(PE.console, prompt, -1);
console_lock_prefix(PE.console);
PE.console = console_create(8192, 200);
int c = mp_interrupt_char;
mp_hal_set_interrupt_char(-1);
/* Set up standard streams */
close(STDOUT_FILENO);
close(STDERR_FILENO);
open_generic(&stdouterr_type, PE.console, STDOUT_FILENO);
open_generic(&stdouterr_type, PE.console, STDERR_FILENO);
char *text = NULL;
while (!text) {
jevent e = jscene_run(PE.scene);
text = pe_handle_event(e, true);
}
mp_hal_set_interrupt_char(c);
vstr_reset(line);
vstr_add_str(line, text);
free(text);
return 0; // TODO: return CHAR_CTRL_C on AC/ON instead
}
int main(int argc, char **argv) {
pe_debug_init();
pe_debug_kmalloc();
//=== Init sequence ===//
keydev_set_async_filter(keydev_std(), async_filter);
/* Make delayed shift/alpha permanent so the stay between calls to
jscene_run() and can be used for delayed key combos */
keydev_transform_t tr = keydev_transform(keydev_std());
tr.enabled |= KEYDEV_TR_DELAYED_SHIFT;
tr.enabled |= KEYDEV_TR_DELAYED_ALPHA;
keydev_set_transform(keydev_std(), tr);
PE.console = console_create(8192, 200);
/* Set up standard streams */
close(STDOUT_FILENO);
close(STDERR_FILENO);
open_generic(&stdouterr_type, PE.console, STDOUT_FILENO);
open_generic(&stdouterr_type, PE.console, STDERR_FILENO);
/* Initialize the MicroPython GC with most available memory */
mp_stack_ctrl_init();
/* Initialize the MicroPython GC with most available memory */
mp_stack_ctrl_init();
#ifdef FX9860G
/* Put basically all the OS heap into the Python GC. For our own purposes
we'll use gint's _uram arena and the leftover from the OS heap. */
int size = 65536;
bool first = true;
/* Put basically all the OS heap into the Python GC. For our own purposes
we'll use gint's _uram arena and the leftover from the OS heap. */
int size = 65536;
bool first = true;
while (size >= 2048) {
void *area = kmalloc(size, "_os");
if (area) {
if (first)
gc_init(area, area + size);
else
gc_add(area, area + size);
first = false;
} else
size /= 2;
}
while(size >= 2048) {
void *area = kmalloc(size, "_os");
if(area) {
if(first)
gc_init(area, area + size);
else
gc_add(area, area + size);
first = false;
}
else size /= 2;
}
if (first)
pe_debug_panic("No heap!");
if(first)
pe_debug_panic("No heap!");
#if PE_DEBUG
/* Add some Python ram */
// https://www.planet-casio.com/Fr/forums/topic15269-10-khicas-add-in-calcul-formel-pour-graph-90e-et-35eii.html#189284
void *py_ram_start = (void *)0x88053800;
void *py_ram_end = (void *)0x8807f000;
gc_add(py_ram_start, py_ram_end);
/* Add some Python ram */
// https://www.planet-casio.com/Fr/forums/topic15269-10-khicas-add-in-calcul-formel-pour-graph-90e-et-35eii.html#189284
void *py_ram_start = (void*)0x88053800;
void *py_ram_end = (void*)0x8807f000;
gc_add(py_ram_start, py_ram_end);
#endif
#else
/* Get everything from the OS stack (~ 350 ko) */
size_t gc_area_size;
void *gc_area = kmalloc_max(&gc_area_size, "_ostk");
gc_init(gc_area, gc_area + gc_area_size);
/* Get everything from the OS stack (~ 350 ko) */
size_t gc_area_size;
void *gc_area = kmalloc_max(&gc_area_size, "_ostk");
gc_init(gc_area, gc_area + gc_area_size);
/* Other options:
- All of _uram (leaving the OS heap for the shell/GUI/etc)
- The OS' extra VRAM
- Memory past the 2 MB boundary on tested OSes */
// gc_add(start, end)...
/* Other options:
- All of _uram (leaving the OS heap for the shell/GUI/etc)
- The OS' extra VRAM
- Memory past the 2 MB boundary on tested OSes */
// gc_add(start, end)...
#endif
mp_init();
mp_init();
/* TODO: Add an option for the shorter prompt */
/* TODO: Add an option for the shorter prompt */
#ifdef FX9860G
MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS1]) =
MP_OBJ_NEW_QSTR(qstr_from_str(">"));
MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS2]) =
MP_OBJ_NEW_QSTR(qstr_from_str("."));
MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS1]) =
MP_OBJ_NEW_QSTR(qstr_from_str(">"));
MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS2]) =
MP_OBJ_NEW_QSTR(qstr_from_str("."));
#endif
pyexec_event_repl_init();
pe_print_prompt(1);
pyexec_event_repl_init();
pe_print_prompt(1);
//=== GUI setup ===//
//=== GUI setup ===//
PE.scene = jscene_create_fullscreen(NULL);
PE.title = jlabel_create("PythonExtra", PE.scene);
jwidget *stack = jwidget_create(PE.scene);
jfkeys *fkeys = jfkeys_create2(&img_fkeys_main, "/FILES;/SHELL", PE.scene);
(void)fkeys;
PE.scene = jscene_create_fullscreen(NULL);
PE.title = jlabel_create("PythonExtra", PE.scene);
jwidget *stack = jwidget_create(PE.scene);
jfkeys *fkeys = jfkeys_create2(&img_fkeys_main, "/FILES;/SHELL", PE.scene);
(void)fkeys;
jwidget_set_stretch(PE.title, 1, 0, false);
jwidget_set_stretch(PE.title, 1, 0, false);
jlayout_set_vbox(PE.scene)->spacing = _(0, 3);
jlayout_set_stack(stack);
jwidget_set_stretch(stack, 1, 1, false);
jlayout_set_vbox(PE.scene)->spacing = _(0, 3);
jlayout_set_stack(stack);
jwidget_set_stretch(stack, 1, 1, false);
/* Filesystem tab */
PE.fileselect = jfileselect_create(stack);
jfileselect_set_filter(PE.fileselect, py_file_filter);
jfileselect_set_show_file_size(PE.fileselect, true);
jwidget_set_stretch(PE.fileselect, 1, 1, false);
/* Filesystem tab */
PE.fileselect = jfileselect_create(stack);
jfileselect_set_filter(PE.fileselect, py_file_filter);
jfileselect_set_show_file_size(PE.fileselect, true);
jwidget_set_stretch(PE.fileselect, 1, 1, false);
/* Shell tab */
PE.shell = pe_shell = widget_shell_create(PE.console, stack);
widget_shell_set_line_spacing(PE.shell, _(1, 3));
jwidget_set_stretch(PE.shell, 1, 1, false);
/* Shell tab */
PE.shell = pe_shell = widget_shell_create(PE.console, stack);
widget_shell_set_line_spacing(PE.shell, _(1, 3));
jwidget_set_stretch(PE.shell, 1, 1, false);
#ifdef FX9860G
PE.show_title_in_shell = false;
jwidget_set_padding(PE.title, 0, 0, 1, 0);
widget_shell_set_font(PE.shell, &font_4x6);
PE.show_title_in_shell = false;
jwidget_set_padding(PE.title, 0, 0, 1, 0);
widget_shell_set_font(PE.shell, &font_4x6);
#else
PE.show_title_in_shell = true;
jwidget_set_background(PE.title, C_BLACK);
jlabel_set_text_color(PE.title, C_WHITE);
jwidget_set_padding(PE.title, 3, 6, 3, 6);
jwidget_set_padding(stack, 0, 6, 0, 6);
PE.show_title_in_shell = true;
jwidget_set_background(PE.title, C_BLACK);
jlabel_set_text_color(PE.title, C_WHITE);
jwidget_set_padding(PE.title, 3, 6, 3, 6);
jwidget_set_padding(stack, 0, 6, 0, 6);
#endif
/* Initial state */
jfileselect_browse(PE.fileselect, "/");
jscene_show_and_focus(PE.scene, PE.fileselect);
/* Initial state */
jfileselect_browse(PE.fileselect, "/");
jscene_show_and_focus(PE.scene, PE.fileselect);
//=== Event handling ===//
//=== Event handling ===//
while (1) {
jevent e = jscene_run(PE.scene);
pe_handle_event(e, false);
}
while(1) {
jevent e = jscene_run(PE.scene);
pe_handle_event(e, false);
}
//=== Deinitialization ===//
//=== Deinitialization ===//
gc_sweep_all();
mp_deinit();
console_destroy(PE.console);
return 0;
gc_sweep_all();
mp_deinit();
console_destroy(PE.console);
return 0;
}
/* Handle uncaught exceptions (normally unreachable). */
void nlr_jump_fail(void *val) {
dclear(C_BLACK);
dtext(2, 2, C_WHITE, "nlr_jump_fail!");
dprint(2, 2, C_WHITE, "val = %p", val);
dupdate();
while (1)
getkey();
void nlr_jump_fail(void *val)
{
dclear(C_BLACK);
dtext(2, 2, C_WHITE, "nlr_jump_fail!");
dprint(2, 2, C_WHITE, "val = %p", val);
dupdate();
while(1)
getkey();
}
/* Do a garbage collection cycle. */
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
void gc_collect(void)
{
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
}
mp_import_stat_t mp_import_stat(const char *path) {
struct stat st;
int rc = stat(path, &st);
if (rc < 0)
return MP_IMPORT_STAT_NO_EXIST;
mp_import_stat_t mp_import_stat(const char *path)
{
struct stat st;
int rc = stat(path, &st);
if(rc < 0)
return MP_IMPORT_STAT_NO_EXIST;
if (S_ISDIR(st.st_mode))
return MP_IMPORT_STAT_DIR;
else
return MP_IMPORT_STAT_FILE;
if(S_ISDIR(st.st_mode))
return MP_IMPORT_STAT_DIR;
else
return MP_IMPORT_STAT_FILE;
}
// TODO: See branch 'posix-open' for a relevant attempt at using the POSIX API
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs) {
mp_obj_t *args_items;
size_t len;
mp_obj_get_array(*args, &len, &args_items);
printf("%d %p\n", (int)len, args_items);
if (len != 2)
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
{
mp_obj_t *args_items;
size_t len;
mp_obj_get_array(*args, &len, &args_items);
printf("%d %p\n", (int)len, args_items);
if(len != 2)
return mp_const_none;
char const *path = mp_obj_str_get_str(args_items[0]);
char const *mode = mp_obj_str_get_str(args_items[1]);
printf("'%s' '%s'\n", path, mode);
return mp_const_none;
char const *path = mp_obj_str_get_str(args_items[0]);
char const *mode = mp_obj_str_get_str(args_items[1]);
printf("'%s' '%s'\n", path, mode);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);

View File

@ -5,109 +5,106 @@
//---------------------------------------------------------------------------//
// pe.mpconfigport: MicroPython's main port configuration file
#include "widget_shell.h"
#include <alloca.h>
#include <stdint.h>
#include <alloca.h>
#include "widget_shell.h"
/* Debugging options: PythonExtra debug tools (pretty much required for any
other one), MicroPython's verbose logging. */
/* PythonExtra's main debug flag */
#define PE_DEBUG (0)
#define MICROPY_DEBUG_VERBOSE (0)
#define PE_DEBUG (0)
#define MICROPY_DEBUG_VERBOSE (0)
/* Custom flag to remove DEBUG_printf in alloc/GC (very verbose) */
#define MICROPY_DEBUG_VERBOSE_ALLOC (0)
#define MICROPY_DEBUG_VERBOSE_ALLOC (0)
#if PE_DEBUG
extern const struct _mp_print_t mp_debug_print;
#define MICROPY_DEBUG_PRINTER (&mp_debug_print)
#define MICROPY_DEBUG_PRINTER (&mp_debug_print)
#endif
/* Custom option to use relative imports. For instance when working at the fs
root, 'import b' in '/folder/a.py' will import 'folder/b.py' not '/b.py'. */
#define MICROPY_RELATIVE_FILE_IMPORTS (1)
#define MICROPY_RELATIVE_FILE_IMPORTS (1)
/* General feature set selection
Other options: BASIC_FEATURES, EXTRA_FEATURES, FULL_FEATURES, EVERYTHING */
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES)
/* Main features */
#define MICROPY_ENABLE_COMPILER (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_GC_SPLIT_HEAP (1)
#define MP_ENDIANNESS_BIG (1)
#define MICROPY_READER_POSIX (1)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
#define MICROPY_REPL_EVENT_DRIVEN (1)
#define MICROPY_ENABLE_COMPILER (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_GC_SPLIT_HEAP (1)
#define MP_ENDIANNESS_BIG (1)
#define MICROPY_READER_POSIX (1)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
#define MICROPY_REPL_EVENT_DRIVEN (1)
/* Other features that we select against MICROPY_CONFIG_ROM_LEVEL */
#define MICROPY_PY_FSTRINGS (1) /* in EXTRA_FEATURES */
#define MICROPY_HELPER_REPL (1) /* in EXTRA_FEATURES */
#define MICROPY_ENABLE_SOURCE_LINE (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_STR_UNICODE (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_HELP_MODULES (1) /* in EXTRA_FEATURES */
#define MICROPY_KBD_EXCEPTION (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_SYS_PS1_PS2 (1) /* in EXTRA_FEATURES */
#define MICROPY_MODULE_BUILTIN_INIT (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_ALL_SPECIAL_METHODS (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_FSTRINGS (1) /* in EXTRA_FEATURES */
#define MICROPY_HELPER_REPL (1) /* in EXTRA_FEATURES */
#define MICROPY_ENABLE_SOURCE_LINE (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_STR_UNICODE (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_HELP_MODULES (1) /* in EXTRA_FEATURES */
#define MICROPY_KBD_EXCEPTION (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_SYS_PS1_PS2 (1) /* in EXTRA_FEATURES */
#define MICROPY_MODULE_BUILTIN_INIT (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_ALL_SPECIAL_METHODS (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_ROUND_INT (1) /* in EXTRA_FEATURES */
#define MICROPY_PY_BUILTINS_ROUND_INT (1) /* in EXTRA_FEATURES */
// #define MICROPY_PY_SYS_STDFILES (1) /* in EXTRA_FEATURES */
#define MICROPY_ALLOC_PATH_MAX (256)
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (32)
#define MICROPY_MEM_STATS (0)
#define MICROPY_GC_ALLOC_THRESHOLD (1)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_ALLOC_PATH_MAX (256)
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (32)
#define MICROPY_MEM_STATS (0)
#define MICROPY_GC_ALLOC_THRESHOLD (1)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1)
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
#define MICROPY_PY_BUILTINS_ENUMERATE (1)
#define MICROPY_PY_BUILTINS_FILTER (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_HELP (1)
#define MICROPY_PY_BUILTINS_INPUT (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY_BUILTINS_REVERSED (1)
#define MICROPY_PY_BUILTINS_SET (1)
#define MICROPY_PY_BUILTINS_SLICE (1)
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
#define MICROPY_PY_BUILTINS_ENUMERATE (1)
#define MICROPY_PY_BUILTINS_FILTER (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_HELP (1)
#define MICROPY_PY_BUILTINS_INPUT (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY_BUILTINS_REVERSED (1)
#define MICROPY_PY_BUILTINS_SET (1)
#define MICROPY_PY_BUILTINS_SLICE (1)
/* Extra built-in modules */
#define MICROPY_PY_ARRAY (1)
#define MICROPY_PY_COLLECTIONS (1)
#define MICROPY_PY_MATH (1)
#define MICROPY_PY_CMATH (1)
#define MICROPY_PY_GC (1)
#define MICROPY_PY_IO (1)
#define MICROPY_PY_STRUCT (1)
#define MICROPY_PY_RANDOM (1)
#define MICROPY_PY_RANDOM_EXTRA_FUNCS (1)
#define MICROPY_PY_SYS (1)
#define MICROPY_PY_TIME (1)
#define MICROPY_PY_ARRAY (1)
#define MICROPY_PY_COLLECTIONS (1)
#define MICROPY_PY_MATH (1)
#define MICROPY_PY_CMATH (1)
#define MICROPY_PY_GC (1)
#define MICROPY_PY_IO (1)
#define MICROPY_PY_STRUCT (1)
#define MICROPY_PY_RANDOM (1)
#define MICROPY_PY_RANDOM_EXTRA_FUNCS (1)
#define MICROPY_PY_SYS (1)
#define MICROPY_PY_TIME (1)
// TODO: Enable the os module:
// #define MICROPY_PY_UOS (1)
// TODO: Enable other modules
// #define MICROPY_PY_URE (1) // + other flags?
/* Enable alias of u-modules */
#define MICROPY_MODULE_WEAK_LINKS (1)
#define MICROPY_MODULE_WEAK_LINKS (1)
/* Command executed automatically after every shell input */
void pe_after_python_exec(int input_kind, int exec_flags, void *ret_val,
int *ret);
void pe_after_python_exec(
int input_kind, int exec_flags, void *ret_val, int *ret);
#define MICROPY_BOARD_AFTER_PYTHON_EXEC pe_after_python_exec
/* Command executed regularly during execution */
extern void pe_draw(void);
extern widget_shell *pe_shell;
#define MICROPY_VM_HOOK_LOOP \
{ \
if (pe_shell->widget.update) \
pe_draw(); \
}
#define MICROPY_VM_HOOK_LOOP \
{ if(pe_shell->widget.update) pe_draw(); }
/* extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
@ -119,6 +116,6 @@ typedef uintptr_t mp_uint_t;
typedef long mp_off_t;
#define MICROPY_HW_BOARD_NAME "sh7305"
#define MICROPY_HW_MCU_NAME "sh-4a"
#define MICROPY_HW_MCU_NAME "sh-4a"
#define MP_STATE_PORT MP_STATE_VM
#define MP_STATE_PORT MP_STATE_VM

View File

@ -14,11 +14,67 @@
#include "py/runtime.h"
#include <gint/keyboard.h>
#include "ionkeyNW.h"
#include <stdio.h>
#include <stdlib.h>
/* BEGINING OF KEY TRANSLATION */
// the following table aims at providing a keymap for NW on Casio
// line that are commented correspond to keys that are similar (with exact same
// name) between NW and Casio
//#define KEY_LEFT
//#define KEY_UP
//#define KEY_DOWN
//#define KEY_RIGHT
#define KEY_OK KEY_F1
#define KEY_BACK KEY_EXIT
#define KEY_HOME KEY_MENU
#define KEY_ONOFF KEY_ACON
//#define KEY_SHIFT
//#define KEY_ALPHA
#define KEY_XNT KEY_XOT
#define KEY_VAR KEY_VARS
#define KEY_TOOLBOX KEY_OPTN
#define KEY_BACKSPACE KEY_DEL
//#define KEY_EXP // Note this one may be challenging
//#define KEY_LN
//#define KEY_LOG
#define KEY_IMAGINARY KEY_F2
//#define KEY_COMMA
//#define KEY_POWER
#define KEY_SINE KEY_SIN
#define KEY_COSINE KEY_COS
#define KEY_TANGENT KEY_TAN
#define KEY_PI KEY_F3
#define KEY_SQRT KEY_F4
//#define KEY_SQUARE
#define KEY_SEVEN KEY_7
#define KEY_EIGHT KEY_8
#define KEY_NINE KEY_9
#define KEY_LEFTPARENTHESIS KEY_LEFTP
#define KEY_RIGHTPARENTHESIS KEY_RIGHTP
#define KEY_FOUR KEY_4
#define KEY_FIVE KEY_5
#define KEY_SIX KEY_6
#define KEY_MULTIPLICATION KEY_MUL
#define KEY_DIVISION KEY_DIV
#define KEY_ONE KEY_1
#define KEY_TWO KEY_2
#define KEY_THREE KEY_3
#define KEY_PLUS KEY_ADD
#define KEY_MINUS KEY_SUB
#define KEY_ZERO KEY_0
//#define KEY_DOT
#define KEY_EE KEY_F5
#define KEY_ANS KEY_NEG
//#define KEY_EXE
/* END OF KEY TRANSLATION */
#define FUN_0(NAME) MP_DEFINE_CONST_FUN_OBJ_0(ion_##NAME##_obj, ion_##NAME)
#define FUN_1(NAME) MP_DEFINE_CONST_FUN_OBJ_1(ion_##NAME##_obj, ion_##NAME)
#define FUN_2(NAME) MP_DEFINE_CONST_FUN_OBJ_2(ion_##NAME##_obj, ion_##NAME)

View File

@ -1,52 +0,0 @@
#include <gint/keyboard.h>
// the following table aims at providing a keymap for NW on Casio
// line that are commented correspond to keys that are similar (with exact same
// name) between NW and Casio
//#define KEY_LEFT
//#define KEY_UP
//#define KEY_DOWN
//#define KEY_RIGHT
#define KEY_OK KEY_F1
#define KEY_BACK KEY_EXIT
#define KEY_HOME KEY_MENU
#define KEY_ONOFF KEY_ACON
//#define KEY_SHIFT
//#define KEY_ALPHA
#define KEY_XNT KEY_XOT
#define KEY_VAR KEY_VARS
#define KEY_TOOLBOX KEY_OPTN
#define KEY_BACKSPACE KEY_DEL
//#define KEY_EXP // Note this one may be challenging
//#define KEY_LN
//#define KEY_LOG
#define KEY_IMAGINARY KEY_F2
//#define KEY_COMMA
//#define KEY_POWER
#define KEY_SINE KEY_SIN
#define KEY_COSINE KEY_COS
#define KEY_TANGENT KEY_TAN
#define KEY_PI KEY_F3
#define KEY_SQRT KEY_F4
//#define KEY_SQUARE
#define KEY_SEVEN KEY_7
#define KEY_EIGHT KEY_8
#define KEY_NINE KEY_9
#define KEY_LEFTPARENTHESIS KEY_LEFTP
#define KEY_RIGHTPARENTHESIS KEY_RIGHTP
#define KEY_FOUR KEY_4
#define KEY_FIVE KEY_5
#define KEY_SIX KEY_6
#define KEY_MULTIPLICATION KEY_MUL
#define KEY_DIVISION KEY_DIV
#define KEY_ONE KEY_1
#define KEY_TWO KEY_2
#define KEY_THREE KEY_3
#define KEY_PLUS KEY_ADD
#define KEY_MINUS KEY_SUB
#define KEY_ZERO KEY_0
//#define KEY_DOT
#define KEY_EE KEY_F5
#define KEY_ANS KEY_NEG
//#define KEY_EXE

View File

@ -166,7 +166,7 @@ static mp_obj_t Kandinsky_fill_rect(size_t n, mp_obj_t const *args) {
int color = Internal_Treat_Color(args[4]);
drect(x, y, x + w, y + h, color);
drect(x, y, x + w - 1, y + h - 1, color);
return mp_const_none;
}
@ -197,8 +197,8 @@ static mp_obj_t Kandinsky_get_pixel(mp_obj_t _x, mp_obj_t _y) {
}
static mp_obj_t Kandinsky_draw_string(size_t n, mp_obj_t const *args) {
int x = mp_obj_get_int(args[1]) + DELTAXNW;
int y = mp_obj_get_int(args[2]) + DELTAYNW;
int x = mp_obj_get_int(args[1]) + DELTAXNW + 1; // values used to adjust the visual result as per actual NW
int y = mp_obj_get_int(args[2]) + DELTAYNW + 2; // values used to adjust the visual result as per actual NW
size_t text_len;
char const *text = mp_obj_str_get_data(args[0], &text_len);