// Copyright 2022 Bradley D. Nelson // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "esp32/platform.h" #include "esp32/options.h" #include "common/tier0_opcodes.h" #include "common/tier1_opcodes.h" #include "common/tier2_opcodes.h" #include "common/floats.h" #include "common/calls.h" #define SIM_HEAP_SIZE (100 * 1024 + 1024 * 1024) #define OPTIONAL_BLUETOOTH_VOCABULARY #define OPTIONAL_CAMERA_VOCABULARY #define OPTIONAL_INTERRUPTS_VOCABULARIES #define OPTIONAL_OLED_VOCABULARY #define OPTIONAL_RMT_VOCABULARY #define OPTIONAL_SPI_FLASH_VOCABULARY static cell_t *simulated(cell_t *sp, const char *op); #define PLATFORM_OPCODE_LIST \ PLATFORM_SIMULATED_OPCODE_LIST \ CALLING_OPCODE_LIST \ FLOATING_POINT_LIST #include "gen/esp32_sim_opcodes.h" #define Z(flags, str, name, code) static const char *STR_ ## name = str; PLATFORM_SIMULATED_OPCODE_LIST #undef Z #define MALLOC_CAP_INTERNAL 0 #define heap_caps_get_largest_free_block(x) SIM_HEAP_SIZE #define heap_caps_get_free_size(x) SIM_HEAP_SIZE // Fault handling can't work in the simulator for now. #undef ENABLE_ESP32_FORTH_FAULT_HANDLING #define forth_faults_setup() #define FAULT_ENTRY #include "common/bits.h" #include "common/core.h" #include "common/calling.h" #include "common/interp.h" #include "gen/esp32_boot.h" #include "esp32/main.cpp" #include #include #include #include #include #include #include static cell_t *simulated(cell_t *sp, const char *op) { if (op == STR_MALLOC) { *sp = (cell_t) malloc(*sp); return sp; } else if (op == STR_heap_caps_malloc) { --sp; *sp = (cell_t) malloc(*sp); return sp; } else if (op == STR_SYSFREE) { free((void*) *sp--); return sp; } else if (op == STR_SERIAL_BEGIN) { --sp; return sp; } else if (op == STR_SERIAL_READ_BYTES) { cell_t len = *sp--; *sp = read(0, (void *) *sp, len); return sp; } else if (op == STR_SERIAL_WRITE) { cell_t len = *sp--; *sp = write(1, (void *) *sp, len); return sp; } else if (op == STR_MS_TICKS) { struct timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); *++sp = tm.tv_sec * 1000 + tm.tv_nsec / 1000000; return sp; } else if (op == STR_RAW_YIELD) { return sp; } else if (op == STR_SPIFFS_BEGIN) { sp -= 2; *sp = 0; return sp; } else if (op == STR_pinMode) { sp -= 2; return sp; } else if (op == STR_digitalWrite) { sp -= 2; return sp; } else if (op == STR_SERIAL_AVAILABLE) { *++sp = 1; return sp; } else if (op == STR_RAW_TERMINATE) { exit(*sp--); return sp; } else if (op == STR_R_O) { *++sp = O_RDONLY; return sp; } else if (op == STR_OPEN_FILE) { cell_t mode = *sp--; cell_t len = *sp--; char filename[1024]; memcpy(filename, (void *) *sp, len); filename[len] = 0; cell_t ret = open(filename, mode, 0777); *sp = ret; *++sp = ret < 0 ? errno : 0; return sp; } else if (op == STR_FILE_SIZE) { struct stat st; cell_t w = fstat(*sp, &st); *sp = (cell_t) st.st_size; *++sp = w < 0 ? errno : 0; return sp; } else if (op == STR_READ_FILE) { cell_t fd = *sp--; cell_t len = *sp--; cell_t ret = read(fd, (void *) *sp, len); *sp = ret; *++sp = ret < 0 ? errno : 0; return sp; } else if (op == STR_CLOSE_FILE) { cell_t ret = close(*sp); *sp = ret ? errno : 0; return sp; } else if (op == STR_getChipModel) { *++sp = (cell_t) "FAKE-ESP32"; return sp; } else if (op == STR_getCpuFreqMHz) { *++sp = 240; return sp; } else if (op == STR_getChipCores) { *++sp = 2; return sp; } else if (op == STR_getFlashChipSize) { *++sp = 4 * 1024 * 1024; return sp; } else if (op == STR_getFreeHeap) { *++sp = 90000; return sp; } else if (op == STR_getHeapSize) { *++sp = 320 * 1024; return sp; } else if (op == STR_getMaxAllocHeap) { *++sp = 80 * 1024; return sp; } else if (op == STR_IS_XTENSA) { *++sp = -1; return sp; } else if (op == STR_IS_RISCV) { *++sp = -1; return sp; } else { fprintf(stderr, "MISSING SIM OPCODE: %s\n", op); exit(1); return sp; } } int main(int argc, char *argv[]) { setup(); for (;;) { loop(); } }