超ミニBASIC for H8/3048 文法説明書

Copyright (C)2003 A.Hiramatsu (04/08/28)


 この文章は超ミニBASIC for H8/3048の、インタプリタの中核部分の文法について説明したものです。キャラクタ液晶モジュールに関する文・関数については「超ミニBASIC キャラクタ液晶モジュールサポート」を参照してください。

 以下の文章で、下にあるような枠で囲まれた文章は、超ミニBASICの内部構造を詳しく知りたい人向けに書いた文章です。内部構造に興味がない人は読み飛ばしても構いません。

    


 また、下にあるような枠で囲まれた文章は、旧来のBASIC(MSX−BASICやN88BASICなど)との重要な相違点を書いた文章です。旧来のBASICの熟練者がハマりやすいポイントです。

    



BASICインタプリタの基本操作

 超ミニBASIC for H8/3048はシリアルターミナル、またはパソコンのシリアルターミナルソフトから以下のようにして操作します。

プログラムの入力

 プログラムを入力するには行番号に続けて文を入力してください。入力された行の先頭に数字があればそれはプログラムの入力と見なされ、メモリに貯えられます。
 プログラムは入力した順ではなく、行番号の小さい順に並べ替えられてメモリに貯えられます。プログラムを実行する際にも、基本的には行番号の小さい行から順に実行されます。

LISTコマンドでプログラムリストを表示すると、行番号部分は右詰めで表示されます!


メモリ上には、行番号以外はすべてテキストのまま格納しています。

※バージョン1.03以降、クオーテーションで囲まれていない部分の、連続した空白は圧縮されるようになりました。
圧縮された空白のコードは以下のようになります。

空白2個

$01

空白4個

$02

空白8個

$03



コマンドの入力、および文の即時実行

 コマンドを実行したい場合、またはを即時実行したい場合(これを文のダイレクトモード実行と言います)、行番号を付けずにコマンドまたは文を入力します。コマンドの違いは以下の点です。

使用可能なコマンドの一覧はこちら文の一覧はこちらを参照してください。

プログラム書式の基本

 超ミニBASICのプログラムは複数(1行でもかまわない)のからなります。行番号本文からなります。本文は複数(1つでも構わない)の文からなります。行の長さは240文字までで、240文字を越えたぶんは切り捨てられます。また、行末の空白も切り捨てられます。タブ(文字コード$09)は1個の空白に変換されます。

 本文に複数の文を書くには、文を :(コロン)で区切って並べて書きます。これをマルチステートメントといいます。

 行番号には、1〜4294967294までの数値を書きます。行の先頭の空白を除いた最初の数字の塊が行番号とみなされます。行番号より後ろの、行末までが本文とみなされます。

 本文は、基本的には英大文字に変換されてメモリに貯えられます。ただし、"(ダブルクオート)で囲まれた文字列と、'(シングルクオート)から行末までの文字列は変換されません。

「行」の例:
  100  FOR I=0 to 9 : PRINT I,"ABC" : NEXT
行番号     文             文        文
       ←              本文              →

 キーワードパラメータからなります。キーワードは超ミニBASICインタプリタに対する命令です。上の例で言えば、FOR、PRINT、NEXT がキーワードです。パラメータは命令の対象を表わしたり、命令の細かい動作を指定したりするもので、キーワードに続けて書きます。上の例で言えば I=0 TO 9 や I,"ABC" がパラメータです。パラメータの書き方はキーワードよってそれぞれ違います。

 パラメータにはを書くことがあります。数値内蔵I/Oアドレス定数変数関数演算子からなります。

・数値

 数値は32ビット整数値です。扱える範囲は符号付きなら -2147483648〜2147483647 、符号無しなら 0〜4294967295 です。

 数値の頭に $(ドル)を付けることによって16進数も扱うことができます。その場合、$ と数字の間にはスペースを入れないでください。

 符号付き・符号無しは、数値に適用する演算子が符号付きか符号無しかによって決まります。数値自身は自分が符号付きなのかどうかを自覚していません。

 オーバーフローは検出しません。オーバーフローした場合下位32ビットのみが有効になります。たとえば、 $80000000+$80000000 は 0 です。

・内蔵I/Oアドレス定数

 H8の内蔵I/Oのアドレスを表す定数です。 定数の一覧はこちらを見てください。

例:&PADDR (ポートAデータディレクションレジスタ、値は $FFFFD1 )

・変数

 変数は、単純変数のみです。配列変数や文字列変数はありません。変数名は英字1文字で、全部で26個あります。ちょっと少ないようですが、サブルーチンではローカル変数を使うことができるので、大昔のtinyBASICよりはかなり制約は少なくなっています。

・演算子

 以下のものがあります。レベルの高いものほど優先度は高くなります。

レベル1(比較系)

= <> > < >= <= _> _< _>= _<=

レベル2(加減算系)

+ - OR XOR

レベル3(乗除算系)

* / _/ AND



 _ (アンダースコア)で始まる演算子は全て、数値を符号無しとみなします。

 比較系の演算子は、条件が成立すれば1、成立しなければ0、を結果として返します。

 旧来のBASICとはかなり優先順位が異なりますので注意してください。特に注意すべきなのは AND OR 等が比較系の演算子より優先度が高いことです。たとえば「A=0で、なおかつB=0」なんて場合、旧来のBASIC感覚で

    A=0 AND B=0

などと書くと期待した動作をしてくれません。面倒かもしれませんが 

    (A=0)AND(B=0)

と書いてください。


・関数

 <関数名>(<式>)の形をしているものを関数といいます。使用できる関数の一覧はこちらを見てください。



詳細リファレンス

コマンド

《 DELETEコマンド 》

書式:

 <開始行番号>から<終了行番号>までの行を削除します。

《 LISTコマンド 》

書式:

 プログラムのリストを画面に表示します。

 "<文字列>"を指定すると、その文字列を含む行のみ表示します。文字列の長さは半角で30文字までです。行番号部分は文字列検索の対象にはなりません。

 行範囲を指定すると、指定範囲のみ表示します。もちろん、文字列と行範囲を両方指定することも可能で、その場合指定範囲内で文字列を含む行のみを表示します。

 <行範囲>の指定の仕方には、以下の4つの書き方があります。

<行番号>

行番号が一致する1行のみ

<開始行番号>-

開始行番号からプログラムの最後まで

-<終了行番号>

プログラムの先頭から終了行番号まで

<開始行番号>-<終了行番号>

開始行番号から終了行番号まで



 LISTコマンド実行中にCTRL-Cを押すと中断することができます。またCTRL-Sを押すと一時停止する事ができます。再開はCTRL-C以外のキーです(CTRL-Cだと中断します)。

《 NEWコマンド 》

書式:

 現在のメモリ上のプログラムを消去します。

 <開始番地>と<バイト数>を指定すると、以後その範囲をBASICのテキストエリアとして使用するよう、BASICインタプリタを設定しなおします。CPUに外付けしたRAM上にBASICテキストを置きたいときに指定します。

 このコマンドは、その範囲に接続されたメモリをイネーブルにする操作などは行いません。メモリが実際にどのように接続されているか(8ビットバスか16ビットバスか、CS端子を使用しているか否か、DRAMかSRAMか、等)システムによって様々だと思われるからです。このコマンドを使用する前に、POKE文でバスコントローラやリフレッシュコントローラのレジスタを適切に設定してください。また、このコマンドは指定の範囲に本当にRAMが実装されているかどうかのチェックはしませんので注意してください。

《 RENUMコマンド 》

書式:

 行番号を付けなおします。

 <旧行番号>で始まる行番号に、<新行番号>を付け、それ以降の行は<増分>づつ行番号を増やして行きます。

 <新行番号>および<増分>は省略すると10とみなされます。

《 RUNコマンド 》

書式:

 現在メモリ上にあるプログラムを実行します。ラベルの指定がない場合はプログラムの先頭から、指定がある場合はそのラベルから実行を開始します。

 実行中のプログラムを中断したい場合はCTRL−C(文字コード $03)をシリアルターミナルから送ってください。



分岐構文

 分岐構文とは、条件に応じてプログラムの流れを変えたり、サブルーチンを呼び出したりサブルーチンから戻ったりする文です。

《 GOTO文 》

書式:

 ラベルに指定された行に飛びます。

《 GOSUB文 》

書式:

 ラベルに指定されたサブルーチンに飛びます。飛んだ先でRETURN文が実行されると、この文の次から実行されます。

GOTO文、GOSUB文ともにラベル「しか」使えません。飛び先を行番号で指定することはできません。


《 RETURN文 》

書式:


 サブルーチンを呼び出した、GOSUB文の次の文に戻ります。

《 LOCAL文 》

書式:

 サブルーチンの中でローカル変数を使えるようにします。この文自体はプログラムの流れを変えたりするわけではないのですが、GOSUB文、RETURN文と深い関係があります。

 <変数並び>には、ローカル変数にしたい変数名をコンマで区切って書きます。

 GOSUB文で呼ばれたサブルーチンの中でこの文を実行すると、指定された変数の値は保存され、RETURN文を実行したときに復帰されます。これによりサブルーチン中でうっかりメインルーチンで使っているのと同じ変数を別の目的に使ってしまい、変数の値が意図しない値に化けてしまうというバグを防ぐことができます。

LOCAL文のベタな例:
 10 A=5
 20 PRINT "MAIN:A=",A
 30 GOSUB *SUB
 40 PRINT "MAIN:A=",A
 50 END
100 *SUB:LOCAL A
110 PRINT "SUB:A=",A
120 A=1000
130 PRINT "SUB:A=",A
140 RETURN

LOCAL文の効果的な例:
 10 FOR I=0 TO 9
 20   GOSUB *SUB
 30   PRINT
 40 NEXT
 50 END
100 *SUB
110 LOCAL I
120   FOR I=0 TO 9 ' この I はメインルーチンの I とは別物
130   PRINT I,
140 NEXT
150 RETURN


《 IF文 》

書式1:(一行IF文)

※ IF と ( の間にスペースは入れられません

 <式>の値が0でなければ行末までの<文>が実行されます。当然マルチステートメントも可です。<式>の値が0ならば、<文>は無視され、次の行に行きます。

書式2:(構造化IF構文)

※ IF と ( の間にスペースは入れられません

 <式>の値が0でない場合、 }{ (ELSEと読みます)または } (ENDIFと読みます)がプログラム中に現れるまでの区間を実行します。現れたのが } ならIF構文は終了し、そのままプログラムの実行を続けます。 }{ が現れた場合、以後 } が現れるまでの区間はスキップされます。

 <式>の値が0の場合、 }{ または } がプログラム中に現れるまでの区間はスキップされます。}{ または } が現れたら以後のプログラムの実行を続けます。

※ }{ (ELSE)}{ の間にスペースは入れられません

構造化IF構文の例:
10 FOR A=1 TO 10
20   IF(A<5) {
30     PRINT A," A<5"
40   }{
50     PRINT A," A>=5"
60   }
70 NEXT


  構造化IF構文の区間の中からGOTOで飛び出さないでください。つまり、IF(<式>){GOTO *<ラベル>} のようなことはしないでください。一見問題ないように見えますが、プログラム終了時に UNEXPECTED END になります。また、ループ中などで何度もやっているうちに OUT OF WORKSPACEになります。一行IF文として IF(<式>) GOTO *<ラベル>とするのは可です。
 また、他の場所からGOTOで構造化IF構文の区間の中に飛び込まないでください。STRUCTURE NEXT ERROR になります。

 構造化IF構文はネスト(構造化IF構文の中にまた構造化IF構文を入れる)することができます。

《 ELSE文、ENDIF文 》

書式:(ELSE文)


書式:(ENDIF文)

 構造化IF構文の、実行範囲を示します。詳しくはIF文の項を参照してください。

《 END文 》


書式:

 プログラムの実行を終了し、BASICのコマンド受け付け状態に戻ります。


ループ構文

ループ構文とは、くり返しを行うための構文です。

・ループ構文全般に関する注意

 ループの中からGOTOで飛び出さないでください。一見問題ないように見えますが、プログラム終了時に UNEXPECTED END になります。また、ネストされたループ内で何度もやっているうちに OUT OF WORKSPACE になります。ループを途中で出たい場合はBREAK文を使ってください。

 また、ループの外部からGOTOで中に飛び込まないでください。 STRUCTURE NEXT ERROR になります。

 ループ構文は、ダイレクト実行した場合くり返しは行いません。

《 FOR文(FOR〜NEXT構文)

書式:

 対応するNEXT文までの区間をくり返し実行します。

 STEP <式3> を省略した場合、式3の値は1であるとみなされます。

 まず<変数>に<式1>の値が代入されます。また、<式2>(STEP節がある場合は<式3>も)の値もこの時点で評価されます。

 プログラムがNEXT文まで実行された時、<変数>に<式3>の値が加算されます。そして<変数>の値が<式2>より小さいとき(<式3>が負の場合は<変数>の値が<式2>より大きい時)、FOR文の直後に戻ります。その比較は、必ず符号付き数値とみなされるので注意してください。

 くどいようですが、<式2>および<式3>の評価は最初にFOR文を実行した時にのみ行われます。くり返し処理の中で<式2>および<式3>の値を変更しても、くり返しの回数は変化しないことに注意してください。ただし、<変数>の値を書き換えた場合はくり返しの回数は変わります。

FOR〜NEXT構文の例:
10 FOR I=0 TO 9
20   FOR J=0 TO 9
30     PRINT I*10+J,
40   NEXT
50   PRINT
60 NEXT


 FOR〜NEXT構文はネスト(FOR〜NEXT構文の中にまたFOR〜NEXT構文を入れる)することができます。ただし、<変数>の名前がダブらないよう注意してください。

 FOR〜NEXT構文の中でBREAK文が実行されると、NEXT文の次までスキップされ、それ以上のくり返しはしません

 FOR〜NEXT構文の中でCONTINUE文が実行されると、FOR文の直後まで戻ります。<変数>の値は変化しません

《 NEXT文 》

書式:

 FOR〜NEXT構文の、くり返し区間の終わりを表します。詳しくはFOR文の項を見てください。

NEXTの後に変数名を書くことはできません。


《 WHILE文(WHILE〜WEND構文)

書式:

 対応するWEND文までの区間を、<式>の値が0以外の間くり返し実行します。<式>の値はくり返しのたびに毎回評価されます。

 <式>の値が0の場合、対応するWEND文の次までスキップされ、それ以上くり返しは行いません。<式>の値が最初から0の場合、その区間は一度も実行されません。

WHILE〜WEND構文の例:
10 I=0
20 WHILE I<10
30   PRINT I
40   I=I+1
50 WEND


 WHILE〜WEND構文はネスト(WHILE〜WEND構文の中にまたWHILE〜WEND構文を入れる)することができます。

 WHILE〜WEND構文の中でBREAK文が実行されると、WEND文の次までスキップされ、それ以上のくり返しは行いません。

 WHILE〜WEND構文の中でCONTINUE文が実行されると、WHILE文まで戻ります。

《 WEND文 》

書式:

 WHILE〜WEND構文の、くり返し区間の終わりを表します。詳しくはWHILE文の項を見てください。

《 REPEAT文 》

書式:

 REPEAT〜UNTIL構文のくり返し区間の最初を表します。詳しくはUNTIL文の項を見てください。

《 UNTIL文(REPEAT〜UNTIL構文)

書式:

 <式>の値が0なら対応するREPEAT文の直後に戻ります。<式>の値が0以外なら何もせず次の文に進みます。

REPEAT〜UNTIL構文の例:
10 I=0
20 REPEAT
30   PRINT I
40   I=I+1
50 UNTIL I=10


 REPEAT〜UNTIL構文はネスト(REPEAT〜UNTIL構文の中にまたREPEAT〜UNTIL構文を入れる)することができます。

 REPEAT〜UNTIL構文の中でBREAK文が実行されると、UNTIL文の次までスキップされ、それ以上のくり返しは行いません。

 REPEAT〜UNTIL構文の中でCONTINUE文が実行されると、REPEAT文の直後まで戻ります。この場合<式>は評価されないので他にBREAK文で脱出できるようにしていないと、無限ループになるので注意してください。

《 BREAK文 》

書式:

 FOR〜NEXT構文、WHILE〜WEND構文、REPEAT〜UNTIL構文などのくり返しから脱出します。

BREAK文の例:
10 FOR I=0 TO 9
20   PRINT I
30   IF(I=5) BREAK
40   ' IF(I=5) {BREAK} ' こう書いてもよい
50 NEXT

《 CONTINUE文 》

書式:

 FOR〜NEXT構文、WHILE〜WEND構文、REPEAT〜UNTIL構文などのくり返しの先頭に戻ります。

CONTINUE文の例:
10 N=0
20 FOR I=0 TO 9
30   PRINT I
40   INPUT "-1:CONTINUE ",N
50   IF(N=-1) CONTINUE
60 NEXT


入出力文

 入出力文とは、H8/CPUのメモリや内蔵I/Oを操作する文や、シリアルターミナルに文字列や数値を表示したり、シリアルターミナルから数値を入力したりする文です。

・BCLR文、BSET文、POKE文に関する注意
 これらの文で、不用意にBASICインタプリタの作業領域や、CPUのI/O領域を操作するとCPUが暴走する恐れがあります。十分注意して使用してください。
(FRE関数の項も参考にしてください)
 また、CPU内蔵ポートのデータディレクションレジスタなど、書き込み専用レジスタはBSET文、BCLR文では正しく扱えませんので注意してください。(CPUの仕様です)

《 BCLR文 》

書式:

 <番地>が指す1バイトのメモリの、<ビット位置>で指定されるビットを0にします。<ビット位置>の範囲は0〜7です。

《 BSET文 》

書式1:

 書式2:

 書式1の場合、<番地>が指す1バイトのメモリの、<ビット位置>で指定されるビットを1にします。

 書式2の場合、<番地>が指す1バイトのメモリの、<ビット位置>に<ビット値>を代入します。<ビット値>が0ならそのビットを0に、0以外ならそのビットを1にします。

 いずれの場合も<ビット位置>の範囲は0〜7です。

《 DUMP文 》

書式:

 <開始番地>から<長さ>バイトだけメモリの内容を表示します。<長さ>は16バイト単位で切り上げられます。<長さ>を省略すると128バイトになります。

 DUMP文実行中にCTRL-Cを押すと中断することができます。またCTRL-Sを押すと一時停止する事ができます。再開はCTRL-C以外のキーです(CTRL-Cだと中断します)。

《 MEMMOVE文 》

書式:

 <転送元先頭番地>から<長さ>バイトぶんのメモリの 内容を<転送先先頭番地>以降にに転送します。転送元と転送先の領域が重なっていても正しく転送されます。

 バイト単位で転送しているので、ワード境界などは気にしなくても大丈夫です。

 BASICのテキスト領域やBASICインタプリタの作業領域を壊さないよう、注意して使ってください。

《 POKE文 》

書式:

 メインメモリの、<開始番地>が指す番地以降にデータを書き込みます。

 最初に <変数>= と書いた場合、POKE文実行後に、データを最後に書き込んだ番地+1が変数に代入されます。

 <POKE要素並び>とはメモリに書き込みたい要素を ,(コンマ)で区切って並べたものです。要素としては以下のものがあります。

  ・数式
  ・%数式
  ・#数式
  ・!%数式
  ・!#数式
  ・"(クオーテーション)で囲まれた文字列

 普通に数式を書くと1バイト単位で書き込まれますが、数式の前に %(パーセント)をつけた場合、数式の値が2バイトで、#(シャープ)をつけた場合4バイトで書き込まれます。2バイトまたは4バイトの書き込みは番地が偶数でないと ALIGN ERROR になります。
 % または # の前にさらに !(エクスクラメーション)を付けると、番地が偶数でない場合自動的に番地に1を加算し、必ず偶数番地に書きこみます。スキップされた番地には何も書きこみません。

 "(クオーテーション)で囲った文字列を書くとその文字列がそのまま書き込まれます。

POKE文の例:

POKE $FFF600,1,2,3,4,5
実行結果:FFF600 01 02 03 04 05

POKE $FFF600,%$1234,#$89ABCDEF
実行結果:FFF600 12 34 89 AB CD EF

POKE P=$FFF600,"HELLO",0
実行結果:FFF600 48 45 4C 4C 4F 00
変数 P には $FFF606 が代入される



《 INPUT文 》

書式:

 シリアルターミナルのキーボードから数値を入力し、変数に代入します。"文字列", があると、その文字列が入力前に表示されます。入力の際、頭に $(ドル)を付けることによって16進数も入力できます。

以下の点が旧来のBASICとは異なります。

    ・区切り記号はすべて ,(コンマ)。 ;(セミコロン)は使わない
    ・実行時 ?(クエスチョンマーク)は表示されない
    ・入力されたものが数値とみなすことができない場合、変数の値が変化しないだけで、特にメッセージ等は出ない。
    ・ダイレクトモードでは実行できない。 BAD MODE エラーになる。


《 PRINT文 》

書式1:

書式2:

 シリアルターミナルの画面に文字列、数値等を表示します。書式1、2のどちらも実行結果は同じです。出力要素並びとは、出力要素を ,(コンマ)で区切って並べたものです。

? はLIST表示時にも ? のままです。
区切り記号に ;(セミコロン)は使いません。



 文が , (コンマ)で終わってる場合、改行しません。

 出力要素としては以下のものがあります。

  ・数式
  ・"(クオーテーション)で囲まれた文字列
  ・PRINT文キャスト

 PRINT文キャストとは、式の値を特定の形式に変換して出力するためのもので
す。以下のようなものが用意されています。

CHR(<式>)

<式>の値をアスキーコードとする文字を出力します。

CSTR(<番地>)

<番地>が指す「C言語風文字列」(0で終わる文字列)を出力します。

HEX(<式>)

<式>の値の下位8ビットを16進2桁で出力します。

HEX%(<式>)

<式>の値を下位16ビットを16進4桁で出力します。

HEX#(<式>)

<式>の値を16進8桁で出力します。

HEX@(<番地>)

<番地>が指す1バイトのメモリの内容を16進2桁で出力します。

HEX%@(<番地>)

<番地>が指す2バイトのメモリの内容を16進4桁で出力します。

HEX#@(<番地>)

<番地>が指す4バイトのメモリの内容を16進8桁で出力します。

LSET(<式>,<桁数>)

 <式>の値を、指定された<桁数>で、左詰めで表示します。<桁数>は、符号も含めた桁数ですので、数字部分の桁数は<桁数>-1になります。たとえば、-999から999までの範囲の数値を表示したい場合、桁数には4以上の値を指定する必要があります。
 数値が指定の桁数に満たなかった場合、数字の右側に空白が補われます。数値が大きすぎて指定の桁数で表示しきれない場合、符号だけ表示して、数字部分には?が表示されます。
 桁数には2から11まで指定可能です。

RSET(<式>,<桁数>)

式の値を、指定された桁数で、右詰めで表示します。右詰めになること以外はLSETと同じですので、詳しくはLSETの項を参照してください。

SPC(<式>)

<式>の値の個数だけ空白を出力します。

USGN(<式>)

<式>の値を符号無し数値とみなして出力します。





その他の文

《 注釈文 》

書式:

 '(シングルクオート)で始まる文は注釈文となります。シングルクオートから行末までを注釈とみなし実行しません。:(コロン)も注釈とみなされるため、注釈文の後ろに他の文を書くことはできません。

REM は使えません。


《 ラベル文 》

書式:

 *(アスタリスク)に空白を入れずに続けて8文字以下の英字または数字を書くと、ラベル文になります。その行にラベルを付ける役割を果たします。ラベルはGOTO文やGOSUB文等の飛び先の目印になります。

 ラベル文は行頭、すなわち行番号の直後になければいけません(行番号とラベル文の間に空白を入れるのは可)。行頭にないラベル文は、エラーにはなりませんが、ラベルとして認識されません。ラベル文の後に他の文を書くのは問題ありません。

 同じラベルをプログラム中の複数の行に付けてもエラーにはなりませんが、認識されるのは一番行番号の小さいものだけです。GOTO/GOSUB等が思った場所に飛んでくれないときは、 LIST "*ラベル名" で、同じラベルを複数個所に付けていないかどうか確かめましょう。

 ラベルは、プログラムに書いただけでは認識されていません。また、ラベル
文のある行を実行してもまだ認識されていません。GOTO/GOSUB等を
実行してそのラベルの行へ飛んだ時点で初めて認識され、メモリ上のラベル格
納領域に格納されます。
 これは、書いてはみたものの実際には使われていないラベルのために、ラベ
ル格納領域を消費するのはもったいないと思ったからです。



《 代入文 》

書式:

 <変数名>で指定される変数に<式>の値を代入します。


関数

《 ABS関数 》

書式:

 式の値の絶対値を返します。

《 BTST関数 》

書式:

 式の値の、<ビット位置>で指定されたビットの値を返します。<ビット位置>の範囲は0〜31です。

《 BTST@関数 》

書式:

 <番地>が指す1バイトのメモリの値の、<ビット位置>で指定されたビットの値を返します。<ビット位置>の範囲は0〜7です。

 結局、BTST(PEEK(<番地>),<ビット位置>) と書くのとほぼ同じなのことなのですが、この組み合わせはH8の内蔵I/Oを操作する際に頻発するので1つの関数にまとめました。

《 CPL関数 》

書式:

 式の値の、全ビットを反転させた値を返します。

《 EXTS関数 》

書式:

 式の値の下位8ビットを符号付き数とみなして、それを32ビットの符号付き数に符号拡張した値を返します。

《 EXTS%関数 》

書式:

 式の値の下位16ビットを符号付き数とみなして、それを32ビットの符号付き数に符号拡張した値を返します。

《 FRE関数 》

書式:

 フリーエリアに関する情報を返します。フリーエリアとは、現在BASICインタプリタが使用していない領域です。
 <式>の値により、以下のように返される値が異なります。

<式の値>

返される値


フリーエリアの総バイト数
(FRE(2)−FRE(1)と同じです)


フリーエリアの先頭番地


フリーエリアの最終番地+1
(フリーエリアとしては使えない、最初の番地)


 メモリにデータを置く目的でPOKE文を使う場合、FRE(1)が指す番地からFRE(2)−1番地までの領域にデータを置けば安全です。

旧来のBASICとはかなり仕様が異なります。



《 GETC関数 》

書式:

 シリアルターミナルから1文字だけ文字を受け取り、その文字コードを返します。

 <式>には入力待ちの有無を指定します。<式>の値が1だと、シリアルターミナル側でキーが押されるまで待ちます。0だといわゆるリアルタイムキー入力となり、何かキーが押されていればその文字コードを返し、何もキーが押されていなければ0を返します。

《 NEG関数 》

書式:

 式の値の符号を反転した値を返します。

《 NOT関数 》

書式:

 式の値が0なら1を返し、0以外なら0を返します。全ビット反転ではないので注意してください。

《 PEEK関数 》

書式:

 メモリの、式が指す番地の1バイトの値を読んで返します。

《 PEEK%関数 》

書式:

 メモリの、式が指す番地の2バイトの値を読んで返します。<式>が偶数番地を指していないとエラーになります。

《 PEEK#関数 》

書式:


 メモリの、式が指す番地の4バイトの値を読んで返します。<式>が偶数番地を指していないとエラーになります。

《 REG関数 》

書式:

 USR関数を使用したあと、マシン語ルーチンが返したレジスタの値を返します。<式>の値が0〜6の場合はER0〜ER6の値を、−1ならCCRの値を返します。

《 SGN関数 》

書式:

 式の値がマイナスなら−1、0なら0、プラスなら1を返します。

《 STRLEN関数 》

書式:

 <式>が指す番地にあるC言語風文字列(0で終る文字列)の長さを調べて返します。

《 USR関数 》


書式:


 <番地>で指定されたマシン語ルーチンを呼び出します。<番地>は偶数番地でないとエラーになります。
 <パラメータ並び>に数式をコンマで区切って書くとCPUのレジスタER0〜ER6に値を渡すことができます。<パラメータ並び>には7つまで数式を書くことができます。それぞれ順にER0からER6に対応します。数式は7つ全部書く必要はなく、書いたところまでレジスタに代入されます。ただし、途中を省略することはできません。

旧来のBASICとかなり仕様が違うので注意してください!!!



 マシン語ルーチンから戻ってきた時ER0に入っていた値が返されます。また、REG関数でER0〜ER6、およびCCRの値を取り出すこともできます。

USR関数、REG関数の例:
1010 POKE $FFF600,%$0A90 ' ADD.L ER1,ER0
1020 POKE $FFF602,%$0AA0 ' ADD.L ER2,ER0
1030 POKE $FFF604,%$5470 ' RTS
1040 ?USR($FFF600,100,200,300) ' ER0=100,ER1=200,ER2=300,RETURN ER0+ER1+ER2
1050 ?HEX(REG(-1))  ' VALUE OF CCR



エラーメッセージ

ALIGN ERROR

POKE文、PEEK%関数などで奇数番地をワードアクセスしようとした

BAD LABEL

ラベル名が正しくない

BAD LINE NO.

行番号の指定が間違っている

BAD MODE

ダイレクトモードで実行できない文(現時点ではINPUT文のみ)を実行しようとした

DEVIDE BY ZERO

0で除算している

ILLEGAL FUNCTION CALL

文、関数等のパラメータの値が正しくない

LABEL NOT FOUND

ラベルが見つからない

OUT OF MEMORY

プログラム用の領域が不足している

OUT OF WORKSPACE

内部作業領域が不足している(式が複雑すぎる、サブルーチン、構造化IF構文、ループ構文などのネストが深すぎる)

STRUCURE NEST ERROR

GOSUB文とRETURN文、ループ構文、構造化IF構文の対応が正しくない

SYNTAX ERROR

文法間違い

UNEXPECTED END

予期しないプログラムの終了(ループ構文などを閉じないままプログラムが終了した)




内蔵I/Oアドレス定数

※ご注意 一応、すべてのH8/3048の内蔵I/Oレジスタのアドレスを定数として用意していますが、これらの中には不用意に操作するとCPUが暴走したり、内蔵ROMの内容が消えてしまったりするものもありますので十分注意して使用してください。
 また、シリアルコミュニケーションインターフェース(SCI)のチャネル1は、BASICインタプリタが常時アクセスしていますので、BASICプログラムでPOKE文等で直接アクセスして使用することはできません。(PRINT文、INPUT文による入出力は可)

内蔵I/O機能ブロック

定数名


レジスタの正式名称

システム

&MDCR

$FFFFF1

モードコントロールレジスタ

&SYSCR

$FFFFF2

システムコントロールレジスタ

割り込みコントローラ

&ISCR

$FFFFF4

IRQセンスコントロールレジスタ

&IER

$FFFFF5

IRQイネーブルレジスタ

&ISR

$FFFFF6

IRQステータスレジスタ

&IPRA

$FFFFF8

インタラプトプライオリティレジスタA

&IPRB

$FFFFF9

インタラプトプライオリティレジスタB

バスコントローラ

&ABWCR

$FFFFEC

バス幅コントロールレジスタ

&ASTCR

$FFFFED

アクセスステートコントロールレジスタ

&WCR

$FFFFEE

ウェイトコントロールレジスタ

&WCER

$FFFFEF

ウェイトステートコントローライネーブルレジスタ

&BRCR

$FFFFF3

バスリリースコントロールレジスタ

&CSCR

$FFFF5F

チップセレクトコントロールレジスタ

リフレッシュコントローラ

&RFSHCR

$FFFFAC

リフレッシュコントロールレジスタ

&RTMCSR

$FFFFAD

リフレッシュタイマコントロール/ステータスレジスタ

&RTCNT

$FFFFAE

リフレッシュタイマカウンタ

&RTCOR

$FFFFA

リフレッシュタイムコンスタントレジスタ

DMAコントローラ

&MAR0AR

$FFFF20

メモリアドレスレジスタ0AR

&MAR0AE

$FFFF21

メモリアドレスレジスタ0AE

&MAR0AH

$FFFF22

メモリアドレスレジスタ0AH

&MAR0AL

$FFFF23

メモリアドレスレジスタ0AL

&ETCR0AH

$FFFF24

転送カウントレジスタ0AH

&ETCR0AL

$FFFF25

転送カウントレジスタ0AL

&IOAR0A

$FFFF26

I/Oアドレスレジスタ0A

&DTCR0A

$FFFF27

データトランスファコントロールレジスタ0A

&MAR0BR

$FFFF28

メモリアドレスレジスタ0BR

&MAR0BE

$FFFF29

メモリアドレスレジスタ0BE

&MAR0BH

$FFFF2A

メモリアドレスレジスタ0BH

&MAR0BL

$FFFF2B

メモリアドレスレジスタ0BL

&ETCR0BH

$FFFF2C

転送カウントレジスタ0BH

&ETCR0BL

$FFFF2D

転送カウントレジスタ0BL

&IOAR0B

$FFFF2E

I/Oアドレスレジスタ0B

&DTCR0B

$FFFF2F

データトランスファコントロールレジスタ0B

&MAR1AR

$FFFF30

メモリアドレスレジスタ1AR

&MAR1AE

$FFFF31

メモリアドレスレジスタ1AE

&MAR1AH

$FFFF32

メモリアドレスレジスタ1AH

&MAR1AL

$FFFF33

メモリアドレスレジスタ1AL

&ETCR1AH

$FFFF34

転送カウントレジスタ1AH

&ETCR1AL

$FFFF35

転送カウントレジスタ1AL

&IOAR1A

$FFFF36

I/Oアドレスレジスタ1A

&DTCR1A

$FFFF37

データトランスファコントロールレジスタ1A

&MAR1BR

$FFFF38

メモリアドレスレジスタ1BR

&MAR1BE

$FFFF39

メモリアドレスレジスタ1BE

&MAR1BH

$FFFF3A

メモリアドレスレジスタ1BH

&MAR1BL

$FFFF3B

メモリアドレスレジスタ1BL

&ETCR1BH

$FFFF3C

転送カウントレジスタ1BH

&ETCR1BL

$FFFF3D

転送カウントレジスタ1BL

&IOAR1B

$FFFF3E

I/Oアドレスレジスタ1B

&DTCR1B

$FFFF3F

データトランスファコントロールレジスタ1B

I/Oポート

&P1DDR

$FFFFC0

ポート1データディレクションレジスタ

&P1DR

$FFFFC2

ポート1データレジスタ

&P2DDR

$FFFFC1

ポート2データディレクションレジスタ

&P2PCR

$FFFFD8

ポート2プルアップMOSコントロールレジスタ

&P2DR

$FFFFC3

ポート2データレジスタ

&P3DDR

$FFFFC4

ポート3データディレクションレジスタ

&P3DR

$FFFFC6

ポート3データレジスタ

&P4DDR

$FFFFC5

ポート4データディレクションレジスタ

&P4PCR

$FFFFDA

ポート4プルアップMOSコントロールレジスタ

&P4DR

$FFFFC7

ポート4データレジスタ

&P5DDR

$FFFFC8

ポート5データディレクションレジスタ

&P5PCR

$FFFFDB

ポート5プルアップMOSコントロールレジスタ

&P5DR

$FFFFCA

ポート5データレジスタ

&P6DDR

$FFFFC9

ポート6データディレクションレジスタ

&P6DR

$FFFFCB

ポート6データレジスタ

&P7DR

$FFFFCE

ポート7データレジスタ

&P8DDR

$FFFFCD

ポート8データディレクションレジスタ

&P8DR

$FFFFCF

ポート8データレジスタ

&P9DDR

$FFFFD0

ポート9データディレクションレジスタ

&P9DR

$FFFFD2

ポート9データレジスタ

&PADDR

$FFFFD1

ポートAデータディレクションレジスタ

&PADR

$FFFFD3

ポートAデータレジスタ

&PBDDR

$FFFFD4

ポートBデータディレクションレジスタ

&PBDR

$FFFFD6

ポートBデータレジスタ

インテグレーテッドタイマユニット
(ITU)

&TSTR

$FFFF60

タイマスタートレジスタ

&TSNC

$FFFF61

タイマシンクロレジスタ

&TMDR

$FFFF62

タイマモードレジスタ

&TFCR

$FFFF63

タイマファンクションコントロールレジスタ

&TOER

$FFFF90

タイマアウトプットマスタイネーブルレジスタ

&TOCR

$FFFF91

タイマアウトプットコントロールレジスタ

&TCNT0

$FFFF68

タイマカウンタ0

&GRA0

$FFFF6A

ジェネラルレジスタA0

&GRB0

$FFFF6C

ジェネラルレジスタB0

&TCR0

$FFFF64

タイマコントロールレジスタ0

&TIOR0

$FFFF65

タイマI/Oコントロールレジスタ0

&TSR0

$FFFF67

タイマステータスレジスタ0

&TIER0

$FFFF66

タイマインタラプトイネーブルレジスタ0

&TCNT1

$FFFF72

タイマカウンタ1

&GRA1

$FFFF74

ジェネラルレジスタA1

&GRB1

$FFFF76

ジェネラルレジスタB1

&TCR1

$FFFF6E

タイマコントロールレジスタ1

&TIOR1

$FFFF6F

タイマI/Oコントロールレジスタ1

&TSR1

$FFFF71

タイマステータスレジスタ1

&TIER1

$FFFF70

タイマインタラプトイネーブルレジスタ1

&TCNT2

$FFFF7C

タイマカウンタ2

&GRA2

$FFFF7E

ジェネラルレジスタA2

&GRB2

$FFFF80

ジェネラルレジスタB2

&TCR2

$FFFF78

タイマコントロールレジスタ2

&TIOR2

$FFFF79

タイマI/Oコントロールレジスタ2

&TSR2

$FFFF7B

タイマステータスレジスタ2

&TIER2

$FFFF7A

タイマインタラプトイネーブルレジスタ2

&TCNT3

$FFFF86

タイマカウンタ3

&GRA3

$FFFF88

ジェネラルレジスタA3

&GRB3

$FFFF8A

ジェネラルレジスタB3

&BRA3

$FFFF8C

バッファレジスタA3

&BRB3

$FFFF8E

バッファレジスタB3

&TCR3

$FFFF82

タイマコントロールレジスタ3

&TIOR3

$FFFF83

タイマI/Oコントロールレジスタ3

&TSR3

$FFFF85

タイマステータスレジスタ3

&TIER3

$FFFF84

タイマインタラプトイネーブルレジスタ3

&TCNT4

$FFFF96

タイマカウンタ4

&GRA4

$FFFF98

ジェネラルレジスタA4

&GRB4

$FFFF9A

ジェネラルレジスタB4

&BRA4

$FFFF9C

バッファレジスタA4

&BRB4

$FFFF9E

バッファレジスタB4

&TCR4

$FFFF92

タイマコントロールレジスタ4

&TIOR4

$FFFF93

タイマI/Oコントロールレジスタ4

&TSR4

$FFFF95

タイマステータスレジスタ4

&TIER4

$FFFF94

タイマインタラプトイネーブルレジスタ4

タイミングパターンコントローラ
(TPC)

&NDRA

$FFFFA5

ネクストデータレジスタA

&NDRB

$FFFFA4

ネクストデータレジスタB

&NDERA

$FFFFA3

ネクストデータイネーブルレジスタA

&NDERB

$FFFFA2

ネクストデータイネーブルレジスタB

&TPCR

$FFFFA1

TPC出力コントロールレジスタ

&TPMR

$FFFFA0

TPC出力モードレジスタ

ウオッチドッグタイマ

&TCSR

$FFFFA8

タイマコントロール/ステータスレジスタ

&TCNT

$FFFFA9

タイマカウンタ

&RSTCSR

$FFFFAA

リセットコントロール/ステータスレジスタ

シリアルコミュニケーションインターフェース
(SCI)

&RDR0

$FFFFB5

レシーブデータレジスタ0

&TDR0

$FFFFB3

トランスミットデータレジスタ0

&SMR0

$FFFFB0

シリアルモードレジスタ0

&SCR0

$FFFFB2

シリアルコントロールレジスタ0

&SSR0

$FFFFB4

シリアルステータスレジスタ0

&BRR0

$FFFFB1

ビットレートレジスタ0

&RDR1

$FFFFBD

レシーブデータレジスタ1

&TDR1

$FFFFBB

トランスミットデータレジスタ1

&SMR1

$FFFFB8

シリアルモードレジスタ1

&SCR1

$FFFFBA

シリアルコントロールレジスタ1

&SSR1

$FFFFBC

シリアルステータスレジスタ1

&BRR1

$FFFFB9

ビットレートレジスタ1

スマートカードインターフェース

&SCMR

$FFFFB6

スマートカードモードレジスタ

A/D変換器

&ADDRAH

$FFFFE0

A/DデータレジスタAH

&ADDRAL

$FFFFE1

A/DデータレジスタAL

&ADDRBH

$FFFFE2

A/DデータレジスタBH

&ADDRBL

$FFFFE3

A/DデータレジスタBL

&ADDRCH

$FFFFE4

A/DデータレジスタCH

&ADDRCL

$FFFFE5

A/DデータレジスタCL

&ADDRDH

$FFFFE6

A/DデータレジスタDH

&ADDRDL

$FFFFE7

A/DデータレジスタDL

&ADCSR

$FFFFE8

A/Dコントロール/ステータスレジスタ

&ADCR

$FFFFE9

A/Dコントロールレジスタ

D/A変換器

&DADR0

$FFFFDC

D/Aデータレジスタ0

&DADR1

$FFFFDD

D/Aデータレジスタ1

&DACR

$FFFFDE

D/Aコントロールレジスタ

&DASTCR

$FFFF5C

D/Aスタンバイコントロールレジスタ

内蔵フラッシュROM

&FLMCR

$FFFF40

フラッシュメモリコントロールレジスタ

&EBR1

$FFFF42

消去ブロック指定レジスタ1

&EBR2

$FFFF43

消去ブロック指定レジスタ2

&RAMCR

$FFFF48

RAMコントロールレジスタ

クロック発振器

&DIVCR

$FFFF5D

分周比コントロールレジスタ

省電力

&MSTCR

$FFFF5E

モジュールスタンバイコントロールレジスタ