要32KB RAM
PasocomMini PC-8001(以降PasocomMini)で動く、FORTRANコンパイラです。
文法としてはJIS-3000相当を目指していますが、かなり簡略化された上に文法も一部変更され、PC-8001固有の拡張も行われているので、FORTRAN的なTiny言語、と考えていいと思います。
作成当時はモチロンPC-8001実機で動いていましたが、当時のソースコードから新たに書き下ろし、バグ修正もされているので、唯一動作環境できたのが上記環境になります。たぶん実機でも動くはずです。
- GitHubのReleases配下にあるfocs.cmtをPasocomMiniのmicroSDに入れて起動します
- PasocomMiniのMEDIAメニューでfocs.cmtを選択します
- N-BASICが起動したら、
clear 300,&hb3ff
を実行 mon
と入力してモニターを起動し、L
コマンドでfocs.cmtをロードします- ロードが終了したら
ctrl+b
でBASICに戻ります
ソースプログラムをBASICのエディタを使って入力します。
<行番号> ' <FORTRAN文>
'(シングルクォート)を行の先頭に入れ(BASICのコメント)、次にFORTRANの文を記載します。REMではエラーになります。
モニターから以下のように入力することでコンパイラが起動します。
mon
*GB400
コンパイルが終了すると、変数とオブジェクト領域を表示してBASICに戻ります
VAR.AD: E9FC-EA00
OBJECT: C000-C015
コンパイルされたプログラムは、C000にジャンプすることで実行が可能です。
mon
*GC000
PasocomMiniのMEDIAメニューからcmtファイルを指定もしくは新規作成し、BASICからcsave
を実行することでソースコードの保存。cload
で保存したソースコードのロードができます。
ちなみにReleasesにはサンプルプログラムsample.cmtが含まれているので、cload"SAMPLE"でロードすると参考になるかと思います。(あまり面白いものではありませんが)
実行にはランタイム(BD00-BFFF)が必要なので、オブジェクトに加えてランタイムもcmtファイルに保存する必要があります。例えばオブジェクトがC000-C015
であった場合、BD00からC015までを保存すれば単体で実行可能です。
mon
*WBD00-C015
FORTRAN文は以下のような構成となっています
{BASIC行番号} `[C] [{行番号}] {FORTRAN文}
- BASICのエディタで`(コメント)の後にFORTRAN文を書いていきます
- `の直後にスペース以外の文字を書くと、その行はコメントになります
- {行番号}は、FORTRANにおける行番号です。{BASIC行番号}はFOTRANコンパイラは一切関与しません
- {FORTRAN文}は、{制御文}と{代入文}から構成されています
- 一部例外があります。詳しくはリファレンスのmemおよびportを参照して下さい
- {制御文}はリファレンスを参照。大文字・小文字は区別されません
- プログラムの最後は必ず
end
で終了させて下さい。endなしでソースコードの最後に達するとエラーになります - {代入文は}
{変数} = {式}
で構成されます。{式}の値が{変数}に代入されます
- プログラムで扱えるのは16bitの整数(-32768〜32767)のみです
- {数値}は10進整数で入力します。数値の前に'$'をつけると、16進数になります
- {変数}は、{単変数}と{配列変数}で構成されます
- {変数}は英字で始まる英数字です。大文字・小文字は区別されません。変数名の制限はありませんが、管理領域が小さいので、短い変数名を使うことをオススメします
- 配列は一次元配列のみ扱えます
- 式には数値(16bit整数)・変数・内蔵関数・四則演算が使えます。加減算より乗除算の方が優先されます。()を使うことで優先度の変更が可能です
abs({式})
{式}の絶対値を返す。
a=abs(-10)
break
STOPキーが押されていれば、プログラムの実行を停止してBASICに戻る。押されていなければ、何もしない。
break
call {行番号}
{行番号}にジャンプする。returnを実行するとcallの次の行に戻る。
call 1
{...}
1 write("Sub-1", /)
return
color({ファンクションコード}[,{ヌルキャラクタコード}][,{グラフィックスイッチ}])
画面の色や機能を指定します。
設定 | 説明 |
---|---|
ファンクションコード | 白黒モードの時機能コード、カラーモードの時カラーを指定する |
ヌルキャラクタコード | 画面クリア時のキャラクタコード |
グラフィックスイッチ | 0の時キャラクタモード。それ以外の時はグラフィックモードを表す |
color(7,0,1)
console({スクロール開始行},{スクロール行数},{ファンクションキー表示},{カラー})
画面モードの設定を行う。
設定 | 説明 |
---|---|
スクロール開始行 | スクロールを開始する行を指定する |
スクロール行数 | スクロールする行数を指定する |
ファンクションキー表示 | 0の時ファンクションキー表示を消す。それ以外の時は表示する |
カラー | 0の時白黒モード、それ以外の時カラーモードになる |
console(0,25,0,1)
dimension {配列変数名}({配列数})
配列変数の使用を宣言する。添字は1から宣言した配列数まで。
dimension a(9)
do i=1,9
a(i)=i
continue
do {単変数}={式1}, {式2} [,{式3}]
{単変数}に{式1}の値をセットし、{式2}の値に達するまでcontinue文までの処理を繰り返す。{式3}はcontinue実行時、{単変数}に加算される。{式3}を省略すると、1が指定されたとみなす。 なお、{式3}の値が負の数である場合、{式3} < {式1}でなくてはならない。
do i=0, 10
write("i=",iI5:i, /)
continue
end
コンパイルを終了する。endがないとコンパイルでエラーになる。
end
goto {行番号}
{行番号}にジャンプする。
1 read(a:k)
if(k-$1b),9,
goto 1
if({式})[{行番号1}],[{行番号2}],[{行番号3}]
{式}の値が負の数の場合{行番号1}、0の場合{行番号2}、正の数(0を除く)の場合{行番号3}にジャンプする。行番号を省略すると、何もしない。
1 read(a:k)
IF(k-$1b),9,
goto 1
9 write("ESC key pressed.", /)
line({開始水平位置},{開始垂直位置},{終了水平位置},{終了垂直位置},{セット})
開始位置から終了位置まで線を描く。
設定 | 説明 |
---|---|
開始水平位置 | 線の開始水平位置 |
開始垂直位置 | 線の開始垂直位置 |
終了水平位置 | 線の終了水平位置 |
終了垂直位置 | 線の終了垂直位置 |
セット | 0の時、線を消去、それ以外の時、線を描画する |
line(20, 25, 50, 40, 1)
mem({式})
mem#({式})
mem({式1}) = {式2}
mem#({式1}) = {式2}
書式1:
{式}をアドレスとみなし、アドレスの示すメモリ1バイトを取得する。mem#とすると、メモリ2バイトを取得する。
書式2:
{式1}をアドレスとみなし、アドレスの示すメモリ1バイトに{式2}の値を書き込む。mem#とすると、メモリ2バイトに書き込む。
a=mem($e000)
w=mem#($e010)
mem($e000)=a
mem#($e010)=w
mod({式1},{式2})
{式1}を{式2}で割った余りを返す。
r=mod(rnd(a), 6)
pause
プログラムの実行を一時停止する。returnキーを押すと実行を再開する。
pause
point({水平位置},{垂直位置})
指定位置にドットがなければ0、そうでなければ0以外を返す。
設定 | 説明 |
---|---|
水平位置 | ドットの水平位置 |
垂直位置 | ドットの垂直位置 |
a=point(20, 25)
port({式})
port({式1}) = {式2}
書式1:
{式}をI/Oポート番号とみなし、{式}の示すポート1バイトを取得する。
書式2:
{式1}をI/Oポート番号とみなし、{式1}の示すポート1バイトに{式2}の値を書き込む。
p=port(9)
port(0)=a
preset({水平位置},{垂直位置})
指定位置のドットを消去する。
設定 | 説明 |
---|---|
水平位置 | ドットの水平位置 |
垂直位置 | ドットの垂直位置 |
preset(20, 25)
pset({水平位置},{垂直位置},{ファンクションコード})
指定位置にドットを描く。
設定 | 説明 |
---|---|
水平位置 | ドットの水平位置 |
垂直位置 | ドットの垂直位置 |
ファンクションコード | 白黒モードの時機能コード、カラーモードの時カラーを指定する |
pset(20, 25, 7)
read({FORMAT}[,{FORMAT}]...)
{FORMAT}に従って、キーボードから値を入力する。画面に数値や文字を表示することもできる。 {FORMAT}は、,で区切ることで、複数書くことが可能。
FORMAT | 説明 |
---|---|
/ | 改行します |
"{文字列}" | {文字列}を出力する |
a:{変数} | キーボードが押されていればキーの文字コードを、押されていなければ0を{変数}に代入する |
b:{変数} | キーボードから16進数を入力し、{変数}に値を代入する |
h:{式} | 出力される画面上の横位置を{式}の値にする |
i:{変数} | キーボードから10進数を入力し、{変数}に値を代入する |
v:{式} | 出力される画面上の縦位置を{式}の値にする |
x:{式} | スペースを{式}の数だけ出力する |
read("a=", i:a)
read(a:k)
return
callの呼び出し元へ戻る。
call 1
{...}
1 write("Sub-1", /)
return
rnd({式})
疑似乱数(0〜32767)を返す。{式}の値により乱数に影響を与える。
r=mod(rnd(a), 6)
sgn({式})
{式}の値が負の数の時-1、0の時0、1以上の整数の時1、を返す。
s=sgn(a)
stop
プログラムの実行を停止してBASICに戻る。
stop
usr({関数アドレス},{パラメータ})
パラメータの値をHLレジスタに入れて関数アドレスをコールする。戻り地はHLレジスタに格納すること。RET命令を実行することで呼び出し元に戻る。
設定 | 説明 |
---|---|
関数アドレス | アセンブラで書かれた関数アドレス |
パラメータ | 関数に渡されるパラメータ値 |
a=point(20, 25)
width({画面の桁数},{画面の行数})
画面の文字数を指定する。
設定 | 説明 |
---|---|
画面の桁数 | 画面の桁数を指定する |
画面の行数 | 画面の行数を指定する |
width(80, 25)
write({FORMAT}[,{FORMAT}]...)
{FORMAT}に従って、画面に数値や文字を表示する。表示位置を変更することもできる。 {FORMAT}は、,で区切ることで、複数書くことが可能。
FORMAT | 説明 |
---|---|
/ | 改行する |
"{文字列}" | {文字列}を出力する |
a:{式} | {式}で示される文字コードの文字を出力する |
b:{式} | {式}の値を16進数4桁で出力する |
b:{式} | {式}の値を16進数2桁で出力する |
d:{式} | {式}の値を16bit符号なし整数で出力する |
h:{式} | 出力される画面上の横位置を{式}の値にする |
i[{数値}]:{式} | {式}の値を{数値}の桁数の10進数で出力する。値は右詰めで{数値}に満たない部分はスペースで埋められる。{数値}を省略すると桁数指定がないものとみなす |
v:{式} | 出力される画面上の縦位置を{式}の値にする |
x:{式} | スペースを{式}の数だけ出力する |
write(h:10, V:5, "Hello, world", /)
write("a=", i5:a, /)
アドレス | 内容 |
---|---|
8021-B3FF | BASICテキストエリア |
B400-BCFF | コンパイラ本体 |
BD00-BFFF | ランタイムルーチン |
C000-E9FF | コンパイルされたオブジェクト/変数領域 |
EA00-FFFF | BASICワーク/VRAM等(一部コンパイラ使用) |
- PasocomMini PC-8001製品情報 │ パソコンミニ公式ウェブサイト
- PC-8001開発環境整備/ソフトウェア編 _ プログラミング指南 - Code Knowledge
- Z80 Assembler 'AILZ80ASM'
有益な製品・情報・ツール等を提供いただいた方々に感謝いたします。
このプログラムを使用したことによるいかなる損害も、当方は一切責任を負わないものとします。
このプログラムは、私が高校時代に卒業研究として作ったものです。ソースコードだけ残されていたので、macで入力し直し、PasocomMiniで動作確認を行いました。可能な限り当時のまま再現することが目標だったので(バグは直した)自分でもいろいろと不満はありますが、とりあえずそのまま公開します。もしバグ・コメント・要望などありましたら、当方のTwitter記事やblog記事などにてコメントいただければと思います。
なお、私のblogにこのプログラムを作った経緯などまとめてありますので、ご興味のある方はどうぞ。