Adding initial pico-ice support.

This commit is contained in:
Brad Nelson
2023-12-03 19:57:14 -08:00
parent fa56ecf59d
commit c40a2f5c6f
12 changed files with 422 additions and 3 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "pico-ice/pico-sdk"]
path = pico-ice/pico-sdk
url = https://github.com/raspberrypi/pico-sdk
[submodule "pico-ice/pico-ice-sdk"]
path = pico-ice/pico-ice-sdk
url = https://github.com/tinyvision-ai-inc/pico-ice-sdk

View File

@ -26,6 +26,8 @@ POSIX = $(OUT)/posix
WINDOWS = $(OUT)/windows
ESP32 = $(OUT)/esp32
ESP32_SIM = $(OUT)/esp32-sim
PICO_ICE = $(OUT)/pico-ice
PICO_ICE_SIM = $(OUT)/pico-ice-sim
DEPLOY = $(OUT)/deploy
OS = $(shell uname -s)
@ -238,9 +240,9 @@ COMMON_PHASE1 = common/comments.fs \
common/structures.fs
COMMON_PHASE1e = common/comments.fs \
common/tier2a_forth.fs \
common/tier2a_forth.fs \
common/boot.fs \
common/tier2b_forth.fs \
common/tier2b_forth.fs \
common/io.fs \
common/conditionals.fs \
common/vocabulary.fs \
@ -287,6 +289,16 @@ WINDOWS_BOOT = $(COMMON_PHASE1) \
$(GEN)/windows_boot.h: tools/source_to_string.js $(WINDOWS_BOOT) | $(GEN)
$< -win boot $(VERSION) $(REVISION) $(WINDOWS_BOOT) >$@
PICO_ICE_BOOT = $(COMMON_PHASE1) \
pico-ice/allocation.fs \
$(COMMON_PHASE2) \
common/tasks.fs common/streams.fs \
pico-ice/platform.fs \
pico-ice/autoboot.fs \
common/fini.fs
$(GEN)/pico_ice_boot.h: tools/source_to_string.js $(PICO_ICE_BOOT) | $(GEN)
$< boot $(VERSION) $(REVISION) $(PICO_ICE_BOOT) >$@
ESP32_BOOT = $(COMMON_PHASE1) \
esp32/allocation.fs esp32/bindings.fs \
$(COMMON_PHASE2) $(COMMON_FILETOOLS) \
@ -793,6 +805,53 @@ CHIP_esp32cam=esp32
%-build: $(ESP32)/%_build/ESP32forth.ino.bin
echo "done"
# ---- PICO-ICE ----
pico-ice: $(PICO_ICE)/ueforth_pico_ice.uf2
$(PICO_ICE)/ueforth_pico_ice.uf2: \
$(PICO_ICE)/Makefile \
pico-ice/main.c \
pico-ice/builtins.h \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/floats.h \
common/calls.h \
common/calling.h \
common/floats.h \
common/bits.h \
common/core.h \
common/interp.h \
$(GEN)/pico_ice_boot.h
make -C $(PICO_ICE) VERBOSE=1
$(PICO_ICE)/Makefile:
cmake $(PICO_ICE) -S pico-ice -B $(PICO_ICE)
# ---- PICO-ICE-SIM ----
pico-ice-sim: $(PICO_ICE_SIM)/ueforth_pico_ice_sim
$(PICO_ICE_SIM):
mkdir -p $@
$(PICO_ICE_SIM)/ueforth_pico_ice_sim: \
pico-ice/main.c \
pico-ice/builtins.h \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/floats.h \
common/calls.h \
common/calling.h \
common/floats.h \
common/bits.h \
common/core.h \
common/interp.h \
$(GEN)/pico_ice_boot.h | $(PICO_ICE_SIM)
$(CXX) $(CFLAGS) -DUEFORTH_SIM=1 $< -o $@
# ---- PACKAGE ----
$(ESP32)/ESP32forth.zip: \

View File

@ -16,4 +16,3 @@
: allocate ( n -- a ior ) malloc dup 0= ;
: free ( a -- ior ) sysfree 0 ;
: resize ( a n -- a ior ) realloc dup 0= ;

43
pico-ice/CMakeLists.txt Normal file
View File

@ -0,0 +1,43 @@
# Copyright 2024 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.
cmake_minimum_required(VERSION 3.13)
# import the pico-sdk
set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/)
include(pico_sdk_import.cmake)
# configure the pico-sdk project
project(ueforth_pico_ice C CXX ASM)
pico_sdk_init()
# add the pico-ice-sdk
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk)
add_executable(${CMAKE_PROJECT_NAME} main.c)
target_link_libraries(${CMAKE_PROJECT_NAME}
pico_ice_sdk
pico_stdio_usb
)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_SOURCE_DIR}/../out/
)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0)
pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0)

18
pico-ice/allocation.fs Normal file
View File

@ -0,0 +1,18 @@
\ Copyright 2023 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.
( Words with OS assist )
: allocate ( n -- a ior ) malloc dup 0= ;
: free ( a -- ior ) sysfree 0 ;
: resize ( a n -- a ior ) realloc dup 0= ;

16
pico-ice/autoboot.fs Normal file
View File

@ -0,0 +1,16 @@
\ Copyright 2023 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.
( TODO: Add autoboot support. )
' ok

91
pico-ice/builtins.h Normal file
View File

@ -0,0 +1,91 @@
// Copyright 2023 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 <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef UEFORTH_SIM
# include "pico/time.h"
#endif
// TODO: Implement RESIZE-FILE.
// TODO: Implement FLUSH-FILE.
#define PLATFORM_OPCODE_LIST \
REQUIRED_MEMORY_SUPPORT \
REQUIRED_SYSTEM_SUPPORT \
REQUIRED_FILES_SUPPORT \
CALLING_OPCODE_LIST \
FLOATING_POINT_LIST
#define REQUIRED_MEMORY_SUPPORT \
YV(internals, MALLOC, SET malloc(n0)) \
YV(internals, SYSFREE, free(a0); DROP) \
YV(internals, REALLOC, SET realloc(a1, n0); NIP)
#ifndef UEFORTH_SIM
# define REQUIRED_SYSTEM_SUPPORT \
X("MS-TICKS", MS_TICKS, PUSH us_to_ms(get_absolute_time())) \
XV(internals, "RAW-YIELD", RAW_YIELD, tud_task()) \
XV(internals, "RAW-TERMINATE", RAW_TERMINATE, exit(n0); DROP) \
YV(internals, getchar_timeout_us, n0 = getchar_timeout_us(n0))
#else
# define REQUIRED_SYSTEM_SUPPORT \
X("MS-TICKS", MS_TICKS, PUSH (time(0) * 1000)) \
XV(internals, "RAW-YIELD", RAW_YIELD, sleep(0)) \
XV(internals, "RAW-TERMINATE", RAW_TERMINATE, exit(n0); DROP) \
YV(internals, getchar_timeout_us, DROP; PUSH fgetc(stdin))
#endif
#define REQUIRED_FILES_SUPPORT \
X("R/O", R_O, PUSH O_RDONLY) \
X("W/O", W_O, PUSH O_WRONLY) \
X("R/W", R_W, PUSH O_RDWR) \
Y(BIN, ) \
X("CLOSE-FILE", CLOSE_FILE, tos = close(tos); tos = tos ? errno : 0) \
X("OPEN-FILE", OPEN_FILE, cell_t mode = n0; DROP; cell_t len = n0; DROP; \
memcpy(filename, a0, len); filename[len] = 0; \
n0 = open(filename, mode, 0777); PUSH n0 < 0 ? errno : 0) \
X("CREATE-FILE", CREATE_FILE, cell_t mode = n0; DROP; cell_t len = n0; DROP; \
memcpy(filename, a0, len); filename[len] = 0; \
n0 = open(filename, mode | O_CREAT | O_TRUNC); PUSH n0 < 0 ? errno : 0) \
X("DELETE-FILE", DELETE_FILE, cell_t len = n0; DROP; \
memcpy(filename, a0, len); filename[len] = 0; \
n0 = unlink(filename); n0 = n0 ? errno : 0) \
X("RENAME-FILE", RENAME_FILE, \
cell_t len = n0; DROP; memcpy(filename, a0, len); filename[len] = 0; DROP; \
cell_t len2 = n0; DROP; memcpy(filename2, a0, len2); filename2[len2] = 0; \
n0 = rename(filename2, filename); n0 = n0 ? errno : 0) \
X("WRITE-FILE", WRITE_FILE, cell_t fd = n0; DROP; cell_t len = n0; DROP; \
n0 = write(fd, a0, len); n0 = n0 != len ? errno : 0) \
X("READ-FILE", READ_FILE, cell_t fd = n0; DROP; cell_t len = n0; DROP; \
n0 = read(fd, a0, len); PUSH n0 < 0 ? errno : 0) \
X("FILE-POSITION", FILE_POSITION, \
n0 = (cell_t) lseek(n0, 0, SEEK_CUR); PUSH n0 < 0 ? errno : 0) \
X("REPOSITION-FILE", REPOSITION_FILE, cell_t fd = n0; DROP; \
n0 = (cell_t) lseek(fd, tos, SEEK_SET); n0 = n0 < 0 ? errno : 0) \
X("FILE-SIZE", FILE_SIZE, struct stat st; w = fstat(n0, &st); \
n0 = (cell_t) st.st_size; PUSH w < 0 ? errno : 0) \
X("NON-BLOCK", NON_BLOCK, n0 = fcntl(n0, F_SETFL, O_NONBLOCK); \
n0 = n0 < 0 ? errno : 0)
#define VOCABULARY_LIST V(forth) V(internals)
#define PATH_MAX 256
static char filename[PATH_MAX];
static char filename2[PATH_MAX];

62
pico-ice/main.c Normal file
View File

@ -0,0 +1,62 @@
// Copyright 2023 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 <stdio.h>
#ifndef UEFORTH_SIM
# include "pico/stdlib.h"
# include "boards/pico_ice.h"
# include "tusb.h"
#else
# include <time.h>
#endif
#include "common/tier0_opcodes.h"
#include "common/tier1_opcodes.h"
#include "common/tier2_opcodes.h"
#include "common/floats.h"
#include "common/calls.h"
#ifndef UEFORTH_SIM
# define HEAP_SIZE (100 * 1024)
#else
# define HEAP_SIZE (200 * 1024)
#endif
#define STACK_CELLS (4 * 1024)
#include "pico-ice/builtins.h"
// TODO: Implement faults.
#define FAULT_ENTRY
static void forth_faults_setup(void) {
}
#include "common/bits.h"
#include "common/core.h"
#include "common/calling.h"
#include "common/interp.h"
#include "gen/pico_ice_boot.h"
int main(int argc, char *argv[]) {
#ifndef UEFORTH_SIM
tusb_init();
stdio_init_all();
tud_task();
#endif
void *heap = malloc(HEAP_SIZE);
forth_init(argc, argv, heap, HEAP_SIZE, boot, sizeof(boot));
for (;;) { g_sys->rp = forth_run(g_sys->rp); }
return 1;
}

1
pico-ice/pico-ice-sdk Submodule

Submodule pico-ice/pico-ice-sdk added at dfc0efeb73

1
pico-ice/pico-sdk Submodule

Submodule pico-ice/pico-sdk added at 6a7db34ff6

View File

@ -0,0 +1,73 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})

50
pico-ice/platform.fs Normal file
View File

@ -0,0 +1,50 @@
\ Copyright 2023 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.
( Add a yielding task so pause yields )
internals definitions
: yield-step raw-yield yield ;
' yield-step 100 100 task yield-task
yield-task start-task
forth definitions
( Initial file handles )
0 constant stdin
1 constant stdout
2 constant stderr
( Set up Basic I/O )
also internals definitions
: setup-saving-base ; ( TODO: implement. )
variable last-key -1 last-key !
forth definitions internals
: default-type ( a n -- ) stderr write-file throw ;
: default-key? ( -- f )
last-key @ 0< if 1000 getchar_timeout_us last-key ! then
last-key @ 0< 0=
;
: default-key ( -- ch )
begin default-key? 0= while pause repeat
last-key @ -1 last-key !
;
previous
' default-type is type
' default-key is key
' default-key? is key?
' raw-terminate is terminate
-1 echo !
( Setup entry )
internals : ok ." uEforth" raw-ok ; forth