2023/6/22 21:00 4759FM音源ボード(2151+2608)基板頒布Project


!!C96で、一部白レジスト基板(1.2b 青みがかった白レジストで、背面マイクロSDカードの部分に「884237」と数字が入っている基板)を購入した方へ!!
※MI68K版はチェック済みです

基板裏面(配線側)のレジストが若干ずれているものが混じっているため、芋はんだ気味につけてしまうと、GNDへショートしてしまうようです。
今のところC26とC41辺りのパスコン周辺が怪しいという情報をいただきました。
※全体的にずれているため、他の部分でも発生する可能性があります。

申し訳ありません。電源投入前に+5VとGND間、+3.3VとGND間をテスターで確認をお願いします。
ショートしているようならば、はんだを吸い取ってください。
銀色のランドパターンから漏れない程度の少量のはんだで修正してください。
その他の場所も芋はんだ気味だと動作しない可能性があります。
さらに難易度があがってしまって申し訳ありません。無理そうなら交換します。
(2名の方から申告在り、5枚在庫ありのため、3枚が怪しいかもです…)

※今のところ左上のレギュレータ周りC26及び、I2CEXT周辺C41等が芋はんだ注意ポイントです

・大丈夫なレジストの基板です


・注意が必要なレジストの基板です

下の銀色の部分まではんだを乗せてしまうとショートしてしまいます。


4759ファームウェアへ
2023/6/22 ・4759firmware v1.16を追加。USB更新2対応版専用です
2023/6/16 ・4759firmware v1.15を追加。USB更新2対応版専用です
2023/6/12 ・4759firmware v1.14を追加。USB更新2対応版専用です
2023/5/13 ・4759firmware v1.13を追加。USB更新2対応版専用です
2023/3/18 ・4759firmware v1.12を追加。USB更新対応版専用です
2023/3/5  ・4759firmware v1.11を追加。USB更新対応版になりました
2023/1/14 ・4759firmware v1.10を追加
2022/11/17 ・4759firmware v1.09を追加
2022/8/16 ・4759firmware v1.08を追加
2022/7/16 ・4759firmware v1.07を追加
2022/6/11 ・4759firmware v1.06を追加
2022/4/13 ・4759firmware v1.04を追加
2022/2/18 ・4759firmware v1.03を追加
2022/2/12 ・4759firmware v1.02を追加
2022/1/18 ・4759firmware v1.01を追加
2021/10/6 ・4759firmware v1.00を追加
2021/5/6 ・4759firmware v0.92を追加
2020/11/14 ・4759firmware 1.4b/1.4c基板専用 v0.91Aを追加
2020/6/24 ・4759firmware v0.91Aを追加
2020/4/27 ・4759firmware v0.81A(β)を追加
2020/4/26 ・4759firmware v0.81(β)を追加
2020/3/29 ・4759firmware v0.80B(β)を追加
2020/3/28 ・4759firmware v0.80A(β)を追加
2020/1/23 ・4759firmware v0.75(β)を追加
2019/11/30 ・4759firmware v0.74を追加
2019/11/21 ・4759firmware v0.73を追加
2019/11/10 ・4759firmware v0.72aを追加
2019/9/27 ・4759firmware v0.72を追加
2019/9/23 ・4759firmware v0.71を追加
2019/8/25 ・4759firmware v0.70を追加
2019/5/17 ・4759firmware v0.63eを追加
2019/5/3 ・4759firmware v0.63dを追加
2019/4/7 ・4759FM音源ボード用ページを作成


■はじめに

このドキュメントは4759FM音源ボードを製作する為に必要な情報を記述したものです。
製作に当たってはこのドキュメントをよく読み、用法用量を守って正しくお使いください。

C96の説明書PDF(C96用説明書)

・基板頒布Projectとはなんですか?

基板は10枚単位で作っています。
基板製造サービスがこの単位で作れるもので、1枚と値段が変わらないのです。
#厳密には重さが変わるので、輸送費に影響が出てるかもしれません

この余りを放出するもののことです。

・作るまえの注意点

部品は付属していませんので、集めてください。部品リストについては下のほうに説明を記述しています。
部品はほぼ秋月電子で購入できますが、一部取り扱いが終了しているものがあるので、他の店でも探す必要があります。
工具はある程度あった方がよいと思います。
主に使っているディスクリート部品は表面実装ではないのですが、マイコンの半田付け確認等にルーペがあると便利です。

抵抗は100本入りで100円で売られています。1本あたりの単価は1円なのですが、100本も不要な場合は他の部品屋で狙ってみてください。ただ、他だと1本10円とかします。
それ以外だと千石電商や通販(RS Online)で手に入れています。
FM音源チップは入手が面倒ですが、海外通販や家電のケンチャンで手に入ります。
家電のケンチャンだと店内に置いてあります。通販では売っていないです。店頭のFM音源ガチャでもFM音源チップは手に入りますが、ガチャガチャで目的のチップを狙うのは面倒だと思われます。

RS Online等では、1つ1つ丁寧にパッケージされている部品と、産業用のトレイやレールで売っているもの等、提供形態が複数種類あります。
1個単位で買えるものもありますが、数個まとめて買わないといけないもの、数を買うと大幅に安くなるものがあります。
単価が安くても、最低注文個数を確認してください。産業用レール売りなどの部品は25個単位などでしか買えず、返って高い場合があります。

なお、ファームウェアを書き込むのにPICKIT3やMPLAB SNAP等が必要です。
#PICKIT4でもいけると思いますが、試した事はありません。

MPLAB IPEでHEXファイルを書き込んでください。
PICKITから電源供給するのチェックボックスを有効にしてください。
ちなみにこのMPLAB IPEですが、画面の高さが最低768pxはないと、ボタンが押せない場合があります。
LATTEPANDAの1024x600で、PICKITから電源供給するのチェックボックスを押すのが至難の業でした。

また、基板にマイコンを実装してプログラムを書き込むのに、ピンヘッダを軽く押し付けながら20秒程度じっとしないといけません。
MPLAB SNAP等の高速書き込みモード対応のプログラマだと2秒程度で済みます。ただ、電源供給に対応してない気がします
この時に動いて接触不良になったりすると、マイコンが使用不可能になります。
自信がない場合は、基板にピンヘッダ端子を半田付けすると楽ですが、邪魔です。仕方がありませんが。

※ファームウェア書き込みについての詳細は、携帯FM音源プレイヤー&YM2608FM音源ボード解説ページも参照してください。

表面実装部品であるマイコンは、コテ先が平らになっているものの方がつけやすいようです。
ざっと半田を溶かしながらなぞれば、端子意外はレジストで弾かれて半田が載らない筈ですが、液体フラックスとかいろいろテクが必要みたいです。

#結構ヤニで汚くなるので、イソプロピルアルコールで拭いています。
 無水アルコールでないのは、買いに行った時の在庫の都合です。


この基板は以下を有している方を対象としています。

・半田付けの知識
・FM音源の知識
・部品を調達できる
・曲データを準備できる

・あると便利な工具など

・ニッパー
・ラジオペンチ
・はんだごて(20wくらい)
・ヤニ入り有鉛はんだ …※
・はんだ吸い取り線
・ドライバー

※Pbフリーなものより有鉛半田のがつけやすいです。確実に。最近のは良くなったのかと使ってみましたが、やっぱりダメでした。詳しい人に聞くと、なんでそんなものを使ったんだとばかりに言われました。ちなみに高密度実装だとPbフリー半田はヒゲ(ウィスカ)が生えて短絡するとの事です。この基板はそんなに高密度ではないので関係ないですが。

・必須

・PICKIT3(http://akizukidenshi.com/catalog/g/gM-03608/)または相当品(MPLAB SNAP等http://akizukidenshi.com/catalog/g/gM-13854/ )
・MPLABX(https://www.microchip.com/mplab/mplab-x-ide ※MPLAB IPEが必要です 下のほうにDL用の説明を用意しています)
・PC
・勇気か根気
・曲データ

■内容物

・4759FM音源プレイヤー

・基板r1.2a


・基板r1.2b


※1.2aと1.2bの違いは基板のレジストの色と、C8あたりのレイアウトが少し違うだけです。
回路は同じです。

■作るための注意点

・作る順番

基本的に背の低い部品、特に表面実装からつけていきます。が、安い部品からつけていくこともあります。
また、全部つけ終わった後に肝心な部品をつけるのに失敗していると非常にがっくりします。
何回かそういう事があってから、表面実装なマイコンを使う場合は、マイコンの動作確認をする為の部品一式をまずつけるようにしています。

具体的には、

マイコン→マイコン用パスコン、マイコン用レギュレータコンデンサ、クリスタル+クリスタル用コンデンサ、
3.3V電源周り(レギュレータ、コンデンサ、ポリスイッチ)、USBコネクタ、PICマイコンのMCLR用抵抗(10kΩ)、LED、
LED用電流制限抵抗

あたりから作業しています。
SDカードなどが検出されない場合、現在のファームウェアはLEDを点滅させます。なので、この段階でLEDが点滅しなければどこかがおかしいということになります。

#早めに動作確認している様子

また、ファームウェアはUSBシリアルポートとして認識されます。LEDが点滅しているのを確認したら、PCに接続してCOMポートが認識されるか確認してください。
認識されない場合は、マイコンの半田付け不良の可能性があります。
特に液晶が上に載るために、液晶を載せてからの不良が判明した場合、修正が困難になります。
必ず液晶を載せる前にUSB COMデバイスが認識されるか確認してください。
あ、USBから給電して確認する場合、USB電源を利用するジャンパピンを忘れないようにしてください。

製作方法の参考に(なるかどうかはわかりませんが)ぶろぐ記事をご覧ください。
基板リビジョンが違うものだったりしますが、大体作る順番のイメージがつかめると思います。

・4759FM音源プレイヤーのぶろぐ記事

【基板作成編】FM音源(OPNA/OPM)ボードの作成
https://asmpwx.at.webry.info/201902/article_1.html

・4759FM音源基板の注意点

注意!! 電源はUSB端子又はDCジャックから供給可能になっていますが、DCジャックから給電する場合は、USB電源のジャンパは外してください。
DCジャックにACアダプタを接続したまま、USB給電ジャンパを刺してUSB端子にUSBケーブルを同時に接続しないでください。

・メモリはFM音源の下に配置されています。製作する順番を間違えると完成が非常に困難になります。

・PCなどのUSB電源はかなり酷いノイズが含まれています。PCだと動画再生など負荷がかかった状態だとノイズがさらににぎやかになります。

・液晶の端子は非常に繊細です。注意して扱ってください。
端子に少しでも負荷をかけると、ガラスごと割れたり、端子とガラスとの接着面が外れて簡単に壊れます。
1列出なくなるとかザラです。軽く5つは壊したと思います。

・バックライトなしの液晶を使う場合は、バックライト制御用の部品は必要ありません。
FETのBS170、抵抗の10Ω、100KΩ、金属皮膜47Ωです。

・液晶をつけなくても動作しますが、I2C用のプルアップ抵抗(10kΩx2本)だけは省略しないでください。
I2Cの処理にウェイトが入り、著しく遅くなります。(残り1本はPIC32のMCLR用抵抗ですのでこれも省略できません。つまりマイコン傍の10KΩ抵抗3本は省略しないでください)

・部品の向きについて

・マイコンの向きは絶対に間違えないでください。
基板の1番ピンの位置にはシルク印刷で丸いぽっちがつけられています。マイコンにも丸いぽっちがあります。
一致するようにつけてください。

・電解コンデンサは極性があるものがあります。音響コンデンサは無極性を使用していますが、極性つきを利用する場合は注意してください。

・ICにも向きがあります。1番ピンの位置はシルク印刷で欠けている方です。
現物の写真がありますので、よく見ながら接続方向を間違えないようにしてください。
ICソケットも間違えずにつけたほうが良いです。チップ自体の取り付けを間違えなければ大丈夫ですが、いつか間違えます。

・部品の向きがわからない場合は、実体写真を参考にしてください。

・FETや大真空の水晶発信器にも向きがあります。シルク印刷のパターン形状を見て取り付けてください。

・LEDの向きについて
 LEDにも極性があります。基板を正面から見て左側がカソード(足が短い方で樹脂内部は受け皿の形状:GND側)です。

・DRAMメモリについて

YM2608の下に入ります。なので、YM2608用のソケットをつけた後では修正が非常に困難です。
しかもチップはSOJなので貼り付けは大変です。ソケットを付ける前に念入りに確認してください。

・PICKITとの接続について

2番が電源です。3番中央がGNDです。
なので、どちらの方向にさすのかは、2番ピンがどちらにあるのかで確認する事できます。
電源やGND配線は、周りの信号線の配線よりやや太めになっているので、太いほうがどちらに寄っているかで見分ける事ができるのです。
ちなみに1番ピンは左側にあるので、必然的にPICKITは裏返して接続する事になります。
部品配置図の1番ピンの位置に▲マークをつけておきました。

・アクリル板でカバーをつける場合は

秋月のアクリル板ですが、ちょうど合いそうなサイズのBタイプ(http://akizukidenshi.com/catalog/g/gP-10243/)も微妙にサイズが合いません。
部品配置が厳しくて、穴の位置が合いません。
接着剤や、あきらめるか大きめのAタイプ(http://akizukidenshi.com/catalog/g/gP-10706/)でなんとかしてください。

・音源チップとマイコンの接続について

音源の割り込みは使えません。配線されていません。
音源チップからデータが読み込めないためです。マイコンと音源チップの駆動電圧が違うから。
マイコンは3.3Vで動いていますが、音源は5Vです。
マイコン→音源チップはこのままでも問題ありませんが、音源チップ→マイコンをやると壊れます。

なので、音源とのBUSY情報は処理時間だけで何とかしています。意外とできるものです。

・絶縁について

!!絶縁は重要です!!
4759FM音源ボード基板は、裏面が絶縁されていません。
金属板の上に置いたり、コインなどが接触した場合、ショートして重大な事態を引き起こす可能性があります。
必ず絶縁の為の処置を行ってください。
金属端子が触れないように、アクリル板をつけたり、ケースに入れたり、絶縁テープやコルクボード等で絶縁してください。
アクリル板で絶縁 ポリイミドテープで絶縁 ポリイミドテープで絶縁2 ポリイミドテープ コルクボード

秋月で液晶などの小さいデリケートな部品を買うと、小型のプラスチックケースに入っています。

プラスチックケース

このケースをはさみで切り開き、基板裏にホットボンドでつけると、丈夫な絶縁シート代わりにすることができます。
特に携帯FM音源プレイヤーの、メイン基板と電池基板の間は15mmしかないため、なるべく飛び出した端子を短く処理し、しっかりと絶縁することをお勧めします。移動中や衝撃で電池が動いた場合、メイン基板と接触しショートしかねません。
!!かならず絶縁対策を行ってください!!

お勧めはやっぱりプラスチック板を使うことです。


ポリイミド+プラスチック版で絶縁

別の基板でプラスチックケースで対策を行っている様子と秋月のプラスチックケース

■部品リスト共通のお約束について

部品リストには、部品とコメント、調達用のリンクが記載されています。
リンクは一例であり、必ずしもリンク先で購入しなければならないわけではありません。
ひょっとしたらリンクが間違っているかもしれません。必ず回路図などでも確認するようにしてください。
部品にはまれに数量が大量のものがあり、そのリンクの場合もあります。数も確認するようにしてください。
#単品ではなく数個入っている部品もありますので、余った部品は何かに活用してください。

部品の足のピッチが2.54mmの場合と5mmの場合の2種類あります。
基板は部品ピッチを2.54mmで設計しているので、購入した部品が5mm品であった場合は、足の幅を狭めてから実装してください。
#2.54mmが売っていないので仕方ありません…

また、部品はセクション別に記述しているので、同じ部品が再度登場します。
注文用に数をカウントする場合は注意してください。

■4759FM音源プレイヤー部品リスト

4759FM音源プレイヤーの部品リストなどの情報です。

回路図

部品配置

全体


1.2a基板だと、C29とC8のあたりはかなりきついです。
根性で入れるか25V品を使うなど工夫してください。物理配置写真は根性で入れています。なんとかなるものです。
あ!YM3012のところがなぜかYM3812とか書いてあった! YM3012(DAC)の間違いです

主要部品を抽出

抵抗を抽出

コンデンサのみ抽出

1.2b基板の場合


※C29,C8あたりのレイアウトが若干違いますが、回路は1.2aと同じです。

物理配置図


ソケットなどの下の配置です。

スペースの都合により、いくつかの部品が重なっています。
また表と裏面の両方に部品を実装する必要があります。
裏面はマイクロSDカードスロットのみ配置されます。
マイコンの上に液晶ユニットが配置されます。マイコン端子の半田付け不具合に注意してください。

・基板

基板フィニッシュはHASLです。
基板リビジョンは1.2bです。規模が大きくなると、大体いつもこれくらいである程度まともに動くものが出来上がるような気がします。
大体まあそんなものです。

・PIC32MX270F256D

https://jp.rs-online.com/web/p/microcontrollers/8417576/

端子の多いD型番は残念ながら秋月では取り扱っていません。
秋月で取り扱っているB型番は皆大好きDIP品なので違います。

マイコンは1番ピンの方向に丸のぽっちが点いています。基板のシルク印刷でもマークがついていますので、
位置と方向を合わせて実装してください。
#リンク先にはなんか新低価格と書いてあるリンクを貼っておきました。

・8MHz水晶発振子(マイコン用)

http://akizukidenshi.com/catalog/g/gP-08667/
以前は10個単位での販売だったのですが、最近は1個から買える様になりました。
小さい割には地味に高い部品でもあります。
ちなみにこれは水晶発振子なので、発振の為には別に回路が必要になりますが、そのための回路はマイコン内部に入っています。

・22pF x 2

http://akizukidenshi.com/catalog/g/gP-04060/
マイコン用水晶の発振用コンデンサです。
水晶発振子なので、発振の為の部品です。

・0.1uF x14くらい

http://akizukidenshi.com/catalog/g/gP-00090/
パスコン、マイコン内蔵レギュレータ用コンデンサは、みんな大好き村田のラジアルリード型積層セラミックコンデンサ(MLCC)です。
海外メーカー品と比べて、大きさがかなり均一に作られています。
#データシートにはサイズの範囲が書かれているくらい誤差があるのですが、村田製はほぼ均一サイズです。
Dマークがついてディスコンになったのが非常に悲しいです…
世界的に積層セラミックコンデンサ(MLCC)が不足しており、製造能力がすべてチップタイプのMLCCに振り分けられている為でしょうか。
ちなみにラジアルリード型は片側のみ端子が出ているタイプです。両側から出ているのはアキシャルリード型です。(主に抵抗がアキシャルリードタイプです)

・10uF

http://akizukidenshi.com/catalog/g/gP-05103/
10uFと大容量なのに積層セラミック。値段も0.1uFの3倍です。30円ですけど。
マイコン内蔵レギュレータ用のコンデンサです。このマイコンはI/Oが3.3Vで、コアは1Vちょいで動作しているようです。

・10kΩ x3

http://akizukidenshi.com/catalog/g/gR-16103/

マイコン用MCLR用抵抗、I2Cバス用抵抗x2です。I2C液晶駆動用です。
使用している液晶は低消費電力設計なので引き込み可能な電流が極めて小さく、I2Cバスのプルアップ抵抗には10Kが最低でも必要になります。

※10kΩは下にもまた出てきます。

・USB miniB

http://akizukidenshi.com/catalog/g/gC-02235/

安心のスルーホール実装(基板貫通)です。
基板に実装するときには、ぴったりと位置を合わせてちょっと斜めに押し込むような感じで入れる必要があります。
信号端子が、きちんと穴に入っていないと、押し込んだ時に非常に曲がりやすいです。
外装のGND端子だけでなく、5本の端子がきちんとスルーホールに入っているか見ながらゆっくり挿入してください。

・OSB5XA7DA4B-GH(青LED)

http://akizukidenshi.com/catalog/g/gI-02754/

安くて安心の青LEDです。
20本入り。

・680Ω

http://akizukidenshi.com/catalog/g/gR-16681/

LED用の電流制限抵抗です。
まぶしくない明るさにしていますが、明るくしたいならもうちょっと低い抵抗を利用してください。

・DM3AT-SF-PEJM5

http://akizukidenshi.com/catalog/g/gC-02395/

ヒロセのマイクロSDカードスロットです。
表面実装な上にピッチが狭く、樹脂部分も多いため、半田付け時の熱にも注意が必要です。
カード挿入検出スイッチは側面にあります。割と金属板がむき出しなので、半田付け作業時ここにフラックスなどがかからないようにしてください。
SDカードの挿入検知ができなくなる場合があります。
カードを挿入しても反応せず、この部分を爪で押さえたりすると検知する場合、ここが接触不良です。

・YM2151

・YM3012

FM音源チップと専用DACです。
何とか手に入れてください。

・TLC2274AIN / TLC2274IN x2

https://jp.rs-online.com/web/p/op-amps/3312182/
OPAMPです。秋月では取り扱いがありません。

4回路入力なRailtoRailであれば、他のOPAMPでも大丈夫のようです。
NUJ7044Dhttp://akizukidenshi.com/catalog/g/gI-02371/とか。
#ピンアサインが同一であるか確認してください

・水晶発振器4MHz

http://akizukidenshi.com/catalog/g/gP-10387/
水晶発振子+発振回路が内蔵された水晶発信器です。
2151用なのですが、3.58MHzが必要な場合は、http://akizukidenshi.com/catalog/g/gP-10386/を使ってください。ソケットで交換可能にするとかもありです。
なんとTO92型(トランジスタとかのパッケージ形状)です。

・水晶発振器8MHz

http://akizukidenshi.com/catalog/g/gP-10388/
こちらは2608用です。
TO92型ですが、サイズがやや大きめなので寝かせて取り付けることになります。
古い4759基板では手前に倒していましたが、うつ伏せでかわいそうだったので、現在の基板では仰向けに配置しています。

・MUSE 10uF x6

http://akizukidenshi.com/catalog/g/gP-04638/

音響用のMUSEコンデンサです。
50V品を使っています。大きいのですが、安定感があります。
無極性の為、どちら向きに取り付けても問題ありません。
YM3012とYM3016の間はかなりスペースが苦しいので、ここだけ25V品(http://akizukidenshi.com/catalog/g/gP-04624/)を利用したほうがいいかもしれません。

・MUSE 4.7uF x7

http://akizukidenshi.com/catalog/g/gP-04637/

音響用の4.7uFです。こちらも50V品を使っています。
25V品は細くて。

・MJ-8435 x2

http://akizukidenshi.com/catalog/g/gC-09060/

ステレオミニジャックです。
ミキシング運用前提なら1つだけで大丈夫です。

・8.2kΩ x8

http://akizukidenshi.com/catalog/g/gR-16822/

・3.9kΩ x6

http://akizukidenshi.com/catalog/g/gR-16392/

・33Ω

http://akizukidenshi.com/catalog/g/gR-08517/

・270Ω

http://akizukidenshi.com/catalog/g/gR-16271/

OPAMP周りの抵抗郡です。
33Ωは金属皮膜しかなかったので、金属皮膜です。

・1000pF x8

http://akizukidenshi.com/catalog/g/gP-07673/

音響に良いとされているフィルムコンデンサです。
値段も安くて良いのですが、ちょっと高さがあります。

・1500pF x2

http://akizukidenshi.com/catalog/g/gP-08133/

1500pFのコンデンサです。フィルムコンデンサがない為、
積層セラミックコンデンサになっています。
5mmピッチなので、足を補正して2.5mmに直してください。

・2700pF x2

http://akizukidenshi.com/catalog/g/gP-08119/
2700pFのコンデンサです。フィルムコンデンサがない為、
積層セラミックコンデンサになっています。
5mmピッチなので、足を補正して2.5mmに直してください。

・68pF

http://akizukidenshi.com/catalog/g/gP-06878/
YM3016Dのリファレンス回路に合ったコンデンサです。どうやらノイズ対策用部品の模様です。

・NJM2845DL1-33

http://akizukidenshi.com/catalog/g/gI-11299/

3.3Vのレギュレータを使っています。
ただし、この部品は前半が同じ型番で、後半の33の部分だけが異なる部品があります。
05の5V版と18の1.8V版(秋月では廃盤のようなので出てきません)と間違えないでください。

#たまに間違える人がいるのですが、その原因がわかりました。
該当の品は1個単位でしか売っていませんが、なぜか下に4個セットがお勧め表示されています。騙されてはいけません。その4個セットは5V品です。
1個だけだと不安だし、複数個欲しいからとセット品を買うと間違えます。
前は3.3Vの4個セットも売っていたのですが、セット売りは廃盤になりました。

・BS170

http://akizukidenshi.com/catalog/g/gI-09724/
液晶のバックライト制御用のFETです。

・100kΩ

http://akizukidenshi.com/catalog/g/gR-16104/
液晶のバックライト制御用FETのゲート放電用です。

・10Ω (炭素皮膜)

http://akizukidenshi.com/catalog/g/gR-16100/
液晶のバックライト制御用FETのゲートへの突入電流制限用です。
マイコン保護用に入れてます。
ここには炭素皮膜品で十分ですが、DACに使っている金属皮膜抵抗の10Ωが流用できますので、すでに持っている場合を除き炭素皮膜を新たに購入する必要はありません。
金属皮膜品 > 炭素皮膜品なので、値段が2倍しますが、金属皮膜を使ってください。

・47Ω

http://akizukidenshi.com/catalog/g/gR-08518/
液晶のバックライトLED用の電流制限抵抗です。
1/6Wサイズですが、許容電流が1/4Wな金属皮膜抵抗を利用しています。

・1uF x3

http://akizukidenshi.com/catalog/g/gP-04066/
液晶内蔵のレギュレータ用のコンデンサです。
0.1uFでもいけそうなんですが、液晶の説明書には1uFと書いてあるのでそのままです。
また、電源のノイズ吸収用にも1つ実装しています。

・AQM0802A-FLW-GBW

http://akizukidenshi.com/catalog/g/gP-09422/

非常に高価で脆いバックライト付きI2C接続キャラクタ液晶です。
液晶本体は非常にデリケートです。液晶の端子に少しでも負荷をかけると直ぐ壊れます。
ぱきっとか音が鳴ったらもう壊れています。
この液晶はマイコンの上にかぶせる形で配置されます。この液晶をつけてからマイコンの接触不良が判明した場合、修正の為には液晶の取り外しが必要になります。
液晶は必ず最後に取り付けるようにしてください。
PCに接続して、COMデバイスが認識されるか動作を確認するなど、マイコンが完全に動作することを確認してから取り付けるようにしてください。

なお、この液晶にフラッシュ撮影等の強い光を当てると、ガラス側から制御回路側に強い光が回り込んで誤動作する場合があります。
この状態になったら直ちに基板の電源を落としてください。
液晶はAC駆動することが前提のデバイスなので、制御回路がおかしい状態だとDC駆動してしまう事があり、液晶に回復不可能なダメージが残る可能性があります。

・タクトSW

http://akizukidenshi.com/catalog/g/gP-03648/
1つ10円(100個詰め合わせだと7円)のタクトスイッチ。
結構耐久性に欠ける気がしてならないのですが、そこまで押さなければたぶん大丈夫。
リセットスイッチは省略してもかまいません。

・YM2608B

・YM3016D

OPNAチップと専用DACです。
これもYM2151と同様に手に入れてください。

・74HC04

http://akizukidenshi.com/catalog/g/gI-08596/
インバーターです。YM2608のメモリアクセスは正論理なのです。なぜか。
一般的なチップのCEは負論理なので、反転が必要なのです。

・M11B416256A-35J(4Mbit)

http://akizukidenshi.com/catalog/g/gI-01451/
4MBit(512KB)のDRAMです。
YM2608のADPCM用です。256KBでよいので実際には半分しか使っていません。
なのでYM2608にDRAMに書き込みをさせつつ、マイコンで余っている1ビットを制御してやれば
実は2バンク使えるのではないかとも思いましたが、やってないところを見ると、このメモリアドレス線は256KB分しかなく、16ビット接続で512KBだった気がします。つまり面倒になってやめました。

・ソケットS64ピン

http://akizukidenshi.com/catalog/g/gP-04602/
64ピンはピン間1.778mmのシュリンク品です。1つ200円もする高価な部品です。
板バネ式は50円と脅威の価格差です。

・24ピンICソケット

http://akizukidenshi.com/catalog/g/gP-00032/
幅600mil品です。

・ソケット14ピン x3

http://akizukidenshi.com/catalog/g/gP-00028/
丸ピンICソケットを利用してください。
安い板バネ式もありますが、正直直ぐ壊れます。ちょっとでも力をかけようものならすぽっと抜けていくのです。
なお、物によっては幅が600milと300milがある場合があるので、注意してください。

・ソケット16ピン x2

http://akizukidenshi.com/catalog/g/gP-00029/
丸ピンICソケットです。

・10kΩ x8

http://akizukidenshi.com/catalog/g/gR-16103/
ADPCM用メモリチップのプルダウン用抵抗です。
なくても動く気がしますが、未接続は誤動作の元なので処理しています。
※10kΩの抵抗は別の場所でも使われています。数をカウントする場合は必要な数を合計してください

・10Ω(5V用) x2

http://akizukidenshi.com/catalog/g/gR-08515/
10Ωですが、金属皮膜の大電流用です。
こちらは5VのUSB電源からDACのアナログ系に流れるところでノイズ低減の為に入れています。
10Ωx1だとなんか電流が不足していた感じだったので、2つにしました。ノイズ低減用なので、気にしなければ別にジャンパでもいいとは思います。
FET制御用に1本10Ω抵抗がありますが、この金属皮膜で代用できますのでこちらを使うならば炭素皮膜側は必要ありません。値段が2倍するのでもったいないけど。

・1kΩ(SSG用)

http://akizukidenshi.com/catalog/g/gR-16102/
SSG音源はある程度電流を流さないと出力が出てきません。
電流を流すための抵抗です。

・270Ω

http://akizukidenshi.com/catalog/g/gR-16271/
DAC用です。

・4.7KΩ

http://akizukidenshi.com/catalog/g/gR-16472/
DACに使っています。ビット列の選択用のピンです。
10kΩでも問題ないと思いますが、参考にした回路が4.7kΩだったので伝統的にそのまま利用しています。
古いチップなのである程度電流が流れた方がなんだか安心できます。

・2kΩ半固定抵抗

http://akizukidenshi.com/catalog/g/gP-06061/
SSGのミキシングボリュームに使っています。
これもオリジナル部品を作っていたメーカーがディスコンになったので、セカンドソースメーカーに切り替わっています。
電子ボリュームチップ(2500円)は高いのです。
ちなみに英語名はポテンショメータです。微妙に覚えてない名称で困ります。
旧基板では10kΩ(103)を使っていました。10kΩだと結局ボリュームの小さいほうのみで調整していたので、抵抗値を下げました。

・タクトSW x3

http://akizukidenshi.com/catalog/g/gP-03649/
http://akizukidenshi.com/catalog/g/gP-03651/
http://akizukidenshi.com/catalog/g/gP-03650/
リセットSW側で出てきたので省略します。

・ピンヘッダx2

・ピンヘッダ2x2

http://akizukidenshi.com/catalog/g/gC-00167/
または
http://akizukidenshi.com/catalog/g/gC-00082/
USB側の電源のみでACアダプタを使わない場合は、省略し、ジャンパ線でショートさせてかまいません。
PICKIT3接続用のピンヘッダも用意した方が便利ではあります。
2151と2608の出力をミキシングする場合にも利用します。

・ジャンパピンx4

http://akizukidenshi.com/catalog/g/gP-03689/
ACアダプタを使わず、USBから供給する場合はピンヘッダにジャンパピンをセットし、電源を供給してください。
ジャンパが不要な場合は、直接ブリッジしてもかまいません。
2151と2608の出力をミキシングする場合にも利用できます。

・DCジャック

http://akizukidenshi.com/catalog/g/gC-01604
シンガトロン社製のジャックです。
マル信のでもかまいません。(http://akizukidenshi.com/catalog/g/gC-00077/)
が、ACアダプタを使わずUSB接続だけで電力供給するならば要りません。
あ、接続するACアダプタの電圧は5Vで、センタープラスになります。今時のACアダプタ(http://akizukidenshi.com/catalog/g/gM-01801/)ならOKです。

・OSコン16V 220uF

http://akizukidenshi.com/catalog/g/gP-08291/
OSコンの220uFバージョンです。別に100uFでも大丈夫だと思いますが、大きさ的に220uFがちょうどいいサイズにしています。
極性があります。

・RXEF050

http://akizukidenshi.com/catalog/g/gP-01355/
500mA品です。


・ファームウェアの書き込み方


PICKIT3をターゲットボードに接続する準備ができたら、MPLAB Xをインストールすると
一緒にインストールされるMPLAB IPEを起動します。

MPLAB IPEは古典的なダイアログベースのアプリケーションのように見えます。
画面サイズが1024x768くらいないと、ボタンが画面外に飛び出てしまい、押すのが困難だったりするのでなんとかしてください。


・MPLAB最新版(v5.1)でのインストールについて


ためしに最新版(https://www.microchip.com/mplabx-ide-windows-installer)を入れてみました。

1.インストーラーを起動します。


2.利用規約に同意します。


3.インストール場所を選択します。


4.インストールオプションを選択します。
MPLAB IPEには最初からチェックがついていると思いますが、チェックがついていることを確認してください。
一番下のオプションはイヤなら外してください。


5.インストールします。


6.最後あたりにATMELの何かをインストールするか聞いてくるのですが不要です。キャンセルでOK。
デフォルトでしないにフォーカスが当たっていますし。


7.情報が出る場合があります。昔のも入っているとでるかも。
出た場合はOKを押します。


8.インストール後にコンパイラなどを入れるかを聞かれます。
MPLAB IDEで開発もします!って言う人は是非入れてみてください。

ファームウェアを書き込みたいだけの人はチェックを外して入れてください


9.MPLAB IPEを起動します。


10.MPLAB IPEが起動しました。
PICKIT3を接続しておかなかった場合は、この段階でPICKIT3を接続しておきましょう。
かってにToolのところが更新されます。
次に、チップを選んでおきましょう。「PIC32MX270F256D」を選択してください。


11.HEXファイルを読み込みます。

#なんだかグレーアウトして読み込めない事も多いみたいなので、そういう時は画面中央にあるHex File欄のブラウズボタンを押して読んだ方が早いです

12.チップを選択して「PIC32MX270F256D」を選択します。
※この時に違うチップとか選択した状態だと、実はちゃんと読み込めていません。
 スクリーンショットは読み込んだみたいに見えているのですが、チップを選択していない状態でHEXを読み、
 その後にチップを選択しています。すると、真ん中のグレーのエリアの「Hex file:」のところがグレーのままです。
 もうチップ選択から一度やり直しです。
 左のメニューみたいなのは、13以降で切り替えるAdvancedメニューの画面です


13.Advancedモードに切り替えます。


14.このときパスワードを聞かれますが、デフォルトは「microchip」と書いてあるので、入力してください。


15.左にメニューが追加されるので、「Power」ボタンを押してください。
右に電源設定メニューが出てくるので、「Power Target circuit from Tool」にチェックを入れてください。
終わったら「Operate」メニューに戻しておきます。


16.ターゲットボードにPICKITを接続して、Toolの横にあるConnectボタンを押します。
この時にPICKITが初期設定のままだと、PICKIT自体のファームウェア更新が開始されます。
数分程度またされます。
※この画面では、チップ選択を後から替えた為に、Hexファイルの表示がグレーアウトしたままです。


17.もし、Connectボタンを押した時点で、画面のようなメッセージ「電力不足」が出た場合は、以下の対策を行ってください。
・ターゲットボードからマイコン以外のチップを外す
・ターゲットボードのUSBから電源を供給する
製作途中の場合は、LEDの点滅を確認するために最低限マイコンが動作する部品をつけたところなどで確認していると思うので、
たぶんでないと思います。
ちなみに今回はチップを外すのが面倒だったので、USBコネクタから電源を供給しています。


18.Hexファイルが選択されていて、Connectにも成功していれば、Programボタンを押してください。
ファームウェアの書き込みが開始されます。およそ20秒ちょいかかります。
!!書き込み中に接触が悪くなるとマイコンが破壊されます!!


19.無事に書き込みが完了しました。
この時にLEDなどが実装されていれば、書き込み完了した瞬間からLEDが点滅を開始します。


・MPLAB最新版(v5.1)にしたついでにMPLAB SNAP(※書き込みには結構新しいMPLAB(5.x以上)が必要)でファームウェアを書いてみる




秋月で取り扱いが開始された激安PICプログラマ(兼デバッガ等)である、MPLAB SNAPでファームウェアが書き込めるかやってみました。

・初めて接続した時にデバイスドライバのインストールが実行されました。

・MPLAB IPEで初回コネクト時に、SNAPのファームウェアが更新されました。

・書き込みが、2秒程度で終わりました。PICKIT3の10倍くらい早いです。
 じっとしている時間が短くで済むのでいいかもしれません。
 #PICKIT4も早いらしいので、PICKIT3が遅いんでしょうか

とうわけでできるみたいです。
が、ひとつ気になったのは、ファームウェアの書き込み時に電力が不足していた場合でも、そうとわかる通知メッセージが出なかったことでした。
デバイスIDが0、ターゲットデバイスが検出できないといったエラーがでます。接続を間違えたのかと思いましたが、
ターゲットボードにUSBから電力を供給した状態にしたら無事認識。書き込みできました。
#今やったらデバイスのコード領域がプロテクトされていると出ました。やっぱり電力を供給してやりながら書き込めば成功しました
・・・ていうか、MPLAB SNAPってひょっとしてターゲットへの電力供給機能がないかも。MPLAB IDEだと電源供給メニューが出てきません。


ちなみにSNAPは8本接続できるのですが、ターゲットボードには▲マークから5本分接続するだけでOKです。
ピンが余るのはPICプログラマの伝統みたいなものです。(余ったピンはPICに書き込む以外で使ったりします)

■ファームウェア・支援ソフトウェア

・PCに繋いだ場合と開発ツールについて

携帯FM音源プレイヤー及びYM2608音源ボードは、PCに接続すると仮想COMポートとして認識されます。
PCからはこのCOMポートを通じて制御することができます。
ドライバはそのまま標準ドライバで認識されると思うのですが、もし認識されない場合は、フェームウェアの
書き込みで使うMPLAB Xをインストールしていれば認識すると思います。

サンプルのプログラムは仮想COMポートが3もしくは4として認識されることを規定値にしています。
他のポートの場合は引数で指定するか、USBへの差込位置を変更して認識されるようにしてください。
同時に他の仮想COMポートを使用するソフトを利用していた場合、悪影響を与えることがありますので、
そういった場合は、他の仮想COMポートのソフトやハードを外してください。

※COMポートの設定はデフォルト値(9600bps等)で構いません。
9600bps設定のままでも、プログラムから叩く分には115200bps以上出ます。
これはこのボードが仮想COMポートそのものだからです。
このボードから外部に通信する場合は、設定を見て速度を決定しますが、音源ボードそのものがCOMポートなので
ボードへの通信は速度設定に影響されません。


・ブートローダーを使ったファームウェア更新方法について(2023/3/5公開のv1.11移行のファームウェアの更新方法について)

■OPNAMシリーズ用ブートローダーを使ったファームウェア更新方法

1.PICKITで、まずブートローダーのFWを書き込みます。

bootloader〜.hex

※bootloaderから始まるhexファイルを書き込んでください。


2.この状態でリセットなどをすれば、ブートローダ画面が立ち上がるようになります。
起動しない場合はリセットボタンを押したり、USBケーブルをいったん抜いて再度接続してください。
ブートローダが起動した場合、ボタンなどは効かず、LEDがやや早めに点滅します。


3.ブートローダーが起動していれば、PICKITを接続する必要はありません。
この状態で、PC上でファーム更新プログラムを使いブートローダに対応したファームウェアを書き込みます。
 更新プログラムはコマンドラインで打ち込みます。


実行コマンドライン例
bootloader.exe 4759〜_v121_bld.hex


 更新結果などを見なくてもよいという場合は、bootloader.exeに4759〜_v121_bld.hexをドラッグ&ドロップすることでも可能です
 終了するとコマンドプロンプトがさっと消えるので結果を確認できませんが、どのみち成功したかどうかはボードを見ればわかります


注意:エラーが出る場合は、ボードのリセットボタンを押す等、ファームウェア更新モードを再度起動してからコマンドを実行してください
   起動してから1分程度経過するとコマンドを受け付けなくなります(Harmonyが出力した公式のブートローダーなのにー)


bootloader.exeは、ファームウェアが正常に更新できると、自動的にリセットをかけて再起動します。

起動したOPNAMシリーズが、通常の画面であるかを確認してください。


■新しいファームウェアが出た時に、ファームウェアを更新する場合

PICKITを使った更新は不要です

PCとOPNAMシリーズをUSBケーブルで接続し、S1とS2ボタン(一番左と真ん中)を押したままリセットボタンを押してください。
ブートローダー画面で起動します。
この状態で新しいファームウェアファイルを指定してコマンドを実行することで、ファームウェアを更新することができます。

※更新時にエラーが出る場合は、いったんボードをリセットして、手早く更新を再度実行してください


・4759FM音源ボード用 ソフトウェア

4759FM音源ボード用ファームウェア

・bootloaderのみの単体セット
bootloaderset_14a.zip ※v1.4a未満,v1.4a,v1.4a2基板用です
bootloaderset_14c.zip ※v1.4b,v1.4c基板用です

■rev.2023/6/22 v1.16
4759firmware_14c_v116_bld.zip v1.4b,v1.4c基板用です
4759firmware_14a_v116_bld.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
ブートローダー2用のファームウェアです

・ボタンをダウンエッジからアップエッジ(※)に変更する拡張オプション(Button Enhance)を追加
 拡張状態では、長押しによるアクションが追加されます
 ※ボタンの動作を、押した時に動作から、押して離した時に動作に変更するオプションです
 
 長押しにより、サブディレクトリ単位での戻し、先送りができるようになります
 中央ボタン長押しで直接設定画面(Config)に入れるようになります
 Config画面では、左ボタン長押しで先頭メニューへ、右ボタン長押しで最後のExitへ遷移できます

・一部のMDXで演奏が正常に行われない問題を修正しました

■rev.2023/6/16 v1.15
4759firmware_14c_v115_bld.zip v1.4b,v1.4c基板用です
4759firmware_14a_v115_bld.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
ブートローダー2用のファームウェアです

・PMD形式の再生が指定時間で終了しない問題を修正
・PMDドライバのパッチを正式版に更新
 ・演奏が終了したら次の曲に即座に遷移(前回までのパッチは時間で遷移)
 ・2ループで終了するように対応(設定のLoopBreakerが有効な時)

 パッチを更新したので、pmdset.zip内のpmd86.binを更新しました。ダウンロードしなおし、
 SDカードにPMD演奏ドライバ(pmdset.zip)を入れてください

■rev.2023/6/12 v1.14
4759firmware_14c_v114_bld.zip v1.4b,v1.4c基板用です
4759firmware_14a_v114_bld.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
ブートローダー2用のファームウェアです

・PMD形式の曲ファイル再生用セットを追加しました
 SDカードにPMD演奏ドライバ(pmdset.zip)を入れてください(補足参照)
※更新補足

・PMD形式の再生
 pmdset.zipをDLし、ZIPファイルを展開してpmd86.binをSDカードのルートディレクトリにコピーしてください
 後は、再生したいPMDの曲ファイルをSDカードのサブディレクトリに格納しておけば再生されます

 制限事項
 ・PMDファイルはサブディレクトリに配置してください
  pmd86.binを見つけた後に、発見した曲ファイルが有効になる為、ルートディレクトリに配置されたpmdファイルは読み込まれるかどうか不明です
  スキャンはディレクトリエントリ順に処理されるため

 ・PMD曲の再生は固定で2分の再生時間となっています。曲が早めに終わっても2分間は次の曲に自動的には進みません
  これはPMD86.BINのパッチによるもので、再生終了フラグなどを見てない為です。そのうち対応するかもしれません


 ZIP内のファイルについて

  ・pmd86.bin
   OPNAMで演奏できるようにパッチを当てたpmd音源ドライバです。SDカードのルートディレクトリにはこのファイルを配置してください

   パッチ内容としては、OPNAMがチェックするバッファとの橋渡し、割り込み周りの処理、I/Oで2回inportしている処理の削除などです。
   パッチ箇所が多いですが、高速化のためにつぶしている部分が多い為です

  ・PMD86.COM
   PMD86の98x1用のFM音源ドライバです。
   オリジナルのドライバとしてセットしていますが、OPNAMでは使いません

  ・pmd_patch.exe
   PMD86.COMにパッチをあて、pmd86.binを作る為のパッチプログラムです
   オリジナルドライバからの作成用として同梱しています


 今回、PMDドライバの配布に関してはKAJA氏に許可をいただきました。ありがとうございました!

■rev.2023/5/13 v1.13
4759firmware_14c_v113set.zip v1.4b,v1.4c基板用です
4759firmware_14a_v113set.zip v1.4未満,v1.4a,v1.4a2基板用です
※都合によりBootloader2になりました。旧bootloaderのままでは利用できません
ブートローダーもブートローダー2に更新してください

※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
ブートローダー用のファームウェアです

・フォルダ毎の設定ファイルsetting.cfgに、ここ最近追加されたConfigを追加
 setting.cfgはv1.07から追加されたフォルダ毎にOPNAMの設定を変更する機能です
 詳細は下にある「SETTING.CFGの使い方」を参照してください
・一定の時間(60秒、120秒、180秒)で次の曲に進むAutoSkip設定を追加しました


■rev.2023/3/18 v1.12
4759firmware_14c_v112set.zip v1.4b,v1.4c基板用です
4759firmware_v112set.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
ブートローダー用のファームウェアです

・2608のクロック設定が起動時に正常に設定されていない問題を修正
・USB CDC読み込みのフレームワークを調整
・SCCI wait設定を追加。Lv.0で従来設定値。1〜3で従来よりも増加。-1〜-4で従来よりも減少。Lv.-4はNOWAITです


■rev.2023/3/5 v1.11
4759firmware_14c_v111set.zip v1.4b,v1.4c基板用です
4759firmware_v111set.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・ブートローダー用のファームウェアになりました。更新にはWindowsPCが必要になります(たぶん今までもそうだと思いますが)
 この上に追記した「ブートローダーを使ったファームウェア更新方法について」を参照してください
・シリアルコンソールモードにミュートコマンドを追加


■rev.2023/1/14 v1.10
4759firmware_14c_v110.zip v1.4b,v1.4c基板用です
4759firmware_v110.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・ループブレーカー設定に、無限(Inf.)を追加しました。曲が終わった場合でも再度同じ曲が再生されます


■rev.2022/11/17 v1.09
4759firmware_14c_v109.zip v1.4b,v1.4c基板用です
4759firmware_v109.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・s98で2608 A0側のレジスタウェイトを正しく設定していない問題を修正
・vgmで正常にループしない場合がある問題を修正
 (タイミング調整カウントリセットミスを修正)
・コンソールに、チップテスト用の簡易MML演奏コマンドを追加
 現状はt,l,o,<,>,cdefgabなどの基本コマンドのみ
 mml initで初期化してから、mml A t192l1o5cdefgab>cのようにしてChにMMLを追加
 mml playで全Ch演奏
 Chは以下の並びになっています
 A,B,C,D,E,F 2608FM
 G,H,I 2608SSG
 J,K,L,M,N,O 2608RYTHM
 P 2608ADPCM(未実装)
 Q,R,S,T,U,V,W,X 2151FM


■rev.2022/8/16 v1.08
4759firmware_14c_v108.zip v1.4b,v1.4c基板用です
4759firmware_v108.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・vgm形式時、ADPCMデータ書き込み専用コマンドの対応を追加(コマンド0x67)
・ログ形式再生時のADPCMウェイト量の調整オプション追加
・一部1.07で追加されたConfig設定が操作できない問題を修正
・Consoleモード修正
 ・細かいバグ修正(バッファ処理修正、テキストミス修正、2608ボリューム制御修正)
 ・ロングファイル名が表示されない場合がある問題を修正(セクタをまたぐときにクリアしてた)
 ・fmsコマンド追加 1秒間おきにfmコマンドを実行してレジスタを表示します


■rev.2022/7/16 v1.07
4759firmware_14c_v107.zip v1.4b,v1.4c基板用です
4759firmware_v107.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・2608パン反転設定が、SSGボリューム調整をいじるとリセットされるバグを修正
・フォルダ内にsetting.cfgファイルを設置すると、フォルダ内を再生している間setting.cfgで指定した設定に変更する機能を追加
 ※フォルダから出ると戻ります。さらに手動で設定をいじった場合でも戻ります
設定ファイルは以下のツールサンプルファイルをDLして確認してください。
setting.zip


■rev.2022/6/11 v1.06
4759firmware_14c_v106.zip v1.4b,v1.4c基板用です
4759firmware_v106.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・Harmonyフレームワークをv1.07からv2.06に変更(Proと同じ)
 →USBフレームワークが標準の状態に戻りました。速度は変化(遅いかも)したかも?
  ついでにUSB認識の名前がデフォルト設定から変更されています
・2151と2608のパンを反転するオプションを追加
 →それぞれ左右を反転できます
・SSGボリューム簡易調整オプションを追加
 →いちいちボリュームをいじるのが面倒な場合用に、簡易的にいじれる設定を追加しました
・従来のUSB制御モード(※)をシリアルコンソールで制御できるように変更 ※SCCIとは別
  TeraTermなどのコンソールをご利用ください。改行コードはLFしか送ってきませんので、LF→CRLF変換してください。
  基板作成時のピン半田付け確認などが便利に使えます。
  使い方は、このドキュメントの一番下につけ足してあります。注意点もあるので、使う前にお読みください。
・SDエラー検出追加
 →不完全かもですが、追加しました。
・VGM再生中に一定回数のI/O操作でCPUを解放するように変更
 →s98の方は入ってたんですが、VGMの方に入ってなかったので追加

※大幅にいじったので何かあったら前のバージョンに戻すなどでお願いします


■rev.2022/4/13 v1.04
4759firmware_14c_v104.zip v1.4b,v1.4c基板用です
4759firmware_v104.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・リセットタイプをSoftにした時に、正常に2608がキーオフされない問題を修正(0x28と書くところが28と書いてあった)
・曲間の間を設けるBlankWait設定を追加。0〜3秒のウェイトを設定できます。


■rev.2022/2/18 v1.03
4759firmware_14c_v103.zip v1.4b,v1.4c基板用です
4759firmware_v103.zip v1.4未満,v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・ディレクトリ内のファイルを昇順ソートするオプションを追加
 ※設定保存をミスってたので、config.cfgによってはいきなり有効になってます


■rev.2022/2/12 v1.02
4759firmware_14c_v102.zip v1.4b,v1.4c基板用です
4759firmware_v102.zip v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・1秒程度の短いs98,vgmの場合、ループブレイカーが有効でもループが終わらない問題を修正

※ちなみにv1.4未満のハードウェアの場合はv1.4a版を入れてください


■rev.2022/1/18 v1.01
4759firmware_14c_v101.zip v1.4b,v1.4c基板用です
4759firmware_v101.zip v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・S98形式のYM2203(タイプ2)を再生対象にするように修正


■rev.2021/10/6 v1.00
4759firmware_14c_v100.zip v1.4b,v1.4c基板用です
4759firmware_v100.zip v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・SCCI Lightの2151処理を修正しました


■rev.2021/5/6 v0.92
4759firmware_14c_v092.zip v1.4b,v1.4c基板用です
4759firmware_v092.zip v1.4a,v1.4a2基板用です
※基板のバージョンにあったファームウェアを入れてください。2151と2608への供給クロックが逆の為、間違えると音源チップが最悪壊れます
・USBから制御するモードが、SCCIに名称が変更になりました。
・SCCIの処理を改善しました
 バッファリングの廃止。2151と2608の処理を分離。ウェイトを削減
・SCCI中に液晶更新を行わないFASTモードを追加
 Normal→Normal Fast→Light→Light Fastの順に切り替わります。
 ※Lightに切り替える場合、従来よりも余計にボタンを押す必要があります。


■rev.2020/11/14 v1.4b/v1.4c基板専用 v0.91A
4759firmware_14c_v091a.zip
・秋月PLL基板を使用する v1.4b/v1.4c基板を利用されている方用ファームウェアです。
 v1.4b/v1.4c秋月PLL基板を使ったクロック出力用のファームウェアです。
※v1.4a/v1.4a2基板の方はご利用にならないでください。音源チップが最悪壊れます

■rev.2020/6/24 v0.91A
4759firmware_v091a.zip
・PlayListの有効・無効設定を追加しました
・SD再生時、曲毎にリセットする設定に、キーオフだけ行うソフトリセットメニューを追加しました
・ハードリセットを行うリセットメニューを追加しました
・PLLで2151及び2608のクロックを制御するようになりました(基板1.4以上のみ)
 1.3c以下のバージョンでは現状通りとなります
・2608クロックの選択メニューを追加しました(基板1.4以上のみ)

※0.73未満のFirmwareからアップされる場合、Configファイルが拡張されている為、一度SDカード内のconfig.cfgファイルを削除してください

■rev.2020/4/27 v0.81A
4759firmware_v081a.zip
・COMの入出力を独立処理版に変更
・USBフレームワーク再調整

■rev.2020/4/26 v0.81
・USBフレームワーク調整
→正常に動作しない場合が多いので、頒布中止

■rev.2020/3/29 v0.80B
4759firmware_v080b.zip
・ウェイト回り再調整

■rev.2020/3/28 v0.80A
4759firmware_v080a.zip
・大幅なソース整理&USBフレームワーク調整
 βテスト用です。不具合があった場合は0.74又は0.75へ戻してください。

■rev.2020/1/23 v0.75
4759firmware_v075.zip
・タイマ周りの制御レジスタを2608へも書き込むように変更
 βテスター向けです。

■rev.2019/11/30 v0.74
4759firmware_v074.zip
・DisplayModeにautoを追加
・SPFMモードで再生中にDisplayModeを変更する(右ボタン)時、2151のタイプB(2151b)が選べない問題を修正
・SDカードからの再生中、左上に余白がある場合でも、三角の再生マークが出ない場合が多い問題を修正(なんか見るとこ間違ってた)

■rev.2019/11/21 v0.73
4759firmware_v073.zip
・Configメニューに2151クロック切り替え設定を追加しました(実際に切り替えるには追加ハードウェアが必要です)
・EXT端子(基板を手前から見て右から2つ目のRA10)に2151クロック切り替え用情報を出力するようになりました。(自動の場合は曲データのクロックが3.8MHz未満の場合、または手動で3.58MHzを指定した場合、3.3Vが出力されます)
・SDカード未挿入時、右ボタン長押しで2151クロック状態を切り替えることができるようになりました。
・Holdメニューを追加しました。Configファイルを読み込んで各種設定を反映した後、Holdが有効になっていた場合は、ボタンを押すまで一時停止します
 SPFMメインで使う場合などにご活用ください。
・Config設定ファイルのサイズが16バイトになりました。動きがおかしい場合は一度configファイルを消してください。ファイルサイズは8バイトのままでも16バイト使っていますので
・2151レベル表示にタイプBを追加しました。タイプBの場合は、左上に曲データ(または手動設定)のクロック表示4M、3Mが出ます。

■rev.2019/11/10 v0.72a 実験版
4759firmware_v072a.zip
・SPFM Lightモードで、SCCI 10/27版だとプレーヤー側が動作しない問題に対処(対処方法がこれでいいのかしら)
・内部ソースを整理していたタイミングなので不具合あるかも版

■rev.2019/9/28 v0.72
4759firmware_v072.zip
・USBからx86データの演奏開始コマンドを実行しても演奏が開始しない問題の修正
・プレイリストファイルの処理修正(最後以外にプレイリストファイルがあると、ファイルサイズを正しく処理しない。サイズ入れるとこ間違ってた)

■rev.2019/9/23 v0.71
4759firmware_v071.zip
・プレイリストファイルの再生に対応
 ■プレイリスト仕様
  ルートに置かれた2047バイト以下のplaylist.txtファイル。
  8+3ファイル名,コメント文<改行>
  8+3ファイル名,コメント文<改行>
  …
  8+3ファイル名のみです。パスは対応していません。ルートに演奏対象のファイルを置いてください。
  512エントリまで。(ファイルサイズ的に無理ですが)
  見つからないファイル、既定の書式に沿っていない行は無視します。
  1行は255バイトまで。使える文字コードについては、AQM0802のデータシートを参照してください。
  コメント文をGEQの代わりに液晶下段に表示する場合は、ConfigメニューのCommentを変更してください。
  ex.
  sample1.vgm,Theme of Sample 1
  smp2.mdx,samle file no.2
  sample03.s98,Sample of sound

■rev.2019/8/25 v0.70
4759firmware_v070.zip
・SPFMモード表示が液晶1行目の左のバーを消していたので修正
・高頻度で液晶が更新されているとと、液晶側がコマンドをスキップする場合があったので、I2Cウェイトを増加

■rev.2019/3/28 v0.63e
4759firmware_v063e.zip
・SPFM Lightモード時のCPU開放タイミングを1.5msに変更

■rev.2019/3/28 v0.63d
4759firmware_v063d.zip
・SPFM Lightモード時のCPU開放タイミングをSPFM Normalと同じに調整(2ms -> 1ms)

■rev.2019/3/28 v0.63c
4759firmware_v063c.zip
・一応今のところの最新版


マイクロSDカードはSDHC専用です。16GBの秋月電子のこのカードを利用しています。
FAT32でフォーマットされている必要があります。
SDXCも使えるかもしれません。(単なるSDはダメです)

左ボタンが戻る、真ん中が一時停止・再生、右ボタンが次へです。

音が小さいので、アンプでの再生をお勧めします。 SSGのミキシング音量は可変抵抗で調整してください。

・Configメニュー説明

ConfigメニューはSDカードを挿入し、演奏状態になっていないと出すことができません。
SDカード未挿入の時は、液晶下の左ボタンを長押しすることで、SPFMモードをLightまたは通常モードに切り替えることができます。
USBからSPFMで制御する場合、複数カードを利用する場合はSPFM Lightモードに切り替えた方が融通が効くようです。

演奏中に液晶下の真ん中のボタンを押すことで、一時停止します。このときに左ボタンを押すことでConfigメニューに入ることができます。
#ちなみに一時停止中に右ボタンを押すと演奏中のサブディレクトリを抜け、次の曲進みます

1.Loop Breaker

ループ指定されている曲の場合、2ループで演奏を中断します。

2.Shuffle

演奏曲をシャッフルして再生します。メモリの関係でディレクトリ内でのみ動作します。2000曲までです。

3.Reset YM2608 (v0.91以降は Reset FMChips に変わりました)

SDカード再生時、2608及び2151、3012、3016を曲ごとにリセットします。
リセット方式には、ハードウェアリセット、ソフトウェアリセット(キーオフのみ)があります。

4.BackLight

LCDのバックライトの点灯時間を設定します。操作時に自動点灯する時間を指定できます。

5.SPFM Mode

SPFMモードを通常かLightモードかを切り替えることができます。
複数枚の音源ボードを使い、任意に設定する必要がなければ、通常モードで十分かと思います。

6.2151Volume

ミキシング端子を使ってミキシングした場合、2151側の出力のほうが大きく聞こえる場合が多いようです。
その場合に、2151の音色のTLパラメータを操作して、2151側の音量を小さくする設定になります。
音色によっては微妙に音色がおかしくなる場合があります。あきらめてミキシングバランスを無視するか、
外部のミキサーで調整してください。

7.SubDirectory

サブディレクトリ内のファイルを演奏するかの設定です。
ルートディレクトリ直下の第一階層にあるディレクトリのみ演奏対象とします。(サブディレクトリのサブディレクトリは演奏されません)

8.YM2608Wait

YM2608アクセス時のウェイト時間を調整します。
YM2608Bではなく2608の場合、Heavyにしないと演奏が正常に行われない可能性があります。

9.Display Mode

液晶表示を切り替えます。
自動切換え、4759モード(3パターン)、2151モード、2608モード(2パターン)があります。

10.SD Speed

SDの速度を計測するベンチマークです。
なるべく高速なものの方が良いです。

11.2203/2608

2608の拡張モード状態を表示、切り替えます。
レジスタ0x29のbit7状態を表示、切り替えることができます。

12.SD LED

マイクロSDカードにアクセスするときにLEDを点灯するかしないかを切り替えることができます。

13.Comment

PlayListを再生しているときに、プレイリストに設定されているコメントを表示するか、キー状態を表示するかを切り替えます。

14.2151Clock

2151のクロックを切り替えます。
自動、4MHz、3.57MHzを切り替えることができます。

15.2608Clock

2608のクロックを切り替えます。
自動、8MHz、7.98MHzを切り替えることができます。

16.Hold

SDカードの内のファイルを自動的に再生開始しません。
Configファイルを読み込み設定を反映し、そのあとにボタンを押すまで停止状態となります。
SPFMメインで使う場合に使う設定です。

17.Playlist

Playlistファイルを見つけた場合に再生するかどうかを設定します。

18.Manual Reset

ボタンを押すと、2151及び2608、3012、3016をハードウェアリセットします。

19.Firmware

ファームウェアバージョンを表示します。

20.Save

Configファイルを書き出します。なるべく何も入っていない状態のSDカードで一度保存することをお勧めします。

21.Exit

Configを抜けて、演奏状態に戻ります。


・x86エミュレータの使い方

x86ドライバを改造して動作できる形式に加工すれば、オリジナルのドライバで演奏させることができるかもしれません。
演奏用のドライバの作り方及び改造の仕方を記載します。


・開発用の支援ツールです

2608サウンドデータヘッダエディタ

■rev.2018/12/30
2608fm_datedit.zip
制御ファームウェアがファイルデータを確認するためのヘッダ情報を設定するための支援ツールです。
1ループの時間を設定したり、タイマA及びBを使うかの設定をしたりします。
サウンドファイルを指定し、実行すればコマンドメニューが出てくるのでいじってください。

・フェードアウトするには

フェードアウトドライバー(がやらない)モードを有効に
フェードアウト時間(0.1秒単位で指定します。600なら1分になります)を、フェードアウトしたい時間の半分に設定。600を指定すれば、120秒で打ち切ります。

・指定した時間で打ち切るには

フェードアウト時間を、打ち切りしたい時間(0.1秒単位で指定します)に設定
制限終了フラグを有効に

にしてください。

2608PCから演奏ファイル転送プログラム

■rev.2018/12/30
2608play.zip
PCで指定したファイルをボードへ転送して演奏するプログラムです。
SDカードに入れる前に確認するのに使えますが、ファイルサイズは32KBまでです。
LOG形式のファイルは指定できません。

2608ボードテストツール

■rev.2018/12/30
2608testtool.zip
2608ボードをテストするためのツールです。
ニコニコ動画でボードをテストします、で使っていたツールです。
ボードを製造した後、テストするための機能がそろっているので、このツールを使ってテストしてください。
ADPCM用のファイルを準備してください。MDXに入っていたファイルを、2608用に変換して使っていました。
ADPCM用データの作成には、たしかベクターにあったツールを使っています。懐かしのこうのたけし氏謹製のツールでした。今時のPCで動かないので、VirtualXPモードなどでやってました。
コンソール用のツールです。
・コマンド
q   終了
c   ボードに接続 COMポート3もしくは4
r   リセット
ry  リズム音源。ry 1などで対応した音色がなります。6ビット分なので全部を鳴らすのは63になります。
l   adpcm用ファイルの読み込みと転送
t   演奏用ファイルの転送
p   ADPCMの再生。番号で鳴らすADPCMを選択します
o   YM2608に直接レジスタとデータを転送します。o レジスタ番号 データみたいな感じで指定します
n   SDカードから演奏中の場合次の曲に進みます

詳細はソースを見てください。
他のCOMポートにする場合は、ソース編集して再コンパイルしてください。

2608ボード開発支援ツールx86

■rev.2018/12/30
2608x86.zip
指定方法
ex.
x86emu.exe -com 3
バイナリのみです。大変だったし、色々恥ずかしいところだらけなので。
起動時にCOMポートのYM2608FM音源ボードに接続し、リセットコマンドを送付します。
この時につながっていないと、以降繋ぐコマンドがありませんので、起動しなおしてください。
YM2608サウンドファイル開発支援の為の、x86エミュレータデバッガです。
音源ボード内と同じx86コアを内蔵していますので、ここでテストして動作すれば、おそらくボードでも動作するでしょう。
x86ツールのターゲットファイルは1MBです。まずは1MBのファイルを作成してください。
完成後、このファイルを最終的には32KBまで加工し、ヘッダを埋め込んでデータファイルにします。
#自信があれば最初から32KBでもOKです

DOS時代のデバッガ、SYMDEBやフリーのddeb等のツールを使っていた方は、大体似たような使い方ができます。
#結構アドレス指定は適当に組んで、もうこれでいいや状態なので、アドレス指定周りは動きが怪しいです

自分用のツールだったので、エラー的な指定やでかいファイルなどを指定した場合は異常終了します。たぶん。
・コマンド
q 終了
n アクセス用ファイル名を指定
l ターゲットファイルを読み込みます。ファイル名は省略可能です。
w ターゲットファイルを保存します。ファイル名は省略可能です。
wc ウェイトキャンセル機能の有効・無効を切り替えます。有効の場合loop $等をスキップします
wait (数値) 実行モード中の'wait'命令の時間を指定します
p 次の行にブレークポイントを設定し、実行します。サブルーチンを飛び越える場合に便利ですが、アセンブラだと帰ってこないとかよくあるので万能ではありません。
実行時にヒストリをクリアしてから実行します。ヒストリが32000に達したら停止します。
h 実行アドレスのヒストリをon/offします。実行したプログラムのアドレスがヒストリに保存されます。
ヒストリはxコマンドの実行時になどにhistory.txtでPG直下に書き出されます。
この記事を書いた後に、ヒストリーにフルバージョンを追加しました。
off→シンプル(この記事と同じモード)→フル→offのように切り替わります。
フルは大量に出力されますので注意してください。
hw ヒストリを追記書き出しし、ヒストリをクリアします。
g <停止アドレス> 現在のアドレスからPGを実行します。停止アドレスを指定した場合停止アドレスで停止します。
ヒストリ対応、ブレークポイント対応、int 3を見つけたら停止、ヒストリが32000に達したら停止します。
x <停止アドレス> 現在のアドレスからPGを実行します。停止アドレスを指定した場合停止アドレスで停止します。
xコマンド専用ヒストリ(命令などつき)を直接ファイルに書き出します。
実行中にQキーを検出すると停止します。(WinAPIのGetKeyStateを使っているので、フォーカスを失っていても別ウィンドウでもQキーが押されたら停止します)
bc ブレークポイントをクリアします。
be <番号> 指定した番号のブレークポイントを有効にします。省略時全有効。
bd <番号> 指定した番号のブレークポイントを無効にします。省略時全無効。
bp ブレークポイント一覧を表示します。
bp <アドレス> ブレークポイントを設定します。同じアドレスを指定するとクリアします。
t ステップトレースです。1命令実行します。
u <アドレス> 現在のアドレスから8行逆アセンブルします。アドレスを指定せずに連続して実行すると、前回アドレスから行います。
d <アドレス> 現在のアドレスからダンプリストを表示します。
アドレスを指定せずに連続実行すると、続きから表示します。
display I/Oアクセスを表示するようにします。トグル動作します。
e <アドレス> 指定したアドレスからデータ入力する入力モードになります。エンターキーで抜けます。
スペースとかタブキーとかでスキップしたりとか色々あります。
e アドレス <データ> データを指定したアドレスに入れ込みます。
r 現在のレジスタと実行アドレスの命令を逆アセンブルして表示します。
その他に現在アドレスのバッファなども設定するので、1回は実行してから処理してください。
r <レジスタ> レジスタの値を表示&入力するモードになります。
r <レジスタ> <データ> レジスタの値を設定します。
m 転送元 転送先 サイズ 転送元アドレスから転送先アドレスへサイズ分だけデータを転送します。
f 開始アドレス サイズ データ 開始アドレスから指定したデータで埋めます。
fs ファイルサイズ ファイルサイズを設定します
fr FM音源ボードへリセットコマンドを送信します。
fe FM音源ボードのYM2608へ、レジスタ0x29へ0x80を発行します。(2203→2608拡張モードへ切り替え)
c アクセスカバレッジ記録モードの有効・無効を切り替えます。
cc アクセスカバレッジをクリアします。
cs 現在のカバレッジ情報のサイズを表示します。
co 現在のカバレッジ情報を出力します。coverage.txtは毎回新規出力します。
コードカバレッジ(4桁)→メモリカバレッジ(8桁)の順番で出力されます。
io I/Oアクセスをiow.txtファイルに記録するモードを切り替えます。トグル動作します。

セグメントを意識しないコマンドなどもありますが、ほとんどはセグメントを意識して処理してください。
色々やっててしないほうが使いやすいところなどもあった為です。

x86エミュレーションは、もう本が何処へ行ったやらなのでWebで検索して解説見ながら作りました。
一部186相当まで実装されているかもしれません。
面倒な命令や使いそうにない命令(AAAとか)、使いそうにないフラグなどは実装していません。
なので、ひょっとしたらどこかおかしいかもしれません。
#下で解説しています

2608ボードサンプルサウンドファイル

2608snowdriver.zip
「実装例 雪だるま式FM音源ドライバを乗せてみる」で実際に作成したサンプルドライバファイルです。
もっといいサンプル作った方が良かったかなぁ。
#下で解説しています


・2608FM音源ボードの曲データの作り方について

#なんかこの章は自分でも書いててよくわかんなくなってきたので、実際の曲データ作成例である「実装例 雪だるま式FM音源ドライバを乗せてみる」を見てください。

・YM2608FM音源ボードのソフトについて

YM2608基板の基本ファームウェアにはシーケンサが載っていません。
なので、曲データはシーケンサ付きで用意する必要があります。
データサイズは最大32KBです。これ以内に、音源ドライバ+曲データが収まるようにしてください。
#収まればそのまま演奏できるって事です

当時はセグメントの壁があったし、メモリも潤沢ではなかったので、大抵のドライバと曲データは64KB以内に収まっていました。
メモリも節約していたので1曲は大体16KBもあれば十分だったと思われます。

先頭ヘッダエリア(0x400くらいまで)+データエリアのサイズに納めてください。

搭載されているx86エミュレータは、0000:0000のエリアからデータをロードすると前提で動作しています。
なので、INT命令もある程度は使えます。
#フルスクラッチで作ったので、音源に利用されなさそうな面倒な命令は処理していません。AAAとか。
 バグなども残っているかも


 普通はx86でマイコンの処理をエミュレーションするのですが、本ボードはその逆で、マイコンでx86を
 処理します。なので、処理時間は結構苦しい気がします。C言語で組んでありますし。

0x380あたりに制御用のヘッダが置かれています。
#ヘッダ情報については、「2608サウンドデータヘッダエディタ」を用意していますので、参照してください

その前は割り込みベクタに使っています。なので、割り込みベクタの後半部分がつぶされる構造になっています。
でも、98の音源割り込みはINT 14h等だったので、音源再生には使わないだろうとケチりました。

ヘッダ情報エリアには、音源の割り込みAを処理するか、割り込みBを処理するか、曲のループ回数、
曲の1ループの時間、曲の終了フラグ、フェードアウトが可能かのフラグ情報、音源処理部からの依頼などが設定されます。
#音源ドライバのタイマ割り込みは、音源チップで処理せず、マイコンのタイマで処理されるようになっています。
タイマへのI/Oはそのままマイコンのタイマ処理に回ります。電圧の関係で音源チップから情報を読み込めないからですが。


音源ドライバ側に機能がある場合は、機能を持っているフラグを設定し、音源処理部からの依頼があれば
その処理を実行してください。処理が完了したら完了フラグをセットしてください。
音源処理部はフラグの設定を持って、処理を次にステップに移行します。

たとえば以下のようなやり取りになります。

1曲の時間は0(処理はドライバでやります扱い)
フェードアウトはドライバ側に機能あり

1.音源ドライバは曲のループが1ループ完了したら、ループカウンタを1増加します。
2.音源ドライバに追加したIF部が、ループカウンタの内容を、ループバッファにコピーします
  (音源ドライバを改造するなら、直接バッファに変更してもよいとは思います)
3.音源処理部は、ループバッファを見て、2回を超えていたら、曲のフェードアウトを実行するために、
  ドライバの処理能力を確認します
4.ドライバがフェードアウト可能となっているので、フェードアウトを依頼するために、フェードアウトバッファにフラグをセットします
5.音源ドライバに追加したIF部は、フェードアウト依頼フラグが有効になっているので、フラグをクリアしつつ、音源ドライバのフェードアウト処理を実行します
6.音源ドライバフェードアウトを毎ループ実行しています
7.音源ドライバのフェードアウトが完了しました。I/F部はフェードアウトの完了を検出したので、曲の完了フラグバッファにフラグをセットします
8.音源処理部はドライバ側の処理が終了し、曲データの再生が終わったことを、完了フラグバッファで検出しました
  次の音源ドライバの読み込みに処理を移します

となります。

つまり、音源処理部はループブレイカーがONの設定になっている場合、2ループで曲を終了して次の曲に移る処理のため、曲データが2ループ
したかどうかを確認しようとしますが、音源ドライバ側の能力フラグがOnになっているために、2ループの検出も音源ドライバ側に任せ、
曲バッファの数値を確認するのみにしています。
(音源ドライバ側に能力がない場合は、1ループの時間設定を見て計算しています)
音源処理部は、音源ドライバとのやり取り用の曲ループカウンタバッファを見て、2ループ以上経過しているかを確認します。
2ループ以上確認した場合は、今再生している曲をフェードアウトさせ、次の曲に移行しなければなりません。
音源処理部は、音源ドライバの能力フラグを見て、フェードアウト機能を有していることを確認しました。
フェードアウト依頼バッファにフラグをセットし、曲の再生完了フラグが有効になるまでを待ちます。
音源ドライバは曲のフェードアウトが完了しました。
音源ドライバに追加したI/F部はフェードアウトが完了したので、完了フラグバッファにフラグをセットします
音源処理部はフェードアウトが完了したのを検出して、次の曲の読み込みを開始します…

ちなみに、フェードアウトするまでもなくループせずに終了する曲は、再生完了フラグを設定すると、音源処理部は直ちに次の曲に移行します。

のような動作をします。

音源ドライバ側に能力がない設定であれば、音源処理部は、指定された時間が経過すると、音源のI/O処理に対して、自動的にボリューム調整の
計算を行い音源チップへボリューム処理を行ったり、音源チップへのボリュームレジスタのI/Oに対して仲介を行い、フェードアウトします。

音源ドライバに能力があれば、なるべくその機能を使おうとする構成になっています。
なければ、または解析が面倒、I/F部を組みたくないなどの理由があれば、能力なしにすれば、音源処理部が代わりにやってくれます。
ただし、この場合は最低でも曲の処理時間を設定してください。ループ中断設定でも延々と同じ曲が流れ続ける事になります。


音源処理部は、処理しているx86のI/O命令のうち音源I/Oしか処理しません。割り込みコントローラ関連の処理は実装していません。
ポートからのIN命令には、音源以外はすべて0x00を返します。
98の割り込みコントローラや音源チップのBUSY周りは0が返って来るとOK扱いになっています。
なので、実質的に何も処理せずに抜けるので問題ありません。

音源からの読み込みの場合は、割り込みフラグがセットされています。
割り込みフラグである割り込みAまたは割り込みBへの処理は、マイコン側のタイマーにより処理されています。
どちらを使うかはヘッダ部にあるどちらの要求を使うかのフラグを設定してください。

両方を設定すると処理に実行時間がとられるので、通常はBだけでかまわないと思います。

#まれに音源ドライバのAで効果音を処理しており、曲の演奏でもドラムセットを割り込みAの効果音扱いで処理している
 ドライバがあったりします
 この場合は、Aも処理しないとなんとも間が抜けてしまいます。

音源チップへのOUTは、キューにバッファされます。
そして、x86のwait命令で一気にI/Oを処理する構成になっています。
x86エミュレータ側は、waitで指定したmsを待つだけですが、ボード側のファームウェアは
FM音源のタイマレジスタに指定した値がセットされるまで待つ動作になります。
1ループの処理終了時にwait命令を実行するようにしてください。

音源ドライバは通常、以下のような構成になっていると思います。

1.レジスタ退避
pusha
push ds
push es
...

2.割り込みの状態を確認
mov dx,188
in al,dx
test al,1
jnz xxx
...

3.割り込みの要因を判定し、割り込みAの場合を処理

終わったら、割り込みAフラグをクリアします

4.割り込みの要因を判定し、割り込みBの場合を処理

終わったら、割り込みBフラグをクリアします


5.割り込みコントローラに終了処理を必要に応じて実行します

※98の割り込みコントローラなどは、割り込みが完了したら再度割り込みを発生させるように割り込みをクリアします

6.レジスタを復帰して戻る

pop es
pop ds
popa
iret

これを以下の構成にします

1.レジスタ退避 →削除します
2、3、4はそのままでOKです
5は削除した方が、速度に余裕がでますが、そのままでもOKです
6.は、以下のようにします

wait
I/F処理を書く
jmp 2へ

I/F処理は、音源ドライバ側に処理能力がある場合に、処理能力があるフラグを設定した場合の処理を書く部分です。


詳細については、下のサンプルを見てください。


・x86ツールについて

どんなツールか?

YM2608を鳴らす事ができる音源ドライバのスタンダードが思いつかず、載せるシーケンサをどうしたものかと考えていました。
9801は、RA21の次は9821Xa13にいきなり移り、2608時代は指をくわえてみているだけでしたので、トレンドに疎かったのです。

結論が出ようはずもありません。知らないのですから。
ボードは既に完成しています。直ぐにでも鳴らしたいのです。
いつまでたっても完成しないので、妥協し、シーケンサは音色の設定と最低限キーOn/Off程度を実装し、適当なMMLを再生できるようにして、
音源ドライバは最低限の機能だけにして、聞きたい曲データをリッチなMMLにして演奏することにしました。

当時聞いていたゲームの曲をまずはなんとかしようとしましたが、既にかなりの時間が経過しており、ドライバのコードを眺めても実際に鳴らしてみないことには、どうもよくわかりません。

鳴らすために、ドライバのアセンブラリストを見ながら、C言語でドライバを組んでいったのですが・・・
サブルーチンの中から他のサブルーチンにjmpするばかりか、一部の命令を書き換えるなど、
古き時代のハイテクニックに満ち溢れたプログラムをC言語化するのは早々にあきらめました。
#SAN値が削れ過ぎて…

98エミュレータで鳴らすことができるのはわかっていたので、エミュレータで調べようともしたのですが、
当時はまったく気にならなかった640x400サイズでシングル画面、SYMDEBでのステップとレースなデバッグにはもう戻る事ができませんでした。

これではダメだということで、I/O情報の記録、実行ヒストリ、カバレッジ等の機能がついている上にトレース実行もできて、I/O処理はUSBで繋いだボード側に送信して実チップで鳴らすツールを開発して解析することにしました。

まずはx86を実行するコアを作らなければなりません。
DOS時代だったらシングルステップ割り込みを駆使すればそんな苦労はしなくてもいいのですが、もはやWindows時代です。そんな割り込みを使うとなると大事でしょう。
ましてや、I/O命令は除外しなければなりません。面倒です。
#SAN値がもっと削れます

久しぶりすぎて、もはやx86系の書籍は何処に言ったのか探すのも大変です。仕方ないのでネットでインストラクションを検索しながら組みました。
実行命令があっているか、逆アセンブルで表示するようにもしたので、逆アセンブラと合体した形で作成しました。
まさか2017年にもなって、8086をC言語で組むことになろうとは思いも寄りませんでしたが、便利に使えるようにするには、
全部自前で用意するしかありません。

結果、大幅に捗りました。
テンポだけは、WindowsAPIのSleep文なので、ミリ秒の単位&USB仮想COMポートの先にコマンドを送るラグがあるためおかしいのですが、
演奏ができるようになりました。

が、まだスタート地点なのです。
今度は調べた結果を専用MMLに変換し、さらにシーケンサも作らなければなりません。
非常に面倒です。
当時聞きたかった曲&ドライバの回数だけ、同じ事を実行する必要があるのです。
さらに面倒です。

そんな時、ふと何かが私に囁いたのです。

…このままマイコンに入れてしまえばよくないか?と。

幸いにもフルスクラッチしたため、どうにでもできます。逆アセンブル表示部分を削り、押し込んでみました。
液晶にニーモニック出してもしょうがないですし。

心配なのは実行速度です。
PCでマイコンをエミュレーションするのはよくやられていますが、まったく逆の事をやらなければなりません。

というわけでやってみました。

…それなりに動きました。最近のマイコン凄いなぁ。

聴きたい曲が聴けたので、ひとまずこれでいいや。
ひよりました。

前置きが長くなりましたが、上記の事ができる2608サウンドボード用の支援ツールです。

・実装例 雪だるま式FM音源ドライバを乗せてみる

さて、実際の音源ドライバを例にとって、これをYM2608音源ボードで演奏できるようにしてみるまでをやってみようと思います。
サンプルに使うのは表題の音源ドライバなのですが、聞いたことないと思います。
ええ、大昔になんか作りかけて放置したものなのですから…。
昔のアーカイブから94-95年くらいに何かやっていたFM音源ドライバです。
雪だるま式。もはや記憶の彼方です。作りかけて途中で放置したと思います。再生したら微妙な曲が流れました。
何も覚えていません。作りかけのまま放置していたようなのですが、サンプルとしてだけはかろうじて使えます。
単純なのでちょうどいいでしょう。
#ドライバのネーミングとか何を持ってQ極と言っていたのやら突っ込みどころ多し

大抵の音源ドライバは大体2つの割り込みベクタを登録しています。
音源ボードからの割り込みを処理するベクタと、プログラムから呼び出して制御するベクタです。
これは、音源ドライバがBGM演奏を主に行っていたためで、何かをしながら曲を流すという目的の為、
メインプログラムとは別に、独立して動くように作られていたためです。

音源ドライバは、メインプログラムから呼び出されて使うので、インタフェース用のベクタを用意しています。
解析はまずこれを利用します。呼び出されて制御する部分を調べれば、曲を鳴らすのはそこまで難しくありません。
#たまに一体化して1つのベクタのドライバとかもいますけど

というわけで、サンプルを元に実装していく例を記述します。

エミュレータでも実行できたので、割と楽です。実際にドライバを解析するように解説します。


まずは制御ベクタを調べます。

・ベクタから調べる場合


ドライバを登録する前と登録した後で、ベクタを比較して差分を調べる方法です。




上が常駐前、下が常駐した後です。
割り込みベクタのアドレス50hつまりint 14h(80/4=20 -> 0x14)と、アドレス348h(/4 -> 0xd2)が変っています。

結果:int 14hとint 0d2hでした。int 14hは音源ドライバからの割り込みでしょう。
ハードウェアからの割り込みは大体同じようなアドレスです。
int 0d2hがプログラム制御部でしょう。ここから解析すればよいわけです。

・ソースを解析する場合


常駐部分は大抵、メイン処理の後ろにあります。
常駐プログラムの性質上、メモリに居座る領域は少ないほうがよいので、初期化のみに必要な処理は切り離して常駐します。
DOSファンクション0x31は常駐量をパラグラフ単位(16バイト)で指定するので、必然的に後ろを切り捨てる事になります。

本当は逆アセンブルして確かめるのですが、ソースがあるので、解析した体で解説します。
stmain:			cld			;駐在管理部
			mov ax,cs
			mov ds,ax

			;タイトル表示
			mov dx,offset mes_tit
			mov ah,9
			int 21h

			;割り込みベクタ 14hを調べて、自分の制御部がいるか見る
			mov ax,3514h
			int 21h
			mov di,bx
			mov si,offset pmain
			mov cx,20
			rep cmpsb
			jnz stay

			;制御部の常駐解除を呼び出す
	remv:		mov ax,0ffffh
			int 0d2h
			
			;FM音源のキーを全部OFF
			call all_key_off

			;解除メッセージ表示
			push cs
			pop ds
			mov dx,offset mes_rmv
			mov ah,9
			int 21h

			;プログラム終了
			mov ax,4c00h
			int 21h

			;ベクタ14hの内容を保存して書き換える
	stay:		mov ds:vect14,bx
			mov ds:vect14+2,es
			mov ax,2514h
			mov dx,offset pmain
			int 21h
			
			;ベクタd2の内容を保存して書き換える
			mov ax,35d2h
			int 21h
			mov ds:vectd2,bx
			mov ds:vectd2+2,es
			mov ax,25d2h
			mov dx,offset cmain
			int 21h

			;常駐メッセージ表示
			mov dx,offset mes_sty
			mov ah,9
			int 21h

			;常駐を呼び出して終了
			mov ax,3100h
			mov dx,offset rb
			shr dx,4
			add dx,25600/16
			int 21h

int 21hはDOSファンクションコールです。

いくつかのDOSファンクションコールは解析の取っ掛かりの為に重要です。
0x35及び0x25は覚えて置いてください。
これは割り込みベクタを取得、保存するためのDOSファンクションコールです。
行儀の悪いプログラムは直接メモリ先頭の割り込みベクタを操作していることもありますが、この場合はセグメント0000にアクセスするコードになっているので、見つけやすいかもしれません。
09hはメッセージの表示、4chはプログラムの終了、31hはメモリに残したまま終了(常駐)です。

さて、制御部が見つかったら制御部を調べます。
制御部は、経験的に以下のような機能が入っています。
・曲の再生
・曲の停止
・フェードアウト
・初期化
・データを転送して、演奏バッファに入れる処理
・常駐の解除

#曲データを内蔵しているドライバの場合、曲の再生などは番号を指定するだけで、転送などはなかったりします。

このドライバの場合、制御部は
			mov ax,25d2h
			mov dx,offset cmain
			int 21h
と、なっているので、cmainのアドレスに制御部があります。

cmainは以下のようになっていました。
cmain:			pusha
			push ds es cs
			pop ds
			cmp ax,0ffffh
			jz remvm
			cmp ax,14+1
			jnb cend
			shl ax,1
			mov si,ax
			call [ds:si+jptblcm]
		cend:	pop es ds
			popa
			iret
典型的なジャンプテーブルを使った機能呼び出し部です。
0xffffだけ特殊な処理をやっているようです。(ソースがあるのでわかりますが、常駐解除ですね)
大体14機能くらいあるみたいです。

次にジャンプテーブルを見てみましょう。
			;制御コマンド

jptblcm		dw	reset			;リセット
		dw	pam_set			;パラメータセット
		dw	fload			;ファイルロード+Pセット
		dw	sound_s			;再生
		dw	sound_t			;停止
		dw	fsound			;reset+pamset
		dw	all_key_off		;キーのオフ
		dw	fead_in			;フェードイン
		dw	fead_out		;フェードアウト
		dw	baf_in			;バッファにパラメータをセーブ
		dw	baf_out			;バッファからロード
		dw	reg_cnt			;レジスタコントロール
		dw	baf_cnt			;
		dw	baf_cnt2		;
		dw	mvolc			;Mボリューム設定

解析の場合は、テーブルの先を見ていく事になります。
#今回はソースがあるのでバレバレですが
reset:			call sound_t		;リセット
			mov ax,cs
			mov es,ax
			xor ax,ax
			mov di,offset ench
			mov cx,27
			rep stosw
			ret

コマンドの0番は、このようになっていました。
サブルーチンを呼んだ後に、バッファをクリアしています。
バッファクリアする=初期化のようです。

どんな感じのルーチンかな、と、あたりをつけたらサブルーチンを見てみます。
sound_t:		cli			;サウンドオフ
			mov ax,3027h
			call outdat
			in al,10
			or al,10h
			out 10,al
			sti
			call all_key_off
			ret
			
all_key_off:		mov ax,0028h		;音を止める
			call outdat
			mov ax,0128h
			call outdat
			mov ax,0228h
			call outdat
			mov ax,3f07h
			call outdat
			ret

outdat:			call nbusy		;2203へのデータ出力
			mov dx,188h
			out dx,al
			out 5fh,al
			out 5fh,al
			out 5fh,al
			out 5fh,al
			mov al,ah
			mov dx,18ah
			out dx,al
			ret
	nbusy:		push ax dx
			mov dx,188h
		nb2:	in al,dx
			shl al,1
			jb nb2
			pop dx ax
			ret

3027hを入れて、サブルーチンを呼んでいます。 サブルーチンでは、FM音源のBUSYレジスタを見て、al番のレジスタにahのデータを書き込んでいました。
これも典型的なFM音源操作の書き方です。
27h番はタイマーや音源リセットがあるレジスタです。リセットを叩いています。
I/O 10hは割り込み関連のI/Oですが、わからなければスルーしても大丈夫です。
その次のサブルーチンで、レジスタ0x28に値を0x00,0x01,0x02を入れています。
さらに0x07に0x3fを入れていました。

28はCh別の発声です。0,1,2なので、FM音源の発音をすべて停止しています。
07hはSSG音源のミキサーで、3fhを入れているので、SSGの発音ミキシングを全部OFFにしています。

初期化とあわせると、このサブルーチンは音を停止して、バッファをクリアする、つまりリセットコマンドであるという事がわかります。

ひとまず演奏前に必要かもしれませんが、次のコマンドを見てみます。
fload:			push cs			;データをバッファにロード
			pop es
			mov di,offset rb
			shr cx,1
			rep movsw
			rcl cx,1
			rep movsb

pam_set:		mov si,offset rb	;パラメータセット
			mov bx,offset pb00
			lodsw
			mov [ds:bx+2],ax
			lodsw
			mov [ds:bx+10],ax
			lodsw
			mov [ds:bx+18],ax
			lodsw
			mov [ds:bx+26],ax
			lodsw
			mov [ds:bx+34],ax
			lodsw
			mov [ds:bx+42],ax
			mov word ptr ds:ench,0
			mov word ptr ds:flg0,0
			ret

このサブルーチンは他のサブルーチンともくっついていました。
#まあよくあることです

上のサブルーチンは、いかにも曲データを内部バッファに転送してそうです。
下のサブルーチンは、転送先のバッファからデータを読み込んで内部制御バッファに値を設定しています。
しかも6箇所。これはFMx3音、SSGx3音の計6Ch分のバッファ設定ではないかと思われます。
ロード部分もあるので、これはデータのバッファ転送(ロード)及び、パラメータ設定のファンクションみたいですね。

これは曲データの再生の前に必要なのでメモです。
曲データは転送してもいいのですが、バッファであるrbにデータを最初から埋め込めば、転送処理を飛ばすことができそうです。
別ファイルで供給されている曲データと演奏ドライバを組み込んだ状態でセットにして、曲データを作り、
先頭でこのパラメータセットを呼び出せばよいでしょう。
#曲パラメータセットもスキップしてもよいように見えますが、このドライバは単純な作りの為です。
色々準備している場合もあるので、こういうのは呼んであげた方がいいです


バッファのセットとパラメータセットは見つかりました。
次は演奏の開始です。
sound_s:		cli			;サウンドスタート
			in al,10
			and al,0efh
			out 10,al
			mov ax,ds:tempo
			mov ah,al
			mov al,26h
			call outdat
			mov ax,3a27h
			call outdat
			sti
			ret

はい、もうコメントでバレバレですけど、割り込み禁止にしたうえに、割り込みコントローラーを操作しています。
そして、タイマレジスタをセットしています。終わった後割り込みを再開しています。
いかにも再生するぞ!っていう感じですね。

これはもう再生でしょうー間違いないですー(棒読み)

エミュレータで動かしてみて、演奏が開始されるかどうか確かめるのが手っ取り早かったりします。
#動く場合はこの方が早いですね

このドライバのようにテンポ設定などを、再生ファンクションで呼び出している場合は問題ありませんが、
ドライバ常駐時にやっているドライバもあります。
こういった場合は、常駐時にやっている音源チップの設定処理を入れる必要があります。

さて、ここまでわかったら曲データを作ります。
#時間があったら、曲の再生終了フラグやフェードアウト処理まで見つけると完璧です

音源ドライバと曲データを結合し、さらに呼び出し部分のコード演奏処理を入れます。
呼び出し部分は以下のようにしました。
			;演奏初期化
			mov ax,1
			int 15h
			mov ax,3
			int 15h
			
			;演奏処理
loop:			int 14h
			wait
			jmp loop

int 0d2hは、後ろ過ぎるので、15hを代わりに使うことにします。
タイマーはBだけで十分です。

曲データは以下のようにします。
割り込みベクタ + ヘッダ + 初期化/演奏処理 + 音源ドライバ本体 + 曲データ
このベースデータを作成します。
int main(int argc, char* argv[])
{
	char *x = new char [1048576];

	memset(x,0,1048576);

	//ドライバ読み込み
	FILE *fr = fopen("fmdrv.com","rb");
	if (!fr)
	{
		return 0;
	}
	fread(x + 0x600,1,32768,fr);
	fclose(fr);

	//このあたりにデータ埋め込みのコード入れる


	//かき出し
	FILE *fw = fopen("test.dat","wb");
	fwrite(x,1,1048576,fw);
	fclose(fw);

	delete[] x;

	return 0;
}

こんな単純なプログラムをつくり、ベースファイルを作成しました。
バイナリエディタをお持ちの場合は、そういったので作業したほうが良いでしょう。
x86エミュレータのmoveコマンドを駆使して作ることもできますが面倒です。

#曲データを読み込んでないじゃないかと、思った方もいるでしょうけど、
初期データとして、最初からバッファに埋め込んでありました。なので省略してます。


x86エミュレータに読み込みます。
>l test.dat
load file comp.[test.dat][1048576(00100000)]
>d 600
0000:0600 e9 73 09 90 00 00 00 00-00 00 00 00 00 00 00 00 駸.・...........
0000:0610 00 00 00 00 80 00 00 01-3f 00 00 00 00 00 00 00 .......?.......
0000:0620 00 00 00 00 00 00 00 00-00 00 00 00 87 db 87 db ............・・
0000:0630 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0640 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0650 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0660 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0670 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>d
0000:0680 60 1e 06 8c c8 8e d8 e8-88 00 ff 06 0c 01 83 3e `..己借闊....・
0000:0690 0c 01 03 73 02 eb 65 e8-b7 00 c7 06 0c 01 00 00 ...s.・霍.ヌ.....
0000:06a0 33 c9 f7 06 0e 01 01 00-75 06 bb 30 01 e8 84 01 3ノ・....u.サ0.閼.
0000:06b0 f7 06 0e 01 02 00 75 07-41 bb 38 01 e8 75 01 f7 ・....u.Aサ8.鑾.・
0000:06c0 06 0e 01 04 00 75 07 41-bb 40 01 e8 66 01 f7 06 .....u.Aサ@.鑁.・
0000:06d0 0e 01 08 00 75 08 33 c9-bb 48 01 e8 c9 01 f7 06 ....u.3ノサH.靄.・
0000:06e0 0e 01 10 00 75 07 41 bb-50 01 e8 ba 01 f7 06 0e ....u.AサP.霄.・.
0000:06f0 01 20 00 75 07 41 bb 58-01 e8 ab 01 b0 20 e6 08 . .u.AサX.隲.ー ・
アドレス600hから読み込んでいますので、元がCOMファイルということで、セグメント0050:0100から読み込まれた事になります。

先ほど作成した呼び出し部分を書き込みます。
>e 400 b8 01 00 cd 15 b8 03 00 cd 15 cd 14 9b eb fb

>d 400 0000:0400 b8 01 00 cd 15 b8 03 00-cd 15 cd 14 9b eb fb 00 ク.ヘ..ク.ヘ..ヘ.幎・ 0000:0410 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0420 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0430 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0440 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0450 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0460 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0470 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ >u 400 0000:0400 b80100 mov ax,0001 0000:0403 cd15 int 15 0000:0405 b80300 mov ax,0003 0000:0408 cd15 int 15 0000:040a cd14 int 14 0000:040c 9b wait 0000:040d ebfb jmp 040a 0000:040f 0000 add [bx+si],al

#アセンブルはなんとかしてください

割り込みベクタに値をセットします。
割り込みベクタは上にある常駐時のオフセット値からわかります。
数値はキャプチャを見るとint 14hは180hで、int 0d2hは6e0hになっています。
>e 50 80 01 50 00 e0 06 50 00
>d 0
0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 80 01 50 00 e0 06 50 00-00 00 00 00 00 00 00 00 .P.・P.........
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

値が設定できました。
一度保存しておきましょう。ついでに終了します。
>w
save file comp.[test.dat]
>q
exit!

再度立ち上げて確認してみましょう。
>l test.dat
load file comp.[test.dat][1048576(00100000)]
>d 0
0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 80 01 50 00 e0 06 50 00-00 00 00 00 00 00 00 00 .P.・P.........
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>d 400
0000:0400 b8 01 00 cd 15 b8 03 00-cd 15 cd 14 9b eb fb 00 ク.ヘ..ク.ヘ..ヘ.幎・
0000:0410 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0420 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0430 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0440 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0450 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0460 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0470 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

OKです。

では、YM2608FM音源ボードを繋ぎ、再度x86を起動します。
reset:01
>l test.dat
load file comp.[test.dat][1048576(00100000)]
>rip 400
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:0400  NV UP EI PL NZ NA PO NC
0000:0400  b80100            mov        ax,0001
>

ボードを繋いだため、起動時にYM2608ボードに対して、リセットコマンド(reset:01の部分がそう)が送信されました。

ボード側もUSB制御モードに入っています。

#写真は編集の都合上、旧1.4版の基板を使用しています。

ちょっとトレースしてみましょう。
>t
ax:0001  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:0403  NV UP EI PL NZ NA PO NC
0000:0403  cd15              int        15
>t
ax:0001  bx:0000  cx:0000  dx:0000  sp:fff2  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0050  ip:06e0  NV UP EI PL NZ NA PO NC
0050:06e0  60                pusha
>u
0050:06e1  1e                push       ds
0050:06e2  06                push       es
0050:06e3  0e                push       cs
0050:06e4  1f                pop        ds
0050:06e5  3dffff            cmp        ax,ffff
0050:06e8  7411              jz 06fb
0050:06ea  3d0f00            cmp        ax,000f
0050:06ed  7308              jnc        06f7
>

AXレジスタに1が入ったあと、制御部にきちんと飛んでいます。

大丈夫そうなので、実行!(セーフティなし実行であるxコマンドを使っています)
>x
break!
ax:0003  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:040d  NV UP EI PL NZ NA PO NC
0000:040d  ebfb              jmp        040a
>

無事微妙な曲が演奏されましたがプログラムが止まりませんのでqキーを押し、ブレークしました。

PCのエミュレータ上では動作OKでしたので、ボードで演奏させる為のヘッダ情報を付け加えます。
今回のようにスタートアドレスが0000:0400であるなどを設定します。


ボード内のx86エミュレータの初期化処理は以下のようになっています。
                x86_init();
                switch(load_file_type)
                {
                    case 0:
                        x86_r.ip = 0x3360;
                        x86_r.cs = 0x0000;
                        x86_r.ds = 0x0000;
                        x86_r.es = 0x0000;
                        x86_r.ss = 0x0000;
                        x86_r.sp = 0x7ff8;
                        request_interrupt = 2;
                        break;
                    case 1:
                        x86_r.ip = 0x1960;
                        x86_r.cs = 0x0000;
                        x86_r.ds = 0x0000;
                        x86_r.es = 0x0000;
                        x86_r.ss = 0x0000;
                        x86_r.sp = 0x7ff8;
                        request_interrupt = 2;
                        break;
                    case 2:
                        x86_r.ip = x86_get_m16_(0x384);
                        x86_r.cs = x86_get_m16_(0x380);
                        x86_r.ds = x86_get_m16_(0x382);
                        x86_r.es = 0x0000;
                        x86_r.ss = 0x0000;
                        x86_r.sp = 0x7ff8;
                        request_interrupt = x86_m[0x389];
                        fade_looptimeout = x86_get_m16_(0x38a);
                        waitloop_cancel = x86_m[0x38d];
                        break;
                }

load_file_typeは2になります。一部拡張子の場合は0とか1になってしまうので、ファイル名は〜.datにするようにしてください。
ヘッダの0x380がcsレジスタの値、0x382がdsレジスタの値、0x384がipレジスタの値、0x389が割り込みタイプ(2はタイマーBです。1はタイマーAで、両方使う場合は3を指定します)
曲の長さは0x38aに0〜65535を入れます。
このサンプル曲の場合は、20秒くらいでしょうか。

cs,ds共に0でOKです。
ipは400hですね。
割り込みタイプは02hで、時間は0.1秒単位で指定するので、x10して200である0c8hにします。

>e 380
0000:0380 00-00 00-00 00-00 00-00 00-00 00-04 00-00 00-00
0000:0388 00-00 00-02 00-c8 00-
>d 380
0000:0380 00 00 00 00 00 04 00 00-00 02 c8 00 00 00 00 00 ................
0000:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

eコマンドの逐次指定モード(アドレスしか入れない)だと、インタラクティブに数値を聞いてくるので、
入力したり、スペースでスキップして次に飛んだりできます。

値を入れたので保存します。
>w
save file comp.[test.dat]

おっと、そろそろ実ファイルのサイズである32KBにしましょう。
ファイルをバックアップしておいてからファイルサイズコマンドで0x8000を指定し、再度書き込みます。
>fs 8000
set filesize -> [32768]
>w
save file comp.[test.dat]
>

これでファイルサイズが32KBになったと思います。確認してください。

再度読み込んでみます
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>d 400
0000:0400 b8 01 00 cd 15 b8 03 00-cd 15 cd 14 9b eb fb 00 ク..ヘ.ク..ヘ.ヘ.幎・
0000:0410 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0420 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0430 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0440 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0450 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0460 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0470 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>d 600
0000:0600 e9 73 09 90 00 00 00 00-00 00 00 00 00 00 00 00 駸.・...........
0000:0610 00 00 00 00 80 00 00 01-3f 00 00 00 00 00 00 00 .......?.......
0000:0620 00 00 00 00 00 00 00 00-00 00 00 00 87 db 87 db ............・・
0000:0630 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0640 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0650 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0660 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0670 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>d 0
0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 80 01 50 00 e0 06 50 00-00 00 00 00 00 00 00 00 .P.・P.........
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>d 380
0000:0380 00 00 00 00 00 04 00 00-00 02 c8 00 00 00 00 00 ................
0000:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

読み込みサイズが32KBになっていて、内部のデータも大丈夫そうですね。

では、他にパラメータを設定するところがあったと思いますが、あんまり覚えてないので、設定ツールを使いましょう。

出来上がったtest.datをfmデータエディタに入れます。
>fm_dat_edit test.dat
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 200
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Disable
6.LimitEnd Flag      .. Disable
8.Save End
9.Exit

現在の状態が出ます。
フェードアウトは今回の曲はずっとループせずに普通に終わるので要りません。
また、2203のドライバなので、液晶のキー表示イコライザが2608用のままだと邪魔ですね。
2203用の6桁にしましょう。
5を押してエンターを押します。
cmd ..5
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 200
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Enable
6.LimitEnd Flag      .. Disable
8.Save End
9.Exit

5の状態が変りました。
曲はループしませんので、曲の終わりがそのまま終了です。
6番を設定します。
cmd ..6
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 200
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Enable
6.LimitEnd Flag      .. Enable
8.Save End
9.Exit

これでOKですね。
8番を押して、保存終了します。
cmd ..8
save end!

さて、データが出来上がりました。

と、その前に現在はPC上のx86エミュレータで動作しているわけですが、マイコンの制限された32KBのメモリで正しく動作するのか、
確認してみましょう。
#まあ実ボード上で演奏してみるのが早いのですけれども

カバレッジ機能でアクセス範囲を確認し、おかしなところにアクセスしていたりしないかを見てみます。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rip 400
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:0400  NV UP EI PL NZ NA PO NC
0000:0400  b80100            mov        ax,0001
>c
set coverage on.
>x
break!
ax:0003  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:040d  NV UP EI PL NZ NA PO NC
0000:040d  ebfb              jmp        040a
>cs
code coverage 426entry.
data coverage 55entry.
>co
writing..done.
>
途中でcコマンドを実行して、カバレッジ機能を有効にします。
そしてxコマンドで通常通り実行し、曲が終わるまで待ちました。
csコマンドで、カバレッジサイズを表示してみたところ、コードの実行範囲は426エントリで、
データにいたっては55エントリでした。曲がしょぼいです…

coコマンドで、coverage.txtが出力されていますので、中身を見てみます。
0180
0181
0182
0183
0185
.
.
.
略
.
.
.
078e
0790
0793
0796
0799
079a
0000060c
0000060e
00000610
00000616
00000618
.
.
.
略
.
.
.
00000d78
00000d7e
00000d88
00000d8a
00000d8e
00000d98
00000d9c
ぱっと見よくわからない表示なのですが、上の4桁がコードカバレッジです。
コードの範囲は180h〜79ahの範囲でアクセスされていました。
おかしなところにジャンプはしていなさそうです。
#本当はセグメントまで考慮して8桁なんでしょうけど、なぜかこれを組んだときは4桁でいいやと思ってしまったようです。

下の8桁の方はデータカバレッジです。
アクセスのあったメモリの情報が記録されています。
これを見る限り60ch〜0d9chの範囲のみメモリアクセスがあったようです。
32KBの壁は8000hですから、範囲内に収まっています。


余談ですが、プログラムが実際にどのように実行されているかは、ヒストリ機能を使って調べることができます。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rip 400
>h
history on
>x
break!
ax:0003  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0000  es:0000  ss:0000  cs:0000  ip:040d  NV UP EI PL NZ NA PO NC
0000:040d  ebfb              jmp        040a
>hw
write history..0
>
実はxコマンドはヒストリが有効な場合は常時追記書き込みしているので、最後にhwコマンドによる書き出しは必要ありません。
出来上がったヒストリは、history.txtに出力されています。
0000:0400  mov	ax,0001	
0050:0403  int	15	
0050:06e0  pusha	
0050:06e1  push	ds	
0050:06e2  push	es	
0050:06e3  push	cs	
0050:06e4  pop	ds	
0050:06e5  cmp	ax,ffff	
0050:06e8  jz	06fb	
0050:06ea  cmp	ax,000f	
0050:06ed  jnc	06f7	
0050:06ef  shl	ax,1	
0050:06f1  mov	si,ax	
0050:06f3  call	[si+0896]	(00d98:0750)

上記でint 15hを実行した直後から、int 15hの実行先であるpushaに移動しています。
#よく見るとint 15hは0000:403にあるのですが、実行後にヒストリテキストを書き出しているので変ってしまってました。後で直しときます ←しときました

0050:0750  mov	si,08c0	
0050:0753  mov	bx,0130	
0050:0756  lodsw	
0050:0757  mov	[bx+02],ax	(00632:0000)
0050:075a  lodsw	
0050:075b  mov	[bx+0a],ax	(0063a:0000)
0050:075e  lodsw	
0050:075f  mov	[bx+12],ax	(00642:0000)
0050:0762  lodsw	
0050:0763  mov	[bx+1a],ax	(0064a:0000)
0050:0766  lodsw	
0050:0767  mov	[bx+22],ax	(00652:0000)
0050:076a  lodsw	
0050:076b  mov	[bx+2a],ax	(0065a:0000)

書き込み先のメモリの内容が表示されています。
#lodswで読み込んだ値も表示されたら嬉しかったですね
 →追加しときました
0050:076e mov word ptr [010e],00 (0060e:0000) 0050:0774 mov word ptr [0110],00 (00610:0000) 0050:077a ret 0050:06f7 pop es 0050:06f8 pop ds 0050:06f9 popa 0000:06fa iret ここで元のアドレスに戻っていっています。 0000:0405 mov ax,0003 0050:0408 int 15 0050:06e0 pusha 0050:06e1 push ds 0050:06e2 push es 0050:06e3 push cs 0050:06e4 pop ds 0050:06e5 cmp ax,ffff 0050:06e8 jz 06fb 0050:06ea cmp ax,000f 0050:06ed jnc 06f7 0050:06ef shl ax,1 0050:06f1 mov si,ax 0050:06f3 call [si+0896] (00d9c:0782) 0050:0782 cli 0050:0783 in al,0a 0050:0785 and al,ef 0050:0787 out 0a,al 0050:0789 mov ax,[0114] ( 614:0080) 0050:078c mov ah,al 0050:078e mov al,26 0050:0790 call 021b 0050:021b call 0231 0050:0231 push ax 0050:0232 push dx 条件分岐命令は条件を満たしていないのでスルーされていることがわかります。 またcall命令を実行した直後にジャンプ先に移動しています。 0050:0233 mov dx,0188 0050:0236 in al,dx 0050:0237 shl al,1 0050:0239 jc 0236 0050:023b pop dx 0050:023c pop ax 0050:023d ret 0050:021e mov dx,0188 0050:0221 out dx,al 0050:0222 out 5f,al 0050:0224 out 5f,al 0050:0226 out 5f,al 0050:0228 out 5f,al 0050:022a mov al,ah 0050:022c mov dx,018a 0050:022f out dx,al 0050:0230 ret 0050:0793 mov ax,3a27 0050:0796 call 021b 0050:021b call 0231 0050:0231 push ax 0050:0232 push dx 0050:0233 mov dx,0188 0050:0236 in al,dx 0050:0237 shl al,1 0050:0239 jc 0236 0050:023b pop dx 0050:023c pop ax 0050:023d ret 0050:021e mov dx,0188 0050:0221 out dx,al 0050:0222 out 5f,al 0050:0224 out 5f,al 0050:0226 out 5f,al 0050:0228 out 5f,al 0050:022a mov al,ah 0050:022c mov dx,018a 0050:022f out dx,al 0050:0230 ret 0050:0799 sti 0050:079a ret 0050:06f7 pop es 0050:06f8 pop ds 0050:06f9 popa 0000:06fa iret 0050:040a int 14 0050:0180 pusha 0050:0181 push ds 0050:0182 push es 0050:0183 mov ax,cs 0050:0185 mov ds,ax 0050:0187 call 0212 0050:0212 mov ax,3827 0050:0215 call 021b 0050:021b call 0231 0050:0231 push ax 0050:0232 push dx 0050:0233 mov dx,0188 0050:0236 in al,dx 0050:0237 shl al,1 0050:0239 jc 0236 0050:023b pop dx 0050:023c pop ax 0050:023d ret 0050:021e mov dx,0188 0050:0221 out dx,al 0050:0222 out 5f,al 0050:0224 out 5f,al 0050:0226 out 5f,al 0050:0228 out 5f,al 0050:022a mov al,ah 0050:022c mov dx,018a 0050:022f out dx,al 0050:0230 ret 0050:0218 mov ax,3a27 0050:021b call 0231 0050:0231 push ax 0050:0232 push dx 0050:0233 mov dx,0188 0050:0236 in al,dx 0050:0237 shl al,1 0050:0239 jc 0236 0050:023b pop dx 0050:023c pop ax 0050:023d ret 0050:021e mov dx,0188 0050:0221 out dx,al 0050:0222 out 5f,al 0050:0224 out 5f,al 0050:0226 out 5f,al 0050:0228 out 5f,al 0050:022a mov al,ah 0050:022c mov dx,018a 0050:022f out dx,al 0050:0230 ret 0050:018a inc word ptr [010c] (0060c:0000) 0050:018e cmp byte ptr [010c],03 (0060c:0001) 0050:0193 jnc 0197 0050:0195 jmp 01fc 0050:01fc mov al,20 0050:01fe out 08,al 0050:0200 mov al,0b 0050:0202 out 08,al 0050:0204 in al,08 0050:0206 or al,al 0050:0208 jnz 020e 0050:020a mov al,20 0050:020c out 00,al 0050:020e pop es 0050:020f pop ds 0050:0210 popa 0000:0211 iret 0000:040c wait 0000:040d jmp 040a 0050:040a int 14 0050:0180 pusha 0050:0181 push ds 0050:0182 push es 0050:0183 mov ax,cs 0050:0185 mov ds,ax 0050:0187 call 0212 0050:0212 mov ax,3827 0050:0215 call 021b 0050:021b call 0231 0050:0231 push ax 0050:0232 push dx 0050:0233 mov dx,0188 0050:0236 in al,dx 0050:0237 shl al,1 0050:0239 jc 0236 0050:023b pop dx 0050:023c pop ax 0050:023d ret . . .
このようにヒストリ機能を有効にすると、プログラムがどのように実行されていったのかを履歴のように確認することができます。
メモリアクセスしていた場合、メモリの内容もある程度表示してくれますので、便利に解析してください。
#メモリの圧迫具合が凄いので、32000ヒストリでいったん中断します。xコマンドの場合、ヒストリはディスクに書き込むので止まりませ。ディスク空き容量に注意してください

閑話休題

さて、ファイルをUSBで転送して、ボード上でスタンドアロンで演奏するか見てみましょう。
2608play.exe test.dat

無事演奏されました!

あれ、イコライザ表示が2608用のままです。
そういえばUSB接続だと変化しなかったかも。
#後でSDカードに入れてみたらちゃんと2203表示になっていました

SDカードにファイルを入れて、演奏をテストし、20秒で次の曲に移ろうとするか確認してください。

不幸にも演奏されなかった人は、何かを間違えてしまったと思われます。
再度チャレンジしてみてください。ボードが暴走している場合は、ボード上のリセットボタンを押してください。
この場合、x86エミュレータも再起動しないと、COMポートを開いたままロックしている場合があります。

音源ドライバによっては処理がもたつくなども出てきますので、今回は省略してしまったのですが、 int 14hの先にある、pushaから始まるレジスタ保存処理などを全部取っ払ってしまうなどのチューニングが必要になります。


以上で解説を終わります。
大体曲データの作り方の雰囲気はつかめたでしょうか。
#曲データを作っているのかサウンドドライバを作っているのやら

・バッファの説明
 アドレス  サイズ  方向  意味 
0x380unsigned shortドライバ→制御初期状態のコードセグメントレジスタ(cs)の値
0x382unsigned shortドライバ→制御初期状態のデータセグメントレジスタ(ds)の値
0x384unsigned shortドライバ→制御初期状態のインストラクションポインタレジスタ(ip)の値
0x386unsigned charドライバ→制御演奏終了フラグ
0x01で制御側に終了が来た事を通知
0x387unsigned charドライバ→制御ループカウンタ
ループブレイカー設定が有効な時、ここが2以上であった場合ループを中断して次の曲へと進めます
0x388unsigned char制御→ドライバ0x01の時、制御部がフェードアウトを要求しています
0x389unsigned charドライバ->制御割り込みタイプ
b0:タイマーA有効 b1:タイマーB有効
0x38aunsigned shortドライバ→制御曲の長さ(0.1秒単位)
ex.200 = 20秒 省略する時は0秒で
0x38cunsigned charドライバ→制御制御フラグ
b0:フェードアウトを自前で実行 b1:2203用表示 b3:時間が来たら終了
0x38dunsigned charドライバ→制御ウェイトループキャンセラ。0x01で有効。
loop $+2をキャンセルします。ドライバによってはループでウェイトしているものがあるので、
キャンセルする場合に有効にします。
0x38eunsigned charドライバ->制御識別子:0x55
0x38funsigned charドライバ->制御識別子:0xaa

※方向が「ドライバ→制御」の場合は、制御部が読み取って処理を行います
 「制御→ドライバ」の場合は、制御部からドライバ側に通知を行っています


おまけ FMPを鳴らしてみる 技術実験


ここでは当時良く利用されていた(らしい)FMPを本ボードで演奏できるかやってみます。

#知り合いに話をしたところ、FMPが演奏できなきゃねーと言い放ち、むきーっとなったので、できるのかどうかを検証してみました。
 なお、FMPの利用規約を確認したところ、改竄しての商利用は禁止で、個人で楽しむ意外の組み込み禁止とあります。
 本PJは商利用ではないのですが、グレーゾーンは回避して改竄をしないように進めていきます。
 当然ながらここではツールの技術実験に終始するので、完成版のファイルは配布しません


説明文を見ると、I/Oポート自動判別、割り込み自動判別と書かれています。
自動判別はちょっとやっかいです。
というのも、I/Oエミュレーションは音源意外は実装していないので、
単に0x00を返す実装になっているからです。

#その音源にしても最低限の実装なのですが。 ちなみに0x00を返すと大抵のBUSYフラグはパスするのでそのまま動いたりします

ひとまず作業ファイルに配置して実行してみることにします。
常駐処理は多岐にわたる自動判別処理を行っているので、解析は最低限に抑えたいです。

プログラムサイズは31Kとかなり大きめです。かなり前方に配置しなければなりません。
曲データバッファがなくなってしまう気がしますが、説明文を読むと20K+バッファ8Kで最大でも28K程度の常駐サイズとあります。
これならば入りそうですが、最初から曲データはロードされた状態にしておく必要があるでしょう。

というわけで作業ファイルを作成します。

今回は2608x86だけで作業してみます。

2608x86を実行し、ファイルをロードします。
>l fmp.com
load file comp.[fmp.com][31073(00007961)]
>d 0
0000:0000 e9 5d 4d 00 00 00 00 00-00 00 00 00 00 00 00 00 饐M.............
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 23 6f 6f 00 00 00-00 00 00 00 00 00 00 00 ..#oo...........
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

次にセグメント0x40にロードされたCOMファイル扱いにします。
ということは、アドレスは500なので、転送コマンドMで転送します。
>m 0 500 7fff
>d 500
0000:0500 e9 5d 4d 00 00 00 00 00-00 00 00 00 00 00 00 00 饐M.............
0000:0510 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0520 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0530 00 00 23 6f 6f 00 00 00-00 00 00 00 00 00 00 00 ..#oo...........
0000:0540 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0550 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0560 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0570 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

一度保存しておきます。
ファイルサイズ及びファイル名を変更し、保存コマンドを実行します。
>fs 8000
set filesize -> [32768]
>n test.dat
set filename [test.dat]
>w
save file comp.[test.dat]
>

次は実行するために、レジスタを設定します。
配置アドレスは、0x500なので、セグメント0x40に配置されたCOMファイルになります。
>rcs 40
>rds 40
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0100  NV UP EI PL NZ NA PO NC
0040:0100  e95d4d            jmp        4e60
>

このドライバは引数を指定せずに実行した場合、常駐処理を実行しません。
なので、常駐用の引数[s]を指定します。

実行ファイルはCOMファイルなので、プログラムより128バイト前にコマンド引数部分があります。
ということで、コマンドラインは0x80から「文字数、スペース、常駐文字、改行文字」を記述します。
>e 80 02 20 73 0d
>d 80
0040:0080 02 20 73 0d 00 00 00 00-00 00 00 00 00 00 00 00 . s.............
0040:0090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0040:00f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

実行前にもう一度セーブしておきます。
>w
save file comp.[test.dat]
>

実行してみます。
>x
change alloc memory block
dealloc memory block
change alloc memory block
Music driver 「FMP」    Ver 4.28u         Copyright (C)1990-98  by Guu

read interrupt vector
read interrupt vector
set interrupt vector
set interrupt vector
division by zero
ax:10a1  bx:0000  cx:0000  dx:0000  sp:8261  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:53a0  NV UP EI PL ZF NA PO NC
0040:53a0  40                inc        ax
>

0除算で止まりました。I/O情報などがあってないみたいですね。
まあ続行してみましょう。
>x
change alloc memory block
dealloc memory block
change alloc memory block
read interrupt vector
set interrupt vector
not dos-function implement
not dos-function implement
read interrupt vector
set interrupt vector
read interrupt vector
set interrupt vector
 - Theme of FMP -   Composed & Arranged by KID

Found YM2203, Access I/O = 0188h, Used INT0h, Hooked INT d2h, Loops = @2
メモリに常駐しました
stay resident
ax:3100  bx:0000  cx:0000  dx:08e7  sp:8261  bp:0000  si:4e7c  di:1404
ds:0040  es:0040  ss:0040  cs:0040  ip:5733  NV UP EI PL NZ NA PO NC
0040:5733  f606a85d01        test       byte ptr [5da8],01      (061a8:04)
>

ひとまずメモリに常駐するところまで実行されました。
#普通は0除算なんて出たらダメなんですけど、たまたまうまくいったようです。ラッキーでしたね
実機であれば、この後に初期に組み込まれているサンプルサウンドが演奏されます。

表示を見ていると、色々問題がありました。YM2203の判別になっています。
2608x86は、0xA460のI/Oエミュレーションは0x41を返すだけなので、なんかおかしいのでしょう。
割り込みベクタがINT0になっています。
しかもINT0の位置にも書いてないので、正常に登録動作もしていないようですが、ルーチンを呼び出せばOKですので、スルーします。
だいたい除算エラーが出たので、あちこち正常値なI/Oではないのでエラーが出ているみたいですね。
なのでここは実機(もしくはエミュレータ)で数値を見ておきましょう。
ベクタのアドレスは1774hでした。
#ベクタが登録されないのは、なんかおかしいなと思って見てみたら実装してなかったです。実装しときます
→しときました
read interrupt vector [0b][0000:0000]
set interrupt vector [0b][0040:1774]
のように表示されます。

よく見ればLoopsの値も文字化けしてます。相当数値が大きいようです。これ、なんかのウェイト値でしょうか。

2203の問題を調査するため、2203の文字が出るところまでトレースして調べました。
その前にある判定文のところでデータを変更すれば2608認識するようです。

というわけでもう一度。
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rcs 40
>rds 40
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0100  NV UP EI PL NZ NA PO NC
0040:0100  e95d4d            jmp        4e60

ここで実行前にブレークポイントを設定します。
>bp 6087
set break point -> 0040:6087

で、実行します。
>x
change alloc memory block
dealloc memory block
change alloc memory block
Music driver 「FMP」    Ver 4.28u         Copyright (C)1990-98  by Guu

read interrupt vector
ax:0000  bx:5df1  cx:0004  dx:038a  sp:825f  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:6087  NV UP EI PL NZ NA PO NC
0040:6087* 3b4702            cmp        ax,[bx+02]      (061f3:0041)    <--bp:e

止まりました。
この0x41が入っているところを0x43にすれば86ボードで認識されます。
データを変更します。
>e 5df3
0040:5df3 41-43 00-

アドレスは、bx+2なのでbxレジスタの値に+2を足したアドレスです。
逐次変更モードで変更しましたが、もちろん直接変更しても問題ありません。

というわけで再度実行。
>x
ax:0043  bx:5df5  cx:0003  dx:0188  sp:825f  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:6087  NV UP EI PL NZ NA PO NC
0040:6087* 3b4702            cmp        ax,[bx+02]      (061f7:0000)    <--bp:e

あ、また同じところで止まりました。
ブレークポイントを解除します。
>bp 6087
clear break point -> 0040:6087

また実行。
>x
read interrupt vector
set interrupt vector
set interrupt vector
division by zero
ax:0850  bx:0000  cx:0000  dx:0000  sp:8261  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:53a0  NV UP EI PL ZF NA PO NC
0040:53a0  40                inc        ax

例の0除算のところで止まりました。
再度実行。
>x
change alloc memory block
dealloc memory block
change alloc memory block
read interrupt vector
set interrupt vector
not dos-function implement
not dos-function implement
read interrupt vector
set interrupt vector
read interrupt vector
set interrupt vector
 - Theme of FMP -   Composed & Arranged by KID

Found YM2608, Access I/O = 0188h, Used INT0h, Hooked INT d2h, Loops = 81
「86ボード」を認識しました
メモリに常駐しました
stay resident
ax:3100  bx:0002  cx:0000  dx:08e7  sp:8261  bp:0000  si:4e7c  di:1404
ds:0040  es:0040  ss:0040  cs:0040  ip:5733  NV UP EI PL NZ NA PO NC
0040:5733  f606a85d01        test       byte ptr [5da8],01      (061a8:04)
>

86ボードで認識しました。
保存しておきます。
>w
save file comp.[test.dat]
>

ひとまずこの状態で実行できるように変更してみましょう。
INT5のアドレス(ベクタは0x14)に呼び出しベクタアドレスをセットします。
>rds 0
>d 0
0000:0000 e9 5d 4d 00 00 00 00 00-00 00 00 00 00 00 00 00 饐M.............
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 23 6f 6f 00 00 00-00 00 00 00 00 00 00 00 ..#oo...........
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

あ、先頭に移動前のゴミが残っていたのでフィルコマンドで消しておきます。
#気分の問題です
>f 0 37f 0
>d 0
0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>

消えました。
ベクタを書きます。int 14hです。定番のINT5です。
#この紛らわしいの何とかならんのですかね
>e 50 74 17 40 00
>d 0
0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0050 74 17 40 00 00 00 00 00-00 00 00 00 00 00 00 00 t.@.............
0000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
>rds 40
>

アドレス指定がいまいちなので、データを読み書きするときには、dsレジスタを変更するようにしてください。
フルアドレス指定にすると、それはそれで使いにくいのです。

呼び出し部分のストラップをコーディングします。
loop:
    int 14
    wait
    jmp loop
という単なるコードです。

書き込みます。
>e 0 cd 14 9b eb fb
>u 0
0040:0000  cd14              int        14
0040:0002  9b                wait
0040:0003  ebfb              jmp        0000
0040:0005  0000              add        [bx+si],al
0040:0007  0000              add        [bx+si],al
0040:0009  0000              add        [bx+si],al
0040:000b  0000              add        [bx+si],al
0040:000d  0000              add        [bx+si],al
>rip 0
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0000  NV UP EI PL NZ NA PO NC
0040:0000  cd14              int        14
>

そしてついでに保存
>w
save file comp.[test.dat]
>

あ、初期設定時に既にある程度のFM音源へのI/Oが行われているようです。
io出力を有効にしてからもう一度やり直して、何が行われたのかを見てください。
#もう一度やるのは面倒なので省略します
>io
io write enable.
>

iow.txtの内容抜粋
略
.
.
0188 <- 27
0188
0188
018a <- 30
0068 <- 0b
0068 <- 0a
0188
0188
0188 <- 26
0188
0188
018a <- 00
0188
0188
0188 <- 27
0188
0188
.
.
略

結構テキスト系のI/Oがありました。
オプション説明を見ると、外字登録をしているようです。ひとまずスルーします。
#5fhや0a1h〜0a9hは邪魔なので、iow.txtには出ないようにしときました

YM2608の27hや26hレジスタは、タイマーやモードレジスタ設定です。これは初期化時にやっておかないといけないですね。
後でやりましょう。

実行してみます。
あ、ボードを接続してなかった。接続して再起動します。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rcs 40
>rds 40
>rip 0
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0000  NV UP EI PL NZ NA PO NC
0040:0000  cd14              int        14
>

さて、実行してみます。
音は鳴りましたが・・・遅いです。qキーを押してブレークします。
>x
break!
ax:ffa5  bx:02f1  cx:0626  dx:018c  sp:1342  bp:0000  si:141e  di:029a
ds:0040  es:0040  ss:0040  cs:0040  ip:3234  NV UP DI PL NZ NA PO NC
0040:3234  e2fe              loop       3234
>fr
reset:01
fm reset!
>

ついでに音が出っぱなしなので、frコマンドでFM音源をリセットしておきます。
2608x86上では、タイマーではなくウェイト設定だけですのでウェイト値を0にして見ます。
>wait 0
set wait 0 msec.
>

再度実行してみても改善されていません。
ヒストリを有効にして、再度実行してみて、何をやっているのか見てみます。
>h
history on
>x
break!
ax:0609  bx:09e1  cx:03de  dx:0188  sp:1340  bp:0000  si:50d6  di:098a
ds:0040  es:0040  ss:0040  cs:0040  ip:323e  NV UP DI PL ZF NA PO NC
0040:323e  e2fe              loop       323e
>fr
reset:01
fm reset!
>h
history off
>

ヒストリを有効にしてほんのちょっと実行しただけなのに、巨大なファイルが出来上がっています。
ヒストリファイルを見てみると、同じアドレスで大量にループしています。
.
.
0040:323e  loop	323e	
0040:323e  loop	323e	
0040:323e  loop	323e	
0040:323e  loop	323e	
0040:323e  loop	323e	
.
.

そういえばさっきブレークしたときも、同じようにウェイトループで止まっていましたね。

ひとつ心当たりがあります。常駐時に表示されていたループ表示がおかしかったことです。
これ、ウェイト調整値でしょう。

ウェイトキャンセル機能を有効にして、ウェイトを無視するようにします。
>wc
wait loop cancel.
>

再度実行してみます。
速度は良い感じになりましたが、最初からやり直しましょう。
さっき鳴りっぱなしのFM音源をリセットしたので、音色がリセットされていてダメです。

再起動して再読み込みします。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rcs 40
>rds 40
>rip 0
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0000  NV UP EI PL NZ NA PO NC
0040:0000  cd14              int        14
>

おっと、忘れてました。
キャンセル機能を有効にして実行します。
>wc
wait loop cancel.
>wait 0
set wait 0 msec.
>x

無事サンプル曲が再生されました!

後はカバレッジテストして、実機で動作するフォーマットに直せばよしです。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>rcs 40
>rds 40
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0100  NV UP EI PL NZ NA PO NC
0040:0100  e95d00            jmp        0160
>rip 0
>r
ax:0000  bx:0000  cx:0000  dx:0000  sp:fff8  bp:0000  si:0000  di:0000
ds:0040  es:0000  ss:0000  cs:0040  ip:0000  NV UP EI PL NZ NA PO NC
0040:0000  cd14              int        14
>c
set coverage on.
>wc
wait loop cancel.
>wait 0
set wait 0 msec.
>x
break!
ax:0080  bx:0000  cx:0008  dx:0188  sp:1348  bp:0000  si:0c26  di:0000
ds:0040  es:0040  ss:0040  cs:0040  ip:1b75  NV UP EI PL ZF NA PO NC
0040:1b75  740c              jz 1b83
>cs
code coverage 1161entry.
data coverage 705entry.
>

再生が終わったので中断してカバレッジ情報を出してみます。
やっぱちゃんとしたPGだとエントリ数が多いですね。
>co
writing..done.
>

出力して範囲を確認してみます。
0000
0002
0003
1774
1775
1778
1779
177e
17ad
.
.
.
3e7c
3e7d
3e81
3e84
3e87
3e8d
3eb7
00000502
00000503
0000050d
0000050f
00000511
00000512
.
.
.
000054fb
00005537
0000553a
0000554a
0000554d
00005590

コード、データ共に範囲内に収まっています。
意外と後ろのほうも使っていました。

次はヘッダを作成します。最初からデータエディタを使います。
fm_dat_edit.exe test.dat
1.TimerA             .. Disable
2.TimerB             .. Disable
3.LimitTime          .. 0
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Disable
6.LimitEnd Flag      .. Disable
8.Save End
9.Exit
cmd ..2
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 0
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Disable
6.LimitEnd Flag      .. Disable
8.Save End
9.Exit
cmd ..3
time ? 100
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 100
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Disable
6.LimitEnd Flag      .. Disable
8.Save End
9.Exit
cmd ..6
1.TimerA             .. Disable
2.TimerB             .. Enable
3.LimitTime          .. 100
4.Fadeout DriverMode .. Disable
5.2203 GraphicECMode .. Disable
6.LimitEnd Flag      .. Enable
8.Save End
9.Exit
cmd ..8
save end!

さて、今回はウェイトループキャンセラフラグも有効にしないといけません。
後でつけたので、データエディタにはついてませんでした。
reset:01
>l test.dat
load file comp.[test.dat][32768(00008000)]
>d 380
0000:0380 00 00 00 00 00 01 00 00-00 02 64 00 08 00 55 aa ..........d...Uェ
0000:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03f0 00 00 00 00 00 00 00 00-46 4d 50 20 34 2e 32 38 ........FMP 4.28
>e 38d 1
>d 380
0000:0380 00 00 00 00 00 01 00 00-00 02 64 00 08 01 55 aa ..........d...Uェ
0000:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03f0 00 00 00 00 00 00 00 00-46 4d 50 20 34 2e 32 38 ........FMP 4.28
>w
save file comp.[test.dat]
>

さて、次は初期設定部分と呼び出し部分を実装します。
先ほどのiow.txtに記録されていた初期化データを設定してから演奏ループに入るコードにします。
やらなくても大丈夫かもしれませんが。
コード部分はこれ。
	cld
	mov cx,9
	mov si,3a8h
lp:
	mov dx,188h
	lodsb
	out dx,al
	mov dl,8ah
	lodsb
	out dx,al
	loop lp

soundloop:
	int 14h
	wait
	jmp soundloop

	
	※以下のがよかったかも
	lodsw
	out dx,al
	mov dl,8a
	mov al,ah
	out dx,al
	loop lp
	

ちなみに設定する先ほどiow.txtで確認したデータ部分は以下の通り。
26,00
27,2a
22,00
b4,c0
b5,c0
b6,c0
07,38
26,ca
27,2a

ということで、入力開始。 ヘッダの直後からコードを書くので、アドレスは390hから入れる事にします。
ipアドレスのスタートアドレスを380hにして、390hにして、コードとデータを入れ込みます。
>e 380
0000:0380 00-  00-  00-  00-  00-90 01-03 00-
>e 390
0000:0390 00-fc 00-b9 00-09 00-00 00-be 00-a8 00-03 00-ba
0000:0398 00-88 00-01 00-ac 00-ee 00-b2 00-8a 00-ac 00-ee
0000:03a0 00-e2 00-f5 00-cd 00-14 00-9b 00-eb 00-fb 00-
>e 3a8
0000:03a8 00-26 00-00 00-27 00-2a 00-22 00-00 00-b4 00-c0
0000:03b0 00-b5 00-c0 00-b6 00-c0 00-07 00-38 00-26 00-ca
0000:03b8 00-27 00-2a 00-
>d 380
0000:0380 00 00 00 00 90 03 00 00-00 02 64 00 08 01 55 aa ....・....d...Uェ
0000:0390 fc b9 09 00 be a8 03 ba-88 01 ac ee b2 8a ac ee ・..セィ.コ・ャホ堪・
0000:03a0 e2 f5 cd 14 9b eb fb 00-26 00 27 2a 22 00 b4 c0 糢ヘ.幎・&.'*".エタ
0000:03b0 b5 c0 b6 c0 07 38 26 ca-27 2a 00 00 00 00 00 00 オタカタ.8&ハ'*......
0000:03c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:03f0 00 00 00 00 00 00 00 00-46 4d 50 20 34 2e 32 38 ........FMP 4.28
>w
save file comp.[test.dat]
>

入れ終わったらセーブしておきます。
これで演奏してみます。

おーオープニング曲が演奏されました!
後は、曲データと結合して1つのファイルにしなければなりません。

では、曲データを設定する方法を調べてみることにします。
データのロードは、画面メッセージを見ていると、Theme of FMPというメッセージを出しているので、ここで曲データを設定していると思われます。
このメッセージ出しているあたりで、きっと制御コマンドをint 0d2hで呼び出しているに違いありません。

wcコマンドでウェイトループをキャンセルし、もう一度ヒストリを出力してみます。
メッセージの表示タイミング的に、0除算エラーからヒストリを有効にしてみます。

・・・

何箇所かメッセージを出しているところがありました。
mov ah,09とint 21の部分をヒストリから探してみます。
見つけたうちの一番手前を見てみます。
0040:56af  test	byte ptr [5da8],02	(061a8:04)
0040:56b4  jnz	56d0	
0040:56b6  mov	si,65e0	
0040:56b9  mov	dx,57af	
0040:56bc  cmp	byte ptr [5263],00	(05663:00)
0040:56c1  jz	56c9	
0040:56c9  mov	ah,09	
0040:56cb  int	21	
0040:56cd  call	4b30	
ここでは、メッセージのアドレスとして、57afhを設定しています。

このメッセージが何かを確認してみます。
>d 57af
0040:57af 20 2d 20 54 68 65 6d 65-20 6f 66 20 46 4d 50 20  - Theme of FMP
0040:57bf 2d 20 20 20 43 6f 6d 70-6f 73 65 64 20 26 20 41 -   Composed & A
0040:57cf 72 72 61 6e 67 65 64 20-62 79 20 4b 49 44 0d 0a rranged by KID..
0040:57df 0a 24 20 2d 20 42 61 6c-61 6e 63 65 20 74 65 73 .$ - Balance tes
0040:57ef 74 20 2d 20 20 20 43 6f-6d 70 6f 73 65 64 20 26 t -   Composed &
0040:57ff 20 41 72 72 61 6e 67 65-64 20 62 79 20 4b 49 44  Arranged by KID
0040:580f 0d 0a 0a 24 20 2d 20 56-6f 6c 75 6d 65 20 63 68 ...$ - Volume ch
0040:581f 61 6e 67 65 20 2d 0d 0a-0a 24 41 63 63 65 73 73 ange -...$Access
を、これは曲のタイトルメッセージですね。

ということは、ここで曲データを設定しているようです。
直前に条件判定文がありますが、分岐しなかった場合は何が出るんでしょうか。
>u 56c1
0040:56c1  7406              jz 56c9
0040:56c3  bee268            mov        si,68e2
0040:56c6  bae157            mov        dx,57e1
0040:56c9  b409              mov        ah,09
0040:56cb  cd21              int        21
0040:56cd  e860f4            call       4b30
0040:56d0  33db              xor        bx,bx
0040:56d2  8a1e560b          mov        bl,[0b56]
dxレジスタに57e1hを設定しています。
このアドレスは、さっきのダンプにありましたが、バランステスト用の曲のようです。

ここで曲を切り替えできるという事は、これより前に曲データに関する処理はないみたいです。
そして、siレジスタに設定しているアドレスが、曲データの先頭でしょうね。
最後にcall 4b30hへジャンプしていますが、内部を確認してみたところ、曲データのロードのようです。
ヒストリでは、このサブルーチンを抜けると、もう後は画面表示をして常駐する処理しかありません。
ということは、siレジスタに値を設定して、このルーチンを呼び出せれば曲データを任意にロードできるようです。

呼び出すためにint 0d2hに設定されている制御コマンドを確認してみます。
ベクタに設定されていたアドレスは、32a0hでした。 この先を確認してみたところ、alレジスタにコマンド番号を入れてから呼び出すようです。
>u 32e5
0040:32e5  2ec6060201fe      mov        byte ptr cs:[0102],fe
0040:32eb  3c15              cmp        al,15
0040:32ed  7711              ja 3300
0040:32ef  2ec606020100      mov        byte ptr cs:[0102],00
0040:32f5  33db              xor        bx,bx
0040:32f7  8ad8              mov        bl,al
0040:32f9  d1e3              shl        bx,1
0040:32fb  2eff974633        call       cs:[bx+3346]

ジャンプテーブルが3346hにあります。テーブルを確認してみます。
>d 3346
0040:3346 72 3d fe 3e 3c 40 30 4b-72 33 fa 33 3c 3a ff 39 r=><@0Kr3・<:9
0040:3356 b8 3e c5 34 8d 39 bf 39-96 36 8c 39 c4 36 69 37 ク>ナ4・ソ9・・ト6i7
略
>
テーブルアドレスを見てみると… +6からありました。4b30hがあります。
という事は、alは3を設定すればOKです。

では、任意の曲データ(ここではdemo.ozi)を使って、その曲が再生されるか実験してみます。
#実際のコマンド表示にコメントを追記しています
reset:01
>l demo.ozi
load file comp.[demo.ozi][10552(00002938)]

#ここではdemo.oziファイルをロードしています

>m 0 a000 3000

#一度データを移動しておきます

>l fmp.com
load file comp.[fmp.com][31073(00007961)]

#fmpをロードします

>m 0 500 7fff

#現在の位置では割り込みベクタの上なので、セグメント40hに移動します

>rcs 40
>rds 40

#セグメントを更新します

>e 80 02 20 73 0d

#常駐コマンドラインを書き込みます

>bp 6087
set break point -> 0040:6087

#86ボード認識用にブレークポイントを設定します

>x
change alloc memory block
dealloc memory block
change alloc memory block
Music driver 「FMP」    Ver 4.28u         Copyright (C)1990-98  by Guu

read interrupt vector [d2][0000:0000]
ax:0000  bx:5df1  cx:0004  dx:038a  sp:825f  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:6087  NV UP EI PL NZ NA PO NC
0040:6087* 3b4702            cmp        ax,[bx+02]      (061f3:0041)    <--bp:e
>bp 6087
clear break point -> 0040:6087
>e 4df3
0040:4df3 06-
>e 5df3
0040:5df3 41-43 00-

#86ボード認識用設定にデータを変更し、ブレークポイントを解除します

>x
read interrupt vector [08][0000:0000]
set interrupt vector [08][0040:62d5]
set interrupt vector [08][0000:0000]
division by zero
ax:0850  bx:0000  cx:0000  dx:0000  sp:8261  bp:0000  si:0082  di:011a
ds:0040  es:0040  ss:0040  cs:0040  ip:53a0  NV UP EI PL ZF NA PO NC
0040:53a0  40                inc        ax

#0除算エラーでとまるので、再度実行します

>x
change alloc memory block
dealloc memory block
change alloc memory block
read interrupt vector [0b][0000:0000]
set interrupt vector [0b][0040:1774]
not dos-function implement
not dos-function implement
read interrupt vector [d2][0000:0000]
set interrupt vector [d2][0040:32a0]
read interrupt vector [1b][0000:0000]
set interrupt vector [1b][0040:327c]
 - Theme of FMP -   Composed & Arranged by KID

Found YM2608, Access I/O = 0188h, Used INT0h, Hooked INT d2h, Loops = 81
「86ボード」を認識しました
メモリに常駐しました
stay resident
ax:3100  bx:0002  cx:0000  dx:08e7  sp:8261  bp:0000  si:4e7c  di:1404
ds:0040  es:0040  ss:0040  cs:0040  ip:5733  NV UP EI PL NZ NA PO NC
0040:5733  f606a85d01        test       byte ptr [5da8],01      (061a8:04)

#メモリに常駐したところで自動で停止します

>e 0 be 00 9c b0 03 cd d2 9b cd 0b 9b eb fb
>u 0
0040:0000  be009c            mov        si,9c00
0040:0003  b003              mov        al,03
0040:0005  cdd2              int        d2
0040:0007  9b                wait
0040:0008  cd0b              int        0b
0040:000a  9b                wait
0040:000b  ebfb              jmp        0008
0040:000d  0000              add        [bx+si],al

#先ほど調べた曲データロードコマンドのコードを書き込みます。移動先は0a000hなのですが、セグメントが40hなので400hほど戻して、9c00hになっています
順序変えて、
	mov si,9c00
	mov al,3
	int d2
loop:
	wait
	int 0b
	jmp loop
のがよかったですね


>rip 0
>r
ax:3100  bx:0002  cx:0000  dx:08e7  sp:8261  bp:0000  si:4e7c  di:1404
ds:0040  es:0040  ss:0040  cs:0040  ip:0000  NV UP EI PL NZ NA PO NC
0040:0000  be009c            mov        si,9c00

#ipレジスタを0に設定します

>wc
wait loop cancel.
>wait 2
set wait 2 msec.

#ついでにデバッガの設定を変更します

>x

#いざ実行!

break!
ax:8181  bx:043e  cx:0000  dx:018a  sp:1342  bp:0c81  si:141e  di:002e
ds:0040  es:0040  ss:0040  cs:0040  ip:3249  NV UP DI PL NZ NA PO NC
0040:3249  58                pop        ax
>fr
reset:01
fm reset!
>

無事に再生することができました!

後は、FMPイメージに曲データをくっつけて、このブートストラップコードを埋め込めば曲データを作ることができますね。
しかし、メモリが32KBだと結構厳しいです。
バッファ8Kと聞いていましたが、曲データのサイズをみると平気で10Kとかあります。
プログラムの半分から後ろは、常駐処理などが書かれているので、つぶしても大丈夫でしょうか。
ここに曲データを入れるとか実験して試してみようかと思いますが、ひとまずデータは完成したので、よしとします。

#最悪ファームウェアを更新して、もうちょっとメモリを確保できるようにしようかと思います。
50KBくらいならいけるかしら・・・



その後…

漏れ:(^ω^)FMP演奏できたぞ!!

→奴:あ、ごめんPMDだったわ

 →漏れ:(#^ω^)





おまけのおまけ PMDを鳴らしてみる 技術実験2



1.試してみました。

2.2608x86のI/Oエミュレーションでは常駐まで行きませんでした。

3.というわけで、実機などで常駐まで実行します。

4.出来上がったら、メモリのイメージをファイルに落とします。

5.割り込みベクタ周りを見て、どこに実体があるか確認しておきます。

6.このドライバは常駐時に音源用のベクタや制御用のベクタを表示してくれますので、制御用のベクタにブレークポイントを設定します。
  音源はINT5(int 14h)、制御はint 60hでした。

7.再生プログラムで再生を実行します。制御用ベクタにどのコマンド送られてきたかを確認します。

8.メッセージの表示や内部のバッファへのデータ転送、再生の開始、停止をコマンドとあわせてメモします。
  コマンドの指定はahレジスタに番号でした。珍しい。

9.コマンド番号は、停止:01h、フェードアウト:02hで速度はal、再生開始:00h、バッファの位置を返す:06h(ds:dxにアドレス)でした。
  演奏を停止してから、バッファの位置にデータを埋め込み、再生開始を行えば再生される事がわかりました。

10.イメージを再配置します。500hに配置できるように、セグメントを設定(0040h)し、実体を転送します。

11.割り込みベクタを再設定します。セグメントを0040hにします。

12.380hにヘッダ情報を書き込みます。
   ひとあえず再生時間は120秒、タイマーB、WCキャンセル有効、時間で終了フラグで完了します。
   コード、データセグメントは0000hで、ipは390hにしておきます。

13.390hにコードを書きます。
	mov ah,0
	int 60h
loop:
	wait
	int 14h
	jmp loop
   ここまでで、ドライバイメージにしておきます。

14.実機上で、ah,06hにして、制御ベクタを呼び出しds:dxレジスタの値を確認しておきます。dsは常駐アドレスと同じ、dxは4e0chでした。
  symdeb.exeがない場合は、vectorからddeb等のsymdebライクなPGを用意して試しましょう。

15.データ作成PGを作ります。
  ドライバイメージをロードし、曲データを先ほどのdxレジスタの位置にロードします。

16.曲データをデータ作成PGで結合し、32KBで保存します。超えていた場合は、あきらめます。(ファームウェア改造まち)
  ※手動でがんばって作成する方法(おまけで解説済み)でもかまいません。

17.USB転送で再生するか確認します。

18.完成!


余裕があれば、演奏終了フラグを見つけたり、ループカウンタを見つけたりして制御部に通知してあげるようにコードを書きます。
面倒な場合は、1曲の時間を計測し、時間を設定、フラグなどを調整してください。

※あ、一点だけパッチが必要でした。
エミュレータのFM音源タイマ割り込みのフラグ設定ですが、一度読み出されるとクリアされるようになっています。
なので、2回連続で読んだりすると2回目はクリアされています。
	in al,dx
	in al,dx
	test al,2
	jc xxxx
のようにコードを組まれると、実チップでは2回目でも同じ値が返って来ますが、
ボードのエミュレーションでは2回目はフラグがクリアされた状態となります。
この為に動きませんので、どちらかのin al,dxをnopにつぶしてください。

・おまけ pmdドライバ+pmd曲から、2608ボードで再生できる形式のファイルを作成するプログラム


・rev.2018/12/30 17:36追加
pmd_song.zip

PMD86.comを用意し、プログラムと同じ場所に配置してください。
バージョンは4.8oが必要です。
#ベクターからPMDドライバをダウンロードしたところ、pmd48oを実行し、自動実行解凍でpmd86.comを出力する必要がありました。(README.1STより)
 9801で実行したので、コマンドプロンプトなどでは実行できないと思います。

使い方
pmd_song.exe sample.m

エラーがなければ、自動的にYM2608FM音源ボードで再生できる形式の.datファイルが出来上がります。
ただし、合計が32KB超えている場合は動作しません。10〜12KB程度のファイルまでなら再生可能だと思われます。

SDカードで聞く場合は、FMデータエディタでヘッダ情報を設定してください。(USBモードだと再生時間などは無視しています)
再生時間設定は2分固定になっています。(フェードアウトあり、1再生は1分で2ループ設定)
それより短い曲は無音が続くことになります。FMデータエディタで曲の再生時間を再設定してください。


シリアルコンソールの使い方

TeraTermなどをご利用いただけます。
改行コードはLFのみなので、CRLFに変換するなどのオプションを指定してください。

!注意!
ピン制御コマンドは、基板作成時の動作確認用のコマンドです。音源チップを搭載した状態で使用しないでください。
最悪マイコンや音源チップが壊れます。

ピン制御コマンドは、使用前にセーフティスイッチ解除コマンドをまず実行しないと使えないようになっています。

シリアルコンソールを起動してEnterキーなどを押下することで、シリアルコンソールモードになります。
※SCCIを利用する場合は、SCCI対応ソフトを起動することで従来通り強制的にSCCIに切り替わります。


繋がった場合は、まずhキーを押してエンターキーを押してください。
コマンドヘルプが表示されます。

-h
Welcome to OPNAM(4759) Console Version 1.01

command
 reset cpu|fm                        ... reset cpu/fm chip
 out/o 2151/M|2608/A reg dat         ... output fm register
 clock 2151/M|2608/A 3.57|4|7.98|8   ... select fm frequency
 eeprom [datas(hex)]|checksum|load   ... eeprom read/write/checksum/load setting
 button                              ... button test
 led on|off                          ... led control
 lcd init|cls|light|string           ... lcd control
     light on|off
     string x y string
 oled init|on|off|cls|bright|string  ... oled control
      bright brightness(hex)
      string x y color(hex) string
 sd init|dir|read/r|write/w|set|dump ... sd control
    read readsector(hex)
    write writesector(hex)
    dump
    set address datas
 play [filename(8+3)]                ... playfile/information
 stop                                ... stop play
 cd directory                        ... change current directory
 fm                                  ... dump fm register
 temp                                ... cpu temperature
 help/h/?                            ... this message

 unlock yes                          ... unlock safety switch
 pin/p 2151/M|2608/A pinname 0|1     ... output pin level (safety unlock only)
    pinname:IC|WR|RD|CS|D0..D7|A0|A1


コマンドの記述方法について

例1.
 reset cpu|fm                        ... reset cpu/fm chip

 コマンド+オプションを指定します

 reset cpu
 reset fm
 のように記述します。
 「cpu|fm」は、cpuまたはfmのどちらかを記述できるという意味です。


例2.
 out/o 2151/M|2608/A reg dat         ... output fm register

 コマンド+オプションを3つ指定します

 out 2151 10 2a
 out M 28 2a
 out 2608 7 3f
  o A 7 3f
 
 のように記述できます。
 「2151/M」は、2151またはMを記述できるという意味です。


例3.
 oled init|on|off|cls|bright|string  ... oled control
      bright brightness(hex)
      string x y color(hex) string

 oled init
 oled bright ff
 oled off
 oled string 12 16 ff test!

 のように記述できます。
 一部オプションでは、追加引数があります。そのようなコマンドは下に追加が必要な場合のオプションが追記されています。
 (hex)となっている引数は16進数で指定してください


例4.
 play [filename(8+3)]                ... playfile/information

 play
 play testdat~1.vgm

 のように記述できます。「[]」は省略可能の意味です。


コマンドの簡易説明

reset
 CPU又はFM音源をリセットします。

clock
 FM音源に供給するクロックを指定できます。あらかじめ決められた組み合わせ以外は指定できません。

eeprom
 オプション設定を管理するEEPROMの内容を表示したり、書き換えたり、書き換えた場合のチェックサム合わせや、
 内容をオプション設定に反映したりできます

 →この機能はスタンダードなOPNAM(4759)では実装されていません


button
 ボタンの押下状態を表示します。負論理の為押下していない状態では7となります。
 押したボタンのビットが0になります。全部押すと0になります。
 この数値が意図した状態と違う場合、ボタンの半田がおかしい可能性があります。

led
 LEDの点灯・消灯を制御します

lcd
 LCDの初期化、クリア、バックライト制御、文字列表示を行います

oled
 OLEDの初期化、表示・非表示、クリア、輝度(正確にはコントラスト00〜ffで、00が半分くらいの輝度です)、文字列表示を行います

 →この機能はスタンダードなOPNAM(4759)では実装されていません

sd
 SDの制御を行います。SDカードのSPIモード初期化、ディレクトリエントリの表示、セクタ読み込み、書き込み、データ設定、ダンプなどが行えます。
 SDカードはSPIモード初期化を行うことでデータの読み書きができるようになります。SDカードを初期化するわけではありません。

 sd init
 まずこのコマンドでSDカードを使えるようにしてください。(SDカードを挿入した状態でボードを起動していた場合、すでに初期化済みです)
 SPIモード初期化コマンドです

 sd dir
 FAT32のディレクトリエントリを確認できます。8+3ファイル名のみです。

 sd r 0
 リードコマンドで指定したセクタを読み込みます。SDバッファに読み込み、バッファをついでにダンプして表示します

 sd w 0
 SDバッファの内容を書き込みます

 sd set 10 01 02 03 04 ..
 バッファの内容を書き換えます。setの後に、アドレスを指定し、そのあとにデータを指定します。
 コマンドの有効最大長はそこまで長くありません。
 長いデータを書き換える場合は複数回指定してください。
 通常はsd readコマンドでバッファに読み込み、sd setコマンドで必要な場所だけを書き換え、sd writeコマンドでバッファの内容を書き込むという使い方をします。

play
 ファイルの再生を指定しています。8+3ファイル名のみです。
 ファイル名を省略した場合、再生中のファイル情報を表示します。

stop
 ファイルの再生を直ちに終了します。

cd
 現在のカレントディレクトリを、指定したディレクトリに変更します。
 ルートディレクトリに直接戻る場合はcd /のように指定してください。1つ上はcd ..を指定してください。

fm
 FM音源チップのレジスタバッファにある情報を出力します。
 内部的に保持しているレジスタ情報の為、実際のチップの情報ではありません。大体同じです。

temp
 現在のCPU温度を表示します。

 →この機能はスタンダードなOPNAM(4759)では実装されていません

help
 簡易ヘルプを表示します。


unlock yes
 ピン制御のロックを解除します。セーフティ解除は作成時のみに利用してください。
 音源チップをつけたままピンを制御しないでください。

pin
 ピンの出力を制御します。通常状態ではこのコマンドは実行できません。セーフティを解除する必要があります。
 ピン名としては IC WR RD CS D0 D1 D2 D3 D4 D5 D6 D7 A0 A1を指定できます。
 pin 2151 WR 1
 pin M IC 1
 のように指定できます。

SETTING.CFGの使い方

SDカードのフォルダ内に設定ファイル「SETTING.CFG」を配置しておくことで、そのフォルダ内の演奏に限定して設定を行うことができる機能について、
設定ファイルのサンプルだけでしか記載していなかったので、専用に章を設けて解説します。

※v1.07から追加された機能です
 ファームウェアのバージョンによっては利用できない可能性があります。アップデートしてください
 一部の設定項目が使えない場合もバージョンアップしてください


■どういう機能なのですか?

曲によっては、この曲だけ、音量を下げたい/上げたい!などという事があります。

対象の曲ファイルをフォルダに入れ、音量を調整する設定を入れた設定ファイルを同時に配置することで、
そのフォルダ内だけ設定を適用することができます。


■設定ファイルについて

テキストファイルです。
コメントも記載できます。
文字コードはおそらくどれでも大丈夫です。
改行コードはCRLFです。

要は、メモ帳で作成してOKということです。

適用したい曲ファイルの入っているフォルダに「SETTING.CFG」というファイル名で配置します。



■設定について

変更が必要な設定のみを記載してください。
変更が必要ない設定の記載は必要ありません。
現状の設定がそのまま引き継がれます。



■記載方法について

設定項目と設定値を1行ずつ記載していく形式です。

例.
LoopBreaker=on

設定項目と設定値の間は=を記載してください。
スペースやタブは自動的に省略されます。

例.
2151PanInv = invert


設定値は、行の先頭から記載してください。
コメント行は先頭を#から開始してください。

例.
#以下の設定は〜です



■簡単な記載例

#このフォルダの曲は適切に初期化しない為、チップ自体のハードリセットを強制します
ResetFMChips=hard

#SSG音量が低い為、音量を+2(設定値2)にします
SSGV.Adjust=2

.
.
.


※サンプルはv107(ファームウェアのところにあるzipファイルです)にあります



■設定項目と設定値について

設定項目は大文字小文字を区別します。正確に記載してください。空白は途中に入りません。
設定値は数字及びアルファベット小文字で構成しています。

NGとなった設定行は無視されます。特にエラーなどは出ません。
設定が効いていないと思った場合は、設定ファイルの記載を確認してください。

また、設定しても意味がない設定については機能しません。
例えば、SCCIモードなどです。これはSDカードからの自動演奏中には意味がありません。



■設定項目/設定値一覧

設定項目と設定する項目値を記載します。
わかりにくい設定値についてのみ解説を記載しています。

・LoopBreaker

  on
  off
  inifinite


・Shuffle

  on
  off

・ResetFMChips

  soft
  hard
  off

・BackLight

  -
  0
  3
  5
  10
  30
  60


・SCCIMode

  normal
  normalf
  light
  lightf


・2151Volume

  15〜0
 16〜31

 ※15が100%で、0が50%です。
  16が100%で、31は180%程度まで増加します

・SubDirectory

  disable
  enable


・YM2608Wait

  heavy
  light


・DisplayMode

  0〜7

 ※0	2608標準	FM1-6,SSG,Rythm,ADPCMすべて表示
    1	2608簡易	FM1-3,FM4-6,SSG,Rythm,ADPCMをまとめて表示
    2	2151標準	FM1-8(2151)
    3	4759標準1	FM1-3,FM4-6,SSG,Rythm,ADPCM, FM1-3(2151),FM4-6(2151),FM7-8(2151)
    4	4759標準2	FM1-6,SSG,Rythm,ADPCM, FM1-2(2151),FM3-4(2151),FM5-6(2151),FM7-8(2151)
    5	4759簡易	2608すべて,2151すべて
    6	2151拡張	2151標準+クロック表示付き
    7	auto		



・SDSpeed

  機能しません


・2203/2608

  2608
  2203


・SDLED

  enable
  disable


・Comment

  comment
  graphic


・2151Clock

  auto
  3.57
  4.00

・2608Clock

  auto
  8.00
  7.98


・Hold

  enable
  disable

・PlayList

  disable
  enable


・ManualReset

  機能しません


・OLEDSaver

  0
  30
  60
  90

 ※0が無限


・OLEDOff

  0
  60
  120
  180

 ※0が無限


・OLEDResume

  screen
  direct

・EEPROM

  overwr
  only

・PlayHold

  enable
  disable


・SCCIWait

  0〜7

 ※0〜3	Lv.0 〜 Lv.3
  4〜7	LV.-1 〜 Lv.-4

・OpeningBGM

  disable
  enable

・SpecialTitle

  enable
  disable

・SortEntry

  enable
  disable


・BlankWait

  0
  1
  2
  3

 ※0がOff
  1〜3は、1秒〜3秒に対応


・2151PanInv

  invert
  normal


・2608PanInv

  invert
  normal


・SSGV.Adjust

  0〜7

 ※0〜4が、+-0 〜 +4
  5〜7が、-1 〜 -3


・2608Volume

  0〜31

 ※15が100%で、0が50%です。
  16が100%で、31は180%程度まで増加します


・ADPCMW-Wait

  light
  normal


・SDWait

  heavy
  light

・OLEDPan

  機能しません

・IOPS

  機能しません

・PDXEmulation

  機能しません


・PDXM.Volume

  機能しません


・PDXVolume

   機能しません


・AutoSkip

 0〜3

 ※0	off
    1	60秒
    2	120秒
    3	180秒





他は2608プレーヤーのページを参照してください。