コグノスケ


link 未来から過去へ表示(*)
link 過去から未来へ表示

link もっと前
   2021年 10月 7日 ---> 2021年 9月 28日
link もっと後

2021年 10月 7日

MiMight and Magic Book One のメインクエスト紹介

目次: Might and Magic ファミコン版 - まとめリンク

ファミコン版 Might and Magic Book One にはたくさんのクエストがありますが、クリアに必要なクエストはさほど多くありません。図示するとこんな感じです。


クエスト、アイテムの依存関係

なお、ファミコン版 Might and Magic Book One の情報は、マイトアンドマジック 1 攻略情報 さんが非常に参考になります。地図がめっちゃ見やすいです。

メインクエスト紹介(手紙、兄弟、真のアラマー王)

クエストの位置など詳しい情報は攻略情報さんを見ていただくとして、下記では TAS で使った攻略ルートを簡単に説明します。

盗賊への転職
ソーピガルの町の [X: 2, Y: 13] にあるギルドに行って盗賊に転職します。Lv.1 クリアには盗賊が必須です。盗賊以外を選ぶと扉の鍵が解除できなくて進めなくなります。Might and Magic はさ、どうぞどうぞ、と投げ出されたイベントアイテムにすら罠が仕掛けてある鬼畜仕様のため、アイテム拾うだけで盗賊が必須です。
ソーピガルからの脱出
ソーピガル → ソーピガル地下 [14, 0] → ノーザンバリアー洞穴 → 地上エリア C2 の経路で移動し、町の外に出ます。ソーピガルの町の出口から出たいところですが、Lv.1 で出口に行くと衛兵に「未熟者」と言われて追い返され、ソーピガルの町から出してくれません。
アイスプリンセスのクエスト(ダイヤの鍵)
C2 → C1 → B1 → B2 の経路で移動し、[4, 4] にいるアイスプリンセスの問いに答えると、革袋がもらえて、中にダイヤの鍵が入っています。このクエストだけ、なぜか「さがす」必要はありません。ダイヤの鍵はテレポート 20回分の魔法が込められていて、とても便利な移動手段です。C2 → B2 は近道に見えますが、残念ながらアイスプリンセスに辿り着く道がありません。
GEM の入手
B2 → B3 → コリンブルッフ洞穴にいき、ダイヤの鍵を使ったテレポートで宝箱([1, 1] [0, 3] [1, 5] のどれでも OK)の真上に飛びます。アイテムはクリアに不要ですが、一緒に手に入る GEM は後で使います。GEM もクリア時間短縮に欠かせない存在です。
手紙のクエスト(手紙 その 1)
コリンブルッフ洞穴 → ソーピガル地下 [1, 2] へ行きコーラックからクエストを受けます。エルキューンのアガールに手紙を渡してくれと言われます。
手紙のクエスト(手紙 その 2)
ソーピガル地下 → ソーピガル →(転送)→ エルキューンの経路で移動します。転送というのは、ソーピガル [11, 3] にいるおじさんのこと(GEM 1個でどの町でも送ってくれる)です。宿屋の奥 [4, 3] にいるアガールに手紙を渡すと、別の手紙を渡されてダスクのテルゴランに渡してくれと言われます。
オーラのクエスト
エルキューン → B1 → C1 → C2 → ソーピガルの経路で移動します。道すがら別のクエストを進めます。
  • C2 [8, 8]: 占いオババと会いオーラの色を調べます。後のクエストで聞かれる(さんごの鍵)のでメモをお忘れなきよう。
手紙のクエスト
ソーピガル →(転送)→ ダスクの経路で移動します。テルゴランは迷路の先 [8, 0] にいます。この町はテレポート無効なので、地道に歩きましょう。テルゴランに手紙を渡すとアルガリーのゾム、ポートスミスのザムの兄弟に会ってくれと言われます。
兄弟のクエスト
ダスク → ダスクの地下 → ソーピガル →(転送)→ アルガリー → ポートスミスの経路で移動し、兄弟に会います。歩いて会おうとすると大量の強制エンカウントで時間が掛かるので、テレポートで全部飛ばします。ゾムザム兄弟はどちらが先でも良いですが、ポートスミス → アルガリーだとポータルもなく移動も辛いので、アルガリー → ポートスミスがおススメです。
  • アルガリー [1, 1]: ゾム
  • ポートスミス [12, 2]: ザム
市民のパスポート、兄弟のクエスト(ルビーの笛)
ポートスミス → B3 → B2 → B1 → C1 の経路で移動します。C1 [7, 7] でゴールデンバウムという金ぴかの木を見て、ゾムザム兄弟の伝言通りに歩き [15, 15] へ行くと、ルビーの笛が沸いてきます。基本的に「さがす」しないとモノが手に入らないゲームですが、このクエストだけ「さがす」をする必要がありません。変なクエスト……。
  • C1 [5, 7]: 市民のパスポート(城に入るために必要)を取る、馬車を調べるか?に「はい」、その後「さがす」です。
  • C1 [7, 7], [15, 15]: ゴールデンバウムとルビーの笛です。
フック付きロープ
C1 → C2 → ソーピガルの経路で移動し、店で「フック付きロープ」を 10G で買います。ソーピガル以外にも売っていますので、ソーピガル以外でも構いません。デューム城で使うので、その前に買っておいてください。
真のアラマー王のクエスト(金の鍵)
ソーピガル →(転送)→ ポートスミス → B3 → 魔法の砦の経路で移動し、魔法の砦 B2 の [3, 4] にいる犬の像まで行きます。テレポート活用が吉です。犬の像と話した後に「さがす」と金の鍵が拾えます。デューム城で使います。
真のアラマー王のクエスト(貴族のパスポート)
B3 → B2 → A2 の経路で移動し、迷路の奥 [0, 15] にいるドルイドのパルセラの問いに「はい」と答えた後に「さがす」と貴族のパスポートが拾えます。アラマー城で使います。エリア A2 はテレポートが使えないので地道に歩きましょう。
真のアラマー王のクエスト(ゴロスのめだま)
A2 → B2 → B1 → A1 → デューム城の石垣 → デューム城内部の経路で移動します。エリア A1 もテレポートが使えないので、地道に歩きますが、迷路がクッソ長くて辛いです。
  • A1 [7, 14]: デューム城の石垣、内部への入り口です。
  • デューム城 [8, 5] [6, 6] [7, 10]: 壁の外に押し戻される罠(三カ所)、フック付きロープで飛び越えましょう。
  • デューム城 [7, 7]: 金の鍵を持たずに行くと扉に吹き飛ばされます。
  • デューム城 [7, 8]: 真のアラマー王と話した後「さがす」と「ゴロスのめだま」を拾えます。
ニセのアラマー王の正体クエスト
デューム城 → A1 → B1 → C1 → C2 → ソーピガル →(転送)→ ダスク → E1 → E2 → E3 → アラマー城の経路で移動します。アラマー城に入るにはハレーショにパスワードを聞いて、ライオンのレリーフに答える必要がありますが、テレポートで全て無視して入り口 [14, 7] に直行できます。必要なアイテムを所持していればニセのアラマー王に「正体を見破ったな」と言われ、イドの迷宮に飛ばされます。
  • 市民のパスポート: 持たずに入り口に行くと、衛兵に追い返されます。
  • 貴族のパスポート: 持たずに王の部屋の前に行くと、衛兵に追い返されます。
  • ゴロスのめだま: 持たずにニセのアラマー王に会うと、クリア不能クエストを押し付けられます(僧侶の「ちゅうし」でキャンセルするしかない)
イドの迷宮
英語版だと Soul Maze ですが、日本語版は「イドの迷宮」という全然違う名前で、ニセのアラマー王のセリフ「ソウルメイズの地に監禁」が意味不明に見えます。訳を間違ったのかなあ……?本来はマッピングしてパスワードを知ります。「いちをしる」魔法が使えないため、マッピングの難易度は高いです。しかしパスワードは固定なので正解を知っていれば瞬殺です。クリア後はソーピガルに戻されます。

以上が Might and Magic の世界に起こった事件と、その謎に迫るメインクエストを超スピード解決する手順となります。初めてプレイする方がこの手順でクリアすると、たぶん訳が分からないと思います。

お時間がある方は、攻略サイトを見ながらでも構わないので、金の板や町のヒント、囚人たちなどに出会い話すと、しっかり作られた世界感が味わえると思います。

メインクエスト紹介(オーラ、アストラル世界)

もう一つのメインクエストの流れです。オーラのクエストは、ストーリーにはあまり関係ないです。ラストダンジョンの歯ごたえを増すためのクエストという感じです。アストラル世界は全てのストーリーの終着点で、ああ、そういうことだったんだ!と思うはずです。

オーラのクエスト(さんごの鍵)
ソーピガル → ポートスミス → B3 → B4 → A4 の経路で移動します。[4, 6] にいる老人に、各キャラクターのオーラの色を答えます。オーラはエリア C2 の占いオババに教えてもらった色です。正解すると [4, 2] に飛ばされるので、その場で旋回(移動しちゃダメ)、「さがす」で「さんごの鍵」を拾えます。
オーラのクエスト(金色のオーラ)
A4 → B4 → C4 の経路で移動します。先頭のキャラクターにさんごの鍵を持たせて [7, 2] で南を向くと、ボルカノ神殿に入れます。ボルカノ神殿 [7, 11] の火山の神に「なぞ」を出してもらって、答えると「金色のオーラ」にしてもらえます。ボルカノ神殿の入り口のある島は、テレポートで入れますが、テレポートで出ることはできません。注意。
オーラのクエスト(キーカード)
C4 → B4 → A4 の経路で移動します。[4, 6] にいる老人に会うと、また [4, 2] に飛ばされるので、その場で旋回、「さがす」で「キーカード」を拾えます。
アストラル世界
ゴロスのめだまを使ってアストラル世界に飛びます。壁がほぼすべて透明のバリアで構成されている鬼畜が考えたダンジョンです。迷ってしまったら敵から逃げれば、かならずスタート地点の [7, 0] に戻れるので、敵を倒すばかりでなくうまく使いましょう。
  • 5カ所の封印: [4, 6] [4, 10] [7, 14] [10, 10] [10, 6] にある封印を解除します。解除するたびに敵が出ます。
  • [7, 10]: ドア、キーカードで開きます。
  • [7, 8]: 「やすむ」と次に進みます。イドの迷宮をクリアしている必要があります。
  • [6, 7]: コーラックがいて、世界の果てに行けと言われ、ソーピガルに戻されます。
世界の果て
ソーピガル →(転送)→ エルキューン → B1 の経路で移動します。[4, 15] にある世界の果てに行くとゲームクリアです。最後に Book Two に続く!と出ますが、Book Two はファミコンでは発売されませんでした。悲しい。スーパーファミコン版が発売されているようです。

この他にも諸侯のクエスト、全く関係ないクエストなど、たくさんありますので、ぜひ遊んでみてください。全体的に良くできたゲームシステムだと思うんですけど、難易度の高さ(敵が強すぎる……)に、挫けそうになるのがイケてないポイントではあります。

編集者: すずき(更新: 2021年 11月 8日 23:41)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2021年 10月 6日

Might and Magic Book One で初めての TAS に挑戦

目次: Might and Magic ファミコン版 - まとめリンク

子ども時代のトラウマ難易度ゲーム Might and Magic Book One に、大人になってから挑みましたが、変わらず撃沈しました。やっぱり難しいです。でもエミュレータなら、Lv.1 で最速クリアする動画を作れるんです。いわゆる TAS(Tool Assisted Speed-run)動画です。

TAS するにあたっては、定番の BizHawk というエミュレータを使います。ROM をロードして Tool - TAStudio を選ぶと、フレーム単位でキー入力を選べる画面が出現します。


BizHawk TAStudio

操作に自信があるなら Recording mode を使って自分の操作を記録し、あとでファインチューンすると良いでしょう。私は操作にあまり自信がなかったので、1フレームずつチマチマとマウスで入力しました。

TAS 第一弾

とりあえずエンディングまで辿り着いたので、YouTube にもアップロード([TAS] NES Might and Magic Book One (J) 23:30 - YouTube)しました。YouTube のアップロード側機能は初めて使いましたが、とても使いやすいですね。

TAS としてのクオリティはあまり良くないです。攻略ルートがかなり適当で、これより早くクリアできる動画は簡単に作れると思います。容易に改善できそうなところは、

  • メッセージスキップしてない(スキップ条件が良くわからなかった)
  • 「ようせい」との戦闘に 2ターン掛けてる
  • 「ガラドリエルのめぐみ」取りに行くのが無駄(Gem は「ようせい」が落とした 7つで足りてた)
  • ダスクの町の店で物を売る必要がない(金は足りてる)
  • 地上エリア A2(火山地帯)からの脱出が遅い
  • 「さんごのかぎ」の受け渡しが無駄(先頭の人が持てるルートに変えた方が良い)
  • 5人もパーティーに入れている

5人パーティーだとオーラのクエストが長いし、戦闘で行動できない人が出やすく無駄が多いので避けたいですが、4人パーティーだと「ようせい x 3」が出ないので、妥協しました。

あと Might and Magic の大きな特徴として、敵から逃げると MAP の特定の位置に必ず戻される仕様があります。わざとエンカウントし逃げれば、歩くよりも早く移動ができる可能性があります。TAS ではぜひとも活用すべき事項ですが、エンカウントのルールがわからず、エンカウント確率もかなり低いため、総当たりだと全然エンカウントしません。これは厳しい。ギブアップ。

とまあ、色々諦めたしょぼい TAS 動画を作っただけで非常に疲れました……。世の中のハイレベル TAS 動画の作者さんは凄いですわ〜。

補足

Might and Magic ファミコン版は日本語版と英語版があります。このうち英語版の TAS は既に存在していて、クリアタイムがたったの 8分[TAS] NES Might and Magic by Dammit in 08:07.72 - YouTube)です!超早ですね。

英語版はアイテムを別のアイテムに化けさせるバグがあって、そのバグを突くとゴミから終盤のクエストでもらえるはずのアイテムを錬成でき、ほぼ全てのクエストを無視してラストダンジョンに挑めます。

日本語版ではバグが修正されているほか、クエストの仕様も違うため、少なくとも同じ攻略法ではクリアできません。

編集者: すずき(更新: 2021年 11月 8日 23:40)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2021年 10月 5日

久しぶりにファミコンの Might and Magic Book One をやってみたい

目次: Might and Magic ファミコン版 - まとめリンク

Nintendo Switch Online に加入すると、ファミコンやスーパーファミコンのソフトでも遊べるので、子供の時に挫折したゲーム(最近だとファミコンウォーズ、スーパーピクロス)をやっています。グラフィクスは近年のゲームと比べるまでもなくショボいですけど、今も名作は名作です。面白いですね。

子どもの時に挫折したゲームはいくつもありますが、ナンバーワンが Might and Magic Book One : the Secret of the Inner Sanctum です。この時代に流行ってた Wizardry みたいな 3D 風の迷路を歩いていく海外製 RPG です。難易度が異常に高くて有名で、小学生の私は Lv.2 すら拝むことなく諦めました。

この手の Switch には収録されていないソフトも遊びたいなあ?と思って、ニューファミコンを物色していたのですが、結構でかくて邪魔そうだし、中古の割に高いです。今でも人気なのか……侮ってましたね。

ですが、我々には PC とエミュレータがあるじゃないですか。幸いなことに、ファミコンソフトそのものはそんなに高くないので、ROM ダンパーで ROM を吸い出して、PC で遊ぶことにしました。


レトロダンパー

私はレトロダンパー(メーカーのサイト)を使っています。クライアントを起動して、認識ボタンを押し、吸い出すだけで OK なので便利です。

Might and Magic Book One 購入

早速、中古のカセットを購入しました。外観は割とズタボロというか、年季入った姿です。ま、動けば良いのさ。


ファミコン版 Might and Magic Book One のカセット

GAKKEN のロゴの通り、なぜか日本語ローカライズは学習研究社(学研)が行っています。今見ると不思議です。教科書作ってる学研が、なぜゲームの移植を……。


レトロダンパーにカセットを挿した状態

レトロダンパーさんで吸い出すときはこんな感じになります。吸い出した ROM をエミュレータに放り込んでみたところ、正常に動作しているようです。良きかな良きかな。

ゲームの感想

まずは普通に遊んでみました。今なら意外とクリアできるのでは?と思ったのも束の間、あっ、無理でした。調子乗ってすみませんでした。在りし日の絶望が蘇りました。

  • 攻撃がほぼ当たらない
  • 敵から逃げられない
  • Lv2 が果てしなく遠い
  • 罠解除役(盗賊)が宝箱の罠に掛かる
  • パーティーがすぐ全滅、タイトルに戻される

最初から難しすぎます。基本的には 1バトルごとに休憩+セーブって感じです。攻撃が当たらないのも辛く、一方的にボコられて死んでしまいます。死んだら復活させるお金がないのでリセットです。

さらに Wikipedia を見てびっくりしたのは、次の一文です。
「ファミコン版は(中略)やや簡単に調整された部分が多い」
えっ?これで?嘘だろ……??オリジナル版はどれだけ鬼畜難易度なの?

息抜きに YouTube で攻略動画を見ていると、ラストダンジョン(イドの迷宮、アストラル世界)の音楽がとてもカッコ良いですね。何とか辿り着きたいですが、最初の町(ソーピガルの町)から脱出できていない身からすると、果てしなく遠いです。

編集者: すずき(更新: 2021年 11月 8日 23:39)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2021年 10月 4日

Might and Magic ファミコン版 - まとめリンク

目次: Might and Magic ファミコン版 - まとめリンク

日記が増えすぎて、一覧が欲しくなってきたので作りました。

リンク集

Might and Magic の攻略、解析の参考になるサイトです。

編集者: すずき(更新: 2021年 11月 24日 01:18)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2021年 9月 30日

携帯の遍歴

日記を漁って携帯の遍歴を書き出してみました。日記を書く習慣がなかった頃の機種や時期は不明です。

J-PHONE, Vodafone
  • 不明(2000年くらい?): SHARP J-SH04 辺り?
  • 不明(2002年くらい?): TOSHIBA J-T06 辺り?(ストレートだった気がする)
NTT ドコモ、ガラケー
  • 2004年 8月: Fujitsu F506i
  • 2005年 6月: Fujitsu F506i マイク故障で交換
  • 2006年 ?月: NEC N902iS
  • 2008年 ?月: NEC N902iS のバッテリー交換
  • 2010年 7月: Panasonic P-03B
NTT ドコモ、スマホ
  • 2011年 7月: Sony Ericsson Xperia acro SO-02C
  • 2014年 3月: SHARP AQUOS PHONE ZETA SH-01F
SIM フリー、スマホ
  • 2016年 11月: ASUS Zenfone 3 Deluxe
  • 2021年 4月: Google Pixel 4a

(基本的には)長く使っていた機種は気に入っていた機種です。ガラケー時代はいずれも良い機種で、バッテリーが死ぬまで使ってました。最後の P-03B だけ 1年しか使っていませんが、不満があったわけではなく、知人に携帯を譲るため手放しました。たしか。

スマホ時代は国内メーカーの質は明らかに落ちました。SO-02C はソツなく良かったんですけど、ストレージが少なすぎで買い替え直前は容量不足で挙動不審でした。SH-01F は性能良いものの、電池がなくなるのが早く、本体が熱すぎでした。この機種で懲りて Android ハイエンド機を買わなくなりました。

今になって調べてみたところ、この 2機種はマシな部類だったようで、富士通 ARROWS のように「カイロ機能搭載」「電話ができない」「メールがこない」など、怨嗟にまみれたレビューが未だに残っている機種もあります。悲惨です。

日本だけ異常に iPhone 普及率が高い理由って、国内メーカーが 2010 年代初頭にやらかしたから……!?と思ってしまいました……。

メモ: 技術系の話は Facebook から転記しておくことにした。

編集者: すずき(更新: 2021年 10月 8日 16:56)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2021年 9月 28日

マルチコアのブート処理

メイン CPU からサブ CPU を起こすとき基本的には、

  • CPU の ID(RISC-V であれば CSR の mhartid)を見て、自身がメインかサブかを知る
  • サブ側は共有 RAM をポーリングなどで見張り、メイン CPU からの起動司令を受け取るまで待つ
  • メイン側は共有 RAM に値を書いてサブ CPU に起動司令を送る

RAM の初期値が不定であると仮定すると、サブ CPU が下手にポーリングすると、不定値によって条件が成立してしまい、メイン CPU からの起動司令がないのに勝手に起動してしまう事態に陥ります。

素朴な実装

先程書いた基本的な構造を素直に書くとこんなコードになるでしょう。

素朴なマルチコアのブート

/* メイン CPU は HARTID=8, サブ CPU は HARTID=0...3 とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	int boot_wait;
	int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メイン CPU が実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		init_core[i].boot_wait = 1;
	}
}

/* サブ CPU が実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	while (!init_core[hartid].boot_wait) {
		/* busy loop */
	}
}

残念ながらこのコードは正常に動作しません。共有 RAM つまり init_core[hartid].boot_wait の値が起動直後から != 0 だったとき、boot_sub() は boot_main() からの起動司令を待つことなく起動してしまうからです。

不定値への対処

共有 RAM の不定値に対処する方法を考えます。基本的にはサブ CPU が変数を初期化(boot_wait = 0)してから待ちに入れば良いのですが、新たな問題が生じます。メイン CPU とサブ CPU の実行順序はどちらが先という保証はないため、

  • メイン CPU からの起動司令 boot_wait = 1
  • サブ CPU で変数を初期化 boot_wait = 0

以上の順で実行されるとメイン CPU 側の起動司令が消されてしまい、ハングアップする可能性があります。この問題の回避のため、変数を 1つ追加し、サブ CPU のブートが終わるまで、メイン CPU は繰り返し起動司令を送るように変更します。

  • 変数を 2つ用意する(boot_wait, boot_done)
  • メイン: boot_done = 0
  • メイン: サブから応答(boot_done != 0)があるまで、boot_wait = 1 を書き続ける
  • サブ: boot_wait = 0
  • サブ: boot_done = 0
  • サブ: boot_wait == 0 なら待つ
  • サブ: boot_done = 1

先程書いた基本的な構造を素直に書くとこんなコードになるでしょう。

不定値への対処を入れたコード

/* メイン CPU は HARTID=8, サブ CPU は HARTID=0...3 とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	int boot_wait;
	int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メイン CPU が実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		init_core[i].boot_done = 0;
		while (!init_core[i].boot_done) {
			init_core[i].boot_wait = 1;
		}
	}
}

/* サブ CPU が実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	init_core[hartid].boot_wait = 0;
	init_core[hartid].boot_done = 0;

	while (!init_core[hartid].boot_wait) {
		/* busy loop */
	}
	init_core[hartid].boot_done = 1;
}

残念ながらこのコードも正常に動作しません。共有 RAM への値の反映が他の CPU に即座に見えること(アトミック性)を暗に期待しているからです。

アトミック性への対処

今日のマルチコアシステムでは、boot_wait = 0 としたときに、他の CPU にも即座に同じ値が見えているとは限りません。主な要因としては、

  • コンパイラによる並べ替え
  • CPU のパイプライン
  • CPU のデータキャッシュ、ライトバッファ

などがあります。通常の変数への代入、参照が他の CPU に即座に値が見えないことにより、おかしくなるパターンはいくつか考えられそうですが、ありがちなパターンとして、

  • サブ CPU 0 が起動した boot_done = 1
  • メイン CPU に boot_done = 1 が伝わらず、サブ CPU 1 の起動指令がいつまでも送られない

以上の順で実行されるとメイン CPU 側が起動司令を送らないまま、サブ CPU 側も何もできずハングアップする可能性があります。この問題の回避のため、通常の変数への代入、参照ではなく他の CPU にも値が見えるように初期化、代入(アトミックアクセスする)必要があります。

従来 C 言語でアトミックアクセスを行うためには、実装対象アーキテクチャの知識やアセンブラの記述を必要とするなど、やや困難が伴いました。ですが C11 でアトミックアクセス用の定義 stdatomic.h が追加されたことで、アトミックアクセスはかなり楽になりました。素敵ですね。

ひとまず速度を全く気にせず、全てのアクセスをアトミックアクセスに入れ替えると、こんなコードになるでしょう。

アトミック性への対処を入れたコード

/* メイン CPU は HARTID=8, サブ CPU は HARTID=0...3 とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	atomic_int boot_wait;
	atomic_int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メイン CPU が実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		atomic_store(&init_core[i].boot_done, 0);
		while (!atomic_load(&init_core[i].boot_done)) {
			atomic_store(&init_core[i].boot_wait, 1);
		}
	}
}

/* サブ CPU が実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	atomic_store(&init_core[hartid].boot_wait, 0);
	atomic_store(&init_core[hartid].boot_done, 0);

	while (!atomic_load(&init_core[hartid].boot_wait)) {
		/* busy loop */
	}
	atomic_store(&init_core[hartid].boot_done, 1);
}

C11 のアトミックアクセスは何も指定しない場合、一番制限の強い(= 確実に他の CPU に見えるものの、アクセス速度は遅い)memory_order_seq_cst アクセスになります。マルチコアのブートを行うにあたって、常に制限が強いアクセスは必要ありませんが、とりあえずこれで動くはず。

編集者: すずき(更新: 2021年 9月 30日 11:36)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2021年 10月 7日 ---> 2021年 9月 28日
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 11/26 11:42

カレンダー

<2021>
<<<10>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント 5件

  • link 20年06月19日
    すずき 「お役に立てて何よりです。これ、わかりにく...」
    (更新:09/27 17:05)
  • link 20年06月19日
    ちまき 「初めまして、こんばんは!\n音源は異なり...」
    (更新:09/27 03:16)
  • link 21年03月03日
    すずき 「お役に立てたようで幸いです。」
    (更新:06/17 17:24)
  • link 21年03月03日
    Shige 「とても参考になりました。\nGood!!...」
    (更新:06/17 13:28)
  • link 20年12月19日
    すずき 「なるほど、地元愛 No.1 は福岡なんで...」
    (更新:05/02 00:08)

最近の記事 3件

link もっとみる
  • link 19年07月21日
    すずき 「[RISC-V の命令] 目次: RISC-V - まとめリンク最...」
    (更新:11/26 11:42)
  • link 21年06月18日
    すずき 「[RISC-V まとめリンク] 目次: RISC-V - まとめリ...」
    (更新:11/24 15:26)
  • link 21年10月04日
    すずき 「[Might and Magic ファミコン版 - まとめリン] ...」
    (更新:11/24 01:18)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報