MSX




例題1 screen 1  
マシン語をはじめる前に、BASICで肩ならしをしましょう。
まず、お手持ちのMSXを起動させ、次のプログラムを打ち、実行させてください。

10 SCREEN 1
11 FOR X=8 TO 15
20 A=VPEEK(X)
30 PRINT BIN$(A)
40 NEXT X
0と1で、"月"という文字が浮かび上がってきましたね。
そうです。
これは、VDPのパターンジェネレーターテーブルの内容をビデオピーク文で、覗き見たわけです。
ピーピングトム


例題2 screen 1  
次に、MSXをリセットして、"月"と表示させてください。
出ましたか?
10 SCREEN 1
20 VPOKE 8,&B11111111
22 VPOKE 9,&B11111111
23 VPOKE 10,&B11111111
24 VPOKE 11,&B11111111
25 VPOKE 12,&B11111111
26 VPOKE 13,&B11111111
27 VPOKE 14,&B11111111
28 VPOKE 15,&B11111111
と、打ち込み、又、月と押してください。
あれれ、"■"とでましたね。
これは、MSXのVDPのパターンジェネレーターテーブルの内容を書き換えたからです。
パターンジェネレータテーブルとは、文字フォントのパターンを記憶させる部分で、これを、ビデオピーク
文で書き換えたわけです。
screen1のパターンジェネレータテーブルは、
VRAM上では、00000Hから、00800Hまでです。



例題3 screen 1  
さあ、例題2で、VPEEKでBASICのPRINTの文字出力機能の働きを強化しました。
(最も、PRINTには、画面への出力以外にも、BEEP等の機能が有りますが、ここではこれは無視して下さい。あくまで文字出力に関してだけ述べています。)
今度は、VPEEKを用いて、LOCATEの働きとPRINT文の働きを再現してみましょう。

10 SCREEN 1
20 FOR I=&H1800 TO &H1B00 STEP 33
30 VPOKE I,2
40 NEXT I
はい、"火"という文字が斜めに出てきましたね。
これは、SCREEN 1の、パターンネームテーブル(01800H〜01B00H)に"火"というデータを入力したからです。
ちなみに、30行でパターンネームテーブルに書き込むデータがここでは2ですが、1にすると、"月"となります。
ここで、パターンネームテーブルの説明をします。
パターンネームテーブルは、1バイトが画面上の1パターンを表しています。
つまり、VPOKE文のコンマの左の数字(番地)が画面のパターンの位置を表し、コンマの右の数字が、表出するパターンを表しているのです。
ここで、鋭い方はお気づきかと思いますが、LOCATEで表すY座標が0のX座標は、VPOKEでいう、アドレスの&H1800に加えることの、0〜31で、32以降になると、次の行に行きます。つまり、Y座標が1プラスされ、X座標が0になります。
ふう、とりあえず、例題3はこんな物かな。
まだHTMLになれていないのですが、使ってみると、結構、いい物ですね。
タグを張ってくれるエディター等も有るそうなので、今度利用してみようかなっと思いました。




例題4 screen 1  
さて、これまでの例題で、SCREEN 1の画面ってどうなっているの?
という疑問がかなり出てきたでしょう。
そこで、次は、VPEEKを用いて、画面全体を探ってみましょう。
とはいっても、やり方は、基本的に例題3と全く同じです。

10 SCREEN 1
20 FOR I=&H1800 TO &H1B00
30 PRINT VPEEK (I)
40 NEXT I
どうですか?32という数字が沢山出てきましたね。
後で、VPOKEで確かめてみると分かると思いますが、32というデータは、空白を表すみたいです。




例題5 screen 1  
 さあ、次は、いよいよ、MSXにおけるSCREEN 1フォント技術の中でも、典型的なアルゴリズム、太文字処理を紹介しましょう.
下のプログラムを走らせると、Aという文字が太くなります.
基本的に、この例題は、今までの例題のアプリケーションなので、今までの例題を踏まえて考えれば、容易に理解出来ます。
 まあ、1ヵ所、50行は、慣れていない人にはきついかもしれないので、念入りに解説します。


1 SCREEN 1
10 PRINT "a"
20 A=ASC("a")
30 FOR I=A TO A*8+7
40 J=VPEEK(I)
50 J=J OR J\2
60 VPOKE I,J
70 NEXT
 変数Jは、フォントの一ラインを表します。
 D\2によって、右に2ビットシフトします。
 例えば、
00001000
というラインだったとします。これを、右に2ビットシフトすると、
00000100
となります。さて、はじめのラインと、シフトさせたラインをロジカルオペレーション(論理演算子)ORを用いて、論理和をとることにします。
00001000
OR
00000100
結果
00001100
ほーら、文字が太くなったあ。あっはっはアアアヒイイイー
おっと失礼。かなり、本ホームページの主旨に添ってきたので、いってしまいました。



類題5


例題6 screen 1  
さて、例題5で、キャラクタコードと、VRAMの関係を、何の説明も無しに、プログラムを組んでしまいましたが、例題6で、その説明をしようと思います。
分かりやすいように、例題1を改良して作ってみました。
10 SCREEN 1
20 A=ASC("A")
30 FOR X=A*8 TO A*8+7
40 A=VPEEK(X)
60 PRINT BIN$(A)
70 NEXT X
つまり、キャラクタコードを8倍したものが、VRAMでの先頭番地である。
VRAMでは、10進数で言う、8番地分で、一つのフォントが出来ているので、先頭番地に7を足した物が、最後尾番地である。





例題7 DOS  
■アセンブラの種類■
さあて、これから、本格的にプログラムを組む為に、幾つか用意して欲しいツールが有ります。
僕は、主に、MSX-DOS TOOLSを用いて組んでいこうと思っているのですが、別のツールを使っている方の為に、幾つか工夫をしていこうと思います。
僕が、中学生の時は、部活でFM77シリーズを主に用いていたのですが、良いアセンブラが手に入らず、自分で、本に書いてあったBASICで出来ているアセンブラを改良して使っていました。
これは、アセンブリ言語を一行一行、翻訳していくというものだったので、出来たマシン語の命令を、マシン語モニタというツールでパソコンに打ち込まなければなりませんでした。
残念ながら、MSXにはこの機能は内蔵されていませんでした。
この様なアセンブラを、ラインアセンブラと呼びます。
ちなみに、これすら用いず、インストラクション表等を用い、手動でアセンブルを行なうことをハンドアセンブルと言います。
これに対し、MSX-DOS TOOLSに付いているような、優秀なアセンブラをディスクアセンブラと言い、いちいち紙に書き取ったりしなくて良いという訳です。
特殊な物には、或るパソコンで、別のパソコンのプログラムを作れるアセンブラを、クロスアセンブラと言います。
 では、手始めに、システムコール(ファンクションコールと呼ばれることもある)でプログラムを組んでみましょう。
.Z80

ASEG

ORG 0100H

LD E,41H
LD C,02H
CALL 00005H
RET

END

まず、上のソースファイルをアセンブルして下さい。
Eレジスタに入れた16進数は、出力する文字コードです。
色々試してみましょう。
Cレジスタに入れた16進数は、ファンクション番号と言います。
ここでは、02という、コンソール1文字出力の機能を有した番地を示しています。
これによって、Eレジスタに入れた、文字を出力したいなあと、妄想する訳です。
そして、最後に、00005H番地をコールすることにより、MSX-DOSの外部コマンドとして、実行されれると言う訳です。
ちなみに、システムコールを利用する際、普通は、ここの部分で,F37DHをコールすると、DISK BASICのマシン語部分として認識されます。
ここで、もうちょっと、詳しく、ソースを解説すると、はじめに.Z80と書きましたよね。
これによって、アセンブルしようとしているニーモニックが、Z80用も物ですよと、宣言している訳です。
何で、いちいちこんな事を書かなければならないのでしょうか?
実は、このM80というアセンブラ、8080 CPUのニーモニックもアセンブル出来るのです。
うっへえ高機能。
ちなみに、8080モードにする時は、.8080とします。
その後のASEGですが、これは、Absolute SEGmentの略で、絶対番地指定を表します。
これも、M80が高機能だから必要な物で、この場合は、アセンブルして出来たプログラムが、次のORG(ORiGin)命令で指定した、0100H番地から、プログラムを始めますよーという意味になります。
さて、これがどうして、M80が高機能だからという事になるのでしょう?
それは、M80では、実行番地を後で好きな所における機能が有るからです。
まあ、この場合、何も指定しなければ良いだけなので、一見、何でも無い機能のような気がしますが、実は、これによって、プログラミングの自由度は格段に上がります。
うーむ、マルチメディア。
このように、プログラムを任意のアドレスに置けるということを、リロケータブル(再配置可能)といいます。
さて、ORGについて、もっと補足しておくと、ここで指定した、実行開始番地の事を、ロケーション・カウンタと呼び、100Hは、今回のようにDOSコマンドを自作したり出来る、TPA(Transient Program Area)の先頭番地です。
PTAじゃないですよ。
TPAです。
さて、こんなに簡単に、文字を画面に出せるなんて、びっくりしたでしょう?
とはいっても、このIT時代に、そんなことで感動するなんて、おかしいぞ定さんと、又、部活の人達に言われそうです。
いいんですよ。
感動したんだから。
簡単にというのは、余計な処理を、パソコンが全部引き受けてくれたて、人間は、画面に文字を出したいという命令をシステムコールというアプリケーションソフトに出したと考えたからです。
勿論、システムコールは、文字を出すだけじゃないですよ。
もっといろんな機能が有ります。
ただし、使用に際して、一つだけ条件が有ります。
何でも、使用上の注意って奴は守らなくっちゃだめですよね。
システムコールを使うと、使っていないレジスターの内容は、破壊される事が有るということです。
今回は、短いプログラムでしたから、そんな心配はしなくて良かったのですが、長いプログラムだと、いろんなレジスタを使いますよね。
だから、そんなときは、システムコールを実行する前に、レジスタの内容は保存するようにしましょう。





例題8 screen 1  
この例題では、文字に色を付けます。
下のプログラム(MSXの半角平仮名は、他機種では出ないので、残念ながら一部化けています。)を実行してください。
まず、はじめのメニューにあるように、背景色と、前景色の色指定をします。
指定の色を打ち込み、リターンキーを押して下さい。
背景色、周辺色の色指定は、COLOR文と同じ様式です。
200行〜240行に有るように、変数IROの上位4ビットが前景色、下位4ビットが背景色を示しています。
10 SCREEN 1:COLOR 15,4,7
20 PRINT "0.苴髏"
30 PRINT "1.傴"
40 PRINT "2.鞣゙・
50 PRINT "3.ライト鞣゙・
60 PRINT "4.偸酎・
70 PRINT "5.ライト装"
80 PRINT "6.偸酎・
90 PRINT "7.陋゙蹄"
100 PRINT "8.走"
110 PRINT "9.ライト走"
120 PRINT "10.・
130 PRINT "11.ライト・
140 PRINT "12.偸挺葯・
150 PRINT "13.髣尢"
160 PRINT "14.齟"
170 PRINT "15.戔"
180 INPUT"齟剪恷・;B
190 INPUT"槲・鰈遏・F
200 B$=BIN$(B)
210 F$=BIN$(F)
220 FOR J=0 TO 3:IF LEN(B$)<4 THEN B$="0"+B$:NEXT J
230 FOR J=0 TO 3:IF LEN(B$)<4 THEN F$="0"+F$:NEXT J
240 IRO=VAL("&B"+F$+B$)
250 CLS
260 FOR I=0 TO 255
270 VPOKE I+&H1800,I
280 NEXT I
290 LOCATE 1,15
300 INPUT "俥・・・・狹翩气;A
310 VPOKE ASC("A")\8+A+&H2000,IRO
320 PRINT"褂沫ー・懊!"
330 K$=INKEY$:IF K$="" THEN 330
340 'B$="":F$="":IRO=0
350 GOTO 10
変数Aに数字を入れても、8文字分しかカラーコードを変えられませんね。
そうです。256文字あるうち、カラー指定は、8文字単位でしか変えることが出来ないのです。
8文字の指定するために、カラーテーブル(&H2020〜&H203Fまでの32バイト)は全部データで埋まります。
8文字を1ブロックと考えると、1ブロックの指定に、始めに書いたように、上位4ビット下位4ビットの8ビットつまり、1バイトが必要になります。
すると、32バイトしかないのだから、256文字の指定には、8文字単位でしか指定できないということです。




例題9 screen 1  
さて、ここまできて、MSXのSCREEN 1とは、8文字に二色しか使えないのかと興醒めする方もいると思います。
所が、えてして世の中には裏技という物が存在するものでありまして、SCREEN 1にも御多分にもれず裏技が存在するのです。
これが、有名な多色刷りです。
〜多色刷り〜
多色刷りは、SCREEN 1の特色である。
というのも、昔から、MSX・FANのファンダム等に、この技術が使われたゲームが掲載されてきたからである。
又、多色刷りを行わないと、8キャラクタに2色しか使えず、本当に文字に色がついているようにしか見えない。
所が、多色刷りでは、1ラインに2色を割り当てられ、ライン同士も独立して色を指定する事が出来るのである。
では、具体的に、多色刷りについて見てみよう、
SCREEN 1は、VRAM構造が、SCREEN 2と大変似通っている。
そこで、テキストを、SCREN 2のグラフィックの様にカラフルに修飾することができるのである。
具体的にどうすれば、多色刷りになるのかというと、SCREEN 1の状態で、BIOSの&H7Eを実行するだけで良い。

SETGRP
MAIN ROMの007EHにあるBIOSで、VDPのみをSCREEN 2(MSXDATAPACKでいう、GRAPHIC1モード)にする。






例題10 screen 1  
今回は、いよいよアセンブラでプログラムを組んでみます。
まず、お手持ちのアセンブラで下記のようなプログラムを組み、REIDAI10.BINとしてセーブして下さい。

D000 LD H,18H
D002 LD L,00H
D004 CALL 0171H
D007 LD A,01H
D009 CALL 0177H
D00C RET

ちなみに、ここで使われているBIOSは、

0171H
VDPにアドレスをセットして、書き込める状態にする。
0177H
HLで指定したVRAMにAに入れたデータを書き込む。

の二つです。
では、このマシン語プログラムを実行するBASICプログラムを作ります。
これは、サンプルプログラム集では、REIDAI10.BASというファイル名になっています。

10 SCREEN 1
20 DEFUSR0=&HD000
30 BLOAD"V.BIN"
40 W=USR0(1)
50 GOTO 50

結果は、画面左上に月と出ましたね?
これは、SCREEN 1のVRAMの&H1800番地がパターンネームテーブルの画面左上を指し、そこにパターンネームテーブルの月をあらわすデータ&H1が書き込まれたからです。




sound関連のページです。
私のもうひとつの顔です。
獨協医科大学メディカルエンジニアリング部のホームページです。




トップページへ

大学の方のメールアドレスです。

@nifty ID:CQJ05446