MSXPenという、
MSX BASICとアセンブラの両方をテキスト画面に書けて、
隣のWebMSXで実行できるというサイトがあります。
そのサイトでマシン語が簡単に実行できます。
(前回の記事にMSXPenの書き方を書いています)
MSXマシン語入門(Z80 アセンブラ・機械語) 第32回 MSX PENでマシン語を書く!(使い方) 勉強レポート - ニャオニャオ21世紀
今回はスプライトをカーソルキーで動かすというのをやりました^^
ソースコードはこちら。
BASIC部分
10 CLEAR 300,&HCFFF
20 SCREEN1,2
30 KEY OFF
40 BLOAD"MOVE.BIN"
80 'SPRITE TEIGI======================
90 RESTORE 2000
100 S$=""
110 FOR I=0 TO31
120 READ DT$
130 S$=S$+CHR$(VAL("&H"+DT$))
140 NEXT
150 SPRITE$(0)=S$
1000 'MAIN
1010 'SPRITE HYOUJI
1020 PUT SPRITE 0,(1,1),15,0
1030 DEFUSR=&HD000
1040 A=USR(0)
1050 END
2000 'SPRITE DATA
2010 DATA00,00,A7,AF,BF,9F,9D,9D,9F,8F,87,80,E7,E1,86,00,00,00,F2,FA,FE,FC,DC,DC,FC,FF,FB,11,7B,CE,30,30
アセンブラ部分(マシン語部分)
BREAKX: EQU 0x00B7
GTSTCK: EQU 0x00D5
RDVRM: EQU 0x004A
WRTVRM: EQU 0x004D
KILBUF: EQU 0x0156
ORG 0xD000
START:
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JR Z,STCKLP
CP 8
JR NZ,STICK1
CALL MOVEL
CALL MOVEU
JP STCKLP
STICK1:
CP 7
JR NZ,STICK2
CALL MOVEL
JP STCKLP
STICK2:
CP 6
JR NZ,STICK3
CALL MOVEL
CALL MOVED
JR STCKLP
STICK3:
CP 5
JR NZ,STICK4
CALL MOVED
JP STCKLP
STICK4:
CP 4
JR NZ,STICK5
CALL MOVED
CALL MOVER
JP STCKLP
STICK5:
CP 3
JR NZ,STICK6
CALL MOVER
JP STCKLP
STICK6:
CP 2
JR NZ,STICK7
CALL MOVER
CALL MOVEU
JP STCKLP
STICK7:
CALL MOVEU
JP STCKLP
MOVEU:
CALL SPYGET
CP 1
RET Z
SUB 1
LD HL,1B00H
CALL WRTVRM
RET
MOVEL:
CALL SPXGET
CP 1
RET Z
SUB 1
LD HL,1B01H
CALL WRTVRM
RET
MOVED:
CALL SPYGET
CP 176
RET Z
ADD A,1
LD HL,1B00H
CALL WRTVRM
RET
MOVER:
CALL SPXGET
CP 240
RET Z
ADD A,1
LD HL,1B01H ;X座標
CALL WRTVRM
RET
SPYGET:
LD HL,0x1B00 ;Y座標
CALL RDVRM
RET
SPXGET:
LD HL,0x1B01
CALL RDVRM
RET
END START
( ; はコメントです)
アセンブラ部分の説明をします。
CALL BREAKX
RET C
LD A,0
これで、
CTRL + STOPを押されると
プログラムが止まります。
KILBUF: EQU 0x0156
は、BIOSでアドレスが、0156Hです。
キーのバッファをクリアします。
キーは、使い続けていくとデータが溜まっていき、
エラーとなってしまうので、クリアしてやります。
MOVEU:
CALL SPYGET
CP 1
RET Z
SUB 1
LD HL,1B00H
CALL WRTVRM
RET
MOVEUというラベルは、スプライトを上に動かすも処理です。
CALL SPYGETで
SPYGETというラベルを呼びます。
そのラベルは、スプライトY座標ゲットの意味です^^
SPYGETは、現在のスプライトのY座標取得します。
Y座標は、レジスタAに入ります。
(SPYGETはのちほど)
CP 1
RET Z
Y座標が1だったらRET(リターン)です。
SUB 1
Y座標が1でないなら、レジスタAから(Y座標が入っています)
−1します。
LD HL,1B00H
CALL WRTVRM
BIOSのWRTVRMを使うのですが、
WRTVRMは、VRAMのあるアドレスにAレジスタの値を書き込みます。
(VRAMの指定したアドレスに値を書き込みます)
その書き込むVRAMのアドレスは、
HLレジスタに入っているものをもってきます。
そのためCALLする前に、HLにアドレスを設定します。
ちなみにスプライト0の
Y座標は、アドレス1B00Hに、
X座標は、アドレス1B01Hに
入っています。
先ほど出てきたSPYGETというサブルーチンの説明をします。
SPYGET:
LD HL,0x1B00
CALL RDVRM
RET
RDVRMはBIOS命令で、
VRAMのあるアドレスからレジスタAに値を持ってきます。
(VRAMの指定したアドレスの値を読む)
VRAMのアドレスはHLに設定!
1B00Hは、スプライト0のY座標です。
SPXGET:
LD HL,0x1B01
CALL RDVRM
RET
RDVRMはBIOS命令で、
VRAMのあるアドレスからレジスタAに値を持ってきます。
こちらもVRAMのアドレスはHLに設定!
1B01Hは、スプライト0のX座標です。
(16進数は、0xをつけたり、Hをつけたりと色々な表現があるんですね^^)
スポンサーリンク
実際にこのプログラムを実行すると、
激速です( ・∇・)
BASICで作っていたハイドライド もどきに
組み込みたいですね〜。
あとは、マシン語で歩行アニメーションをさせたいです!