#include "py/compile.h" #include "py/gc.h" #include "py/mperrno.h" #include "py/stackctrl.h" #include "py/builtin.h" #include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" #include #include #include #include #include #include #include #include "console.h" //=== Console-based standard streams ===// ssize_t stdouterr_write(void *data, void const *buf, size_t size) { console_t *cons = data; console_write_at_cursor(cons, buf, size); return size; } fs_descriptor_type_t stdouterr_type = { .read = NULL, .write = stdouterr_write, .lseek = NULL, .close = NULL, }; //=== Main function ===// static console_t *cons = NULL; void pe_draw(void) { dclear(C_WHITE); #ifdef FX9860G int rows = 8; console_render(1, 1, cons, DWIDTH-2, rows); #else dprint(3, 3, C_BLACK, "PythonExtra, very much WIP :)"); dline(2, 16, DWIDTH-3, 16, C_BLACK); int rows = 12; console_render(3, 20, cons, DWIDTH-6, rows); int y = 20 + PE_CONSOLE_LINE_SPACING * rows; dline(2, y, DWIDTH-3, y, C_BLACK); #endif dupdate(); } void pe_exithandler(void) { pe_draw(); #ifdef FX9860G drect(DWIDTH-4, 0, DWIDTH-1, 3, C_BLACK); #else drect(DWIDTH-8, 0, DWIDTH-1, 7, C_RED); #endif dupdate(); getkey(); } int main(int argc, char **argv) { /* Set up standard streams */ cons = console_create(8192); close(STDOUT_FILENO); close(STDERR_FILENO); open_generic(&stdouterr_type, cons, STDOUT_FILENO); open_generic(&stdouterr_type, cons, STDERR_FILENO); atexit(pe_exithandler); /* Initialize MicroPython */ #define HEAP_SIZE 32768 void *heap = malloc(32768); if(!heap) { dclear(C_WHITE); dtext(1, 1, C_BLACK, "No heap!"); getkey(); return 1; } mp_stack_ctrl_init(); gc_init(heap, heap + HEAP_SIZE); // TODO: gc_add(start, end) for each area we want to allocate to // fx-9860G III: // * (nothing? x_x) // fx-CG 50: // * The entirety of _uram // * The entirety of the extra VRAM // * Possibly memory past 2M // * (keep the OS heap for normal malloc()) mp_init(); // Start a normal REPL; will exit when ctrl-D is entered on a blank line. pyexec_friendly_repl(); console_destroy(cons); // Deinitialise the runtime. gc_sweep_all(); mp_deinit(); return 0; } // Handle uncaught exceptions (should never be reached in a correct C implementation). 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(); }