スポンサーリンク
WebMSXでMSX BASICのゲームを作ろう!第13弾。
マシン語を使うことによって、最初の待ち時間を3秒縮めましたw
マシン語にすればいける!と思ったのですが、
ほとんど変わらなかったですw
非常に効率の悪いマシン語ではありますが。
VRAMの一部を別の場所にコピーしているだけなんですけどね〜。
プログラムの挙動をみていると、
マシン語化されたところは一瞬で処理されているようです。
"vram copy"と表示した後が、
マシン語なのですが一瞬です。
問題は、その前の、DATA文から読み込んだデータを
VRAMに書き込むときみたいですね。
それとスプライトの定義みたいです。
URLクリックで実行できます。
http://webmsx.org/?DISKA_URL=http://goods.heteml.jp/msx/MM4 (17).dsk
マシン語を使っていますが、今回はそこの説明は省略します。
ループとかでてくるので。
マシン語勉強レポートでそのうちとりあげます。
それではBASIC部分の解説を。
5 CLEAR 200,&HB800:COLOR 15,5,1
10 SCREEN2:SCREEN1,2,0:DEFINTA-Z
:KEYOFF:WIDTH32:LOCATE14,4:PRINT
"wait"
15 DEFUSR=&H7E
16 DEFUSR1=&HB800:DEFUSR2=&HB861
17 A=USR(0)
20 H2 = 1:X=112:Y=160:XX=4:YY=4:
DIM A1(20):SS=19:DIMR(16,12)
30 FOR J=0 TO 7:S$="":FOR I=1 TO
32:READD$:S$=S$+CHR$(VAL("&H"+D$
)):NEXT:SPRITE$(J)=S$:NEXT
40 FOR K=0 TO SS:A1(K)=65+K:NEXT
41 D$="":RESTORE 1000
44 FOR K=0 TO SS
49 D$=""
50 FOR I=0 TO 7
60 READ D$,C$
70 VPOKE A1(K)*8+I,VAL("&b"+D$)
72 '
74'
90 VPOKE &H2000+A1(K)*8+I,VAL("&h"+C$)
92'
94'
96 NEXT
99 NEXT
140 RESTORE980
150 B$="":READ B$:FOR I=0 TO47:POKE &HB800+I,VAL("&H"+MID$(B$,I*2+1,2)):NEXT:PRINT"&hb800"
151 D$="":E$="":READ D$,E$:D$=D$+E$:FOR J=0 TO61:POKE &HB830+J,V
AL("&H"+MID$(D$,J*2+1,2)):NEXT:PRINT"vram copy"
152 T=USR1(0)
167 BLOAD"STAGE1.BIN"
168 U=USR2(&HC000)
170 S=STICK(0) OR STICK(1):TG=ST
RIG(0) OR STRIG(1)
180 IF JF<>1 THEN XX=0
185 XA=X:YA=Y
190 IF S=3 THEN XX=8
200 IF S=7 THEN XX=-8
210 X=X+XX
220 '
230 '
240 H2=-H2:IF JF=1 THEN H2=-1
250 IF S=3 AND H2=1 THEN H=0
260 IF S=3 AND H2=-1 THEN H=4
270 IF S=7 AND H2=1 THEN H=1
280 IF S=7 AND H2=-1 THEN H=5
290 IF X<0 THEN X=240:IF ST>0 TH
EN ST=ST-1:GOSUB 610
300 IF X>240 THEN X=0:IF ST<7 TH
EN ST=ST+1:GOSUB 610
310 IF JF=1 THEN 340
320 IF TG=0 THEN 390
330 JF=1:JY=-16:JC=3
340 IF JC=0 THEN 370
350 IF TG=0 THEN JC=0:GOTO 370
360 JC=JC-1
370 IF JC=0 AND JY<16 THEN JY=JY+4
380 Y=Y+JY
390 X2=(X-XX)\8:Y2=Y\8:Y3=(Y-JY)\8:IF J
F=0 THEN JY=0
391 'PUTSPRITE 0,(XA,YA),7,H
392 'PUTSPRITE 1,(XA,YA),11,H+2
400 AD = &H1800+(X¥8)+(Y¥8)*32
410 AE=&H1800+(
(X+15)¥8)+(Y¥8)*32
420 IF XX>0 AND VPEEK(AE)>=A1(0) THEN X
=X2*8:XX=0
430 IF XX>0 AND VPEEK(AE+32)>=A1(0) THE
N X=X2*8:XX=0
440 IF XX<0 AND VPEEK(AD)>=A1(0) THEN X
=X2*8
450 IF XX<0 AND VPEEK(AD+32)>=A1(0) THE
N X=X2*8:XX=0
460 AD = &H1800+(X¥8)+(Y¥8)*32
470 AE=&H1800+(
(X+15)¥8)+(Y¥8)*32
480 IF JY<0 AND VPEEK(AD)>=A1(0)
THEN Y=Y3*8:JF=0:JY=0
490 IF JY<0 AND VPEEK(AE)>=A1(0)
THEN Y=Y3*8:JF=0:JY=0
500 IF JY>=0 AND VPEEK(AD+64)>=A
1(0) THEN Y=Y2*8:JF=0:GOTO 531
510 IF JY>=0 AND VPEEK(AE+64)>=A
1(0) THEN Y=Y2*8:JF=0:GOTO 532
520 IF JF=0 THEN JF=1:JC=0:JY=0
530 GOTO 539
531 IF VPEEK(AD+32)>=A1(0) THEN
Y=(Y2-1)*8:JF=0:GOTO 539
532 IF VPEEK(AE+32)>=A1(0) THEN
Y=(Y2-1)*8:JF=0:GOTO 539
534 '
539 PUTSPRITE 0,(X,Y),7,H
540 PUTSPRITE 1,(X,Y),11,H+2
550 GOTO 170
610 CLS
611 PUTSPRITE 0,(X,Y),7,H
612 PUTSPRITE 1,(X,Y),11,H+2
620 U=USR2(&HC000+768*ST)
630 RETURN
800 DATA 2E,2D,67,7E,78,7C,38,06,16,17,
0F,14,1D,07,0F,0F,F0,F8,80,00,00,00,00,
00,E0,70,70,20,50,80,80,E0
省略
870 DATA 00,00,00,08,0A,1B,0F,07,00,00,
00,03,03,00,00,00,00,04,04,0C,00,80,80,
80,00,00,00,00,00,00,00,00
980 DATA 21080211080A01A000CD4A0
0EBCD4D00EB23130B78B120F12108021
1081201A000CD4A00EBCD4D00EB23130
B78B120F1
985 DATA 21082211082A01A000CD4A0
0EBCD4D00EB23130B78B120F12108221
1083201A000CD4A00EBCD4D00EB23130
B78B120F1C9
990 DATA 2AF8F7110018010003CD5C0
0C9
1000 DATA 00000100,1f
1010 DATA 00000100,15
1020 DATA 00000100,15
1030 DATA 11111111,15
1040 DATA 00100000,15
1050 DATA 00100000,15
1060 以下省略
16 DEFUSR1=&HB800:DEFUSR2=&HB861
ここは、マシン語がメモリのどこにはいっているか、
スタート位置です。
今回は、マシン語(サブルーチン)を2つ使います。
DEFUSR1=&HB800
ここは、今回のマシン語部分です。
何をやっているか説明します。
キャラクター(文字)をカラフルなブロックなどに変える場合、
ちょっと複雑でした。
画面が上部、中部、下部と別れていて、
それぞれにキャラクター定義しなければいけませんでした。
詳しくはこちら。
VRAMに、同じデータを3回書き込まないといけないのです。
それを2回目、3回目をマシン語でやっています。
上段のデータを、コピーしているだけです。
DEFUSR2=&HB861
前回までの画面を表示するところです。
マシン語自体は触っていません。
開始アドレスは変わっています。
150 B$="":READ B$:FOR I=0 TO47:POKE &HB800+I,VAL("&H"+MID$(B$,I*2+1,2)):NEXT:PRINT"&hb800"
151 D$="":E$="":READ D$,E$:D$=D$+E$:FOR J=0 TO61:POKE &HB830+J,V
AL("&H"+MID$(D$,J*2+1,2)):NEXT:PRINT"vram copy"
152 T=USR1(0)
読み込んだマシン語のデータが長すぎて、ひとつのB$に入りきらなかった
ので2つに分けただけです。
一番苦労したのが、メモリのアドレス(番地)ですね。
BASIC部分のいろんなところに、
マシン語のアドレスが出てきていると思いますが、
1でも違えば暴走なので;
どのアドレスにどのデータが入っているかは一番重要みたいです。
普通のBASICでは特に意識しなかったところですねぇ。
iOSのアプリを作っていても、
メモリのアドレスを意識することはありませんでした。
ここが苦労しました。
これからもっとマシン語をやっていくと大変なのかなぁ。
うわぁ〜。
次回は、キャラクター定義を外部ファイルにします。
マップデータの入ったファイルにキャラクターも入れてしまいます。
これをやればもう少し早くなるのではないでしょうか。
そうなってくるとスプライトのデータも、外部ファイルにするといいのかな?
そこはどうしようかな〜。
しばらくはやらないかな〜。
それでは、また次回〜。
スポンサーリンク