SSブログ

孤独へ向って突っ走れ (26)  [  PC-98x1(補完計画)]

ビットマップデータの展開ルーチンに到達した。しかし例の「ANDをとってORをとる」をやっていない。つまり、このままでは背景との重ね合わせができないはずだ。ということは、まだ先があるのかもしれない。現在解析進行中。

picファイルのヘッダ情報により、5つの条件分岐先へ振り分けられ、そこに展開ルーチンがある。簡単そうなルーチンから解析を始めたので、まだ日高総帥の著書にあったような実践的な圧縮展開ルーチンは出てきていない。

私が日高総帥の著書を処分してしまってから10年か20年が経っているはずだが、アセンブラに接していると本の内容が部分的に頭に蘇ってくる。良い本は人の血肉となって生き続けるという好例だ。たとえ本そのものは消滅してしまっても、その本は人の頭の中に在り続ける。




サブルーチンEF80H

この構造化されていないがゆえに複雑なルーチンは、巨大なLOOPでできている。
このLOOPは次回繰り返しの直前にDIに50H(=80) を足すことから考えて、グラフィックVRAMへの縦方向の描画ライン数と思われる。

MOV CX,CS:[EF02]
まずCXにコードセグメントのオフセットEF02Hからの2バイトを入れる。これが巨大なLOOPの回数となる。
(CS:[EF02]には呼び出し元のサブルーチンEF08Hで先ほどpicファイルを読み込んだ場所からオフセット2以降の2バイトを入れてある。グラフィックの縦ライン数と思われる。)

EF85: ;LOOPのラベルはここ
PUSH CX
PUSH DI
ここから巨大なLOOPが始まる。

LODSB
CMP AL,6F
JB EFB0②
JZ EFB4(②)
CMP AL,80
JB EFEB
CMP AL,90
JB EFD7
CMP AL,C0
JB EFB0②
CMP AL,D0
JB EFAD
JZ EFCE①
JMP Short EFB0②
LOOP内ではまずDS:SI(先ほどpicファイルを読み込んだ場所のオフセット8)の1バイトの値を調べ、5通りの条件分岐をする。

条件分岐先の各処理は先の方のアドレスに存在し、その処理が終わるとEFA3Hに飛んでくる。

EFA3: ;JMP Shortのラベルはここ
POP DI
POP CX
ADD DI,CS:[EF06]
CS:[EF06]には呼び出し元のサブルーチンEF08Hで50H(=80) が入れてあり、DIをグラフィックVRAM内の1ライン下に変更する。
LOOP EF85
巨大なLOOPをCX回繰り返したら、ループから抜けてサブルーチンが終わる。

RET




①条件分岐用のバイトがD0Hの場合。5つの分岐先の中でいちばん単純で、素直に指定横バイト数だけVRAMに書き込む。

EFCE: ;JZのラベルはここ
MOV CX,CS:[EF00]
REP MOVSB
JMP Short EFA3




②条件分岐用のバイトが6EH以下、90HからBFHまで、D1H以上の場合。この分岐へ来る条件は、値が小さかったり中間だったり大きかったり、色々な値に散在している。
この分岐先に来るデータには、同じ値のバイトが連続する場合に効果的なきわめて基本的な圧縮がかけられている。条件分岐用の1バイトの後は、(書き込むデータ1バイト)と(書き込む回数1バイト)の組み合わせが続く。ただし、同じ値のバイトが続かないデータだと、最悪で2倍のデータ量になる。圧縮の効果がある時だけ使うのだろう。
1行の最初の(書き込むデータ1バイト)が条件分岐用の1バイトでもあるので、他の条件分岐へ行くための値にはできない。

EFB0: ;JBふたつとJMP Shortのラベルはここ
DEC SI
JMP Short EFB7
SIが条件分岐用のバイトを指すように戻す。

EFB7: ;JMP Shortのラベルはここ
MOV DX,CS:[EF00]
指定横バイト数をDXに入れ、ループ開始。ただしこのループは単純なループではない。全体のDX回のループはJMP Short EFBCで構成している。その中で、(書き込むデータ1バイト)を(書き込む回数1バイト)の回数だけ書き込むのにLOOP EFC4を使う。

EFBC: ;JMP Shortのラベルはここ
LODSB
MOV CL,AL
LODSB
XCHG AL,CL
XOR CH,CH
(書き込むデータ1バイト)をALに入れる。
(書き込む回数1バイト)をCXに入れる。

EFC4: ;LOOPのラベルはここ
STOSB
DEC DX
JZ EFCC
LOOP EFC4
JMP Short EFBC
ALの値をCX回続けてグラフィックVRAMに書き込む。全体の書き込みバイト数がDXに達したらループを抜ける。

EFCC: ;JZのラベルはここ
JMP Short EFA3




追記
条件分岐用のバイトが6FHの場合。この分岐先は、ほとんど②の処理そのものだ。ただ冒頭の、「SIが条件分岐用のバイトを指すように戻す」処理だけを行わない。つまりこの分岐先に来た時は、1行の最初の(書き込むデータ1バイト)は条件分岐用のバイトの次。このフォーマットがあれば、最初の(書き込むデータ1バイト)に値の制約がある②は必要ないのだが、下位バージョン互換のためにコードを残したのか。それとも、すでに②のフォーマットで作ってしまったpicファイルをこのフォーマットに作り直す暇がなかったのか。それとも、②が使える時にこのフォーマットを使うと生じる1バイトの無駄を作りたくなかったのか。

EFB4: ;JZのラベルはここ
JMP Short EFB7

コメント(0) 

コメント 0

コメントの受付は締め切りました