Slide 1

Slide 1 text

OSC東京でいただいた UIAPduinoマイコンボードで PSG演奏と液晶ドッド絵デモ オープンソースカンファレンス 2026 香川 「290円マイコンボードでPC-6001デモ」 Izumi Tsutsui [email protected] (Twitter): @tsutsuii 𝕏 Mastodon: @[email protected]

Slide 2

Slide 2 text

0. はじめに 今日の展示物と セミナーについて

Slide 3

Slide 3 text

ラズパイHATサイズPSG演奏基板

Slide 4

Slide 4 text

PC-6001 PSG演奏と 8フレームミクさんデモ

Slide 5

Slide 5 text

UIAPduino PSG演奏と 8フレームミクさんデモ

Slide 6

Slide 6 text

1. 先々月の OSC大阪展示と 先月の OSC東京展示 「P・S・G!」

Slide 7

Slide 7 text

OSC2026大阪 https://x.com/ebijun/status/2017409056194105825  NetBSD+ラズパイ で PSG演奏 デモ

Slide 8

Slide 8 text

OSC2026東京 春 https://x.com/tsutsuii/status/2027210506042523999  NetBSD+ラズパイ で PSG ブラッシュアップ

Slide 9

Slide 9 text

OSC2026東京 春  なお一部の展示予定がておくれに https://x.com/tsutsuii/status/2026627528283337010

Slide 10

Slide 10 text

というわけで作って展示してます https://x.com/tsutsuii/status/2033167358928527452

Slide 11

Slide 11 text

……なんですが、 ラズパイ4のFDT対応とか aarch64 GPIO対応とか ドライバ実装の議論中で コミットできていないので 今日の本題はもう一つの UIAPduinoです

Slide 12

Slide 12 text

2. NetBSDとは 2024年のOSC愛媛で 紹介スライドを作ったので 毎回ちょっとだけ説明

Slide 13

Slide 13 text

BSDとは? ●Berkeley Software Distribution ●カリフォルニア大学バークレー校 で開発されたUNIX系OS ●’70年代 UNIX研究として開発開始 ●’80年代 ネットワーク機能、 仮想記憶など現代のOSの 基礎を築く ●UNIXの進化と普及に貢献

Slide 14

Slide 14 text

●“Of course, it runs NetBSD” ➔特定の機種に依存しない設計 ●“Reasonable Goal” ➔性能より「理にかなった」設計 ●機能別によく分離された構造の  ドライバやインタフェース NetBSDの特長 

Slide 15

Slide 15 text

●いろんなCPUやデバイスで動く ●クロス開発環境の意識が強い ➔組み込み系での採用例が多い NetBSDの特長  https://www.ricoh.co.jp/-/media/Ricoh/Sites/co_jp/pdf/34211809/pro-8420y-8420ht-8410y-8410ht.pdf

Slide 16

Slide 16 text

●“セルフコンパイル” ➔バイナリを作るホスト=実行するホスト 通常のPC等のアプリケーション開発など ●“クロスコンパイル” ➔バイナリを作るホスト≠実行するホスト めちゃくちゃ遅い古いマシンとか 組み込み機器やスマホなど ➔NetBSDは標準でクロスコンパイラを使用 クロスコンパイルとは

Slide 17

Slide 17 text

3. PC-6001とは このところずっと 展示デモしてますね……

Slide 18

Slide 18 text

PC-6001 とは ● NEC製の 8ビットパソコン ●1981年 11月 発売

Slide 19

Slide 19 text

PC-6001 スペック ●CPU: 8bit Z80互換 4MHz ●RAM: 標準 16KB, 最大32KB ●グラフィック: 128×192ドット 4色 256×192ドット モノクロ2色 ●音源:PSG 3和音 ●標準価格:89,800円

Slide 20

Slide 20 text

●VRAMも共用 → 空きは 7KB/23KB ●10〜100バイト単位で残りメモリを  見つつ削りながら作っていた時代 メモリ 16KB/32KB

Slide 21

Slide 21 text

4. PC-6001と エミュレータ なんでNetBSDブースで? というこじつけの歴史

Slide 22

Slide 22 text

PC-6001用エミュレータ 実機がなくても遊べます ●2000年頃からPC-6001のエミュレータが 多数開発される ●エミュレータだけでなく、 開発に必要なツールも多数 ●データ記録テーブ模擬 ●テープ音声⇔エミュ用データ変換 ●プログラムテキスト⇔エミュ用変換 ●エミュレータもデバッグ機能が充実

Slide 23

Slide 23 text

PC6001VX https://eighttails.seesaa.net/article/305067428.html https://github.com/eighttails/PC6001VX

Slide 24

Slide 24 text

●READMEより 「PC6001VをLinux等で動作  するよう改変したものです」 「PC6001VXの末尾のXは  クロスプラットフォームの  Xです」 PC6001VX https://github.com/eighttails/PC6001VX

Slide 25

Slide 25 text

●基本的な機能は PC6001V 準拠 ●クロスGUI環境としてQtを使用 ●互換ROM内蔵で 実機ROM不要 → ●pkgsrc にしたので NetBSDでも動作可能! ●Android版もあります→ PC6001VX https://github.com/eighttails/PC6001VX

Slide 26

Slide 26 text

むりやりブース展示理論 NetBSDは いろんなマシンで動く + pkgsrcは NetBSDで使える ↓ 自分がpkgsrcのメンテ担当の PC6001エミュやツールを使えば それはNetBSDセミナーネタ

Slide 27

Slide 27 text

というこじつけを 解消するために 「NetBSDとラズパイで 本物のPSGハードを 制御して鳴らす」 というテーマで作って 展示発表したのが OSC大阪と東京でした

Slide 28

Slide 28 text

5. PSG音源と 演奏原理 限られたCPU性能と メモリ容量でも 演奏するための工夫

Slide 29

Slide 29 text

PSG音源 ●いわゆるピコピコ音 × 3和音 ●元はアーケードゲーム用? ●BASIC言語だと PLAY 文で MML (Music Macro Language) という楽譜相当の書式で演奏 こんなの→ "d4b4&b32r16.b8.r16q2b8b8b8" ●“d” が「レ」、“4” が「4分音符の長さ」  “&” がタイで音をつなげる、といった具合

Slide 30

Slide 30 text

PC-6001内のPSG音源IC

Slide 31

Slide 31 text

PC-6001で PSG曲を演奏する手段 について

Slide 32

Slide 32 text

よっしゅさんの PC-6001用 PSG音源ドライバ http://park10.wakwak.com/~yosh/p6.html デモ演奏にはこれを使います

Slide 33

Slide 33 text

40年前の クロック4MHz メモリ 32KB (MBではありません) で これだけ演奏できるなら 今どきのマシンでは 楽勝のはずだよね?

Slide 34

Slide 34 text

PSGの出力原理 スピーカー アンプ ♪♪ ♪ Pico pico 加算 PSGチップ チャンネル3 Volume 1〜15 チャンネル1 Volume 1〜15 音程 チャンネル2 Volume 1〜15 音程 音程 各chに音程と音量を設定すると その音が鳴り続ける

Slide 35

Slide 35 text

PSG演奏ドライバの考え方  「演奏」とは ●PSGに「周波数と音量」を書くだけで  各チャンネルの音は鳴る ●でも一定の音が鳴り続けるだけ ●曲を演奏するには、時間経過と共に  ピアノの鍵盤を順に弾くのと同様に  一定周期で周波数と音量(OFF含む)を  PSGに書き込み続ける必要がある

Slide 36

Slide 36 text

よっしゅさんの PC-6001用 PSG音源ドライバ  特長 ●2ms周期割り込みを使用 ●96分音符単位で制御 ●ビブラート(周波数変化)サポート ●ソフトウェアエンベロープ  (発声中の時間音量変化)サポート ●割り込み駆動なのでBGM演奏も可能

Slide 37

Slide 37 text

2ms割り込みでの演奏イメージ 「96分音符単位」がキモ BASICプログラム実行 時間 2ms 周期割り込み 96分音符長単位演奏処理 96分音符長単位演奏処理 96分音符長単位演奏処理 ●4分音符を鳴らすには? ➔出力ONした後 24(=96÷4)回後にOFFする ●音量や周波数も96分時間単位で変化させる ←この回数でテンポ決定→ (3〜12回程度)

Slide 38

Slide 38 text

PSG音源ドライバで必要な処理  要件定義から ●2ms周期で演奏ルーチンを呼ぶ ●演奏データを解釈して処理する ▶音符データに従った周波数と音量出力 ▶音長のカウントと出力ON/OFF ▶ビブラートの周波数変化処理 ▶エンベロープのボリューム変化処理

Slide 39

Slide 39 text

という感じでOSC大阪展示  展示用PSG演奏状態表示も作りました https://social.mikutter.hachune.net/@tsutsuii/115974096152180552

Slide 40

Slide 40 text

6. OSC東京向け リファクタリング NetBSDセミナーぽいネタを

Slide 41

Slide 41 text

OSC大阪時点の演奏プログラム  突貫作成のテストプログラムからそのまま ●GPIO関数が main関数と同じファイル ●演奏データ読み出しもmain関数内 ➔NetBSD的な「機能別の分離」をして  「どんなマシンでも動く」という  構成にすべき! ……という病気を発症

Slide 42

Slide 42 text

PSGハード接続仕様を考える  ラズパイ以外にもできるはず? ●今はラズパイのGPIOに接続 ●PCだとUSB経由でGPIO接続する? ●PSGをソフトでエミュレートするかも ➔何が相手でも、プレーヤーは共通で  バックエンド差し替えで動くように  再構成したい OSC東京セミナースライドより

Slide 43

Slide 43 text

機能別分割とI/F定義  以下に分離 ●起動初期化と2ms周期呼び出しmain() ●PSG演奏データ読み出し処理 ●PSGレジスタアクセスH/Wアクセス層 ●PSGドライバ2ms周期演奏処理 ●展示デモ用演奏状態表示処理 ➔インタフェースと構造体定義が面倒くさい、  と言いながらChatGPTに構造案を出させて修正

Slide 44

Slide 44 text

……と、ブース展示では わからない要素込みだったOSC東京 https://x.com/ebijun/status/2027227799686443419

Slide 45

Slide 45 text

8. OSC東京と UIAPduino ……と伏線を張ったところで 45ページ目の本題です

Slide 46

Slide 46 text

UIAPduino とは  「290円」Ardiuno互換マイコンボード https://www.uiap.jp/uiapduino/

Slide 47

Slide 47 text

UIAPduino とは  主な仕様 ●RISC-Vコア CH32V003 CPU 48MHz ●Arduino IDE対応 ●FLASH ROM 16KB / RAM 2KB ●GPIO 15本, ADC, UART, SPI, PWM,  I2C, タイマ 等々のI/O ●5V / 3.3V 動作切替可能 https://www.uiap.jp/uiapduino/pro-micro/ch32v003/v1dot4

Slide 48

Slide 48 text

OSC東京の展示ブースにて  290円どころではなくて ●OSC東京で同じ部屋だった  UIAPさんのブースで  無償配布ボードを頂く ●GPIO端子 と FLASH ROM 16KB を見て  考えることはただひとつ: 「これにPSGをつなげられるだろうか」

Slide 49

Slide 49 text

ひとまずサーベイ  公式ページ AI支援コーディングのススメ https://www.uiap.jp/uiapduino/pro-micro/ch32v003/v1dot4

Slide 50

Slide 50 text

教えに従って ChatGPTに雑に聞いてみる UIAPduinoに PSG YM2149F を接続して、 Raspberry Pi 3Bから制御したとき同様に 演奏制御できますか? また、ボード同士の接続端子も 教えてください。 以下のWEB資料を参考にしてください。 https://www.uiap.jp/uiapduino/pro-micro/ch32v003/v1dot4 https://ch32v003-guidebook-arduino.74th.tech/

Slide 51

Slide 51 text

 はい、できます。 しかも UIAPduino Pro Micro CH32V003 V1.4は 5V動作に対応し、 CH32V003 は 48MHz で動き、 Arduino IDEでスケッチを書けるので、 YM2149F を 8bit パラレルで直接 たたく用途には十分向いています。

Slide 52

Slide 52 text

AIにマニュアルを読ませよう  だいたい聞くと出てくる ●「GPIOとYM2149接続案を出して」 ➔さくっと提示されたのでそれを元に割り当て修正 ●「レジスタアクセスのサンプルを見せて」 ➔MMIO含めてアクセスの感触がだいたいわかる ●「ROM容量的にPSGドライバ入りそう?」 ➔Arduinoではなくch32fun開発環境を勧められる ●「2msタイマ割り込みってどう書けばいい?」 ➔割り込み関数の書式もサクっと出てくる ●「2MHzクロックの出力はさすがに厳しい?」 ➔PWM出力キャリア 2MHzの Duty 50%でいける

Slide 53

Slide 53 text

AIにテストコードを書かせよう  ラズパイPSG開発の経験が生きている? ●「ラズパイの時みたいにドミソを出す   サンプルコードを書いて」 ➔どこかで見たようなサンプルコードが出てくる ●あまりにもサクサク実装設計が進むので  部品箱に転がってた万能基板と  ラズパイPSGの余剰部品でおもむろに  UIAPduino + PSG の回路を作ってみる

Slide 54

Slide 54 text

基板は人間が作ります  材料の UIAPduinoとアンプとYM2149

Slide 55

Slide 55 text

基板は人間が作ります  サイズギリギリ基板

Slide 56

Slide 56 text

基板は人間が作ります  土地がないので違法建築

Slide 57

Slide 57 text

基板は人間が作ります  ジャストフィットレイアウト

Slide 58

Slide 58 text

基板は人間が作ります  配線

Slide 59

Slide 59 text

基板は人間が作ります  2時間半ほどで完成

Slide 60

Slide 60 text

とりあえず WSL上のch32fun環境で ビルドしていきなり動作確認 https://social.mikutter.hachune.net/@tsutsuii/116188262998132305

Slide 61

Slide 61 text

https://social.mikutter.hachune.net/@tsutsuii/116188295183443921 (ドミソー♫ の和音が   5秒鳴る動画)

Slide 62

Slide 62 text

UIAPduino PSG動作確認RTA https://social.mikutter.hachune.net/@tsutsuii/116188330047219980

Slide 63

Slide 63 text

リファクタリングの伏線回収で PSG演奏ドライバも一瞬で動作 https://social.mikutter.hachune.net/@tsutsuii/116188996603484913

Slide 64

Slide 64 text

そのまま勢いで基板作成段取り https://social.mikutter.hachune.net/@tsutsuii/116199133399158713

Slide 65

Slide 65 text

回路図とパターンも引いて発注 https://social.mikutter.hachune.net/@tsutsuii/116205429797034834

Slide 66

Slide 66 text

https://social.mikutter.hachune.net/@tsutsuii/116232445555611502

Slide 67

Slide 67 text

とりあえず動画投稿 https://www.nicovideo.jp/watch/sm46078036

Slide 68

Slide 68 text

奉納準備 https://social.mikutter.hachune.net/@tsutsuii/116263951737042111

Slide 69

Slide 69 text

というわけで 3/21(土)のNT京都で UIAPさんブースに寄贈しました https://social.mikutter.hachune.net/@tsutsuii/116265666962369271

Slide 70

Slide 70 text

また追加で UIAPduinoを いただいたので 次の計画を立案   CH32V006バージョンもいただいたのですが、 順番に片付けますので……

Slide 71

Slide 71 text

PC-6001 PSGデモといえば  160x90ドットミクさん https://www.nicovideo.jp/watch/sm45229358

Slide 72

Slide 72 text

UIAPduinoでも 160x90ミクさんを 動かしながら PSG演奏できたら めちゃくちゃ 楽しいのでは?

Slide 73

Slide 73 text

とりあえず 160x90表示できる モノクロ液晶を 探してみたものの なかなか無い? カラーのはいくつかあるけど

Slide 74

Slide 74 text

いろいろ探して一つ発見 https://www.switch-science.com/products/3350

Slide 75

Slide 75 text

 Adafruit SHARP Memory Display ●144x168ドットモノクロ ●SPIで3線接続可能 ●5V/3V両対応 ●メモリ内蔵で行ごとに書き換え可能 いろいろ探して一つ発見

Slide 76

Slide 76 text

“ディスプレイ書込時には、 168 x 144ビット全体 (3KB)のバッファが マイコン側に必要です”

Slide 77

Slide 77 text

UIAPduino の RAM は 前述の通り 2KB ですが、 液晶マニュアルを見て 「まあなんとかなるやろ」 と脳内構想段階で 予備含めて2台発注

Slide 78

Slide 78 text

メモリ容量見積もり (ROM)  160×90÷8=1800バイト ●PC-6001の空きメモリは約23KB ●4枚 7.2KBは割と余裕 ●8枚 14.4KBは非圧縮でギリいける ●16枚 28.8KBはZX0圧縮でギリOK ➔UIAPduino の FLASH ROM 16KBでも  圧縮すればなんとかなりそう?

Slide 79

Slide 79 text

メモリ容量見積もり (RAM)  144×168÷8=3024バイト ●全体を一度にSPIするから足りない ●液晶のコマンド仕様を見る限りは  任意行単位で書き込みできるっぽい ➔160x90画像を分割してから圧縮して  ブロックごとに展開して表示すれば  320〜800バイト程度でもイケそう?

Slide 80

Slide 80 text

例によってChatGPTと設計  仕様は人間、実装はAI ●160x90画像を左回転して144x168の  真ん中よりに表示 ●上下4ラインと左右3バイトはベタ ●端数6ドットは画像に含める ●16ライン毎にZX0圧縮してROM保持 ●表示も16ライン毎展開してSPI通信

Slide 81

Slide 81 text

画像データ→圧縮ROMデータ作成  ツール作成も仕様定義すればAIで十分 ●160x90画像を読んで、左回転して  液晶仕様のLSBが左側に変換して  黒を0、白を1にしてバイト変換して  16ライン(32バイト) 毎にZX0圧縮して  画像展開用構造体として出力  みたいな感じでさくっとツールを作ってもらう ✔(上記は最終仕様でビットオーダーとか白黒設定は途中で   いろいろ試行錯誤してました)

Slide 82

Slide 82 text

ブレッドボードでテスト  オシロもテスタも持ち出さない勘デバッグ戦法 ●最初はうんともすんとも言わない  いろいろ一度に詰め込みすぎ ●SPIのSCSをLED付きのピンにして様子を見る ●明るいままなので無限ループしそうなところを  チェックして、要らなそうな受信待ちを削除 ➔なんかミクさんの髪の  一部が出たっぽい!?

Slide 83

Slide 83 text

デバッグもテストもAIブースト  便利なしもべ ●切り分けのために1ラインずつ書いてみよう、  と言われてテストルーチンを追加してもらう ●各ライン問題無いようなので ZX0展開ルーチン  を疑ってみる ●展開ルーチンはC実装だから、NetBSD上で動く  同じ展開処理を検証するテストを書いて、  と依頼して、その結果(NG)をまた投げる  ➔「2ブロック目の展開で通るパスで処理を   間違えてました」と自分で直してくる   (元実装の goto文を勝手にfor(;;) に書き換えてバグっていた)

Slide 84

Slide 84 text

修正して実行すると……  検証サイクル速すぎ問題(1枚絵OK) https://social.mikutter.hachune.net/@tsutsuii/116317929811940946

Slide 85

Slide 85 text

4枚ループ表示もOK! https://social.mikutter.hachune.net/@tsutsuii/116318071675023293

Slide 86

Slide 86 text

楽しい! ✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌

Slide 87

Slide 87 text

ゴールが 見えてきたので 書き換え速度を 見積もってみる

Slide 88

Slide 88 text

SPIクロック律速?  これもChatGPTに計算してもらいつつ ●液晶仕様としては上限 1.1MHz ●CH32V003の仕様上は 24MHzの分周  つまり 750kHz か 1.5MHz? ●計算上は1.5MHzでも厳しい ●試しに3MHzで動かす →動く? ●試しに6MHzで動かす →動く!? ➔画面4分割で6MHzならPSG演奏の2ms周期  も現実味ありそう、というChatGPT所見

Slide 89

Slide 89 text

とりあえずやっつけで PSG演奏プログラムと 液晶表示プログラムを ニコイチして、 適当に脳内計算で タイミングを合わせてみる (これをChatGPTに投げると変にいらないところ を修正してきておかしくなる予感がした)

Slide 90

Slide 90 text

約1時間のデバッグの結果 https://social.mikutter.hachune.net/@tsutsuii/116351549158752741

Slide 91

Slide 91 text

またまたサクッと引いて発注 https://social.mikutter.hachune.net/@tsutsuii/116366908730723893

Slide 92

Slide 92 text

というわけでミッションコンプリート! https://x.com/tsutsuii/status/2044741400219300341

Slide 93

Slide 93 text

というわけでミッションコンプリート! https://x.com/tsutsuii/status/2044741400219300341

Slide 94

Slide 94 text

●手間をかけてちゃんとI/F定義して  モジュールとして分割実装すると  めっちゃ楽に流用ができる、という  NetBSD的しぐさが奏功しました ●クロス開発練習にもオススメです ●「これで動かせるだろうか」  →「うおおおおおおお、動いた!」  を久しぶりに味わえました! まとめ