ラベル $Nintendo の投稿を表示しています。 すべての投稿を表示
ラベル $Nintendo の投稿を表示しています。 すべての投稿を表示

1985年5月18日土曜日

[ゲーム][FC] ドラゴンクエスト4

[ゲーム][FC] ドラゴンクエスト4
FC版ドラクエ4が最高だ vol.1 - 勇者に居場所はない(エンディング考察)
2020.05.12.Tue
ドラクエは、ファミコン版の4が最高だ。なぜなら、エンディングの最後で、勇者が気が◯って●ぬからである。
この度、私がドラゴンクエストシリーズで一番好きな「ファミリーコンピューター版のⅣ」について、その魅力を連載形式で記してみたいと思う。第1回目の今回は、エンディングのシーンを題材に、私がドラ4でもっとも惹かれた点である 「勇者の立場とその心情」 について考察する。
なお、エンディングを扱うということは、すなわち「究極のネタバレ」ということである。本記事は、ドラ4を(リメイク版でもいいので)1回以上クリアしてから読まれると、十分に楽しめるであろうことをお断り申し上げる。
また、本連載は、主に、私が最後にドラ4をクリアした学生時代の記憶に基づいて書いている。記憶違いについては何卒ご容赦願いたい。
■勇者には、帰りを待ってくれる人がいない
標題の事象が一番端的に現れているのが、本作のエンディングのシーンである。
お転婆姫の帰国はまだいい。王国の跡継ぎという存在は、もともと庶民には縁遠いものである。国家に属さない、山奥のひなびた田舎(隠れ里)の村で育った「17歳の無職少年(もしくは女子少年)」にはなおのことだ。
勇者にとって一番つらかったのは、トルネコの帰宅シーンを目にしたことだろう。出迎える妻ネネ、駆け寄ってくる息子(『トルネコの大冒険』では「ポポロ」)。そして、満面に喜びの色を浮かべて、夢中で息子を抱きかかえるトルネコ。
30後半で脱サラして事業を起こし、戦争を契機に国家に食い込んで政商となり、アベ友バリの随意契約で勝ち取った甘い汁を公共事業支援(ブランカ洞窟)にぶち込んで名声を金で買い、さらに、勇者一行に帆船を乗組員ごと用立てて、その名誉を不動のものとする…。
死の商人(武器商人)として、世界の混乱に乗じて商才を開花させ、イケイケドンドンで成り上がり続ける、基本的に悲壮感とは無縁の事業家としての自信に満ちているトルネコとは、冒険中から、何か反りの合わないものを、勇者は感じていたと推察される。
しかし、そんなことは、このエンディングのワンシーンの破壊力に比べたら、とるに足らないものである。トルネコには、帰りを待ち望んでいる家族が居る。自分(勇者)には居ない。この現実を、この数秒間の間に、勇者(とプレイヤー)は、厳然と叩きつけられることになる。トルネコ一家を邪魔しないように「2マス」距離を空け、静かに眺める勇者。この侘しさ。え?「天空城に実母がいる」だって? 確かに、実母は勇者と共に暮らしたがっているかも知れない。しかし、17年以上ぶり(旅立ち時点で勇者は満17歳)で会って、いきなり「私が本当のお母さんよ」と、それまで1度も会ったことのない、髪の毛の色くらいしか似ていないオバサンに言われて、果たして勇者は、ポポロ(仮)がトルネコにしたように、無邪気に、自然に抱きつくことが出来るだろうか。否である。いくら血がつながっていると言っても、勇者と実母は明らかに、精神的には他人同士だ。マスドラが喜ぶように感動の再会の演技をしたとしても、その余所余所しさに、少なくとも思春期真っ盛りの「17歳の無職少年(もしくは女子少年)」は、30分と耐えられないだろう。
■勇者は、この世界では “珍獣”
この、勇者の抱える絶望的な孤独に、導かれし者たちの中で最初に気づいたのは、恐らくライアンだと思われる。地元に帰ってきた、家に帰ってきた喜びが爆発し、勇者のことは眼中から消えてしまっている他の仲間たちと違い、ライアンは、バトランド王との謁見の際、冷静に、王に勇者を紹介している。他のキャラクターらのはしゃぎぶり(滑らかな動き)とは大きく異る、しゃちほこばった、儀礼的な動き。そしてバトランド王も、丁重に、勇者を国に迎えたい旨を申し出る(ように見える)。それを、あっさり断る勇者。このシーンのポイントは、ライアン(そして、ライアンの意を咄嗟に酌んだバトランド王)が、強く引き止めていないことである。長く職業軍人を務め、また、休職後は何年間も、独りで世界を旅していたライアンは知っている。勇者は、これまでの旅の道中と同じく、仲間以外のいわゆる一般人からは、同じ人間ではない何か珍しい存在のように扱われるだろうこと。勇者や王の意図にかかわらず、勇者がバトランド王の配下に入ることは国家間のパワーバランスを一変させるため、政治的に極めて機敏な問題となること。「狡兎死して走狗烹らる」で、良くても飼い殺しになるだろうこと。
そして「現実社会に適応しろ。大人になれ」と言うには、勇者はまだ若く、しかも数年間のうちに苛烈で凄惨な体験を味わい過ぎていて、その経験を受け入れるのには、長い休息を要するだろうこと。を。
王の方も、勇者が申し出を断ってくれて、内心ホッとした公算が高い。バトランドは、この世界の中では明らかに小国に属する。この国力では、他国との摩擦の種になり得る勇者を、持て余すに決まっているからだ。このシーンは、極めて儀礼的で、そっけない印象を受けるが、それらは全部、ライアンの心遣いの表れと言える。なるべく勇者の孤独感を刺激しない形で、「お前のことを気にかけている」というメッセージを伝えたい、ということであろう。
■勇者は旅の過程で、人間の暗部をコレでもかと見てきた
17歳まで、山奥の隠れ里で、村人全員から家族同様に接せられてまっすぐ育ってきた勇者の目には、世間とはひどく汚く、冷たいものに映ったに違いない。口の悪い木こりのおじいさんにこそ、人間の暖かみを感じられたであろう。しかし、ブランカ王は口先だけ。(王の権威を実感できぬ勇者は、王直々の声がけに有り難みを感じることは出来ない)ホフマンは人間不信。最初に仲間になるのは、見目麗しいが育ちの悪い、擦れっ枯らしの怪しい水商売のお姉さま2人。しかも、露出狂で男にだらしない姉は、この若さでアル中かつギャンブル依存症。そんな姉の世話をずっとしていた妹は、明らかに「アダルトサバイバー(アダルトチルドレン)」であり、幼少期からの無理がたたって険のある人格。「2人揃って魔法使い」という鉄板の怪しさ。ソレッタ国の貧困…はむしろ人間の健気さか!?キングレオによる圧政の爪痕(バハラタ等)。
ロザリー婦女暴行・傷害致死事件
エビプリが裏で糸を引いているとは言え、騙されることにも責任があるし、人間は、魔族に対しては幾らでも残酷になれる好例。しかも「ピサロナイトを倒した自分が悪い」と匂わせられるという追い打ち。
アッテムト鉱山の公害。
公害病で死者累々にもかかわらず、経済的利益のため採掘が継続されているという非情ぶり。(自分にとっては本当の)家族、恋人、家族同然の村人たちを殺した敵の大将もまた、命を慈しみ自分の家族・同族を守るべ行動していた有徳の士であり、人間に虐げられてきた歴史があった。
全部マスドラが悪い。
実父を殺し、実母を引き離し、自分を、来たるべき危機に備えて戦の駒に育て上げた諸悪の根源が、堂々と神様ヅラして偉そうにふんぞり返ってる。しかも「事情を知らぬ子羊どもからは、かなりの崇拝を受けている」という救いの無さ。
と、勇者はこれでもか、これでもかと、人間(及びマスドラ)の暗部を見せつけられてきた。しかも勇者は、その暗部のお陰で、何万匹もの魔族を手に掛け、自らも多々血を流し、あまつさえ「ミネア、メガザル頼む」に代表される、非人道的発言及び行動をする羽目になってきたのである。そして、黒澤映画「七人の侍」ばりに、「どうかデスピサロを倒してください」と判で押したように平身低頭で自分達に拝み倒してきた世界中の民は、危機が去ったら 「勇者様御一行、ばんざ~い\(^◯^)/」 と叫んで、後は用済み扱いで知らん顔。罪悪感なくやっている分だけ、一番たちが悪いかも知れない。これでどうやって、家族・恋人・友人知人を皆殺しにされた挙げ句、自分の意志に反して勇者様に仕立て上げられた「17歳の無職少年(もしくは女子少年)」が、育った村の住人以外の人間に、親しみが持てると言うのか。外の世界を知れば知るほど、勇者は、「自分は、村の外の人間とは違うんだ」という断絶を深く感じていったのではなかろうか。■そんな世界に、勇者はNOと言った
そして、自分を手駒として扱う世界に、勇者は最後にNOを突きつける。今まで、プレイヤーに1から10まで操作されていた、コントロールされていた勇者が、エンディングにおいて、最初で最後の自己主張をする。彼は、彼の世界で至高の存在(のアホ)である、マスドラの申し出を拒否する。言葉は要らない。というか、言葉にならない。言葉にできるほど、彼は、彼の熾烈な体験を、アタマで消化できていない。しかし、心は叫んでいる。天空城は、自分の居るべき場所ではないと。そして、ルーラを使えるにもかかわらず、わざわざ時間をかけて、気球で1軒ずつ、仲間たちのホームタウンをめぐる。そして、彼らの帰宅を見届けると、そっと、画面端に消える。最後に、生まれ育った村にたどり着く勇者。
これまでずっと、ほぼ画面中央に陣取り続け、プレイヤーに操られ右往左往していた勇者のアイコンが、画面左下から、ヨタヨタと這い出してくる。そして、廃墟となった村の、シンシアとの思い出が詰まった花壇跡の脇に寝そべり、天を仰ぐ。世界中の人間は、喜びに沸いている。世界は、希望にあふれている。自分だけが、その輪から漏れている。自分だけが、救いようのない喪失感の中に居る。村が襲撃されて以降、生きるために命を殺め、恨みを晴らすために戦ってきた勇者。そして、結果として手に入れたのは、「自分はこの世界で1人きり」という、厳然たる事実。共に行動する仲間はいるものの、本当に会いたい人は、もうこの世には居ない。デスピサロを倒したことで、「常に魔族に命を狙われ続ける」という強烈なプレッシャーが急に無くなった勇者の心は、あたかも、「急激に水揚げされたため、水圧が無くなって体がバラバラになってしまう深海魚」の如く破裂。
こうして勇者は、Zガンダムのカミーユ・ビダンよろしく、夢の世界の住人となる。自分を戦いの駒とし、戦いが終わればポイ捨てする世界。そんな狂った世界に、勇者の――少なくとも、正気を保ったままの、勇者の居場所はない。
■8bit機の人形劇で、表現し切った凄み
私が初めてこのエンディングを目にしたのは、確か小学校4年生の頃、隣の集落の友人宅においてだったと思う。親から強烈なゲーム禁止令を喰らっていた自分は、友人宅でしか、ゲームに触れなかった。子供心に「なんて辛い終わり方なんだ」と、お腹に、消化不良時のような痛みが走ったことを覚えている。また、一緒に居た友人達が「気ぃ◯って死んだ~」とゲラゲラ笑い転げていたことも、鮮明に。
それから約10年後。大学に入って親元を離れ、アパートにネットを引き、何気なく “ネットサーフィン” していたところ「ドラクエ4の最後はシンシアが生き返って、ハッピーエンドで本当によかった♪」という書き込みを偶然見かけた。しかも、リメイク版ではなく、ファミコン版の話題。そうだ、そうだ、みたいな感じになっている。
これを読んで、私は大層驚いた。そして私は、自分の記憶の正誤を確かめるべく、ドラクエ4をプレイし、公式ガイドブックや攻略サイトを参考に早解きをした。(この時初めて「ロザリー婦女暴行・傷害致死事件」のイベントがあることに気づいた)
エンディングを見ると、やはり私には、勇者は気が違って死んだようにしか見えなかった。
ドラクエ4は、前作のドラクエ3から比べ、画面がとてもスッキリして綺麗になった。4をプレイした後に3をプレイすると、画面がとても荒々しく感じる。(私は、ファミコン版の3の画質に耐えられず、3はスーファミ移植版をやり込むことに相成った。)しかしながら、結局のところ、ファミコン画質である。ドットは荒く、色数は限界でも20色強、サウンドも、PSG3和音+ノイズだけ(少なくとも、エンディングではデルタPCMを使ったと思しき音は鳴らない。もちろん、拡張音源もない。)この条件下で、本作は、効果音もセリフの字幕も使わず、一種のサイレント映画(サイレント人形劇)の手法でもって、本記事にこれまで書いてきたような内容を、私に強く訴えてきた。友人宅で、友人がプレイするのを何回か見ただけの、小学生の私に、である。
この、ドラクエ4のエンディングをこえる表現力を持つ作品を、私は寡聞にして知らない。どんな小説よりも、どんな映画よりも、そしてどんなゲームよりも、ドラクエ4のエンディングは、私に強烈な印象を残した。よって、少なくとも私にとっては、Skylim まで含め、今までプレイした中では、ドラクエ4が至高のRPGである。
なお、ファミコンというハードの性能と512KBという容量という制約によって「サイレント人形劇」という表現しかできなかったため、受け手・プレーヤーは、各自の脳内で場面の内容を空想で補完する必要、即ち「思考の映像化」を行う必要を常に迫られる。それが結果として、強い印象を与えることに繋がった、と解釈することもできる。
■本作は、人間の醜さを描ききった傑作
前作のドラクエ3は、
「魔王は絶望をすすり、憎しみをくらい、悲しみの涙でのどをうるおす」=大魔王ゾーマは、人間のネガティブな感情を糧にして、みずからの力を蓄えている?
※参考:「おおぞらはおまえのもの バラモスは15年近くもなにをしていたのか(2)」
という形而上の争い、人間と非人間との争いがメインテーマだった。アリアハンの世界侵略についての話は出てくるものの、それは序盤に薄っすらと、世界中で同じ言葉が通用することのエクスキューズ的に触れられるに過ぎず、ゲーム進行に直接絡んでくるわけではない。(※参考「おおぞらはおまえのもの なぜアリアハン王はバラモス退治に軍隊を使わないのか」)
それに対して本作は「人間同士の争いがテーマ」と言ってよい。第一、ラスボスのデスピサロですら人間臭い。(もともと、シナリオ担当の堀井雄二氏には、ピサロを仲間にする構想があったとのことなので、当然とも言えるが。)そして、醜い人間が寄り集まって作り上げた人間社会において、自分だけは純粋であろうとすることは許されない。実祖父のように世間を離れ、脱社会的に生きるか、アリーナ一行のように、歪んだ人間社会を御して利益を得るか、トルネコのようにその歪みから滴り落ちる果実を貪るか、マーニャのように、全てを呑み込んだ上で、あえて先のことを考えず、今に集中して享楽的に生きるか…。(※参考: 内田樹 著「下流志向」)何れにしても、世間の中にあって、自分ひとりが身ぎれいであろうとすることは不可能なのだ。前記したように、勇者もまた、己の手を血で真っ赤に染めている。この事を、(少なくとも1~3までは)初心者向けの牧歌的なRPGである「ドラゴンクエスト」という枠組みの中で、表現し切った事実には感服する。
■「勇者が勇者で居られる世界」を作るべきは我々
そもそも勇者にはなりたくなかった主人公に、人間社会の変革、人の意識の変容まで、求めるのは酷である。マスドラ他の支援(という名のコントロール)と、世間の期待を一身に浴びて、デスピサロを倒し世界を魔物の脅威から救ったこと。至高の存在であるマスドラ(つまり、ゲームの駒という役割)にNOを突きつけ、プレイヤーに強烈なメッセージを送ったこと。この2つの実績だけでも大したものだ。特に「2」については、並の人間どころか、並の物語の主人公にも、なかなか達成できない偉業である。
勇者が、ありのままで居られる世界
勇者が戦闘員であなく、シンシアと静かに暮らせる世界
を作るのは、勇者の仕事ではない。それは、ドラゴンクエスト4で遊んだ、我々プレイヤーが実現すべき課題である。
■余談
鳥山明の目の描き方から分かるように、 #ドラクエ もまた #カバール の影響下にある作品。
ドラ4の裏の意図は
⚫唯一神の絶対性、善悪、秩序、貞操観念の相対化(攻撃)
⚫我欲肯定と個人への無力感の植え付け
と思われるが、最後で勇者が「ゴイムを騙す役割」自体を拒否した格好になったのが痛快
— いいげる(ハッキング投稿の嫌がらせを受けています) (@igel_jp) May 12, 2020
ドラクエ3のメッセージも素晴らしい。
⚫「絶望をすすり、憎しみをくらい、悲しみの涙で喉を潤す」 #カバール 思想の存在を、アリアハン王(政治家)は己の統治に利用
⚫バレて頭を抱える
⚫カバール支配に屈せずに明るく生き抜くアレフガルドの民
⚫ゾーマを倒してもカバール思想は滅びぬという警告
— いいげる(ハッキング投稿の嫌がらせを受けています) (@igel_jp) May 12, 2020

いいげるブログ
http://igelblog.blog15.fc2.com/blog-entry-939.html








1985年4月19日金曜日

[ゲーム][TVゲーム] 任天堂ファミリーコンピュータ・ゲーム,1985.4~1985.6発売分,


[ゲーム][TVゲーム] 任天堂ファミリーコンピュータ・ゲーム,1985.4~1985.6発売分, 
◆イー・アル・カンフー
コナミ
1985.4.22発売
4500円
カートリッジ
イーアルカンフー
・どう考えても3面の鎖が最強だと思うが。(ふくろ~)
◆けっきょく南極大冒険
コナミ
1985.4.22発売
4500円
カートリッジ
けっきょく南極
・アザラシのオッサンづらが憎い。(ふくろ~)
・タケコプター!ってこいつペンギンちゃうんじゃ?国旗たてるし。(吉ダム)
◆忍者くん 魔城の冒険
ジャレコ
1985.5.10発売
4500円
カートリッジ
忍者くん
あんた誰!?
・ステージ間の夜の城のグラフィックがキレイ。うさぎも芸コマ。(ふくろ~)
・しっかりまとまってるグラフィック。ちゃんと移植されてる。(吉ダム)
◆ちゃっくんぽっぷ
タイトー
1985.5.24発売
4500円
カートリッジ
ちゃっくん
・「もんすた」「まいた」は生き残ったのに、ちゃっくんはどこへ?ハートだけ?(ふくろ~)
・妙にファンがいたが、私は良さわからずじまい。(吉ダム)
◆ディグダグ
ナムコ
1985.6.4発売
4500円
カートリッジ
ディグダグ
・岩など無視して敵を膨らましまくる、そんな俺はこのゲーム向いてない。(ふくろ~)
・穴掘るとBGMが鳴リ始めるのが好き。(吉ダム)
◆フラッピー
デービーソフト
1985.6.14発売
5500円
カートリッジ
フラッピー
・200面クリアの証、「ブルーストーンカード」実家にまだあるかなあ。(ふくろ~)
・しょぼい画面のわりに楽しいでございます。リモコンきのこ。(吉ダム)
◆レッキングクルー
任天堂
1985.6.18発売
5500円
カートリッジ
レッキングクルー
・ビル→下水→ビル、と庶民派時代のマリオ。隠れキャラのブタが謎。(ふくろ~)
・マリオ兄弟以外のキャラが謎の連中だらけ。なんじゃナスビ仮面て。(吉ダム)
◆スパルタンX
任天堂
1985.6.21発売
4900円
カートリッジ
スパルタンX
・妖術使いで残機が確実に減る。首飛ばし後の硬直がひどいなあ。(ふくろ~)
・ユンピョウとサモハンはどこだぁ!シルビアが真のラスボス・・・ではない。(吉ダム)
◆ハイパーオリンピック
コナミ
1985.6.21発売
6500円
カートリッジ/専用コントローラー付
ハイパーオリンピック
・今のコナミのゲームに通じるものがあるなあ。(ふくろ~)
・やりすぎてつめ焦げた。最終的にジョイボールで世界新。あーあ。(吉ダム)
スターフォース
ハドソン
1985.6.25発売
4900円
カートリッジ
スターフォース
・もとは「帝国管材」ことテーカン(現テクモ)のゲームです。シンプルなのが一番。(ふくろ~)
・素晴らし移植シリーズ。これの影響からかハドソン隠しボーナス好きに。(吉ダム)

ファミコンDataBase
http://www.geocities.jp/f_tamakoku/famicon/database/databaseframe.htm



















1985年4月2日火曜日

[ソフト] FC,ファミコン, Mother

今日のゲームは、ファミコンより発売されたMOTHERです!
軽快な音楽とアメリカンなキャラ登場のRPGで当時は、ずっとクリアまでやってました!
テレポートも確か距離がないと物にぶつかって出来ないと言った変わったシステムで考えながら使うと言ったのもありましたっけね(^_^;)
ファミコンは、結構思い出の多いソフトが多いな\(^o^)/
ーGoogle+

jdmuM pc   











1985年3月21日木曜日

[ソフト] ファミコン・ゲーム,1985.1.1~1985.4.21

[ソフト] ファミコン・ゲーム,1985.1.1~1985.4.21
1985.1.1~1985.4.21
◆ バルーンファイト
任天堂
1985.1.22発売
4500円
カートリッジ
・ドラえもーん、ボクも風船で飛びたいよー!(ふくろ~)
・ジャウストの100倍おもろい。バルーントリップモードも良いのら。(吉ダム)
◆アイスクライマー
任天堂
1985.1.30発売
4500円
カートリッジ
・最後、あの怪鳥につかまっちゃって大丈夫か?(ふくろ~)
・GCのスマブラでポポ&ナナが登場してますな。感慨深し。(吉ダム)
◆エクセリオン
ジャレコ
1985.2.11発売
4500円
カートリッジ
・ダブルビームよりシングルビームのほうが強い。渋い。(ふくろ~)
・まずはちゃんと面白かった。ですはい。(吉ダム)
◆ギャラガ
ナムコ
1985.2.15発売
4500円
カートリッジ
・味方を撃ったときの曲と、1000点がせつなく心に染みる。(ふくろ~)
・ボーナスステージのパターンしっかり覚えたり、昔は真面目にやってたなあ。(吉ダム)
◆ファミリーベーシックV3
任天堂
1985.2.21発売
9800円
カートリッジ
・誰も持ってなかったが、CMの「ブイスリ~~~~~」は真似した。(ふくろ~)
・やっぱCMだけは記憶に残ってるなあ。おれ遊ぶの専門でよろしく!(吉ダム)
◆バンゲリングベイ
ハドソン
1985.2.22発売
4900円
カートリッジ
・発売前の、コロコロの煽り記事はすごいものだったなあ。(ふくろ~)
・前評判の反動がすごかったあまりにクソゲーあつかい。(吉ダム)
◆フォーメーションZ
ジャレコ
1985.4.4発売
4500円
カートリッジ
・中ボスの名前、「サトゥ・テム・ユル・ボワク」は、ちょいやりすぎ。(ふくろ~)
・海上をジャンプで渡れるのだ!ってウラ技むずくてできね!(吉ダム)
◆サッカー
任天堂
1985.4.9発売
4500円
カートリッジ
・当時知っていたサッカー選手、釜本。ペレ。以上!(ふくろ~)
・微妙にフットサル。ロングシュート最強説。(吉ダム)
◆スペースインベーダー
タイトー
1985.4.17発売
4500円
カートリッジ
・ゼビウスの後に出たインベーダーを、君は買うか?爆弾発言。(ふくろ~)
・すでに私の世代なんも思いいれなし。スマン。(吉ダム)
◆チャンピオンシップロードランナー
ハドソン
1985.4.17発売
4900円
カートリッジ
・チャンピオンシップすぎ!1面しかクリアできなかった。(ふくろ~)
・タイミングが全てのやなむずかしさ。やりなおし覚悟でよろしく!(吉ダム)

FamilyComputer Database 







バルーンファイト
アイスクライマー
エクセリオン
ギャラガ
ファミリーベーシックV3
バンゲリングベイ
フォーメーションZ
サッカー
スペースインベーダー
チャンピオンシップロードランナー





















1985年2月26日火曜日

[機器][TVゲーム] 任天堂ファミコンディスクシステム













2013/3/2
「ファミコン ディスクシステム RAMアダプタ 回路図」  ファミコン
(改訂 2013/03/02)
ファミコン ディスクシステムのRAMアダプタについて回路図を起こしてみた。以前、途中まで書いてRP2C33のピンアサインが分からず放置していたもの。写真1,2はHVC-023 RAMアダプタのオモテ面外観。初期のものはシボ(表面処理)がない。後になってキズが付きやすいためか、シボ付きに変更されている。なお、左上にラベルで示してある形番は、中に入っていた基板の形番。
 初期のもの :基板 HVC-FMR-01 RP2C33 搭載
 中期?のもの:基板 HVC-FMR-04 RP2C33A 搭載
HVC-FMR-03もあるらしいが所有しておらず。
こちらによるとHVC-FMR-03まではRP2C33,DRAM4つ搭載の構成だったようです。
HVC-023 初期のRAMアダプタ オモテ
基板はHVC-FMR-01
初期のRAMアダプタは筐体表面に皺(シボ)加工が入っていないので表面に傷つきまくり
HVC-023 初期のRAMアダプタ オモテ
基板はHVC-FMR-04
HVC-FMR-01
・HVC-FMR-01,HVC-FMR-04回路図 Rev.05(PDF)
○Rev.05での変更点
2013年03月01日 回路図Rev.05
・EXT-PORT(P3) 9番ピン 音声を出力に修正
(SuperTurbo さんの情報提供・指摘により修正。ありがとうございました。)
・4069UB(U5)の未使用ピンNC表示追加
○Rev.04での変更点
・Rev.03での修正をDISK DRIVE CONNECTORに反映していなかったのでピン番号を変更
・EXT7/BATT信号のバス接続先が間違っていたので修正
・「VCC +5V」を「+5V」に修正
・「CLOCK」が「CLICK」になっていたので修正
・「PHI2」が意味のないところに記載されていたので削除
・図面タイトルに「HVC-FMR-04」が抜けていたので追加
なお、RP2C33、LH2833-15ピンアサインの情報はこちらを参照。
KEYWORD:ファミリーコンピュータ ファミコン ディスクシステム HVC-023 HVC-FMR-01 HVC-FMR-04 回路図 FC CIRCUIT SCHEMATIC DISK SYSTEM RP2C33 RP2C33A LH2833-15

子機器 Junker
https://green.ap.teacup.com/applet/junker/116/trackback













[機器][TVゲーム] 任天堂ファミコンディスクシステム
ファミコンディスクシステム
RAMアダプタに8KByteのROM(カスタムに内蔵)
32KByteのRAM($6000-$DFFF)、8KByteのキャラクタRAMのメモリを載せて
クィックディスク(QD)ドライブ込みで15、000円はかなり安い。
またドライブは通信アダプタの底面にあるコネクタ(ロットによっては無くなっている)でも接続可能
■RAM、拡張ポートテスト
スタートキーとセレクトーキーを押しながらリセットすると実行されます
このときにメインRAM$6000-$DFFFのチェック
次にPPU$0000-$1FFFをCPURAM$C000-$DFFFに転送してチェックを行います
エラーがあればOKと表示される所にエラーが出たアドレスが表示されます
$0000-$1FFFPPUのアドレス
$6000-$DFFFCPUのアドレス
拡張ポートのテストは左からBit0-Bit7の並びになっていて
$4026で拡張ポートにデータを書き込み、$4033で拡張ポートのデータを読み込みます
Cf=0にして$FFと左ローテイトで1つだけビットを0にして他は1にしてポートのチェックを行います
ただしBit7のBATTRY_SENCEはモータを起動していない為0(電圧NG)になります
■ROMの種類
RAMアダプタ内のROMはファミリーコンピュータ用の旧、新バージョンの2つ
ツインファミコンのデモでNintendoと出るのとFamicomとでるタイプの2つの計4つがあります
ROMのバージョンの判定方法はIコントローラのスタートキーとセレクトーキーを押しながらリセットすると、
RAM、拡張ポートテスト画面になりますが、そのテスト画面になる前に
Iコントローラの右とAを押すとメッセージがでます。
このときDEV2があれば新バージョン、数字が出ないのは旧バージョンになります
ツインファミコンの方は両方ともDEV2なので起動画面が違うだけのようです
■ROMバージョンの違いによる不都合
若干ROMエントリのアドレスが変っていますので、そこの部分をコールされると動かない可能性がでます
しかし実際に純正ソフトでは使わないようになっているようで実際問題での不都合はありません
非ライセンスソフトのDISKHACKERVer1.0では
FCBのブロックに$FFがあると新バージョンではエラーがでます(旧バージョンはそのままコピーが出来ます)
バックアップ活用研究のDISKCOPYでは
RAMアダプタのバージョンに合わせてアドレス変更して対応しています
NMI割り込み$E18B
ワークエリアの$0100のBit7-6(NMIコード)を見てジャンプするようになっています。
NMIコード
$00=RAMアダプタ用$E18B
$40=ゲーム用0JMP($DFF6)
$80=ゲーム用1JMP($DFF8)
$C0=ゲーム用2JMP($DFFA)
IRQ割り込み$E1C7
ディスクアクセスに使用
ワークエリアの$0101のBit7-6を見てジャンプします
IRQコード
$00=ディスクロード・スキップの終了
$01~$3F=ディスクロード・スキップnnバイト(nn=$01~$3F)
*$40=ディスク1バイト転送
読み込みの場合A、Xにデータが読み込まれる
書き込みの場合Aにデータをセットする
$80=ディスクステータスを読む
$C0=JMP($DFFE)
*$40だけPC-下位、PC-上位、PSRを空読みしてRTSを実行($E7A3の割り込みトラップから戻る為)
リセット割り込み$EE24
電源を入れるとオートリセットが掛かるので電源を入れるかリセットを押すとココにジャンプします
まずPPUの設定、その他のポートの設定、スタックの設定を行います
次にNMIコードを$C0、IRQコードを$80をセットします
リセットコードがあり使用アドレスは$0102-$0103のリセットコードによって動作が変わります
1.$0102が$35以外RAMアダプタのデモへ行きます。
2.$0102が$35、$0103が$53ならスクロールセット。JMP($DFFC)
3.$0102が$35、$0103が$ACなら$53にセット、スクロールセットしてJMP($DFFC)
4.$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タイマ下位クロックは1.79MHz
$4021:(出力)IRQタイマ上位
$4022:(出力)
Bit2:1=IRQタイマカウント開始、0=IRQタイマカウント停止
$4023:(出力)2C33タイマーコントロール
Bit1:サウウンド?T/Oのアクセス1=許可、0=禁止
Bit0:ディスクI/Oのアクセス1=許可、0=禁止
$4024:(出力)ディスクライトデータ(/WRITE_DATA)
1バイトのデータをシフトレジスタによって
/WRITE_DATAにシリアルデータで転送されます
$4023Bit0=1ディスクI/Oアクセス許可
$4025Bit2=0/WRITEGATEデータライト
$4030Bit7=1リード・ライト可能
の条件がそろってないと書き込めません
$4025:(出力)ディスクコントロール
Bit7:IRQデータ転送1=実行する、0=実行しない
Bit6:CRCレジスタ1=クリアする、0=クリアしない
Bit5:不明1=、0=
Bit4:CRC-Hコントロール1=行う、0=行わない
Bit3:スクロール1=スクロール-V、0=スクロール-H
Bit2:/WRITEGATE1=データリード、0=データライト
Bit1:/MOTOR1=モーターの回転停止、0=モーターの回転開始
Bit0:/RESET1=リセットを行わない、0=リセットを行う
不明ほとんど1になっている、CRC転送の実行?0だとデータ転送が出来ない
CRC-Hコントロールを行うと書き込みの場合CRC-Hが$4024に転送され
WaitでCRC-Hをディスクに書き込む?
読み込みの場合次にロードした$4031のデータとCRC-Hの比較を行い
結果を$4030のBit4(同じなら0)に出力する?
/RESETは転送タイミングのリセット
$4026:(出力)バッテリーコントロール、背面の拡張I/Oライト
Bit7:BATTRY_SENCE1=オン、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バイトのデータに変換されます
$4023Bit0=1ディスクI/Oアクセス許可
$4025Bit2=1/WRITEGATEデータリード
$4030Bit7=1リード・ライト可能
の条件がそろってないと読み込めません
???データを書き込んでいる場合(/WRITEGATE=0)はCRC-Lの値
$4032:(入力)ドライブステータス
Bit7:不明0
Bit6:不明1
Bit5:不明0
Bit4:不明0
Bit3:不明0
Bit2:/WRITE_PROTECT1=カード書き込み禁止、0=カード書き込み可
Bit1:/READY1=内部に移動している、0=スタート位置
Bit0:/MEDIA_SET1=セットされていない、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面)/片面$00のみ
ボリューム(ディスクの順番):1バイト2枚以上のソフトで使用$00から
ディスクの種類: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はディスクシステムに必要なデータでこれが無いとBIOSからのディスクアクセスが出来ません
$01-2はディスクの情報なりますディスクアクセスに必要なデータになります
ディスクサイド=$00(A面)、ボリューム=$00でないと起動出来ません
ゲームネームの最後の1バイトはイベント等を表し
$20=通常のディスク
$45=Eイベントディスクファックスを使った全国トーナメント
$52=Rリダクションインプライス広告による値引き
コールドスタートは起動時に読み込む最大ロードナンバで一括でファイルを読み込みます
$0Fの場合、ディスク内のロードナンバ$00~$0Fまで全て読み
ロードナンバ$10以上のファイルは読み込みません
$01-3は主にメーカー管理用
実際のディスクサイドはディスクライタで両面ソフトの書き換え時にチェックされます
もしディスクA面に$01(B面)のデータだとディスクライタはA面の書き換えチェック時にエラーを出します
プライスは値段や周辺機器の対応
書き換え回数が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バイト一番最初のファイルを$00として以降+1される
ロードナンバ:1バイト一括ロードするためのグループナンバ
ファイルネーム:8バイト
アドレス:2バイト下位、上位の順
ファイルの長さ:2バイト下位、上位の順
ファイルの種類:1バイト00=プログラム、01=キャラクタ、02=許諾ファイル
CRC:2バイト
ファイルナンバ最初のファイル(通常はKYODAKUファイル)を$00で次のファイルは$01になり
書き込む場合に使用されます(ファイルを追加するごとに+1)
ロードナンバ読み込むときに使用されるナンバで他のファイルにも同じナンバがある場合があります
同じナンバだと一度にロードする事が可能になります
ブロックコード$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ブロック分まで繰りかえす
起動時に必要なもの
1.ブロックコード$01-1’*NINTNDO-HVC’
2.ブロックコード$01-2ディスクサイド$00、ゲームボリューム$00、コールドスタート$nn
3.ブロックコード$02のマウントファイル数、マウントファイル数分のファイル
4.$00、$00に’KYODAKU-’の許諾ファイル
5.割込み、リセットベクタ($DFFA~$DFFF)のあるプログラムファイル
<例>リンクの冒険A面のファイル内容
ブロックコード$01
+--------------------------------+
|+0+1+2+3+4+5+6+7||
|-----------------------+--------|
|012A4E494E54454E|.*NINTEN|
|444F2D4856432A01|DO-HVC*.|
|4C4E4B2000000000|LNK....|
|000FFFFFFFFFFF62|.......b|
|0114496100000200|..Ia....|
|25021800620114FF|%...b...|
|FFFFFFFF00000000|........|
+--------------------------------+
’*NINTNDO-HVC’
メーカーコード$01
ゲームネーム’LNK’
ゲームバージョン$00
ディスクサイド$00A面
ボリューム$00
ディスクの種類FMC
予備1$00
コールドスタート$0F

ブロックコード$02
マウントファイル数=$07
ブロックコード$03
+-------------------------------------+
|Fnn|Lnn|ファイル名|アドレス|長さ|種類|
|---+---+--------+-----+-----+--------|
|$00|$00|KYODAKU-|$2800|$00E0|$02(許諾)|
|$01|$03|MAIN-PRG|$6340|$7CC0|$00(PRG)|
|$02|$28|CASTLE-L|$C000|$1FF6|$00(PRG)|
|$03|$29|ENDING-P|$D660|$0996|$00(PRG)|
|$04|$01|CHARA-00|$0000|$2000|$01(CHR)|
|$05|$14|CHARA-05|$0E00|$09C0|$01(CHR)|
|$06|$06|SAVE-DAT|$6000|$0338|$00(PRG)|
+-------------------------------------+
コールドスタート$0Fなので起動時L$00~$0Fのファイルをロード指定
ディスクサイドA面、ボリューム$00なので起動ディスクとみなしロード開始
$00$00KYODAKU-
$01$03MAIN-PRG
$04$01CHARA-00
$06$06SAVE-DATが一括ロードされる
一括ロード終了後、VRAMの$2800-$28DFに’KYADAKU-’がロードされたかチェックを行い
許諾ファイルがVRAMにロードされているのなら、上スクロールで許諾画面を表示して
’MAIN-PRG’の$DFFC-$DFFDのアドレスにジャンプします
■書き込む場合
CRCレジスタのリセット=0
GAP$00を書き込む
CRCレジスタのリセット=1

|スタートデータ$80以降を書き込む

CRCデータ下位の書き込み
CRCコントロール=1
CRCデータ上位の書き込み
読み込む場合
GAP$00を読み込む
CRCレジスタのリセット=1

|データを読み込む

CRCデータ下位の読み込む
CRCコントロール=1
CRCデータ上位の読み込む
ブロックコード$01の書き込み例
JSR$E64D;BootDiskDrive
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;WriteCRC
エラー
■ドライブ&ディスクセット関連
01:DISKSETERR.01ディスクが正しくセットされていない
02:BATTERYERR.02ディスクドライブの電圧が規定値以下になっている
03:WRITEPROTECTERR.03ライトプロテクトのツメが折れているのに書き込もうとした
04:GAMEMAKERERR.04違ったメーカのディスクがセットされた
05:GAMENAMEERR.05違ったゲームのディスクがセットされた
06:GAMEVERSIONERR.06違ったバージョンのディスクがセットされた
07:A.B.SIDEERR07違ったサイドのディスク(表と裏)がセットされた
08:DISKNUMBERERR.08違った順番のディスクがセットされた
09:ERR.09違ったディスクの種類がセットされた
10:ERR.10違った予備1のデータがセットされた
08はROM内ではDISKNO.ERR.08として出力
11-19はディスクライター用?
ファイルアクセス関連
20:DISKTROUBLEERR.20許諾ファイルが読み込めない
21:DISKTROUBLEERR.21ブロックコード$01の*NINTENDO-HVC*が見つからない
22:DISKTROUBLEERR.22ブロックコード$01の開始マーク$01が見つからない
23:DISKTROUBLEERR.23ブロックコード$02の開始マーク$02が見つからない
24:DISKTROUBLEERR.24ブロックコード$03の開始マーク$03が見つからない
25:DISKTROUBLEERR.25ブロックコード$04の開始マーク$04が見つからない
26:DISKTROUBLEERR.26ディスクに正しく書き込みが出来ない
27:DISKTROUBLEERR.27CRCエラーを検出
28:DISKTROUBLEERR.28ディスクの読み込みでタイミングが合っていない(読み込み途中でヘッドが最後まで行った)
29:DISKTROUBLEERR.29ディスクの書き込みでタイミングが合っていない(書き込み途中でヘッドが最後まで行った)
ユーザーセーブ関連
30:DISKTROUBLEERR.30ディスクに書き込みが出来なくなった(容量不足またはドライブ・プロテクトによる強制終了)
31:DISKTROUBLEERR.31ディスクのデータ数が合わない、または書き込もうとしたマウントファイル数がマイナスになった
35:DISKTROUBLEERR.35テストファイル(ブロックコード$05ファイル)の書き込み失敗
その他
40:DISKTROUBLEERR.40一括ロードでロード出来なかったファイルがあった(ファイル数が足りない)
41:DISKTROUBLEERR.41不明(きね子IIの説明書にERR.41~の表記あり)
*DISKTROUBLEERR.35以降はROMルーチンではなくソフトのルーチンでエラーの判断を行います
DISKROM エントリ
$E000:00
$E001-$E148:キャラクタデータ(文字)
$E149:Wait
$E153:nnミリWait
入力:Y=nnミリ
使用:X、Y
Yミリ秒のウェイトをかけます
ルーチン内で$0000をロード、コンペアの実行を行っていますが
時間稼ぎの為で内容の変更はありません
主にディスクアクセスのタイミングに使用
$E161:OBJ+BGOff
使用:A
$00FE
スプライトとBG画面を表示しません。
$E16B:OBJ+BGOn
使用:A
$00FE
スプライトとBG画面を表示します。
$E171:OBJOff
使用:A
$00FE
スプライトを表示しません。
$E178:OBJOn
使用:A
$00FE
スプライトを表示します。
$E17E:BGOff
使用:A
$00FE
BG画面を表示しません。
$E185:BGOn
使用: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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$24=DISKTROUBLEERR.24
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$26=DISKTROUBLEERR.26
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$26=DISKTROUBLEERR.26
$27=DISKTROUBLEERR.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ファイルデータ下位,ファイルデータ上位
BNEERROR

$01-2データはメーカーコードからコールドスタートの次の$FFまで
ファイルデータはブロックコード$03のロードナンバからファイルタイプまで
ファイルデータに記されているアドレスと長さが書き込む範囲になります
$E26B:ファイルセーブ(メイン)
入力:$0000=ブロックコード$01-2比較データアドレス下位
$0001=ブロックコード$01-2比較データアドレス上位
$0002=ブロックコード$03データアドレス下位
$0003=ブロックコード$03データアドレス上位
$000E=$00から$FE$0006で指定した場所-1にセーブ
$FF最後にセーブ
出力:A=エラーコード$00=エラー無し
$01=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$26=DISKTROUBLEERR.26
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$27=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$27=DISKTROUBLEERR.27
$29=DISKTROUBLEERR.29
$30=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$27=DISKTROUBLEERR.27
$29=DISKTROUBLEERR.29
$30=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.02
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$27=DISKTROUBLEERR.27
$29=DISKTROUBLEERR.29
$30=DISKTROUBLEERR.30
使用:A、X、Y
$0002
$0004
$0005
$0006
$0007
$00FA
$0101
スタック
ブロックコード$01-2のチェックを行ってから
マウントファイル数+nnを書き込みます
$E32A:ディスクインフォメーションの収得
入力:1st=ディスクインフォメーションアドレスの下位
2nd=ディスクインフォメーションアドレスの上位
出力:A=エラーコード$00=エラー無し
$01=DISKSETERR.01
$02=BATTERYERR.02
$21=DISKTROUBLEERR.21
$27=DISKTROUBLEERR.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ロードナンバー001バイトファイルの順番00のロードナンバ(ブロックコード$03のデータ)
+0Cファイルネーム008バイトファイルの順番00のファイルネーム(ブロックコード$03のデータ)

|以降ファイル数分のファイルが続き最後にディスクの総容量

+nnディスクの総容量の下位
+mmディスクの総容量の上位
ディスクの総容量はヘッダ部分+00~+0A10バイト
ファイル部分ファイルの順番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=DISKSETERR
使用: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バイトセットの場合)
$000E=パラメータnnバイトの値(0か2エラーの場合)
A=エラーコード$00=エラー無し
$01=DISKSETERR
$03=WRITEPROTECTERR
$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パラメータ
3rdパラメータ(パラメータ4バイトセットの場合)
$0003=4thパラメータ(パラメータ4バイトセットの場合)
$000E=パラメータnnバイトの値(0か2エラーの場合)
A=ロードの場合$00=エラー無し
$01=DISKSETERR.01
セーブの場合$00=エラー無し
$01=DISKSETERR.01
$03=WRITEPROTECTERR.03
使用:A、X、Y
$0004
$0005
$0006
スタック
$0000からそれぞれ対応するデータをセットして
Aレジスタにディスクの状態を送ります
セーブの状態なら$E3EAをサブルーチンコールをすれば良いのですが
エラーが発生するとRTSする前にスタック操作を行って
このルーチンを実行したルーチンを強制終了されます
$E445:ブロックコード$01リード、チェック
$0001=ブロックコード$01-2比較データアドレス上位
出力:A=エラーコード$00=エラー無し
$01=DISKSETERR.01
$02=BATTERYERR.02
$04=GAMEMAKERERR.04
$05=GAMENAMEERR.05
$06=GAMEVERSIONERR.06
$07=A.B.SIDEERR07
$08=DISKNUMBERERR.08
$09=ERR.09
$10=ERR.10
$21=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$27=DISKTROUBLEERR.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=DISKTROUBLEERR.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=DISKSETERR.01
$02=BATTERYERR.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=DISKTROUBLEERR.21
$22=DISKTROUBLEERR.22
$23=DISKTROUBLEERR.23
$24=DISKTROUBLEERR.24
使用:A、X、Y
$0004
$0007
$00F9
$00FA
$0101
CRCレジスタをリセットを行い、
1バイト読み込んだデータをブロックコードとして読みます
ヘッドが予めブロックコードのある所にいなければなりません
$E6B0:ブロックコードの書き込み
入力:A=ブロックコード
$3F1F-$3F1Fカラーパレット
使用: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=DISKSETERR.01
$02=BATTERYERR.02
$21=DISKTROUBLEERR.21
使用:A、X、Y
$0004
$0007
$00F8
$00F9
$00FA
ドライブを起動し
ブロックコード$01-1の'*NINTENDO-HVC*'があるかチェックを行います
*NINTENDO-HVC*'が無ければドライブを止め
Aレジスタにエラーコード$21を返します
$E706:CRCリード
出力:A=エラーコード$00=エラー無し
$01=DISKSETERR.01
$27=DISKTROUBLEERR.27
$28=DISKTROUBLEERR.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=DISKSETERR.01
$29=DISKTROUBLEERR.29
$30=DISKTROUBLEERR.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=DISKSETERR.01
$28=DISKTROUBLEERR.28
エラーコード$28(エラーの場合)
使用:$00FA
2バイトロードしてドライブをクローズします
CRCチェックは行いません
エラーチェックはヘッドの検知を行います
CRCデータのロード?
$E778:ドライブのクローズ(エラー無し)
入力:
出力:A=エラーコード$00=エラー無し
使用:A、X
$00FA
X=$00(エラー無し)として
ドライブクローズ($E786)を実行します
当然、出力でAレジスタには$00が入ります
$E77F:ディスクコンペアデータZfチェック
入力:Zf=0比較データと違う
1比較データと同じ
出力:A=エラーコード(Zf=0で入力の場合)
使用:$0004
$00FA
前もってデータを比較したりしてZfの変化を見るルーチンになります
入力でZf=1なら何もせずRTS
0ならエラー
エラーでは$0004のスタックデータをスタックポインタにして
ドライブクローズ、エラー出力して強制終了します
$E786:ドライブクローズ
入力:X=エラーコード
出力:A=エラーコード(Xレジスタの値)
使用:A、X
$00FA
$4025Bit7:0
6:0
5:1
4:0
3:*
2:1
1:1
0:*
XレジスタをAレジスタにコピーして、IRQをオンにします
$E794:IRQ1バイト転送の開始
入力:A=ライトデータ(書き込みの場合)
出力:A=CRC下位(書き込みの場合)
X=リードデータ(読み込みの場合)
A=リードデータ(読み込みの場合)
使用:$00FA
$0101
IRQコードを$40(0101:40)
IRQデータ転送を1($4025のBit7=1)にして
下の$E7A3(IRQ1バイト転送)を実行します
ディスクのリード・ライトの始めに使用しますが事前に
CRCレジスタをクリアしていないとCRC計算が正しく行われません
$E7A3:IRQ1バイト転送
入力: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のサブルーチンによってはJSRnnmmの後にパラメータを設定するのですが
それらのサブルーチンが使用して、パラメータを読みRTSする為のスタックを調節します
$0005から$0006の内容が壊れます
$E86A:VRAMバッファ出力
入力:$0302=バッファデータ00VRAMアドレス上位
$0303=バッファデータ00VRAMアドレス下位
$0304=バッファデータ00データの長さ
$0305=バッファデータ00VRAMに書き込むデータ

$03nn=エンドマーク($80から$FF)
出力:$0301=$00
$0302=エンドマーク$80から$FF(実際には$FF)
使用:A、X、Y
$00FF
PPUアクセス時のアドレスの増加をX方向($2000Bit2=0)にして
VRAMバッファからアドレス、長さを取得してVRAMにバッファデータを書き込みます
バッファデータの第1バイトのVRAMアドレスが$80から$FFだとエンドマークになります
データフォーマット
バッファデータ00VRAMアドレス上位
バッファデータ00VRAMアドレス下位
バッファデータ00出力データの長さ
バッファデータ00出力データ

バッファデータnnVRAMアドレス上位
バッファデータnnVRAMアドレス下位
バッファデータnn出力データの長さ
バッファデータnn出力データ
エンドマーク($80から$FF)
$E8B3:VRAMバッファ入力
入力:X=インデックス($02から)
Y=転送するバイト数
$0302=データ00VRAMアドレス上位
$0303=データ00VRAMアドレス下位
$0305=データ01VRAMアドレス上位
$0306=データ01VRAMアドレス下位

出力:$0304=指定したデータ00のVRAMの内容
$0307=指定したデータ01のVRAMの内容

使用:A、X、Y
$0302にあるVRAMバッファにVRAMの内容を転送します
1バイトごとの転送なので3バイト1組になります
入力するXレジスタの値は$02以上になります
VRAMバッファは
+00VRAMアドレス上位
+01VRAMアドレス下位
+02VRAMの内容(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
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エリアセット
使用:A
仮想OBJを$0200に設定します。
$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をコールして得たデータをIコン、IIコンの2つにまとめます
$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をアクセスした後スクロールセットをするのに使用します
スクロールをセット
PPUR#0を$00FFの内容でセット
$EAFD:テーブルジャンプ
入力:A=テーブジャンプNo.nn($00-$7Fまで)
1st=テーブルジャンプNo.$00下位アドレス
2nd=テーブルジャンプNo.$00上位アドレス
3rd=テーブルジャンプNo.$01下位アドレス
4th=テーブルジャンプNo.$01上位アドレス

使用:A、X、Y
$0000
$0001
テーブルジャンプを行います
BASICのONAGOTOnnnn,mmmm,...に相当
使用例
JSR$EAFD
DWADDRESS0;A=$00のジャンプ
DWADDRESS1;A=$01のジャンプ
DWADDRESS2;A=$02のジャンプ

$EB13:HVC-007キーボードのキーマトリクス入力
出力:$0000=キーマトリクスP29の反転データ
$0001=キーマトリクスP28の反転データ
$0002=キーマトリクスP27の反転データ
$0003=キーマトリクスP26の反転データ
$0004=キーマトリクスP25の反転データ
$0005=キーマトリクスP24の反転データ
$0006=キーマトリクスP23の反転データ
$0007=キーマトリクスP22の反転データ
$0008=キーマトリクスP21の反転データ
使用:A、X、Y
$00FB
ファミリーBASICのキーボード(HVC-0007)のキーマトリクス入力を行います
出力データは反転されているので押していると1、離している0になります
P31がBit0...P38がBit7になります
$EB66:ポインタ+8バイト、Y=#$00、DEC($02)
入力:$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)
出力:Y=$00
$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)-1
使用:A、Y
$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)
$0000から$0001をポインタとして
ポインタ+8
Y=#$00
$0002の内容を-1にします
パターンテーブル定義用
$EB69:ポインタ+Aバイト、Y=#$00、DEC($02)
入力:A=ポインタにプラスする値
$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)
出力:Y=$00
$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)-1
使用:A、Y
$0000=ポインタ下位
$0001=ポインタ上位
$0002=ブロック(長さ)
$0000から$0001をポインタとして
ポインタ+A
Y=#$00
$0002の内容を-1にします
パターンテーブル定義用
$EBAF:パターンテーブル定義
入力:Y=PPUアドレス上位
A=PPUアドレス下位+コード
Bit7:PPUアドレスA7
Bit6:PPUアドレスA6
Bit5:PPUアドレスA5
Bit4:PPUアドレスA4
Bit3:コードD111=反転通常、10=埋める通常
Bit2:コードD001=通常埋める、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=ロード・スキップの終了
$01-$3F=ロード・スキップバイト
$40=ディスク1バイトリード・ライト
$80=ディスクステータス
$C0=JMP($DFFE)
$0102-$0103:RESETコントロール
$0102:3553=JMP($DFFC)
$0102:35AC=$0103を$53にしてスクロールセットの後、JMP($DFFC)
それ以外のデータはデモ
$0200-$02FF:仮想OBJエリア
$0300-$03FF:VRAMバッファ
■ディスクドライブのプロテクト
最初のドライブにはプロテクトは掛かっていませんでしたがコピープログラムの発表や発売され
一定時間(約1秒)しか書き込みが出来ないようになりました。
プロテクトの内容はドライブ内の基板でライト信号が送られたらカウントして約1秒たったら
シャットダウンする方式でコレをパターンカットとバイバスを通して無効する方法があります。
最終的にはFDC自身に同等のプロテクトを掛けるのですがロジック回路で破られています。
ソフトでのプロテクト
元々QDなのでそれほどきついプロテクトは掛けられません。
特定のソフトのコピーツールに対してのプロテクトとなります。
またPCから読み書きやデュプリケータでは全くプロテクトの意味がありません。
ダミーファイル
ブロックコード$02のマウントファイル数より多くファイルを持つタイプ
とびだせ大作戦、夢工場ドキドキパニック、ディープダンジョンII勇士の紋章(店頭販売、書き換え共)が該当します
主に対DISKHACKERV1.1用です
DISKHACKERV1.1までではファイル数を見て必要なファイルだけをコピーしていました
とびだせ大作戦のA面では実際のファイルはブロックコード$02のファイル数より1つ多く
DISKHACKERV1.1でコピーすると最後の1つだけファイルが足りないものになります
そのファイルが無ければコピー品と判断しています
ダミーファイルとはいえ、とびだせ大作戦はダミーファイルが本当のメインプログラムになっていて
ゲームスタートするとMAINPROG(警告プログラム)がロードされ、その後すぐにダミーファイル(本当のメイン)が
RAMに上書きされ実行されます
ダミーファイルが上書きされないと警告プログラムが動いてコピー品とみなされメッセージを出します
夢工場ドキドキパニック、ディープダンジョンII勇士の紋章では数バイトのデータが書き込まれていて
このファイルがロード出来るかでコピー品の判断を行っています。
とびだせ大作戦ではコピー失敗すると作者からメッセージが出ます。
夢工場ドキドキパニックのコピー失敗
勇士の紋章のコピー失敗
新鬼ヶ島のコピー失敗
40KBファイル
コピーツールのバッファより大きいファイルを持つタイプ
麻雀家族、スーパーロードランナーが該当
1つのファイルがRAM容量よりも大きくなっています
ファイルが40KBのファイルがあり、コピーバッファが少ないとコピー出来ないようになっています
主に対DISKHACKERV1.2用
DISKHACKERV1.3ではV1.2より大きいバッファを持ちコピー出来ます。
ファミコンのディスクはランダムアクセスが出来ないQDなのでトラックやセクタ等は無く
テープと同じように最低でも一つのファイルを一気に書き込まないといけません
つまり分割して一つのファイルを書き込みする事はかなり困難になります
しかし、本体メモリは32KB(RAMアダプタ)+2KB(ワーク)+2KB(VRAM)+キャラクタ(8K)計44KBなので
4KB内でコピープログラム、最低限40KBのバッファを取ってコピー出来るツールもあります
スーパーロードランナーではSIDEAの4番目のファイルLRMAIN01が
ロードアドレス$6000で長さ$A000になります
3番目のファイルPROTECT(ローダ)を本体内ワークRAMにローダを転送、実行
LRMAIN01は$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を出力して
コピーできないようになっています
DEV1のRAMディスクとディスクハッカーVer1.0ではエラーが出ずにコピー出来ます
DEV2のRAMディスクとディスクハッカーVer1.0ではエラーFFが出てコピー出来ません
他のコピーツールではコピーが出来ますが44KBファイルはコピーできません
プログラム書き換えチェック
これはプロテクトといってもコピープロテクトでは無くプログラムの改造されたかチェックをするタイプ
改造するとチェックサムエラーのメッセージが出たり、起動画面に飛んだり、ゲームが起動出来ない様になっています
ただし完全なチェックを行っているとは限りません(コピーライト表記の書き換えを阻止するだけの為?)
コナミやカプコンのソフトに見かけます
セクションZのチェックサムエラーメッセージ
ナムコのディスクソフト
プロテクトでは無いのですがナムコのディスクソフトは非ライセンスソフトと同じような
許諾画面を出さないような事をしています。
実際には許諾画面を出しているのですがRAMアダプタのプログラムで動いてなくて
ゲームソフト(IPLMAIN)が割り込みでRAMアダプタからの許諾画面表示
を乗っ取っていながらゲームソフトから許諾画面を表示しています。
これにより任天堂が許諾画面表示の乗っ取りプログラムに対する
プロテクトを掛けるのが難しくなっています
つまりプロテクトを掛けるのを防ぐ為の任天堂に対する逆プロテクト(?)に思えますが
真相は不明です。

Enri's HP
http://www43.tok2.com/home/cmpslv/














1985年2月12日火曜日

[機器][TVゲーム] 任天堂ファミコンディスクシステム,マッパー206

[機器][TVゲーム] 任天堂ファミコンディスクシステム,マッパー206
ファミリーコンピューターROMカセットマッパー206(namcot34xx)
PRG128KB16バンク8KB
CHR64KB64バンク1KBまたは2KB
$8000:コマンドNo.nn(nn=$00-$06)
$8001:バンクNo.mm(PPUバンクmm=$00-$3F1KBまたは2KBごと)
(CPUバンク$00-$0F8KBごと)
コマンド$00PPU$0000-$07FFCHRバンク2ブロック単位の指定(最下位ビットは無視$01なら$00-$01の範囲?)
$01PPU$0800-$0FFFCHRバンク2ブロック単位の指定(最下位ビットは無視$01なら$00-$01の範囲?)
$02PPU$1000-$13FFCHRバンク1ブロック単位の指定
$03PPU$1400-$17FFCHRバンク1ブロック単位の指定
$04PPU$1800-$1BFFCHRバンク1ブロック単位の指定
$05PPU$1C00-$1FFFCHRバンク1ブロック単位の指定
$06CPU$8000-$9FFFPRGバンク
$07CPU$A000-$BFFFPRGバンク
PPU$0000-$07FFパターンテーブル0-02KB
PPU$0800-$0FFFパターンテーブル0-12KB
PPU$1000-$13FFパターンテーブル1-01KB
PPU$1400-$17FFパターンテーブル1-11KB
PPU$1800-$1BFFパターンテーブル1-21KB
PPU$1C00-$1FFFパターンテーブル1-31KB
パターンテーブル0128キャラクタ
パターンテーブル164キャラクタごとの切換えが可能になります
ワルキューレの冒険の回路図(3407)PRG32K、CHR32KB
その為A14はそのまま接続されプログラム領域は$8000-$FFFFでPRGバンク切換え無し
CHRのみのバンク切換えとなります
PRG$8000-$9FFFバンク$0C(設定する)
$A000-$BFFFバンク$0D(設定する)
$C000-$FFFFバンク$0E、$0F(固定)
CPU$C000-$FFFFはPRGバンク$0E、$0Fが出力されるので便宜上バンク$0C,$0Dに設定してるようです
カイの冒険の回路図(3416)PRG128K、CHR64KB

Enri's HP
http://www43.tok2.com/home/cmpslv/





1985年1月28日月曜日

1985年1月24日木曜日

[ゲーム][TVゲーム] 任天堂ファミリーコンピュータ・ゲーム,1985.1~1985.4発売分,

◆バルーンファイト
任天堂
1985.1.22発売
カートリッジ
バルーンファイト
・ドラえもーん、ボクも風船で飛びたいよー!(ふくろ~)
・ジャウストの100倍おもろい。バルーントリップモードも良いのら。(吉ダム)
◆アイスクライマー
任天堂
1985.1.30発売
4500円
カートリッジ
アイスクライマー
・最後、あの怪鳥につかまっちゃって大丈夫か?(ふくろ~)
◆エクセリオン
ジャレコ
1985.2.11発売
4500円
カートリッジ
◆エクセリオン
・ダブルビームよりシングルビームのほうが強い。渋い。(ふくろ~)
・まずはちゃんと面白かった。ですはい。(吉ダム)
◆ギャラガ
ナムコ
1985.2.15発売
4500円
カートリッジ
ギャラガ
・味方を撃ったときの曲と、1000点がせつなく心に染みる。(ふくろ~)
・ボーナスステージのパターンしっかり覚えたり、昔は真面目にやってたなあ。(吉ダム)
◆ファミリーベーシックV3
任天堂
1985.2.21発売
9800円
カートリッジ
ファミベV3
・誰も持ってなかったが、CMの「ブイスリ~~~~~」は真似した。(ふくろ~)
・やっぱCMだけは記憶に残ってるなあ。おれ遊ぶの専門でよろしく!(吉ダム)
◆バンゲリングベイ
ハドソン
1985.2.22発売
4900円
カートリッジ
バンゲリングベイ
・発売前の、コロコロの煽り記事はすごいものだったなあ。(ふくろ~)
・前評判の反動がすごかったあまりにクソゲーあつかい。(吉ダム)
◆フォーメーションZ
ジャレコ
1985.4.4発売
4500円
フォーメーションZ
あんた誰!?
・中ボスの名前、「サトゥ・テム・ユル・ボワク」は、ちょいやりすぎ。(ふくろ~)
・海上をジャンプで渡れるのだ!ってウラ技むずくてできね!(吉ダム)
◆サッカー
任天堂
1985.4.9発売
4500円
カートリッジ
サッカー
・当時知っていたサッカー選手、釜本。ペレ。以上!(ふくろ~)
・微妙にフットサル。ロングシュート最強説。(吉ダム)
◆スペースインベーダー
タイトー
1985.4.17発売
4500円
カートリッジ
インベーダー
・ゼビウスの後に出たインベーダーを、君は買うか?爆弾発言。(ふくろ~)
・すでに私の世代なんも思いいれなし。スマン。(吉ダム)
◆チャンピオンシップロードランナー
ハドソン
1985.4.17発売
4900円
カートリッジ
チャンピオンシップロードランナー
・チャンピオンシップすぎ!1面しかクリアできなかった。(ふくろ~)
・タイミングが全てのやなむずかしさ。やりなおし覚悟でよろしく!(吉ダム)

ファミコンDataBase
http://www.geocities.jp/f_tamakoku/famicon/database/databaseframe.htm