ファミコン ディスクシステム
RAMアダプタに8KByteのROM(カスタムに内蔵) 32KByteのRAM($6000−$DFFF)、8KByteのキャラクタRAMのメモリを載せて クィックディスク(QD) ドライブ込みで15、000円はかなり安い。 またドライブは通信アダプタの底面にあるコネクタ(ロットによっては無くなっている)でも接続可能 RAM、拡張ポート テスト スタートキーとセレクトーキーを押しながらリセットすると実行されます このときにメインRAM$6000−$DFFFのチェック 次にPPU$0000−$1FFFをCPU RAM$C000−$DFFFに転送してチェックを行います もしこの時にエラーがあればOKと表示される所にエラーが出たアドレスが表示されます $0000−$1FFF PPUのアドレス $6000−$DFFF CPUのアドレス 拡張ポートのテストは左からBit0−Bit7の並びになっていて $4026で拡張ポートにデータを書き込み、$4033で拡張ポートのデータを読み込みます Cf=0にして$FFと左ローテイトで1つだけビットを0にして他は1にしてポートのチェックを行います ただしBit7のBATTRY_SENCEはモータを起動していない為0(電圧NG)になります IPLの種類 IPL ROMはファミコン用のRAM アダプターの旧、新バージョンの2つ ツインファミコンのデモでNintendoと出るのとFamicomとでるタイプの2つの計4つがあります IPLのバージョンの区別方法はIコントローラのスタートキーとセレクトーキーを押しながらリセットすると、 RAM、拡張ポート テスト画面になりますが、そのチェックの画面になる前に Iコントローラの右とAを押すとメッセージがでます。 このときDEV 2があれば新バージョンです。 数字が出ないのは旧バージョンです。 ツインファミコンの方は両方ともDEV 2なので新バージョンと同等で起動画面が違うだけのようです。 IPLのバージョンの違いによる不都合 若干ROMエントリのアドレスが変っていますので、そこの部分をコールされると動かない可能性がでます。 しかし実際に純正ソフトでは使わないようになっているようで、実際問題での不都合はありません。 非ライセンスソフトのDISK HACKER Ver1.0ではFCBのブロックが全て$FFだと 新バージョンではエラーがでます。(旧バージョンはそのままコピーが出来ます) バックアップ活用研究のDISK COPYではRAMアダプタのバージョンに合わせて変更して 対応しています。 IPLの起動 RAMアダプタを本体にセットして、電源を入れればデモが動きます。 ディスクがセットされればディスクロードするのですが基本はFCBの内容にしたがって ロード、メモリ$DDFCの内容(アドレス)をみてジャンプします。 NMI割り込み(エントリアドレスは$E18B) ワークエリアの$0100のBit7−6(NMIコード)を見てジャンプするようになっています。 NMIコード $00=RAM アダプタ用 $E18Bから$E19Dへ $40=ゲーム用0 JMP ($DFF6) $80=ゲーム用1 JMP ($DFF8) $C0=ゲーム用2 JMP ($DFFA) IRQ割り込み(エントリアドレスは$E1C7) ディスクのアクセスに使用されます。 ワークエリアの$0101のBit7−6(IRQコード)を見てジャンプするようになっています。 IRQコード $00−$3F=IRQコード分のディスク ロード スキップ *$40=ディスク1バイト転送(読み込みの場合A、Xにデータが読み込まれる、書き込みの場合Aレジスタにデータ) $80=ディスク・ステータスを読む $C0=JMP ($DFFE) *$40だけPC−下位、PC−上位、PSRを空読みしてRTSを実行します。($E7A3の割り込みのトラップから戻る為) リセット割り込み(エントリアドレスは$EE24) 電源を入れるとオートリセットが掛かるので電源を入れるかリセットを押すとココにジャンプします。 まずPPUの設定、その他のポートの設定、スタックの設定を行います 次にNMIコードを$C0、IRQコードを$80をセットします リセットコードがあり使用アドレスは$0102−$0103のリセットコードによって動作が変わります まず$0102が$35かをチェック$35でなければRAMアダプタのデモへ行きます。 $35なら$0103が$53か$ACかそれ以外のチェックを行いす $0102が$35以外ならRAMアダプタのデモへ行きます。 $0102が$35で$0103が$53なら、スクロールセットしてJMP ($DFFC) $0102が$35で$0103が$53でなく$ACなら$53にセット、スクロールセットしてJMP ($DFFC) $0102が$35で$0103が$53でなく$ACでなければRAMアダプタのデモ 電源を入れると本体RAMの内容が不確定なのを利用して $0102と$0103の内容が特定のデータかをチェックして 一番初めに起動したのかを判断しています。 次にリセットしたときにRAMアダプタの起動かゲームの再起動が任意に出来ます。 $0102、$0103のデータがリセットコード以外の値(電源をOn)ならデモンストレーションへ $0102が$35、$0103が$ACなら$0103:$53にしてゲームのリセットベクトルへ $0102が$35、$0103が$53ならゲームのリセットベクトルへ となります スクロールセットは$EAEAのサブルーチンコールを行いますので ゲームではポート$2005のセットは$00FC,$00FDと$EAEAのコールを行い ディスクシステムの基準に倣った方が良いです。
$4020:(出力) IRQ タイマー下位 $4021:(出力) IRQ タイマー上位 $4022:(出力) Bit2:1=タイマーカウント開始、0=タイマーカウント停止 $4023:(出力) 2C33 タイマーコントロール Bit1:サウウンドT/Oのアクセス 1=許可、0=禁止 Bit0:ディスク I/Oのアクセス 1=許可、0=禁止 $4024:(出力) ディスク ライトデータ(/WRITE_DATA) 1バイトのデータをシフトレジスタによって /WRITE_DATAにシリアルデータで転送されます $4023 Bit0=1 ディスクI/Oアクセス許可 $4025 Bit2=0 /WRITEGATE データ ライト $4030 Bit7=1 リード・ライト可能 の条件がそろってないと書き込めません $4025:(出力) ディスク コントロール Bit7:IRQデータ転送 1=実行する 、0=実行しない Bit6:CRCレジスタ 1=クリアする 、0=クリアしない Bit5:不明 1= 、0= Bit4:CRC−Hコントロール 1=行う 、0=行わない Bit3:スクロール 1=スクロール−V 、0=スクロール−H Bit2:/WRITEGATE 1=データ リード 、0=データ ライト Bit1:/MOTOR 1=モーターの回転停止、0=モーターの回転開始 Bit0:/RESET 1=リセットを行わない、リセットを行う 不明 ほとんど1になっている、CRC転送の実行? 0だとデータ転送が出来ない CRC−Hコントロールを行うと書き込みの場合 CRC−Hが$4024に転送され WaitでCRC−Hをディスクに書き込む? 読み込みの場合 次にロードした$4031のデータとCRC−Hの比較を行い 結果を$4030のBit4(同じなら0)に出力する? /RESETは転送タイミングのリセット $4026:(出力) バッテリーコントロール、背面の拡張I/Oライト Bit7:BATTRY_SENCE 1=オン、0=オフ Bit6:背面の拡張I/O Bit5:背面の拡張I/O Bit4:背面の拡張I/O Bit3:背面の拡張I/O Bit2:背面の拡張I/O Bit1:背面の拡張I/O Bit0:背面の拡張I/O $4030:(入力)ディスクI/O ステータス Bit7:ドライブの検知 1=リード・ライト可能、0=リード・ライト不可 Bit6:ヘッド の検知 1=最後まで移動した 、0=最後まで移動していない Bit5: Bit4:CRC−Hチェック 1=エラー有り 、0=エラー無し Bit3: Bit2: Bit1:シフトレジスタ転送 の検知 1=転送中 、0=転送終了 Bit0:IRQタイマ割り込みの検知 1=発生した 、0=発生していない CRCチェックはCRC−HとCRC上位として読み込んだデータが同じなら0になる? $4031:(入力) ディスク リードデータ(READ_DATA) READ_DATAから転送されたシリアルデータをシフトレジスタによって 1バイトのデータに変換されます $4023 Bit0=1 ディスクI/Oアクセス許可 $4025 Bit2=1 /WRITEGATE データ リード $4030 Bit7=1 リード・ライト可能 の条件がそろってないと読み込めません ???データを書き込んでいる場合(/WRITEGATE=0)はCRCの下位の値 $4032:(入力) ドライブ ステータス Bit7:不明 0 Bit6:不明 1 Bit5:不明 0 Bit4:不明 0 Bit3:不明 0 Bit2:/WRITE_PROTECT 1=カード書き込み禁止 、0=カード書き込み許可 Bit1:/READY 1=スタート位置 、0=内部に移動している Bit0:/MEDIA_SET 1=セットされていない 、0=セットされた Bit6はほとんど1になっている /WRITE_PROTECTはディスクカードのツメが折れていたら1、折れていなければ0 /READY はヘッドが一番外に移動し、内に移動し読み書きのが可能な時に0になる /MEDIA_SET はディスクカードがセットされていなければ1、セットされれば0 $4033:(入力) バッテリーステータス、背面の拡張I/Oリード Bit7:BATTRY_SENCE 1=電圧 OK、0=電圧 NG Bit6:背面の拡張I/O Bit5:背面の拡張I/O Bit4:背面の拡張I/O Bit3:背面の拡張I/O Bit2:背面の拡張I/O Bit1:背面の拡張I/O Bit0:背面の拡張I/O
ディスク フォーマットFCB部分 まず最初にブロック01、ブロック02が存在します ブロック01にそのディスクのゲーム名、両面ソフトでどの面か、青色のディスクか黄色のディスクか等の情報が入っています ブロック02はマウントファイル数が書き込まれています ファイル部分 ブロック03がファイル情報、ブロック04がデータになります ブロック03はファイルID、ファイル名、ロードアドレス等が書かれています ブロック04はバイナリデータになります 1つのファイルはブロック03と04の対となります。 ブロック コードの説明 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− GAP : $00 スタートデータ : 1バイト $80 ブロックコード : 1バイト $01 チェックコード : 14バイト *NINTENDO−HVC* メーカーコード : 1バイト ゲーム ネーム : 4バイト ゲーム バージョン : 1バイト ディスク サイド : 1バイト $00=A面、$01=B面 ディスクの順番(VOLUME) : 1バイト 2枚以上のソフトで使用 ディスクの種類 : 1バイト $00=FMC(ノーマル カード)、$01=FSC(シャッター付きカード) 予備1 : 1バイト コールドスタート : 1バイト 起動時に読み込む最大ロードナンバ 不明(予備) : 5バイト $FF、$FF、$FF、$FF、$FF 製造年月日 : 3バイト 国コード : 1バイト $49=日本 不明 : 1バイト $61 地域? 不明 : 1バイト $00 場所? 不明 : 2バイト $00、$02 不明(各ゲームの情報?) : 5バイト 書換えた年月日 : 3バイト 店頭販売の場合、製造年月日と同じ 不明 : 1バイト 不明 : 1バイト $80 書き込んだシステム? ディスクライターのナンバ : 2バイト 不明 : 1バイト $07 書換えた回数 : 1バイト 10進数で書かれている(00=店頭販売のディスク) 実際のディスク サイド : 1バイト $00=A面、$01=B面 不明 : 1バイト デバグバージョンまたは、プライス: 1バイト CRC : 2バイト ブロック コード$01は3つに分けられ $01−1 *NINTNDO−HVC* $01−2 ディスク アクセス用(メーカーコードからコールドスタート) $01−3 ディスク ライター用 になります $01−1はディスクシステムに必要なデータでこれが無いと起動すらできません $01−2はシステム自体の情報なります ディスクアクセスに必要なデータになります ゲーム ネームの最後の1バイトはイベント等を表し $20=通常のディスク $45=E イベント、ディスクファックスを使った全国トーナメント $52=R リダクション イン プライス(広告による値引き) コールドスタートは起動時に読み込む最大ロードナンバで一括でファイルを読み込みます $0Fの場合、ディスク内のロードナンバ$00〜$0Fまで全て読み $10以降のロードナンバは読み込みません $01−3は主にディスクライター用 プライスは値段や周辺機器の対応 書き換え回数が00の場合は販売用のディスクの値段となり $01=3400円 $03=3400円(とびだせ大作戦でメガネ同梱版と無しの両方) 01以上の場合は書き換えの値段 $00=500円 $01=600円 帰ってきたマリオブラザースの場合は500円で広告で100円引かれるので 書き換え料金は500円とされる −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− GAP : $00 スタートデータ : 1バイト $80 ブロックコード : 1バイト $02 マウントファイル数 : 1バイト 登録されているファイル数 CRC : 2バイト −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− GAP : $00 スタートデータ : 1バイト $80 ブロックコード : 1バイト $03 ファイルナンバ : 1バイト 一番最初のファイルを0として以降+1される ロードナンバ : 1バイト 一括ロードするためのナンバ ファイル ネーム : 8バイト アドレス : 2バイト 下位、上位の順 ファイルの長さ : 2バイト 下位、上位の順 ファイルの種類 : 1バイト 00=プログラム、01=キャラクタ、02=許諾ファイル CRC : 2バイト ファイルナンバは最初のファイルを$00で次のファイルは$01になり 書き込む場合に使用されます ロードナンバ は読み込むときに使用されるナンバで他のファイルにも同じナンバがある場合があります 同じナンバだと一度にロードする事が可能になります ブロックコード$01−2のコールドスタートではそのロードナンバ以下の値がロードされます 例えばコールドスタートが$0Fなら起動時に$00−$0Fまでの ロードナンバのファイルが一度にロードされ$10以降のファイルはロードされません −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− GAP : $00 スタートデータ : 1バイト $80 ブロックコード : 1バイト $04 プログラム : データ本体(ブロックコード$03の長さ分) CRC : 2バイト −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− テスト ファイル用 スタートデータ : 1バイト $80 ブロックコード : 1バイト $05 データ : 3バイト $6D、$B6、$DB : | : | 以降この3バイトのデータがディスクの最後まで続く : | CRC : 2バイト −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− CRCは16ビットでスタートデータからブロックの最後まで計算される まずデータとCRCレジスタを右シフトしてCRCレジスタ最下位が1なら CRCレジスタとXOR $8408を実行する これを8回(8ビット分)繰り返せば1バイトのCRC計算となる これを1ブロック分まで繰りかえす 書き込む場合 CRCレジスタのリセット=0 GAP $00を書き込む CRCレジスタのリセット=1 | |スタートデータ$80以降を書き込む | CRCデータ下位の書き込み CRCコントロール=1 CRCデータ上位の書き込み 読み込む場合 GAP $00を読み込む CRCレジスタのリセット=1 | |データを読み込む | CRCデータ下位の読み込む CRCコントロール=1 CRCデータ上位の読み込む ブロックコード$01の書き込み例 JSR $E64D ;Boot Disk Drive LDA $00FA AND #$2B STA $4025 LDA #$00 STA $4024 LDY #$C5 JSR $E153 LDY #$86 JSR $E153 LDA #$01 ;Write $00,$80,$01 JSR $E6B0 | | *NINTENDO−HVC*...のデータをJSR $E7A3で書き込む | JSR $E729 ;Write CRC
エラー ドライブ&ディスクセット関連 01:DISK SET ERR.01 ディスクが正しくセットされていない 02:BATTERY ERR.02 ディスクドライブの電圧が規定値以下になっている 03:WRITE PROTECT ERR.03 ライトプロテクトのツメが折れているのに書き込もうとした 04:GAME MAKER ERR.04 違ったメーカのディスクがセットされた 05:GAME NAME ERR.05 違ったゲームのディスクがセットされた 06:GAME VERSION ERR.06 違ったバージョンのディスクがセットされた 07:A.B.SIDE ERR 07 違ったサイドのディスク(表と裏)がセットされた 08:DISK NUMBER ERR.08 違った順番のディスクがセットされた 09:ERR.09 違ったディスクの種類がセットされた 10:ERR.10 違った予備1のデータがセットされた 08はROM内ではDISK NO. ERR.08として出力 11−19はディスクライター用? ファイルアクセス関連 20:DISK TROUBLE ERR.20 許諾画面のデータが読み込めない 21:DISK TROUBLE ERR.21 ブロックコード$01の*NINTENDO−HVC*が見つからない 22:DISK TROUBLE ERR.22 ブロックコード$01の開始マーク$01が見つからない 23:DISK TROUBLE ERR.23 ブロックコード$02の開始マーク$02が見つからない 24:DISK TROUBLE ERR.24 ブロックコード$03の開始マーク$03が見つからない 25:DISK TROUBLE ERR.25 ブロックコード$04の開始マーク$04が見つからない 26:DISK TROUBLE ERR.26 ディスクに正しく書き込みが出来ない 27:DISK TROUBLE ERR.27 CRCエラーを検出 28:DISK TROUBLE ERR.28 ディスクの読み込みでタイミングが合っていない(読み込み途中でヘッドが最後までいった) 29:DISK TROUBLE ERR.29 ディスクの書き込みでタイミングが合っていない(書き込み途中でヘッドが最後までいった) ユーザーセーブ関連 30:DISK TROUBLE ERR.30 ディスクに書き込みが出来なくなった(容量不足またはドライブプロテクトによる強制終了) 31:DISK TROUBLE ERR.31 ディスクのデータ数が合わない(書き込もうとしたマウントファイル数がマイナスになった) 35:DISK TROUBLE ERR.35 テスト ファイル(ブロックコード$05ファイル)の書き込み失敗 その他 40:DISK TROUBLE ERR.40 一括ロードをしたがロードで出来ていないファイルがあった(ファイルの数が合わない) 41:DISK TROUBLE ERR.41 不明(きね子IIの説明書にERR.41〜の表記あり) *DISK TROUBLE ERR.35以降はROMルーチンではなくソフトのルーチンでエラーの判断を行います
DISK ROM エントリ $E000:00 $E001−$E148:キャラクタデータ(文字) $E149:Wait $E153:nnミリ Wait 入力:Y=nnミリ 使用:X、Y Yミリ秒のウェイトをかけます ルーチン内で$0000をロード、コンペアの実行を行っていますが 時間稼ぎの為で内容の変更はありません 主にディスクアクセスのタイミングに使用 $E161:OBJ+BG Off 使用:A $00FE スプライトとBG画面を表示しません。 $E16B:OBJ+BG On 使用:A $00FE スプライトとBG画面を表示します。 $E171:OBJ Off 使用:A $00FE スプライトを表示しません。 $E178:OBJ On 使用:A $00FE スプライトを表示します。 $E17E:BG Off 使用:A $00FE BG画面を表示しません。 $E185:BG On 使用:A $00FE BG画面を表示します。 $E18B:NMIベクタ ディスク システムのNMIベクタです。 割り込みがかかったら$0100のBit7−6をみて、それぞれの処理を行ないます。 0100:11** ****で$DFFAの内容の所へジャンプ 0100:10** ****で$DFF8の内容の所へジャンプ 0100:01** ****で$DFF6の内容の所へジャンプ 0100:00** ****でRAMアダプタ内で処理(許諾画面表示中などで使用) $E1B2:NMIがかかるのを待ちます。 使用:$00FF まず、Aレジスタ、NMIコード($0100の内容)をスタックにセーブしてから NMIコード$00にしてNMIがかかるのを待ちます NMIがかかるとセーブしたNMIコード、Aレジスタを元に戻るようになっています $E1C7:IRQベクタ 入力:$0101=IRQコード 出力:IRQコードによって異なる ディスク システムのIRQです。 割り込みがかかったら$0101のBit7−6をみて、それぞれの処理を行ないます。 0101:11** **** $DFFEの内容の所へジャンプ 0101:10** **** $4030(ディスクI/Oステータス)を読んでWaitをかけRTI 0101:01** **** ディスク1バイト転送、スタックからPC−L、PC−H、PSRを取り出してRTS これは1バイト転送($E7A3)をコールしたアドレスに戻る為 ライトの場合入力:A=セーブするデータ 出力:A=CRC下位のデータ X=CRC下位のデータ(Aレジスタと同じ内容) リードの場合出力:A=リードデータ X=リードデータ(Aレジスタと同じ内容) 0101:00** **** $0101の内容が$00なら何もせず、 それ以外はBit5−0のデータ分をAにディスクロード(スキップ) $E1F8:ファイル ロード 入力:1st=ブロックコード$01−2 比較データアドレス下位 2nd=ブロックコード$01−2 比較データアドレス上位 3rd=ロードナンバ群 ポインタ下位 4th=ロードナンバ群 ポインタ上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $24=DISK TROUBLE ERR.24 $27=DISK TROUBLE ERR.27 Y=ロード出来たファイル数 使用:A、X、Y $0000 $0001 $0002 $0003 $0004 $0005 $0007 $0008 $000E $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから($E445を実行) ブロックコード$02のマウントファイル数を読み込み($E484を実行) ロードナンバデータで$FF(エンドマーク)が出るまでファイルロードを行います ただし、ロードナンバ群の第1バイトが$FFならコールドスタートとしてロードされます このルーチンで一括ロードを行うのですが ファイルをロードできなくてもエラーが出ない恐れがあります その為に幾つロード出来たかYレジスタにロードしたファイル数が入ります ロードするファイル数とロード出来たファイル数とが合わないとERR.40として 各自で処理する必要があります(ROMルーチンでは何もしません) ロードナンバ群 nn,mm,...,$FF(エンドマーク) ロードするロードナンバが記されている(最大19個まで) ロードナンバ群の第1バイト $FF=コールドスタートの値と比較する その場合エンドマークを足して$FF,$FFになる $E237:一番最後にファイル セーブ 入力:1st=ブロックコード$01−2 比較データアドレス下位 2nd=ブロックコード$01−2 比較データアドレス上位 3rd=ブロックコード$03 データアドレス下位 4th=ブロックコード$03 データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $26=DISK TROUBLE ERR.26 $27=DISK TROUBLE ERR.27 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0004 $0005 $0006 $0007 $0009 $000A $000B $000C $000D $00F8 $00F9 $00FA $0101 Aレジスタに$FFを入れて、下のファイルセーブを行います $E239:ファイル セーブ 入力:A=$00から$FE $0006で指定した場所−1にセーブ(最後のファイル) $FF 最後にセーブ(新しく作成) 1st=ブロックコード$01−2 比較データアドレス下位 2nd=ブロックコード$01−2 比較データアドレス上位 3rd=ブロックコード$03 データアドレス下位 4th=ブロックコード$03 データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $26=DISK TROUBLE ERR.26 $27=DISK TROUBLE ERR.27 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0004 $0005 $0006 $0007 $0009 $000A $000B $000C $000D $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから($E445を実行) 指定した番号のファイルをセーブを行います またブロックコード$02にファイルナンバが書き込まれます ロックコード$03 データアドレスはロードナンバからファイルタイプまで 書かれているアドレスを指します セーブが成功すれば、ベリファイの実行を行います またベリファイの前にマウントファイル数の書き込みを行います ファイルはブロックコード$04も含む LDA #$05 JSR #$E239 DB $01−2データ下位,$01−2データ上位 DB ファイル データ下位,ファイル データ上位 BNE ERROR | $01−2データはメーカーコードからコールドスタートの次の$FFまで ファイルデータはブロックコード$03のロードナンバからファイルタイプまで ファイルデータに記されているアドレスと長さが書き込む範囲になります $E26B:ファイル セーブ (メイン) 入力:$0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 $0002=ブロックコード$03 データアドレス下位 $0003=ブロックコード$03 データアドレス上位 $000E=$00から$FE $0006で指定した場所−1にセーブ $FF 最後にセーブ 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $26=DISK TROUBLE ERR.26 $27=DISK TROUBLE ERR.27 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0004 $0006 $0007 $0009 $000A $000B $000C $000D $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから($E445を実行) $000Eを見て$00なら$0006の場所の最後に移動してファイルをセーブ $FFならブロックコード$02を読み込んでマウントファイル数の最後に移動してセーブ ファイルはブロックコード$04も含む $E2AB:マウントファイル数の書き込み 入力:$0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 $0006=フマウントァイル数 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $27=DISK TROUBLE ERR.27 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $0009 $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから($E445を実行) ブロックコード$02のマウントファイル数の書き込みを行います $E2B7:ブロックコード$01のチェック、マウントファイル数の書き込み 入力:A=マウントファイル数 $0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $27=DISK TROUBLE ERR.27 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $0009 $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから ブロックコード$02に指定したマウントファイル数の書き込みを行います。 $E2BB:ブロックコード$01のチェック、マウントファイル数の削除 入力:A=削除するファイル数 $0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $27=DISK TROUBLE ERR.27 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $0009 $00F8 $00F9 $00FA $0101 ブロックコード$01のチェックを行ってから ブロックコード$02のマウントファイル数から指定したファイル数の分だけ減らします この時マウントファイル数がマイナスになるとERR.31となります。 $E2F7:マウントファイル数の読み込み 入力:$0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $27=DISK TROUBLE ERR.27 $0006=ファイル数 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0004 $0007 $00F8 $00F9 $00FA ブロックコード$01のチェックを行ってから($E445を実行) ブロックコード$02のマウントファイル数を読み込みます($E484を実行) その為、前もってブロックコード$01の比較データを用意する必要があります。 $E301:マウントファイル数+1を書き込む 入力:A=マウントファイル数 1st=ブロックコード$01−2 比較データアドレス下位 2nd=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $27=DISK TROUBLE ERR.27 $29=DISK TROUBLE ERR.29 $30=DISK TROUBLE ERR.30 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $00FA $0101 スタック ブロックコード$01−2のチェックを行ってから マウントファイル数より1つ多く書き込みます $E305:マウントファイル数を書き込む 入力:A=マウントファイル数 1st=ブロックコード$01−2 比較データアドレス下位 2nd=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $27=DISK TROUBLE ERR.27 $29=DISK TROUBLE ERR.29 $30=DISK TROUBLE ERR.30 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $00FA $0101 スタック ブロックコード$01−2のチェックを行ってから マウントファイル数を書き込みます $E307:マウントファイル数+nnを書き込む 入力:A=マウントファイル数 X=nn(加えるファイル数) $0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $27=DISK TROUBLE ERR.27 $29=DISK TROUBLE ERR.29 $30=DISK TROUBLE ERR.30 使用:A、X、Y $0002 $0004 $0005 $0006 $0007 $00FA $0101 スタック ブロックコード$01−2のチェックを行ってから マウントファイル数+nnを書き込みます $E32A:ディスク インフォメーションの収得 入力:1st=ディスク インフォメーション アドレスの下位 2nd=ディスク インフォメーション アドレスの上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $21=DISK TROUBLE ERR.21 $21=DISK TROUBLE ERR.27 $0002−$0003=ディスクの総容量 $000A−$000B=ディスクの総容量 使用:A、X、Y $0000 $0001 $0004 $0005 $0006 $0009 $000A $000B $000C $000D ディスクを最初から読み、指定したディスク インフォメーションにデータを書き込みます ディスク インフォメーションの内容 +00 メーカーコード 1バイト +01 ゲーム ネーム 4バイト +05 ゲーム バージョン 1バイト +06 ディスク サイド 1バイト A面=00、B面=01 +07 ディスクの順番 1バイト +08 ディスクの種類 1バイト 00=FMC(黄色の磁気カード)、01=FSC(シャッター付きカード) +09 不明(地域?) 1バイト +0A マウントファイル数 1バイト ブロックコード$02のデータ +0B ロードナンバー00 1バイト ファイルの順番00のロードナンバ +0C ファイルネーム00 8バイト ファイルの順番00のファイルネーム | | 以降ファイル数分のファイルが続き最後にディスクの総容量 | +nn ディスクの総容量の下位 +mm ディスクの総容量の上位 ディスクの総容量はヘッダ部分 +00〜+0A 10バイト ファイル部分 ファイルの順番 1バイト +0B ロードナンバ 1バイト +0C〜+12ファイルネーム 8バイト ロードアドレス 2バイト ファイルの長さ 2バイト ファイルタイプ 1バイト GAP? 255バイト($03と$04分?) プログラム部分 ファイルの長さ 以降ファイル部分+プログラム部分がマウントファイル数−1分まで加算されます。 ???ディスクの総容量は$E31Fまで $E3E7:パラメータの取得、現在のドライブの状態を見る(ロード) 入力:A=$FF(パラメータ4バイト)、$00(パラメータ2バイト) 1st,2nd 3rd、4th(パラメータ4バイトの場合) 出力:$0000=1st パラメータ $0001=2nd パラメータ $0002=3rd パラメータ(パラメータ4バイトの場合) $0003=4th パラメータ(パラメータ4バイトの場合) A=エラーコード $00=エラー無し $01=DISK SET ERR 使用:A、X、Y $0004 $0005 $0006 スタック パラメータのの取得を行って$0000からそれぞれ対応するデータをセットして メディア セットを調べます $E3EA:パラメータの取得、現在のドライブの状態を見る(セーブ) 入力:A=$FF パラメータ4バイト セット $00−$FE パラメータ2バイト セット 1st,2nd 3rd、4th(パラメータ4バイトの場合) 出力:$0000=1st パラメータ $0001=2nd パラメータ $0002=入力したAレジスタの内容(パラメータ2バイト セットの場合) 3rd パラメータ (パラメータ4バイト セットの場合) $0003=4th パラメータ (パラメータ4バイト セットの場合) $000E=パラメータnnバイトの値(0か2 エラーの場合) A=エラーコード $00=エラー無し $01=DISK SET ERR $03=WRITE PROTECT ERR 使用:A、X、Y $0004 $0005 $0006 スタック パラメータのの取得を行ってJSR命令の実行した後のアドレスをパラメータとして $0000からそれぞれ対応するデータをセットして Aレジスタにディスクの状態を送ります。 エラーが発生するとRTSする前にスタック操作を行って このルーチンを実行したルーチンを強制終了されます $E3EB:パラメータの取得、現在のドライブの状態を見る メイン 入力:Cf=1 ロード時のドライブ状態を見る 0 サーブ時のドライブ状態を見る A=$FF パラメータ4バイト セット $00−$FE パラメータ2バイト セット 1st、2nd 3rd、4th(パラメータ4バイトの場合) 出力:$0000=1st パラメータ $0001=2nd パラメータ $0002=入力したAレジスタの内容(パラメータ2バイト セットの場合) 3rd パラメータ (パラメータ4バイト セットの場合) $0003=4th パラメータ (パラメータ4バイト セットの場合) $000E=パラメータnnバイトの値(0か2 エラーの場合) A=ロードの場合 $00=エラー無し $01=DISK SET ERR.01 セーブの場合 $00=エラー無し $01=DISK SET ERR.01 $03=WRITE PROTECT ERR.03 使用:A、X、Y $0004 $0005 $0006 スタック パラメータのの取得を行って前にJSR命令の実行した後のアドレスをパラメータとして $0000からそれぞれ対応するデータをセットして Aレジスタにディスクの状態を送ります セーブの状態なら$E3EAをサブルーチンコールをすれば良いのですが ロードの状態はCf=1にしてから$E3EBをコールする事になります。 エラーが発生するとRTSする前にスタック操作を行って このルーチンを実行したルーチンを強制終了されます $E445:ブロックコード01 リード、チェック 入力:$0000=ブロックコード$01−2 比較データアドレス下位 $0001=ブロックコード$01−2 比較データアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $04=GAME MAKER ERR.04 $05=GAME NAME ERR.05 $06=GAME VERSION ERR.06 $07=A.B.SIDE ERR 07 $08=DISK NUMBER ERR.08 $09=ERR.09 $10=ERR.10 $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $27=DISK TROUBLE ERR.27 $0008=コールドスタート出来る最大ロードナンバ 使用:A、X、Y $0004 $0007 $00F8 $00F9 $00FA ブロックコード$01−1と$01−2のチェックを行います $01−3とCRCはスキップされる 違うメーカ、ゲームネーム、バージョン等の判断が出来ます ブロックコード$01−2のチェックは予備1まで必要です $E484:ブロックコード$02のマウントファイル数 リード 出力:A=エラーコード $00=エラー無し $27=DISK TROUBLE ERR.27 $0006=マウントファイル数 使用:A、X、Y $0004 $0007 $00F9 $00FA $0101 マウントファイル数を読み、CRCチェックを行います。 $E492:ブロックコード$02のマウントファイル数 ライト 入力:A=マウントファイル数 使用:A、X、Y $0004 $0007 $00FA $0101 マウントファイル数を書き込み、CRCデータを書き込みます。 $E4A0:ファイル チェック 入力:$0002=ロードナンバ群 ポインタ下位 $0003=ロードナンバ群 ポインタ上位 $0008=コールドスタートの値 出力:$0009=ロード コントロール $00=ロード $FF=スキップ $000E=ロード出来るファイル カウンタ 使用:A,X、Y $0101 指定したファイルがロードが出来るかチェックを行います ファイルナンバの読み込みから始まりますので ブロックコード$03の$00、$80、$03を読んでからコールします ロードナンバ群とブロックコード$03を読み同じなら $0009に$00、$000Eをインクリメント 違うのなら$0009に$FF ロードナンバ群 nn,mm,...,$FF(エンドマーク) ロードするロードナンバが記されている(最大19個まで) ロードナンバ群の第1バイト $FF=コールドスタートの値と比較する $E4DA:全てのファイルをスキップ 入力:$0006=マウントファイル数 使用:A、X、Y $0002 $0003 $0004 $0007 $0008 $0009 $000A $000B $000C $000D $00F9 $00FA $0101 マウントファイル数の次の所まで移動します 新しくファイルを追加する場合等にコールします $E4E0:指定したファイル数をスキップ 入力:A=スキップするファイル数 使用:A、X、Y $0002 $0003 $0004 $0007 $0008 $0009 $000A $000B $000C $000D $00F9 $00FA $0101 指定したファイル数をスキップします $E583:ブロックコード$03のデータ解析 入力:$0002=ブロックコード$03 データポインタ下位 $0003=ブロックコード$03 データポインタ上位 出力:$000A=ロード、セーブアドレス 下位 $000B=ロード、セーブアドレス 上位 $000C=ファイルの長さ 下位 $000D=ファイルの長さ 上位 使用:A、X、Y $00FE 前もって読み書きしたブロックコード$03の内容に沿って ブロックコード$04へ読み書きする為に アドレス、ファイルの長さを取得し ファイルの種類がキャラクタか許諾ファイルなら PPUアドレスをセットします またPPUロードの為1回$2007を空読みを行っています $E64D:ディスク ドライブの起動 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 使用:A、X、Y $0004 $00F8 $00F9 $00FA モータ・オフ 約0.512秒のウェイト モータ・オン+バッテリーチェック ディスクセットのチェックを行いながら /READY=0になるまで待ちます $E685:ディスク ドライブ モーター ストップ 出力:A=$4025の内容 使用:A $00FA ドライブのモーターを止めます $4025に0010 ?110Bを出力し、その内容をAレジスタ出力されます このAレジスタはドライブのモータ スタート($EE17)で使用します つまり$E685と$EE17は対で使用(間にウェイトが入る場合がある)されます $E68F:ブロックコードの読み込み 入力:A=ブロックコード 出力:A=エラーコード $00=エラー無し $21=DISK TROUBLE ERR.21 $22=DISK TROUBLE ERR.22 $23=DISK TROUBLE ERR.23 $24=DISK TROUBLE ERR.24 使用:A、X、Y $0004 $0007 $00F9 $00FA $0101 CRCレジスタをリセットを行い、 1バイト読み込んだデータをブロックコードとして読みます ヘッドが予めブロックコードのある所にいなければなりません $E6B0:ブロックコードの書き込み 入力:A=ブロックコード 使用:A、X、Y $0004 $0007 $00FA $0101 $4025の設定(AND #$2Bをとる) 約0.01秒のウェイト GAP $00を書き込む CRCレジスタのリセット スタートデータ $80を書き込む 指定したブロックコードを書き込みます(1バイト) ヘッドが予めブロックコードのある所にいなければなりません $E6D5−$E6E2:*NINTENDO−HVC* データ '*CVH-ODNETNIN*'(逆になっています) $E6E3:*NINTENDO−HVC*のチェック 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $02=BATTERY ERR.02 $21=DISK TROUBLE ERR.21 使用:A、X、Y $0004 $0007 $00F8 $00F9 $00FA ドライブを起動し ブロックコード$01−1の'*NINTENDO-HVC*'があるかチェックを行います '*NINTENDO-HVC*'が無ければドライブを止め Aレジスタにエラーコード$21を返します $E706:CRC リード 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $27=DISK TROUBLE ERR.27 $28=DISK TROUBLE ERR.28 使用:$00FA CRC−Lデータをリード(データ自体は使用しません) CRC−Hコントロールを1($4025のBit4=1) CRC上位バイトをリード リードしたデータがCRC−Hコントロールによってチェックが行われ 結果が$4030のBit4に現れ(1=エラー、0=エラー無し) それの合わせてエラーコードが出力され、ドライブクローズされます $E729:CRC ライト 入力:A=CRC−Lデータ 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $29=DISK TROUBLE ERR.29 $30=DISK TROUBLE ERR.30 使用:$00FA *CRC−Lデータをライト CRC−Hコントロールを1($4025のBit4=1) 約0.0005秒のウェイト <−ここでCRC−Hが書き込まれている? $4032の/READY=1(Bit1=1)ならエラー(ERR.31) 0(Bit1=0)ならエラーなし *CRC−LデータはIRQの1バイトデータ転送ルーチンでAレジスタに出力されています $E761:2バイトロード、ドライブのクローズ 入力:$000A=ロードアドレス下位 $000B=ロードアドレス上位 出力:A=エラーコード $00=エラー無し $01=DISK SET ERR.01 $28=DISK TROUBLE ERR.28 エラーコード$28 (エラーの場合) 使用:$00FA 2バイトロードしてドライブをクローズします CRCチェックは行いません エラーチェックはヘッドの検知を行います CRCデータのロード? $E778:ドライブのクローズ(エラー無し) 入力: 出力:A=エラーコード $00=エラー無し 使用:A、X $00FA X=$00(エラー無し)として ドライブ クローズ($E786)を実行します 当然、出力でAレジスタには$00が入ります $E786:ドライブ クローズ 入力:X=エラーコード 出力:A=エラーコード(Xレジスタの値) 使用:A、X $00FA $4025 Bit7:0 6:0 5:1 4:0 3:* 2:1 1:1 0:* XレジスタをAレジスタにコピーして、IRQをオンにします $E77F:ディスク コンペア データ Zfチェック 入力:Zf=0 比較データと違う 1 比較データと同じ 出力:A=エラーコード(Zf=0で入力の場合) 使用:$0004 $00FA 前もってデータを比較したりしてZfの変化を見るルーチンになります 入力でZf=1なら何もせずRTS 0ならエラー エラーでは$0004のスタックデータをスタックポインタにして ドライブ クローズ、エラー出力して強制終了します $E794:IRQ 1バイト転送の開始 入力:A=ライト データ(書き込みの場合) 出力:A=CRC下位 (書き込みの場合) X=リード データ(読み込みの場合) A=リード データ(読み込みの場合) 使用:$00FA $0101 IRQコードを$40(0101:40) IRQデータ転送を1($4025のBit7=1)にして 下の$E7A3(IRQ 1バイト転送)を実行します ディスクのリード・ライトの始めに使用しますが事前に CRCレジスタをクリアしていないとCRC計算が正しく行われません $E7A3:IRQ 1バイト転送 入力:A=ライト データ(書き込みの場合) 出力:A=CRC下位 (書き込みの場合) X=リード データ(読み込みの場合) A=リード データ(読み込みの場合) IRQをオンにして無限ループでIRQが掛かるまで待ちます 1バイトだけIRQによってディスク転送を行いますが、 ディスクドライブ起動、IRQの設定は行わないので前もって設定する必要があります IRQのディスク1バイト転送ではスタック操作して このルーチンをコールしたアドレスに返るようになっています・ $E7A7:ファイル アドレスのINC、プログラムの長さのDEC 入力:$000A=ファイル アドレス下位 $000B=ファイル アドレス上位 $000C=ファイルの長さ下位 $000D=ファイルの長さ上位 出力:$000A=ファイル アドレス+1下位 $000B=ファイル アドレス+1上位 $000C=ファイルの長さ−1下位 $000D=ファイルの長さ−1上位 使用:A $000Aと$000Bを16ビットカウウンタとしてINCします 下の$E7ADへ続き $000Cと$000Dを16ビットカウウンタとしてDECします ブロックコード$04のデータを読み書き等に使用します 通常、入力はブブロックコード$03のデータ解析($E583)でセットされ このルーチンで入力する事はありません $E7AD:プログラムの長さのDEC 入力:$000C=ファイルの長さ下位 $000D=ファイルの長さ上位 出力:$000C=ファイルの長さ−1下位 $000D=ファイルの長さ−1上位 使用:A $000Cと$000Dを16ビットカウウンタとしてDECします $E7BB:文字列出力 入力:1st=データアドレス下位 2nd=データアドレス上位 使用:A、X、Y $0000 $0001 $0005 $0006 PPUにデータを送ります JSR #$E7BB DB データアドレス下位、データアドレス上位 | 上記の様にJSR命令の後にデータアドレスを指定します データのフォーマットは PPUアドレス上位またはコード PPUアドレス下位 コマンド+表示する長さ データ | コマンド+表示する長さ データ $FF(コード エンドマーク) コード $80−$FFならエンドマークとみなし終了(通常は$FF) $60ならサブデータから戻ります $4Cなら次のデータをアドレス上位、下位の順でサブデータのアクセスを行います サブデータは通常のデータと同じフォーマットになりエンドマークが$60になります コマンド Bit7:1=Y方向+1 、0=X方向+1 6:1=メモリを埋める、0=データレングスとして処理 5−0:長さ $E844:パラメータの取得 入力:コールする前の1st コールする前の2nd 出力:$0000=1st パラメータ $0001=2nd パラメータ 使用:$0005 $0006 ROMのサブルーチンによってはJSR nnmmの後にパラメータを設定するのですが それらのサブルーチンが使用して、パラメータを読みRTSする為のスタックを調節します $0005から$0006の内容が壊れます $E86A:VRAMバッファ出力 入力:$0302=バッファデータ00 VRAMアドレス上位 $0303=バッファデータ00 VRAMアドレス下位 $0304=バッファデータ00 データの長さ $0305=バッファデータ00 VRAMに書き込むデータ | $03nn=エンドマーク($80から$FF) 出力:$0301=$00 $0302=エンドマーク$80から$FF(実際には$FF) 使用:A、X、Y $00FF PPUアクセス時のアドレスの増加をX方向($2000 Bit2=0)にして VRAMバッファからアドレス、長さを取得してVRAMにバッファデータを書き込みます バッファデータの第1バイトのVRAMアドレスが$80から$FFだとエンドマークになります データフォーマット バッファデータ00 VRAMアドレス上位 バッファデータ00 VRAMアドレス下位 バッファデータ00 出力データの長さ バッファデータ00 出力データ | バッファデータnn VRAMアドレス上位 バッファデータnn VRAMアドレス下位 バッファデータnn 出力データの長さ バッファデータnn 出力データ エンドマーク($80から$FF) $E8B3:VRAMバッファ入力 入力:X=インデックス($02から) Y=転送するバイト数 $0302=データ00 VRAMアドレス 上位 $0303=データ00 VRAMアドレス 下位 $0305=データ01 VRAMアドレス 上位 $0306=データ01 VRAMアドレス 下位 | 出力:$0304=指定したデータ00のVRAMの内容 $0307=指定したデータ01のVRAMの内容 | 使用:A、X、Y $0302にあるVRAMバッファにVRAMの内容を転送します 1バイトごとの転送なので3バイト1組になります 入力するXレジスタの値は$02以上になります VRAMバッファは +00 VRAMアドレス上位 +01 VRAMアドレス下位 +02 VRAMの内容 (3バイトで1組になっています) | +nn $FF(エンドマーク) このルーチンではVRAMバッファのアドレスを読んで その内容をVRAMの内容としてVRAMバッファに書き込みます データの長さは3バイトで1つの長さになります $E8D2:メモリからVRAMバッファへ1行分の転送 入力:A=VRAMアドレス上位 X=VRAMアドレス下位 Y=転送する長さ 1st=データアドレス下位、2nd=データアドレス上位 $0300=VRAMバッファ インデックスの上限 $0301=VRAMバッファ インデックス 出力:A=$01 エラー有り $FF エラー無し $0002=キャラクタ定義用($0002−$0003に$20足される他のルーチン用) $0003=キャラクタ定義用 $0301=入力したVRAMバッファ インデックス+データの長さ(次のインデックス) $0302=VRAMアドレス上位 $0303=VRAMアドレス下位 $0304=データの長さ $0305=データ | $03nn=$FF エンドマーク 使用:A、X、Y $0000 $0001 $0004 $0005 $0006 メモリからVRAMバッファ($0302−$03FF)へ1行分転送(追加)します バッファの上限が$0300に設定され これを超えるとバッファにエンド マーク$FFが書き込まれ このルーチンをコールしたルーチンが強制終了されます 書き込み例 LDA #$20 ;VRAM上位 LDX #$00 ;VRAM下位 LDY #$04 ;転送する長さ JSR $E8D2 ;VRAMバッファに転送 DB データアドレス下位,データアドレス上位 JSR $E1B2 ;VBLANK期間になるまで待つ JSR $E86A ;VRAMバッファからVRAMに転送 JSR $EAEA ;スクロール(画面のクローズ) | DB ’ABCD’ ;データ $E8E1:メモリからVRAMバッファへ数行転送 入力:A=VRAMアドレス上位 X=VRAMアドレス下位 1st=データアドレス下位、2nd=データアドレス上位 $0300=VRAMバッファ インデックスの上限 $0301=VRAMバッファ インデックス 出力:A=$01 エラー有り $FF エラー無し $0002=キャラクタ定義用($0002−$0003に$20足される他のルーチン用) $0003=キャラクタ定義用 $0301=入力したVRAMバッファ インデックス+データの長さ(次のインデックス) $0302=VRAMアドレス上位 $0303=VRAMアドレス下位 $0304=データの長さ $0305=データ | $03nn=$FF エンドマーク 使用:A、X、Y $0000 $0001 $0004 $0005 $0006 メモリからVRAMバッファ($0302−$03FF)へ数行転送(追加)します $E8D2と違うのはデータの第1バイトがPPUデータでなく Bit7−4:行数で Bit3−0:データの長さ になります バッファの上限が$0300に設定され これを超えるとバッファにエンド マーク$FFが書き込まれ このルーチンをコールしたルーチンが強制終了されます $E94F:VRAMバッファ アドレスチェック、リード 入力:X=$00 (VRAMバッファ オフセット) Y=VRAMバッファ スキップする個数(3バイトで1) $0000=チェックするVRAMバッファ (VRAMアドレスの上位) $0001=チェックするVRAMバッファ (VRAMアドレスの下位) 出力:<同じアドレスの場合> A=VRAMバッファにあるVRAMの内容 Cf=0 <違うアドレスの場合> チェックしたVRAMバッファ+0=チェックするVRAMアドレス上位($0000) チェックしたVRAMバッファ+1=チェックするVRAMアドレス下位($0001) Cf=1 Y=VRAMバッファ インデックス VRAMバッファ X=インデックス(+0の位置)、Y=スキップする個数(3バイトで1)で X=$0302+X+3*(Y−1)でチェックするアドレスを決めます そのアドレスと$0000、$0001と比較して 同じならAレジスタに+2のデータを読み、Cf=0にしています 違う場合は+0、+1に比較した$0000、$0001のアドレスを書き込み Cf=1にしてエラーとみなします $E97D:座標からネームテーブル0変換 入力:$0002=Y座標(0から224) $0003=X座標(0から255) 出力:$0000=ネームテーブル0 上位 $0001=ネームテーブル0 下位 使用:A ドットの座標からネームテーブル0($2000−$23BF)に変換を行います $E997:ネームテーブルから座標変換 入力:$0000=ネームテーブル 上位 $0001=ネームテーブル 下位 出力:$0002=Y座標(0から232) $0003=X座標(0から248) 使用:A ネームテーブルオフセット($0000−$03BF)からドットの座標に変換を行います 入力のネームテーブル上位は$0000から$03BFで計算を行っているので どのネームテーブル、ネームテーブルオフセットでも同じ出力になります $E9B1:乱数の発生 入力:X=インデックスデータ Y=長さ ゼロページ 出力:ゼロページ+入力したXレジスタからゼロページ+入力したX+Yまで 使用:A、X、Y $0000 指定したゼロページ+Xレジスタのアドレスを起点として長さYまでを 発生レジスタとして乱数の発生を行います 指定したゼロページ+XレジスタのBit1だけマスクして$0000にストア 指定したゼロページ+1+XレジスタのBit1と$0000とEORする 0ならCf=0、1ならCf=1 全発生レジスタを右シフトする $E9C8:仮想OBJエリア セット 仮想OBJを$0200に設定します。 使用:A $E9D3:ロジック カウンタ 入力:X=カウンタ0のアドレス(ゼロページ内) A=カウンタ1のアドレス(ゼロページ内) Y=カウンタ2のアドレス(ゼロページ内) 出力:X=カウンタ0のアドレス(ゼロページ内0から9) A=カウンタ1のアドレス(ゼロページ内0から255) Y=カウンタ2のアドレス(ゼロページ内0から255) 使用:A、X、Y カウンタを1つ減らします カウンタ0が基本になり、9からカウントダウンして−1になると9に戻ります カウンタ0が9から0の時にカウンタ1のカウントダウン(00で止まる) −1の時にカウンタ2のカウントダウン(00で止まる) $E9EB:リアルタイムでコントローラを読む 出力:$0000:拡張端子のI−コントローラ $0001:拡張端子のII−コントローラ $00F5:I−コントローラ $00F6:II−コントローラ 使用:A、X $00FB 本体コントローラと外部のコントローラを読んで 各ワークエリアにデータをストアします。 $EA0D:コントローラデータの合成 入力:$0000:拡張端子のI−コントローラ $0001:拡張端子のII−コントローラ $00F5:I−コントローラ $00F6:II−コントローラ 出力:$00F5:I−コントローラ $00F6:II−コントローラ 使用:A $E9EBで得たデータをまとめます $EA1A:リアルタイムで本体コントローラを読む 出力:$00F5:I−コントローラ $00F6:II−コントローラ $00F7:I−コントローラを1回押した時の内容 $00F8:II−コントローラを1回押した時の内容 使用:A、X、Y $0000 $0001 リアルタイムでントローラを読み($E9EBをコール) ワークエリアにストアします $00F7と$00F8は 押されたままだと1になり離すと0になります $EA1F:リアルタイムで本体コントローラと拡張コントローラを読む 出力:$00F5:I−コントローラ $00F6:II−コントローラ $00F7:I−コントローラを1回押した時の内容 $00F8:II−コントローラを1回押した時の内容 使用:A、X、Y $0000 $0001 リアルタイムでコントローラを読み($E9EBをコール) コントローラデータの合成($EA0Dをコール)を行い ワークエリアにストアします $00F7と$00F8は 押されたままだと1になり離すと0になります 使用:A、X、Y $0000 $0001 $EA36:本体コントローラを読む 出力:$00F5:I−コントローラ $00F6:II−コントローラ $00F7:I−コントローラを1回押した時の内容 $00F8:II−コントローラを1回押した時の内容 使用:A、X、Y $0000 $0001 リアルタイムでコントローラを読み($E9EBをコール)、レジスタA、Yに読む リアルタイムでコントローラを読み($E9EBをコール) 1回目と2回目に読んだ内容が同じになるまでループ 同じになったら$00F5から$00F8までのワークに それぞれストアします $EA4C:本体コントローラと拡張コントローラを読む 出力:$00F5:I−コントローラ $00F6:II−コントローラ $00F7:I−コントローラを1回押した時の内容 $00F8:II−コントローラを1回押した時の内容 使用:A、X、Y $0000 $0001 $EA36と同様に本体コントローラと拡張コントローラで コントローラの読み込みを行います $EA84:PPUメモリを埋める 入力:A=PPU アドレス上位 X=埋めるデータ Y=パラメータ(PPUアドレスの指定によって違う) 出力:X=指定した埋めるデータ 使用:A、X、Y $0000 $0001 $0002 指定したPPUアドレスが$2000未満(パターンテーブル)なら 特定したXレジスタのデータをYレジスタで指定した長さ*256バイトで埋めます 指定したPPUアドレスが$2000以上なら 指定したXレジスタのデータ$0400バイトをネームテーブルに埋め 指定したYレジスタのデータ$40バイトをネームテーブルのアトリビュートに埋めます。 PPUアドレスは上位のみで下位アドレスは$00になります。 転送量も上位になるので256バイト単位になります。 $EAD2:メモリを埋める 入力:A=埋めるデータ X=スタートアドレス上位 Y=エンド アドレス下位 使用:A、X、Y $0000 $0001 CPUメモリを特定のデータで埋めます 指定できるのはアドレス上位のみなのでページ単位$nn00−$mmFFが指定範囲になります $EAEA:スクロールをセット 入力:$00FC=ポート$2005の内容(X座標) $00FD=ポート$2005の内容(Y座標) $00FF=ポート$2000の内容 使用:A VRAMをアクセスした後スクロールセットをするのに使用します スクロールをセット PPU R#0を$00FFの内容でセット $EB13:HVC−007 キーボードのキーマトリクス入力 出力:$0000=キーマトリクスP2 9の反転データ $0001=キーマトリクスP2 8の反転データ $0002=キーマトリクスP2 7の反転データ $0003=キーマトリクスP2 6の反転データ $0004=キーマトリクスP2 5の反転データ $0005=キーマトリクスP2 4の反転データ $0006=キーマトリクスP2 3の反転データ $0007=キーマトリクスP2 2の反転データ $0008=キーマトリクスP2 1の反転データ 使用:A、X、Y $00FB ファミリーBASICのキーボード(HVC−0007)のキーマトリクス入力を行います 出力データは反転されているので押していると1、離している0になります P3 1がBit0...P3 8がBit7になります$EBAF:パターンテーブル定義 入力:Y=PPUアドレス 上位 A=PPUアドレス 下位+コード Bit7:PPUアドレス A7 Bit6:PPUアドレス A6 Bit5:PPUアドレス A5 Bit4:PPUアドレス A4 Bit3:コード D1 11=反転 通常 、10=埋める 通常 Bit2:コード D0 01=通常 埋める、00=通常 通常 Bit1:コード 1=リード モード、0=ライト モード Bit0:コード 1=$FFで埋める、0=$00で埋める X=キャラクタ数 1st=パターン データアドレス下位 2nd=パターン データアドレス上位 使用:A、X、Y $0000 $0001 $0002 $0003 $0004 $00FF パターンテーブル(キャラクタ)の定義を行います アクセスするPPUアドレスを指定しますがPPUアドレス下位のBit3−0は0になる($xxx0) 次にコード解析でBit1−0の設定、Bit3−2で各キャラクタ定義を行います キャラクタは1キャラ8バイト+8バイトの計16バイト必要で コードによって定義のパターン(必要なパターンデータ数)が変わります コード11(パターン データは1キャラクタ 16バイト必要) プレーン0 パターン データを反転してVRAMに書き込む プレーン1 ライト モード=パターン データをVRAMに書き込む リード モード=VRAMの内容をパターン データに書き込む コード10(パターン データは1キャラクタ 8バイト必要) プレーン0 ライト モード=VRAMに$FFまたは$00で埋める リード モード=VRAMのデータを読み、VRAMに書き込む プレーン1 ライト モード=パターン データをVRAMに書き込む リード モード=VRAMの内容をパターン データに書き込む コード01(パターン データは1キャラクタ 8バイト必要) プレーン0 ライト モード=パターン データをVRAMに書き込む リード モード=VRAMの内容をパターン データに書き込む プレーン1 ライト モード=VRAMに$FFまたは$00で埋める リード モード=VRAMのデータを読み、VRAMに書き込む コード00(パターン データは1キャラクタ 16バイト必要) プレーン0 ライト モード=パターン データをVRAMに書き込む リード モード=VRAMの内容をパターン データに書き込む プレーン1 ライト モード=パターン データをVRAMに書き込む リード モード=VRAMの内容をパターン データに書き込む $ED37−$EE16:許諾画面 データ $EE17:ドライブのモータ スタート 入力:A=$4025の内容 使用:A $00FA /RESET=1にして/MOTOR=0にします 前もってディスク ドライブ モーター ストップ($E685)を実行しておく必要があります $EE24:リセット ベクタ 電源を入れたり、リセットされるとココにとびます。 $F1C3:キャラクタ定義 使用:A、X、Y $0000 $0001 $0002 $0003 $0004 $00FF BG(PPU$1000)に数字、英字のキャラクタ41文字の定義を行います $F431:許諾画面の書き込みチェック 出力:Zf=0 エラーなし 1 エラーあり キャラクタ定義、カラーの設定、BG−Aをクリア BG−Cにロードされた許諾データとROM内にある許諾データの比較を行います $F48C:キャラクタ定義の退避または復帰 入力:Y=$03 キャラクタデータの退避 $07 キャラクタデータの復帰 使用:A、X、Y $0000 $0001 $0002 $0003 $0004 $0007 $0008 $0009 $000A $000B $00FF PPU $2930以降 ディスクを起動したときにはキャラクタデータ、プログラムデータ、許諾データが 一括ロードされている場合があります キャラクタデータがロードされていても必ずしも許諾画面を確実に表示する為の英数字とは限りません そこで、このルーチンでロードしたPPU$1000以降のキャラクタデータを 一旦PPU$2930以降を退避用エリアとして一時退避、復帰を行います データを退避したら英数字のキャラクタ定義を行いPPUにロードした許諾画面のチェック、表示 許諾画面の表示が終了したらデータの復帰を行いロードしたプログラムの実行となります。
$0000:JSR文の後の第1パラメータ データアドレス下位 $0001:JSR文の後の第2パラメータ データアドレス上位 $0002:JSR文の後の第3パラメータ VRAMアドレス下位 指定したマウントファイル数 $0003:JSR文の後の第4パラメータ VRAMアドレス上位 $0004:スタックポインタ退避 データの長さ $0005:JSRで戻るアドレス下位 ディスクアクセス リトライカウンタ VRAMバッファの長さ $0006:JSRで戻るアドレス上位 マウントファイル数 $0007:ブロックコード $0008:エラーコード 最初に読み込むロードナンバ $0009:ロード コントロール $00=ロード、$FF=スキップ セーブ コントロール $00=セーブ、$FF=ベリファイ $000A:ファイルの先頭アドレス 下位 $000B:ファイルの先頭アドレス 上位 $000C:ファイルの長さ 下位 $000D:ファイルの長さ 上位 $000E:パラメータnnバイトの値 ファイルカウンタ $00F5:コントローラIの内容 $00F6:コントローラIIの内容 $00F7:コントローラIを1回押した時の内容 $00F8:コントローラIIを1回押した時の内容 $00F9:ポート$4026の内容 $00FA:ポート$4025の内容 $00FB:ポート$4016の内容 $00FC:ポート$2005の内容(垂直) $00FD:ポート$2005の内容(水平) $00FE:ポート$2001の内容 $00FF:ポート$2000の内容 $0100:NMI コントロール $00=BIOS内 $40=JMP ($DFF6) $80=JMP ($DFF8) $C0=JMP ($DFFA) $0101:IRQ コントロール $00−$3F=IRQコード分のディスク ロード スキップ $40=ディスク1バイトロード $80=ディスクステータスを読む $C0=JMP ($DFFE) $0102−$0103:RESET コントロール $0102:35 53=JMP ($DFFC) $0102:35 AC=$0103を$53にしてスクロールセットの後、JMP ($DFFC) それ以外のデータはデモ $0200−$02FF:仮想OBJエリア $0300−$03FF:VRAMバッファ
ディスクドライブのプロテクト 最初のドライブにはプロテクトは掛かっていませんでしたがコピープログラムの発表や発売され 一定時間(約1秒)しか書き込みが出来ないようになりました。 プロテクトの内容はドライブ内の基板でライト信号が送られたらカウントして約1秒たったら シャットダウンする方式でコレをパターンカットとバイバスを通して無効する方法があります。 最終的にはFDC自身に同等のプロテクトを掛けるのですがロジック回路で破られています。 ソフトでのプロテクト 元々QDなのでそれほどきついプロテクトは掛けられません。 特定のソフトのコピーツールに対してのプロテクトとなります。 またPCから読み書きやデュプリケータでは全くプロテクトの意味がありません。 ダミー ファイル ブロックコード$02のファイル数より多くファイルを持つタイプ とびだせ大作戦、夢工場ドキドキパニック、ディープダンジョンII勇士の紋章(店頭販売、書き換え共)が該当します 主に対DISK HACKER V1.1用です DISK HACKER V1.1ではファイル数を見て必要なファイルだけをコピーしていました とびだせ大作戦のA面では実際のファイルはブロックコード$02のファイル数より1つ多く DISK HACKER V1.1でコピーすると最後の1つだけファイルが足りないものになります そのファイルが無ければコピー品と判断しています。 ダミーファイルとはいえ、とびだせ大作戦はダミーファイルが本当のメインプログラムになっていて ゲームスタートするとMAINPROG(警告プログラム)がロードされ、その後すぐにダミーファイル(本当のメイン)が RAMに上書きされ実行されます ダミーファイルが上書きされないと警告プログラムが動いてコピー品とみなされメッセージを出します 夢工場ドキドキパニック、ディープダンジョンII勇士の紋章では数バイトのデータが書き込まれていて このファイルがロード出来るかでコピー品の判断を行っています。 とびだせ大作戦ではコピー失敗すると作者からメッセージが出ます。夢工場ドキドキパニックのコピー失敗
勇士の紋章のコピー失敗
新鬼ヶ島のコピー失敗
40KB ファイル コピーツールのバッファより大きいファイルを持つタイプ 麻雀家族、スーパーロードランナーが該当 1つのファイルがRAM容量よりも大きくなっています ファイルが40KBのファイルがあり、コピーバッファが少ないとコピー出来ないようになっています 主に対DISK HACKER V1.2用 DISK HACKER V1.3ではV1.2より大きいバッファを持ちコピー出来ます。 ファミコンのディスクはランダムアクセスが出来ないQDなのでトラックやセクタ等は無く テープと同じように最低でも一つのファイルを一気に書き込まないといけません つまり分割して一つのファイルを書き込みする事はかなり困難になります しかし、本体メモリは32KB(RAMアダプタ)+2KB(ワーク)+2KB(VRAM)+キャラクタ(8K)なので 本体内の全メモリ44KBにコピープログラム+バッファを取ってコピー出来るツールもあります。 スーパーロードランナーではSIDE Aの4番目のファイルLRMAIN01が ロードアドレス$6000で長さ$A000になります このファイルは$6000から読み込まれますが始めの$2000バイトを空読みして 残りの$8000バイトが$6000−$DFFFにロードされます ロード終了後、$DFE0−$DFEFのチェックと $6000−$DFFFのチェックサムを行い、合えば$6000にジャンプします。 44KB ファイル 本体内の全RAMと同じ容量のファイルを持つタイプ HACKERのソフトで途中から出てきたプロテクトです 1つのファイルの大きさが44KBで本体内の全RAMより同じになります これだとコピープログラムの入る所が無くソフトのコピーツールではコピー出来なくなります メインプログラムが$4800からロードしてBIOSの$F7FFまでロードするようになっていて 実際にはRAM領域の$6000−$DFFFにプログラムがロードされるようになります HACKERのソフトで同タイトルでもプロテクトが掛かっているのと掛かっていない2タイプがあります。 偽データ ブロックコード$03と$04が合わないプロテクトです アイツーのジンゴローが該当 ブロックコード$03にはファイル名やロードされるアドレス、長さが書き込まれています ブロックコード$04が実際のプログラムやデータとなります そのブロックコード$03で書き込まれた長さとブロックコード$04の長さが合わないようするタイプです。 コピーツールでブロックコード$03を見てブロックコード$04のファイルをコピーする コピーツールに対して有効です。 ジンゴローでは最後のファイルがブロックコード$03では1バイトの長さになっていますが 次のブロックコード$04では1バイトでなく7バイト×$2000=$E000バイトのデータが書き込まれており IPLプログラムでデータをメモリとVRAMに振り分けながらロードしています 第1バイトがプログラムデータ(ストア アドレス下位の値で引く) 第2バイトがダミー 第3バイトがダミー 第4バイトがダミー 第4バイトがダミー 第6バイトがキャラクターデータ(ストア アドレス下位の値で足す) 第7バイトがダミー このデータ群をロード(CRC計算もされているのでダミーデータも必要)する様になっています CRCエラー ファイルにワザとCRCエラーの出るファイルが存在するタイプ トンカチエディタが該当 ディスクが起動するまでは通常のフォーマットでその後の読み込みにCRCエラーの出るファイルを ロードしてCRCエラーが出るかチェックします コピーツールによっては正しいCRCが書き込まれるので CRCエラーが出るはずのファイルがエラー無しとなり コピーされたと判断しています オリジナルフォーマット 最後のメイン・ファイルが独自のフォーマットで書き込まれIPLプログラムでロードするプロテクトです 子育てゴッコ、クイックハンターが該当 検査システムでチェックするとディスクデータが最後までデータの読み書きが出来るかチェックされる時に テストファイルが上書きされるので注意が必要なタイプです 途中まで普通のフォーマットでIPLもそのフォーマット内のファイルにあるので IPLをロードして実行、独自のフォーマットで書かれたプログラムを読む 単純なバイナリデータや、加工したデータ、プログラムとダミーデータとVRAMデータと混合等 ソフトによってデータが変わります 子育てゴッコではメインプログラムは$0200−$05FFで 通常のフォーマットの後ろに直接メインプログラムが書かれていて IPLプログラムでこのメインプログラムを$0200からロード ロード終了したら最初の0200:20と最後の05FF:23をチェックして ロードされたか判断をしています このメインプログラムのコピーに失敗すると隠しゲームのバリケードゲームが遊べます。 クイックハンターではIPLプログラムまで行くまでに自己書き換え(一部分が暗号化されている)しながら 数ヶ所にジャンプされています 最終ファイルはブロックコード$00として書き込まれており $1000バイト空読みしてから$B000−$CFFFにロードします $B000以降のロードデータは暗号化されておりEOR $C9(データを一部反転)しながらロードします 当然、このブロックコード$00のファイルもCRCチェックも行われています。 メーカーコード$00 HACKER製コピーツールでHACKER製ソフトをコピー出来ない為のプロテクトです 通常のソフトはメーカーコードは$01からになっており$00は使用していません そこでHACKERのソフトはここに$00を書き込みを行っています メーカーコードが$00だとHACKER製コピーツールではエラー FFを出力して コピーできないようになっています プログラム書き換えチェック これはプロテクトといってもコピープロテクトでは無くプログラムの改造されたかチェックをするタイプ 改造するとチェックサムエラーのメッセージが出たり、起動画面に飛んだり、ゲームが起動出来ない様になっています ただし完全なチェックを行っているとは限りません(コピーライト表記の書き換えを阻止するだけの為?) コナミやカプコンのソフトに見かけます。 セクションZのチェックサムエラーメッセージ
ナムコのディスクソフト プロテクトでは無いのですがナムコのディスクソフトは非ライセンス ソフトと同じような 許諾画面を出さないような事をしています。 実際には許諾画面を出しているのですがRAMアダプタのプログラムで動いてなくて ゲームソフト(IPLMAIN)が割り込みでRAMアダプタからの許諾画面表示 を乗っ取っていながらゲームソフトから許諾画面を表示しています。 これにより任天堂が許諾画面表示の乗っ取りプログラムに対する プロテクトを掛けるのが難しくなっています つまりプロテクトを掛けるのを防ぐ為の任天堂に対する逆プロテクト(?)に思えますが 真相は不明です。
Home へ戻る