今回はカーソルキーの入力です。
やっとゲームらしくなってきました^^
BASICでいうところのSTICK関数みたいなのがあるのかな?
それでは始めます。
MSXマシン語では、BIOSでジョイスティック(カーソル移動キー)の状態が分かるそうです。
BIOS
-------------------------------------------------
アドレス:00D5 (GTSTCK)
ジョイステックの状態を調べる。
エントリーパラメータ:Aレジスタに調べるジョイスティックの番号を入れる。
リターンパラメータ:Aレジスタにジョイスティックが向いている方向がはいる。
使用レジスタ:すべて。
-------------------------------------------------
おお!BASICのSTICK関数と同じですね!
サンプルプログラム
文字をカーソルキーで移動させるサンプルが載っています。
(スプライトの移動じゃないんですね^^;)
D000 CDB700 STCKLP:CALL BREKX
D003 D8 RET C
D004 3E00 LD A , 0
D006 CDD500 CALL GTSTCK
D009 2A00D8 LD HL , (0D800H)
D00C B7 OR A
D00D 28F1 JR Z , STCKLP
D00F FE08 CP 8
D011 2008 JR NZ , STICK1
D013 CD6BD CALL MOVEL
D016 CD5FD0 CALL MOVEU
D019 18E5 JR STCKLP
D01B FE07 STICK1: CP 7
D01D 2005 JR NZ,STICK2
D01F CD6BD0 CALL MOVEL
D022 18DC JR STCKLP
D024 FE06 STICK2: CP 6
D026 2008 JR NZ,STICK3
D028 CD6BD0 CALL MOVEL
D02B CD77D0 CALL MOVED
D02E 18D0 JR STCKLP
D030 FE05 STICK3: CP 5
D032 2005 JR NZ,STICK4
D034 CD77D0 CALL MOVED
D037 18C7 JR STCKLP
D039 FE04 STICK4: CP 4
D03B 2008 JR NZ,STICK5
D03D CD77D0 CALL MOVED
D040 CD83DO CALL MOVER
D043 18BB JR STCKLP
D045 FE03 STICK5: CP 3
D047 2005 JR NZ,STICK6
D049 CD83D0 CALL MOVER
D04C 18B2 JR STCKLP
D04E FE02 STICK6: CP 2
D050 2008 JR NZ,STICK7
D052 CD83D0 CALL MOVER
D055 CD5FD0 CALL MOVEU
D058 18A6 JR STCKLP
D05A CD5FD0 STICK7:CALL MOVEU
D05D 18A1 JR STCKLP
D05F 7D MOVEU: LD A,L
D060 FE01 CP 1
D062 C8 RET Z
D063 CD8FD0 CALL PUTSPC
D066 2D DEC L
D067 CD98D0 CALL PTSTAR
D06A C9 RET
D06B 7C MOLEL: LD A,H
D06C FE01 CP 1
D06E C8 RET Z
D06F CD8FD0 CALL PUTSPC
D072 25 DEC H
D073 CD98D0 CALL PTSTAR
D076 C9 RET
D077 7D MOVED: LD A,L
D078 FE17 CP 23
D07A C8 RET Z
D07B CD8FD0 CALL PUTSPC
D07E 2C INC L
D07F CD98D0 CALL PTSTAR
D082 C9 RET
D083 7C MOVER: LD A,H
D084 FE20 CP 32
D086 C8 RET Z
D087 CD8FD0 CALL PUTSPC
D08A 24 INC
D08B CD98D0 CALL PTSTAR
D08E C9 RET
D08F CDC600 PUTSPC: CALL POSIT
D092 3E20 LD A,20H
D094 CDA200 CALL CHPUT
D097 C9 RET
D098 CDC600 PTSTAR: CALL POSIT
D09B 3E2A LD A,2AH
D09D CDA200 CALL CHPUT
D0A0 2200D8 LD (0D800H) , HL
D0A3 RET
D000 CDB700 STCKLP:CALL BREKX
D003 D8 RET C
D004 3E00 LD A , 0
まず、ここまで。
アドレスのD000
STCKLPは自分で定義したラベルです。
そしてBIOSの00B7 (BREKX)を呼んでいます。
(CDはアドレスへ飛ぶでした。CDが出た場合、BIOSを呼んでないかチェック!)
MSX MAGAZINE永久保存版3によりますと、
CTRL + STOP が押されているかを得る、とあります。
戻り値:Cy(キャリーフラグ) CTRL + STOPが押されている場合にセットされる。
D003は、フラグCが立っているとRETします。
MSXマシン語入門(Z80 アセンブラ・機械語) 勉強レポート 第23回 条件ジャンプ。これは大切! - ニャオニャオ21世紀
RETは、RETURNの意味で、BASICに戻るなのかな。
D004は、Aに0を入れる。
続きは、
D006 CDD500 CALL GTSTCK
D009 2A00D8 LD HL , (0D800H)
D00C B7 OR A
D00D 28F1 JR Z , STCKLP
アドレスD006は、
BIOS 00D5 (GTSTCK)を呼びます。
D009は、レジスタHL に、D800Hの内容を入れていますが、これはなに?
どうもBASIC部分でアドレスの
&HD800にX座標を、
&HD801にY座標を
入れているみたいです。
(BASICでは初期値がLOCATE 0,0で表示、
D800HとD801Hにはそれぞれ1。
内部処理用には、初期値が(1,1)になっています。)
その値をHLに入れている?
D00Cは、OR Aです。
これはAレジスタが0かどうか調べてZフラグに入れる、だそうです。
D00Dは、Zフラグが1なら、STCKLPへ飛びます。
( 上のアドレスで、Aレジスタが0ならZフラグが1です^^)
JRは相対ジャンプで、F1は補数ですね。(-15)
これはステックが0(何も押されていなければ) なら、STCKLPへ。
ループです。
D00F FE08 CP 8
D011 2008 JR NZ , STICK1
D013 CD6BD0 CALL MOVEL
D016 CD5FD0 CALL MOVEU
D019 18E5 JR STCKLP
アドレスD00Fは、
MSXマシン語入門(Z80 アセンブラ・機械語) 勉強レポート 第21回 比較命令 - ニャオニャオ21世紀
CP 8は、Aレジスタが8なら、Zフラグが1。
(AレジスタにはBIOSのGTSTCKによりジョイスティックの値が入っていたはず!)
D011は、Zフラグが0なら、STICK1へ飛びます。
1
8 ↑ 2
7 ← ・ → 3
6 ↓ 4
5
8は左上の入力です。
上の方のアドレスを考えると、
ここではジョイスティックが8以外(0も)の入力だった場合、
ジャンプします。
そのジャンプ先で、
一つづつ、CP 7とか、CP 6とかやって
ジョイスティックがどんな値か?チェックするみたいですね^^
MSXマシン語入門(Z80 アセンブラ・機械語) 勉強レポート 第23回 条件ジャンプ。これは大切! - ニャオニャオ21世紀
ジョイスティックが8なら、そのまま下のアドレスへ行きます。
D013、D016はCALLです。
自分で作るラベル(後の方ででてくる)のMOVELとMOVEUへ飛びます。
MOVELのLはLEFT、MOVEUのUはUP
の意味でしょう。
ジョイスティックの8は左上なので、
MOVEL、 MOVEUで、左移動と上移動をさせるのかな?
D019は相対ジャンプ。ジョイスティックの入力チェックへ。
ループですね。
この相対ジャンプは困ります^^;
D019 18E5
アドレスがE5。こういうのはハンドアセンブルだと全部アドレスを
書いていかないといけないです_:(´ཀ`」 ∠):
相対アドレスなので、上に何バイト戻るか書く訳ですが、
プログラムに何か追加などの変更をしたらアウトですよね!
やっぱりアセンブラのツールを使わないと( ・∇・)
次回はアセンブラについて調べてみます^^
(win / mac 用になります。MSXのアセンブラは...)
D01B ~ D05Dは、だいたい今までと同じです。
ジョイスティックの7 ~ 1までをチェックして、各移動サブルーチンに飛ばす、と。
D05F 7D MOVEU: LD A,L
D060 FE01 CP 1
D062 C8 RET Z
D063 CD8FD0 CALL PUTSPC
D066 2D DEC L
D067 CD98D0 CALL PTSTAR
D06A C9 RET
アドレスD05Fは、レジスタHLのうちのLをAレジスタに。
これはY座標が入っています。
D060で、Y座標が1かどうかチェック!
D062で、Y座標が1なら移動処理はしません。
これは、画面の表示範囲チェックかな?
画面からはみ出ないようにするためのものみたいです。
D063で、ラベルPUTSPCへ。
PUTSPCは、文字を消します。
D066で、Y座標の値を、-1しています。
D067で、ラベルPTSTARへ。
PTSTARは、文字を表示します。
D06Aでリターン。
文字の表示は、スプライトと違って、
表示->消す->別の場所に表示
とわざわざ元の文字を消してやらないとダメなんです~。
そうしないと動いた感じにならないんですよね。
スプライトは座標を変更してやるだけで移動できるのは楽ですよね!
D06B ~ D08E はほぼ同じです。
X=X+1とか、X=X-1は、
自分で表示する座標を入れるアドレスを決めておいて、
そのアドレスの値をレジスタHLにいれて、
それをINCしたり(+1ですね^^)、DECしたり(-1です^^)
するだけみたいです。
思ったより簡単かも( ・∇・)
D08F CDC600 PUTSPC: CALL POSIT
D092 3E20 LD A,20H
D094 CDA200 CALL CHPUT
D097 C9 RET
MSX マガジン 永久保存版3によれば、
BIOSの00C6 (POSIT)は、
カーソルを移動する。
引数: レジスタH カーソルのX座標を指定。
レジスタL カーソルのY座標を指定。
アドレスのD092は、20HをレジスタAに入れます。
キャラクターコード20Hはスペースでしたっけ?
10進数でチェック! CHR$(32)はスペースですね。
16進数でやられるとわかりづらいなぁ〜(^^;)
アドレスD094で、
BIOSの00A2 (CHPUT)は、
レジスタAに入っているキャラクターコードを画面に表示。
(この場合、カーソル位置を指定しておきます。)
D097 はリターンです。
D098 CDC600 PTSTAR: CALL POSIT
D09B 3E2A LD A,2AH
D09D CDA200 CALL CHPUT
D0A0 2200D8 LD (0D800H) , HL
D0A3 RET
アドレスD098は、カーソル位置の設定BIOS
アドレスD098Bは、2AHをAレジスタに入れる。
16進数の2Aは、キャラクターコードで*です。
D09Dは、BIOSのCHPUT(文字表示)
D0A0は、XY座標を入れている(自分で決めた)メモリのアドレスD800Hに、HLの値を入れています。メモリ上の座標を更新しているのですね。
D0A3はリターン。
今回は、BASIC+マシン語でやっています。
おお!超高速移動!
マシン語すごいなぁ(〃ω〃)
BASICであれこれスピードを稼ぐために四苦八苦していたのが....
スプライトの移動も簡単にできそう^^
そのうち書きますね(^∇^)
しかし、ウェイトをかけないといけないほどのスピードですね^^
すごい!
ソースコードはこちら。
10 CLEAR 300,&HCFFF
20 SCREEN1
30 KEY OFF
40 'MACHINE CODE WO RAM HE
50 FOR I=&HD000 TO &HD0A3
60 READ D$
70 DT=VAL("&H"+D$)
80 POKE I,DT
90 NEXT
100 'MAIN
110 'X,Y ZAHYOU
120 POKE &HD800,1
130 POKE &HD801,1
140 LOCATE 0,0:PRINT "*"
150 DEFUSR=&HD000
160 A=USR(0)
170 END
1000 DATACD,B7,00,D8,3E,00,CD,D5
1010 DATA00,2A,00,D8,B7,28,F1,FE
1020 DATA08,20,08,CD,6B,D0,CD,5F
1030 DATAD0,18,E5,FE,07,20,05,CD
1040 DATA6B,D0,18,DC,FE,06,20,08
1050 DATACD,6B,D0,CD,77,D0,18,D0
1060 DATAFE,05,20,05,CD,77,D0,18
1070 DATAC7,FE,04,20,08,CD,77,D0
1080 DATACD,83,D0,18,BB,FE,03,20
1090 DATA05,CD,83,D0,18,B2,FE,02
1100 DATA20,08,CD,83,D0,CD,5F,D0
1110 DATA18,A6,CD,5F,D0,18,A1,7D
1120 DATAFE,01,C8,CD,8F,D0,2D,CD
1130 DATA98,D0,C9,7C,FE,01,C8,CD
1140 DATA8F,D0,25,CD,98,D0,C9,7D
1150 DATAFE,17,C8,CD,8F,D0,2C,CD
1160 DATA98,D0,C9,7C,FE,28,C8,CD
1170 DATA8F,D0,24,CD,98,D0,C9,CD
1180 DATAC6,00,3E,20,CD,A2,00,C9
1190 DATACD,C6,00,3E,2A,CD,A2,00
1200 DATA22,00,D8,C9
次回はアセンブラを使ってみたいと思います。
twitterのフォロワーさんによると、
pasmoがいいのかなぁ^^
winもmacも使えるみたいだし。
(僕は開発はおもにMacを使っております。)
では〜。