エミュレーター
2012年 4月、ペーパーマシンが誕生 !
この度、TANACOM-1 のエミュレータがやっと完成しました。
あなたのPC( Windows機のみ )の上で、TANACOM-1 が動きます。
エミュレータ pack のダウンロードとインストール
では、さっそく、エミュレータ pack をダウンロードしましょう。
( このエミュレータ pack は、フリーライセンスで無料です )
[New]クロスアセンブラを同梱しました!
[New]サンプルGameソースを追加です!
エミュレータ更新しました・・・ Ver 0.93
クロスアセンブラ更新しました・・・ Ver 1.5
但し、配布中のエミュレータ( tanacomemu093 )は、CPU 使用率が まだ100% 近くになる場合があります。
主な変更点: TANACOM-1 CPU の停止時に限り、エミュレータのWin機Cpu使用率を低減しました。
ダウンロードしたZIPファイルをお好きなフォルダー/ディレクトリに展開
してください。インストール作業はこれだけです。
- ①エミュレータ
tanacomemu093.exeを実行すれば、すぐにエミュレータが動きます。
アプリフォルダは、マイドキュメント等お好きな場所に移動されても結構です。
- ②クロスアセンブラ
tanacom1casm15.exeを実行すれば、すぐにクロスアセンブラが動きます。
ソースフォルダは、マイドキュメント等お好きな場所に移動されても結構です。
今回、ほとんどのファイルが更新されておりますので、旧バージョンをご使用の方は
恐れ入りますが、古いものを削除(アンインストール作業不要)して、新しいものをお使い下さい。
なお、エミュレータにて自動的に作られる設定ファイル(tanacomEmulater.ini)には、
ウェィトパラメータが保持されていますので、従来のtanacomEmulater.iniを今回のtanacomemu093.exeの在るフォルダにコピーすると、そのまま使えます(もちろん、そうしなくともtanacomemu093.exe上で新たにWAIT値を設定してやっても大丈夫です)
画面各部のご説明
起動直後の画面です
■ 黒地の画面が、TANACOM-1 エミュレータのメインウィンドです。
TANACOM-1 に接続されている、ディスプレー画面( VRAM )とキーボードを担当します。
メインウィンドには、「RUN」と「DISK」のランプがあります。
「RUN 」・・・ CPU が RUN 中に、緑に点灯します。
現在、消えていますので、CPU は停止状態です。
「DISK」・・・ TANACOM-1 に PC からファイルを読み込んでいる時に、赤く点灯します。
本来、TANACOM-1 には、ディスクは存在しませんがご愛嬌です。
■ 白地で横長の画面は、CUI ウィンドと称すサブ・ウィンドです。
コマンドやパラメータを打ち込んで、TANACOM-1 を操作します。
メインメモリに対して、書き込み、読み出し等の作業を行います。
Windows機で言えば、DOS窓 的な役目です。
あなたの TANACOM-1 は、何MHzで動く?
皆さんがお使いの PC は、30数年前に作られた TANACOM-1 に比べると、超高性能になっておりますので、WAIT をかけないと、早すぎて、ゲーム等が遊べません。
そこで、まずは WAIT 値を決めましょう。
( STEP 1 )
メインウィンドのメニューバーにて、「 FILE 」-「 Load 」と選択し、アプリフォルダより、「エミュCLOCK測定.txt 」を読み込みます。
ファイルの中身は、実はこの様になっています。
0000,000C
0000,090B,FE00,2001,A103,4801,A103,FE01
FE02,F100,8100,00E6
これは、TANACOM-1 のシングルブロックのマシン語ファイルで、テキストで構成されています。内容は次のような意味があります。
このファイルでは、アドレス 0 番地から順に、12個のデータを書き込んで行きます。
( STEP 2 )
では、さっそく、実行してみましょう。
メニューバーにて、「 CPU 」-「 CPUをReset 」と選択します。
きちんとリセット出来たか、現在のレジスタの状況を見てみます。
メニューバーにて「 コマンド 」-「 各レジスタ表示 」を選択します。
Pc が 0000 になっていますね。
( STEP 3 )
では、メニューバーにて「 CPU 」-「 PC の示す現アドレスから RUN 」を選択します。
これで、読み込まれたプログラムを 0 番地から実行し始めました。
メインウィンドの RUN ランプは、緑色に点灯します。
数秒のうちに
このような表示が返って来ました。この例では、約 334 MHz だと、出ました。
本物の TANACOM-1 は、10 MHz で動いていますので、それの 33 倍ほどで、今エミュレータが動いていることを示しています。
( STEP 4 )
さあ、では、WAIT を指示してみましょう。
CUI ウィンドの「 CMD / Para 」に、WAIT セットのコマンドを入力します。
WAIT セットコマンドは「 W xxxx 」で、引数xxxx は 0 ~ 0x7ffffff まで指定できます。
引数 0 を指定すると、WAIT なしのフルスピードとなります( WAIT 値のみ 32bit 変数なのです)。
皆さんは、まず「 W 0100 」程度から始められて、0200 → 0300 → 0400 と試されて、適正値を探されると良いでしょう( コマンド等に使います引数は、すべて 16進表現になっております)。
今回は例として「 W 0460 」と入れてみます(エンターキーを忘れずに)。
そして、先ほどと同じく、リセット後、 「 PC の示す現アドレスから RUN 」を指示します。
すると、約 30 秒ほどで、
と出ました。今度は、10.207 MHz となりました。これで、目的達成です。
実際は、先ほど述べましたとおり、何回か試行錯誤して、約 10 MHz になる適切な WAIT 値を見つけて行きます( あまり神経質にならなくて結構です。およそ 10 ~ 11 MHz になれば大丈夫です )。
WAIT 値は、変更しない限り、すっと記憶されてます。
さあ、基本ソフトFORSEの読み込みです
メインウィンドのメニューバーにて、「 FILE 」-「 Load 」と選択し、アプリフォルダより、
「基本ソフトFORSE.abn 」を読み込みます。
ファイルの中身は、実はこの様になっています。
0000,08af
0000,06cf,7c00,7dd9,ffff
F001,8302,012C,191D,0800,7000,B109,90EA,・・・
お気づきのように、拡張子が「 .abn 」となっています。
これは、TANACOM-1 のマルチブロックのマシン語ファイルで、同じくテキストで構成されています。
内容は次のような意味があります。
これで、基本ソフトFORSE がメインメモリに読み込まれました。
FORSE のスタートアドレスは、 0x0100 なのです。
では、コマンドで PC に 0x0100 をセットして・・・、
実は、メニューバーに、「 CPU 」-「 FORSE Re-START 」がありまして、これは「 常に 0x0100 から RUN 」してくれるのです。
よって、FORSE をスタートさせたい時は、これを使います。
さあ、スタートさせてください。
「ポッ」と beep 音がして、 FORSE の起動画面が現れます。
まずは FORSE アプリを読み込んで遊んでみましょう
今回、サンプルプログラムとして、大昔マイコン界ではあこがれのゲームだった「スタートレック」を入れております。
FORSE が RUN の状態のままで結構ですので、先ほどと同じように、メニューバー「 FILE 」-「 Load 」で、アプリフォルダにあります「 STARTRAK改善版.abn 」を読み込んでみます。
これは、 FORSE のアプリになります。マシン語ではなく、 FORSE の各命令で書かれています。
では、アプリ・プログラムの中身を覗いてみましょう。
「 T 」+エンター
と打ち、編集ポインタをトップに持ってきます。
そこから
「 P10 」+エンター
と打つと、編集ポインタ位置から、プログラムを10 行リストしてくれます。
画面には、
では、ゲームを実際に、走らせてみましょう。
FORSE での、RUN 指示は、
「 @ 」+エンター
画面が消去されゲームがスタートします。
画面には、
スタートレックの始まりです!
もし、スタート直後の宇宙全体の設計を行う部分が、あまりにも長いと感じられる場合は、FORSE Re-START して、最初からやり直してみて下さい(条件が合うような宇宙を乱数を用いて展開する処理にバグ疑惑?・・・)。
さあ、ゲームの中での指令コマンドは、
[S] ・・ SHORT RANGE SENSOR
[L] ・・ LONG RANGE SENSOR
[G] .. GARXY MAP
[P] ・・ PHASER
[W] ・・ WARP
[T] ・・ TORPEDOES
[R] ・・ REPORT
[Q] ・・ QUIT
魚雷やワープでは、方向を指示してやりますが、その「方向」とは、
上を0度とし、時計回りに90度、180度、270度となり、0~359度まで、1度単位で指示出来ます。
・・・この先は、おいおいご説明してまいります。
待ちきれない方は、ネットで「スタートレック」を検索して、遊び方と指令コマンドの使用方法を見つけてみて下さい。
今回のスタートレックは、ソースがあちらこちらで公開されている Palo Alto 版 Tiny BASIC 用スタートレックをベースにし、過去のパソコン雑誌等も参考にして、FORSE で書き直しました。
よって、指令コマンドの使い方等は、一緒のはずです。
もしも途中で、暴走したり、変な動きをしたら、メニューバー「 CPU 」-「 FORSE Re-START 」 で仕切り直しをし、再スタートすると良いでしょう。
ご注意.
FORSE アプリは、基本ソフトFORSE の上で走るアプリですので、メモリに基本ソフトFORSE が先に読み込まれていないと、「 FORSE Re-START 」しても、暴走するだけです。
エミュレータの使い方
メイン・ウィンドの操作方法
メイン・ウィンドのメニューバーについて、ご説明します。
メニュー項目に於いて、「黒丸●」の付いたものは、パラメータを必要とする操作であることを表しております。
パラメータは、CUI ウィンドの「 CMD / Para」エリアにキーボードで直接入力します。
■ メニューバー [ FILE ]
- Load
TANACOM-1のシングルブロックのマシン語ファイル(拡張子に定めなナシ)、ならびにマルチブロックのマシン語ファイル(拡張子は .abn )をメインメモリに読み込む。
- Text Load
FORSE のプログラム領域に、通常のテキストで書かれた文章をFORSE プログラムとして読み込む。
その時点で FORSE のプログラム領域に何かプログラムが書かれていても、無視してロードされます。
読み込まれるテキストファイルは、TANACOM-1 が扱える文字で構成されている事が前提です。扱える文字は、半角英数字(大文字のみ)、半角カタカナ、半角記号の一部だけです。
- Save
FORSE のプログラムをマルチブロック・マシン語ファイルとして、ファイルに書き出します。よって、必ず、ファイルの拡張子を「 .abn 」にしなければなりません。
もし、FORSE のプログラムと併せて、保存したいマシン語領域があれば、CUIウィンドの「 CMD/Para 」に16進で「先頭アドレス、終了アドレス」を記述しておいて、それから「 SAVE 」の指示をして下さい。マシン語領域は、複数領域の指定が可能です。その場合、先ほどのパラメータ・ペアを必要な分、並べて下さい。
- 終了
エミュレーションの全てのウィンドを閉じ、終了します。
■ メニューバー [ CPU ]
- FORSE Re-START
プログラムカウンタ Pc に、FORSE のスタートアドレス 0x0100 をセットし、RUN する。
メインメモリに「基本ソフトFORSE.abn 」が読み込まれていないと、暴走します。
- 停止 HALT
TANACOM-1 をSTOP させます。プログラムカウンタ Pc は、STOP した地点の次実行すべき命令のアドレスを示しています。
- PCの示す現アドレスから RUN
プログラムカウンタ Pc が現在示しているアドレスから、RUN する
- 指示アドレスから RUN ●
CUIウィンドの「 CMD/Para 」に16進で示されたパラメータをプログラムカウンタ Pc にセットし、そこから RUN する
- CPU を Reset
CPU の全てのレジスタ、フラグをリセットする。
よって、プログラムカウンタ Pc も0x0000 になる。
■ メニューバー [ 操作 ]
- FORSE 追跡する
FORSE プログラムの命令をトレースします。実行されたFORSE 命令をCUI ウィンドに表示していきます。
この指示は、トグルスイッチになっています。
基本ソフトFORSE が走っていないと、この指示は何の意味も持ちません。
- トレースする
TANACOM-1 のマシン語の1命令1命令をトレースします。
この指示は、トグルスイッチになっています。
大きなプログラムを長時間トレースすると、CUI ウィンドが溢れて、異常な表示になる場合があります。
■ メニューバー [ 編集 ]
- FORSEアプリをクリップボードにコピー
現在、FORSE のプログラム領域に書かれているプログラムの全文を、テキストとして、クリップボードにコピーします。
よって、他のエディタ等で「貼り付け」して、閲覧、修正、加筆が出来ます。
- CUI ウィンドを隠す
CUI を必要とする操作が無い場合、サブ・ウィンドが邪魔に感じられたら、隠すことが出来ます。
この指示は、トグルスイッチになっています。
但し、CUI ウィンドが隠れたまま、CUI を必要とする操作指示がありましても、何も表示されないので、お気をつけ下さい。
■ メニューバー [ コマンド ]
- 各レジスタ表示
現時点で、実行した命令が存在するアドレスとそのメモリ内容(命令)、そして、各レジスタ、フラグの現在値および、その命令(逆アセンブル)を表示します。
もし、CPU が停止中であれば、実行した命令が存在するアドレスは、0x7fff と表示され、逆アセンブルでの命令表示はありません。
この指示操作は、CPU が実行中でも可能です。
- CUI 画面のクリア
サブ・ウィンドの CUI 画面をクリアします。
但し、「 CMD/Para 」エリアは、消去されず残されます。
CUI ウィンドの操作方法
「 CMD/Para 」エリアにキーボードより、コマンドを入力し、TANACOM-1 の操作やメインメモリへの読み書きを行います
アドレス等指示するパラメータは、すべて 16進表現です(例 01FA とか。頭に 0x や $ は添える必要はありません)。
d アドレス,[大きさ] ・・・ DUMP
アドレスの位置から、指示された大きさのメモリの内容をダンプする。
大きさが省略された場合は、大きさを16ワードとします。
p アドレス ・・・ Set Pc
プログラムカウンタ Pc に指示アドレスをセットする
r [r0値],[r1値] ・・・ Set Rx
汎用レジスタ R0 または R1 または両方に指示値をセットする
「 r xxxxx 」とすれば R0 にセットされ、 R1 は不変です。
「 r ,xxxxx 」とすれば R1 にセットされ、 R0 は不変です。
「 r xxxx ,yyyy 」とすれば R0 に xxxx 、 R1 に yyyy がセットされます。
g ・・・ Pcの示す現アドレスより RUN
w WAIT値 ・・・ Set WAIT
WAIT値を指定します。値は 0 ~ 0x7ffffff まで指定できます( WAIT 値のみ 32bit 変数です)。
値を0とすると、WAIT なしのフルスピードとなります
s SWR値 ・・・ Set SWR
TANACOM-1 のフロントパネルにあるSWR(SWレジスタ)の状態を指示します。SWRに関わるプログラムのデバッグ時等に使用されます。
m アドレス,値,値,,, ・・・ Set Memory
メインメモリに対して、指示アドレスから順番に値をセットして行きます。セットされたら、その内容がダンプされます。
z アドレス,[大きさ] ・・・ 逆アセンブル
指示アドレスから、指示された大きさ分、逆アセンブルします。
大きさが省略された場合は、大きさを16ワードとします。
b [preアドレス],アドレス,[ステルスモード] ・・・ BreakPoint
ブレーク・ポイントを設定します。
「 b アドレス」とすれば、実行中のCPU が 指定アドレスを実行した時点で、そのレジスタ等内容表示し、停止します。
「 b アドレス1,アドレス2」とすれば、実行中のCPU が アドレス1からアドレス2の範囲にある間、1命令実行ごとに、停止します。
「 b アドレス1,アドレス2,1」とすれば、実行中のCPU が アドレス1から1命令ごとにレジスタ等内容表示しながら実行され、アドレス2を実行した時点で、停止します。
「 b アドレス1,アドレス2,2」とすれば、実行中のCPU が アドレス1から1命令ごとにレジスタ等内容表示しながら実行され、アドレス2の時点で、平常に戻り、先へ進みます。
a ・・・ アセンブルド・ペースト
アセンブラで生成したマシン語(シングルブロック)をペーストにて、メインメモリに書き込みます。
c ・・・ CUI 画面 Clear
サブ・ウィンドの CUI 画面をクリアします。
但し、「 CMD/Para 」エリアは、消去されず残されます。
l アドレス ・・・ Look Point
アドレスが示すメモリの内容を、レジスタ状況表示時に合わせて表示します。なお、アドレスに 0 を指定すればこの機能が解除されます。
? ・・・ Help
簡易なコマンド説明を表示します
FORSE プログラムの編集を、より簡単に
FORSE 自体ではプログラムの保存・読込みは、カセットテープだから非現実だし、FORSE エディトモードでのラインエディタも、皆様にとって相当使い辛いと思われます。
そこで、もっと簡単にFORSE プログラムの編集をやれる様に工夫しました。
新規で、FORSE プログラムを作る
- 皆様の使い慣れたエディタで、FORSE プログラムを書き、テキストファイルを保存する(但し、使える文字は、半角英数字(大文字のみ)、半角カタカナ、半角記号の一部だけですので、お気をつけ下さい)
- メイン・ウィンドのメニューバー「 FILE - Text Load 」にて、先ほどのテキストファイルを読み込み、FORSE プログラム領域に展開させる。
- 実行して、正しく動くか、試してみる。
- メイン・ウィンドのメニューバー「 FILE - save 」にて、新規のFORSE プログラムとして、保存する(拡張子.abn をお忘れ無く)。
既存の FORSE プログラムを修正したり、改造する
- まず、既存の FORSE プログラムをロードする。
- メイン・ウィンドのメニューバー「編集 - FORSEアプリをクリップボードにコピー」にて、既存の FORSE プログラム内容をクリップボードにコピーさせる。
- 皆様の使い慣れたエディタにて、新規作成に、「貼り付け」で、先ほどのテキストを取り込み、そして、好きなように、修正、改造する。
- 修正、改造したテキストファイルをメイン・ウィンドのメニューバー「 FILE - Text Load 」にて、FORSE プログラム領域に戻し込んでやる。
- メイン・ウィンドのメニューバー「 FILE - save 」にて、別の新たなFORSE プログラムとして、保存する(拡張子.abn をお忘れ無く)。
もし、既存プログラムにマシン語の添付がある場合は、それもパックして保存される様に、パラメータをきちんと設定してから、「 FILE - save 」をしなければならない。
例えば、0x1A00~0x1AF0のマシン語をパックして保存したい場合は、CUIウィンドーの CMD/Para に「 1A00,1AF0 」と入れておいてから、「 FILE - save 」を指示します。
マシン語の有無を調べるには、既存 FORSE プログラムの頭か末尾にコメントとして記録されていますので、ご確認下さい。
キーボードについて
TANACOM-1 のキーボードは、パソコンのキーボードの一部をマッピングして模倣させています。
使えるのは、アルファベット、シフトキー、ctrlキーとテンキーです。
TANACOM-1 のカナキーは、実はキーコードのbit 8 のオン・オフとして伝えられます。
エミュレータでも、その点をしっかり模倣してます。
カナキーの役目を、パソコンのキーボードでは、「無変換キー」(スペースキーの左横)にて代行させています。
よって、エミュレータでカタカナを入力したい時は、「無変換キー」を押しながら、例えば「A」を押してやると「チ」が入力されます。
また、TANACOM-1 のカナキーは、キーコードのbit 8 を独立してオン・オフ出来る点を利用して、ゲームでのミサイルの発射ボタン等によく使われます(これもキチンと再現できております)。
カーソルキーは、↑↓←→ キーで、そのまま対応出来ています。
エミュレータでの弱点として、キーボードをマッピングしながら模倣させているため、動きの早いゲームなどでは、キー反応に若干、鈍さを感じる場合が出てきます。
注.ペーストは、[ f1 ] キーが使えます。
注.アプリケーション・キー( 右 ctrl の左のキー )は、LF キーとして使います。
FORSE アプリを公開
イスカンダルのトーフ屋ゲーム(移植版)
このゲームは1978年に、原作者である津田伸秀氏が考案し作成され、当時のマイコン雑誌に掲載されたものです。
それを当方が、TANACOM-1 FORSE 上で遊べる様にFORSE言語にて移植してアプリにしました。
この度、この移植版の公開及び配布について、源著作権者の津田伸秀氏より正式にご承諾を得ました( 快くお許し頂いた津田伸秀氏には、この場を借りて、厚く御礼申し上げます )。
ゲームは、「主人公であるあなたが、イスカンダル星に1人取り残されて、トーフ店を経営しながら地球までの帰還費用を稼ぐ」というモノで、実は経営戦略シュミレーションゲームになっています。
舞台が、「イスカンダル星」というのが、また読者を引きつけました。
では、具体的な遊び方をご説明します。
- ゲーム開始時、あなたと、ライバル店は、 手持ち資金5000円を持ち、
豆腐屋経営をスタートします。
- 豆腐の製造原価は1個15円、販売価格は1個25円です。
- 豆腐の売れ具合は、その日の天候によって大きく変動します。
晴れ・・・ 500個
曇り・・・ 200個
雨 ・・・ 100個
- あなたは、明日の天気を予想し、製造する豆腐の量を決めなければなりません。
作りすぎれば、売れ残り、損失となって資金が減ります。
- 天気予報はコンピュータが出してくれます。しかし、毎回当たる訳ではありません。
- 豆腐をどんどん売って、利益を出し、資金が20000円を超えたプレーヤーが、勝者となります。
画面には、天気予報とともに、現在の手持ち資金で最大何個の豆腐が製造可能かも、表示されます。
ライバル店のオヤジは、バリバリの商売人で、口は悪いですが、手強いです。
ぜひ勝利して、地球に帰れるよう頑張って下さい。
なお、ゲーム中、「 Bksp キー」を押すと、ゲームを中断し、FORSE エディト・モードに戻ることが出来ます。
移植アプリの公開と配布ポリシー
今回の「イスカンダルのトーフ屋ゲーム(移植版)」は、原作者の方とコンタクトが取れて、移植版の公開・配布の許諾を得られた事は、本当に奇跡的でした。
当方の手元には、まだ十本近く、マイコン雑誌掲載ゲーム等の移植版がございますが、許諾取得は長~い道程の様です。
もちろん許諾取得が出来たモノは、すぐ公開・配布したいと考えておりますので、よろしくお願いします。
クロスアセンブラ
クロスアセンブラの使い方
起動直後の画面です
ソースファイルは、あらかじめ外部のテキストエディタ等で、作っておきます。
拡張子に決まりは有りません、任意です。
( STEP 1 )
「 Load 」ボタンを押して、まずソースファイルを読み込みます。
読み込んだ内容は、「ソーステキストの入力・編集画面」に表示されます。
ソーステキストが読み込まれました
( STEP 2 )
まずはリファレンス・タイプで、アセンブルしてみます。
「 ASM-Ref 」ボタンを押します。
先頭よりソースが順に解析され、誤りがあれば、中断して、指摘されます。それに従い、外部でソースファイルを修正し、再度「 Load 」して下さい。
実は、この「ソーステキストの入力・編集画面」上でも、修正が可能です(また修正したソースを Save ボタンで再保存も可能です)。
何の誤りも無ければ、アセンブルは成功します。
アセンブルが成功、リファレンスが出来ました
「アセンブル結果の表示画面」にリファレンス形式でアセンブル結果が表示されます。
リファレンスを保存したい場合は「 Save 」ボタンを押して、好きな名前と拡張子を付けて、保存出来ます。
( STEP 3 )
次に、実際のマシン語を得るためのダンプ・タイプで、アセンブルします。
「 ASM-Dump 」ボタンを押します。
この段階では、もうソース・エラーは無いはずですから、すんなり、アセンブルは成功し、その結果が、TANACOM-1 のシングルブロックのマシン語形式で、表示されます。
アセンブルが成功、マシン語形式の結果です
この結果は、同じく「 Save 」ボタンを押して、好きな名前と拡張子を付けて、保存出来ます。
このファイルは、TANACOM-1 およびTANACOM-1 エミュレータに、直接マシン語として、読み込ませることが出来ます。
なお、マシン語の製作途中の段階であり、すぐエミュレータに掛けたい場合は、Dump をいちいちファイルに保存すること無く、クリップボード経由で、エミュレータに渡すことも可能です。
その場合は、「 ClipCopy 」ボタンを押して下さい。
注.一番左の「画面切替」ボタンは、「ソーステキストの入力・編集画面」と「アセンブル結果の表示画面」を切り替えるトグルスイッチになっています。
なお、「アセンブル結果の表示画面」は、参照は可能ですが、編集は出来ません。
TANACOM-1 アセンブラの仕様
TANACOM-1 のソース・コードは、下記、仕様に従って構成されていなければなりません。
- 値とは
10進数( 0~65535 または -32768~ 32767 )
"0x"で始まると16進表現(桁数は1~4桁)
- セパレータとは
TAB、空白、"," 但し全角空白は文字として見るので注意して使うこと
- ラベルについて
第1文字目がセパレータ以外の文字である場合、それをラベルとする
ラベル名( 大文字小文字区別あり、文字数30byteまで )
ラベルのみの行も可能
- ORG 文の書式
書き出しアドレスの宣言(本文中、何度でも可)
ORG (又は org )、書き出しアドレスの値
なお、この ORG にはラベルは付けないられない
これが無いと書き出しの位置が未定となり、エラー
- NewPage 文
次のページの先頭へ進める。その間は、値で埋めていく。値を省略すると0で埋められる
ORG とは違い、キリを良くするため次のページ頭まで、値を埋めて行くのである
もし既にキリが良ければ何もしない
- REM文の書式
";" 以降は、行の終わりまで全て REM 文として読み跳ばす
- アドレスの相対表現
アドレスの表現について、「現在地±n」という表現を使うことが出来る
主にブランチ系で使われる
書式は、「 ( +n ) 又は ( -n ) 」 例 「 BNM ( -1 ) 」
n は0~32767である
但し、実用的な範囲は±3程度にとどめる事
- DWの書式
1 ワード長( 16bit )定数の定義
先頭から、定数名( ラベル名等他の名との重複は不可 )、DW (又はdw)、値またはラベル名
ラベル無しでも DW は使用出来る
また連続した DW の領域は、先頭にだけラベルを付ける事も可能
値に、ラベル参照が使える。これでページ越えた間接ジャンプにラベル名を使い有機的にジャンプ出来る
- DSの書式
1ワード長( 16bit )変数の定義
先頭から、変数名( ラベル名等他の名との重複は不可 )、DS ( 又はds )、確保数
確保数は、「 1 」でも省略出来ない
確保数に 2 以上を指定すれば、配列変数として扱える
- EQUの書式
読替の定義。但し 0 ~ 255 まで( すなわち 16bit データの読替は不可 )
先頭から、読替名( ラベル名等他の名との重複は不可 )、EQU (又は equ )
"~"( チルダ )をつける事で 1byte で反転した読替値を指示できる
例 beepHI EQU 0x40 ならば、 A 0,~beepHI で、 0x40 の反転すなわち 0xbf が加算される( 8bit枠内 )
- SRの特殊書式
SR 命令のオペランドには、パラメータを直接値または EQU 定義で指定するが、下記の記述も可能である
Rx
Rx.0
Rx.1
Rx.Arth
Rx.Carry
但し R0,R1 同時指示は、現在のところ不可
複雑な指定は、直接 16進2桁 で指示して下さい
- SLの特殊書式
SL 命令のオペランドには、パラメータを直値または EQU 定義で指定するが、下記の記述も可能である
Rx
Rx.0
Rx.1
R0.MSB
R1.Sin
R1.Carry
但し R0,R1 同時指示は、現在のところ不可
複雑な指定は、直接 16進2桁 で指示して下さい
- CNTの特殊書式
CNT 命令のオペランドには、繰り返したい回数の数値を指示すること
アセンブル時には、その回数になるようなパラメータで命令を構成してくれる
例 16 回ならば、「 CNT 16 」と記載する
- 使用するエディタの注意点
ソースを書く際のエディタにおいて、「改行」はWindows上での使用を前提としていますので「 CR + LF 」になります。
これが、違うと正しくアセンブルされませんので、ご注意下さい。
アセンブラ結果をエミュレータで動してみよう
先の「クロスアセンブラの使い方」で例として使われた「練習_かけ算asmソース」を、実際アセンブルして、エミュレータで動してみましょう。
<<クロスアセンブラを起動>>
それでは、手順 STEP 1 ~ 3 に従って、アセンブルして行きます。
STEP 1 ・・・ソースフォルダにある 練習_かけ算asmソース.txt を Load する。
; TANACOM-1 練習プログラム1 ; 掛け算 C = a x b ; 例 123 x 56 = 6888 (0x1AE8) になるはずです。 ; aとbを好きな数字に変えてテストして下さい ; ORG 0x0000 Top L 0,0 ; R0をゼロにする ST 0,C ; 答えが入る変数Cをクリア L 1,b ; R1にbの値を CNT 16 ; 16回ループする値をカウンタにセット Loop IA 0,a ; R1のLSBが1であれば、R0にaの値を加算 SR 0x98 ; R0.Carry,R1 右に1bitシフト B_cnt Loop ; カウンタが回りきるまでジャンプ ST 1,C ; 積を変数Cに格納 HALT ; 停止 B Top ; 再び掛け算を実施する a DW 123 b DW 56 C DS 1 ; 答えが入る変数C
STEP 2 ・・・ ASM-Ref ボタンでアセンブル
; TANACOM-1 練習プログラム1 ; 掛け算 C = a x b ; 例 123 x 56 = 6888 (0x1AE8) になるはずです。 ; aとbを好きな数字に変えてテストして下さい ; ORG 0x0000 0000 : 0000 Top L 0,0 ; R0をゼロにする 0001 : 110C ST 0,C ; 答えが入る変数Cをクリア 0002 : 090B L 1,b ; R1にbの値を 0003 : F7F1 CNT 16 ; 16回ループする値をカウンタにセット 0004 : 310A Loop IA 0,a ; R1のLSBが1であれば、R0にaの値を加算 0005 : F598 SR 0x98 ; R0.Carry,R1 右に1bitシフト 0006 : 8804 B_cnt Loop ; カウンタが回りきるまでジャンプ 0007 : 190C ST 1,C ; 積を変数Cに格納 0008 : F100 HALT ; 停止 0009 : 8000 B Top ; 再び掛け算を実施する 000A : 007B a DW 123 000B : 0038 b DW 56 000C : C DS 1 ; 答えが入る変数C Top 0000 Loop 0004 a 000A b 000B C 000C
STEP 3 ・・・ ASM-Dump ボタンでアセンブル
0000,000D 0000,110C,090B,F7F1,310A,F598,8804,190C F100,8000,007B,0038,0000
出来上がったマシン語を ClipCopy ボタンを押して、クリップボードにコピーします。
<<エミュレータを起動>>
①今作られたマシン語をクリップボードより、取り込みます
エミュレータの CUI ウィンドーにて、コマンド「a ・・・ アセンブルド・ペースト」を実行。
これで、そのマシン語がメインメモリに書き込まれます。(必要があれば、ダンプコマンドで、メモリの中身を確認する)。
② Lookポイントの設定
先ほどのアセンブル結果であるリファレンスを見てみると、かけ算の答えCは、メモリの 0x000C 番地に作られるようです。
このかけ算のマシン語実行時の 0x000C 番地の変化を観測するために、Lookポイントを設定してみましょう。
エミュレータの CUI ウィンドーにて、
l 000c
③トレースで追跡しながら、かけ算を実行する
- エミュレータ・メインウィンドのメニューバーにて、「操作-トレースする」を指示する。
- 同じくメニューバー「 CPU - CPU を Reset」を指示
リセットにて、プログラムカウンタ PC も、0x0000 になったので、かけ算のスタート位置に合致 - メニューバー「 CPU - PCの示す現アドレスから RUN」を指示
あっという間に、かけ算が実行され、その過程の状況が CUI ウィンドに表示された。
そして、Lookポイントで、観測してた 0x000C 番地( 答えC )は、ちゃんと正しく「 積 0x1AE8 」になっている。
ただし、あっという間に実行されてしまいますので、プログラムが実行されていく様をゆっくり見るには、トレースではなく、プレークポイントを使います。
④プレークポイントを設定します
まず先にトレース機能をオフにしましょう。
メニューバー「操作-トレースする」を再指示し、チェックを外す。
次に、エミュレータの CUI ウィンドーにて、
b 0000 0007
とし、プレークポイントを設定。
この指示は、「プログラムが 0x0000 から 0x0007 番地を実行した際には、現在のレジスタ状態等を表示して、毎回ブレイク( 一端停止 )しなさい」を意味します。
では、メニューバー「 CPU - CPU を Reset」で、リセットして、
メニューバー「 CPU - PCの示す現アドレスから RUN」を指示。
すると、さっそく 0x0000 番地を実行して、ブレイクして、停止します。
次にステップを進ませるには、再び、メニューバー「 CPU - PCの示す現アドレスから RUN」を使うのですが、これと同じ機能が、実は用意されています。
それは、エミュレータのメインウィンド内で、「 shiftキー + 左クリック」するのです。
これで、ブレイクした次のアドレスから、プログラムが再開されます。
「 shiftキー + 左クリック」をカチッ、カチッと繰り返すだけで、まるでシングル・ステップの様な動作をさせる事が出来ます。
これだと、変化していくレジスタや Lookポイントの状況を、ひとつひとつ確認しながらプログラム実行を観測する事が出来ます。
ただし、この「 shiftキー + 左クリック」は、ブレイクポイント設定がなされている場合しか、有効ではありません。
さあ、ソースフォルダには、練習_割り算asmソース もあります。
こちらも、かけ算同様、やって見て下さい。
加算と減算しか出来ないマシンがいかに、割り算をやるのかが、よーく解ると思います。
頑張って下さい!
ページファールに気をつけよう
先ほどの例題「かけ算ソース」において、ちっょと実験をしてみます。
プログラムの書き出しアドレスを指定する ORG 命令は、
ORG 0x0000
となっていますが、それをアドレス 0x01FD からに変更してみましょう。
ORG 0x01FD
さあ、これを ASM-Ref ボタンでアセンブルしますと、
; TANACOM-1 練習プログラム1 ; 掛け算 C = a x b ; 例 123 x 56 = 6888 (0x1AE8) になるはずです。 ; aとbを好きな数字に変えてテストして下さい ; ORG 0x01FD 01FD : 0000 Top L 0,0 ; R0をゼロにする 01FE : 1109 ((( ★ PF ★ ))) ST 0,C ; 答えが入る変数Cをクリア 01FF : 0908 ((( ★ PF ★ ))) L 1,b ; R1にbの値を 0200 : F7F1 CNT 16 ; 16回ループする値をカウンタにセット 0201 : 3107 Loop IA 0,a ; R1のLSBが1であれば、R0にaの値を加算 0202 : F598 SR 0x98 ; R0.Carry,R1 右に1bitシフト 0203 : 8901 B_cnt Loop ; カウンタが回りきるまでジャンプ 0204 : 1909 ST 1,C ; 積を変数Cに格納 0205 : F100 HALT ; 停止 0206 : 81FD ((( ★ PF ★ ))) B Top ; 再び掛け算を実施する 0207 : 007B a DW 123 0208 : 0038 b DW 56 0209 : C DS 1 ; 答えが入る変数C Top 01FD Loop 0201 a 0207 b 0208 C 0209
この様なリァレンスが出力されました。
メッセージは、「アセンブルに成功しました!」と出たはずです。
しかし、よく見ると「 ★ PF ★ 」と書かれた行が、3カ所出てきました。
これは、「この行は、ページファールを起こしています」の意味のメッセージなのです。
ページファールとは、ページを越えてアクセスしようとするエラーの事です。
TANACOM-1 では、ページアドレス方式を採用しておりますので、1ページあたり 256word で、構成されております。
よって、メモリを直接、読み書きしたり、直接ジャンプしたり出来るのは、自分のいるページの 256word だけなのです。
もし、他のページに存在するメモリを読み書きしたり、ジャンプしたりしたければ、間接アドレッシングを使わなければなりません。
当初、ORG 0x0000 の場合は、何も問題は、発生していなかったのですが、ORG 0x01FD になって、初めて越境問題に直面したのでした。
このファールを解決する方法としては、
①必要な部分で、間接アドレッシングを用いてやる ②ページをまたがないようにプログラムの配置を考え、適切な ORG にする
現実的には、この①と②の併用になります。
間接アドレッシングだと、1つの命令に 2word 分のメモリを使うし、命令実行速度も 0.6 μs 余計に掛かります。よって、グローバルな変数は別として、ローカルな変数はなるべく、間接アドレッシングにならない様に、配置を考えます。
しかし、現実のプログラムでは、数ページにわたるのは、必定です。
例えばインベーダゲームで、プログラムの大きさは 1Kword でしたので、4ページ、 FORSE システムだと、 2Kword で8ページを使用しました。
ですから、自ずと間接アドレッシングも多用しました。
TANACOM-1 の設計で反省する点の一つとして、この1ページあたり 256word という狭さです。
もし、TANACOM-2 作るのでしたら、この点は絶対に、改善したいところです( 笑 )。
でも、私も含めて当時のマイコン・ホビィスト達は、2K 程度のプログムを賢明にもハンド・アセンブルしてました(それしか方法が無かった)。
なので、このアセンブラのありがたさが、つくづく身に浸みます。
さて、例題のソースで、「★ PF ★」のところを間接アドレッシングを使って、問題を解消してみましょう。
; TANACOM-1 練習プログラム1 PFを改善した ; 掛け算 C = a x b ; 例 123 x 56 = 6888 (0x1AE8) になるはずです。 ; aとbを好きな数字に変えてテストして下さい ; ORG 0x01FB ; ※ ; WKC DW C ; ※ WKb DW b ; ※ ; Top L 0,0 ; R0をゼロにする ST 0,Id,WKC ; 答えが入る変数Cをクリア ※ L 1,Id,WKb ; R1にbの値を ※ CNT 16 ; 16回ループする値をカウンタにセット Loop IA 0,a ; R1のLSBが1であれば、R0にaの値を加算 SR 0x98 ; R0.Carry,R1 右に1bitシフト B_cnt Loop ; カウンタが回りきるまでジャンプ ST 1,C ; 積を変数Cに格納 HALT ; 停止 B Id,WKTop ; 再び掛け算を実施する ※ a DW 123 b DW 56 C DS 1 ; 答えが入る変数C WKTop DW Top ; ※
プログラム・スタートの Top のアドレスを変えないように、わざと
ORG の位置を 0x01FB に変更してみました。
注.元ソースより、「※」の行に修正を加えました。
皆さん、実験される時は、元ソースをご自分のエディタで修正されるか、この画面から、適当に
コピペしてソースとし、アセンブルしてみて下さい。
さあ、再び ASM-Ref ボタンでアセンブルしてみましょう。
この中で、トリッキーな事としまして、
「 CNT 命令」が、ちょうどページを超えた、0x0200 に配置されるはずです。
ここは、実行時、プログラムカウンタ PC が、0x01FF からインクリメントして、勝手に 0x0200 に突入してくれるので、ページを渡るためのジャンプが必要ないケースでした。
それでは、皆さん、実際にやってみて下さいね!
さて、この例題程度の大きさのマシン語であれば、「 PF 対策」も手作業で十分ですが、ある程度ソースコードが大きくなってくると、手動でやるのは、相当大変になってきます。
そこで、ロボットにお手伝いさせようと言うのが、次の「ASM-Auto 」なのです。
ASM-Auto 機能
アセンブルの際に、次の作業を自動的に行います。
- ①各ページの境には、前のページから次のページへの橋渡しのためのジャンプ( 間接を使用 )を自動挿入
- ②アセンブル中に、PF (ページファール)を発見したら、ソーステキストに対して、その部分の命令を間接インデックス方式に書き換え、合わせて間接に必要な定数定義( DW )文を挿入する。
そして変更したソーステキストを対象に、再アセンブル。これを PF が1件も出なくなるまで、繰り返す。
例えば、
(01ページ) L 0,kotae ・・・ ・・・ (02ページ) kotae DS 1
これは、01 ページの命令が、02 ページの変数を読もうとして、PF を起こしているので、ロボットが、
(01ページ) L 0,Id,#1kotae ・・・ ・・・ #1kotae DW kotae (02ページ) kotae DS 1
と、自動的に修正し、PF を回避します。
ASM-Auto が、完了すれば、「ソーステキストの入力・編集画面」には、修正後のソースが完成していますので、「Save」ボタンで、その修正後ソースを保管しましょう。
あとは、その修正後ソースを対象として、今までどおり、「 ASM-Ref 」や「 ASM-Dump 」をすることが、出来ます。
修正後ソースに於いて、ロボットが手を施した部分には、「 Robot 」とコメントが付いていますので、どこを自動修正されたかが判ります。また人間が見て不必要な部分は、手作業で取り除いて構いません。
数ページに渡るような規模のマシン語を書く場合は、最初から、この「 ASM-Auto 」に通すことを前提にし、ソースを書くと良いでしょう。すなわち、1ページ は、256 word ではなく、無限大だと思って、気にせず書けば良いのです。
さて、実際どのように使うかは、次の「デモ」をご覧下さい。
サンプルGame デモ
ソースフォルダに「サンプルGameソース」を用意しました。
このサンプルGameソースを、ASM-Auto に通し、PF の発生しないソースを生成させ、それを ASM-Dump に投入し、ゲーム・マシン語を作らせます。
さらに、エミュレータを起動し、出来上がったマシン語を走らせて、ちゃんと、ゲームが動くかを試します。
どうぞ、皆さんも、下記のデモ動画を参考に、やってみて下さい!
○ サンプルGameについて
サンプルGameは、スペース・インベーダ風のゲームです。
1978 年当時、マイコン雑誌に、インベーダゲームのプログラムが、色々なマイコンのマシン語や BASIC 言語で掲載されまして、ゲーム構造の詳しい解説も在りました( 今でもネット上で、Java や BASIC言語 のプログラムリストを見かける事がありますね )。
当 TANACOM-1 は、他マイコンの様なグラフィック解像度( 256 x 256 )はありませんが、何とかそれらしいゲームになる様に、先の「ゲーム構造の解説」を参考にして、TANACOM-1 のマシン語で書き上げました( よって、他マイコンの特定のインベーダ・ソースを移植した「移植版」ではございません )。
ソースリストには、適当にコメントを入れていますので、それを見られて、色々いじくって見て下さい( ピーム砲の数を変更するとか、ミサイルに当たっても絶対に負けないとか・・・笑)。
注1.
このサンプルGameは、オールマシン語で組まれており、これ単独で動きますので、「基本ソフトFORSE.abn」は、必要在りませんので、ご注意下さい。
注2.
エミュレータには、「 w 」コマンドを使って、あなたの PC に合った適度な WAIT を掛けて、動作させて下さい。