# 技術オリエンテーション — システム全体像とエントリポイント

> リポジトリの目的（RP2040/RP2350 向け BASIC コンパイラファームウェア）、2 つのファームウェアバリアント（phyllosoma / puerulus）、主要モジュールの責務、ビルド成果物 (.uf2) の種類、および開発者がこの Wiki を読み進める順序を解説します。

- Repository: machikania/phyllosoma
- GitHub: https://github.com/machikania/phyllosoma
- Human wiki: https://grok-wiki.com/public/wiki/machikania-phyllosoma-fab169c4381c
- Complete Markdown: https://grok-wiki.com/public/wiki/machikania-phyllosoma-fab169c4381c/llms-full.txt

## Source Files

- `README.md`
- `CMakeLists.txt`
- `config.cmake`
- `main.c`
- `compiler.h`

---

<details>
<summary>関連するソースファイル</summary>
このWikiページの生成に使用したファイル:

- [README.md](README.md)
- [CMakeLists.txt](CMakeLists.txt)
- [config.cmake](config.cmake)
- [config.h](config.h)
- [main.c](main.c)
- [compiler.h](compiler.h)
- [compiler.c](compiler.c)
- [run.c](run.c)
- [globalvars.c](globalvars.c)
- [withkeyboard.c](withkeyboard.c)
- [withoutkeyboard.c](withoutkeyboard.c)
- [memmap_machikania.ld](memmap_machikania.ld)
- [config/pico_ili9341.h](config/pico_ili9341.h)
- [interface/](interface/)
</details>

# 技術オリエンテーション — システム全体像とエントリポイント

このページは **machikania/phyllosoma** リポジトリを初めて読む開発者向けに、プロジェクト全体の目的・構造・ビルド設計・実行モデルを解説します。どのファイルが何を担い、`.uf2` バイナリがどのような組み合わせで生成されるかを把握することで、以降の詳細な Wiki ページを効率よく読み進められるようになります。

## リポジトリの目的

このリポジトリは **KM-BASIC for ARM** の実装であり、Raspberry Pi Pico (RP2040) および Pico 2 (RP2350) 上で動作する BASIC コンパイラファームウェアを提供します。「コンパイラ」は PC 上で動くクロスコンパイラではなく、**マイコン本体上で BASIC ソースコードを ARM Thumb 機械語に変換して即実行するオンデバイスコンパイラ**です。BASIC プログラムは microSD カード (MMC/SPI) から読み込まれ、コンパイル後すぐに `kmbasic_object[]` 領域に書き込まれた Thumb コードとして実行されます。

ライセンスは LGPL 2.1（一部のファイルはそれ以外）。作者は Katsumi (kmorimatsu) および Kenken (kenkenMkIISR)。

Sources: [README.md](README.md)（冒頭の各バリアント説明）、[compiler.c:1-8](compiler.c)（ライセンスヘッダ）

---

## 2 つのファームウェアバリアント

リポジトリは単一のソースツリーから **2 種類のファームウェア名** を生成します。どちらが生成されるかは `config.cmake` の `MACHIKANIA_BUILD` 変数で決まります。

| バリアント名 | 型番称 | 映像出力 | 対象ボード例 | `MACHIKANIA_BUILD` 値 |
|---|---|---|---|---|
| **phyllosoma** | MachiKania type P | SPI 接続 LCD (ILI9341 / ILI9488 / ST7789 等) | Raspberry Pi Pico, Pico W, Pico 2, YD-RP2040 | `pico_ili9341`, `pico_ili9488`, `pico_st7789`, `pico_restouch`, `pico_picocalc`, `rp2350_lcd_1_47` |
| **puerulus** | MachiKania type PU | NTSC コンポジットビデオ | Raspberry Pi Pico, Pico W, XIAO RP2040, Tiny 2040, RP2040-Zero | `pico_ntsc`, `xiao_ntsc` |

`config.cmake` の末尾近くで、`MACHIKANIA_BUILD` が `pico_ntsc` または `xiao_ntsc` の場合に `MACHIKANIA_CODE_NAME=puerulus` が設定され、それ以外では `MACHIKANIA_CODE_NAME=phyllosoma` になります。`CMakeLists.txt` はこの変数をプロジェクト名・実行ファイル名・プリプロセッサマクロ (`MACHIKANIA_PHYLLOSOMA` / `MACHIKANIA_PUERULUS`) に使います。

Sources: [config.cmake:73-88](config.cmake)（`MACHIKANIA_CODE_NAME` の選択ロジック）、[CMakeLists.txt:164-170](CMakeLists.txt)（コンパイル定義の付与）

---

## ビルド成果物 (.uf2) の種類

各バリアントにつき **2 つの `.uf2`** が生成されます。

```text
phyllosoma_kb.uf2  ─── USB キーボード直結モード (USB HID ホスト)
phyllosoma.uf2     ─── USB シリアル接続モード  (PC との REPL/ファイル転送)

puerulus_kb.uf2    ─── USB キーボード直結モード
puerulus.uf2       ─── USB シリアル接続モード
```

`_kb` 版は `withkeyboard.c` と `interface/usbkeyboard.c` を含み、USB を HID ホストとして初期化します。無印版は `withoutkeyboard.c` と `pcconnect.c` を含み、USB CDC シリアルとして PC に接続します。`CMakeLists.txt` でこの切り替えを明示しています。

```cmake
# _kb.uf2: キーボード版
add_executable(${MACHIKANIA_CODE_NAME}_kb
    ${MACHIKANIA_EDITOR}.c          # editor.c または editor_ntsc.c
    interface/${MACHIKANIA_KEYBOARD}.c  # usbkeyboard.c / picocalc_keyboard.c
    ...
    withkeyboard.c
)

# .uf2: シリアル版
add_executable(${MACHIKANIA_CODE_NAME}
    withoutkeyboard.c
    pcconnect.c
)
```

Sources: [CMakeLists.txt:95-120](CMakeLists.txt)（2 つの `add_executable`）、[withkeyboard.c:19-28](withkeyboard.c)、[withoutkeyboard.c:19-28](withoutkeyboard.c)（排他的コンパイルのコメント）

---

## システムアーキテクチャ図

```text
┌─────────────────────────────────────────────────────────┐
│                    ファームウェア全体                        │
│                                                           │
│  ┌──────────────┐  ┌──────────────────────────────────┐  │
│  │  入力 / I/O   │  │          shared_files ライブラリ   │  │
│  │              │  │                                  │  │
│  │ withkeyboard │  │  main.c  ──► compiler.c          │  │
│  │   または      │  │               ├─ statements.c    │  │
│  │withoutkeyboard│  │               ├─ functions.c     │  │
│  │ + pcconnect  │  │               ├─ integer.c       │  │
│  └──────────────┘  │               ├─ float.c         │  │
│                    │               ├─ string.c        │  │
│  ┌──────────────┐  │               ├─ value.c         │  │
│  │ video_files  │  │               ├─ operators.c     │  │
│  │              │  │               └─ cmpdata.c       │  │
│  │ graphlib_lcd │  │          run.c  (ARM asm BX)     │  │
│  │  または       │  │          memory.c / class.c      │  │
│  │graphlib_ntsc │  │          file.c (FatFS)          │  │
│  │ + LCD/NTSC   │  │          display.c / io.c        │  │
│  │   driver     │  │          timer.c / music.c       │  │
│  └──────────────┘  │          rtc.c / hexfile.c       │  │
│                    └──────────────────────────────────┘  │
│  ┌──────────────┐  ┌──────────────────────────────────┐  │
│  │  wifi_files  │  │          aux_files               │  │
│  │ withwifi.c   │  │       auxcode/auxcode.c           │  │
│  │  (Pico W のみ)│  │                                  │  │
│  └──────────────┘  └──────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
         ▲                        ▲
    ハードウェア              microSD (FatFS)
  (LCD/NTSC/GPIO/               BASIC ソース
   SPI/I2C/USB)                 クラスファイル
```

---

## 主要モジュールの責務

### コア — コンパイル・実行パイプライン

| ファイル | 責務 |
|---|---|
| `main.c` | エントリポイント。初期化シーケンス全体を制御し、`compile_file()` → `run_code()` を呼び出す |
| `compiler.c` | `init_compiler()` / `compile_line()` 等。BASIC ソースを ARM Thumb オブジェクトコードに変換する中核 |
| `run.c` | `run_code()` / `call_interrupt_function()`。インライン ASM で ARM レジスタ (R5/R6/R7/R8) をセットし `bx r1` でコンパイル済みコードへジャンプ |
| `globalvars.c` | `kmbasic_object[]`・`kmbasic_variables[]`・バッファなど全グローバル変数の実体定義 |
| `compiler.h` | エラーコード・ライブラリ番号 (LIB_*)・CMPDATA 型・全モジュールのプロトタイプ宣言。リポジトリ共通の「単一インクルード」ヘッダ |

### 言語要素のコンパイル

| ファイル | 責務 |
|---|---|
| `statements.c` | `GOTO` / `GOSUB` / `IF` / `FOR` 等のステートメント |
| `functions.c` | 組み込み関数のコンパイル (`argn_function` 等) |
| `integer.c` | 整数リテラル・式のコンパイル |
| `float.c` | 浮動小数点式のコンパイル |
| `string.c` | 文字列式のコンパイル |
| `value.c` | 汎用値取得 (`get_value()`) |
| `operators.c` | 演算子優先度・計算コード生成 |
| `cmpdata.c` | コンパイル時中間データ（ラベル、変数名、クラス情報）の管理 |
| `variable.c` | 変数番号の割り当て・参照 |

### ランタイムサポート

| ファイル | 責務 |
|---|---|
| `memory.c` | `alloc_memory()` / `garbage_collection()` — ALLOC_BLOCK_NUM (256) ブロック単位のヒープ |
| `class.c` | クラス定義・フィールド・メソッド・`NEW` / `DELETE` |
| `library.c` | `kmbasic_library()` — 実行時ライブラリディスパッチャ (LIB_* 番号で分岐) |
| `error.c` | コンパイル・実行時エラー表示 |

### ペリフェラル・インタフェース

| ファイル / ディレクトリ | 責務 |
|---|---|
| `file.c` + `interface/ff.c` | FatFS ラッパー。microSD からの BASIC / クラスファイル読み込み |
| `display.c` + `interface/graphlib_*.c` | LCD / NTSC の抽象表示レイヤ |
| `io.c` | GPIO / SPI / I2C / UART / ボタン / ADC / PWM |
| `timer.c` | タイマー割り込み・コアタイマー・フレームカウント |
| `music.c` | PWM 音楽・WAV 再生 |
| `rtc.c` | RTC (AON タイマー) |
| `wifi/` | Pico W 向け TCP/TLS/NTP クライアント・サーバ (lwIP + mbedTLS) |
| `hexfile.c` | `.HEX` バイナリの直接実行 |
| `interface/*.c` | LCD ドライバ (ILI9341/ILI9488/ST7789/NTSC)、USB キーボード HID、フォントデータ、FatFS 低レベル (pico-sdmm.c)、ファイル選択 UI |

### 入力モード切替

| ファイル | 定数 `g_active_usb_keyboard` | 動作 |
|---|---|---|
| `withoutkeyboard.c` | `0` | USB CDC シリアルで PC 接続。`connect2pc()` 呼び出し |
| `withkeyboard.c` | `1` | USB HID ホストとしてキーボードをポーリング。`usbkb_init()` + `start_core1()` |

---

## エントリポイントの制御フロー

`main()` は以下の順序で処理を行います。

```c
// main.c — main() の要点（簡略）
io_init();          // GPIO / SPI / ADC 初期化
timer_init();       // タイマー初期化
stdio_init_all();   // USB/UART stdio
display_init();     // LCD または NTSC 初期化
init_file_system(); // FatFS マウント
read_ini();         // MACHIKAP.INI 解析
connect_wifi(1);    // Pico W のみ Wi-Fi 接続
post_inifile();     // キーボード or PC 接続確立
str = fileselect(); // ファイル選択 (または AUTOEXEC=)
init_compiler();    // コンパイラ初期化
compile_file(str, 0); // BASIC → ARM Thumb
post_compile();     // クラスのリンク
run_code();         // コンパイル済みコードを実行
// 終了後: RESETATEND 設定により software_reset() または無限ループ
```

実行後の「無限ループ」では START キーを押すと `software_reset()` が呼ばれ、`0xe000ed0c` (AIRCR) に `0x05FA0004` を書き込んでリセットします。

Sources: [main.c:94-160](main.c)（`main()` 関数全体）

---

## メモリレイアウト

カスタムリンカスクリプト `memmap_machikania.ld` で、コンパイル済み BASIC オブジェクトコードを格納する `kmbasic_object[]` を RAM 先頭 (`0x20000000`) に固定配置しています。

```
FLASH  0x10000000 (2 MB): ファームウェアコード・定数
RAM    0x20000000 (256 KB):
       0x20000000  .kmbasicobject_section  ← kmbasic_object[] (BASIC Thumb コード)
       ...         .data / .bss
SCRATCH_X/Y  (4 KB 各): Pico SDK スクラッチバッファ
```

RP2350 (Pico 2) 向けには別のリンカスクリプト `memmap_machikania_pico2.ld` が使われます (`CMakeLists.txt:143-148`)。

Sources: [memmap_machikania.ld:24-41](memmap_machikania.ld)（`MEMORY` / `.kmbasicobject_section` 定義）、[globalvars.c:19-21](globalvars.c)（`kmbasic_object[]` の `section` 属性宣言）

---

## ビルド設定のガイド

`config.cmake` の `MACHIKANIA_BUILD` を変更するだけで、グラフィックライブラリ・キーボードライブラリ・モニタライブラリ・ファームウェア名が一括で切り替わります。

```cmake
# 例: ILI9341 LCD (デフォルト) → phyllosoma
set(MACHIKANIA_BUILD pico_ili9341)

# 例: NTSC ビデオ出力 → puerulus
#set(MACHIKANIA_BUILD pico_ntsc)
```

Pico W / Pico 2 / Pico 2 W を対象にする場合は cmake 実行時に `-DPICO_BOARD` と `-DPICO_PLATFORM` を追加します。`PICO_BOARD=pico_w` 等が検出されると `MACHIKANIA_WIFI=withwifi` が自動設定され、`wifi/withwifi.c` 等が `wifi_files` ライブラリに含まれます。

Sources: [config.cmake:1-31](config.cmake)（ビルドターゲット一覧と選択方法）、[config.cmake:88-103](config.cmake)（Wi-Fi の自動有効化）

---

## Wiki 読み進めの推奨順序

1. **本ページ**（システム全体像）— 完了
2. **コンパイルパイプライン詳解** — `compiler.c` / `cmpdata.c` / `statements.c` を中心に BASIC → Thumb 変換の仕組みを解説
3. **実行モデルとライブラリディスパッチ** — `run.c` のアセンブリコンテキスト・`library.c` の `kmbasic_library()` ディスパッチ構造
4. **グラフィック・映像サブシステム** — `interface/graphlib_lcd.c` / `rp2040_pwm_ntsc_textgraph.c` / LCD ドライバ
5. **ペリフェラル API** — `io.c` / `timer.c` / `music.c` / `wifi/`
6. **クラスシステムとメモリ管理** — `class.c` / `memory.c`
7. **ビルド設定リファレンス** — `config/` 配下の各 `.h` ファイル

---

## まとめ

phyllosoma リポジトリは、RP2040/RP2350 マイコン上で自己完結するオンデバイス BASIC コンパイラ・実行環境です。`config.cmake` の `MACHIKANIA_BUILD` 変数が **phyllosoma (LCD)** と **puerulus (NTSC)** の分岐点であり、各バリアントについてさらに **USB シリアル版** と **USB キーボード版** の計 4 種の `.uf2` が生成されます。`main()` が初期化・INI 解析・ファイル選択・コンパイル・実行の全フェーズを順番に担い、コンパイル済み ARM Thumb コードは `run.c` のインラインアセンブリによって直接ジャンプ実行されます。

Sources: [CMakeLists.txt:130-170](CMakeLists.txt)（ライブラリ構成・コンパイル定義の全体像）
