MSX2グラフィックZ80プログラミング講座 -HI- 

グラフィックツールを堅く考えることはない、グラフィックの道具になればいいと思う。
インターフェイスを覚えるより必要なモノだけを作る。プロらしい手法…

去年の11月までEX講座をやっていました。今年は少しハイレベルなHI講座をひらいて
MSX2パソコンのグラフィックを解説していきます。

MSX-DOS(2)から グラフィックを使う。CALSLT
VRAMのアドレス操作、 スロット指定、ほぉじゃぁでBIOS解析、新BIOS
BASICリストのプロテ クト、文字の入出力、SHEM、算術演算シフト、条件分岐
PABLICと EXTRN、DEの拡張プログラム、スプライトの設定、表示、移動

第5回 VRAMのアドレス操作をマスターする

前回はMSX-DOS(2)でとりあえず、やってみました。
実行すると画面を白で描いて、SCREEN1になるまで数秒かかっています。
これはアドレスの指定がうまくいっていないところでした。

VRAMのアドレスはSCREEN5は1バイト、2ドット構成です。
例えば1Fhであれば黒と白というコードになります。
ですから、256の半分の128で1ラインで212ラインが全画面です。

MSXBASICでマシン語を想定してやってみましょう。
パターンネームテーブルの一例を考えましょう。
これを計算すると? HEX$(128*212)とすればVRAMのエリアがわかります。
そうしなくてもVRAMマップでわかりますけどね。
これをXとYにしてみるとBASICでは

10 COLOR15,1,0:SCREEN5
20 PSET(100,100),8
30 PSET(150,100),8
40 I$=INPUT$(1)

例えばX=100:Y=100からX=150:Y=100では
128*100+50から128*100+75となります。これをHEX$にすればよいですね。
試しにVPOKEしてみてください。

50 DEFFNY=128*100
60 A=(100/2)+FNY
70 VPOKE A,15
80 A=(150/2)+FNY
90 VPOKE A,15
100 I$=INPUT$(1)


少しわかりやすくDEFFN(デファインファンクション)を使って略しました。
少したりないかもしれませんが、このように重なった?と、思います。
この間に線を引く場合はBCに最初のAから算出したアドレス値、
DEに次のAのアドレス値に書き換えればよいです。

100 COLOR15,1,0:SCREEN5
110 PSET(100,100),8
120 PSET(150,100),8
130 I$=INPUT$(1)
140 DEFFNY=128*100
150 A1=(100/2)+FNY
160 VPOKE A1,15
170 A2=(150/2)+FNY
180 VPOKE A2,15
190 I$=INPUT$(1)
200 SCREEN0
210 PRINT"BC:";HEX$(A1)
220 PRINT"DE:";HEX$(A2)

これでレジスタ値がわかります。
次回はスロット指定をしてインタースロットコールをマスターします。
MSX-DOSにBIOSコールを入れてしまおうという話のはじまりです。
テクニカルハンドブックの内容でいきますので、かなりテクニカルです。

第6回 スロット指定のしかた

とにかく、マシン語はテクニカルでどう使おうか考えてしまいます。
正しく動作すればいいのですが、当時は高校生でしたから^^;
前回はその一例でBASICで調べる方法でした。
これまでのことを確認するとBIOSをCALSLTすると動作が重いので
CALST先のプログラムを持ってくるための準備をします。
今度はバイナリから算出するプログラムです。
これもビットの意味がわからないと困ったモンです。
MSXテクニカルブックでビット指定(0〜3)とはどういうことでしょうか?
これはバイナリに置き換えると00,01,10,11となります。
ですから、2バイトで表現して指定をします。
例えば83ってよくききませんか?これは
? BIN$(&H83)
10000011
となります。ビットは0〜7ビットあり
MSB 7 6 5 4 3 2 1 0 LSB
となっています。7ビット目が1で拡張スロット1、
次が1ビットと0ビットが11で基本スロット3
ということになります。
これは基本スロット3番の拡張スロット1の0を指定ということです。
間違いなく裏RAMを指定ということのようです。

基本スロットはMSXBASICが起動するとスロット0、
BIOSが入っているROMのエリアです。
ROMカートリッジ1でスロット1、ROMカートリッジ2でスロット2
スロット3が拡張スロットで

#3-0がMSX-DOS(DRAM)、#3-1がサブROMのBIOS(0000-4000h)、
MSXBASICはMAINがスロット0
SUBが#3-0のDRAM8000h以降でMSXの16KBならば8000h〜C000hとなる。
なお、MAINとかSUBとはウチのマシン語の別ページ参照。

これからは山登りの始まりです。
でも、成功すれば尾瀬に着いたようにMSXの視野がぐっと広がるでしょう。
私もここからが勝負と思います。
次回はBIOS部分をスロット指定して逆アセンブラしてみます。

第7回 ほぉじゃあからファイル出力をする

当時は逆アセンブラをプリントアウトしてコーティングしていました。
MSXプリンタがなくなっている現在では従来の方法ではできません。
逆アセンブラしたプログラムをファイル出力できないか、
さがしてみました。ほぉじゃあがありました。
ここで欲しいのはVRAMの読み書きです。
0174Hと0177Hです。CALLからRETまでです。
MAINのROMですから、スロット指定の数値は0です。

VRAMの読む場合を例にしてみましょう。

A>HOJA VRMR.ASM -S0174 -E0177 -SL0 -R

とするとJP 07E9になっています。
07E9hへ飛びます。これからがメイン部ですね。
このように変えます。

A>HOJA VRMR.ASM -S07E9 -SL0 -R

ENDまで出力されるようです。
このようにJPとかCALLとかのジャンプ命令で
指定を変えながら出力します。

逆アセンブラをする場合もこのようにして、
プログラムを調べていきます。
「ほぉじゃあ」はいろいろなオプションがあってとても助かります。
ファイルを表示すると自動で仮ラベル、アドレスがコメントとして
組んでいるので解析もかなりラクにできました。

第8回 BIOSのVRAMの読み書きを解析する

BIOSはプログラムを変えることはできません。
MSXパソコンは正しく数値をいれなければいけないルールになっています。
VRAMとCPU間の通信ですね。
VRAMのデータ読み込みはCPUからVDP(V9938)にデータを送って、
VRAMアドレスのデータを受けたりします。
そこでBIOSのプログラム保持して参照することにしてみます。

MSXのI/Oマップを見てみます。
98H:VRAMアクセス
99H:コマンドレジスタアクセス
9AH:パレットレジスタアクセス(ライトのみ)
9BH:レジスタ間接指定(ライトのみ)

アクセスするにはOUT,INのコマンドを使っています。

-READ-
0174 JP 07E9

07E9 CALL 06C5
07F0 RET

06C5 PUSH BC
06C6 PUSH DE
06C7 PUSH HL
06CD CALL NZ,068FH
06EB RET

-WRITE-
0177 JP 0769

0769 PUSH AF
076A CALL 06B3H 
076D EX     (SP),HL
076E EX     (SP),HL
076F POP AF
0770 OUT (098H),A
0772 RET

06B3 PUSH BC
06B4 PUSH DE
06B5 PUSH HL
06BB CALL NZ,068FH
06C3 JR 06D3
06D3 PUSH AF 
06EB RET

-ACCESS-
068F EX DE,HL
06A5 RET

疲れました。コーヒーでも飲んで、ひと休みします。

第9回 MSX-DOSにVRAMの読み書きを加える

前回のプログラムを加えてVRM_RとVRM_Wとして新BIOS(おい)
にします。ただ、新BIOSはBIOSの話と識別するために使うものです。
新BIOSは一回一回のBIOSのスロットコールがないので、
連続したVRAMの読み書きに効果があり、
プログラムによってアドレスを変えることができます。
これからはCALL VRM_R、CALL VRM_Wができます。

;MSX-GRAPHIC TEST PROGRAM
        PUSH IX
        PUSH IY
;SCREEN5
        LD   A,5
        LD   IX,005Fh
        CALL I_BIOS

        LD  BC,00000h
        LD  DE,06A00h
        LD   H,B
        LD   L,C
;VRAM_ON
        LD  IX,0171h
        CALL I_BIOS
LOOP:

;VRAM_WRITE
        LD   A,0FFh 
       CALL VRM_W
       
;ADR+1
        INC  HL
        LD   A,H
        CP   D
        JP   Z,ADRCLK
        JP   LOOP
ADRCLK:
        LD   A,L
        CP   E
        JP   Z,P_END
        JP   LOOP
P_END:
        POP  IX
        POP  IY
;SCREEN1
        LD   A,1
        LD   IX,005Fh
        CALL I_BIOS
    RET

;InterSlotCall_BIOS
I_BIOS:
        LD   IY,(0FCC0H)
        CALL 001Ch
        RET      
;New_BIOS

VRM_R:
    CALL    VRM_R1
    RET

VRM_W:
    PUSH    AF
    CALL    VRM_W1
    EX    (SP),HL
    EX    (SP),HL
    POP    AF
    OUT    (098H),A
    RET
 
以降のサブルーチンのWRM_ACは新BIOSです。
プログラムが長いので実行ファイルの変換に
若干時間がかかるようになりましたが、
CALSLTが読み書きには不要になって前回よりは速くなりました。
まだモードの切り替えにはCALSLTは使います。
うまくできました。この方法をMSX-DOSで使っていきます。

このようにROMにあるBIOSプログラムを
MSX-DOS(2)の64KBのDRAMに再配置できることがわかりました。
これでアセンブラでラベル定義をVRAMに割り当てていたプログラムで
実行することができなかったVRAMを操作するプログラムが
M80を使えばできるようになります。
これでグラフィック、スプライトはもちろんできますね。(*^_^*)

今回はメールの回答から作っていきました。
これでほとんどMSXのFAQがわかってきたと思います。
次回はMSXBASICにカンタンなプロテクトをかけて
プログラムの書き換えができないようにしてみます。

第10回 プログラムにプロテクトをかける 次へ