I/Oも用意できたのでいよいよ意味のあるプログラムを書いてみますが、いくつか準備があります。
1.2段階ジャンプ
これはトランスピュータのアーキテクチャを調べ始めた時にも検討していましたがリセットベクタがメモリ空間の最上位-2:Bootstrap(0x7FFFFFFE)の位置にあって残り2バイトなので大ジャンプするコードが書けません。そこでいったん中継点:startvect(0x7FFFFFF0)に飛んでそこから改めてROMの先頭番地:MemStart(0x7FFC0000)へ飛ばすことになります
この一連の16バイトコード:
”63 20 20 20 0B 00 00 00 00 00 00 00 00 00 60 00”
はROMの最終16バイトに毎回必ずセットしてやることになります。80x86のメモリ空間最上位-16の位置に置くjump far segment,offset "EA xx xx xx xx"みたいなもんです
2.インストラクションセット
ここが一番のポイントなんですが・・JUMP以外のメモリアクセス系のインストラクションをマニュアルで調べてます
先ず基本的にトランスピュータは内蔵の汎用レジスタが32bit長のもので3本(Areg,Breg,Creg)あり、それらはAreg→Breg→Cregとスタック構造になっています
レジスタトップ(Areg)に定数を押し込むのがLDC(load constant)命令です
Aレジスタをポップして値をメモリ空間の任意の場所に書き込むストア命令STL(store local)がありますが
これは別途用意されているレジスタ:WorkspacePointer(Wptr)でインデックスされたレジスタ間接アドレッシングということでしょう
最初なんでここでは簡単にレジスタ直接アドレッシングでいきます。これにはSTNL(store non-local)命令が使えそうです
Bレジスタの値をAレジスタで示されるメモリアドレスに書き込む、という動作になります。すなわちあらかじめ書込み値、メモリアドレスの順でLDC命令でスタックにプッシュしておく必要があるということです
3.ビット入れ替え
これは完全にポカミスによる自己都合なんですが生成されたコードをROMに焼く際に32ビット幅コードのうちD23とD22を入れ替えておく必要があります。アセンブラが出力したバイナリベタコードを4つの8ビット幅ROMに焼くためにコード分割するツールを作りそのうち3個目だけ変換関数をかましておきました
ところでこの変換の入出力をプロットするとこんな非線形関数になります。昔、電子楽器の音源がアナログからデジタルに移行するころ、低コスト(PCMはメモリをたくさん使うので)で倍音を豊かにするためにFM音源,PD音源,LA音源とか方式が色々出ましたが、単純にカウンタとD/Aコンバータの接続をスクランブルすればいいんじゃねと個人的に実験してみました(素直につなぐとのこぎり波になる)でもあまり楽音に使える結果にはならなかったような・・・