見出し画像

6K BASIC - 仕様解説

少し調べていたのですが、Apple][の整数BASIC(6K BASIC)に関しては、少なくとも日本語の資料がネット上にはほとんど見当たらないことがわかりました。英語のものでも、さほど無いようです。これは説明する必要もないほど、ご本家のマニュアルが良く出来ているので、それさえ読めば十分だということでもあるのですが、他のBASICとの比較もしながら、まとめておこうと思います。少々長いですがお付き合いください(noteのマークダウン表現が少々機能不足なので、あまり構造化出来ていない点はご容赦を)。

6K BASIC ガイド (ご本家マニュアル)


行とプログラム文

  • 行は行番号と式または文からなります。

  • 改行と同時に文は解釈され、BASICのコードとして中間言語に変換されてメモリに格納されます。また行番号が省略された場合には、改行と同時に実行されます。

  • 1行の長さは255文字までで、1つの行にコロン(“:”)で区切って複数の文を書くことができます。

  • 文字列リテラルは100文字以内の文字列が使えます。(改行以外の)制御文字を直接、入力することが出来ます(CHR$関数は無い)。そのためコメントなどに注意書きを残さないと表示上わからないことになります(特にDOSコマンドで使われるCTRL-D)。

  • 行番号には0〜32767の数字を使うことができます(32768以上の行番号を使おうとすると >32767 ERR)。

  • 既にある行番号を使った場合、以前の内容と置き換えられます。行番号のみで文が無い場合、その行は削除されます。同様のことはDEL [行番号]でも行えます。

  • プログラムは(HIMEM:で指定された)メモリ上限からアドレスの小さい向きに格納されます。メモリの中には行番号の小さい順にアドレスが大きい向きに格納されます。

  • 文字列および数値リテラルは、プログラムの一部として格納されます。


変数

  • 変数名は英字で始まり英字または数字が続く文字列が使えます(100文字までらしい)が、名前の一部に予約語を含むことはできません(BOTTOMはTOを含むのでダメ)。

  • 変数名の最後にドル文字(“$”)を付けると、その変数は文字列変数になります。変数Aと変数A$は別の変数です。

  • 数値としては-32767〜32767の整数が使用できます(-32768は使えません)。

  • 文字列としては0〜255文字の文字列が使用できます。

  • 変数は(LOMEM:で指定された)メモリ下限からアドレスの大きな向きに格納されます。


・四則演算は +-*/ です。除算は当然ですが整数除算です(\ はありません)。剰余は MOD です。
・大小比較演算は >(大なり) <(小なり) と >=および<=です。=>や=<は使えません。
・等値比較演算は =(等しい) #(等しくない)です。==はもちろん<>や!=ではありません。
・論理演算として AND OR NOT があります(これだけです)。
・累乗演算の ^ があります。但し結果が32767までの範囲でなければならないので、あまり使えません。
・演算子の優先度を変える時は括弧()を使います。
・演算子の優先度は以下の順で上の方が高くなります。

()
NOT -(数値のマイナス符号)
^
* / MOD
+ -
< = <= <= #
AND
OR

論理値は1が真で0が偽です。


配列と文字列

  • 配列は1次元のみです。DIM A(10)と宣言した場合、A(0)~A(10)までの11個の領域が確保されます。暗黙の配列宣言はありませんが、DIM文なしにA(0)だけは利用できます。但しA(0)とAは同じ変数として扱われます。配列の大きさはおよそ16000あたりまでのようです。

  • 文字列変数の場合、変数に入れることができる文字列の長さを指定します。DIM A$(10)とした場合、A$には10文字までの文字列を入れることが出来ます。DIM宣言をしない文字列変数には1文字しか入れられません。文字列の最大の長さは255文字です。

  • 文字列変数の配列を使うことはできません。

  • 文字列の一部を取り出すには、配列のように扱います。A$(3,5)で3文字目から5文字目までの3文字が得られます。1文字だけ取り出すときには、A$(3,3)などとします。


命令

  • AUTO [開始]{,[増分]} - 行番号を自動的に生成します。改行を押すと次の行には自動的に行番号が入力された状態になります。増分を指定しなければ改行するたびに行番号が10ずつ増えます。解除するときには、バックスペースで行番号を削除してからMANと入力します。なおRENUMはありません(AID#1 ROMで機能としては提供はされています)。

  • CALL [アドレス] - マシン語を呼び出します。10進数でアドレスを指定します。ROM内など$8000より上位のアドレスを呼び出す場合には2の補数表現で負の値を指定します。数値表現の制約からちょうど$8000を呼び出すことはできません。

  • CLR - 変数をクリアします。

  • COLOR=[色番号] - ローレゾ・グラフィックにおける色指定(0-15)をします。

  • CON - プログラムの実行を(エラーまたはCTRL-Cから)継続します。CONTではありません。またSTOPはありません。

  • DEL [行番号]{,[行番号]} - 指定された行番号(または行番号の範囲)のプログラムを削除します。

  • DIM [変数]([最大値]) - 配列を宣言します。文字列変数の場合は最大長(255まで)。1次元のみです。

  • DSP [変数1]{,[変数2]…} - デバッグ用。変数の値に変化があると行番号と変数名、値を表示します。NODSPまたは変数がクリアされると指定も無効になります。この命令は他のBASICでは見たことがありません。

  • END - プログラムを終了します。ENDを実行するとCONはできなくなります。ENDを実行せずに次の行が存在しなくなるとNO END ERRとなります。

  • FOR [変数]=[開始値] TO [終了値] {STEP [増加値]} - NEXTを実行するまで変数を変化させながら繰り返し実行します。NEXTの置かれている行の位置は関係なく、NEXTで指定された変数に対して最後に実行したFORに戻ります。STEPを省略した場合の増加値は1。

  • GOSUB [行番号] - 行番号を呼び出しRETURNでGOSUBの次から実行を続けます。RETURNで戻る必要のない時は、POPで戻り先を破棄することができます。

  • GOTO [行番号] - 行番号に実行を移します。

  • GR - 下4行にはテキストが表示されるローレゾ・グラフィックのミックスモードになります。全画面のグラフィックモードにするには、POKEでI/Oを叩きます。TEXTでテキストモードに戻ります。

  • HLIN [開始横位置],[終了横位置] AT [縦位置] - ローレゾ・グラフィックでCOLOR=で指定されている色の横線を引く。なぜかHLINEではなくてHLIN。

  • HIMEM:[アドレス] - BASICが使用するメモリ上限のアドレスを10進数で指定します。$8000より上位のアドレスを指定する場合には2の補数表現で負の値を指定します。数値表現の制約からちょうど$8000を指定することはできません。格納されていたプログラムは適切なアドレスに移動されます。

  • IF [式] THEN [行番号 または 文] - 式を評価して真であればTHEN以下を実行します。THEN以下が行番号であればGOTOが省略されたものと解釈します。THEN以下がマルチステートメントであっても式が偽の時は実行されません。ELSEはありません。

  • IN#[スロット番号] - 入力デバイスを指定します。内部的には$Cn00を呼び出して入力を指定したデバイスに接続します。指定を解除するにはIN#0とします。

  • INPUT {“文字列”,}[変数]{,[変数]…} - 文字列が指定されたら、それを表示をし、変数が数値であった場合にはさらに”?”も表示してから、キーボードからの入力を待ちます。キーボードからの入力は改行を押すまで続きます。入力された内容は変数に代入されます。複数の変数に代入する場合には、入力のカンマ(“,”)毎に区切られて対応する変数に代入します。数値を代入する場合に解釈できない文字列だった場合には、”RETYPE LINE”と表示され再度キーボードからの入力を待ちます。INPUTで入力できるのは128文字までです。GETはありません。改行を待たずにキーボードからの入力を行うにはポートを直接読み出します。

  • LET [変数]=[値] - 変数に値を代入します。LETは省略できるので、いきなり変数名で始めて構いません。

  • LOAD - カセットからプログラムを読み込みます。行番号をつけてプログラムに含めることはできません(SYNTAX ERRになります)。ファイル名を続けるとディスクからプログラムを読み込みます(この場合はDOSコマンドとして実行されます)。

  • LOMEM:[アドレス] - BASICが使用するメモリ下限のアドレスを10進数で指定します。$8000より上位のアドレスを指定する場合には2の補数表現で負の値を指定します。数値表現の制約からちょうど$8000を指定することはできません。変数はクリアされます。

  • LIST {[開始行番号]}{,[終了行番号]} - メモリに格納されているプログラムを表示する。行番号を一つだけ書けば該当する行のみ、カンマ(“,”)で区切って2つ書けば、その範囲の行(どちらの行番号も省略できない)。行番号がなければ全部を表示します。指定した行番号が存在しなくてもエラーにはなりません。表示される内容が画面の行数を超えてもスクロールされてしまいます。途中で止める機能はありません。

  • MAN - 行番号の自動入力を解除します。AUTOも参照してください。

  • NEW - プログラムを初期化します。変数もクリアされます。

  • NEXT [変数] - 最後に実行された指定された変数が使われているFORへ戻り変数を増加値だけ変化させて終了値になるまで実行を続けます。変数を省略することはできません。

  • NODSP - DSPを解除します。

  • NOTRACE - TRACEをやめます。

  • PLOT [X],[Y] - ローレゾ・グラフィックでCOLOR=で指定された色で点を描きます。

  • POKE [アドレス],[値] - 1バイトの値をメモリに書き込みます。アドレスを10進数で指定します。$8000より上位のアドレスを指定する場合には2の補数表現で負の値を指定します。数値表現の制約からちょうど$8000を指定することはできません。256以上の値を書き込もうとすると>255 ERRになります。

  • POP - GOSUBでサブルーチンを呼び出した際に、RETURNで戻る必要がない時に使います。呼び出し元の情報が破棄されます。他のBASICではPOPではなくRETURN [行番号] として呼び出し元情報を破棄します。

  • PRINT - 文字列や変数の値を出力します。文字列または変数の値を表示します。複数の文字列や変数を出力する時は、カンマ(“,”)またはセミコロン(“;”)で変数を区切ります。カンマは次のタブ位置まで空白を補いますが、セミコロンは隙間なく表示されます。最後がいずれかの記号で終わっていなければ改行されます。

  • PR#[スロット番号] - 出力デバイスを指定します。内部的には$Cn00を呼び出して出力を指定したデバイスに接続します。指定を解除するにはPR#0とします。

  • REM - プログラムに注釈(コメント)を書くことが出来ます。注釈はプログラムの実行に影響を与えません。シングルクォーテーション(“‘“)をREMの代わりに使うことはできません。

  • RETURN - GOSUBで呼び出した次の文へ戻ります。戻る必要がない場合はPOPで呼び出し元の情報を破棄します。RETURN [行番号]という形式はありません。

  • RUN {[行番号]} - 変数をクリアし指定された行番号から実行します。行番号が指定されなかった場合には、最も小さな行番号から実行をはじめます。

  • SAVE - カセットへプログラムを書き出します。行番号をつけてプログラムに含めることはできません(SYNTAX ERRになります)。ファイル名を続けるとディスクからプログラムを書き出します(この場合はDOSコマンドとして実行されます)。

  • TAB [横位置] - 次の横方向の表示位置を指定します。HTABではありません。縦位置の指定はVTABです。

  • TEXT - テキストモードにします。GRも参照してください。

  • TRACE - デバッグ用。実行している行番号が変わるたびに行番号を表示します。NOTRACEで表示をやめます。

  • VLIN [開始縦位置],[終了縦位置] AT [横位置] - ローレゾ・グラフィックでCOLOR=で指定されている色の縦線を引きます。横線はHLIN。ATが予約語なので変数名を付ける時に影響が出やすかった。

  • VTAB [横位置] - 縦方向の表示位置を指定します。TABも参照してください。


関数

  • ABS(X) - 変数の絶対値。

  • ASC(A$) - 文字列変数のアスキーコード(最初の文字)。CHR$はありません。

  • LEN(A$) - 文字列の長さ。

  • PDL(n) - n番パドルの値を読み取る(1バイト)。ボタンの値はPEEKで読みます。

  • PEEK(-16384) - 指定されたアドレスのメモリ内容(1バイト)。

  • RND(6) - 指定された値未満の疑似乱数(0≦戻り値<指定した値)。

  • SCRN(x,y) - ローレゾ・グラフィックで指定された座標の色コード。

  • SGN(X) - 符号。正(1)、負(-1)、ゼロ(0)。


よく使われるサブルーチンとI/O

  • 画面クリア - CALL -936

  • モニタに入る - CALL -151。 戻ってくる時はCTRL-Cまたは3D0G(DOSを使っている場合)。

  • スクロール範囲の指定 - POKE 32,X 左端 POKE 33,W 幅 POKE 34,Y 上端 POKE 35,Y 下端

  • 表示する文字の白黒反転 - POKE 50,255 正常 POKE 50,63 反転

  • スピーカを鳴らす - POKE -16336,0 または PEEK(-16336) 実行速度の違いから音が違う。

  • リアルタイムキーボード読み取り - PEEK(-16384)が>127でキーが押されたことが判る。押されたときのコードが返る。POKE -16368,0 でストローブをリセット。

  • ミックスドモード切り替え - POKE -16301,0 POKE -16302,0

※他にもモニタが利用しているゼロページの値を便利に使ったり、モニタに含まれる便利なサブルーチンは多数あります。


代表的なエラー

*** MEM FULL ERR
*** >255 ERR
*** >32767 ERR
*** RANGE ERR
*** DIM ERR
*** TOO LONG ERR
*** 16 FORS ERR
*** 16 GOSUBS ERR
*** BAD NEXT ERR
*** BAD RETURN ERR
*** BAD BRANCH ERR
*** SYNTAX ERR
エラー処理を扱うことが無いので、エラーコードはありません。


付録

カセットまたはディスクにプログラムを書き出す場合、プログラムは入力された時点で中間コードに翻訳されているので、翻訳されたバイナリが書き出されます。入力された文字列自身を書き出すアスキーモードはありません。このため書き出されたファイルを解析するには中間コードを知る必要があります。

Apple Integer BASIC tokenized file


最後に

独自の実装だけあって、Microsoft系のBASICと随分と違う部分もあることがおわかりいただけたかと思います。I/Oポートを叩いたり機械語ルーチンを呼べば十分な機能が省かれているのは構わないのですが、文字列変数の機能不足は厳しいものがあります。またエラー処理はありません。これはディスクを扱うときには致命的です。

6K BASICは、やはり拡張された(?)TinyBASICであって、ゲームを書くには適していますが(とはいえ斜めの線は引けませんし、ハイレゾもサポートされていません)、浮動小数点が扱えないというだけではなく、本格的なコードを書くには力不足を感じます。ただ10K BASICと比べると体感的には数倍の速度が出るので、割り切ればよく出来た実装であるとは言えます。

以上は、調べた上で書いたつもりですが、不正確な表現や誤りが含まれているかもしれません。お気づきの点があればコメントでご指摘いただければ幸いです。



この記事が気に入ったらサポートをしてみませんか?