新しい仲間 IchigoJam P をいじってみる

# IchigoJam P

先日、タンザニア (アフリカ) でプログラミング教育をすると謳うクラウドファンディングが行われた。
そこでの返礼品の一つとして、[IchigoJam](https://ichigojam.net/) の新型「IchigoJam P」を入手する機会があった。

* [アフリカの子ども達に継続的なプログラミング学習機会を提供したい！（NPO法人エル・コミュニティ 2024/06/10 公開） - クラウドファンディング READYFOR](https://readyfor.jp/projects/IchigoJam-tanzania)
* [IchigoJam P | PCN プログラミング クラブ ネットワーク](https://pcn.club/sp/ijp/)
* [IchigoJam P - SHIROのIchigoJam日記](https://www.ichigojaman.jp/entry/ichigojamp)

この記事では、そんな IchigoJam P の基本的な性質を見ていく。

※IchigoJamはjig.jpの登録商標です。

# 外観

届いたときのパッケージ。

![届いたときのパッケージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/2ca85ce0-2b43-a91d-d62d-4bb138cbf322.jpeg)

開封。

![パッケージを開けた様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/a4a4a63e-598c-c74b-cbdf-400ecc2df1f5.jpeg)

セット内容は、以下であった。

* 本体
* USB OTG ケーブル
* セットアップ方法が書かれた紙
* 命令のリファレンスが書かれた紙
* 緑色のビニールタイ

![セット内容](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/90de7eb2-9752-246e-8e60-0f16106b2112.jpeg)

本体を右から。
レギュレーター・水晶発振子・キーボード接続用のコネクタは独立したパーツとしては搭載せず、Raspberry Pi Pico に組み込まれているものを利用するようである。

![IchigoJam P 本体を右から見た写真](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/5ae81cf3-1ddc-f63c-e95b-7b394945d82b.jpeg)

本体を左から。

![IchigoJam P 本体を左から見た写真](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/5dabaf19-203a-922e-98c2-34d06b98bea6.jpeg)

本体を裏から。

![IchigoJam P 本体を裏から見た写真](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/d669f454-1897-612b-1ae5-1f4da481e42e.jpeg)

Raspberry Pi Pico を外した様子。
中央に配置されている抵抗は、映像出力関係のようである。

![Raspberry Pi Pico を外した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6b66d356-1e3b-5346-40f6-926ab214e7da.jpeg)

外した Raspberry Pi Pico の裏側。

![Raspberry Pi Pico の裏側](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/a314ded6-79cc-74a6-1fd8-a4a760e5df51.jpeg)

Raspberry Pi Pico を取り付け直し、横から見た様子。
Raspberry Pi Pico がピンソケットの面より上に飛び出ているため、一部の拡張ボードはそのまま接続できなくなる心配がある。

![IchigoJam P 本体を横から見た写真](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/21611eda-ab84-d47b-2cb2-c33774ee10e2.jpeg)

[PanCake](http://pancake.shizentai.jp/) および [MixJuice](http://mixjuice.shizentai.jp/) に関しては、奥まで挿してもぶつからず、支障はなさそうである。
![IchigoJam P に PanCake を接続した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/964eb283-1088-2174-8300-57a697d27ddb.jpeg)
![IchigoJam P に MixJuice を接続した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/692359dc-c7a4-c1e8-c2b5-b91624624a16.jpeg)

# 入出力

## 電源

電源入力用に、USB Type-C コネクタがある。
ただし、プルダウン抵抗が無く、チェックを行うタイプの機器・ポートからの (直接の) 給電はできないようである。
また、USB Type-C コネクタのプラス側と CN5 の 5V 端子は直結されており、この 5V 端子に USB-シリアル変換器などから 5V の電源を供給することでも、電源として利用できそうである。

![電源入力側](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/c2933d0d-921b-c0a4-c89c-ff1be47de61e.jpeg)

:::note warn
IchigoJam P の VCC や 3.3V の端子は、Raspberry Pi Pico の 3V3 端子に接続されている。
この 3V3 端子は電源**出力**であるため、VCC などに直接 3.3V の電源を繋ぐのは危険だと思われる。
:::

## モニター

モニターへは、側面に取り付けられた DVI-D コネクタを用いて接続できる。
コネクタ横のネジは省かれている。

![側面に取り付けられた DVI-D コネクタ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/600c3820-622f-0701-9c2f-9490bd1b85e2.jpeg)

:::note info
DVI-I ではなく DVI-D コネクタを用いているのは、[返礼品の特別仕様](https://readyfor.jp/projects/IchigoJam-tanzania/announcements/349552)のようである。
:::

以前中古屋で購入した変換ケーブルと、[Amazon で購入](https://www.amazon.co.jp/dp/B08L3F2818)した HDMI キャプチャーボードを用いることで、出力される映像をパソコンに取り込むことができた。

![用いた変換ケーブルと HDMI キャプチャーボード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/fb051e1e-23bf-fac5-63a9-590d3461c254.jpeg)

[ウェブカメラの解像度 | ウェブカメラテスト](https://ja.webcamtests.com/resolution)でテストを行ったところ、640×480 では画像が白黒ではっきりと表示されたが、認識されたその他の解像度では画像を拡大または縮小したかのような中間色がみられた。
よって、出力されている解像度は **640×480** であると推測できる。

## キーボード

付属の USB OTG ケーブルを用いて、USB キーボードを Raspberry Pi Pico の USB コネクタに接続する。
(市販のケーブルや、Micro-B に直接挿せるタイプのキーボードでも接続できるかもしれない)

![キーボードなどを接続した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/472b9a67-af92-0a27-80b3-37fdb89ad9d1.jpeg)

[IchigoJam R に関する諸々 #IchigoJam - Qiita](https://qiita.com/mikecat_mixc/items/6108adcd11b5b7a76abe#%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89)
で試した各種キーボードを接続し、動作を確認したところ、以下のようになった。

|キーボード|IchigoJam R (記事より)|IchigoJam P|
|---|:-:|:-:|
|YDKBU11BK (BUFFALO)|○|○|
|HC56TU (DENSO)|○|○|
|SKB-KG2BK (サンワサプライ)|×|○|
|AOK-184WH (アオテック)|×|○|
|ワンボタンキーボード (TOKYO FLIP-FLOP)|×|○|

IchigoJam R ではうまく動作しなかったキーボードを含め、今回試したキーボードでは全て不具合はみられなかった。
特に、単純なキーボードではなく USB Composite Device になっているワンボタンキーボードでも、問題なく草を生やすことができた。
ただし、USB ハブを経由しての接続には対応していないようである。

## ブザー

[SHIROのIchigoJam日記](https://www.ichigojaman.jp/entry/ichigojamp)でも指摘されている通り、デフォルトのビープ音がこれまでより高くなっている。

`BEEP` を実行し、オシロスコープで確認すると、約1560Hzのようである。(表示されている周波数は、10周期で測定しているため10分の1になっている)

![IchigoJam P のビープ音](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/c8b5504f-6fb2-81af-6405-0a8ccc2f7031.png)

比較対象として、IchigoJam Q (1.4.3) のビープ音は約787Hzである。

![IchigoJam Q のビープ音](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/46b7766b-18d6-cb44-9a74-0afc627cfa29.png)

また、IchigoJam R (1.5b) のビープ音は約800Hzである。

![IchigoJam Q のビープ音](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6f088fcc-60f8-d102-db26-0ea7ad4e9d3c.png)

IchigoJam P で `BEEP 20` を実行すると、IchigoJam Q と同じ約787Hzの出力が得られた。
したがって、「デフォルトのビープ音の周期が変更された」のではなく、「周期の指定に対応する周波数が変更された」のであると考えられる。

![IchigoJam P のビープ音 (周期20)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/f52f1beb-12b9-a2c9-74a2-9856c9ef3b23.png)

## 入出力ポート

:::note warn
Raspberry Pi Pico で用いているCPU (RP2040) の入出力ポートに入力可能な電圧の最大値 (絶対最大定格) は **3.8V** (IOVDD + 0.5) である。
5V トレラントの入出力ポートは存在せず、UART のポートを含めた入出力ポートに **5V を入力してはいけない。**
:::

入出力ポートの配置は、ビデオ関係・キーボード関係・ISP を除いて IchigoJam R と同じようである。(すなわち、従来型の IchigoJam と比べると SDA・SCL の位置が異なる)

IN1～IN4 は、リセット時プルアップされている。
`OUT` 命令の第2引数で `-1` を指定すると、対応するポートが**プルダウン**の入力になる。

:::note info
この「プルダウンされる」という動作は、`-1` を指定するとプルアップもプルダウンもなしになった従来型の動作とは異なる。
:::

### UART

従来通りの UART (シリアル通信) を用いることができ、デフォルトの通信速度は 115200bps である。
数種類のプログラムで試したところ、Tera Term の送信遅延を**字・行ともに 0 ミリ秒**に設定した状態でも、長い (1024バイトに近い) プログラムを欠けることなく流し込めるようであった。

これまでのバージョン (1.4.3、1.5b) では、リセット後最初に出力されるバージョンなどの部分は、目に見える速さで1文字ずつ出力されていた。
一方、IchigoJam P では、全体が一気に出力される。

### PWM

`PWM` 命令による PWM 出力は、OUT1～OUT6 で利用可能である。
IN1～4 および LED は、`PWM` 命令で指定しても何も起こらないようである。

```text
PWM1,300:PWM2,600:PWM3,900:PWM4,1200:PWM5,1500:PWM6,1800
```

を実行すると、以下の出力が得られた。

![PWM の出力例 1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/428e9035-6028-559f-edee-45c57ddb5d4a.png)

ほぼ同時に `PWM` 命令を実行しているが、OUT2 および OUT4 は他の出力より出力開始が1周期遅れている。
さらにこれを拡大すると、以下のようになっていた。

![PWM の出力例 1 (拡大)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/da970723-f259-d1a2-95b3-54cd3acdfed6.png)

OUT1 と OUT2、OUT3 と OUT4 の立ち上がりのタイミングは揃っているが、それ以外の組み合わせの立ち上がりのタイミングはズレている。
ここで、RP2040 の GPIO と PWM の関係をみると、以下のようになっている。

|出力|GPIO|PWM|
|:-:|:-:|:-:|
|OUT1|GP8|PWM4 A|
|OUT2|GP9|PWM4 B|
|OUT3|GP10|PWM5 A|
|OUT4|GP11|PWM5 B|
|OUT5|GP22|PWM3 A|
|OUT6|GP21|PWM2 B|

OUT1 と OUT2、OUT3 と OUT4 は「PWM○」の○に入る番号が同じであるが、それ以外ではこの番号が異なっている。
この番号が同じ組み合わせでは出力開始のタイミングが揃い、違う組み合わせでは揃うとは限らなそうだ。

また、

```text
PWM1,200,400:PWM2,300,600:PWM3,400,800:PWM4,500,1000:PWM5,600,1200:PWM6,700,1400
```

を実行すると、以下の出力が得られた。

![PWM の出力例 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/156b9c4f-bba7-f66c-5167-9a36d58ee63b.png)

第3引数を指定しても Syntax error などのエラーにはならないものの、無視されているようである。
負の値を指定することによる高解像度化も効かないようである。

:::note info
よく見ると、リファレンスにも `PWM` の第3引数の話は書かれていない。
:::

### ANA (アナログ入力)

`ANA` 関数によるアナログ入力は、IN1・IN2・BTN で利用可能である。
これは、Raspberry Pi Pico の ADC 端子の配置と合致している。

### DAC (アナログ出力)

`DAC` 命令は、リファレンスの紙で「非対応」となっている。
実行してみると、Syntax error などのエラーにはならないが、何も起きないようである。

## LCD (非対応)

リファレンスの紙によると、画面の出力先を LCD に切り替える `SWITCH` コマンドには非対応のようである。
実行してみると、Syntax error などのエラーにはならないが、何も起きないようである。

# 入出力ポートの対応関係

IchigoJam P の入出力ポートと、それに使われている Raspberry Pi Pico の入出力ポートの関係は、以下のようになっている。

## IchigoJam P 基準

|IchigoJam P|Raspberry Pi Pico|IchigoJam P|Raspberry Pi Pico|
|:-:|---|:-:|---|
|-|-|-|-|
|-|-|-|-|
|IN1|[32] GP27 / ADC1|-|-|
|IN2|[31] GP26 / ADC0|SND|[26] GP20|
|IN3|[9] GP6|-|-|
|IN4|[10] GP7|RESET|[30] RUN|
|VCC|[36] 3V3(OUT)|GND|GND|
|GND|GND|VCC|[36] 3V3(OUT)|
|OUT1|[11] GP8|SCL|[7] GP5 / I2C0 SCL|
|OUT2|[12] GP9|SDA|[6] GP4 / I2C0 SDA|
|OUT3|[14] GP10|OUT5|[29] GP22|
|OUT4|[15] GP11|OUT6|[27] GP21|
|BTN|[34] GP28 / ADC2|TXD|[1] GP0 / UART0 TX|
|LED|[4] GP2|RXD|[2] GP1 / UART0 RX|

## Raspberry Pi Pico 基準

|Raspberry Pi Pico|IchigoJam P|Raspberry Pi Pico|IchigoJam P|
|:-:|:-:|:-:|:-:|
|1|TXD|40|5V (スイッチ経由)|
|2|RXD|39|-|
|3|GND|38|GND|
|4|LED|37|-|
|5|-|36|VCC / 3.3V|
|6|SDA|35|VCC / 3.3V|
|7|SCL|34|BTN|
|8|GND|33|GND|
|9|IN3|32|IN1|
|10|IN4|31|IN2|
|11|OUT1|30|RESET|
|12|OUT2|29|OUT5|
|13|GND|28|GND|
|14|OUT3|27|OUT6|
|15|OUT4|26|SND|
|16|DVI 18 (TX0+)|25|DVI 9 (TX1-)|
|17|DVI 17 (TX0-)|24|DVI 10 (TX1+)|
|18|GND|23|GND|
|19|DVI 23 (TXC+)|22|DVI 1 (TX2-)|
|20|DVI 24 (TXC-)|21|DVI 2 (TX2+)|

DVI コネクタのピン番号と名称は、
[FMVマニュアル > 『製品ガイド』FMV-D5370：富士通](https://www.fmworld.net/biz/fmv/support/fmvmanual/0810-0903/9271d/09_gijyutsu4.html)
を参考にした。

# バージョンとその他のパラメータ

今回入手した IchigoJam P のバージョン情報は、以下のようになっていた。

![ijp-ver-20241201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6ec176b0-51cc-7585-8283-2fd0d3acb8ef.png)

|引数|意味|値|
|:-:|---|---|
|なし / 0|バージョン|16000|
|1|プラットフォーム種別|8 (未知のプラットフォーム)|
|2|キーボード種別|255 (未知のキーボード種別)|
|3|言語の種類|1 (カタカナ・ローマ字入力)|
|4|1 秒の TICK() 値|60 (NTSC 規格)|

:::note info
特に、キーボード種別 `VER(2)` が未知の値になっている。
これは、キーボードを接続していてもいなくても同じ値が返るようだった。
:::

さらに、リファレンスの紙から、以下のことが読み取れる。

* `SAVE` や `LOAD` で本体に保存できるファイルは、0～99 の 100個
* 高解像度版の `WAIT` や `TICK()` の単位は、(従来の261倍ではなく) 240倍

後者については、

```text
CLT:WAIT60:?TICK(1)
```

を実行すると `14401` (=60×240+1) が、

```text
CLT:WAIT-14400:?TICK()
```

を実行すると `60` が出力されたことからも確かめることができる。

# メモリマップ

`HELP` コマンドの出力は、以下のようになった。

```text
#000 CHAR
#700 PCG
#800 VAR
#900 VRAM
#C00 LIST
```

仮想メモリのアドレスは、`#117F` までが有効なようである。

# マシン語の実行環境

## アーキテクチャ

IchigoJam P で用いられている RP2040 は、Arm® Cortex®-M0+ CPU である。
これは、従来型の IchigoJam で用いられる Cortex®-M0 CPU と比べて、命令セットは同じであるが、より消費電力が少ない、分岐にかかるクロック数が少ない (ため実行速度が速い) などの違いがある。

* [「Cortex-M0＋」の動作時消費電力は「Cortex-M0」の2/3、処理性能は1.1倍：ARM Cortex-M0＋ - EDN Japan](https://edn.itmedia.co.jp/edn/articles/1203/14/news108.html)
* [ARM Cortex-M - Wikipedia](https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M0+)

すなわち、IchigoJam P においては、(IchigoJam R ではない) **従来型の IchigoJam と同じマシン語を実行できる。**
ただし、クロック数を用いて時間を制御しているプログラムでは、分岐にかかるクロック数の違いに注意するべきである。

Arm and Cortex are registered trademarks of Arm Limited (or its subsidiaries or affiliates) in the US and/or elsewhere.

## 渡される引数

[IchigoJam R に関する諸々 #IchigoJam - Qiita](https://qiita.com/mikecat_mixc/items/6108adcd11b5b7a76abe#%E3%83%9E%E3%82%B7%E3%83%B3%E8%AA%9E%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E6%99%82%E3%81%AE%E5%BC%95%E6%95%B0)
で用いたプログラムを用いてマシン語の実行時に渡される引数を確認すると、以下のようになった。

```text
ARG0 = #00001234
ARG1 = #200291C0
ARG2 = #20001090
ARG3 = #1000C739
PC   = #200298C0
SP   = #20041DE8
*(ARG1+#700): B7 2F 29 E0 97 0F 00 00 13 87 CF 0F 08 C3 4C C3
*ARG2       : 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF
*(ARG3&~#1) : 11 4A 93 6F 9B 08 13 D2 10 66 51 66 00 29 05 D0
```

第4引数の値付近から読み取ったデータを逆アセンブルすると、

```text
	R2 = [18]L
	R3 = [R2 + 30]L
	R3 = R3 >> 2
	IF CS GOTO 21
	[R2 + 24]L = R0
	[R2 + 25]L = R1
	R1 - 0
	IF 0 GOTO 7
```

となった。
`[18]L` に格納されているのが `0xd0000000` (`SIO_BASE`) だと仮定すると、`[R2 + 30]L`、`[R2 + 24]L`、`[R2 + 25]L` はそれぞれ `DIV_CSR`、`DIV_UDIVIDEND`、`DIV_UDIVISOR` に相当し、第4引数には仕様通り割り算ルーチンのアドレスが渡されていると考えられる。

## API

IchigoJam P で用いられている RP2040 では、`0x00000000` からの領域は起動時の処理やプログラムの書き込みなどを担う ROM に割り当てられている。
そのため、API のアドレスを置くのは難しく、[マシン語用の API](https://fukuno.jig.jp/2498) には**対応していない**と思われる。
「オールマシン語かわくだり」も動作しなかった。

## アーキテクチャの判別

従来型の IchigoJam と IchigoJam P は、アドレス `#E000ED00` にあるレジスタ `CPUID` の値を確認することにより見分けることができる。
下から 8ビット目～11ビット目 (0-origin) を確認し、`2` であれば従来型、`6` であれば IchigoJam P である。

```text:アセンブリコード
	IF M0 GOTO @M0
MODE RV32C
	R10 = -1
	RET
MODE M0
@M0
	R0 = [@CPUID_ADDR]L
	R0 = [R0]L
	R0 = R0 >> 8
	R1 = #F
	R0 &= R1
	RET
ALIGN 4, 0, 0
@CPUID_ADDR
	DATAL #E000ED00
```

```text:BASICコード
10 ' ｱｰｷﾃｸﾁｬ ﾊﾝﾍﾞﾂ
20 POKE#700,183,47,1,224,125,85,130,128,2,72,0,104,0,10,15,33,8,64,112,71,0,237,0,224
30 C=USR(#700,0)
40 IF C<0 PRINT "IchigoJam R":END
50 IF C=2 PRINT "IchigoJam":END
60 IF C=6 PRINT "IchigoJam P":END
70 PRINT "UNKNOWN"
```

とはいえ、IchigoJam P で実行できる命令セットは従来型と同じなので、周辺機器 (ペリフェラル) に直接アクセスするなどの特殊な処理を行うのでなければ、基本的には判別処理は不要だろう。

# プログラムの実行速度

[IchigoJam速度比較 ～IchigoJam Rが10倍速いってマジ？～ #ベンチマーク - Qiita](https://qiita.com/mikecat_mixc/items/eb1786dc384d579b7705)
で用いたプログラムにより、プログラムの実行速度を比較した。
IchigoJam R のデータは同記事のものを用い、IchigoJam Q (1.4.3、VER() = 14323) および IchigoJam P における実行速度を新たに測定した。
相対速度は、IchigoJam Q のビデオ出力有のときの速度を 1 とする。

## フィボナッチ数列の計算

|機種名|実行時間<br>(ビデオ出力有)|実行時間<br>(ビデオ出力無)|相対速度<br>(ビデオ出力有)|相対速度<br>(ビデオ出力無)|
|---|---|---|---|---|
|IchigoJam Q|10047|6587|1.0000|1.5253|
|IchigoJam R|1215|1067|8.2691|9.4161|
|IchigoJam P|610|545|16.4705|18.4349|

## 素数の和の計算

|機種名|実行時間<br>(ビデオ出力有)|実行時間<br>(ビデオ出力無)|相対速度<br>(ビデオ出力有)|相対速度<br>(ビデオ出力無)|
|---|---|---|---|---|
|IchigoJam Q|10156|6657|1.0000|1.5256|
|IchigoJam R|1228|1078|8.2704|9.4212|
|IchigoJam P|604|538|16.8146|18.8773|

## Xorshift (疑似乱数)

ビデオ出力有での実行時間

|機種名|空転|マシン語|BASIC|マシン語-空転|BASIC-空転|
|---|---|---|---|---|---|
|IchigoJam Q|773|1608|9468|835|8695|
|IchigoJam R|93|194|1123|101|1030|
|IchigoJam P|49|99|562|50|513|

ビデオ出力無での実行時間

|機種名|空転|マシン語|BASIC|マシン語-空転|BASIC-空転|
|---|---|---|---|---|---|
|IchigoJam Q|507|1054|6207|547|5700|
|IchigoJam R|81|171|985|90|904|
|IchigoJam P|43|90|502|47|459|

ビデオ出力有での相対速度

|機種名|空転|マシン語|BASIC|マシン語-空転|BASIC-空転|
|---|---|---|---|---|---|
|IchigoJam Q|1.0000|1.0000|1.0000|1.0000|1.0000|
|IchigoJam R|8.3118|8.2887|8.4310|8.2673|8.4417|
|IchigoJam P|15.7755|16.2424|16.8470|16.7000|16.9493|

ビデオ出力無での相対速度

|機種名|空転|マシン語|BASIC|マシン語-空転|BASIC-空転|
|---|---|---|---|---|---|
|IchigoJam Q|1.5247|1.5256|1.5254|1.5265|1.5254|
|IchigoJam R|9.5432|9.4035|9.6122|9.2778|9.6184|
|IchigoJam P|17.9767|17.8667|18.8606|17.7660|18.9434|

## 宇宙旅行

|機種名|実行時間<br>(ビデオ出力有)|実行時間<br>(ビデオ出力無)|相対速度<br>(ビデオ出力有)|相対速度<br>(ビデオ出力無)|
|---|---|---|---|---|
|IchigoJam Q|576|386|1.0000|1.4922|
|IchigoJam R|72|63|8.0000|9.1429|
|IchigoJam P|35|31|16.4571|18.5806|

## まとめ

IchigoJam Q でビデオ出力有のときと比べて、IchigoJam P ではビデオ出力有では**16倍**前後、ビデオ出力無では**18倍**前後の実行速度となった。
これは、それぞれ **IchigoJam R のおよそ2倍**である。

[IchigoJam P 動作速度検証 - SHIROのIchigoJam日記](https://www.ichigojaman.jp/entry/ichigojampspeed)
では「IchigoJam R並みの速度でプログラムが動きます。」と主張しているが、これとは異なる結果になった。

# クロック周波数

従来型の IchigoJam では定格 50MHz のマイコンで [48MHz](https://fukuno.jig.jp/916)、IchigoJam R では定格 108MHz のマイコンで [96MHz](https://fukuno.jig.jp/3111) のクロックが使用されている。
IchigoJam P に使用されている Raspberry Pi Pico (RP2040) の定格は 133MHz であるが、使用されているクロックはどの程度の速度だろうか？

これを調べるため、プログラム実行用のクロック `clk_sys` を出力させてみることにした。
まず、`clk_gpout0` の設定を行い、`clk_sys` を1倍で出力させる。
次に、GPIOの設定を行い、GP21 にクロックの GPOUT0 が反映されるようにする。
すると、GP21 に対応する OUT6 にクロックが出力される。

<details><summary>アセンブリコード</summary>

```text
R3 = [@CLKGPOUT0_CTRL]L
R0 = `1000110
R0 = R0 << 5
R1 = 1
R1 = R1 << 8
[R3 + 1]L = R1
[R3]L = R0

R3 = [@GPIO21_CTRL]L
R0 = [R3]L
R1 = #1F
BIC R0, R1
R0 += 8
[R3]L = R0

RET

ALIGN 4, 0, 0
@CLKGPOUT0_CTRL
DATAl #40008000
@GPIO21_CTRL
DATAL #400140AC
```

</details>

```text
POKE#700,6,75,70,32,64,1,1,33,9,2,89,96,24,96,4,75,24,104,31,33,136,67,8,48,24,96,112,71,0,128,0,64,172,64,1,64
?USR(#700,0)
```

この信号をオシロスコープで見てみると…

![clk_sys をオシロスコープで見た結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/e37cd3a2-4efa-23ac-276f-fad46c338b6c.png)

うーん…速すぎてよくわからないようだ。
そこで、USR の第2引数を分周比として使用するよう、プログラムを書き換えてみる。
分周比は、MHz の値がそのまま kHz になってわかりやすいよう、1000分の1とする。

<details><summary>アセンブリコード</summary>

```text
R3 = [@CLKGPOUT0_CTRL]L
R1 = `1000110
R1 = R1 << 5
R0 = R0 << 8
[R3 + 1]L = R0
[R3]L = R1
R3 = [@GPIO21_CTRL]L
R0 = [R3]L
R1 = #1F
BIC R0, R1
R0 += 8
[R3]L = R0

RET

ALIGN 4, 0, 0
@CLKGPOUT0_CTRL
DATAl #40008000
@GPIO21_CTRL
DATAL #400140AC
```

</details>

```text
POKE#700,6,75,70,33,73,1,0,2,88,96,25,96,4,75,24,104,31,33,136,67,8,48,24,96,112,71,0,0,0,128,0,64,172,64,1,64
?USR(#700,1000)
```

すると、以下の結果が得られた。

![clk_sys の1000分の1をオシロスコープで見た結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/16bb9fca-132a-26ef-7e1c-29324ea007fa.png)

得られた信号の周波数が 252kHz なので…クロック周波数は 252MHz？
定格が 133MHz のはずなので、これは速すぎるように思える。
何かの間違いだろうか？

そこで、出力するのを `clk_usb` (の1000分の1) に切り替えてみた。
このクロックは 48MHz のはずである。

<details><summary>アセンブリコード</summary>

```text
R3 = [@CLKGPOUT0_CTRL]L
R1 = `1000111
R1 = R1 << 5
R0 = R0 << 8
[R3 + 1]L = R0
[R3]L = R1

R3 = [@GPIO21_CTRL]L
R0 = [R3]L
R1 = #1F
BIC R0, R1
R0 += 8
[R3]L = R0

RET

ALIGN 4, 0, 0
@CLKGPOUT0_CTRL
DATAl #40008000
@GPIO21_CTRL
DATAL #400140AC
```

</details>

```text
POKE#700,6,75,71,33,73,1,0,2,88,96,25,96,4,75,24,104,31,33,136,67,8,48,24,96,112,71,0,0,0,128,0,64,172,64,1,64
?USR(#700,1000)
```

すると、48kHz の信号が得られ、48MHz のはずのクロックを正しく反映していそうである。

![clk_usb の1000分の1をオシロスコープで見た結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/ce72d687-41ff-34d3-ed2a-628a1665d5aa.png)

調査を行うと、RP2040 を 252MHz で動かして DVI 信号を出力するというプロジェクトが見つかった。
[GitHub - Wren6991/PicoDVI: Bitbanged DVI on the RP2040 Microcontroller](https://github.com/Wren6991/PicoDVI)
このことから、今回得られた 252MHz という数値には信憑性がありそうだといえる。
(IchigoJam P にこのプロジェクトが使用されているかは不明である)

さらに裏付けを進めるため、マシン語でループを 252,000,000 回実行するプログラムを用意した。
`R0 -= 1` は1クロックで、`IF !0 GOTO @LOOP` によるジャンプは2クロックで実行できるはずなので、このループを1回回るのには3クロックかかるはずである。
よって、もし IchigoJam P がマシン語を 252MHz のクロックで実行しているのであれば、このプログラムは約3秒で実行できるはずである。

```text:アセンブリコード
R0 = 252
R1 = 100
R2 = 10
R1 *= R2
R1 *= R1
R0 *= R1
@LOOP
R0 -= 1
IF !0 GOTO @LOOP
RET
```

```text:実行するプログラム
POKE#700,252,32,100,33,10,34,81,67,73,67,72,67,1,56,253,209,112,71
CLT:?USR(#700,0):?TICK()
```

これを実行すると、`211` が出力された。
さらに、`VIDEO 0` を実行してからこれを実行すると、`180` が出力された。
予想通り、IchigoJam P はこのループを約3秒で実行できており、クロック周波数は **252MHz** のようである。

# まとめ

* 画面出力の解像度は **640×480** のようである
* IchigoJam R よりも対応するキーボードの幅が広い
  * USB ハブ経由の接続には対応していない
* 同じ周期を指定したとき、ビープ音の周波数が従来の**約2倍高い**
* **5V を入力可能な入出力ポートは無い**
* `OUT` 命令の第2引数で `-1` を指定すると、対応する入出力ポートが**プルダウン**される
* **送信遅延ゼロ**でも、Tera Term から UART でプログラムを流し込めそうである
* PWM の周期指定や高解像度化には未対応である
* アナログ入力は **IN1・IN2・BTN** で利用可能である
* アナログ出力 (`DAC`) には対応していない
* LCD への出力 (`SWITCH`) には未対応である
* プラットフォーム種別 (`VER(1)`) は **`8`** である
* キーボード種別 (`VER(2)`) として `255` が返される
* 本体に保存できるファイルは **0～99** の100個
* 高解像度版の `WAIT` や `TICK()` の解像度は (従来の261倍ではなく) **240倍**
* 仮想メモリのアドレスは **`#117F`** までが有効である
* 従来型の IchigoJam と**同じ命令セット**のマシン語を実行できる
  * 分岐にかかるクロック数が減っている
* マシン語用の API は利用できない
  * 割り算ルーチンのアドレスは渡され、利用できる
* プログラムの実行速度は、従来型の**約16倍**、IchigoJam R の**約2倍**である
* クロック周波数は **252MHz** である