Frequency Shifter の検討(その1) 原理と構成について
Fig1
Freqency Shifterって?
長い入院生活の間で何か面白いモジュールの検討をしたいと思っていました。
そのとき頭に浮かんだのが、Freqency Shifter です。
かなりマイナーなモジュールで、私自身も実際の製品を見たことも無く、音を聞いたこともありません。
なぜ思いついたかというと、10年近く前ですが、houshu氏が学会で京都に来たとき、折角だからということで夜に京都でお会いし飲む機会がありました。
そのとき、彼が話題のひとつとして持ってきてくれたのがFreqency Shifterで、資料としてたしかUSP(米国特許)を見せて貰ったように思います。
このモジュールがどれほど音作り効果が期待できるかはともかく、技術的な面白さに大層興奮したことだけは記憶しています。
検討に入る前のおぼろげな私の理解
・Ring Modulatorで得られるピッチシフトは、必ず二つの周波数(和と差の周波数)が発生する。
多くの場合不協和の2音が現れるので、倍音が多い原音を入れるとすぐ濁ってしまうので、きれいな音を出すには、原音は倍音の少ないものに限定される。または、あえて濁った音を出す使い方になる。
・なんとかして和や差だけの周波数が得られれば、濁らせずにピッチシフトができ、より広範囲な応用ができそう。
・Ring Modulatorでの4象限乗算を90度位相のずれた、sineとcosで各々行えば、差の出力を打ち消すことが出来そうである。
・自分で発生する変調信号では、sineと同時にcosも出力するの構成が可能。
しかし、入力される任意の原音(倍音も含めて)に対して90度位相のずれた信号(倍音含む)を作るのは困難。たぶん不可能だろう。(各倍音を検出して90度位相のずれた信号を作るデジタル的な手法は×。原音には和音や打楽器音なども来るため。)
・dome filterという巧妙な技術により原音を二相化できそう。
ポイントは原音の全ての倍音を二相化するのでは無く、位相の絶対的なシフトは気にせず(耳では位相だけがずれても違いは分からないはずなので)相対的に90度位相のずれた出力を出す二組のPhase Shifter(広域に直線的に位相がシフトよう設計された)の二組の出力を、sineとcosとする。
dome filterはFreqency Shiftwerのキモですので次回詳しく説明します。
今回の検討
病室からhoushu氏にメールして、moog他の資料のURLを教えて頂き、時間を掛けて検討を進めました。
その結果を整理すると、
(1) Freqency Shifter(FS) は Ring Modulator(RM) の発展系である。
・Ring Modulator(RM)
RMの機能を数式で表すと、原音を正弦状波 cos(ωt)、変調波も正弦状波 cos(αt)とすると、
両信号の4象限乗算になるので、
となり、よく知られているように、両信号の和の周波数の正弦状波と、差の周波数の正弦状波がミックスされたものになります。
実用的には変調波には正弦状波が用いられますが、原音には何が入力されるか解かりません。
倍音も含む場合は、例えば2倍音に対しても式(1)からα加算とα減算のミックスが生成されます。
倍音に対して一定周波数が加減算されるので、ピッチか変わる効果と倍音構成が崩れる効果が得られます。
・Freqency Shifter(FS)
ピッチシフト効果を狙うためには、和のみや差のみを取り出したいところです。
それが得られる数式が、三角関数の加法定理です。
(2A)を用いると和のみが得られ、(2B)で差が得られます。
これを実現するには、二つのRing Modulator と加減算器が必要で、
構成を図で表すとFig.1 のようになります。
変調側のsin(αt)を作るのは、cos(αt)とsin(αt)を発振する二相発振器で可能ですが、
もっと難しいのは、sin(ωt)を作ることです。
これには、上で説明したDome filterを使います。
6809/Z80マシーンを発掘しました(4) マルチCPUの仕組み(2) ソフト編
マルチCPUの仕組み(2) ソフト編
動いているCPUが自分自身を停止させ、相手を動かせるハードの仕組みについては、
6809/Z80マシーンを発掘しました(3) マルチCPUの仕組み(1) ハード編 - 電音の歩み
を見てください。
とてもシンプルなハードですが、シンプルすぎてどのように使えば良いのか疑問にもたれた方もあるでしょう。
実際、このハードだけではCPUを交互に動かせるだけなので何もできません。
これを活かすソフト面での仕掛けが、「CPU Manager」です。
この図は、発掘したソースコードを見て、私が再発見しながら書いた「CPU Manager」の動作フローです。左半分は6809コード、右半分はZ80コードです。
仕組みはとてもシンプルですが、驚くほどパワフルです。
この「CPU Manager」の狙いは、
(1) 6809からZ80の関数を、Z80から6809の関数を引数付きでコールできる。
( ACCA, X ) は、 ( Areg , HLreg )に相互に引き継がれます。
(2)相互の関数コールは、多重にできる。
だけです。
これができれば、相手のCPUの関数も自在に利用できることになりますよね。
まず、基本動作を説明します。
■Z80側の初期化
Resetが掛かると最初に6809が動き出すので6809側の色々な初期化は自由にできますがZ80側の初期化も必要です。
話を簡単にするため、ここには書いていない6809側の初期化コードで、Z80をResetから起動しSPを設定し、< 0 >のルートでCHG_CPUのポイントまで導き、制御を6809の初期化コードに戻します。(Z80 のRESET後の例外的な動きのためハードでもRESETを記憶するD-FFが付いています)
これで Z80 側の準備もできました。
重要なのは、CHG_CPU(どちらのCPUからも切替ポートにダミーライトすると相手に制御が移る)のポイントは、どちらのCPUも1箇所しか無いことです。
■6809からZ80の関数をコールする動作
6809でZ80の関数(サブルーチン)を呼びたいときは、
CALLZ80 address
というマクロを記述します。
実際の命令は、
JSR CALZ80
FDB address
というコードが生成されます。
シーケンス< A >
JSR 命令の後ろに続くコーリングシーケンスのアドレスを取り出し、引数メモリの (PC) に格納し、" CFLG = 0"にします。これは、6809からZ80をコールすることを意味します。
さらに、 X レジスタを ( XREG )、 ACCA を( AREG )に書き込み、CHG_CPUポイントでCPUを Z80 に切り替えます。
シーケンス< 2 >< 4 >< 5 >
6809は停止し、Z80は CHG_CPUポイントから動き出します。
( XREG )を HL レジスタに、( AREG ) を A レジスタにロードし、CFLG をチェックします。
ここでは CFLG は 0 なので、( PC )のアドレスのサブルーチンをコールします。
関数から戻ってくると、今度は CFLG は 6809 に Z80 から帰ってきたことを示すために" CFLG = 0" に再設定し、HL と A レジスタを書き戻し、CHG_CPUポイントでCPUを 6809 切り替えます。
シーケンス< B >< C >
CHG_CPUポイントから戻ってきた6809は、レジスタの引き継ぎを行い、 CFLG をチェックし ここでは CFLGが 0 なので、Z80 の関数から戻ってきたことが分かり、リターンします。
ここが重要なポイントですが、もしこのとき CFLG が 1 であった場合、6809からコールしたZ80の関数から戻ってきたのでは無く、そのZ80の関数の中からさらに6809の関数をコールしたことになり、シーケンス< C >ではなくシーケンス< D >に向かいます。
このCFLG の仕組みと、6809 と Z80 それぞれのスタックの働きにより、何重にでも多重コールが実現できることになります。
話が飛びましたが、こんどはZ80から6809を呼ぶ動作を説明します。
■Z80から6809の関数をコールする動作
シーケンス< 1 >
CALL CALL6809
DW address
と記述すると、シーケンス < 1 >に入り、" CFLG = 1"として CHG_CPU に行き、制御を 6809に移します。
シーケンス< B >< D >< E >
6809はレジスタを引き継ぎ、 CFLG が 1 であることを確認し、addressの関数を間接アドレッシングのJSR命令でコールします。
戻ってくると6809関数からの復帰を知らせるため、CFLG を再度 1 に設定し<
CHG_CPUポイントからZ80に復帰します。
シーケンス< 2 >
レジスタを引き継ぎ、CFLGが 1 なので6809からの帰還と見なしRETします。
■6809からZ80の関数をコールし、その関数は6809の関数をコールしているときの動作
6809で書かれたアプリケーションソフトが CP/M で動作している様子を見てみましょう。アプリは既に動いており、スクリーンに文字を表示しようととしています。
6809コードのアプリですので、Z80コードのCP/M の API をコールするためには、CALLZ80機能を使います。
ここまでで、CFLG=0 でシーケンス < A><2 > < 4 >まで来ました。
CP/M の API は さらにZ80コードのBIOSをコールします。
ところが呼ばれたBIOS の大半のAPI はそのまま 6809 で書かれた ROM内ルーチンをコールするだけで済ませています。
即ち、CFLG=1 として、シーケンス< 1 >< B >< D >と進みます。
< D >で呼ばれたROM内の6809コードで文字表示を行い、CFLG = 1として< E >
を進み、CHG_CPUで< 2 >< 3 >と抜け6809関数コールを終えます。
この関数コールをしていたのは、< 4 >で6809から呼ばれていたZ80 のBIOSですので、CFLG = 0 として< 5 >に進み、CHG_CPU ポイントから、6809コードで書かれたアプリに戻ってきます。
万事うまくいくでしょう。
このような仕組みにより、FLEX09用に作られた6809コードのスクリーンエディタ " DUET " ですが、APIコールだけ CP/M 用に変更して、立派な CP/M アプリとして動いています。
アプリのコードも実際のBIOSの下請けコードも全部 6809 なので、このアプリの動作中はほとんど赤のLEDが点いています。
6809/Z80マシーンを発掘しました(3) マルチCPUの仕組み(1) ハード編
マルチCPUシステムの工夫
実家をあさっていると、このシステム(たぶん)の回路図や資料も出てきました。
今見ても面白い点があるので、一度まとめて紹介します。
まず一番の売りは、「6809からZ80のサブルーチンをコール」したり、逆に「Z80から6809をコール」したり自由に(多重に)できることです。
これを使って、CP/MのBIOSを6809のコードで書いたりしています。
この機能は、ハードとソフトの連携で実現しているのですが、ハード側は、単にCPUを切り替えるだけの回路で大変シンプルです。
■CPU切り替えのハード側の仕組(アービトレーション)
このシステムは、68B09(2MHz)とZ80(4Hz)、ふたつのCPUのアドレスバスとデータバスを完全にパラ接続する完全密結合のマルチCPUシステムで、ダイナミックにふたつのCPUが切り替えられます。
切替には1bitの切替ポートが用意されており、最初は6809側になっています。
6809が動いているときはZ80は*BUSREQ状態のためアドレス/データバスを開放(ハイインピーダンス状態に)して止まっています。
そこで6809が切替ポートをダミーライト(青矢印)すると、切替ポート(LS393)がZ80側に代わります。緑矢印により6809にHALTが掛けられ、6809がバスを開放して停止したのをBSとBAにより確認してから、Z80の*BUSREQを外しZ80が動き出します。
逆にZ80が切替ポートにダミーライトすると(このポートはトグル動作なので)こんどは6809側になり、Z80に*BUSREQをかけます。こんどはZ80がバスを開放して停止したのを*BASACKにより確認してから、6809の*HALTを外し6809が動き出します。
このように6809とZ80がたすき掛けになったフリップフロップのような動作をして、とてもシンプルなバスアービトレーションを実現しています。
D-FFは、RESET時にZ80を起動させない働き(リセットを解除させない)をします。
最初の切り替えアドレスに6809がダミーライトして初めてZ80のリセットが外れます。
この仕掛けにより、6809側のソフトとZ80側のソフトをCPU切り替えハンドラに導くことが出来ます。
具体的には、
① リセットで起動した6809はCPU切り替えハンドラに到達し、Z80に切り替える。
② Z80のリセットが外れ、Z80もCPU切り替えハンドラに到着し、6809に切り替える。
③ 制御は6809に戻り、かつZ80は切り替えハンドラで切り替えられるのを待機する状態になっている。
ソフト側の仕掛けは次回
6809/Z80マシーンを発掘しました(2) CPUボード
■ 6809 と Z80 マルチCPUのCPUボードです。
'81から'82頃に作ったものと思います。
裏面
ジュンフロン線で手配線です。 昔は苦も無くこんな配線していたのです。
2本切れた線がありました。わかりやすいところでしたので付けなおしました。
表面の中央
中央が日立製の2MHzの68B09 、右がNECのZ80です。
左のP-ROMは、4KB の2732です。アドレス$F000-$FFFF に配置されてます。
後半の$F800-$FFFF は、モトローラ製の高機能モニタプログラム Assist09 を入れています。
前半は、Assist09 の独自拡張部 (私が作りました)が入っています。
主には、6809とZ80の切り替えサポート(互いに相手のCPUのサブルーチンをコールできる仕掛け)と、8インチフロッピーのドライバが入っています。
表面の全体
上に乗っている基板は、DRAMです。
64Kbit ×8 ×2 で 128KBあります。
8bitCPUのアドレス空間(16bit )は、最大 64KBなので、2ページ分になります。
簡易MMUを使って 8KB 単位に、ページを選択できる仕組みです。
右上のLEDですが、赤は6809/緑はZ80 が走っていること示します。
CP/Mが走っているときは両方が点滅していました。(BIOSは6809コードなので)
6809/Z80マシーンを発掘しました(1)
年始めに母が他界して無人になった実家から色々なモノが発掘されました。
そのひとつが、6809/Z80マシーンです。
6800から6809に進んできて最後に自作したマシーンです。
その後は、FM77を購入してしまいました。
ジャンクの 8"FDDです。大変でかくて重いです。
逆にディスプレイは、ジャンクのモノクロモニタでこちらは小さい。
それまでカセットテープしか使っていなかったので、あこがれのフロッピーでした。
6809 / Z80 のマルチCPU マシンなので、6809のFLEX09 だけでなく CP/M も移植し使っていました。このCP/Mは、BIOSのほとんどが6809コードで動作する面白い物ですので、これについては、次回以降詳しく書きます。
これを作った時期ですが、いつ頃のものかを記憶にあるイベントから推測しますと、
・大学4回からM1いっぱいの間('77-'78)、初歩のラジオに例のアナログシンセを連載
・'79に松下電器に就職
・'79にアスキーに「なかもずTinyBasic」を発表
これは、日立のH68というワンボードマイコンを拡張したものをベースに開発。
その頃、私がマイコン開発をどのように始めたかは、ここを見てください。
http://hyamasynth.web.fc2.com/ACII_NTB/ACII_NTB.html
・'80-'83 勤めて時間が無くなったため、それ以降の開発ものは発表していないので正確な時期はよく分かりませんが、
6800のNAKAMOZU BASIC COMPILER (なかもずTinyBasicのコンパイラ版)を開発
その後6809のNAKAMOZU BASIC COMPILERを作ったわけですが、
それの開発に使った6809マシンがこれです。
八尾ロボットフェア2018でLEDバッジ製作教室
今年も八尾アリオのロボットフェアで「LEDバッジの製作教室」をやりました。
4年生以上としていたのですが、八尾のおばちゃんの圧力に負け、ついに2年生まで引き受けてしまいました。
はんだ付けに苦労する子、お絵かきで悩む子、などいろいろ有りましたが、完成したらみんな笑顔でした。
多くの子がこれから「電子工作」をしてみたいと言ってくれました。楽しそうな様子を見てください。
応援に来てくれれリペアを手伝ってくれたIKKEIさんありがとう。
まずは、バッジにLEDをはんだ付け
LEDはどちら向けに付けてもOKになっています。
次は、バッジ表面にアクリル絵の具でお絵かきです
何を描いて良いか悩む子や、最初から絵のイメージを描いてLEDの色と配置を決めている子もいました。
ご満悦の子
作ったバッジを妹にプレゼント
なかよく二人でエントリー