圧縮ロードデータフォーマット


マニュアルの目次に戻る


 ブートローダのLDCMコマンドの圧縮データ形式の説明です。

基本的な考え方

 基本的には、データ列を順に見て行って、以前と同じパターンが現れたらその部分をコピーする、というやり方です。たとえば、

番地

0

1

2

3

4

5

6

7

8

9

10

11

12

13

データ

















というデータ列があったとします。0番地から5バイトと7番地から5バイトには同じ「ABCDE」というパターンがあります。この場合、7番地から5バイトはバカ正直に記述せずに、「7バイト戻った番地から5バイトコピーしなさい」と書いても復元可能です。従ってこのデータ列は

	ABCDEFG[copy-7,5]HI

のように表現できます。また、

番地

0

1

2

3

4

5

6

7

8

9

10

11

12

データ
















のようなデータ列の場合、5番地からのデータは、2バイト戻って6バイトコピーすれば、いわゆる「自己増殖コピー」効果により、パターン「DE」がくり返し複写されます。このデータ列は

	ABCDE[copy-2,6]FG

と表現できます。この [copy-x,y] というのをうまい具合に短いコードで表現すればデータを圧縮することができます。

実際のデータ形式

 データは、基本的にバイナリデータをそのまま書いていくのですが、データ中に以前のデータからコピー可能なパターンがあった場合、以下のようなコードに変換されます。

ショートコピーコード

0E7H xx

ロングコピーコード

0F7H yy zz


 ショートコピーコードは2バイトです。まず16進数の 0E7H があり、そのあとの1バイト xx の値は

	(コピーするバイト数−1)*32+戻るバイト数−1

です。この形式では最大32バイト戻ることができ、最大8バイトコピー可能です。

 ロングコピーコードは3バイトです。まず16進数の 0F7H があり、そのあとの2バイト値 yy zz の値は、

	(コピーするバイト数−1)*1024+戻るバイト数−1

です。この形式では最大1024バイト戻ることができ、最大64バイトコピーできます。なお、この yy zz のバイト順は「モトローラ方式」で、yy が上位です。

 ところで、データ列中に始めから 0E7H とか 0F7H とかいったデータが含まれる場合も当然あり得ます。それをコピーコードと誤認してはいけないので、データ列中に 0E7H、0F7H が含まれている場合、

	0E7H → 0E7H 000H
	0F7H → 0F7H 000H

と変換します。圧縮データの展開時には、0E7H または 0F7H に続く1バイトが0だった場合、それはコピーコードではなく 0E7H、0F7H そのものを表すと解釈します。

 データ中に 0E7H、0F7H が多く含まれている場合、かえってデータが大きくなる可能性もあるわけですが、一応出現頻度の低い値、ということでこの値を選びました。実際今まで私が作ったH8用プログラムで調べた限りでは出現頻度はかなり低いです。

 H8の命令コードとしてみると 0E7H は AND.B #xx,R7H、0F7H は MOV.B #xx,R7H です。R7はスタックポインタですから、普通のプログラムではこんな命令を実行することはまずありえません。純粋なデータとしてみた場合にはなんともいえませんが、経験的にあまり出てこないデータだと思います。

コンプレッサ「H8COMP.COM」

 圧縮を行うには H8COMP.COM というプログラムをMSX−DOS上で実行します。H8COMP.COM は以下のような形式のファイルを出力します。なお、H8COMP.COM が出力するファイルの拡張子は .H8C です。

オフセット

意味

内容

0〜3

ファイルID

文字列"H8C\0"

4〜7

展開後のデータのサイズ

4バイト整数(下位バイトが先の、インテル方式)

8以降

データ本体

圧縮されたデータ本体



 実際にH8側にデータを送る場合、ファイルの先頭8バイトは送りません。オフセット4〜7の展開後のデータサイズがインテル方式なのも、それがMSX側で判断すべき情報だからです。

 それにしても、H8COMP はかなり時間がかかります。(^^;;; だれかオールマシン語版つくりませんか?