パピコン(PC-6001)でGAME言語(その2)GAMEコンパイラ [PC-6001]
前回の「パピコン(PC-6001)でGAME言語」で書いたようにGAME80のインタプリタがパピコン上で動いたので今回は機能改善とGAMEコンパイラの移植を行いました。
★2020/01/29 追記
適切か否かは疑問がありますが、コンパイラの有効性を示す簡単なデモを作ってみました。
ソースは以下のとおりです。
[TOP] [ 前へ ] 連載記事 [ 次へ ]
- GAME80インタプリタの改善
前回の初期バージョンではバックスペースに対応していませんでしたが、左カーソルキーのコード(1DH)でカーソルが左移動することが判ったのでBSキーに対応しました。
更にコントロールXの操作で入力キャンセルにも対応しています。
起動時の画面を貼っておきます。
GAME80(PC-6001)起動画面
- GAMEコンパイラの移植
元版のGAME80インタプリタの開始アドレスは8600Hからですが、今回パピコンに移植するにあたり、インタプリタのコードを拡張ROMエリアである4100Hからにし、ワークエリアを8406Hからにリロケートしています。
このためコンパイラがコンパイル時に埋め込むインタプリタ内の処理アドレスとワークアドレスを変更する必要があります。
手作業では大変なのでGAMEコンパイラのリロケートツールを作成し一括変換しました。
リロケート時のログが下記になります。コンパイラソースの行カウント値、行番号、変更前データ、変更後データを表示しています。
GAME80コンパイラ リロケート時のログ C:\src\PC-6001\compiler>perl cnvcomp.pl <GAMECOM.GAM >GAMEC6001.GAM 7 65 : $8D06 -> $8406 15 220 : $8603 -> $4103 15 220 : $8603 -> $4103 25 380 : $8C83 -> $4783 31 440 : $8B58 -> $4658 33 460 : $8B85 -> $4685 34 470 : $8D52 -> $8452 75 2420 : $8785 -> $4285 78 2510 : $8C26 -> $4726 80 2610 : $8C32 -> $4732 81 2620 : $8C31 -> $4731 83 2710 : $8C31 -> $4731 85 2810 : $8B9C -> $469C 95 3210 : $8A03 -> $4503 96 3220 : $8A0F -> $450F 97 3230 : $8A2C -> $452C 111 3610 : $8A03 -> $4503 140 4620 : $889E -> $439E 144 4720 : $8D4E -> $844E 145 4750 : $8C96 -> $4796 148 4800 : $8A5B -> $455B 149 4810 : $8872 -> $4372 150 4820 : $8881 -> $4381 151 4830 : $8904 -> $4404 190 5740 : $8A03 -> $4503 C:\src\PC-6001\compiler>
このツールはperlを使って作っています。ソースは以下になります。
GAME80コンパイラ リロケータ(perl) #!/usr/bin/perl # convert GAME compiler to any offset # ver 0.02 2020/01/28 skyriver use strict; use warnings; my $OrgStart = 0x8600; my $OrgSrcSt = 0x8E00; my $NewStart = 0x4100; # set here new code start address my $NewSrcSt = 0x8500; # set here new source save address my $OfstCod = $NewStart - $OrgStart; my $OfstDat = $NewSrcSt - $OrgSrcSt; my $Border = $OrgSrcSt - 0x100; # code/data border adrs my $LinCnt; # line counter my $LinNo; main(); sub main { my ( $ln, $find, $change ); while( <> ) { chomp(); $LinCnt++; $ln = $_; if( $ln =~ /^(\d+)/ ) { $LinNo = $1; while ( $ln =~ /\$(8[0-9,A-F]{3})/ ) { $find = $1; $change = eval( "0x" . $find ); $change += $change < $Border ? $OfstCod : $OfstDat; $change = sprintf( "%04X", $change ); printf( STDERR "\n%5d %5s : \$%s -> \$%s", $LinCnt, $LinNo, $find, $change ); $ln =~ s/\$$find/\$_$change/; } $ln =~ s/\$_/\$/g; printf( "%s\n", $ln ); } } }
これでコンパイラはできたのですがエミュレータに入れるため、エミュレータ(PC6001V)の「打込み代行」機能を使ってインタプリタに読込ませる段階で1行が64文字程度以上ある行が文字化けでうまく読み込めなかったため、若干ソースをいじって長い行をなくしました。
コンパイラは自信をコンパイルするのに時間が掛かること、及びコンパイラのソースを開示していいか不明なことからコンパイル後のバイナリで公開する予定ですが、メモリの何処に配置するかが悩ましいところです。
※コンパイラのソースに関しては「3チップ構成Pic24CPMマイコン(その7)GAMEコンパイラ」の記事を参照すればGAMEコンパイラのソースを入手できます。
拡張メモリの5000H-5FFFH、7000H-7FFFHを使用すると実機のROM&RAMカートリッジで試すのが難しくなるというコメントをTwitterで頂いたのですが、コンパイル結果のサイズが1939H程度で4KBの枠には収まりません・・
そこで下表のように拡張ROMの最後の方にコンパイラを配置することにしました。
>=$6666でコンパイラが起動します。4桁なので縁起が悪いということもないと思いますw
No. address content 1 4000-4001 'A'+'B'(auto exec mark) 2 4002-4003 初期化処理のエントリアドレス 3 4004 exit処理 4 4006 locate処理(変数Aに位置情報 High:ライン、Low:カラム) 5 400C-40FF 初期化処理など 6 4100-47DF GAMEインタプリタ本体 7 6666-7F9E GAMEコンパイラ 8 8406-84FF GAMEインタプリタ用ワーク 9 8500 ソース保存アドレスの初期値
- ダウンロード場所
今回変更したコンパイラ付きGAMEインタプリタは「パピコン(PC-6001)でGAME言語」のページからダウンロードできます。
★2020/01/29 追記
適切か否かは疑問がありますが、コンパイラの有効性を示す簡単なデモを作ってみました。
パピコン(PC-6001)に移植したGAME言語コンパイラの簡単なデモを作ってみた
— skyriver (@wcinp) January 29, 2020
コンパイルするだけで結構速くなる(大きなソースなら尚更)
この程度ならマシン語でも更に高速なのが簡単に作れるけどねw#PC6001 #パピコン #GAME言語 #GAMEコンパイラhttps://t.co/oJIEzSOIie pic.twitter.com/fl8G4mOVuJ
ソースは以下のとおりです。
GAME80コンパイラ デモ(GAME言語) |
1' PC-6001 sample2 source 2' ver 0.01 2020/01/29 by skyriver 100 B=&+1 VRAM=$8200 X=32 Y=15 110 D=VRAM+X M=X*(Y-1)/2-1 $=12 120 I=0,X-1 130 B:I)=" " ;='3=1 B:I)='224+" " 140 @=I+1 150 @ 160 I=M @ D(I)=VRAM(I) I=I-1 @=(I<0) 170 I=0,X/2-1 VRAM(I)=B(I) @=I+1 180 I=0,'4 190 R='X-1 ;=B:R)=" " B:R)='224+" " #=210 200 B:R)=" " 210 @=I+1 220 "" 230 @=(0) |
[TOP] [ 前へ ] 連載記事 [ 次へ ]
パピコン(PC-6001)でGAME言語 [PC-6001]
「ポケコン(PC-G850V)でGAME言語」の記事ではポケコンにGAME言語を移植しましたが、今回はパピコンにTK-80BS用のGAME80インタプリタを移植してみました。
PC-6001の実機を所有していないのでGAME言語の移植は予定していなかったのですが、今ではパソコン上でエミュレータ(PC6001V)が動くようなので実機ROM無しの状態ではありますが、GAME言語のインタプリタを移植してみました。
コンソール入出力関連の処理はN60-BASICとROM内ルーチンで互換性のあるPC-6001用互換BASICの処理をコールする形で実装しました。
画面表示は1075Hの表示ルーチンを使用していますが、この処理はバックスペースでカーソルが移動しないため(実物もそうなのでしょう)、BSキーについては内部的には1文字キャンセルしていますが画面表示上はカーソルが戻らない状態です(GAMEのエディタを使って画面上でソース編集することはあまりないと思うので今後対応するかは未定)。
その代りカーソルキーでカーソルを左右に移動して1ラインのスクリーンエディタのように使えます。
★2020/01/28 変更
BSキーとコントロールXでの入力キャンセルに対応しました。
また、キー操作としてはスペースキーでポーズ(その後任意のキーで再開)、エスケープキーで中断です。
実装方法としては拡張ROMの 4000Hからのアドレスに配置したのでこのページからダウンロードしたファイルをエミュレータで拡張ROMとして設定すれば下図のようなGAME言語のインタプリタが自動起動するはずです。
Twitterにポストした動画付きコメントも貼っておきます。
上の動画で実行しているサンプルソースは以下の通りです。VRAMの内容を参照して方向を変更しています。
今回はROMカートリッジの前半(4000H-5FFFH)に入れる想定なので元版のインタプリタのコードとワークをそれぞれ異なるオフセットで移動しました。
メモリマップの概要は以下のとおりです。
★2020/01/28 追記 Ver0.02でメモリマップにコンパイラを追加
【ダウンロード】
・GameCompV002_20200128.zip
・GAME_V001_20200127.zip(旧バージョン)
【履歴】
★2020/02/01 追記
GAMEソースをリナンバ処理するGAMEのソースリストがここにあります。
【参考にさせて頂いた主なサイト】
[TOP] [ 前へ ] 連載記事 [ 次へ ]
PC-6001の実機を所有していないのでGAME言語の移植は予定していなかったのですが、今ではパソコン上でエミュレータ(PC6001V)が動くようなので実機ROM無しの状態ではありますが、GAME言語のインタプリタを移植してみました。
コンソール入出力関連の処理はN60-BASICとROM内ルーチンで互換性のあるPC-6001用互換BASICの処理をコールする形で実装しました。
画面表示は1075Hの表示ルーチンを使用していますが、この処理はバックスペースでカーソルが移動しないため(実物もそうなのでしょう)、
★2020/01/28 変更
BSキーとコントロールXでの入力キャンセルに対応しました。
また、キー操作としてはスペースキーでポーズ(その後任意のキーで再開)、エスケープキーで中断です。
実装方法としては拡張ROMの 4000Hからのアドレスに配置したのでこのページからダウンロードしたファイルをエミュレータで拡張ROMとして設定すれば下図のようなGAME言語のインタプリタが自動起動するはずです。
PC-6001でのGAMEインタプリタ起動画面 |
|
Twitterにポストした動画付きコメントも貼っておきます。
エミュレータ環境を使ってパピコン(PC-6001)にGAME言語インタプリタを移植してみた
— skyriver (@wcinp) January 27, 2020
実機のROMが無いので実機環境で動作するのかは未確認^^;;
メモリマップのVRAM方式なのでGAME言語との相性はいいかも^^#PC6001 #GAME言語 #パピコン #PC6001Vhttps://t.co/KxE6MxkINv pic.twitter.com/eWFqGiP4Pn
上の動画で実行しているサンプルソースは以下の通りです。VRAMの内容を参照して方向を変更しています。
サンプルソース(GAME言語) |
1' PC-6001 sample source 2' ver 0.01 2020/01/27 by skyriver 100 VRAM=$8200 X=32 Y=15 O="1" 110 B=0 C=0 120 M=1 N=0 $=12 130 @ 140 @ 150 D=B E=C 160 VRAM:C*X+B)=O O=O+1 ;=O>"z" O="1" 170 B=%((B+M+X)/X) 180 C=%((C+N+Y)/Y) 190 @=(VRAM:C*X+B)<>" ") 200 B=D C=E 210 ;=M<>0 N=M M=0 #=230 220 ;=N<>0 M=-N N=0 230 B=B+M C=C+N 240 @=(VRAM:C*X+B)<>" ") |
今回はROMカートリッジの前半(4000H-5FFFH)に入れる想定なので元版のインタプリタのコードとワークをそれぞれ異なるオフセットで移動しました。
メモリマップの概要は以下のとおりです。
No. | address | content |
---|---|---|
1 | 4000-4001 | 'A'+'B'(auto exec mark) |
2 | 4002-4003 | 初期化処理のエントリアドレス |
3 | 4004 | exit処理 |
4 | 4006 | locate処理(変数Aに位置情報 High:ライン、Low:カラム) |
5 | 400C-40FF | 初期化処理など |
6 | 4100-47DF | GAMEインタプリタ本体 |
7 | 6666-7F9E | GAMEコンパイラ |
8 | 8406-84FF | GAMEインタプリタ用ワーク |
9 | 8500 | ソース保存アドレスの初期値 |
★2020/01/28 追記 Ver0.02でメモリマップにコンパイラを追加
【ダウンロード】
・GameCompV002_20200128.zip
・GAME_V001_20200127.zip(旧バージョン)
【履歴】
- Ver 0.02 2020/01/28
BSキー対応、コントロールXキー対応、コンパイラ同梱、詳細はこちらを参照 - Ver 0.01 2020/01/27 初版 公開
★2020/02/01 追記
GAMEソースをリナンバ処理するGAMEのソースリストがここにあります。
【参考にさせて頂いた主なサイト】
- 秋川藤志のページ PC-6001用互換BASIC
互換BASICの内部コール処理等 - Hashi's HomePage THE B-TYPE UNION.
N6x BASIC リファレンス-付録2:メモリマップ - ぱぴこんのこころ PC6001V
PC6001Vエミュレータに関する情報 - 戦士のカートリッジmkII 技術資料
- P6つくろうブログ ROMカートリッジについて
ROMカートリッジに関する情報
[TOP] [ 前へ ] 連載記事 [ 次へ ]