/var/log/hdk.log

2016 年 6 月下旬


20 (月)

%1 一回休み

朝目覚めた時点でやっぱりのど痛い。 熱もちょっとあるのか頭も痛い。 そんなわけで職場に休みの連絡を入れる。

午前中はそれなりに寝た。 熱はもう落ち着いてきたか、しかしやっぱりのど痛い。 そして立ち上がると頭痛い。 うーん。

午後もゆっくりしていたが、少ししか眠れなかった。 結局夜になってもあまり症状は変わらず。 のどの痛みは何もしてなければ気にならないが、唾液等を飲み込むと痛みがある。 頭痛も静かにしてれば気にならないが、立ち上がると痛みが走る。

%2 C++

一時オブジェクトというのは使ってみたが、結局 rvalue reference などというものは使わず、必殺 (?) 値渡しでの実装を行った。 どうせ初期化の時だけだから多少のメモリーコピーがあってもかまわないし、簡単なデータ構造だからコピーコンストラクターを自分で書く必要もない。

とりあえず C っぽくリストを書いてみたのだが、当然のことながら STL を使うのが普通であろう。 しかし、STL を見ていたらちょっと C の感覚と違うことに気づいた。C の双方向リストの場合、例えば struct hoge に struct hoge *prev, *next; などと宣言を加えて、それでゴリゴリやるわけだから、確実にリストに入っているとわかっている struct hoge のポインターを扱っているならば、リストを探索することなく要素の削除ができるわけだ。 これが std::list <struct hoge> でできるのかと言うと、struct hoge の中に std::list<int>::iterator を入れておかないとできないんじゃないかなぁ。 そうすると C のやり方より無駄が増えている感じがする。

そうそう、他にも C の感覚だと違和感があるのは、private のメソッドだ。 メソッドは private であっても class の記述の中に含めなければならず、そうすると、ちょっと処理を書きやすくするために作った内部用の小さなメソッドでさえも、class を書いたヘッダーファイルの中に現れることになる。 対策案としては Pimpl idiom と呼ばれているらしい方法があって、ヘッダーファイルの private メンバーとしては構造体またはクラスのポインターのみを置いておき、その構造体またはクラスの中身を本体のほうに書いてしまおうというやり方である。 これはこれでいいんだけど、new delete が必要になるので頻繁に自動変数でオブジェクトの生成削除が繰り返されるようなケースでは向いていないのではないかと思う。 って、それは C でも同じか。 それより外側のオブジェクト (ポインターを持つだけ) の new と内部用オブジェクトの new が別々に必要になることを心配するべきか。

2016/06/20 のコメントを読む・書く


21 (火)

%1 かようび

まだのどの痛みが残っているが、きのうの朝よりはマシ。 というわけで普通に出勤。

風邪の症状は何となく徐々によくなってきているように思う。 のどの痛みがあまりにひどいようなら耳鼻咽喉科に行こうと思っていたが、この様子なら数日で治るだろう。

%2 C++

std::list がああなっている理由、ひとつはたぶん、offsetof が使えないことにあるのかも知れないと思った。C でリストを書く場合には:

struct mydata {
  struct mydata *next;
  int weight, height;
};

みたいにするのが普通に習う方法だと思う。 こういう単方向リストはまだいいけど、双方向その他は共通化しておきたい、となった時にはマクロに頼ることになって、それをやったのが BitVisor の include/core/list.h である。

bitvisor / bitvisor / ソース / include / core / list.h - Bitbucket

ま、これはこれで有りだと思うのだが、LIST1 を実装した後、複数のリストに入れたい構造体のために直接 ->next を参照するわけにいかなくなって、その名前に指定したキーワードを追加するようにした別バージョンを実装する羽目になったのが LIST2 であるw

で、ものによっては以下のような手法を使っているものがある:

struct list { struct list *next; };
struct mydata {
  struct list list;
  int weight, height;
};

この場合は struct list という型で扱えるのでマクロにしなくても普通の関数定義で扱える。 しかし、降ってくるのが struct list のポインターなので struct mydata のポインターに変換する必要が出てくる。 この例では先頭にあるので単にキャストすれば通るわけだが、実際には先頭にない場合もあって、そこで offsetof の登場となる。 もちろんその部分はマクロで定義することになるし、リストの要素をたどるたびにアドレスの減算が必要なのは無駄といえば無駄かも知れない。

で、std::list もこの struct list に似た状態になっているのではないか。 いや、テンプレートだから当然違うわけだけど、仮に std::list <struct mydata> とした場合の各エレメントのデータ構造想像図 (C で書くとこんな風になってそう) は以下になる:

struct list_internal_data {
  struct list_internal_data *prev, *next;
  struct mydata element;
};

ここで struct mydata * から struct list_internal_data * を得たいとなれば offsetof の登場だが、C ならそれで良いところ、C++ だと offsetof が使えるところに制限があるらしく、本当に C の構造体っぽいもの、全メンバーが public で、メソッドはあってもいいけど virtual 等を使っていない、といった条件みたいなので、おそらく std::list はそのへんの都合で要素のポインターからリストのイテレーター等を得ることができないのではないか。 もちろんマクロの嵐は C++ でも書けるわけだけどねぇ。

2016/06/21 のコメントを読む・書く


22 (水)

%1 風邪

今日は症状は変わらなかったかな。

職場にも同じような風邪を発症している同僚がいる疑惑。 潜伏期間を考えると誰が持ってきたのか... いや、発症しないまま退治できた人がばらまいていたかも知れない。

%2 JX エミュレーター

アドレス変換みたいな仕事を担うデバイスのエミュレーションがだいぶ強引だったので、コードを整理して、ハードっぽく「バス」を導入し、そこに各デバイスがぶら下がるようにして、まぁまぁきれいにしたらパフォーマンスに影響が出てしまったので、対処した。 コンピューターのバスってのはようするに CPU とメモリーやデバイスの間をつなぐ線のことであり、そこを流れる信号は基本的にはブロードキャストなのでつながっている全デバイスに届くわけであり、そういうつもりでエミュレーションするとオーバーヘッドが大きすぎたみたいだ。 それでアドレス範囲を 16 分割して各デバイス側でアドレス範囲を主張できるように変えた。

○ード○ンナーというゲームで遊んでいるとやたら動作が速かったのだが、コードを整理したことで原因が判明。VRAM と共用の汎用メモリーはアクセスに平均で 1.5 倍の時間を要するらしいのに、B800h の VRAM 空間のアクセスだけをその時間にしていた。 そこを直したところ動作速度がいい感じになったので、それが原因だったみたいだ。PCjr 互換モードでは下位のアドレスに VRAM と共用のメモリーが割り当てられているため、おそらくそこに読み込まれているであろうゲーム本体のプログラム実行速度も遅くなるようだ。

そして、まさかと思ったが、よく遊んだ○ンチ○ールというゲーム、なんと 128KB 拡張メモリーカード (VRAM との共用不可、すなわち速い) を 3 枚とも全部取り外すと遅くなるようなのだ。YouTube で他機種の同ゲームの動画を見た感じからすると、どうもその遅いほうが正しいスピードみたいだ。20 年以上前に遊んだけどまさか速い状態だったとは今まで考えもしなかった。 アチャー、これはメモリー容量の変更機能も付けないといけないかもなー。 しかし 128KiB RAM (基本メモリー 64KiB + 拡張メモリー 64KiB) だけではさすがに動かないゲームも多いようだ。

2016/06/22 のコメントを読む・書く


23 (木)

%1 風邪

のどの症状はちょっとずつ良くなってきている感じがする。 立ち上がったときの頭痛もほぼ解消か。 もう最後の症状が残っているくらいな感じだ。 ひたすらのどに来る風邪だったということか。

%2 バス

小田急バスの降車ボタンを押したときに流れる放送「次 とまります。危険ですから...」の音声が女声から男声に変わったのはいつだったか、去年くらいだったような気がするんだが、これが最近また変わったのである。 今度は子供の声になっていて、さらに、「自転車や歩行者に注意してください」などというせりふが追加された。 ちょっと滑舌が悪い感じで「電車や歩行者」みたいに聞こえて、えっ、ってなる感じが、まぁ、そういう注意喚起が狙いか。 そういう意味で適度に変えないと効果がないのかも知れない。

小田急バス運行のコミュニティーバスはというと、あえて乗ってみたところ、男声のままだった。 そして、乗ってから気づく、ドアーを閉めた時の「発車します。おつかまりください」みたいな放送も男声だ。 そういえば路線バスのほうはこっちは子供の声には変わってなかったんだっけ。

そして具体的なせりふを思い出そうとすると、どうしても「バスがよくとまるまで」を思い出してしまうのであったw 関東鉄道バスがかつて使っていたやつ。

2016/06/23 のコメントを読む・書く


24 (金)

%1 休暇

風邪を引く前から予定通りの休暇。 風邪のほうはというと、のどの痛みに多少波があって、平均するとここ 2 日ほど結局あまり変わっていないような気がする。 手持ちの風邪薬は期限を 5 年くらい過ぎていたので処分しよう。 手持ちの薬の中にのどの痛み用の薬があったので、夜に飲んでみたところ、効いているようだ。

%2 株主総会

三菱自動車の株主総会。 会場は幕張イベントホール。 人数が多くなることを見込んでだったようだが、さすがに大きすぎたか、1 階部分の前半分で足りそうなくらいだった。

三菱自動車、話題の会社である。 会場周辺にはカメラを構えた報道関係者らしき人をちらほら見かけた。 監査報告は燃費不正があったことをふまえつつ、それ以外に問題は無いというような内容。 決算報告のビデオでは燃費不正問題を淡々と説明している。 さらに会長の益子修から再発防止策等に関して直々に説明がされる。 最大の疑問はなぜ益子修はやめないのかというところ。 一応本人が言うには再発防止策の筋道を立てるまでは自分がやる、その後は日産との資本提携の後で株主総会で? 取締役会で? 決めることで自分が決めることじゃない、みたいな、そんな言い分だった。 何だよコラと言いたくなるような話だが、そのときが来るまでの役員報酬は自主返納する、というようなことも言ったので、それでまぁいいかと思った株主も多いのではないだろうか。

議案の上程までされてから質疑応答が始まる形式。 それまでに 1 時間弱が経過していた。 様々な質問があったが、外部有識者による特別調査委員会について詳細は、という質問の答えが一番興味深かった。 別に秘密にしているわけではないようで (当然か)、元検事? か何か、弁護士の 3 人ほどと、それでは自動車の専門的な知識を持つ人が足りないとして、元トヨタ自動車の人も加わっているらしい。 そして関係者が (?) 毎日のようにインタビューをしているほか、これらの委員も週に 1, 2 度は岡崎に行って終日インタビューをしているとか、何かそんなような話。 中間報告は無く、詳細は来月の下旬あたりに出てくるんだとか。

質問で、三菱自動車の企業体質を問う声も。 社外取締役もほとんどが三菱の関係者だとか、縁故採用があるんじゃないのかとか。 当然、縁故採用は無い、って答えになるが、これって、三菱グループの関係者くらいしか三菱自動車に入りたい人がいないのではなかろうか、なんて思った。 益子修は経営の最高責任者なのだから辞任するべき、とか、問題の軽自動車は益子修が社長の時代に出た車種だろ、とか、様々な厳しい指摘も当然あったが、会長は極めて穏やかに誠実に答えている感じではあった。 そういえば、舛添要一のやったことは不正ではないが不適切 (正しくは違法ではないが一部不適切)、三菱自動車のやったことは不適切ではなく不正だという、時事ネタ指摘もあった。

違和感があった点。 以前の不祥事かな、2004 年頃とか言っていたと思うが、そのときに数百人が辞めて、人手不足になったというような話があった。 人手不足ってね、他人のせいか? 問題だらけの会社でも、高い給料を出せば必ず人は入ってくる。 それをやらなかったのは誰だい? みたいな。 それと、再発防止策、今回走行抵抗の机上計算があった (この問題自体はスズキに近い、数車種が挙げられていたが燃費を良く見せるものではなかったそうな) ということで、そういう不正行為がないように徹底する、教育する、みたいなそんな感じの言い方があったんだけど、あの言い方だと開発部門の技術者にまで強制されないかな? 開発段階の内部用データとしては机上計算だろうが何だろうがやっていいんだよね。 そうしないとデータのばらつきもあるから開発がなかなか進まなくなる。

%3 移動

天気が怪しげでめんどくさいので、車で高速フル利用。 中央道から永福にかけてが一番渋滞していた。 中央環状線では事故現場を通過、発炎筒が左側に置かれていて、ああ、右に行けってことかな、と右ミラーを見ると無灯火で結構なスピードで迫ってきそうな車があり、勘弁してくれよと思いながらさっさと右合図を出して車線変更、先の見えないカーブを曲がると左側で事故処理中だった。 事故だって表示が出ているにも関わらず、カーブの多いトンネルで制限速度 +20km/h 以上な車が走っている世界、首都高だと事故処理の人もめっちゃ危険そうな感じがする。

帰りも高速フル利用、調布 IC 出口ランプが渋滞していた。 調布 IC からだと手頃な給油所に行くのが面倒くさいのと、窓がだいぶ汚れていたこともあって、セルフじゃない給油所に寄って給油。 窓を拭いてくれた。130 円/l。 燃費計算 20.4km/l。 燃費表示 21.8km/l。 もしかして、計算よりも表示の燃費のほうがやたら良くなることがある原因は、例の 1NR-FE の燃料噴射装置の不具合問題が確か、冷間時にコンピューターの計算よりも燃料を噴射しすぎているという話だったと思うので、冷間時の分はそういう傾向になるのではないか。 修理をすれば解消するのかも。

2016/06/24 のコメントを読む・書く


25 (土)

%1 ブックオフ

ブックオフの株主総会。 本以外に手を出した結果、赤字だとか? まぁ今期はシステム開発等にお金がかかったって言うけどね、本以外では遅い参入なのだから、同業者に勝ち目があるのかどうか。 利益が年々減ってマイナスってことで、今年は質問でも厳しそうな指摘があったね、本がおろそかになってどうすんのみたいな。 今回は取締役の任期満了のタイミングではなかったし、採決に興味は無かったので 80 分くらいのところで退出した。

%2 JX のスーパーインポーズの謎

CRTC HD46505SP-2 (MC6845) のエミュレーションを JX エミュレーターに実装し、それをもとに VRAM の読み出しなどを行うようにして、いい感じに動くなと思っていたのがきのう。 そして何となくスーパーインポーズを試したら... 適当に screen 1,1:screen 7,1,1 を試したら、合成された VP1 のグラフィック画面が崩れているのであった。 あれ? あれれ?

原因は CRTC の MA (メモリーアドレス) と RA (ラスターアドレス) を、テキスト表示の VRAM アドレスとフォントアドレスに使用するだけでなく、グラフィック表示の VRAM アドレスにも流用したことだ。 いや、VRAM のアドレス計算が、1 ラインごとにバンクが違うなど少々トリッキーなことを考えれば、これは流用されてしかるべきものではないかと思うし、パラメーター値からしてたぶん PCjr はそういう設計になっているのではないかと思われる。VP1 のページレジスターにだけ、画面モードに合わせて設定するビットがあるが、これはアドレス計算に関係しているようである。 問題は、VP1 のグラフィックと、VP2 のテキストを合成する場合、CRTC のパラメーターはフォントアクセスの関係でテキスト表示に合わせられるから、MA と RA はテキスト表示用のものになり、グラフィック表示に使う VRAM アドレスとは無関係のものになる。

さて、謎を解くために回路図を開く。RA をたどっていくと... まずメインメモリーのところだ。 さりげなく CG1 のフォント ROM が見えている。 フォント ROM のアドレスラインの下 3 本が RA に直結だ。2KiB のはずなのだがアドレスラインが 13 本 (!) あり、一番上はプルダウンのようだ。 その下は RA3 がつながっているが何のためか? フォント ROM の出力は D フリップフロップ (!) によりラッチされる、というか、フォント ROM のアドレスラインにつながる文字コード読み取り用、CPU アクセス (読み取り?) 用と、属性読み取り用のラッチがあって、これでタイミングを合わせているみたいだ。 文字コード読み取り側は RA3 がクリアにつながっていて、これで縦 8 ドットを超える時には強制的に文字コード 0 になるのかも。 へぇー。64KiB 拡張メモリーを搭載するとインターリーブとなり、奇数アドレス・属性が拡張メモリー側になる。 とまぁともかくそんな感じで、そのほかは VP2 用と思われる漢字 ROM の近くと、拡張表示カードにつながるところか。 あと RA0 だけ何か別のセレクターっぽい回路にもつながっているようだがよくわからなかった。

MA はすぐ隣の LSI に直結だ。 メインメモリーは RAS CAS を用いた 8 ビットのアドレス指定になっており、その LSI がアドレスを出しているようだ。 詳しくはわからんけどその LSI に RA が入力されていないことから、やはり VRAM のアドレス計算に RA は使われていないと見るべきだろう。

ってちょっと待て、じゃあこのスーパーインポーズの時の VRAM アドレスはどこで計算されるんだ。 ってこの LSI しか無いと思うんだけど、RA は使ってないしいったいどういうことだろう。 どこか巡り巡って RA が入っているとか? と思ったけど拡張表示カードの端子説明でも RA はテキスト表示用だとある。 あれれ?

2016/06/25 のコメントを読む・書く


26 (日)

%1 JA

そうそう、きのうはじゃがいも掘りだった。 今年はそんなに多くはなかったような? でも、腐った感じのは無かったから、いいかも。

あと、准組合員なので今年も配当金があったわけだが、またしても普通貯金の残高から特別配当金、これがまた 0.15% もあるから下手な銀行の定期預金より利率が良いわけで、わずか 3 万円の出資で至れり尽くせりである。 引換券は醤油だったかな、くじを引いたら見事に当たり! うどんとそうめんがそれぞれ 500g x 2 入っている。

%2 JX

スーパーインポーズ対策は、グラフィック画面の時は DISP 信号と VSYNC 信号をもとに、最初だけ MA をもらって、その後はアドレスを独自に計算する方式でごまかし実装。 次に、ボーダーカラーが出るようにするのと、画面をずらすことができるようにするために、画面表示回りをさらに改変する。 要するにブラウン管の縁に隠れる部分を含めて構成し、必要部分を表示しようってわけなんだが、いざ作ってみると画面モードによって画面の位置が意外と大きくズレる。 特に PCjr の画面がやたら右にズレる。 何でかというと、CRT コントローラーに設定される水平同期信号のタイミングが違う。

例えば横 40 桁 (低域モード) では水平トータル 57 桁、表示 40 桁 (当然)、水平同期信号の長さが 6 桁というのはいずれも同じだが、水平同期信号の位置が、基本モードでは 40x25 テキスト画面で 47 桁、2 色グラフィックモードで 46 桁となっているのに対し、PCjr では 40x25 テキスト画面で 44 桁、2 色グラフィックモードで 43 桁となっている。 そうすると水平同期信号の終わりから左端の文字が出るところまでの長さ + 右端の文字の終わりから水平同期信号の始まりまでの長さは、それぞれ 4 + 7 桁、5 + 6 桁、7 + 4 桁、8 + 3 桁となる。 さすがにここまでズレたらどうしようもないな。 なお、英文モードカートリッジならズレないみたいなので、パラメーターを日本向けに変えてあるようだ。

いろいろ調べていたら、ビデオ信号をソフトウェア側から確認できる仕掛けが存在するらしいことを見つけた。VP1 のステータスレジスターのビットに、ゲートアレイのアドレスに応じて IRGB のいずれかが現れるらしい。 起動時に画面の一番上にチラッと線が見えていたやつ、あれは何かというと、40x25 モードで背景色白・文字色白? で画面の一行目に _ を 40 桁並べ、その信号をステータスレジスターから得てテストしているらしい。 今までその部分をちゃんとエミュレートしていなくて、何か返さないと POST で引っかかるのでとりあえず毎回ビット反転しておくというあり得ない実装をしてあったので、おかげでテストを一瞬でパスしてしまい、白い線が見えなかったわけだ。

垂直帰線時割り込みの頻度が狂うようなバグを作ってしまい、動作確認中に某ゲームのデモの動作がなんか変だと思ったらデモ中にワールドレコードが更新される事案が発生w 垂直帰線時割り込みを音と時間計測に使用していたらしく、2/3 くらいの頻度になっていたもんだから、ゲームの進行ペースは変わらないのに時間がなかなか進まないことになってそういう結果になっていたようだ。

2016/06/26 のコメントを読む・書く


27 (月)

%1 8088

拙作エミュレーターの 16 ビットの IN/OUT 命令の実装をミスっていて、上位 8 ビットから先にアクセスしていた。 こういうのは little endian らしく素直に下位 8 ビットからアクセスするのが正解である。 そうしないと CRT コントローラーへの書き込みを 3d4h への 16 ビット OUT 命令で実行できなくなってしまうのである。 って、そんなことを子供の頃に試した記憶はあるが、一般的な方法ではないのかと思っていたら、実際に使われていたらしいことを知ったのであった。

なお 8088 は外部バス 8 ビットなので、こういうのは CPU 内部で行われるが、その後の外部バス 16 ビット以上の機種では CPU は 16 ビット幅でそのままバスに流してしまう。 当然ハードウェアがそれを許容するようにできていなければちゃんと動かないのだが、おそらく IBM PC 互換機というのは、IBM PC が 8088 だった名残で、これを 8 ビット幅のアクセスに変換するような仕掛けがどこかについていて、未だにそういうのが動くものと思われる。PC-98 シリーズなんかは最初から 8086 だから、8253 タイマーなど 8 ビットでやりとりする同じシリーズのチップであっても、IBM PC とはアドレスの割り当て方が異なり、偶数アドレスだけを使用するなどになっている。

%2 のど

一週間経っても違和感があるのは変だから、明日は耳鼻科に行ってみよう。

2016/06/27 のコメントを読む・書く


28 (火)

%1 休暇

マルハニチロの株主総会。 おみやげを帰りにもらった記憶があって、それはあっていたが、おみやげだけもらって帰るという選択肢も用意されていた。 すなわち、早めに行っておみやげをもらって、その足で FFRI なりミクシィなりの株主総会に行くという選択肢はあった。 しかしながら、2 年前に行った時に使った駐車場はなくなっており、手頃な駐車場を見つけるのに手こずったため、それはしなかった。2 年前の時の子会社の農薬混入事件についてあらためて質問している人もいたが、安全管理については以前にも増して注意が注がれているのではないかと思う。 チルド事業だったかな、魚肉ソーセージとかゼリーとか? そのへんだけ減収減益だとかで、それ以外はずいぶんと好調みたいだったんで、満足して 1 時間ほどで帰った。

一般道で甲州街道に出て、バスタ新宿の前を通った。 出入り口は信号のある交差点になっているのね。 タクシーも一掃されて、良い感じであるが混雑していたw 初台あたりから首都高・中央道をちょろっと使って帰宅。

耳鼻咽喉科へ。 のどが腫れているとのことで、薬を処方された。 とりあえず 4 日分、あんまり調子が良くないようなら週末また来てくれとのこと。

拙作エミュレーターの遅いところはどこか、gprof を使ったら時間がちゃんと出てないし、インライン展開されているような関数も回数を数えるらしくすげぇ CPU を食っているっぽい。 うーん。 代わりに oprofile と思ったが、カーネルに機能は入っているけどユーザーランドのプログラムが Debian パッケージに無いっぽい? 今時は perf というツールを使うらしい。 これは linux-tools というパッケージでサクッとインストールでき、使うのも簡単だ。 仕組みがよくわからないけど特に CPU 使用率も上がらず、それでいていい感じに情報が取れている。 早速見てみたら、画像処理ではなく音関係の処理がトップに来た。 予想外。 どうも妙ちくりんな構成のループに CPU がついてこれないらしいw

for(i=0;i<n;i++){
  a++;if(a>=A){a-=A;...;}
  b++;if(b>=B){b-=B;...;}
  c+=x;if(c>=C){c-=C;...;}
}

i, n をローカル変数、その他の小文字をクラスのメンバー変数、大文字を定数として、こんなようなループを書いてあったのだが、実は c のところの条件が成り立つ頻度が一番低い。 もちろんコンパイラーにはそんなことはわかりようがなく、3 つを同じようにコンパイルしてくれて、その結果、それぞれの足し算と条件比較の回数がものすごいことになっていた。 このクソループをゴリゴリと書き換え... るのではなく、c のところの条件に引っかかるまでの間だけ、a と b のところを単純なループでゴリッとすませるようにしたら、コンパイラーも CPU も素直に動いてくれるようになった。

2016/06/28 のコメントを読む・書く


29 (水)

%1 JX

そうそう、JX のビデオ・ゲートアレイのリセット・レジスターの説明には、メモリー・リフレッシュをしてから同期リセットをすればメモリーの内容が消えないよ、みたいなことが書かれている。 某所で見つけた PCjr のほうでも同様の、いや、より詳細な説明があり、同期リセット中はメモリーへのアクセスができないといったような説明があるし、そういえば BIOS のソースコードにもそういうコメントがあった。 要するに、メモリー・リフレッシュがとまってしまうという話なわけだ。

しかし、しかしだ。 昔試した記憶では、BASIC プログラムや RAM 上の機械語プログラムから同期リセットをかけてモード変更をすることが、できた記憶がある。 少なくともそれで、POST 処理を RAM 上に移して一部書き換えて実行することで、7.2MHz のまま拡張表示モードから基本モードへ遷移させるプログラムを動かしたことがある。 モード切替時の同期リセットは、とうていプリフェッチキューに乗るサイズではないので、実際 RAM へのアクセスはできていたわけである。

単純に謎だなぁと思っていたけど、最近になって謎が解けた。 内蔵の 64KB メモリーと 64KB RAM カードのメモリーは、VRAM と共用のものでシステム基板側でリフレッシュが行われる。 しかし、拡張チャネルに接続される 128KB RAM カードは、リフレッシュ回路を内蔵しているのだ。 つまり、ビデオ・ゲートアレイのリセットでメモリー・リフレッシュがとまるのは実は VRAM と共用の 128KB 部分だけで、残りの拡張メモリーはリフレッシュ回路を内蔵しているのだから、電源供給が途絶えでもしない限りはリフレッシュがとまることはあり得ない。 と思ったんだけど、リフレッシュ用の端子が拡張チャネルに存在するみたいなので、そこの信号が途絶えてしまえばリフレッシュはとまるかも知れない。

とはいえ、おそらく、VRAM 共用かどうかは重要なところで、英文モードではその VRAM 共用メモリーが下位 128KB に来てしまうので、これが飛ぶということは割り込みベクターやら何やらといった重要情報がすっ飛んでしまうことになりうまく動かない。 ところが基本モードや拡張表示モードであれば、このメモリーは上位に来るので、128KB RAM カードを 3 枚さしてあったはずのあのマシンでは、ちょっとしたテストプログラムはほぼ確実に下位の拡張メモリー側にのっていたに違いなく、そのときに VRAM 共用メモリーの内容が失われていたかどうかは確認していないんだけど、おそらく失われていたんじゃないかなーと。

なお、エミュレーターではリセット・レジスターの処理はまともにやっていない。 モード切替の時に使うらしいのだけど、一部のレジスターは変更が即座に反映されないとでも言うのかな? とにかく具体的にどういうことなのかいまいちわかってないのだ。 しかも、そんなふうに扱いづらいレジスターだから、おそらくこれを触るソフトウェアは BIOS 以外にはほとんど無くて、ちゃんとやってなくても動かないソフトウェアはまずない。

%2 のど

薬を飲んでいるけどいまいち効き目が感じられない。 このまま行くと土曜日再受診かな。 この薬が効かないとすればおそらく抗生物質の種類が変えられるのではなかろうか?

2016/06/29 のコメントを読む・書く


30 (木)

%1 もくようび

きのうは効き目が感じられない (キリッ なんて書いたけど、今日になったら急に薬が効き始めた気がする。 よしよし。

夕方は雨とか言っていたけど全然降らず。 きのうもそんなんだったような。 関東はそんな感じだが、九州地方は大変な大雨が降ったらしい...

Bochs のシリアルポートのコードを借りて JX エミュレーターに移植しようとしたが、いや、してみたんだが、BIOS の Power On Self Test が通らない。 あれれ。 このテストって結構厳しいんだよなー。 なお、JX では RS-232C カードはオプションで (2F8H-)、接続すると 8255 のビットが落ちるようになっているが、PCjr ではどうやら標準で (2F8H-)、モデムを拡張 (3F8H-) すると 8255 のビットが落ちる仕掛けのような感じっぽいらしい。 あと、どちらもボーレート計算に使用するベースクロックが IBM PC とは異なるらしい。JX にも PCjr のモデムの名残と思われる 3F8H のポート割り当てが MODM という名前で残っているが、その拡張自体は存在しないっぽい。

拡張表示モードの表示タイミングを計算する。 テキストモードは水平 102 桁、水平表示 80 桁、水平同期 88 桁、水平同期の長さ 12?、垂直 27 行、垂直の補正 2 走査線、垂直表示 25 行、垂直同期 25 行!?、一行 21 走査線? グラフィックモードは水平 57 桁、水平表示 45 桁、水平同期 49 桁、水平同期の長さ 6?、垂直 72 行、垂直の補正 0 走査線、垂直表示 64 行、垂直同期 65 行!?、一行 8 走査線? か。 ちょっと設定値がよくわからないところもある。 一行の走査線は通常、数値から 1 を引いた値を設定するが、インターレースでは -2 なのか? そして垂直同期の開始と垂直表示の終わりのタイミングが同一って有りなのか!? それとも垂直同期のも 1 引いた値なのかな。 で、テキストモードは一桁 9 ドット、グラフィックモードは一桁 16 ドットになる。 ビデオ周波数は 20MHz、それでかけ算・割り算をすれば 76.68Hz と 21.930kHz が出るはずなのだが...

20000000/(102*9*(27*21+2)/2)
76.57818057900762335787
20000000/(102*9)
21786.49237472766884531590
20000000/(57*16*(72*8+0)/2)
76.14522417153996101364
20000000/(57*16)
21929.82456140350877192982

うーん、微妙にズレるな。

2016/06/30 のコメントを読む・書く


Powered by Tomsoft Diary System 1.7.4

/var/log/hdk.log コメント一覧

トップ / 日記索引 / 日記 (2016 年 6 月下旬)

Hideki EIRAKU