付録というか蛇足 †
- ディスク版ローダの自作マシン語部分の解説は、内容的には重複する上に、枝葉の話で本筋から離れてもいけないので、ここにまとめて記載した。あとで思いついた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
【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つ。
- [CALL 513Ah]はディスクのファイル名のセット。 regHLにファイル名文字列の先頭文字( " ダブルコーテーションマーク)のアドレスをセットしてCALLするだけ。ファイル名の拡張子区切り「.」や最後の「”」は不要
- [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]にジャンプして、ディスク版ローダはその任務を終了する。