MSX0のプログラミングメモ

MSX0 Stackに関して、私がつくった簡単なBASICプログラムや、プログラミングのメモなどを載せていきます

MSX0でミニクイズ

概要

MSX0のタッチパネルに対応した、4択ミニクイズのプログラムです。

MSX0ミニクイズアプリのタイトル画面
MSX0ミニクイズアプリのクイズ画面

タイトル画面と、クイズ画面と、解説画面があります。
緑のボタンをタッチパネルで押せます。
(キーボードでも、1〜4のキーと、スペースキーで操作できます)

全部で15問あります。
BASICプログラムは下にありますが、今回はクイズデータが別ファイルでありますので、そちらも必要です(ファイル名:quiz.txt)。

ですが、クイズデータのテキストを見るとネタバレになるので、今回はディスクイメージも用意しましたw
https://data.hellotocky-msx.net/blogdata/msx0_quiz/quiz.dsk
(クイズの内容に誤りがあったら、そっと教えてくださいw)

プログラムの中で使えそうなところがあったら、自由に使っていただいて結構です。
またプログラム全体の転載は、このブログのURLも紹介していただければOKです(出典が明らかになれば)。

テキストファイルも好きに書き換えていただいて構いません。

1行目がタイトル、
2行目がクイズ本文、
3行目が選択肢(半角スペース3つで区切る)
4行目が解説、
5行目が正解の選択肢の番号(1~4)
6行目以降は、2~5行目の繰り返しです。
問題数は最大で15問までにしていますが、これを超える場合は、プログラムの20行目のQZ$, Q1$, AN, KA$の個数(15となってるところ)を変えてください。あと2行目の4000というところも、文字列領域が足りなくなったら増やしてください。

プログラム

(すみません、初出時よりもちょっとだけ変えました。360〜363行目を分割、1015行目と1115行目の処理をPLAY文への置き換え)

2 CLEAR 4000:DEFINT A-Z
10 _KANJI0:WIDTH32:SCREEN5:COLOR 1,15,15
20 DEFINT A-Z:DIM BX(5),BY(5),BW(5),BH(5),BV(5),BC(5), BE(1,5),BD(3), QZ$(15),Q1$(15),AN(15),KA$(15), R(2),G(2),B(2)
30 BM=5:BS=2
40 RESTORE 9000:FOR I=0 TO BM-1:READ BX(I), BY(I), BW(I),BH(I), BV(I),BC(I):NEXT I
50 RESTORE 9200:FOR I=0 TO BS-1:FOR J=0 TO BM-1:READ BE(I,J):NEXT J,I
60 LINE(0,0)-(255,211),15,BF
70 RESTORE 2000:FOR I=0 TO 1: READ R(I),G(I),B(I): NEXT I
80 FOR I=2 TO 2+BM-1:COLOR=(I,R(0),G(0),B(0)):NEXT I
90 OPEN "QUIZ.TXT" FOR INPUT AS #1:QM=0:INPUT #1, TT$
91 LOCATE 10,10:PRINT"NOW LOADING..."
92 INPUT #1, QZ$(QM), Q1$(QM), KA$(QM), AN(QM): QM=QM+1:IF EOF(1)=0 GOTO 92
94 CLOSE #1
99 C=0:BB=-1
200 ' title
210 CLS:LOCATE 0,4:PRINTTT$:T$=" スタート":GOSUB 1200:GOSUB 1300
220 PLAY "v12l32o6cde":TIME=0:FOR I=0TO1:I=-(TIME>20):NEXT I
300 ' main
310 QI=0:SC=0
320 COLOR1,15,15:LINE(0,0)-(255,211),15,BF
330 FOR I=0 TO 3:LINE(BX(I),BY(I))-STEP(BW(I),BH(I)),I+2,BF:NEXT I
340 FOR I=2 TO 2+5-1:COLOR=(I,R(0),G(0),B(0)):NEXT I
350 LOCATE 0,1:PRINTQZ$(QI):COLOR1,2
360 LOCATE 2,6:PRINT "①";:GOSUB 400
361 LOCATE 18,6:COLOR1,3:PRINT"②";:GOSUB 450
362 LOCATE 2,10:COLOR1,4:PRINT"③";:GOSUB 450
363 LOCATE 18,10:COLOR1,5:PRINT"④";:GOSUB 450
370 GOTO 500
400 ' cut select start
410 ST=1
450 ' print select one
460 EN=INSTR(ST, Q1$(QI), "   "):IF EN>0 THEN PRINTMID$(Q1$(QI),ST,EN-ST):ST=EN+3 ELSE PRINTMID$(Q1$(QI),ST)
470 RETURN
500 ' touch pad loop
510 BP=0:GOSUB 8000
520 IF BT=-1 GOTO 510
530 IF AN(QI)=BV(BT) THEN SC=SC+1:GOSUB 1000 ELSE GOSUB 1100
540 GOSUB 8000:IF BT<>-1 GOTO 540 ' wait key up
550 COLOR9,15:CLS:LOCATE0,0:PRINT"*解説*":COLOR1:LOCATE0,2:PRINTKA$(QI);
560 QI=QI+1:IF QI<QM THEN T$=" 次の問題へ" ELSE T$="  採点へ"
570 GOSUB 1200:GOSUB 1300
580 IF QI>=QM THEN 800
590 GOTO 320
800 ' finish
810 GOSUB 8000:IF BT<>-1 GOTO 810 ' wait key up
820 COLOR 1,15:CLS:LOCATE 5,3:PRINT"全問終了":LOCATE 3,5:PRINT"スコア:";SC;"(全";QM;"問)"
830 IF SC=QM THEN COLOR 9,15:LOCATE 4,7:PRINT"すごい!満点おめでとう!"
840 T$="  終了":GOSUB 1200:GOSUB 1300
890 END
1000 ' sound seikai
1010 LINE(92,90)-(163,120),9,BF:COLOR 15,9:LOCATE 13,6:PRINT"正解!"
1015 PLAY"v12o6ecec8"
1020 TIME=0:FOR I=0 TO 1:I=-(TIME>100):NEXT I
1040 RETURN
1100 ' sound bubu-
1110 LINE(92,90)-(171,120),7,BF:COLOR 15,7:LOCATE 13,6:PRINT"はずれ!"
1115 PLAY"v12o3c16r32c4"
1120 TIME=0:FOR I=0 TO 1:I=-(TIME>100):NEXT I
1140 RETURN
1200 ' draw next button, input=T$
1210 LINE(BX(4),BY(4))-STEP(BW(4),BH(4)),6,BF:COLOR 1,6:LOCATE 10,12:PRINTT$;
1220 RETURN
1300 ' wait press next button
1310 BP=1:GOSUB 8000:IF BT=-1 GOTO 1310
1320 RETURN
2000 DATA 1,6,1, 2,3,7   :'color
8000 ' touch pad loop
8010 BT=-1:BD(1)=BD(0):BD(0)=PAD(4)
8020 IN$=INKEY$:IF IN$="Q" THEN END
8030 IF IN$="" THEN8040
8031 IN=ASC(IN$):I=0:
8032 IF BE(BP,I) AND BC(I)=IN THEN BT=I:BD(0)=-1:BD(2)=BT:GOSUB8200:RETURN ELSE IF I<BM-1 THEN I=I+1:GOTO 8032
8040 IF BD(1)=-1 AND BD(0)=0 THEN GOSUB 8400:RETURN
8050 IF BD(0)=0 THEN RETURN
8060 X=PAD(1):Y=PAD(2):I=0
8070 IF BE(BP,I)<>0 AND BX(I)<=X AND X<=BX(I)+BW(I) AND BY(I)<=Y AND Y<=BY(I)+BH(I) THEN BT=I:GOTO8090
8080 IF I<BM-1 THEN I=I+1:GOTO 8070 ELSE RETURN
8090 IF BD(2)<>BT THEN GOSUB 8400
8100 BD(2)=BT:GOSUB 8200:RETURN
8200 ' key down
8210 COLOR=(BT+2,R(1),G(1),B(1))
8390 RETURN
8400 ' key up
8410 IF BD(2)<>-1 THEN COLOR=(BD(2)+2,R(0),G(0),B(0))
8590 RETURN
9000 REM button position (X, Y, W, H, value, alt-key-code)
9010 DATA  10, 86,110, 40, 1, 49
9020 DATA 140, 86,110, 40, 2, 50
9030 DATA  10,148,110, 40, 3, 51
9040 DATA 140,148,110, 40, 4, 52
9050 DATA  56,160,144, 48, 5, 32
9200 REM button pattern (btn-0 status, btn-1 status, ... btn-(BM-1) status)
9210 DATA 1, 1, 1, 1, 0
9220 DATA 0, 0, 0, 0, 1

※クイズデータをどうしても別ファイルでダウンロードしたい方は、こちらから
quiz.txt

プログラムの解説

主な処理

行番号 処理の概要
2~99 初期設定・データの読み込み
200~220 タイトル画面の表示
300~370 ①クイズの表示
500~520 ②回答待ち
530~590 ③正解・不正解の処理。解説画面の表示
800~890 ④採点画面

サブルーチン

行番号 エントリ行 処理の概要 受け取る変数 処理結果が
入る変数
400~470 1個目は400
2~4個目は450
クイズの選択肢を1つずつ表示する。 QI=何問目か なし
1000~140 1000 正解の表示・効果音処理 なし なし
1100~1140 1100 はずれの表示・効果音処理 なし なし
1200~1320 1200 「スタート」「次の問題へ」ボタンの表示・操作待ち処理 BT$=ボタンに表示する文字列 なし
8000~8100 8000 ⑤ボタンが押されたかの検出処理 BP=ボタンの有効/無効パターンで、使うもの T=ボタンが押されてなかったら-1。押されてたらそれ以外の数字。
BV(BT)とすると、ボタンに割り振られた数値が得られる。
8200~8390 8200 ボタンが押されたときの処理。⑤がコールする。ここでは、ボタンの色を変えている。 BT なし
8400~8590 8400 ボタンが離されたときの処理。⑤がコールする。ここでは、ボタンの色を変えている。 BT なし

データ

行番号 内容
2000 ボタンの色データ
9000~9050 ボタンの座標などの情報
9200~9220 ボタンの有効・無効状態のパターン

主な変数

全体的に使用するもの

変数名 用途
BX(), BY(), BW(), BH() ボタンのX座標・Y座標・幅・高さ。ボタンの数に応じた個数を定義する。
BV() 押されたボタンごとに対応する値。ボタンの数に応じた個数を定義する。
BC() ボタンの代わりに受け付けるキーのキャラクターコード。ボタンの数に応じた個数を定義する。
BE() ボタンの有効・無効のパターンの定義。ボタンの数に応じた個数を定義する。
BD() ボタン関係のサブルーチン内部データの保存用(0=PAD(4)/タッチパネルが押されてるか, 1=前回のPAD(4)の値, 2=前回押されたボタンの番号)
QZ$(), Q1$(), AN(), KA$() クイズのデータ。QZ$=出題文、Q1$=選択肢、AN=正解の選択肢、KA$=解説文。
最大15問分をメモリに持てるように、それぞれ15個用意してます。
R(), G(), B() ボタンの色。0=押されてないとき、1=押されたとき。
BM ボタンの個数。BX()などの個数と同じ値。
BS ボタンの有効/無効のパターン数。
QM クイズの設問数。ファイルからデータ読み出すときに自動で算出する。

①,②,③,④の部分で使う主なもの

変数名 用途
QI 何問目か。
SC 正解数。

局所的に使うもの

変数名 用途
I, J よく使う、ループ変数。非常によく使うので、短いループで使う。
ほか いろいろ

メモ

  • 4つの選択肢を1つの文字列に入れてるので、ちょっと変わった処理になってます。これは「MSXべーしっ君」を使おうとしたときの制限を回避してた処理の名残りです。
  • 「スタート」とかのボタンで、ユーザーがボタンを押すまでそのまま待つ、という場合は、以下の処理をやってます。
    • T$に文字列を入れてGOSUB 1200とすることでボタンを表示し、
    • GOSUB 1300とすることで、ユーザーがボタンを押すまで待つ
  • クイズの解答を待つ場面では、500~540行目で以下のように処理してます。
    • BPに0を入れて(ボタンのパターン0を選択)、GOSUB 8000とすることで、ボタンが押されてるかを取得。押されるまでぐるぐる回る。
    • 530行目は、答え合わせ。
    • ボタンが押されたら、離されるまで待つ(540行目)。
  • 8000~8100行目は、ほかでも使いまわしができるといいな、と思って書いたものです。
    • ボタンが押されたら8200行目を、放されたら8400行目をコールするので、「押されたら音を鳴らす」とか「振動する」とかの処理を書いてもいいかも(今のMSX0では振動できないですが)。

MSX0のBASICによる簡易ファイラ

はじめに

MSX0で遊ぶのに少し慣れてきたら、プログラム読み込むためにパソコン繋げるのは面倒だな…、と思い始めたので、BASICでタッチパネル対応の簡単なファイラーを作ってみました。

オールBASICなので、ディスク内のファイル名を取得する方法が、とても胡散臭いですw
拡張子が .BAS なもののみを列挙します。

これをautoexec.basという名前で保存するか、autoexec.basから読み込むようにしてください。

プログラムの中で使えそうなところがあったら、自由に使っていただいて結構です。
またプログラム全体の転載は、このブログのURLも紹介していただければOKです(出典が明らかになれば)。

制限

BASICだけで手を抜いてファイル名一覧を取得しているので、ディスクイメージ内に *.BASのファイルが非常に大量にある(139個以上くらい)と、原理的に挙動がおかしくなります。が、現状112個までしか作成できないので、問題なしです。
(thanks to Lithelia@うるうる(@Lithelia)さん)
(実際にMSX0で試して、112個までしか作成できない&112個のBASICファイルがあってもファイラーは動く、と確認できました)

スクリーンショット

画面1
画面2

動画

プログラム

1 ' TINY-FILER 2023   Copyright (c) 2023 hellotocky
10 ' get files
11 COLOR1,1,1:SCREEN0:WIDTH80:FILES"*.BAS"
14 DEFINT A-Z:DIM FD(12):RT=0 ' for get file name after turbo-off
15 _TURBO ON(RT,FD())
20 '   FL$()=file list, BS()=sprite no, BX(),BY()=position, BE()=enabled(status), BK()=alter key char-code, BM=num of buttons, NM=num of files
21 DEFINT A-Z:DIM FL$(8),BS(5),BX(5),BY(5),BE(5),BK(5):BM=4:NM=0
22 FI=0:FOR I=0 TO 7:FL$(I)="":NEXT I
30 FOR Y=0 TO 23:FOR X=0 TO 80-13 STEP 13
40 F$="":FOR XX=0 TO 11:F$=F$+CHR$(VPEEK(Y*80+X+XX)):NEXT XX
50 IF F$="            " THEN X=80:Y=24:NEXT X,Y:GOTO 100
60 FL$(FI)=FL$(FI)+F$:NM=NM+1:IF LEN(FL$(FI))>244 THEN FI=FI+1
70 NEXT X,Y
100 ' init
110 SCREEN 1,3:COLOR15,1,1:CL=0:TP=0
120 FOR I=0 TO BM: READ BS(I), BX(I), BY(I), BK(I):NEXT I
130 S1$="":S2$="":S3$="":S4$=""
140 '   sprite 0=UP, 1=DOWN, 2=GO, 3=NG
150 FOR I=0 TO 15:READ A$:B$=CHR$(VAL("&B"+LEFT$(A$,8))):S1$=S1$+B$:S3$=B$+S3$:B$=CHR$(VAL("&B"+RIGHT$(A$,8))):S2$=S2$+B$:S4$=B$+S4$:NEXT I
160 SPRITE$(0)=S1$+S2$:SPRITE$(1)=S3$+S4$
170 FOR J=2 to 3
180 S1$="":S2$="":FOR I=0 TO 15:READ A$:B$=CHR$(VAL("&B"+LEFT$(A$,8))):S1$=S1$+B$:B$=CHR$(VAL("&B"+RIGHT$(A$,8))):S2$=S2$+B$:NEXT I:SPRITE$(J)=S1$+S2$
190 NEXT J
200 ' print list
210 PUT SPRITE 0,(BX(0),BY(0)),11,0:PUT SPRITE 1,(BX(1),BY(1)),11,1:PUT SPRITE 2,(BX(2),BY(2)),13,2
220 CLS:LM=22:FOR I=0 TO LM-1:NI=TP+I:GOSUB1200:PRINT "  ";F$
230 IF (TP+I) >= NM-1 THEN I=24:NEXT I ELSE NEXT I
240 BE(0)=1:BE(1)=1:BE(2)=1:BE(3)=0:BE(4)=0
300 ' cursor
301 '   BC=before cursor pos, CL=cursor index, TP=top offset
310 LOCATE 0,BC:PRINT" ";:BC=CL-TP
320 LOCATE 0,CL-TP:PRINT">";
330 GOSUB 1000:IF BT=0 THEN CL=CL-1 ELSE IF BT=1 THEN CL=CL+1 ELSE IF BT=2 THEN 2000
340 IF CL<0 THEN CL=0 ELSE IF CL>=NM THEN CL=NM-1
350 IF CL<TP THEN TP=TP-1:NI=CL:GOSUB1200:PRINTCHR$(27);"H";CHR$(27);"L  ";F$;CHR$(13);CHR$(10);"  "; ELSE IF TP+LM=<CL THEN TP=TP+1:NI=CL:GOSUB1200:LOCATE0,21:PRINT "  ";CHR$(13);CHR$(10);"  ";F$
360 GOTO 300
1000 ' wait button press, return BT
1010 IN$=INKEY$:IF IN$="Q" THEN END
1020 IF IN$<>"" THEN FOR I=0 TO BM:IF BE(I)<>0 AND ASC(IN$)=BK(I) THEN BT=I:RETURN ELSE NEXT I
1030 IF PAD(4)=0 THEN 1010
1040 X=PAD(5):Y=PAD(6)
1050 MG=8:BT=-1
1060 FOR I=0 TO BM:IF BE(I)<>0 AND BX(I)-MG<=X AND X<=BX(I)+32+MG AND BY(I)-MG<=Y AND Y<=BY(I)+32+MG THEN BT=I:GOSUB 1100:NEXT I ELSE NEXT I
1070 IF BT<>-1 THEN TIME=0:FOR I=0 TO 1:I=-(TIME>5):NEXT I:RETURN ELSE 1010
1100 ' button clicked
1110 RETURN
1200 ' get file name from NI, return F$
1210 FI=NI\21:LF=NI MOD 21
1220 F$=MID$(FL$(FI),LF*12+1,12):RETURN
2000 ' file selected
2010 PUT SPRITE 0,(0,209),0,0:PUT SPRITE 1,(0,209),0,0:PUT SPRITE 2,(0,209),0,0
2020 PUT SPRITE 0,(BX(3),BY(3)),13,BS(3):PUT SPRITE 1,(BX(4),BY(4)),15,BS(4)
2030 CLS:LOCATE0,6:NI=CL:GOSUB1200:PRINT F$;": Run?(y/n)"
2040 BE(0)=0:BE(1)=0:BE(2)=0:BE(3)=1:BE(4)=1:GOSUB 1000:IF BT=3 THEN 2100 ELSE 200
2100 ' load basic program
2110 FOR I=0 TO 11:FD%(I)=ASC(MID$(F$,I+1,1)):NEXT I:RT=1
2120 _TURBO OFF
2130 IF RT=0 THEN SCREEN1:END ' for end command while turbo-on
2140 F$="":FOR I=0 TO 11:F$=F$+CHR$(FD%(I)):NEXT I
2150 SCREEN1:RUN F$
2160 END
4000 ' button position (id, X, Y, alt-key-code)
4010 DATA 0,200,20,30,  1,200,90,31,  2,160,140,32,  2,48,100,121,  3,176,100,110
5000 ' up-down button data
5010 DATA 1111111111111111
5020 DATA 1000000000000001
5030 DATA 1000000110000001
5040 DATA 1000000110000001
5050 DATA 1000001111000001
5060 DATA 1000001111000001
5070 DATA 1000011111100001
5080 DATA 1000011111100001
5090 DATA 1000111111110001
5100 DATA 1000111111110001
5110 DATA 1001111111111001
5120 DATA 1001111111111001
5130 DATA 1011111111111101
5140 DATA 1011111111111101
5150 DATA 1000000000000001
5160 DATA 1111111111111111
5200 ' GO button data
5210 DATA 1111111111111111
5220 DATA 1111111111111111
5230 DATA 1100000110000011
5240 DATA 1101111110111011
5250 DATA 1101111110111011
5260 DATA 1101111110111011
5270 DATA 1101111110111011
5280 DATA 1101000110111011
5290 DATA 1101110110111011
5300 DATA 1101110110111011
5310 DATA 1101110110111011
5320 DATA 1101110110111011
5330 DATA 1101110110111011
5340 DATA 1100000110000011
5350 DATA 1111111111111111
5360 DATA 1111111111111111
5600 ' NO button
5610 DATA 1111111111111111
5620 DATA 1000000000000001
5630 DATA 1010000101111101
5640 DATA 1010000101000101
5650 DATA 1011000101000101
5660 DATA 1011000101000101
5670 DATA 1010100101000101
5680 DATA 1010100101000101
5690 DATA 1010010101000101
5700 DATA 1010010101000101
5710 DATA 1010001101000101
5720 DATA 1010001101000101
5730 DATA 1010000101000101
5740 DATA 1010000101111101
5750 DATA 1000000000000001
5760 DATA 1111111111111111

MSX0の鍵盤プログラム

MSX0 Stackにはタッチパネルが付いているので、それを使った鍵盤プログラムを作成しました。

タッチパネルを使ったBASICプログラムを作る際の参考になったらうれしいです。
使えそうなところがあったら、自由に使っていただいて結構です。(プログラム全体の転載は、このブログのURLも紹介していただければOKです(出典が明らかになれば)。)

スクリーンショット

タイトル画面(シンプルすぎるw)

鍵盤プログラムのタイトル画面

演奏中の画面

演奏中画面

上の段:左から「ド」「レ」「ミ」「ファ」
下の段:左から「ソ」「ラ」「シ」「ド」
です。
ボタンを押している間は、ボタンが赤くなって、音が鳴り続けます。
押したタイミングと、離したタイミングでそのあたりの処理を行っています。

プログラム

ファイル名:PADMUSIC.BAS

1 ' Copyright 2023 hellotocky
10 SCREEN 5:COLOR15,2,15
20 LINE(0,0)-(255,211),15,BF
30 LINE(10,120)-(245,160),2,BF:open "GRP:" FOR OUTPUT AS #1:PRESET(30,136):PRINT #1,"HIT this button to START"
100 ' INIT
110 _TURBO ON
120 DEFINT A-Z
129 ' BD(): 0=current pad(4), 1=before pad(4), 2=before tapped
130 DIM R(2),G(2),B(2), X1(9),X2(9),Y1(9),Y2(9),BE(2,9), BD(3), HZ(9):BM=9:BS=2
140 RESTORE 9000:FOR I=0 TO BM-1:READ X1(I), Y1(I), X2(I), Y2(I), HZ(I):NEXT I
150 RESTORE 9200:FOR I=0 TO BS-1:FOR J=0 TO BM:READ BE(I,J):NEXT J,I
160 RESTORE 9400:FOR I=0 TO 1: READ R(I),G(I),B(I): NEXT I
190 BD(0)=0:BD(1)=0:BD(2)=-1:BT=-1
200 ' TITLE loop
210 BP=0:GOSUB 8000
220 IF BT<>0 GOTO 210
300 ' MAIN loop
310 LINE(0,0)-(255,211),15,BF:FOR I=2 TO 2+8:COLOR=(I,R(0),G(0),B(0)):NEXT I
320 FOR I=1 TO 8:LINE(X1(I),Y1(I))-(X2(I),Y2(I)),I+2,BF:NEXT I
330 BP=1
340 GOSUB 8000:GOTO 340
8000 ' touch pad loop
8010 BD(1)=BD(0):BD(0)=PAD(4)
8020 IN$=INKEY$:IF IN$="Q" THEN END
8030 IF BD(1)=-1 AND BD(0)=0 THEN GOSUB 8400:BT=-1:RETURN
8040 IF BD(0)=0 THEN RETURN
8050 X=PAD(1):Y=PAD(2):I=0
8060 IF BE(BP,I)<>0 AND X1(I)<=X AND X<=X2(I) AND Y1(I)<=Y AND Y<=Y2(I) THEN BT=I:GOTO8080
8070 IF I<BM THEN I=I+1:GOTO 8060 ELSE RETURN
8080 IF BD(2)<>BT THEN GOSUB 8400
8090 BD(2)=BT:GOSUB 8200:RETURN
8200 ' key down
8205 IF BP=0 THEN COLOR=(2,R(1),G(1),B(1)):RETURN
8210 COLOR=(BT+2,R(1),G(1),B(1))
8220 SN=111860!/HZ(BT):SOUND 8,10:SOUND 0,SN AND 255:SOUND 1,SN\256
8230 RETURN
8400 ' key up
8405 IF BP=0 THEN COLOR=(2,R(0),G(0),B(0)):RETURN
8410 SOUND 8,0
8420 COLOR=(BD(2)+2,R(0),G(0),B(0))
8430 RETURN
9000 REM button position, sound Hz
9010 DATA  10,120,245,160,   0
9020 DATA  10, 10, 60,100, 261
9030 DATA  70, 10,120,100, 294
9040 DATA 130, 10,180,100, 330
9050 DATA 190, 10,240,100, 349
9060 DATA  15,115, 65,205, 392
9070 DATA  75,115,125,205, 440
9080 DATA 135,115,185,205, 494
9090 DATA 195,115,245,205, 523
9200 REM button status pattern
9210 DATA 1,0,0,0,0,0,0,0,0
9220 DATA 0,1,1,1,1,1,1,1,1
9400 DATA 1,6,1,  7,1,1   :'color

メモ

ちょっと無駄なループが多いですが、8000行からの処理は使いまわせるように意識したつもりです。

9010行目~9090行目:ボタンの座標データの定義。9010行目は0番、9020行目は1番、9030行目は3番…となる。
9210行目~9220行目:タイトル画面で押せるボタンと、演奏画面で押せるボタンのパターンを定義。
 ※9210行目は、0番のボタンのみ押せる、という意味。(パターン0番)
  9220行目は、1番~8番のボタンのみ押せる、という意味。(パターン1番)

変数のBPに何番のパターンを使用するかを代入してから、8000行目をコールします。結果が変数BTに入って帰ってきます。
 BT=-1なら、何も押されなかった
 BT=0なら、ボタン0番が押された
 BT=1なら、ボタン1番が押された
というような意味になります。

タイトル画面では以下の処理を行っています。

210 BP=0:GOSUB 8000
220 IF BT<>0 GOTO 210

ここでは何も処理してないですが、この中で音を鳴らすとかスプライトを動かすとかの処理を入れてもいいですね。
BP=0を代入しているので、9210行目で定義したパターン1番を使う=ボタン0番のみ有効となります。
BP=1を代入すると、9220行目で定義したパターン2番を使うことになり、ボタンの1番~8番が有効になります。

ボタンが押された、離れた、と言う処理を9200行目~と9400行目~に書きましたが、ちょっとイマイチかな…。お好みで変更どうぞ。