ニャオニャオ21世紀

レトロゲーム(MSX、PCエンジン、セガサターン)と、MSXぽいアプリ開発と、最新ゲーム(PS4、SWITCH)、身体(身体意識など)、ライフハックほか雑記を綴っています

MSXマシン語入門(Z80 アセンブラ・機械語) 第31回 カーソルキーで自由自在に動かす!! 勉強レポート 






今回はカーソルキーの入力です。

やっとゲームらしくなってきました^^

 

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 CD6BD            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         

                ↑   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+マシン語でやっています。

 

サンプルの実行(WebMSX)

ダウンロード

 

おお!超高速移動!

マシン語すごいなぁ(〃ω〃)

 

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を使っております。)

 

では〜。

 

www.nyaonyao21.com

 


「ニャオニャオ21世紀は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」

当サイトは第三者配信の広告サービス「Google Adsense グーグルアドセンス」を利用しています。 広告配信事業者は、ユーザーの興味に応じた広告を表示するためにCookie(クッキー)を使用することがあります。 Cookie(クッキー)を無効にする設定およびGoogleアドセンスに関する詳細は「広告 – ポリシーと規約 – Google」をご覧ください