ＶＴＬ＿ｏｎ＿ＦＰＧＡ[その４　］ＶＴＬ＿ｏｎ＿ＦＰＧＡコンパイラ]

#効能
　VTLで書いたソースプログラムをVTL_on_FPGAで動く機械語に変換できます。

#元ネタ
　スクラッチからでは能力的にも時間がかかりそうなので、下記サイトのものを使わせてもらっています。
　　[［GAME80コンパイラ解説］](https://www.mztn.org/rvtl/game80.html)
　※許諾については記載が無いので、黙って使わせていただいておりますが、問題あれば取り下げます。
　GAME80コンパイラの作者の中島聡さんは、高校生の時にこれを作成されたとか、驚きですね。

#構成
  プログラムソースはここに上げています。
　　[［GM80］](https://github.com/hi631/VTL_on_FPGA/tree/master/game86/gm80)
　GM80のソースプログラムは、次の３つの構成を組み合わせたものです。
　コンパイラをコンパイルする場合は、３つを纏めてロードしてコンパイルします。
　※[P0 [LO gm80.gm [L0 moni.gm [L0 bios.gm [L0 gm80ovf.gm [P1 [LO gm80.gm [L1 gm80ovp.gm #=1
　1.GM80.GM
　　コンパイラ本体。
　2.BIOS.GM
　　入出力処理(PC8801のROM相当)
　3.MONI.GM
　　VTL_on_FPGAのインタープリター風の機能を提供

#コンパイラ本体(GM80)
　行番号 0001 - 8499 を占有しています。
  オンメモリのソースを読み、機械語をメモリに吐き出す。コンパイラ本体です。
  ディフォルト状態ではメモリマップは下記となります。
　　ソース　　　　　\$0000 - \$77FF
　　ワーク　　　　　\$7800 - \$7FFF
　　コンパイラ本体　\$8000 - \$BFFF
　　機械語　　　　　\$C000 - \$FFFF
　　この中には機械語のファイル出力や、逆アセンブラ機能が有ります。
　　なお、「[」で始まる拡張機能は、コメント扱いとなります。

#入出力処理(BIOS)
　行番号 9000 - 9999 を占有しています。
　GAME80が動作するパソコンにはROMが有りますが、VTL_on_FPGAには有りません。
  これはこまったと言う事で、ROMの代替機能を設けました。
　VTL_on_FPGAにはアセンブラが無いので、BIOSもVTLで書いています。
　VTLでは表せない命令は、\$xxと記載することにより、機械語に直接落ちます。
　また、VTLにはローカル変数が無いので代替機能として、変数A-Fのスタックへの退避機能を設けています。
　スタックに退避後は、A-Fをローカル変数として使用可能です。
　※例　\$EA \$EB \$EC \$ED \$EE \$EF　*　PUSH A-F

#モニタ(MONI)
　行番号 8500 - 8999 を占有しています。
　VTL_on_FPGAの電源ONでこれが起動し、「G>」のプロンプトを表示し、下記機能を有します
#1.ダイレクト入力
　　行番号無で入力すると、即コンパイルし実行されます。
　　下記では「?=1234」を入力し「1234」が表示されたことを示しています。

```
	G>?=1234			<- 入力
	-PASS1-				<- コンパイル(Pass1)
	    0 2000 ?= 1   ]=
	-PASS2-				<- コンパイル(Pass2)
	 5000 NOP: 0F
	 5001 LIA: DF 1F FF
	 5004 STS: 38
	 5005 LIB: FF 00 00 ; 0 ?=1234 ]
	 5008 PSH: E9
	 5009 LIA: DF 04 D2
	 500C POP: E1
	 500D JSR: DE 00 17
	 5010 RTS: C2
	 5011 RTS: C2
	SOURCE:12(2000-200C)		<- ソースの格納状況
	OBJECT:18(5000-5011)5000-5012	<- 機械語の格納状況
	 WORK :66(4800-4887)		<- ワークの使用状況
	Go5005
	1234				<- 実行結果
	G>
```

#2.プログラム入力と実行
　行番号付きでプログラムを入力すると内部に登録されます。
　入力時にコメント内容は無視されます。
　下記では行番号10,20,30に続けてプログラムを入力しています。
　入力の直後はプロンプトは表示されません。
　※これは、パソコン上でのコピー/ペーストによる連続入力を想定しているためです。
　空行(Enterのみ)の入力でプロンプトが再度現れます。
　「0」を入力すると、プログラムリストが表示されます。
　「#=1」を入力すると、コンパイル、実行が行われます。
　標準ではコンパイル処理がずらずらと流れていきますが、GM80の30行のP=0をP=4とする事により、表示されなくなります。

```
	G>10 A=1111　　　　　　<- プログラムの入力
	20 B=2222
	30 ?=A+B
	
	G>0　　　　　　　　　　<-　リスト表示
	10 A=1111
	20 B=2222
	30 ?=A+B
	G>#=1　　　　　　　　　<-　コンパイル開始
	(コンパイル処理省略)
	SOURCE:38(2000-2026)
	OBJECT:29(5000-501C)5000-501D
	 WORK :72(4800-4893)
	Go5005　　　　　　　　<-　実行
	3333　　　　　　　　　<-　実行結果
```

　実行時のメモリマップを下記に示す。
　　コンパイラ　　　　\$0000 - \$1EFF
　　スタック　　　　　\$1F00 - \$1FFF
　　ソース　　　　　　\$2000 - \$47FF
　　コンパイルワーク　\$4800 - \$4FFF
　　機械語格納　　　　\$5000 - \$67FF
　　VGA表示 　　　　　\$6800 - \$77FF
　※この状態ではコンパイラのVTL_on_FPGA上でのコンパイルはできない。
  　実施する場合はVGA表示を無効とし、メモリを\$77FF迄拡張する必要あり。

#3.補助命令
　(1)ロード&ゴー
  　[[(Enter)
　　ヘキサデータ読み込むと指定番地($5000)から実行する。
　　パソコン上でコンパイルすると、クリップボードにデータを作成するのでペーストする。

```
	(パソコン上での操作)
	G>>[[[
	[p0 [LO gm80\test.gm [p1 [LO gm80\gm80.gm #=1
	(コンパイル処理省略)
	Hex作成　クリップ作成
	SOURCE:71(0000-0047)
	OBJECT:76(C000-C04B)5000-504C
	 WORK :78(7800-789F)
	G>>

	(VTL_on_FPGA上での操作)
	G>[[
	L>............................................................................
	Go5005
	  1  2  3  4  5  6  7  8  9 10 1 2 3 4 5
	G>
```

　(2)メモリ読み書き
　　[M\$xxxx(Enter)
　　xxxx:xx _　(-1入力で終了)
　(3)メモリダンプ
　　[D\$5000(Enter)

```
	G>10 ?=123
	G>[M$2000
	2000:00
	2001:0A $0B
	2002:20 -1
	G>[D$2000
	2000 00 0B 20 3F 3D 31 32 33 00 FF 00 00 00 00 00 00
	2010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	G>0
	11 ?=123
```

　(4)コンパイルのみ
　　[C(Enter)
　(5)実行
　　[G\$xxxx(Enter)
　(6)プログラムセーブ
　　[S7(Enter)
　　プログラムをEPCS.ROMに書き込む。(S7のみ許可)
　　Save>Noで、書き込んだ順番が表示される。

```
	G>[S7
	*Save*
	 (Y/N) Y
	Source= $2000 - $200A  Write= $13FD - $1407
	Save.No= 3
	G>[L3(Enter)
```
　(7)プログラムロード
　　[Lnn(Enter)　　
　　EPCSに書き込んだプログラムを、Save.Noで呼び出す。
　(8)セーブプログラム実行
　　[Xnn(Enter)
　　EPCSに書き込んだプログラムを、Save.Noで呼び出し、コンパイル、実行する。
　(9)フォーマット
　　[F7(Enter)
　　EPCSの格納エリア(\$70000-\$7FFFF)を初期化する。(F7のみ許可)
## その他
　とりあえず動いているのレベルであり、状況によっては動かない可能性が有ります。
　上記記載のハード、ソフトは無保証であり、各自の責任においてご利用願います。