DOORmk2/(7)付録 のバックアップ(No.2)



付録というか蛇足

  • ディスク版ローダの自作マシン語部分の解説は、内容的には重複する上に、枝葉の話で本筋から離れてもいけないので、ここにまとめて記載した。あとで思いついたP6関連のTipsも書き留めていきたいと思う。
  • 基本的には、【disp_title】【start1】【start2】【start3】【start4】の5つである。
  • なお、逆アセンブルリストには NOP(00h) が多くて見苦しいが、これはハンド・ドアセンブルしているためで、後で修正や追加したりする時のダミーと言うことでご了解を。また、ラベルも付いていないので見にくいが、まぁ、よしなにご判読を(^^;)

【disp_Title】の解説

============================
【Disp_Title】&hC000-&hC08F
・グラフィックタイトル表示処理
 &hC000-&hC079:メインルーチン
 &hC080-&hC08F:ワークエリア
=============================
C000 010020 LD   BC,2000h
C003 0000000000 NOP
C008 2A80C0 LD   HL,(C080h)
C00B CD8DFE CALL FE8Dh
C00E 23 INC  HL
C00F 23 INC  HL
C010 2280C0 LD   (C080h),HL
C013 00 NOP
C014 2A82C0 LD   HL,(C082h)
C017 77 LD   (HL),A
C018 23 INC  HL
C019 23 INC  HL
C01A 2282C0 LD   (C082h),HL
C01D 000000 NOP
C020 2A84C0 LD   HL,(C084h)
C023 CD8DFE CALL FE8Dh
C026 23 INC  HL
C027 23 INC  HL
C028 2284C0 LD   (C084h),HL
C02B 00 NOP
C02C 2A86C0 LD   HL,(C086h)
C02F 77 LD   (HL),A
C030 23 INC  HL
C031 23 INC  HL
C032 2286C0 LD   (C086h),HL
C035 000000 NOP
C038 2A88C0 LD   HL,(C088h)
C03B CD8DFE CALL FE8Dh
C03E 2B DEC  HL
C03F 2B DEC  HL
C040 2288C0 LD   (C088h),HL
C043 00 NOP
C044 2A8AC0 LD   HL,(C08Ah)
C047 77 LD   (HL),A
C048 2B DEC  HL
C049 2B DEC  HL
C04A 228AC0 LD   (C08Ah),HL
C04D 000000 NOP
C050 2A8CC0 LD   HL,(C08Ch)
C053 CD8DFE CALL FE8Dh
C056 2B DEC  HL
C057 2B DEC  HL
C058 228CC0 LD   (C08Ch),HL
C05B 00 NOP
C05C 2A8EC0 LD   HL,(C08Eh)
C05F 77 LD   (HL),A
C060 2B DEC  HL
C061 2B DEC  HL
C062 228EC0 LD   (C08Eh),HL
C065 000000 NOP
C068 110002 LD   DE,0200h
C06B 1B DEC  DE
C06C 7A LD   A,D
C06D B3 OR   E
C06E C26BC0 JP   NZ,C06Bh
C071 00 NOP
C072 0B DEC  BC
C073 0B DEC  BC
C074 78 LD   A,B
C075 B1 OR   C
C076 C208C0 JP   NZ,C008h
C079 C9 RET
C080 0040000000600020
C088 FF5FFF1FFF7FFF3F 
  • これは、グラフィックタイトルを描画するルーチンである。いったんPage2(4000h-7FFFh)にロードしたデータを1バイトずつPage3(0000h~3FFFFh)に分散転送するもの。
  • regBCはカウンターとして使用している。初期値として2000h を格納。処理の最後に 減算処理を2回するので、実質1,000h回のループ処理であるが、4基点のデータ転送だから、トータル 4,000hバイトの処理となり、V-RAM容量と勘定が合うはず。
  • [C080h-C08Fh]は、転送元と転送先のGV-RAMアドレス値を管理するデータエリアとして使用
    C080h-C08Fh 16バイト分 (2バイト×4基点×元先)
     C000 0040:転送元基点① 4000h
     C002 0000:転送先基点① 0000h
     C004 0060:転送元基点② 6000h
     C006 2000:転送先基点② 2000h
    ------------------
     C008 FF5F:転送元基点③ 5FFFh
     C00A FF1F:転送先基点③ 1FFFh
     C00C FF7F:転送元基点④ 7FFFh
     C00E FF3F:転送先基点④ 3FFFh
  • [CALL FE8Dh] は、RAMで LD A,(HL) を行うBasicROM内サブルーチンである。Page2-3のアドレス領域(0000h-7FFFh)は、BasicROMとの重複するエリアであり、このエリアのメモリーデータを読み取る場合はRAM側であることを指示する必要がある。その指定を簡単に行うためにBasicルーチンを利用している。逆に、書き込む際は、無条件にRAM側になるため、処理は不要である。
  • 転送元アドレスの値をregAに読み込み、転送先アドレスに書き込んで、それぞれのアドレスアイアイを2バイトずつ加算(もしくは減算)して格納する。
  • C080h~ は描画スピードの調整するための処理である。4バイト分転送(描画)する度に、200回の減算処理ループをまわしている。ところで、これは何妙程度の時間稼ぎになっているのだろう?

【start1】の解説

  • 【start1】では、BasicROMを直接CALLする形で、BLOADと画面の切替処理を行っている。
    ============================
    【start1】&hE0A0-&hE0DF
    ・BasicROMを直接CALLして、BLOAD処理と画面の切替
     &hE0A0-&hE0BA:メインルーチン
     &hE0D0-&hE0EF:文字列(ファイル名データ格納エリア)
    ============================
    E0A0 21D0E0 LD   HL,E0D0h
    E0A3 CDC0E0 CALL E0C0h
    E0A6 0000 NOP
    E0A8 3E01 LD   A,01h
    E0AA CDED13 CALL 13EDh
    E0AD 21E0E0 LD   HL,E0E0h
    E0B0 CDC0E0 CALL E0C0h
    E0B3 3E02 LD   A,02h
    E0B5 CDED13 CALL 13EDh
    E0B8 C380E0 JP   E080h
    E0BB 0000000000 NOP
    E0C0 CD3A51 CALL 513Ah
    E0C3 DD360300 LD   (IX+3),00h
    E0C7 DD361901 LD   (IX+25),01h
    E0CB CD465F CALL 5F46h
    E0CE C9 RET
    -------------------
    E0D0   "DoorM3PRG"
    E0E0   "DoorM0CHR"
  • それぞれの詳細を説明する

BLOADのROM内ルーチン利用方法

  • BLOAD処理は、E090h~にサブルーチンとしてまとめてある。CALLするBasicROMは2つ。
    1. [CALL 513Ah]はディスクのファイル名のセット。 regHLにファイル名文字列の先頭文字( " ダブルコーテーションマーク)のアドレスをセットしてCALLするだけ。ファイル名の拡張子区切り「.」や最後の「”」は不要
    2. [CALL 5F46h]がBLOAD処理。主なパラメータは、
        (IX+3):BLOADフラグ 00h:Rオプションなし   (IX+25):BLOADフラグ 01h:アドレス指定なし

表示画面の切替にROM内ルーチン利用

  • [CALL 13EDh]でSCREEN第3パラメータ値を設定するもので、regA に設定値(パラメータ値-1)をセットして、CALLする。
  • すなわち、"DoorM0.PRG"のBLOAD中は、そのままPage3(グラフィック画面)を表示し、 "DoorM0.CHR"のBLOAD直前に、表示画面をPage2(テキスト)に切替えている。
  • 2つのファイルをBLOADするが、後者はGV-RAM領域のロードされるので、その前にPage2(テキスト画面)に切り替えている。実は、ロード後に再度Page3に切替えている。この時の表示画面は一部崩れているのだが、ほぼ瞬時にメインプログラム起動まで進むので、見た目は全く問題ない。

【start2】の解説

============================
 【start2】&hE080-&hE09C
 ・BasicROMを直接CALLして、BGM停止
============================
E080 CD90E0 CALL E090h
E083 CDB31B CALL 1BB3h
E086 0000 NOP
E088 C300E0 JP   E000h
E08B 0000000000 NOP
E090 F3 DI
E091 3E74 LD   A,74h
E093 3206FA LD   (FA06h),A
E096 3E0F LD   A,0Fh
E098 3207FA LD   (FA07h),A
E09B FB EI
E09C C9 RET
  • [FA00h-FA17h]はシステムのワークエリアで、割込み用テーブルがある。個々を直接操作しているが、実際はBasicROMのルーチンにリンクしている。
  • [FA06h:DEFW 0F74h]は、2msecタイマ割込みで、TIMEのカウントやカーソル点滅、PLAYの発生処理とあるが、詳細は不明。同じく[FA07h:DEFW] も?
  • [1BB3h]は、PLAY用のバッファをクリアし、PSGの音を止める
  • BGMを止めるための処理を記述したものだが、たぶん、オリジナルのIPLの処理をパクッたものだと思われる。

【start3】の解説

============================
【start3】&hE000-&hE041
・無敵化等のパッチ処理
============================
E000 F3 DI
E001 3EDD LD   A,DDh
E003 D3F0 OUT  (F0h),A
E005 D3F1 OUT  (F1h),A
E007 3E55 LD   A,55h
E009 D3F2 OUT  (F2h),A
E00B 3EFF LD   A,FFh
E00D ED47 LD   I,A
E00F 310000 LD   SP,0000h
E012 000000000000 NOP
E018 3E3D LD   A,3Dh
E01A 329B57 LD   (579Bh),A
E01D 000000 NOP
E020 3E23 LD   A,23h
E022 325757 LD   (5757h),A
E025 000000 NOP
E028 3E09 LD   A,09h
E02A 325957 LD   (5759h),A
E02D 000000 NOP
E030 3E23 LD   A,23h
E032 326257 LD   (5762h),A
E035 000000 NOP
E038 3E27 LD   A,27h
E03A 326F57 LD   (576Fh),A
E03D 000000 NOP
E040 C3004F JP   4F00h
  • 例によって、NOP(00h)が多いが、まず前半はポート操作によるメモリーブロックの指定。このあたりから、いよいよBasicROMとはおさらばだ。
  • [ポートF0h,F1h]は、メモリリード時のメモリブロック指定である。
      F0h 下位4bit 0000h-3FFFhを指定      上位4bit 4000h-7FFFhを指定   F1h 下位4bit 8000h-BFFFhを指定      上位4bit C000h-FFFFhを指定 値はすべて0Dhなので、RAM1(内部RAM)の指定となる
  • [ポートF2h]は、メモリライト時のメモリブロック指定   2bitごとにメモリ範囲を指定(0000h/4000h/8000h/C000h)   指定値は55h=01/01/01/01 すべてRAM1(内部RAM) つまり、READ&WRITEとも、ALL RAMで動作する形になる。
  • 後半は、無敵化のパッチデータ処理である。メインプログラム(”DooRM3.PRG")を全部で5個所書き換えるようになっている。ここに、セットされているデータはデフォルト値(非無敵化)だが、最初のBasicの隠しメニュー画面から、必要によりデータが書き換えられる。
  • 最後に、JP 4F00h でゲームスタートへの最終処理となる

【start4】の解説

============================
【start4】&h4F00-&h4F16
・"DoorM0.CHR"のデータをブロック転送
・画面モードの変更と割込み禁止処理
============================
4F00 F3        DI
4F01 21003C    LD   HL,2000h
4F04 110078    LD   DE,E000h
4F07 010030    LD   BC,1F00h
4F0A EDB0      LDIR
4F0C 3E08      LD   A,08h
4F0E D3C1      OUT  (C1h),A
4F10 3EC7      LD   A,C7h
4F12 D3F3      OUT  (F3h),A
4F14 C39D2A    JP   559Dh
  • まず、GV-RAMの2000h~に仮にロードしておいた”DoorM0.CHR"を、本来のアドレスE000h~に転送する。もう、BGMは停止したし、Basicシステムにも依存していない環境なので、問題はない。
  • [ポート C1h]は、CRTコントローラモードの設定で、08hで15色グラフィックモードを指定している。
  • [ポート F3h]は、割り込み処理の設定で、C7hで完全に割込み禁止となる。ゲームが始まったら最後、本体をリセットするしかなく手はなくなる。
  • メインプログラムのスタートアドレスである[559Dh]にジャンプして、ディスク版ローダはその任務を終了する。

トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   リンク元