SSブログ

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

のんびりと日がな一日横になっているという王様生活も、病気ゆえという事情であり、いつまでも続くことは良いことでない。明日は元気に歩き回り仕事ができるようでありたい。そのために今あえて足に負担をかけないように横になっているのだから。

今日の分のコード解析はここまでとしよう。もし明日元気になっていたら私は働くから、この続きはUPできない。



コードセグメントのアドレス0026Hから0038Hまでの命令
サブルーチン4306Hから戻ってきたメインルーチン。
最終的にサブルーチン6629Hへ飛ぶ(初回)まで。

MOV AX,0000
INT 33
CMP AX,FFFF
JZ 0036
マウスの初期化をし、マウスを使用できる環境ならば0036Hへ飛べ
(マウスの初期化はすでにサブルーチン4306Hで済んでいるので、ここではマウスを使用できる環境かどうか調べているだけ。)

MOV AX,0000
JMP 43B1

0036: ;JZのラベルはここ
CALL 6629
6629Hへ行ってこい




コードセグメントのアドレス6629Hから663DHまでの命令
メインルーチンから飛んできたサブルーチン。
最終的にメインルーチンへ戻るまで。

MOV AH,09
LEA DX,[3B50]
INT 21
LEA DX,[3B55]
INT 21
LEA DX,[3B5B]
INT 21
DOSの文字列の表示コマンドを使って画面にエスケープシーケンスを送る
(ESC) [2J テキスト画面全消去
(ESC) [>5h カーソル非表示
(ESC) [>1h システム行非表示

RET
メインルーチンへ戻る




コードセグメントのアドレス0039Hから00AAHまでの命令
サブルーチン6629Hから戻ってきたメインルーチン。
最終的にサブルーチン663EHへ飛ぶまで。

MOV AH 0C
INT 18
テキスト画面用GDCに表示開始要求を行う

CALL 6629
DOSコマンドによるテキスト画面消去。サブルーチン6629Hへはほんの少し前にも飛んでいる。詳細はそちらを参照。
(なぜサブルーチン6629Hを2回実行する必要があるのか?)

MOV AH,41
INT 18
グラフィック画面の表示停止

MOV AX,0002
INT 33
マウスポインタを非表示

MOV AL,4B
OUT A2,AL
MOV AL,01
OUT A0,AL
グラフィックGDCにCSRFORMコマンドを送り、1行2ラインに変更する

MOV AX,0012
MOV BX,000F
INT 33
カーソル表示画面(プレーン)の設定か?

MOV AH,41
INT 18
グラフィック画面の表示停止

MOV WORD PTR[0002],0000
データセグメントのオフセット0002Hから2バイトに0000Hを入れる

MOV AX,[16E4]
ADD AX,[16E0]
ADD AX,[16E6]
ADD AX,[16DC]
ADD AX,[16DE]
XOR DX,DX
MOV BX,0005
DIV BX
MOV [1138],AL
データセグメントのオフセット16E4Hから2バイトの値に、オフセット16E0Hから2バイト、オフセット16E6Hから2バイト、オフセット16DCHから2バイト、オフセット16DEHから2バイトの値をすべて足し、それを5で割る。その商の下位1バイトをデータセグメントのオフセット1138Hに入れる

LEA SI,[0004]
ADD SI,1130
SIにアドレスとして0004Hを入れ、それに1130Hを足す
(もしもLEAでなくMOVならば、[0004]はデータセグメントのオフセット0004Hから2バイトの中身になる。でもここはLEAだから、[0004]は0004Hそのものを意味するはずだ。それならなぜ後から1130Hを足すというまどろっこしいことをする?)

LEA DI,[12C6]
ADD DI,+22
DIにアドレスとして12C6Hを入れ、それに22Hを足す

MOV CX,0006
0092: ;LOOPのラベルはここ
MOV AL,[SI]
XOR AH,AH
MOV [DI],AX
ADD SI,+01
ADD DI,+02
LOOP 0092
データセグメントのアドレス[SI]から1バイトを取り出してアドレス[DI]に入れ、次のアドレスには00Hを入れる。それをSIとDIをインクリメントしつつ6回繰り返す。最終的に元の[DI]から12バイトが変更されることになる。

MOV AH,41
INT 18
グラフィック画面の表示停止
(さっきからメインルーチンの中で同じ命令が3回目だ。さすがに無駄としか思えない。納期に急がされて以前のコードをチェックする暇がなかったのか?)

XOR AX,AX
OUT A6,AL
グラフィックVRAM描画画面0を選択する

CALL 663E
663EHへ行ってこい




コードセグメントのアドレス663EHから6664Hまでの命令
メインルーチンから飛んできたサブルーチン。
最終的にメインルーチンへ戻るまで。

MOV AL,80
OUT 7C,AL
MOV AL,00
OUT 7E,AL
MOV AL,00
OUT 7E,AL
MOV AL,00
OUT 7E,AL
MOV AL,00
OUT 7E,AL
GRCGを有効にする、CPUのVRAMリード時TCRモード、ライト時TDWモード、全プレーン有効
4つすべてのタイルレジスタに00Hを設定

CLD
MOV AX,A800
MOV ES,AX
XOR DI,DI
MOV CX,3E80
665D: ;LOOPのラベルはここ
STOSW
LOOP 665D
GRCGを使って4プレーン同時にタイルレジスタの値を書き込む
書き込む領域は画面全体(横640ピクセル×縦400ピクセル÷一回の書き込み分16=3E80H)

MOV AL,00
OUT 7C,AL
GRCGを無効にする

RET
メインルーチンへ戻る




コードセグメントのアドレス00ABHから00CAHまでの命令
サブルーチン663EHから戻ってきたメインルーチン。
最終的にサブルーチン98D0Hへ飛ぶまで。

XOR AX,AX
OUT A4,AL
グラフィックVRAM表示画面0を選択する

MOV AL,4B
OUT A2,AL
MOV AL,00
OUT A0,AL
グラフィックGDCにCSRFORMコマンドを送り、1行1ラインに設定する

LEA SI,[374B]
MOV CX,0010
SIにアドレスとして374BHを入れ、CXに0010Hを入れる

CALL 441C
441CHへ行ってこい

サブルーチン441CHは前に出てきた。DS:SIから格納されているパレットデータを使ってCX個のパレットを設定するルーチン。SIとCXの値も前回と同じ。

MOV AH,40
INT 18
グラフィック画面を表示する

MOV AX,000A
AXに000AHを入れ

CALL 98D0
98D0Hへ行ってこい

コメント(0) 

コメント 0

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