Skip to content

yasuho68k/focs_pc-8001

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FOCS (FOrtran Compiler System) for PC-8001

要32KB RAM

概要

PasocomMini PC-8001(以降PasocomMini)で動く、FORTRANコンパイラです。

文法としてはJIS-3000相当を目指していますが、かなり簡略化された上に文法も一部変更され、PC-8001固有の拡張も行われているので、FORTRAN的なTiny言語、と考えていいと思います。

動作環境

PasocomMini PC-8001

作成当時はモチロン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

プログラムのsave/load

PasocomMiniのMEDIAメニューからcmtファイルを指定もしくは新規作成し、BASICからcsaveを実行することでソースコードの保存。cloadで保存したソースコードのロードができます。

ちなみにReleasesにはサンプルプログラムsample.cmtが含まれているので、cload"SAMPLE"でロードすると参考になるかと思います。(あまり面白いものではありませんが)

実行にはランタイム(BD00-BFFF)が必要なので、オブジェクトに加えてランタイムもcmtファイルに保存する必要があります。例えばオブジェクトがC000-C015であった場合、BD00からC015までを保存すれば単体で実行可能です。

mon
*WBD00-C015

FORTRAN文法

基本構成

FORTRAN文は以下のような構成となっています

{BASIC行番号} `[C] [{行番号}] {FORTRAN文}

  • BASICのエディタで`(コメント)の後にFORTRAN文を書いていきます
  • `の直後にスペース以外の文字を書くと、その行はコメントになります
  • {行番号}は、FORTRANにおける行番号です。{BASIC行番号}はFOTRANコンパイラは一切関与しません
  • {FORTRAN文}は、{制御文}と{代入文}から構成されています
    • 一部例外があります。詳しくはリファレンスのmemおよびportを参照して下さい
  • {制御文}はリファレンスを参照。大文字・小文字は区別されません
  • プログラムの最後は必ずendで終了させて下さい。endなしでソースコードの最後に達するとエラーになります
  • {代入文は}{変数} = {式}で構成されます。{式}の値が{変数}に代入されます

数値・変数・式

  • プログラムで扱えるのは16bitの整数(-32768〜32767)のみです
  • {数値}は10進整数で入力します。数値の前に'$'をつけると、16進数になります
  • {変数}は、{単変数}と{配列変数}で構成されます
  • {変数}は英字で始まる英数字です。大文字・小文字は区別されません。変数名の制限はありませんが、管理領域が小さいので、短い変数名を使うことをオススメします
  • 配列は一次元配列のみ扱えます
  • 式には数値(16bit整数)・変数・内蔵関数・四則演算が使えます。加減算より乗除算の方が優先されます。()を使うことで優先度の変更が可能です

リファレンス

abs関数

書式

abs({式})

説明

{式}の絶対値を返す。

    a=abs(-10)

break文

書式

break

説明

STOPキーが押されていれば、プログラムの実行を停止してBASICに戻る。押されていなければ、何もしない。

    break

call文

書式

call {行番号}

説明

{行番号}にジャンプする。returnを実行するとcallの次の行に戻る。

    call 1
    {...}
  1 write("Sub-1", /)
    return

color文

書式

color({ファンクションコード}[,{ヌルキャラクタコード}][,{グラフィックスイッチ}])

説明

画面の色や機能を指定します。

設定 説明
ファンクションコード 白黒モードの時機能コード、カラーモードの時カラーを指定する
ヌルキャラクタコード 画面クリア時のキャラクタコード
グラフィックスイッチ 0の時キャラクタモード。それ以外の時はグラフィックモードを表す

  color(7,0,1)

console文

書式

console({スクロール開始行},{スクロール行数},{ファンクションキー表示},{カラー})

説明

画面モードの設定を行う。

設定 説明
スクロール開始行 スクロールを開始する行を指定する
スクロール行数 スクロールする行数を指定する
ファンクションキー表示 0の時ファンクションキー表示を消す。それ以外の時は表示する
カラー 0の時白黒モード、それ以外の時カラーモードになる

  console(0,25,0,1)

dimension文

書式

dimension {配列変数名}({配列数})

説明

配列変数の使用を宣言する。添字は1から宣言した配列数まで。

    dimension a(9)
    do i=1,9
      a(i)=i
    continue

do文

書式

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がないとコンパイルでエラーになる。

    end

goto文

書式

goto {行番号}

説明

{行番号}にジャンプする。

  1 read(a:k)
    if(k-$1b),9,
    goto 1

if文

書式

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文

書式

line({開始水平位置},{開始垂直位置},{終了水平位置},{終了垂直位置},{セット})

説明

開始位置から終了位置まで線を描く。

設定 説明
開始水平位置 線の開始水平位置
開始垂直位置 線の開始垂直位置
終了水平位置 線の終了水平位置
終了垂直位置 線の終了垂直位置
セット 0の時、線を消去、それ以外の時、線を描画する

  line(20, 25, 50, 40, 1)

mem関数・文

書式1

mem({式})
mem#({式})

書式2

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関数

書式

mod({式1},{式2})

説明

{式1}を{式2}で割った余りを返す。

    r=mod(rnd(a), 6)

pause文

書式

pause

説明

プログラムの実行を一時停止する。returnキーを押すと実行を再開する。

    pause

point関数

書式

point({水平位置},{垂直位置})

説明

指定位置にドットがなければ0、そうでなければ0以外を返す。

設定 説明
水平位置 ドットの水平位置
垂直位置 ドットの垂直位置

  a=point(20, 25)

port関数・文

書式1

port({式})

書式2

port({式1}) = {式2}

説明

書式1:
{式}をI/Oポート番号とみなし、{式}の示すポート1バイトを取得する。

書式2:
{式1}をI/Oポート番号とみなし、{式1}の示すポート1バイトに{式2}の値を書き込む。

    p=port(9)
    port(0)=a

preset文

書式

preset({水平位置},{垂直位置})

説明

指定位置のドットを消去する。

設定 説明
水平位置 ドットの水平位置
垂直位置 ドットの垂直位置

  preset(20, 25)

pset文

書式

pset({水平位置},{垂直位置},{ファンクションコード})

説明

指定位置にドットを描く。

設定 説明
水平位置 ドットの水平位置
垂直位置 ドットの垂直位置
ファンクションコード 白黒モードの時機能コード、カラーモードの時カラーを指定する

  pset(20, 25, 7)

read文

書式

read({FORMAT}[,{FORMAT}]...)

説明

{FORMAT}に従って、キーボードから値を入力する。画面に数値や文字を表示することもできる。 {FORMAT}は、,で区切ることで、複数書くことが可能。

FORMAT

FORMAT 説明
/ 改行します
"{文字列}" {文字列}を出力する
a:{変数} キーボードが押されていればキーの文字コードを、押されていなければ0を{変数}に代入する
b:{変数} キーボードから16進数を入力し、{変数}に値を代入する
h:{式} 出力される画面上の横位置を{式}の値にする
i:{変数} キーボードから10進数を入力し、{変数}に値を代入する
v:{式} 出力される画面上の縦位置を{式}の値にする
x:{式} スペースを{式}の数だけ出力する

  read("a=", i:a)
  read(a:k)

return文

書式

return

説明

callの呼び出し元へ戻る。

    call 1
    {...}
  1 write("Sub-1", /)
    return

rnd関数

書式

rnd({式})

説明

疑似乱数(0〜32767)を返す。{式}の値により乱数に影響を与える。

    r=mod(rnd(a), 6)

sgn関数

書式

sgn({式})

説明

{式}の値が負の数の時-1、0の時0、1以上の整数の時1、を返す。

    s=sgn(a)

stop文

書式

stop

説明

プログラムの実行を停止してBASICに戻る。

    stop

usr関数

書式

usr({関数アドレス},{パラメータ})

説明

パラメータの値をHLレジスタに入れて関数アドレスをコールする。戻り地はHLレジスタに格納すること。RET命令を実行することで呼び出し元に戻る。

設定 説明
関数アドレス アセンブラで書かれた関数アドレス
パラメータ 関数に渡されるパラメータ値

  a=point(20, 25)

width文

書式

width({画面の桁数},{画面の行数})

説明

画面の文字数を指定する。

設定 説明
画面の桁数 画面の桁数を指定する
画面の行数 画面の行数を指定する

  width(80, 25)

write文

書式

write({FORMAT}[,{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等(一部コンパイラ使用)

謝辞

有益な製品・情報・ツール等を提供いただいた方々に感謝いたします。

免責

このプログラムを使用したことによるいかなる損害も、当方は一切責任を負わないものとします。

おわりに

このプログラムは、私が高校時代に卒業研究として作ったものです。ソースコードだけ残されていたので、macで入力し直し、PasocomMiniで動作確認を行いました。可能な限り当時のまま再現することが目標だったので(バグは直した)自分でもいろいろと不満はありますが、とりあえずそのまま公開します。もしバグ・コメント・要望などありましたら、当方のTwitter記事blog記事などにてコメントいただければと思います。

なお、私のblogにこのプログラムを作った経緯などまとめてありますので、ご興味のある方はどうぞ。

About

FOCS (FOrtran Compiler System) for PC-8001

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published