Sprinter: добавить отладку C-исходников и интеграцию VS Code

This commit is contained in:
2026-09-15 17:58:41 +03:00
parent 50c6e56b7b
commit e4695b8281
62 changed files with 7147 additions and 27 deletions
+65 -10
View File
@@ -65,6 +65,8 @@
# --max-allocs N SDCC --max-allocs-per-node (default: 100000 — smaller/
# faster code at the cost of compile time; pass a lower
# value, e.g. SDCC's own default 3000, to compile faster).
# --src-debug карта C/asm для всех пользовательских модулей
# --src-debug-file FILE карта выбранного TU (повторяемый, вместо --src-debug)
# --debug enable runtime diagnostics — defines DEBUG_RT for both
# sdcc (-DDEBUG_RT) and the crt0 assembly (prepended
# `DEBUG_RT = 1`). Exposes runtime introspection symbols
@@ -81,6 +83,18 @@
set -eo pipefail
# Можно выбрать интерпретатор без личного пути в репозитории.
SPRINTER_PYTHON="${SPRINTER_PYTHON:-python3}"
# Отладочная сборка публикуется транзакционно отдельным драйвером.
if [[ "${SPRINTER_SDBG_ACTIVE:-}" != 1 ]]; then
for arg in "$@"; do
if [[ "$arg" == --src-debug || "$arg" == --src-debug-file ]]; then
exec "$SPRINTER_PYTHON" "$(dirname "$0")/../toolchain/sdbg_driver.py" "$0" "$@"
fi
done
fi
# ------- Locate the toolchain ------------------------------------------------
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJ_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
@@ -109,6 +123,8 @@ LOAD_ADDR=""
ENTRY_ADDR=""
STACK_ADDR="0xBFFE"
STACK_SIZE="" # if set, used to compute HEAP_TOP = STACK_ADDR + 1 - STACK_SIZE
SRC_DEBUG=0
SRC_DEBUG_FILES=()
DEBUG_RT=0 # if 1, prepend `DEBUG_RT = 1` to crt0 + pass -DDEBUG_RT to sdcc
VERBOSE=0
USER_INCS=()
@@ -135,6 +151,7 @@ SAFE_LIBS=0 # if 1, prefer *_safe.lib variants (fallback to standard)
# ------- Parse args ----------------------------------------------------------
usage() {
sed -n '3,28p' "$0" | sed 's/^# \{0,1\}//'
echo ' --src-debug / --src-debug-file FILE: карта исходников C и asm'
exit "${1:-0}"
}
@@ -166,6 +183,10 @@ while [[ $# -gt 0 ]]; do
--mkexe) MKEXE_EXTRA+=("$2"); shift 2;;
--max-allocs) MAX_ALLOCS="$2"; shift 2;;
--gfx) GFX_MODE="$2"; shift 2;;
--src-debug) SRC_DEBUG=1; shift;;
--src-debug-file)
[[ $# -ge 2 ]] || { echo "--src-debug-file требует FILE" >&2; exit 1; }
SRC_DEBUG_FILES+=("$2"); shift 2;;
--debug) DEBUG_RT=1; shift;;
--safe) SAFE_LIBS=1; shift;;
-v) VERBOSE=1; shift;;
@@ -415,14 +436,44 @@ else
fi
run "$SDASZ80" -o "$HEAP_TOP_REL" "$HEAP_TOP_SRC"
# Единый путь компиляции выбранных C-модулей с картой исходников.
compile_c() {
local src="$1" rel="$2" selected=$SRC_DEBUG candidate
shift 2
for candidate in "${SRC_DEBUG_FILES[@]}"; do
[[ "$src" -ef "$candidate" ]] && selected=1
done
if [[ $selected -eq 1 ]]; then
run "$SPRINTER_PYTHON" "$PROJ_ROOT/toolchain/sdbg_build.py" compile \
--sdcc "$SDCC" --assembler "$SDASZ80" --source "$src" --output "$rel" \
-- "${CC_FLAGS[@]}" "$@"
elif [[ "${SPRINTER_SDBG_ACTIVE:-}" == 1 ]]; then
run "$SPRINTER_PYTHON" "$PROJ_ROOT/toolchain/sdbg_build.py" compile --plain \
--sdcc "$SDCC" --assembler "$SDASZ80" --source "$src" --output "$rel" \
-- "${CC_FLAGS[@]}" "$@"
else
run "$SDCC" "${CC_FLAGS[@]}" "$@" -c -o "$rel" "$src"
fi
}
# Уникальные имена объектов в debug-пакете допускают одинаковые basename.
object_path() {
local prefix="$1" src="$2"
if [[ "${SPRINTER_SDBG_ACTIVE:-}" == 1 ]]; then
"$SPRINTER_PYTHON" -c 'import hashlib, pathlib, sys; p=pathlib.Path(sys.argv[3]); print(sys.argv[1]+"/"+sys.argv[2]+p.stem+"_"+hashlib.sha256(str(p.resolve()).encode()).hexdigest()[:12]+".rel")' "$WORK" "$prefix" "$src"
else
echo "$WORK/$prefix$(basename "$src" .c).rel"
fi
}
# 2. user sources → .rel (HOME)
USER_RELS=()
CC_FLAGS=(-mz80 --no-std-crt0 --std-c99 --opt-code-size -I "$INC_DIR" -I "$BGI_INC_DIR" "${USER_INCS[@]}" "${USER_DEFS[@]}")
[[ $DEBUG_RT -eq 1 ]] && CC_FLAGS+=(-DDEBUG_RT)
[[ -n "$MAX_ALLOCS" ]] && CC_FLAGS+=(--max-allocs-per-node "$MAX_ALLOCS")
for src in "${SOURCES[@]}"; do
rel="$WORK/$(basename "$src" .c).rel"
run "$SDCC" "${CC_FLAGS[@]}" -c -o "$rel" "$src"
rel=$(object_path "" "$src")
compile_c "$src" "$rel"
USER_RELS+=("$rel")
done
@@ -431,9 +482,8 @@ done
# остаются в обычном _DATA (W2). Прямые вызовы, без трамплинов.
if [[ ${#W3_SPECS[@]} -gt 0 ]]; then
for src in "${W3_SPECS[@]}"; do
rel="$WORK/w3_$(basename "$src" .c).rel"
run "$SDCC" "${CC_FLAGS[@]}" --codeseg W3CODE --constseg W3CODE \
-c -o "$rel" "$src"
rel=$(object_path "w3_" "$src")
compile_c "$src" "$rel" --codeseg W3CODE --constseg W3CODE
W3_RELS+=("$rel")
done
W3_LD_FLAGS+=("-Wl-b_W3CODE=0xC000")
@@ -469,7 +519,7 @@ if [[ "$CRT0_TYPE" == "banked" ]]; then
for spec in "${BANK_SPECS[@]}"; do
bank_n="${spec%%=*}"
bank_src="${spec#*=}"
rel="$WORK/bank${bank_n}_$(basename "$bank_src" .c).rel"
rel=$(object_path "bank${bank_n}_" "$bank_src")
# По умолчанию --dataseg НЕ задаём: писучие данные банкового
# модуля (глобалы, file-static, статики функций) остаются в
# общем _DATA, то есть в W1/W2 — они замаплены всегда и видны
@@ -484,10 +534,9 @@ if [[ "$CRT0_TYPE" == "banked" ]]; then
[[ "$bl" == "$bank_n" ]] && bank_local=1
done
[[ $bank_local -eq 1 ]] && bank_data_flags=(--dataseg "BANK${bank_n}")
run "$SDCC" "${CC_FLAGS[@]}" \
compile_c "$bank_src" "$rel" \
--codeseg "BANK${bank_n}" --constseg "BANK${bank_n}" \
"${bank_data_flags[@]}" \
-c -o "$rel" "$bank_src"
"${bank_data_flags[@]}"
BANK_RELS+=("$rel")
# Virtual address: bank_n in upper byte, BANK_LOW16 in low half.
addr=$(printf "0x%X" $(( (bank_n << 16) | BANK_LOW16 )))
@@ -500,6 +549,7 @@ fi
IHX="$WORK/$(basename "$OUT" .exe).ihx"
LINK_FLAGS=(-mz80 --no-std-crt0 --std-c99 --opt-code-size
--code-loc "$CODE_LOC" --data-loc "$DATA_LOC")
[[ "${SPRINTER_SDBG_ACTIVE:-}" == 1 ]] && LINK_FLAGS+=(--debug)
LINK_FLAGS+=("${BANK_LD_FLAGS[@]}")
LINK_FLAGS+=("${W3_LD_FLAGS[@]}")
for f in "${LD_EXTRA[@]}"; do LINK_FLAGS+=("$f"); done
@@ -529,7 +579,7 @@ fi
# Отчёт по раскладке памяти + проверка лимитов — для ЛЮБОЙ модели памяти
# (сколько свободно в W1/W2, W3 при --w3, и в каждом банке при --bank).
if [[ -f "${IHX%.ihx}.map" ]]; then
python3 "$CHECK_BANKS" "${IHX%.ihx}.map" \
"$SPRINTER_PYTHON" "$CHECK_BANKS" "${IHX%.ihx}.map" \
--mode "$MEMORY_MODE" --heap-top "$HEAP_TOP_VAL" --stack "$STACK_ADDR" || true
fi
@@ -544,4 +594,9 @@ MK_PREFIX+=("${MKEXE_EXTRA[@]}")
MK_PREFIX+=(-L "$LOAD_ADDR" -E "$ENTRY_ADDR" -S "$STACK_ADDR" -o "$OUT")
run "$MKEXE" "${MK_PREFIX[@]}" "$IHX"
if [[ "${SPRINTER_SDBG_ACTIVE:-}" == 1 ]]; then
"$SPRINTER_PYTHON" "$PROJ_ROOT/toolchain/sdbg_driver.py" --metadata "$WORK" \
"$OUT" "$MEMORY_MODE" "$CODE_LOC" "$DATA_LOC" "$LOAD_ADDR" "$ENTRY_ADDR" "$STACK_ADDR"
fi
echo "sprinter-cc: wrote $OUT"