3チップ構成Pic24CPMマイコン(その7)GAMEコンパイラ [Z80]
Old68funさんが6809 / 6800とFLEXのブログで書かれている「SBC8080でGAME80がようやく動作」の記事です。TK-80BS用のGAME80インタプリタをSBC8080上で動かされています。
TK-80BSと言えば中島さんにより開発されたGAME80コンパイラが発表された環境であり、Jun's Homepageの「GAME80コンパイラ解説 (2003/08/05)」に解説とともにソースが掲載されています。
久々にGAMEコンパイラを動かしてみたいものですねぇ^^
最初にGAME80をCP/M-80に移植してみました。GAMEインタプリタ自体はコンソール入出力関連の処理をハード環境に合わせて変更すれば動作するのでCP/M-80用に先頭にコールドスタートへのジャンプ命令を追加し、末尾にコンソール関連の処理を追加しました。使用した環境はマイクロソフトのMACRO80/LINK80です。
全体をリロケートしなかったのは上記のコンパイラを動かしてみたかったからです。
|
★2019/04/30 変更
連続表示中にスペースでポーズできなかったので修正
オリジナルは'!'キーで中断ですが、ESCで中断するように変更
★2019/05/01 変更
コール先やワークのアドレスをラベル名に変更
GAME80インタプリタがCP/M-80上で動いたので上記のGAME80コンパイラの解説ブログページからコンパイラのソースを頂いて動かしてみます。
ブログにも「リストは昔に記事を読んで打ち込んだもので、実行して確認していません。ミスがあるかもしれませんが、その場合はご容赦下さい。」と書かれているように実際に動かそうとすると数ヶ所修正が必要です(手元にエンサイクロペディアアスキーの該当ページのコピーがあったので突合チェックした)。
オリジナルとの差分を以下にメモしておきます。
No. | 修正箇所 |
---|---|
1 | 225 ?(5)=V .=5 ??=A .=5 ??=G / |
2 | 3270 ;=H="+" #=3300 |
3 | 3410 ;=G:0)="=" G=G+1 !=4000 H=$FA #=3600 |
4 | 5620 A:0)=$CD A=A+3 A(-1)=A A:0)=$D5 A=A+1 |
これで何十年かぶりにGAMEコンパイラのコンパイルぶりを見れる(私が当時動かしていたのはTRS-80用のGAME-Z80を自作マイコンに移植したものだったのでTK-80BSのGAMEは初体験)と思いきやコンパイルしたコードが全く動きません・・・
コンパイラのソースを確認したところ、文字列出力部で$FA52をコールしているコードを生成しています。
そこで1文字出力ルーチンを使ったループ処理のコードを生成するように変更し、機種依存性を無くしました。
オリジナル |
2410 @=(G:I-1)=""") A(0)=A+I 2420 G=G+I A=A+I A:0)=$3E 2430 A:1)=I-2 A:2)=$32 A=A+5 A(-1)=$847A 2440 A:0)=$21 A=A+3 A(-1)=Q 2445 A:0)=$22 A=A+3 A(-1)=$847B 2450 A:0)=$CD A=A+3 A(-1)=$FA52 2460 #=700 |
---|---|
変更後 |
2410 @=(G:I-1)=""") A(0)=A+I 2420 G=G+I A=A+I A:0)=$06 2430 A:1)=I-2 A:2)=$21 A=A+3 2432 A(0)=Q A(1)=$CD7E A(2)=$8C99 2433 A(3)=$0523 A=A+11 A:-3)=$C2 A(-1)=A-9 2460 #=700 |
ソースを見ると生成するコードが何となく判ると思いますが、文字列生成処理のコンパイル結果を確認してみます。
サンプルソースとしては単に"Hello"と出力するだけのものを使用しました。
|
0x4000以降にコンパイルされたコードが書かれているので、一旦GAMEを抜けてCP/Mのディバッガ(ZSID)を起動し、確認しました。
ZSIDDはZSIDに小文字シンボル対応や1行ダンプ等のパッチをあてたものです。
|
想定通りのコードが生成されていますね。当然実行結果もokでした。
当初の目的であるGAMEコンパイラをインタプリタ動作でコンパイラ自身をコンパイルし、コンパイルされたコンパイラで更にコンパイラをコンパイルすることも問題なくできました(^^)/
GAME言語のインタプリタやコンパイラのソースを公開していいか判らないのでCP/M-80に移植したバイナリだけ置いておきます。
冒頭で紹介したブログと本ブログを参照すれば、CP/M環境でGAMEコンパイラのセルフコンパイル(通常とは違う意味での「セルフ」)まで試せると思います。
-
GameOnCpm80_20231130_005d.zip
★2023/11/30 Ver 0.05d
filesコマンド(¥¥)の表示を改善
★2023/11/29 Ver 0.05c
files(¥¥)命令を追加(ワイルドカード対応)
★2023/11/29 Ver 0.05b
files(¥¥)命令を追加
★2023/11/04 Ver 0.05a
エラーの表示の改善とBIOSコール部の若干の高速化
★2023/11/02 Ver 0.05
save(¥>FileName)とload(¥<FileName)コマンドをインプリメント
★2023/11/01 Ver 0.04a
キーセンス部分の間引き処理廃止
★2023/10/30 Ver 0.04
キーセンス部分で実際のキーセンスを8回に1回コールすることで若干高速化
起動時にアーギュメントを付けてるとホットスタート起動するように変更
★2019/05/18 Ver0.03
コンパイル時の表示をGAME-Z80版のように見易くした
★2019/05/09 Ver0.02
スペースキーでのポーズ及びESCでのブレーク時にエコーバックしないようにした
★2019/05/06 Ver0.01
コンパイラを0200H~に包括した( >=$200 でコンパイラ起動)
版数特定ができるようにVer付きオープニングメッセージを表示するようにした
★2019/05/04
起動時にGAME本体を8600Hへ転送するようにして起動時間短縮
★2019/05/01
コンソール関連処理を2バイト軽量化しました(機能的には変わらず)
★2019/04/30 追記
twitterにポストした動画付きコメントを貼り付けておきます。
平成最後のカキコはGAME言語ネタです^^
— skyriver (@wcinp) April 30, 2019
GAME言語をCP/M-80に移植してGAMEコンパイラをコンパイル^^
久々に自分自身をコンパイル後の爆速ぶりを見たよ^^
Z80 16MHzなので当時は1/4程度の速度だったと思う。#GAME言語 #CPM #GAMEコンパイラhttps://t.co/cmOuhxzror pic.twitter.com/MXGxqFy5oo
★2019/05/02 追記
コメントに書いたように文字列出力処理部のコンパイルでインタプリタ内の'\0'で終端された文字列の出力処理である0x8785を呼び出すようにして生成コードを短縮し、更にキーチェックだけを行う長さゼロの文字列出力 "" に対応してみました。
GAMEコンパイラの修正箇所は下記になります。ソース自体も短くなりました。
オリジナル |
2300 A:0)=$C3 A=A+1 I=2 2400 Q=A+2 @ A:I)=G:I-1) I=I+1 2410 @=(G:I-1)=""") A(0)=A+I 2420 G=G+I A=A+I A:0)=$3E 2430 A:1)=I-2 A:2)=$32 A=A+5 A(-1)=$847A 2440 A:0)=$21 A=A+3 A(-1)=Q 2445 A:0)=$22 A=A+3 A(-1)=$847B 2450 A:0)=$CD A=A+3 A(-1)=$FA52 2460 #=700 |
---|---|
変更後 |
2300 A:0)=$C3 Q=A+1 A=A+2 2400 @ G=G+1 A=A+1 A:0)=G:0) @=(G:0)=""") 2410 G=G+1 A(0)=$2100 A(1)=Q+2 Q(0)=A+1 2420 A=A+7 A:-3)=$CD A(-1)=$8785 2460 #=700 |
それではコンパイル結果を確認してみます。
|
想定通りですね^^
GAMEコンパイラはコンパイラ自身をコンパイルし、拡張していけるのでマイコン環境でC言語等の開発環境が無かった時代にブートストラップ方式で言語仕様を拡張することでいくつかのコンパイラが作られました。独自言語が色々出てきて楽しい時代でしたね。
★2019/05/03 追記
インタープリタ ⇒ インタプリタ に変更
★2019/05/03 追記
CP/MでGAME言語が動くようになったので以前、「PIC24FJ64GAでGAME言語(その5)」で記載した迷路生成/探索のプログラムを動かしてみました。
GAME80ではPIC24FJ版GAMEとの相違点として
- &(AND)演算子が無い
- 配列のインデックス部で
計算ができない配列が参照できない※1 - 乱数 'N の範囲が0~N-1ではなく、1~Nである
- タイマ管理変数の '¥' が無い
等がありましたが容易に移植できました。
★2019/05/03 追記
※1 インデックス部で計算はできるようです。下記の事象が発生しました。
W=B:P+D(Z)) | ⇒ NG | C=D(Z) W=B:P+C) | ⇒ OK |
ソースを以下に貼りました。TeraTermのWindowサイズは80カラム×32行で動かしてください(と言ってもTeraTerm接続で動くCP/M-80環境を持っている人は希少だとは思いますが)。
|
参考にtwitterにポストした動画付きコメントを貼ります。
CP/M-80でGAME言語が動くようになったので以前PIC24版のGAME用に作った迷路プログラムを動かしてみた。若干の相違はあったけどすぐに動いたよ^^
— skyriver (@wcinp) May 3, 2019
ブログにも追記しました#GAME言語 #CPM80 #GAME80https://t.co/cmOuhxzror pic.twitter.com/XBUdIIDtBz
★2019/05/10 追記
GAME80のソースのリナンバプログラムを作ったので貼っておきます。
GAME68等でも動作すると思います。
|
★2020/12/01 追記
Ver 0.03a リナンバー後のプログラム範囲の表示を追加
★2019/05/11 追記
Ver 0.03 """処理部簡略化
Ver 0.02 行短縮しました
★2019/12/01 追記
MSX-DOSでCP/M-80のコマンドを実行できることからWebMSX環境で動作させたMSX-DOS上でGAMECを動かしてみた。
Twitterにアップしたコメントを貼っておきます。
CP/M-80に移植したGAME言語をWebMSXで動かしてみた
— skyriver (@wcinp) December 1, 2019
コンパイラも動いたけどソースをコピペができないのでソースのロード/セーブ機能を追加しないと使いづらい・・#GAME言語 #GAMEコンパイラ #MSXDOS #WebMSXhttps://t.co/7OsMhjhhbX pic.twitter.com/e3KTLJSHks
★2019/12/03 追記
上のTwitterではWebMSXでコピペができないと書いてしまいましたが、ALT+V の操作でコピペできました^^
なんとWebSMXの作者であるPaulo PeccinさんからTwitterで教えて頂きました。
★2020/01/05 追記
「MSX-DOS上でのGAME言語のベンチマーク」の記事にWebMSX上で動かしたMSX-DOSでのGAME言語(インタプリタ&コンパイラ)やBASIC等のベンチマーク計測結果を記載しました。
★2020/01/16 追記
ポケコン(PC-G850V)にGAMEコンパイラを移植しました。
「ポケコン(PC-G850V)でGAME言語(その3)GAMEコンパイラ」
twitterにポストしたメッセージも貼っておきます。
先日入手した中古ポケコン(G850V)にGAMEコンパイラを移植してみたよ
— skyriver (@wcinp) January 15, 2020
ベンチマークではGAMEインタプリタは予想に反して遅かったけどコンパイラは予想通りの速さだった^^#G850V #ポケコン #GAME言語 #GAMEコンパイラhttps://t.co/FJqKLuMn0w pic.twitter.com/TuyxscTQSD
★2020/05/03 追記
エミュレータ環境を使ってパピコン(PC-6001)にGAMEインタプリタとコンパイラを移植しました。
「パピコン(PC-6001)でGAME言語(その2)GAMEコンパイラ」
Twitterのメッセージも貼っておきます。
パピコン(PC-6001)に移植したGAME言語コンパイラの簡単なデモを作ってみた
— skyriver (@wcinp) January 29, 2020
コンパイルするだけで結構速くなる(大きなソースなら尚更)
この程度ならマシン語でも更に高速なのが簡単に作れるけどねw#PC6001 #パピコン #GAME言語 #GAMEコンパイラhttps://t.co/oJIEzSOIie pic.twitter.com/fl8G4mOVuJ
★2020/08/08 追記
GAMEコンパイラの開発者である中島さんがコンパイラのソースをgithubで公開!!
これが高校生の時に作って月間アスキーで発表した GAME(という言語)で書かれたGAMEコンパイラ。見開き2ページの下半分に全ソースコードが入る大きさ。
— Satoshi Nakajima (@snakajima) August 7, 2020
ソースコードを github に置いておきます。https://t.co/f1vlEIrOKR pic.twitter.com/9cXhgkSASX
[TOP] [ 前へ ] 連載記事 [ 次へ ]
CP/M版GAMEを修正しました。
・連続表示中にポーズできなかった問題を修正(スペースキーでポーズ)
・中断キーを’!’からESCに変更
by skyriver (2019-05-01 00:30)
コンパイラが生成するコードで文字列出力処理について1文字出力処理を使ったループ処理を生成するようにしましたがインタープリタ内の 0x8785 が'\0'で終端された文字列出力処理部でポーズや中断キーチェック機能も付いているので、ここをコールするようなコードを生成した方がいいですね。コードが短くなるし、ポーズ等のチェックも入るようになる。
8785 AF XRA A
8786 47 MOV B,A
8787 7E MOV A,M
8788 23 INX H
8789 B8 CMP B
878A CA 8793 JZ 8793H
878D CD 8C99 CALL PUTCH ;8C99H
8790 C3 8787 JMP 8787H
8793 CD 8C9C CALL KBHIT ;8C9CH
8796 D0 RNC
8797 CD 8C96 CALL GETCH ;8C96H
879A FE 1B CPI K_STOP
879C CA 8617 JZ 8617H
879F FE 20 CPI K_PAUSE
87A1 C0 RNZ
87A2 C3 8C96 JMP GETCH ;8C96H
by skyriver (2019-05-01 09:15)
文字列表示のコンパイルコードについて、長さ0の文字列表示 "" のためには最初にカウンタがゼロか確認すべきですが、 ”” はコンパイル時にエラーになります。
GAME-Z80版のGAMEコンパイラは ”” に対応していたと記憶しています。""はキーセンスのためにループ内でよく使っていたはず。
by skyriver (2019-05-01 15:52)
コメントで書いた文字列出力部のコンパイルが気になったので頭の体操として生成コードの短縮化と長さゼロの文字列に対応するようコンパイラを変更しました。
by skyriver (2019-05-02 23:35)
CP/Mで起動時にGAME本体を8600Hへ転送するようにして起動時間を高速化しました。
by skyriver (2019-05-04 08:34)
起動のたびにコンパイラをコンパイルするのは面倒なので0x0200~にコンパイラを包括しました。コマンド名もgamecに変更しました。
by skyriver (2019-05-06 11:20)
起動時のメモリマップは下記のようになっているので
1)作成したGAMEソースのコンパイル結果を$0200に上書き
この時、$0200からのコンパイラは使えません
2)下記のコマンドで起動時のジャンプ先をコンパイル結果に変更してGAMEから抜ける。
A=$011B A:0)=$02 >=0
3)下記のコマンドでセーブすると作成したGAMEソースのコンパイル結果を実行する自作のCP/Mコマンドを作成できます。
save 34 hoge.com
[起動時のメモリマップ]
0200-1b23 : compiler
1C00-22FF : interpretter
by skyriver (2019-05-06 15:33)
CP/M-80用GAME80のVer0.02でスペースキー、ESCによるポーズ、ブレーク時にエコーバックしないようにしました。
by skyriver (2019-05-10 00:01)
GAMEソースの行番号をリナンバするプログラムを追記しました。
by skyriver (2019-05-10 23:48)
懐かしいGAME言語ですね.
昔,HITACHIのLevel3やFujitsu FM-8/7/11上で動くGAMEコンパイラを開発していました.ASCIIにGAME-FMを載せたことがあります.
GAME-FMを載せたのは1984年くらいだったでしょうか.他のGAMEコンパイラと異なり最適化を最大限行うためにアセンブラで全てを記述しました.シンプルな言語ですが,ちょっとしたプログラムを高速化するには便利でしたね.
by Level3 (2019-11-10 14:22)
コメントありがとうございます。
GAME言語コンパイラをアセンブラで最適化されたのはすごいですね。
ハンドアセンブルがメインだった当時の私にとってGAME言語は非常にインパクトがありました。
更にGAME言語自身で記述されたコンパイラが公開され大変驚きました。
その後も色々な独自言語が出てきましたが私にとって一番懐かしく感じるのはGAME言語です。
by skyriver (2019-11-10 15:22)
GAME言語、懐かしいです。大学生の時にTK-80BSを持っていましたが、月刊ASCIIに次号にGAME80コンパイラが掲載されると予告された時の興奮、発刊を指折り数えて待つソワソワ、次号に載らなかった時の落胆、その次の号に掲載されたときの興奮、動いた時の感動を、40年以上経った今でもありありと思いだします。GAME80ではリロケータブルコンパイラを作成しました。生成されたオブジェクトはどこへ移しても動くものでした。また、1981年の月刊ASCIIに掲載されましたが、GAME言語用ラインエディタを開発しました。当時はエディタやOSが存在しなかったので。
by mocapapa (2020-05-03 09:45)
コメントありがとうございます。
リロケータブルなマシン語を出力するように改造したのはすごいですね。
GAME言語のエディタは使いづらいので私も自作マイコン上で1ラインのスクリーンエディタもどきの機能を付けて使ってました。
by skyriver (2020-05-03 23:15)
GAME言語は懐かしいです。僕もこの間、GAME言語のインタプリタをLinuxのCで開発しました。まだベータ版と言ったところですが、よろしければホームページをお訪ね下さい。実行ファイルとソースをGithubに上げてあります。
by T.M (2023-02-01 19:30)
CでGAME言語のインタプリタを作ったんですね。
私も以前、Cで作りポケコン(FX-890)とPIC24で動かして遊びました。
by skyriver (2023-02-01 20:56)