2020年8月25日火曜日

最近のコーヒー事情(自宅&外)

アイスコーヒーが好きなので、ほぼ年中飲んでます。

在宅勤務になる前は、主に喫茶店とコンビニコーヒー。

在宅勤務になってからはUCCの「職人のコーヒー」という930mlペットボトル。ペットボトルは1本78円で買えるのでお財布に優しい反面、洗って潰して捨てるのが中々面倒臭い。フニャフニャのペットボトルなら良いのですが、コーヒーのペットボトルって固いので潰すのが面倒臭い。玄関口に並んでいる「捨て待ち」の空ペットボトルがどんどん溜まっていくのを見ていると憂鬱な気分になります。さてどうしたものかと思っていたところ、近所のヨーカドーで水出しアイスコーヒーポットなるものを発見。

https://www.monotaro.com/p/4337/4486/

近所のスーパーで400g 298円の安いコーヒー粉を使って作ってみたのですが、メチャクチャ美味しい。200〜300円ぐらいで飲める喫茶店のアイスコーヒーより断然美味しい。昔、品川駅で待ち合わせをしていた時にウッカリ間違って入ってしまった意識高い系のコーヒー専門店で飲んだアイスコーヒー(1杯800円近くしたブルジョア向けの高級品)と同じぐらい美味しい。1杯800円相当のコーヒーが約4リットルで298円と考えれば激安。

廃棄についても一般ごみしか出ないので楽です。

ただし、抽出に時間が掛かる(1回の抽出に8時間掛かる)ので、2本導入してアクティブ・スタンバイのクラスタ構成にする方向で検討中です。

自宅のコーヒー環境は完璧ですが、問題は外の喫茶店。(在宅勤務に切り替わった影響で全然気づかなかったのですが、いつの間にかタバコが吸えなくなっていた...)

2020年8月22日土曜日

エアロバイク導入

 毎週土日に水元公園という近所の公園(23区で一番デカイらしい?)を組み込んだ15km前後のサイクリングコースを周回していました。

(コース)

  • 水元公園まで: 5〜6km前後
  • 水元公園内: 3kmぐらい
  • 帰宅: 5〜6km前後

地形を覚えるため、Googleマップなどは使わず物理マップを脳内マッピングしながら進んでいる(なので、かなり高確率で迷う)ので、公園内以外の距離はあまり正確ではないです。多分、片道で10kmぐらい走ることもあります。なお、公園内は人が多いのでインターバル(クールダウン)区間と割り切ってゆっくり安全運転してます。水元公園は、大きな溜池、北海道のような平原、森林などがコンパクトに詰まった走っていてとても気持ちが良い区間だから、ゆっくりと走らなければ損だとも言えます。

かなり良い運動になります。
春先は良かったのですが、自粛モードが解除されたぐらいの頃から、色々と懸念が出てきました。
  • 事故が怖い(一応なるべく車通りの少ないコースを選定しているが7月以降は交通量が気持ち多めで怖い)
  • 雨の日はできない
  • 日中は光化学スモッグ注意報がしばしば発令されている
  • 事故回避のため夜間はNG
  • マスクがかなりキツイ(これは運動目的だと高山トレーニングのような効果があるので逆に良いことかもしれない)
  • 水分補給コストの問題(750mlでは全然足りず、汗の量から多分1Lよりも多めに補給する必要があるけど、そんなデカイ水筒は持ってない & 自販機で買うと高い)

という訳で、秋ぐらいまでは毎週恒例だったサイクリングを暫くお休みすることにしました。

ただ、在宅勤務で運動不足気味だし、思いっきり運動しないと寝付きが悪いので、さてどうしたものか・・・と、考えていたところ弊社の取締役が「エアロバイクはいいぞ」と勧めてきたのでAmazonでエアロバイクを物色してみたところ、以下のSTEADYという商品が気になったので買ってみました。

https://www.amazon.co.jp/dp/B07HNVVZ38

購入を決めたポイント

  • 静音性の評価が高い
  • iPadを見ながら使える
  • サイズ感

静音性についてはマンションなので必須事項です。幸い私の自宅(4F)は1〜3Fが商業施設(メディカルモール)で隣室が看護師の休憩所っぽいので、音の面はあまり問題ないかもしれませんが、以前リモート会議で喋っていたら隣室で休憩中と思しき看護師から軽く壁ドンされたことがあるので、あまり音が出るヤツは避けたほうが良さそうだなと。

iPadを見ながら使える事もかなり重要です。昔、ジム通いをしていた時期があるのですが、風景が変わらない状態で走ったり漕いだりするのはとにかく退屈だからすぐに飽きてしまう(なのでジムでは水泳中心でした)ので、iPadでdアニメでも見ながらやれば飽きずに漕げるかなと。

サイズ感については、折りたたんだ状態ではなく広げた状態のサイズ感を重視しました。折りたたんだり仕舞ったりしてしまうと、出すのが面倒臭くてタンスの肥やしになると考えられるので、ベッドルームに常にセットアップした状態で配置可能な程度のサイズであることが重要です。

とりあえず、数日使ってみたところ、以下のような使用パターンで定着できそう。

  • 朝、起床後にアニメ1話(約20分)をみながら重さ7の設定で漕ぐ→汗びっしょり
  • 昼ごろは気が向いたらちょくちょく重さ6以下で5分ぐらい走らせる→ストレス解消
  • 夜、風呂前にアニメ1話(約20分)をみながら重さ7の設定で漕ぐ→汗びっしょり

ちなみに、重さは8段階で最大が8で、7は最大より1個軽い設定です。

毎日ルーチン的にやれるようにするため、意図的に筋肉がつかないように(筋肉痛にならないように)調整したつもりだったのですが、何か股関節あたりが筋肉痛っぽい感じになってしまったので、もっと軽くした方が良いかもしれません。Amazonのレビューに少し書かれてましたが重めの設定だと負荷バランスがあまり良くはないかもしれません。ただ、軽め(6以下)だとアニメ1話では汗びっしょりにはならないので、プロテインでも飲んだ方が良いかも。

2020年8月17日月曜日

東方BGM on VGS(コマンドライン版)

コマンドラインで動作する東方BGM on VGS(東方VGS)を作ってみました。

https://github.com/suzukiplan/tohovgs-cli

今の所、macOSのTerminal専用です。

Windowsの方がニーズがあるのかもしれませんが、手元に使えるWindowsマシンがない and 今後Windowsを使う予定もないので、どうしてもWindowsで使いたい場合、頑張ってポーティングしてください...(Linuxであれば私のメインマシンがmacOSからLinuxに変わったら対応予定)

プレイリストを簡単に編集できる形にしておいたので、好きな曲だけ任意回数ループさせたりといった細かいカスタマイズが簡単にできます。

在宅勤務のお供などにどうぞ。(その目的で自分用に作ったものだったりします)

2020年8月2日日曜日

Z80での PUSH/RET について

Z80エミュレータのテストのために作ったゲームギア・エミュレータのテストの過程で、ゲームのコード解析を結構したのですが、その中で面白かったテクニックとしてPUSH/RETというものがあります。

PUSH: スタックにデータを格納する命令
RET: CALL元へ復帰する命令

RETはCALLから復帰するための命令ですが、戻りアドレスはスタックから取り出すので、「スタックからPOPして得られるアドレス値へジャンプする命令」と解釈することもできます。

つまり、アドレス値をPUSHしてからRETを呼び出せば、「PUSHしたアドレスにジャンプ」することができます。6502には、任意メモリに格納されたアドレスへジャンプする命令が存在しないので、6502であれば割と有用なテクニックだったといえます。

ただ、Z80のプログラムでこのテクニックを利用する意味が分からないです...Z80であれば、任意メモリに格納されたアドレスへジャンプする命令(JP (HL) など)が存在するので。

性能面についても、PUSH/RETを使うメリットはありません。
そもそも、スタックアクセスが遅いので。

例えば、アドレス nn に格納されているアドレスにジャンプしたい場合:

(PUSH/RET)
LD BC, $(nn) ... 20Hz
PUSH BC ... 11Hz
RET ... 10Hz
合計: 41Hz

(JP (HL))
LD HL, $(nn) ... 20Hz
JP (HL) ... 4Hz
合計: 24Hz

上記のように、PUSH/RETだと「17Hz」もの無駄クロックを消費してしまいます。
PUSH(スタックアクセス)がそもそも重い上に、RETも(スタックアクセスするので)重いので、PUSH/RETでは性能的な意味での恩恵が得られることは無い筈です。

なのに何故、あのゲームはZ80だと一見無意味なPUSH/RETを使っていたのか...謎が深まります。(プログラマがFCに慣れてて、Z80をあまり知らない状態で書いたとかそんなオチでしょうけど)

2020年8月1日土曜日

自前Z80エミュレータのテスト完了

昨年作成したきり放置気味だった自作Z80エミュレータ(C++)でシステムテストを実施して完成させました。

システムテストは、別途ゲームギアのエミュレータを作成して実施しました。(なお、作成したゲームギアについては、現在進行系でゲームギア関連ビジネスが動いているようなので、念のため非公開にしておきます...既に完成度が高いエミュレータなら沢山ありますし)

Z80を搭載したゲーム機なんて沢山あるんじゃないかと思いきや、意外と少なくて、シングルコアで純正Z80を搭載しているのは、調べた限りではSG-1000、Sega MARK III、Sega Master System、Game Gearぐらいのようです。(ゲームボーイがZ80カスタムなので若干惜しい)

そして、その中で私がハードとソフトを唯一持っているのがGGだったので、GGエミュレータを作ることにしました。なお、GGのハード仕様については、以下の資料を読んで把握。
セガのハードは中々面白くて、初代SG-1000の中身はだいたいMSXと同じ構造です。
そして、SM3、SMS、GGはVDP(Video Display Processor)をゲーム向きの専用設計(モード4)に切り替えていますが、ハード構造的にはSG-1000と(ついでに、オセロマルチビジョンとも?)互換性を持たせられる設計になっているようです。

モード4のVDPはかなりシンプルな構造です。
16KBのRAM(VRAM)の中にパターンテーブル、ネームテーブル、OAM(Sprite Attribute)がある形。
ファミコンのハード仕様を理解していれば、容易に理解できると思います。
ファミコンと違ってネームテーブルがかなり扱いやすくなっていて、キャラクタパターン(1byte)と属性データ(1byte)のセット(2byte)で1セルを表現する形になっています。(ファミコンでゲームを作った事がある人なら分かると思いますが、かなりプログラムし易いメモリレイアウトになっています)

GGの場合、MSX相当(SG-1000相当)のモード実装は不要っぽかったので、2週間ぐらいで作れました。(途中4連休もあったので楽勝)
GG Dumperで手持ちのカセットからROMを吸い出して動作検証したところ、手持ちソフトの範囲では10割正常に動きました。(そんなに沢山持ってないのが悔やまれる...)

【動作確認したソフト】
・ベアナックル2
・GG忍
・ソニック・ザ・ヘッジホッグ2
・ドラゴンクリスタル
・デビリッシュ
・魔導物語1(PSG/PCMでちゃんと喋ります)
・魔導物語A
本体が通電不可能なので、今度ハードオフで見つけたら調達予定...
(ついでに検証ソフトも増やしたい)

私の自前Z80の場合、ほぼ実機相当のマシンサイクル単位(実は厳密には少し違うけど...)で同期実装が可能なので、エミュレータ開発者の誰もが苦労する同期実装周りで苦労することはありませんでした。GGの場合、LCDディスプレイ領域は160x144ピクセルですが、内部的には1フレーム342x262ピクセル(NTSC)で処理していて、4Hzにつき3ピクセル描画する形で同期すれば完璧な同期を実現できます。(CPUパワーはかなり消費しますが)

このテスト過程で発見したZ80側のバグがこのPull Requestでfixされています。

先日、このZ80エミュレータにゲームボーイのCPU(LR35902)のコンパチブルモードも実装したので、ゲームボーイのエミュレータも作ろうと思えば作れますね。(作るとは言っていない)

2020年7月30日木曜日

ブログ のデザイン変更

ブログのデザイン変更をかなり大幅に変更しました。

ダークテーマに慣れすぎたせいで、微妙に明るくて見にくかったのでダークテーマのデザインに変更しつつ、そろそろ細かい字を見るのがキツイお年頃なのでフォントサイズなどを大きめにしてみました。

過去記事で色が見難い箇所があるかもしれません。
色は基本的にデフォルトから変えるべきではないですね。(今後は気をつけよう)

2020年7月29日水曜日

ゲームボーイのCPUについて

ゲームボーイのCPUについて、誤った技術情報が検索トップの方に表示されるので、私が把握する限りでZ80との仕様差を書いておきます。

ゲームボーイのCPUとは?
☓ 8080
☓ Z80
○ 8080カスタム or Z80カスタム(正確にはSHARPのLR35902)

Z80との仕様差:
  1. 1マシンサイクルが全て4Hz(なので全ての命令のTサイクルは4で割り切れる)
  2. 一部フラグ(S, P/V, X, Y)が存在しない(※X, Yはundocumented)
  3. レジスタ IX, IY が存在しない
  4. プレフィクスDD(IX命令)、FD(IY命令)が存在しない
  5. 裏レジスタが存在しない(ので、EX/EXX命令も存在しない)
  6. IN/OUT命令が存在しない(I/Oは$FF00〜$FFFFにメモリマップド)
  7. プレフィクスED命令(結構便利な命令群)が存在しない
    1. $ED $4D (RETI命令) については $D9 (EXX命令) へ移動
    2. Rレジスタに実質アクセスできない(Rレジスタ=DRAMへ通電するためのレジスタで命令実行毎に0〜127の範囲でインクリメントされ続けるもの。この特徴を利用してゲームでは乱数ジェネレータとして利用されることがあるが、ED命令削除の影響でゲームボーイでは利用できないので、乱数を使いたい場合は自前の乱数テーブル等を作る必要がある)
  8. プレフィクスCBのSLL命令(undocumented)がSWAP命令に置き換わっている(SWAPはレジスタ上位4bitと下位4bitを入れ替えるLR35902固有機能)
  9. DJNZ命令がSTOP命令に置き換わっている(STOPはHALTよりも省電力な割込待機機能)
  10. LDI/LDD命令をシンプル化(Bレジスタのデクリメントを行わず、HLのインクリメント・デクリメントのみ行う)
    1. LDIR/LDDR(OTIR/OTDR)相当の命令が無いのでBレジスタのデクリメントが要らない(これらの命令は結構便利だが、継続条件時に5Hzの無駄クロックが発生する関係で、性能が求められる箇所では使用せずにOUTI, OUTI, OUTI...などといった形でRじゃない方の命令を並べて書くのが普通...つまり、ゲーム用CPUなら無くても良いよね という判断だと思います)
  11. LDH命令を追加($FF00〜$FFFFへのアクセス命令のサイクル数を少なくしたもの=I/O命令の代替用)
  12. スタックポインタを便利に使えるようにする命令群(LD (addr),SP / ADD SP,d / LDHL SP,d)を追加(※LDHLはADD SP,dの結果をHLに代入する命令)
  13. LD (addr),A と LD A,(addr) の命令コードを変更
  14. LD HL, (addr) と LD (addr), HL を廃止
私の認識はだいたいこんな感じ。

これで本当に正しいか少し自信がないので、自前Z80エミュレータにLR35902コンパチモードを追加して検証してみようと思っているところです。
https://github.com/suzukiplan/z80/pull/17

(以下、余談)
ゲームボーイのCPUが8080派生なのかZ80派生なのかという議論を目にしますが、機能的には8080とZ80のどちらにも近いと思います。レジスタセットは8080に近いし、豊富なシフト命令(CB prefix instruction set)はZ80に近い。また、IN/OUT命令をメモリマップで代用しているから6502っぽさも感じられます。(Z80をよりゲーム用に洗練させた感じなので、GBZ80という通称が一番しっくりくる)
敢えて、8080派生 or Z80派生のどちらが正しいかを「CPUの設計過程でどちらをベースCPUにしていたか」という観点で推測すると、Z80派生が正しいと思います。というのも8080をLR35902化するのと、Z80をLR35902化するのなら後者の方が設計コストが圧倒的に低いので。(8080派生だとするとCBプレフィクス命令の追加設計が物量的に重そうだし、bit/set/res命令辺りは普通にand/orで代用できてand/or比で性能的なメリットも無いから、ゲーム用の機能としてわざわざ新設する意味がないような気がするので)

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...