SSブログ

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

懐かしのCGウィンドウ

今夜はPC-98のキャラクタジェネレータからCGウィンドウを介して文字フォントを読み取る件だ。でもその前に私の足の怪我の報告をさせてほしい。

私の歳になると怪我の治りが遅い。毎日、前日よりもほんのわずかに良いような気がする。薄紙をはぐようにとは、よく言ったものだ。いまの状態がどんなかは、頭で思い巡らすよりも自分の無意識の行動を観察したほうがよくわかる。足の第1指が腫れている私は、相撲の蹲踞のような姿勢は怖くてできなかった。それが今朝、何も気にせずに蹲踞の形に爪先を曲げている自分がいた。ああ、昨日より良くなったんだなと私は思った。人間は、体が悪いうちは意識するまでもなく動きたくない。横になっていたい。ところが体が良くなると今度は無意識に動き回ろうとする。今日は久しぶりにPCの前に座った。そうしたら、今は蹲踞の形に爪先を曲げるのが怖くてできない。ああ、また悪くしたな、と私は思っている。

それでは本題、懐かしのCGウィンドウの話だ。この言葉を聞いて懐かしいと感じる方は、昔PC-9801でプログラミングをした人に違いない。私はすっかり忘れていたが、例の逆アセンブル結果の解析を進めていたら、今日それが出てきた。思い出して懐かしかった。CGウィンドウなどの情報は、BIOSの情報とは違ってあまり細かく公式公開されなかったと記憶している。だから存在は知っていても使い方はよくわからないというのが第一段階だった。でも世の中にはすごい人がいて、公式の公開データが足りない部分は自分で実験を重ねて補い、さらに、有り難いことにその結果を本にして出してくださった。私のような、後からゆっくりと追いかける人間は、その本を買って学び理解した。これが第二段階だった。

今日は私が解析中のテニステニス2から、CGウィンドウを介して文字フォントを取得する部分を出したい。ニーモニックを追いかけて行けばCGウィンドウの利用のしかたもしっかりわかる。(もはやPC-9801用のプログラミングをする機会はないので、実用目的でなくただ懐かしむのが目的という所が少し寂しいが。)




PUSH AX
MOV AL,0B
OUT 68,AL
POP AX
漢字アクセスモードをドットアクセスに変更(常時フォント読み出し可能、そのかわりにテキスト画面漢字表示不可;テキスト画面を使用せず、フォントを読み出してグラフィック画面に描画するためのモードと思われる)




この先はAHの値による条件分岐

PUSH AX
CMP AH,2C
JZ 9BA8
CMP AH,2D
JZ 9BA8
CMP AH,2E
JZ 9BA8
CMP AH,2F
JZ 9BA8
CMP AH,76
JZ 9BA8
CMP AH,79
JZ 9BA8
CMP AH,7A
JZ 9BA8
CMP AH,7B
JZ 9BA8
CMP AH,7C
JZ 9BA8
AHが2CH, 2DH, 2EH, 2FH, 76H, 79H, 7AH, 7BH, 7CHなら9BA8Hへ行け
(JISコードの第1バイトが2CHから2FHまでと76H以上の文字のフォントは、CGウィンドウの奇数アドレス からしか読み出せない。つまり全角文字の右半分と左半分を別々に読み出さなければならない。)

JMP Short 9C00
AHがそれ以外の値なら9C00Hへ行け




2つの条件分岐先が順に出てくる。それぞれの行数が多い

AHが2CH, 2DH, 2EH, 2FH, 76H, 79H, 7AH, 7BH, 7CHの場合はここへ来る

NOP
9BA8: ;たくさんのJZのラベルはここ

MOV AL,00
OUT A5,AL
全角文字フォントの右半分(のライン0)を読み出す指定
(もうひとつの条件分岐先にはこの部分はない)

POP AX
PUSH AX
SUB AX,2000
全角文字フォントを読み出す時はJISコードの第1バイトから20Hを引くことになっている

OUT A1,AL
読み出す全角文字フォントの文字コードの第2バイトを指定

XCHG AH,AL
今度は第1バイトがAL

OUT A3,AL
読み出す全角文字フォントの文字コードの第1バイトを指定

MOV AX,A400
MOV ES,AX
ESはA400H(このセグメントのメモリはCGウィンドウと呼ばれ、I/Oポートによる読み出しを省いてこのメモリから直接文字フォントを読み取ることができる)

MOV SI,0001
LEA DI,[48A1]
ここがもうひとつの条件分岐先と違う
SIは0001H、DIは48A1H

MOV CX,0010
9BC6: ;LOOPのラベルはここ
MOV AL,ES:[SI]
MOV [DI],AL
ADD SI,+02
ADD DI,+02
LOOP 9BC6
CGウィンドウからデータセグメントのバッファへフォントの右半分を転送する
(もうひとつの条件分岐先では左右2バイトを一度に転送する。)

ここからJMP Short 9C26でもうひとつの条件分岐先と合流するまでの処理は、もうひとつの条件分岐先にはない

MOV AL,20
OUT A5,AL
全角文字フォントの左半分(のライン0)を読み出す指定

POP AX
SUB AX,2000
全角文字フォントを読み出す時はJISコードの第1バイトから20Hを引くことになっている

OUT A1,AL
読み出す全角文字フォントの文字コードの第2バイトを指定

XCHG AH,AL
今度は第1バイトがAL

OUT A3,AL
読み出す全角文字フォントの文字コードの第1バイトを指定

MOV AX,A400
MOV ES,AX
ESはA400H(上記の通り、このアドレスはCGウィンドウ)

MOV SI,0001
LEA DI,[48A0]
SIは0001H、DIは48A0H

MOV CX,0010
9BF0: ;LOOPのラベルはここ
MOV AL,ES:[SI]
MOV [DI],AL
ADD SI,+02
ADD DI,+02
LOOP 9BF0
CGウィンドウからデータセグメントのバッファへフォントの左半分を転送する

JMP Short 9C26
NOP
もうひとつの条件分岐先と合流せよ




9C00: ;JMP Shortのラベルはここ
AHがそれ以外の値ならここへ来る

POP AX
SUB AX,2000
全角文字フォントを読み出す時はJISコードの第1バイトから20Hを引くことになっている

OUT A1,AL
読み出すフォントの文字コードの第2バイトを指定

XCHG AH,AL
今度は第1バイトがAL

OUT A3,AL
読み出すフォントの文字コードの第1バイトを指定

MOV AX,A400
MOV ES,AX
ESはA400H(このセグメントのメモリはCGウィンドウと呼ばれ、I/Oポートによる読み出しを省いてこのメモリから直接文字フォントを読み取ることができる)

MOV SI,0000
LEA DI,[48A0]
ここがもうひとつの条件分岐先と違う
SIは0000H、DIは48A0H

MOV CX,0010
9C19: ;LOOPのラベルはここ
MOV AX,ES:[SI]
MOV [DI],AX
ADD SI,+02
ADD DI,+02
LOOP 9C19
CGウィンドウからデータセグメントのバッファへ2*16バイトのフォントデータを転送する




9C26: ;JMP Shortのラベルはここ
ここで、2つの条件分岐先が合流する




ところで、PC-98についての貴重な情報
http://www.webtech.co.jp/company/doc/undocumented_mem/io_disp.txt
の中で、
I/Oポート 00A1h の所の解説に、

漢字フォントの場合はJISコードの第2バイトから 20hを減じたものを設定する。

となっている。でも上に挙げたコードでは第1バイトだけ20Hを引いているようだ。それに、私が若い頃に作ったCライブラリでも

#define jiscodeset(jiscode) (outp(0xa1,(unsigned)(jiscode)&0xff),\
(void)outp(0xa3,((unsigned)(jiscode)>>8)-0x20))

となっている。

コメント(0) 

コメント 0

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