パピコン(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] [ 前へ ] 連載記事 [ 次へ ]