ベーシックマスターのソフトウェア(8)BASICプログラム領域の謎を解く
以下、ベーシックマスターのハードウェア(2)グラフィック画面のアドレスの続きなのだが、ソフトウェアの話になる。
先の記事では、グラフィック画面の開始アドレスやBASICプログラムの格納開始アドレスが、資料によっては$0A00と書かれていると書いた。実装では$0900なので、誤った情報が書かれているわけだ。
別件で資料を調べていたら、bit臨時増刊「パーソナル・コンピュータの使い方」でも、BASIC領域は$0A00-$7FFFと書かれていた。
bit増刊記事はベーシックマスターレベル2を対象としている。1980年1月出版なので、記事が書かれたのはMB-6881L2IIが出る直前だと思われる。
bit臨時増刊「パーソナル・コンピュータの使い方」 p.244 より引用
L2 BASICのSIZEコマンド
bit増刊の記事ではフリーエリアが30208バイト(32KB実装時)と書かれていたので、実機のSIZEコマンドで確認してみた。$A00と$900の違いでサイズは変わるはずだし。
PROGRAM=$0A00になっていて、REMAIN=42495 ($AFFF-$0A00)である。POKE 8,$7Fとして32KBに偽装するとREMAIN=30207である。1バイト違うけど、ほぼ記事通り。
ここでも$0A00なのか! (なんで今まで気がつかなかったんだ、俺?)

マニュアルにも$0A00開始と書かれている。以下の記述はL2IIのマニュアルからの引用だが、Jr.でも同じである。
「ベーシックマスターレベル2II 取扱説明書」p.40 より引用
SIZEコマンドのPROGRAMで表示される値よりも前の部分(上図のプログラムエリア)には、ダイレクトコマンドのワークも含まれる。
以下、L2IIマニュアルより引用(Jr.のマニュアルではp.135)。
「ベーシックマスターレベル2II 取扱説明書」p.117 より引用
SIZEコマンドの内部
L2II/Jr.のL2 BASICのソースを見ると以下のようになっている。L2用でもロジックは一緒である。
BASICの格納アドレスの末尾(basic_tail)に$FBを足した結果をPROGRAMとして表示している。
VARIABLEは変数領域の先頭で、電源ON/NEWの直後はメモリ末尾を指している。
REMAIN(残りメモリ領域)を計算するときは、calc_REMAIN($BC6B)を実行している。これは確保済みの変数領域の先頭アドレスからBASICプログラム末尾のアドレスを引いて、さらに$00FBを引いた結果を返すルーチンである。
このルーチン(calc_REMAIN)は変数領域を確保する時にも使われていて、結果が負であれば MEMORY FULL ERROR になる。
SIZE JSR ZBD63 ;BC45: BD BD 63 '..c' LDX #mPROGRAM ;BC48: CE BC 7C '..|' BSR ZBC20 ;BC4B: 8D D3 '..' LDX basic_tail ;BC4D: DE 78 '.x' LDAB #$FB ;BC4F: C6 FB '..' JSR ADDIXB ;BC51: BD F0 03 '...' BSR ZBCA1 ;BC54: 8D 4B '.K' LDX #mVARIABLE ;BC56: CE BC 89 '...' BSR ZBC20 ;BC59: 8D C5 '..' LDX variable_area_top ;BC5B: DE 7A '.z' BSR ZBCA1 ;BC5D: 8D 42 '.B' LDX #mREMAIN ;BC5F: CE BC 96 '...' BSR ZBC20 ;BC62: 8D BC '..' BSR calc_REMAIN ;BC64: 8D 05 '..' BSR outAccAB_dec ;BC66: 8D 9F '..' ZBC68 JMP ZB04B ;BC68: 7E B0 4B '~.K' calc_REMAIN LDAA variable_area_top ;BC6B: 96 7A '.z' LDAB M007B ;BC6D: D6 7B '.{' SUBB #$FB ;BC6F: C0 FB '..' SBCA #$00 ;BC71: 82 00 '..' SUBB M0079 ;BC73: D0 79 '.y' SBCA basic_tail ;BC75: 92 78 '.x' BCC ZBC7B ;BC77: 24 02 '$.' CLRA ;BC79: 4F 'O' CLRB ;BC7A: 5F '_' ZBC7B RTS ;BC7B: 39 '9'
電源投入後の$0900-の状態を見てみると、FF FF 05 17 0D 00 00 05 15 0D が入っている。
この時のbasic tailは$0905で、FF FF 05 17 0D の次を指している。つまりNEW直後でも5バイトは使われている。$0905に$FBを足すと$0A00になる。
L2II BASICの中間言語として読むと、"65535 END" になる。FFFFは行番号、05は行長(5バイト)、17がEND、0Dは行末である。
この5バイトはLISTコマンドでも見えない。プログラム末尾にENDを書いていないプログラムを救うために
その後ろの 00 00 05 15 0D は MONコマンドを入力した残骸である。ダイレクトコマンド実行時は、BASICプログラム以降の領域に中間コードを入れてそれを実行している。
L1 BASICのSIZEコマンド
ちなみにL1 BASICの場合は、こう説明されていたようだ(マニュアルが入手できていないので、雑誌記事から引用)。
S=で示されているアドレスは、BASICプログラムの最終番地である。ユーザーが使えるのは S+1以降。
ダイレクトコマンドのワーク領域は$540-にあり、BASICプログラムは$5C0-から入っている。番兵のENDと行末が9バイト使うので、起動直後はS=$05C8となる。
電子展望 1978年9月号 「日立ベーシックマスター活用のキーポイント」 p.41 から引用
SIZEコマンドのPROGRAMの意味
ここまで書いて思ったのだが、SIZEコマンドのPROGRAMの表示は「BASICプログラムの末尾+1」ではなく、「機械語プログラムが使って良いアドレスの先頭」を意味しているように思える。
L1 BASICでは、Sの次のアドレスから 機械語プログラムを入れることができた。
ダイレクトコマンドで使う領域がBASICプログラム領域より若い番地にあるので、プログラム最終アドレスをそのまま表示しても困らない。
利用者は最終アドレス+1以降を使えば良い。
ところが L2 BASICでは、ダイレクトコマンドはワーク領域として、BASICプログラム末尾以降を使う。
最終アドレスをそのまま表示したのでは、利用者がどこから機械語プログラムを入れて良いかわからない。
ダイレクトコマンドが使う分だけ、後ろにずらす必要がある。
この時点で意味合いが「機械語プログラムが使って良いアドレスの先頭」になっている。意味が変わったので、表示もS=ではなく PROGRAM= になったのかもしれない。
そして、SIZEコマンドの表示がPROGRAMであることで、この数値はBASICプログラム開始アドレスとして誤解され、そのようにマニュアルにも記載され、後々の混乱を招いたのかもしれない。
SIZEコマンドのマージン($FB)の意味
では、どれだけ後ろにずらせばいいのだろうか?
マージンとしては、見えないENDの5バイト+ダイレクトコマンドの最大長であれば良い。
ダイレクトコマンドとして入力できる文字数は1行79文字だが、これを中間言語に変換したときにはバイト数が増える場合がある。
たぶん、最大になるのは ? 1,1,1,1,1…1,1 (1が39個)のときで、$09CBまで使われる。
(数値は中間コードでは4バイトになる。","が38個で各1バイト、?は内部コードで1バイト。さらに行番号と行サイズと行末がつく。39*4 + 38 + 1 + 3 = 237バイト。見えないENDが5バイト、合計242バイト。$0900 + 242 = $09cc が空き領域の先頭になる)
マージンとしては$cb以上なら何バイトでもいいはずだが、NEW直後にキリのいいアドレス($0A00)を表示するために選ばれた値が$FBかもしれない。
余談
変数確保時のマージン計算はunsignedで行われていて、正しく確保できるのだけど、実際に配列参照を行うと $8000をまたぐ部分でおかしくなる。
下記のプログラムを64KB実装のJr.で実行すると、ERROR 17になる。実行前に POKE 8,$7F として RAM末を$7FFFに変更すると、問題なく実行できる。
エラー時のIは1544、配列先頭アドレスは$61D8なので、参照アドレスは$8000である($61D8+5*1544=$8000)。
10 DIM A(4000) 20 FOR I=1 TO 4000 30 LET A(I)=$1234 40 NEXT I
日立アセンブラも64KB実装では動かないバージョンがあったし、アドレスの扱い難しいですね。
(実際 C言語でもアドレス計算でハマることはありますし)。
資料
- bit臨時増刊「パーソナル・コンピュータの使い方」 「ベーシックマスター」 pp.239-254
- インターフェース1980年2月号 「ベーシックマスター拡張・汎用ラボオート装置の制作」 pp.61-88 (レベルIIの一部回路図)
- インターフェース1980年6月号 「ベーシックマスター用高解像度カラーグラフィック装置の制作」 pp.122-134
- インターフェース1981年5月号 「ベーシックマスター・レベルIIの回路図解剖」 pp.165-177 (MB6881の全回路図)
- I/O 1982年3月号 「ベーシックマスターJr.全回路図集」pp.198,291-299
- I/O 1982年4月号 「Jr.カラーアダプタ[全回路図公開]/アセンブラ」 pp.304-306
- I/O 1982年5月号 pp.337-347 「Jr.カラーアダプタ・グラフィック・ユーティリティ」
- ベーシックマスター活用研究 : Level 3,Jr – 国立国会図書館デジタルコレクションpp.95-
- テクノポリス 1982年10月号記事「ゲームのためのマシン語講座」pp.145-150
- 月刊RAM 1982年2月号 「ベーシックマスターJr.の可能性を探る」pp.74-80 の図1メモリマップ(p.76)
- BMUG会報 1982年7月号P.10
- BMUG会報 1983年5月号P.3
- BMUG会報 1984年12月号 P.4
- Enri’s Home PAGE BM Jr.
- Basic Master Jr. – HeAVeN@Wiki
- sedoc/8bit/hitachi/memmap.md at main · 0cjs/sedoc









ディスカッション
コメント一覧
まだ、コメントがありません