2009年3月アーカイブ



スキッシュを合わせてみました。段差0.25mmで0.8mm。

そしてヘッドの燃焼室の切削テストをしました。どのくらい削ってどのくらい 容量が変化するかがまったくわからない。削ったな〜と思ったのに0.2ccしか減っ てなかったり。7,8回、測定、切削を繰り返してなんとか9.4ccまで。ヘッド高 さが低くなってるから、このくらいでちょうどいいのでは。
スキッシュは幅広めにとっておいて燃焼室の切削で幅を合わせるといい。

ベストヘッドu01は、参考用にカットモデルにしました。スキッシュは15度くら いでもいいのかな。あまりピストンと並行にすると燃焼室の容量稼ぐのつらい。 いきおい、天頂部が平たい燃焼室になる。それがいいのか悪いかどうかはわか らないけれど。

完成。これは使えそうなのでいざというときの予備にとっておこう。

トウモロコシも種を蒔きました。

x86続き。
割り込み、例外について。

これらのエントリはゲートデスクリプタで指定する。

ゲートはコールするセレクタ:オフセットを設定するもの。コールゲートの場合、
callerとcalleeの間の引数の引き渡しのためにスタックをコピーするため、い
くつコピーするかの情報がさらに必要になる。割り込みゲートは自動的に割り
込みを制限する。

ゲートデスクリプタはinterrupt, trap, call, taskの4つがある。

コールゲートはjmp/call命令でそのセレクタを指定することで間接的にジャンプ
する。

タスクゲートはjmp/call命令でそのゲートセレクタを指定すると、ゲートに指
定されたセレクタに指定されるタスクに切り替わる。

jmp命令では準位をまたいだ移行はできない。callのみ準位をまたげる。

ゲートを登録できるテーブルには制限がある。

  GDT ... code, data, stack | call, task,            | tss, ldt
  LDT ... code, data, stack | call, task,            |
  IDT ...                   |       task, intr, trap |

IDTにタスクゲートを登録できるのは割り込みによってタスク切り替えをする
ことを想定したのだろう。

割り込みゲートとトラップゲートの違いは、ゲートに入った時にEFLAGSのIFが
クリアされる(割り込みゲート)かされないか(トラップゲート)。

保護モード用にIDTを設定したら、リアルモードに戻る前にリアルモードのベク
タテーブル位置(0x0-0x3ff)をlimitとして設定したIDTに登録しなおす。デスク
リプタのリミットはリアルモードでも適用されるから。


保護モードのIDTの最初の32個(0x00-0x1f)はプロセッサによって予約されてい
る。なのでユーザが定義できるのは0x20-0xff。

  0	divide by zero
  1	single step/ trap, interrupt.
  2	nmi
  3	break point
  4	interrupt on overflow
  5	bound range exceeded
  6	invalid opcode
  7	processor extension not available
 *8	double exception
  9	processor extension segment overrun
 *a	invalid task state segment
 *b	segment not present
 *c	stack segment overrun of not present
 *d	general protection
 #e	page fault.
  f	reserved by intel
  10	coprocessor error
 *11	alignment
  12	machine check
  13-1f	reserved by intel.

  * push error code
  # push error code (special)

プロセッサからの例外のうち、8,10,11,12,13,14,17はエラーコードをプッシュ
してくるので、IRETする前にプッシュされた分を戻さないといけない。

    +---------------+
    |     EFLAGS    |-4
    +---------------+
    |     CS        |-8
    +---------------+
    |     EIP       |-12 <-ESP
    +---------------+
    |  Error code   |-16 <-ESP (8,10,11,12,13,14,17) *,#
    +---------------+
    |               |
           ...
    |               | stack_top
    +---+---+---+---+
      3   2   1   0

ゲートに入る時はEFLAGS, CS, EIPの順にスタックに積まれる。IRET命令はこれ
をそのまま復帰する。

スレッドの実装ではnear callで呼ばれたスタック構成をIRETでリターンできるように
再構成することにした。

	/* void do_thread_switch (void) */
	/* Assume already interrupt disabled */
	/* Called from thread context */
	.code32
FUNC (do_thread_switch)
	/*
	Rearrange stack frame for IRET.
	     before   ---->  after
	|               ||               |
	+---------------++---------------+
ESP ->	|     EIP       ||    EFLAGS     |
	+---------------++---------------+
	|               ||    CS         |
	+---------------++---------------+
	|               ||    EIP        | <-ESP
	+---------------++---------------+
	|               ||               |
	+---------------++---------------+
	|               ||               |
        ...		 ...
	|               ||               |
	+---+---+---+---++---+---+---+---+ stack_top
	    3   2   1   0    3   2   1   0
	*/
	popl	%eax	// EIP
	pushf		// EFLAGS
	subl	%edx,	%edx
	movw	%cs,	%dx
	pushl	%edx	// CS
	pushl	%eax	// EIP
	//
	// save context.
	movl	current_thread, %ecx
	movl	%esp, 0x1c (%ecx)
	movl	%ebp, 0x18 (%ecx)
	movl	%edi, 0x14 (%ecx)
	movl	%esi, 0x10 (%ecx)
	movl	%ebx, 0x04 (%ecx)
	// no need to store caller saved. (this is subroutine call.)

	call	thread_context_switch
	movl	current_thread, %eax

	// restore all. thread may be suspended by interrupt.
	movl	0x1c (%eax), %esp
	movl	0x18 (%eax), %ebp
	movl	0x14 (%eax), %edi
	movl	0x10 (%eax), %esi
	movl	0x0c (%eax), %edx
	movl	0x08 (%eax), %ecx
	movl	0x04 (%eax), %ebx
	movl	0x00 (%eax), %eax
	//
	// resume EFLAGS/CS. and return
	iret

スレッドを作成する時にはこの通りにスタックを設定する。IRETした先が関数の
入り口になるので、こうなる。EFLAGSのIF設定に配慮が必要かも。

  struct iret_stack
  {
    uint32_t eip;
    uint32_t cs;
    uint32_t eflags;
    uint32_t noreturn;	// place holder.
    uint32_t arg;
  } __attribute ((packed)) *iret_arg;

  /*
                     stack_bottom
    +---------------+
    |  1st arg      |-4
    +---------------+
    |return address |-8
    +---------------+
    |     EFLAGS    |-12
    +---------------+
    |     CS        |-16
    +---------------+
    |     EIP       |-20  <-ESP
    +---------------+
    |               |
           ...
    |               | stack_top
    +---+---+---+---+
      3   2   1   0

   */
  __thread_setup (tc, stack_size, name);
  tc->regs.sp = (addr_t)(tc->stack_bottom - sizeof (struct iret_stack));

  // install return address for 'IRET'
  iret_arg = (struct iret_stack *)tc->regs.sp;
  iret_arg->eflags	= eflags_get ();
  iret_arg->cs		= cs_get ();
  iret_arg->eip		= (addr_t)start;
  iret_arg->noreturn	= (uint32_t)thread_machdep_noreturn_assert;
  iret_arg->arg		= arg;



また嫌なメモリ破壊バグに出会った。なんとかそれを再現するコード。

このコードの主役はfunca。引数をとり、その引数は使わなく、funcaがリター ンすることはないことがポイントだ。
void
funca (int a)
{
  int i = 1234567890;

  funcb (i);
}

void
funcb (int a)
{
  while (1)
    ;
}
これを i386-elf-gcc -O2 -S a.c でコンパイルする。
gccのx86向けの最適化はすごくて、funcbがリターンすることがないことをわかっ ていてcallじゃなくjmpする。
funca:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$1234567890, 8(%ebp) ←引数を使いまわす。この関数用を次の関数用に。
	leave
	jmp	funcb
そして戻ることはないのだから、引数領域のスタックをそのまま使いまわすの だ。ここまで最適化するとは思わなかったよ。
これが問題なるコードを書いてしまったのだ。ブートストラップから自分自身を スレッドに移行する部分。
  __asm volatile ("movl %0, %%esp \n jmp *%1"::
		  "r"(current_thread->stack_bottom), "r"(board_main));

void
board_main (uint32_t arg)
{
  while (/*CONSTCOND*/1)
    ;
}
このコードで上記のようなことになってしまい、スタックの底を割ってメモリ を破壊したのだ...。
きっちりと
  __asm volatile ("movl %2, %%esp\n"
		  "pushl %0\n"
		  "pushl %1\n"
		  "jmp *%3" ::
		  "g"(arg),
		  "g"(dummy_return),
		  "g"(current_thread->stack_bottom), "r"(board_main));
のように変更。うっかりnoreturnの関数が帰ろうとしてとんでもないEIPに飛ば ないように、return addressにも、おかしいことを気付かせるルーチンを入れ ておきました。
これ、結構キツかった...。



今日は弟が来て、旋盤を使っていたので先に新品シリンダのポート加工をしま
した。

最近旋盤の使い方にも慣れてきたようで、好き勝手になにか自転車のパーツを 作っています。
机はなんとか甥に受け入れてもらえました。「おじゃる丸のがいい〜」とか言 われたら立つ手ないな...とドキドキした。
さて、シリンダは。今までで一番思いっきりよく削りこんでみた。

掃気ポートの隔壁はきっちり残す派です。ここは残しても残さなくても絶対的な 差はない。

今回、下側に結構掘りこんだ。

排気ポートは全面サラって、メッキ部分と面一にするくらい。ポートのへりは 全部のポートをゴム砥石でナメておきました。

これは以前、ヤフオクで落としたCRに入ってたシリンダ。削りっぷりがいい。 これを見ると削る気になる。これは掃気ポートとの隔壁を落とすタイプ。

しかしなかなかここまで削る勇気がない...。一度カットモデルでも作ってみよ うか。

ちょっとヘッドを進めました。まずはゴミヘッドでテスト。これは11度。これ でピッタシかな。12度くらいがいいかな。

この形で逆転で切削します。

マクガイバーの今のとこの最高は「ミサイル撃墜作戦」。他は、1話「決死の救 出作戦」これはまさにマクガイバーの原点、3話「少女イアナ」後半の東側から 逃げるカーチェイスがいい。他も8話までは全部いい。「恐怖の時限爆弾」やっ ぱり時限爆弾の処理こそ!


桜が咲きはじめた。





スイカも植えます。数打ちゃあたる方式で。

ピストン状況。np.

05ヘッドとピストンヘッド。もうちょっとスキッシュをピストンに並行にしたい。

これは04ヘッド。

プラグ高さの目安のためにヘッド高さを測っておきます。
05: 26.81
04: 27.59
u01:26.68  ベストヘッド。
u02:25.93  それなりにいいヘッド。これはプラグにワッシャをかましていた。
27mmくらいに合わせればいいかな。

u02(それなりにいいヘッド)はこの通り、外周の方がスキッシュが拡がってるの だ。これはよろしくないけれど、このヘッド自体は悪くなかった。

探したら切削練習用ヘッドが4つも見つかった(そのうち2つはATACがついてたこ ろのCR80だ)。u01ヘッドをもうちょっと追いこんで、スキッシュ0.8mmを確実に したところで、燃焼室で単体9.5ccにもっていこう。燃焼室の切削で容量を調整 するのは結構大変なんだけどね。
削っては計測の繰り返し、やり過ぎたら最初からやり直し、とはいってもヘッ ド高さはどんどん低くなっていってしまう。

MCFAJ一戦まであと3週間だ!



残りの菜園も耕しました。汗だく。3畝全部で40kg堆肥を入れて、鶏糞も混ぜま
した。去年は自家製の腐葉土を混ぜただけだった。

手前の半畝の部分にチンゲンサイを蒔きました。

トマトは腐葉土(自家製)を使って育苗箱に。夜は部屋に入れています。

x86続き。
保護モードに移行した後もリアルモードのBIOSはまだ使いたい。

BIOSを呼ぶルーチンはこの形に固定することにした。引数が2つなのは
regparm (3)のうち一つはこの関数へのポインタに使われてしまうから。
保護モードとリアルモードでpush/popのアライメントが異なるので、そこの複
雑さをレジスタ渡しでクリアする目論見も。

typedef int (bios_func_t)(int, int) __attribute__((regparm (2)));
bios_func_t bios_com_init; これはリアルモード用の関数。

保護モードからはこのようにしてコールする。regparm (3)なので
3引数はそれぞれ左からEAX, EDX, ECXに積まれる。

int call16 (bios_func_t *, int, int) __attribute__((regparm (3)));

// int call16 (void (*)(int, int), int, int)__attribute__((regparm (3)))
// call real-mode subroutine from protect-mode.
	.code32
FUNC (call16)
	ENTER_32	これはcaller saved(EBX,ESI,EDI,EBP,ESP)を退避。

まず、リアルモードの設定にしたデスクリプタを設定。保護モード用の設定
だけれど、そのlimitはリアルモードでも引きつがれる。Dビットは16bitに
設定。
BXを使っているのは引数のAXをそのまま下に渡すため。
	// Install Descriptor for real-mode.
	movw	$0x20,	%bx
	movw	%bx,	%ds
	movw	%bx,	%es
	movw	%bx,	%ss
CSはmovで設定できないのでLJMPで設定。
	ljmp	$0x18,	$1f	// Load CS descriptor for real-mode.
Dビットは16bitに設定してあるので、ここから16bitモード。
1:	.code16
	// Change to real-mode.
	movl	%cr0,	%ebx
	andl	$~1,	%ebx
	movl	%ebx,	%cr0
パイプラインをフラッシュして、リアルモードのCSに0x0を設定。
	ljmp	$0,	$2f	// Load real-mode CS with pipeline flush.
2:
その他のセグメントもリアルモード用に設定。
	// Set real-mode DS,ES,SS
	subw	%bx,	%bx
	mov	%bx,	%ds
	mov	%bx,	%es
スタックポインタは今現在、リアルモードでもそのまま使える設定なので
これでいい。
	mov	%bx,	%ss
	// Now Real-mode.

呼び出す関数の引数を設定します。
	// Setup argument.
	mov	%ax,	%bx
	mov	%dx,	%ax
	mov	%cx,	%dx
	// Call requested function.
	call	*%bx

この後は普通にプロテクトモードに移ります。
	// Return to Protect-mode.
	movl	%cr0,	%ebx
	orl	$0x1,	%ebx
	movl	%ebx,	%cr0
	ljmp	$0x8,	$4f	// Load CS(0x08) with pipeline flush.
4:	.code32
	// Load DS(0x10),ES,FS,GS
	movw	$0x10,	%bx
	movw	%bx,	%ds
	movw	%bx,	%es
	movw	%bx,	%fs
	movw	%bx,	%gs
	// Load SS
	movw	%bx,	%ss
	LEAVE_32
	ret

これを使って、保護モードから呼ぶラッパーを作成。
void
bios_com_putc32 (int8_t c)
{

  call16 ((void *)bios_com_putc, c, 0);
}
これでBIOSを使ってシリアルにputc/getcできるようになったので、ここで はじめて本体のOSにつなげてみました。何も問題なくシェルモジュールは 動いた。気をよくして、ささっとスレッドまわりもポートしてみたところ、
qemu  -serial stdio -std-vga -hda boot
boot1: disk=0x0080
jump to boot2
stack_start: 0xfff0
data: 0xbc00-0xc4c4 2244byte
bss: 0xc4e0-0xcee4 2564byte
A20: enabled.
boot drive: 80
__thread_setup: [1] c928-c528
__thread_setup: [2] ced4-cad4
thread_create: [2]:app0 func=86ab esp=cec4 eip=86ab eflags=2 cs=8 stack=1024byte
thread_start: [2]
thread_priority: [1] pri 1->1 state = 0 (UP)
thread_context_switch: c4e0: sp=c8a0
thread_context_switch: switch 1->2: sp=cec4
app0: arg=abcdef90
thread_context_switch: ca8c: sp=ce88
thread_context_switch: switch 2->1: sp=c8a0
thread_priority: [1] pri 1->3 state = 0 (DOWN)
thread_context_switch: c4e0: sp=c880
thread_context_switch: switch 1->1: sp=c880
>help
[0] help
2: 610
1: 498
---Ready Queue---
<0>: 
<1>: 
<2>: 
<3>: 1 
---Thread Status---
id   pri(used/total)
[2] W 1 (418/1028) app0
[1] R 3 (530/1028) root
---Monitor---
avaliable command: help reset S 
>
おお。こんなにうまくいくとは思わなかった。



081002から作りはじめて半年弱かかってやっと完成。細かい所を見ると、多々
失敗があるのだけど、まぁなんとかギリギリのとこじゃない??? 自分のなら、
ある程度どうでもいいのだけれど、甥のプレゼント用に作っていたのだ(失敗し
たら自分用で)。この手のデザインは子供は好きじゃないかな。



ちょっと引出しのクリアランス1mmはギリギリ過ぎた。微妙な反りやねじれでか すってしまう。1.5mmかな。

いろいろ一息ついたところで、やっとジャガイモの植えつけ。堆肥(15kg程度) と鶏糞をちょこっとすきこみました。

もう既に結構、芽が出てきてしまった。(推奨は3月上旬)

堆肥をすきこんでから二週間待つ方がいいのだけど、そんな時間はないのです ぐに植え混み。株の間に鶏糞をひとつかみ入れて、株の上に堆肥をひとつかみ かぶせました。

ついでにネギの植え替えも。

残りの菜園には、去年惨敗したチンゲンサイと、これまた難しいトマトに挑戦 します。百均のトレーに穴をあけて育苗パッドにしました。





レールで引出しをインストールしました。SPFだとネジの喰いつきが悪いので
ちょっと強度的に不安。ネジの種類をまちがえたかな。普通の木ネジじゃなく
コーススレッドみたいな、エッジの鋭い小ネジがよかった。あるのかは不明。



オイルをかけてしまったタイヤは一度外して、パーツクリーナーできっちり拭 いて組み直しました。これで安心。



BSです。走行前には霰がパラつく寒さ。一本目は8時から。8.7℃。新品スリッ
クなので3周ほど皮剥きしてピットイン。タイヤを調べてみると、ちょっとビー
ドの隙間からオイルが出てる。やっぱり一度タイヤ外して拭きとるべきだった
か....。走行には問題ないレベルなので、走り始めるも、気持ち的にちょっと
怖い。なんか曲がらないし。Fの伸びを固くしたのがよくなかったのかな...
などと思いつつ、結局11秒しか出なかった!



タイヤは中古に履き替え。Fの伸び減衰をいつもより柔いくらいにしてみた。二 本目は11:50。日射しが現れることもなく、気温は10.6℃。まぁ10℃越えれば普 通に走れる。
ガツガツ走るも、10秒切れない...。曲がらないし。よくよく冷静に見てみると そこそこ初期旋回はしてるのに、アクセル開けれる気がしない。今日はシート に座れてないんだ。雨の後だからかな。ちょっとづつリラックスして乗るよう にしてなんとか8.9まで。
05ノーマルヘッドは13000rpmまでで吹け切り。あと500欲しい。下のトルク感あ るかというとそういうわけでもなく(下はトルク感ない方が僕は開けやすいので、 これはいい)、12000から13000間がとてもいい感じかな。このままあと一伸びあ れば。13000だと、15:34だと最終入り口でちょうど吹け切り。いいっていえば いいか。
ちょっと今迄、最終はイン付きが早すぎたかも。もっと覗いてから入った方が よさそう。
走行後残ストを見るとF11/R6、リヤはいつも通りとして全然Fが沈んでない。 どうしたんだろう。たぶんブレーキが甘かったんだろう。

タイヤゲージチェックサービスをやっていたので、チェックしました。2.0kPa で+0.04くらい。ついでにスリック前後YDC購入。D'sでprojectμのFブレーキパッ ド購入。

7:50 D.alt -217m 8.7℃ 44.0% 1013.4hPa 曇
1.8/1.8
F12巻き
4.5枚60℃
11秒

11:40 D.alt -132m 10.6℃ 56.6% 1012.5hPa 曇
1.8/1.8
F12巻き
残スト F11/R6
best 8.9



ホンダに追加注文出しに行ったら、クランクのB/Oは4/1の予定。


机続き。ラビングコンパウンドでポリッシャー磨きしました。その後は「かん たんマイペット」で掃除。

削りが甘いんだよね。集成材くらい固ければもっと楽なんだけれど。SPFは 柔らかさが難しい。ちょこっとぶつけてすぐ凹んでしまうし。
塗装は終了。後は引出しの組み立てで完成だ。




腰上は何も交換せずそのまま組み。火が入るのだけ確認して整備終了。た
だ...うっかり新品のスリックに思いっきりエンジンオイルかけちゃったんだ。
パーツクリーナーで吹きとって、一度ビード落としてホイールとの隙間部分も
拭いたけど...。うっかりにも程があるよ。



一戦で結構パーツを使ってしまったので補充。3/4に頼んだクランクが未だB/O で入ってこない。これからはそんなこともあるだろうと、ちょっと多めに頼ん でおきました。
BS、雨はなんとか降らなさそうだけど、また寒そう。なんでだ。どうでもいい 時だけ、いい天気で。
積み込みして、一息ついたところで、久々に散髪。最近、あまりにもボサボサ 過ぎて、道行く人に見つめられるくらいだったんだ。

机の続き。磨きに入る前に#600で表面ならしまで。




今日もまったりマシンを組みました。トルクロッドのワイヤリングを変更して
フレームに固定しました。今迄はトルクロッド側に固定していた。



サポート部も同様に。前のMCFAJの車検でダメ出しされたのだ。トルクロッド 以外は筑波選手権とそう変わりないです。

今日は親父が屋根裏を掃除していて、シリンダゲージをもらった。アダプタが 35,55,60しか残ってなく、残念ながらCR85には使えない。
上につけているダイヤルゲージは、今僕が使っているミツトヨのもの。これに 元々同梱されていたピーコックのダイヤルゲージはないけれど、幼少時、見た 覚えがある、あれかもしれない。ちょっと動かして、もの凄いいきおいで廻る 針が楽しかった。

なんと49年物。

こんなのももらった。温度センサーと圧力センサーと、そのアンプとロガー。 これはさすがに...使う機会はあるのか?

後は腰上整備だけのとこまで。全バラして洗浄すると輝きが違う。今回、 マメに全部の部品をマジックリンで洗ったんだ。



しかしBSの天候が微妙だ...。勘弁してくれ...。



まったりと車体を組み中。ちょこっと作業してはマクガイバー見たり、ちょう
どamazonで注文しておいたマイアミバイスがやってきたので、まだそれを見て
で進まない。

マイアミバイスは実は見たことがない。ちょこっと見たことはあるのだけれど、 居間のテレビで見るにはちょっと刺激が強いシーンも多いので、見れなかった ^^。
残念なことに、今回僕が買ったマイアミバイスは吹き替えがなかった。それに これレンタル用だし。
VIPPER刑事物語 やる夫とやらない夫 」このやる夫 版は、原作を噛みくだいた上で、ストーリーに乗りながら、いいアレンジでと てもいい。というか、こっちの方がストーリーとしては好きかな。日本人向け なのか。
あと「ダウリング神父」がもう一度見たい。残念ながらDVD化されてないようだ。 シスター・ステファニー、好きだったんだ。神父の下の男が吹き替えだと、確 か美味しんぼの富井副部長。ネーティブの声は結構渋くてギャップがすごかっ たのが忘れられない。

それはともかく。フォークオイルが真っ黒でした。あれ...なんでだと思ったら、 前にフォークをバラしたのは予備のフォークで(10月)、このフォークは去年の 8月以来だった。お恥かしい...。

x86続き。
嫌なバグに悩まされた。0x0:0x8000に二段目をロードした後、メモリが破壊
されるのだ。つきとめていったところ、スタックの設定を間違えていた。
今迄
	movw	_stack_start,	%sp
になっていた。これでは_stack_startのアドレスにある値がspになってしまう。
	movw	$_stack_start,	%sp
じゃないといけなかった。_stack_startはldscriptで設定。
偶然、_stack_startには0xfff6が入っていたので、そこそこ動いていた。
リアルモードなら16bitだし、0xfff6でも動きそうなものだけど、どうも4byte
アラインじゃないとだめみたい。

昨日のような実験を元に保護モードのデスクリプタの設定は普通に設定して
先に進めます。ベースは0から。スタックセグメントもデータセグメントと
同じ設定で。

保護モードに入ってしまうと、そのままBIOSコールは呼びだせない(BIOSはリア
ルモードで呼ばれるのを前提としているので)。なのでデバッグ用にprintfを作
りました。これはH8で作ったやつをコピペで。

やっとA20のテスト。QEMUはデフォルトでA20は有効なので何もすることがない。
ので、あえて無効にしてテスト。

#define	inb(addr, val)	__asm volatile \
("inb %1, %0" : "=a"(val) : "d"((uint16_t)addr))
#define	outb(addr, val)	__asm volatile \
("outb %0, %1" :: "a"((uint8_t)val), "d"((uint16_t)addr))

x86はオペランドにレジスタの制限があるのでgasでもコンストレイントを
指定できるようになっている。幅はキャストで効く。

void
a20_test ()
{
  uint32_t m0, m1;

  uint8_t r0;
  // make sure that i/o buffer is empty.
  do
    {
      inb (0x60, r0);	// drain buffer
      inb (0x64, r0);	// get status
    }
  while (r0 & 0x01);	// output(i8042) buffer full
  do
    {
      inb (0x64, r0);
    }
  while (r0 & 0x02);	// input(i8042) Buffer Full

  outb (0x64, 0xd0);	// output port read command.
  inb (0x60, r0);	// read output port.

  printf1 ("i8042 output port:%x\n", r0);

  outb(0x64, 0xd1); // output port write command.
  outb(0x60, 0x01); // write to output port.	ここでA20を無効に。
  // bit 0 ... RESET if set 0.
  // bit 1 ... A20 disabled if set 0.

  printf1 ("%x\n", r0);

  // 0x200なのはリアルモードの割り込みハンドラのその先を設定。一応。
  m0 = *(uint32_t *)0x200;

  //A20が無効なら、この操作で0x200も書き変わるはず。
  *(uint32_t *)((1 << 20) + 0x200) = m0 ^ 0xa5a5a5a5;
  //  __asm volatile ("wbinvd");

  m1 = *(uint32_t *)0x200;

  printf1 ("%x %x\n", m0, m1);
  if (m1 != m0)
    {
      printf1 ("A20 disabled\n");これが表示されればA20は無効だ。
      *(uint32_t *)0x200 = m0;	// restore.
    }
  else
    {
      printf1 ("A20 enabled\n");
    }

}

これでA20のスイッチをテスト。これはQEMU上では想定通りの動き。これを
ML115 G5の実機で動かしてみたところ、A20は有効のままだった。

さすがに今はもうこのあたりは削ったようだ。


MCFAJ一戦筑波、エントリーしました。悩んでたんだけど。今日がエントリー締
切。今年からエントリフィーが、筑波29000円、富士32000円(MCFAJの会員じゃ
ない場合)なのだ。

出れるうちに出ておこうということで。
マクガイバーのせいで作業が進んでいません。どれもこれもいい話だ。必要以 上に暴力的な場面が出ないのがいいね。
今日はここまで。フェンダーにフレームよけの穴を開けました。

机は7回塗り終了で、まぁなんとか。塗装は終了でここから仕上げの磨きです。

x86続き。保護モードに移行するのをいろいろ試してみた。

例えば二段階目を0x20000にロード。そのリアルモードのプログラムは
CS,DS,SS=0x2000になるように設定。ここから保護モードに移る。

保護モードのデスクリプタの設定は
struct gdt_config
{
  uint32_t base;
  uint32_t size;
  uint8_t unit;
  uint8_t mode;
  uint8_t type;
} gdt_config [] = {
  { 0x20000,	0x100,	SIZE_UNIT_4KB, CODE_32, CODE_SEGMENT },
  { 0x20000,	0x100,	SIZE_UNIT_4KB, CODE_32, DATA_SEGMENT },
  { 0x40000,	0x100,	SIZE_UNIT_4KB, CODE_32, STACK_SEGMENT },
};
と、0x20000オフセットしたものに。

lgdtに設定するのはリニアアドレスでないといけないので、0x20000の下駄を。

	.section .data
	.balign 4
lgdt_arg:
	.word	0x1f	// 0, Code, Data, Stack.
	.long	_gdt + 0x20000

このように移行。

	lgdt	lgdt_arg

	movl	%cr0,	%eax
	orl	$0x1,	%eax
	movl	%eax,	%cr0
	// Load CS(0x08) with pipeline flush.
//	DATA32	ljmp	$0x08,	$protect_mode_start
	ljmp	$0x08,	$protect_mode_start
protect_mode_start:
	.code32

lgdtは16bitと32bitの二命令がある。それはオペランドの処理の方法で、
16bit命令の場合(このサンプル)、設定したGDTRのベースに0xffffffがANDされ
るかどうかだけ。リアルモードから移行する場合は0xffffffを越えることはあ
りえないので16bit命令でいい。

ljmpは「保護モードのCS」が自動的に更新されているからフェッチできるはず。
オフセットについて。このljmpで先にロードしたGDTの設定(0x08)をCSにロード
して、それに基ずいてアドレスを計算する。設定では0x20000がベースになって
いるので、下駄をはかせる必要はない。
この状態ではまだCSがロードされてないからDビットは16bitモードだ。

DATA32でオペランドサイズプリフィックスをつけた場合、0x66がついてるので
オペランドの解釈を32bitモードだとする。(その変換の寄りどころはCPUによって
自動的に更新されている保護モードのCS)
 1af:	66 ea b7 01 00 00 08 	ljmpl  $0x8,$0x1b7	//DATA32あり
これを32bitとしてオペランドを解釈

つけなかった場合16bitとしてオペランドを解釈。(まだDビットは16bit)
 1af:	ea b4 01 08 00       	ljmp   $0x8,$0x1b4

なので、どっちでも同じはず。

そしてその他のセグメントの設定。
	movw	$0x10,	%ax
	movw	%ax,	%ds
	// Load SS
#if 1
	movw	$0x18,	%ax
	movw	%ax,	%ss
	// Reset stack pointer.
	movl	$0,	%esp
	movl	$0,	%ebp
#else
	movw	%ax,	%ss
	// Reset stack pointer.
	movl	$0xfff0,	%esp
#endif

スタックセグメントの設定は、インテルが想定していた設定はベースにスタッ
クの最大アドレスを設定して、ESPは0からはじまってマイナスに伸張するもの。
(上のコードの#if 1)、これだと同じアドレスでもデータセグメントからと
スタックセグメントからでポインタが異なる。

一般には(#if 0)のようにデータセグメントと同じように設定する。

今回、インテルの想定したような使い方を試してみた。普通にpush,popする分
にはいいのだけれど、varargsがだめ。今の状態ではきっちり追うことはできな
いけれど、スタックをがりがりいじるようなところで予想外のことになってい
るのかな...。スタックポインタ、コピーしてアクセスできないんじゃ、いくら
なんでも地獄過ぎだね。


保護モードに移ったテストはVGAにベタ書き込み。リアルモードの内に320x240 16bppに
しておきます。

	movl	$0x80000,%eax
	movl	$32000,	%ecx
1:	movb	$5, (%eax)
	inc	%eax
	loop	1b

ここで0x80000になっているのはセグメントが0x20000オフセットされているの
で、本来のV-RAM 0xa0000になる。もう既に気が狂いそうだ。




長ネギは今のところ順調っぽい。収穫は秋。ジャガイモの植え時期は3月上旬だっ
た。もう過ぎてるし。まだ堆肥をすきこんでもいない。すきこんでから2週間し
てから植えるのに。



フレームを洗ったついでに整備性を上げることにしました。今迄、NFのフレームの 後端の横にとびでているところを切断して、04のシートカウルをつけていたのだけど、これだととても脱着が面倒。なので切段することに。
それだけだとちょっと強度に不安があるので新しくフレームを入れます。

材料は、素材&テスト用の89から切りとりました。これで着脱が楽になるのを確 認しました。

ピッチリはまるようにして、ベベルグリーンで表面削って、シンナーで脱脂。

電極はトリタン1.6φ。これだと電極が溶けて丸まってよくない。そういえばこ の前もそんなことを書いた。すでに2.4φのセリタンが用意してあったのだけど、 忘れていた。
トリタンだと直流用なんだよ。交流で使うとトリウムが析出してよろしくない らしい。
アルミ用に純タングステンが欲しいのだけど、Monotaroにはなかった。探して 買っておこうか。

75Aでタック溶接。

簡単な突き合わせのところから。うまくいかない。手が震えるし。緊張し過ぎだ。

隅肉は超失敗。最後の4ヶ所目でちょっとうまくいった。やっぱり練習入れない と久々にいきなりはつらいな。

汚ない溶接になってしまった。0点。

ちょっとここで冷汗、タイヤとのクリアランスを忘れてた。ダンパーだけにし たリアショックを入れて全屈させてみたところ、なんとかセーフ。でもフェン ダーは切らないとだめだ。
溶接してから強度が元に戻るまで一週間はかかるので、今日やっとかないと BSに間に合わない...。と焦っていた。

切断砥石で後を切断。後で切断にしたのは、もし微妙に歪んで応力がかかって いたら、切断した瞬間に完全に歪んでしまう。それが怖かったのでこの順番に しました。

PANA-TIG WS200。単相200Vなので一般家庭でもそのまま使えるし(今日日は家ま で単相200Vで来ていてアースに対して+-100Vで配線されてます。)、このくらい の溶接までなら40Aのブレーカーでも落ちないです。おすすめ。

マクガイバーはやっぱりいい。このコンピュータ感もたまらない。冷戦時代も 懐しい。「あぁ、上出来だ。」いつもずっと頭の中で言ってたセリフがそのま まだ。



筑波選手権第一戦、すまぐるta-1さんの撮影です。ありがとうございます!

これは予選。

思ったより、元気よく乗れてるじゃない...という感じ。もともとテンションの 低い僕だけど、雨の日はことさらテンションは低い...割りには。

決勝。S字の一個目の水溜りのスプラッシュが凄かった。あの水溜り、いけるのか いけないのかわからない。一度ニュルッと来てドキドキした。ドキドキ程度で 済むのか、ヤバいのか。

ここ、S字の一個目で飛ばし過ぎて1ヘア前でアウトに振れなくてそのままイン 突っこみ。

ラインのせいで微妙なスピードだけど、雨だとここで半クラあてるのも怖い。 でも写真で見ると、余裕であてれそう。









ベストショット!

これ、突っこみ過ぎだね^^。この周、シールド曇ってたんだよ。



この後、どんどん離されてしまいました。

このレイン、F2.0,R3.0にはめてるのだけれど、R3.0だとサイドが使いきれない。 (FはOK)。BSのレイン自体は3.0からOK。でも3.5の方がよさそうな気がする。



レースウィークに入って中断していた、机の塗装を再開。3回まで塗ったところ
だった。ここでオービタルサンダーで#400で割と思いっきり削りました。3回塗
りといえども、壁面塗りなので塗膜厚さが稼げてなくてちょっと厳しい。ここ
からは仕上げ塗りということで刷毛目が出ないようにちょっと薄めて塗装しま
した。これはこれでタレるから難しい。

ちょっと思ったような塗面に仕上がってない。

ML115 G5を4.99.72のGENERICで起動してみました。後半キーボード、マウスで タイムアウトや、エラーが出てるのはXを起動した時のもの。このせいで立ちあ がるのに1分くらいかかる。立ちあがれば普通に使える。ML115のビデオはさす がの僕でも「これは使えない...」と思ったけれど、ML115 G5のビデオなら使え なくないレベル。それでもPower Edge T105より多少滲むかな。(今のデスクトッ プはT105)
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 4.99.72 (GENERIC) #0: Mon Mar 16 19:35:26 JST 2009
	uch@alexandrite:/usr/work/src-4.99.72/sys/arch/i386/compile/GENERIC
total memory = 511 MB
avail memory = 491 MB
timecounter: Timecounters tick every 10.000 msec
timecounter: Timecounter "i8254" frequency 1193182 Hz quality 100
HP ProLiant ML115 G5 (  )
mainbus0 (root)
cpu0 at mainbus0 apid 0: AMD 686-class, 2700MHz, id 0x70ff2
ioapic0 at mainbus0 apid 1: pa 0xfec00000, version 11, 24 pins
acpi0 at mainbus0: Intel ACPICA 20080321
acpi0: X/RSDT: OemId <HP    ,ProLiant,20080526>, AslId <FOXC,00000097>
acpi0: SCI interrupting at int 9
acpi0: fixed-feature power button present
timecounter: Timecounter "ACPI-Fast" frequency 3579545 Hz quality 1000
ACPI-Fast 24-bit timer
pcppi1 at acpi0 (SPKR, PNP0800)
pcppi1: io 0x61
midi0 at pcppi1: PC speaker (CPU-intensive output)
sysbeep0 at pcppi1
npx1 at acpi0 (COPR, PNP0C04)
npx1: io 0xf0-0xff irq 13
npx1: reported by CPUID; using exception 16
UAR1 (PNP0501) at acpi0 not configured
hpet0 at acpi0 (HPET, PNP0103-0)
hpet0: mem 0xfed00000-0xfed00fff irq 0,8
timecounter: Timecounter "hpet0" frequency 25000000 Hz quality 2000
attimer1 at acpi0 (TMR, PNP0100): AT Timer
attimer1: io 0x40-0x43
acpibut0 at acpi0 (PWRB, PNP0C0C-170): ACPI Power Button
MI0 (IPI0001) ACPI Error (nsxfeval-0213): Incorrect return type [Buffer] requested [String] [20080321]
at acpi0 not configured
MI1 (HPI0002) ACPI Error (nsxfeval-0213): Incorrect return type [Buffer] requested [String] [20080321]
at acpi0 not configured
apm0 at acpi0: Power Management spec V1.2
attimer1: attached to pcppi1
pci0 at mainbus0 bus 0: configuration mode 1
pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok
vendor 0x10de product 0x0369 (RAM memory, revision 0xa2) at pci0 dev 0 function 0 not configured
pcib0 at pci0 dev 1 function 0
pcib0: vendor 0x10de product 0x0360 (rev. 0xa3)
nfsmbc0 at pci0 dev 1 function 1: vendor 0x10de product 0x0368 (rev. 0xa3)
nfsmb0 at nfsmbc0 SMBus 1
iic0 at nfsmb0: I2C bus
nfsmb1 at nfsmbc0 SMBus 2
iic1 at nfsmb1: I2C bus
ohci0 at pci0 dev 2 function 0: vendor 0x10de product 0x036c (rev. 0xa1)
LUB0: Picked IRQ 21 with weight 0
ohci0: interrupting at ioapic0 pin 21
ohci0: OHCI version 1.0, legacy support
usb0 at ohci0: USB revision 1.0
ehci0 at pci0 dev 2 function 1: vendor 0x10de product 0x036d (rev. 0xa2)
LUB2: Picked IRQ 22 with weight 0
ehci0: interrupting at ioapic0 pin 22
ehci0: BIOS has given up ownership
ehci0: EHCI version 1.0
ehci0: companion controller, 10 ports each: ohci0
usb1 at ehci0: USB revision 2.0
viaide0 at pci0 dev 5 function 0
viaide0: NVIDIA MCP55 Serial ATA Controller (rev. 0xa3)
viaide0: bus-master DMA support present
viaide0: primary channel wired to native-PCI mode
LSA0: Picked IRQ 23 with weight 0
viaide0: using ioapic0 pin 23 for native-PCI interrupt
atabus0 at viaide0 channel 0
viaide0: secondary channel wired to native-PCI mode
atabus1 at viaide0 channel 1
viaide1 at pci0 dev 5 function 1
viaide1: NVIDIA MCP55 Serial ATA Controller (rev. 0xa3)
viaide1: bus-master DMA support present
viaide1: primary channel wired to native-PCI mode
LSA1: Picked IRQ 21 with weight 1
viaide1: using ioapic0 pin 21 for native-PCI interrupt
atabus2 at viaide1 channel 0
viaide1: secondary channel wired to native-PCI mode
atabus3 at viaide1 channel 1
viaide2 at pci0 dev 5 function 2
viaide2: NVIDIA MCP55 Serial ATA Controller (rev. 0xa3)
viaide2: bus-master DMA support present
viaide2: primary channel wired to native-PCI mode
LSA2: Picked IRQ 22 with weight 1
viaide2: using ioapic0 pin 22 for native-PCI interrupt
atabus4 at viaide2 channel 0
viaide2: secondary channel wired to native-PCI mode
atabus5 at viaide2 channel 1
ppb0 at pci0 dev 6 function 0: vendor 0x10de product 0x0370 (rev. 0xa2)
pci1 at ppb0 bus 1
pci1: no spaces enabled!
ppb1 at pci0 dev 10 function 0: vendor 0x10de product 0x0376 (rev. 0xa3)
pci2 at ppb1 bus 2
pci2: no spaces enabled!
ppb2 at pci0 dev 11 function 0: vendor 0x10de product 0x0374 (rev. 0xa3)
pci3 at ppb2 bus 3
pci3: no spaces enabled!
ppb3 at pci0 dev 12 function 0: vendor 0x10de product 0x0374 (rev. 0xa3)
pci4 at ppb3 bus 4
pci4: no spaces enabled!
ppb4 at pci0 dev 13 function 0: vendor 0x10de product 0x0378 (rev. 0xa3)
pci5 at ppb4 bus 16
pci5: i/o space, memory space enabled, rd/line, wr/inv ok
vga1 at pci5 dev 0 function 0: vendor 0x102b product 0x0522 (rev. 0x02)
wsdisplay0 at vga1 kbdmux 1: console (80x25, vt100 emulation)
wsmux1: connecting to wsdisplay0
drm at vga1 not configured
ppb5 at pci0 dev 14 function 0: vendor 0x10de product 0x0375 (rev. 0xa3)
pci6 at ppb5 bus 17
pci6: memory space enabled, rd/line, wr/inv ok
bge0 at pci6 dev 0 function 0: Broadcom BCM5722 Gigabit Ethernet
LNEC: Picked IRQ 16 with weight 0
bge0: interrupting at ioapic0 pin 16
bge0: ASIC BCM5755 C0 (0xa200), Ethernet address 00:23:7d:61:42:c1
bge0: setting short Tx thresholds
ukphy0 at bge0 phy 1: Generic IEEE 802.3u media interface
ukphy0: OUI 0x000af7, model 0x002d, rev. 0
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto
ppb6 at pci0 dev 15 function 0: vendor 0x10de product 0x0377 (rev. 0xa3)
pci7 at ppb6 bus 18
pci7: no spaces enabled!
pchb0 at pci0 dev 24 function 0
pchb0: vendor 0x1022 product 0x1100 (rev. 0x00)
pchb1 at pci0 dev 24 function 1
pchb1: vendor 0x1022 product 0x1101 (rev. 0x00)
pchb2 at pci0 dev 24 function 2
pchb2: vendor 0x1022 product 0x1102 (rev. 0x00)
amdtemp0 at pci0 dev 24 function 3
amdtemp0: AMD CPU Temperature Sensors (K8: core rev DH-G2)
isa0 at pcib0
com0 at isa0 port 0x3f8-0x3ff irq 4: ns16550a, working fifo
pckbc0 at isa0 port 0x60-0x64
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
uhub0 at usb0: vendor 0x10de OHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 10 ports with 10 removable, self powered
uhub1 at usb1: vendor 0x10de EHCI root hub, class 9/0, rev 2.00/1.00, addr 1
uhub1: 10 ports with 10 removable, self powered
viaide0 port 0: device present, speed: 3.0Gb/s
viaide2 port 0: device present, speed: 1.5Gb/s
wd0 at atabus0 drive 0: <GB0160EAFJE>
wd0: drive supports 16-sector PIO transfers, LBA48 addressing
wd0: 149 GB, 310101 cyl, 16 head, 63 sec, 512 bytes/sect x 312581808 sectors
wd0: 32-bit data port
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd0(viaide0:0:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA)
atapibus0 at atabus4: 2 targets
cd0 at atapibus0 drive 0: <HL-DT-STDVD-ROM GDRH20N, , D8E4> cdrom removable
cd0: 32-bit data port
cd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
cd0(viaide2:0:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA)
Kernelized RAIDframe activated
pad0: outputs: 44100Hz, 16-bit, stereo
audio0 at pad0: half duplex
boot device: bge0
root on bge0
nfs_boot: trying DHCP/BOOTP
uhidev0 at uhub0 port 5 configuration 1 interface 0
uhidev0: ServerEngines SE USB Device, rev 1.10/0.01, addr 2, iclass 3/1
ukbd0 at uhidev0
wskbd1 at ukbd0 mux 1
wskbd1: connecting to wsdisplay0
uhidev1 at uhub0 port 5 configuration 1 interface 1
uhidev1: ServerEngines SE USB Device, rev 1.10/0.01, addr 2, iclass 3/1
ums0 at uhidev1: 8 buttons and Z dir.
wsmouse1 at ums0 mux 0
uhub2 at uhub0 port 8: Chicony Generic USB Hub, class 9/0, rev 1.10/1.00, addr 3
uhub2: 3 ports with 2 removable, bus powered
nfs_boot: DHCP next-server: 192.168.33.2
nfs_boot: my_name=sicklemoon
nfs_boot: my_domain=s.vnop.net
nfs_boot: my_addr=192.168.33.25
nfs_boot: my_mask=255.255.255.0
nfs_boot: gateway=192.168.33.1
uhidev2 at uhub2 port 1 configuration 1 interface 0
uhidev2: Chicony PFU-65 USB Keyboard, rev 1.10/1.00, addr 4, iclass 3/1
ukbd1 at uhidev2
wskbd2 at ukbd1 mux 1
wskbd2: connecting to wsdisplay0
root on 192.168.33.2:/usr/work/nfsroot/i386
root file system type: nfs
wsdisplay0: screen 1 added (80x25, vt100 emulation)
wsdisplay0: screen 2 added (80x25, vt100 emulation)
wsdisplay0: screen 3 added (80x25, vt100 emulation)
wsdisplay0: screen 4 added (80x25, vt100 emulation)
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pms_enable: command error 35
pckbport: command timeout
pckbport: command timeout
pms_disable: command error
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pms_enable: command error 35
pckbport: command timeout
pms_disable: command error
pckbport: command timeout
pms_enable: command error 35
pckbport: command timeout
pms_disable: command error
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pckbport: command timeout
pms_enable: command error 35
x86続き。
セグメントの領域を設定するデスクリプタを生成するプログラム。

#include <sys/types.h>
#include <stdio.h>
#include <string.h>

typedef int8_t bool;

// Access byte (Lower attribute filed) defines.
#define	PRESENT			0x80

// DPL
#define	DPL_MASK		0x60

// S (Descriptor Type) bit
#define	SEGMENT_SYSTEM		0x00
#define	SEGMENT_APPLICATION	0x10

// Code/Text Segment.
#define	APP_CODE		0x08
#define	APP_DATA		0x00
/*
  Data:
  E Lower extension. (Stack)
  W Writable
  A Access
  Code:
  C Conforming (omit privileged level check.)
  R Readable
  A Access
*/
#define	DATA_R			0x00
#define	DATA_RW			0x02
#define	DATA_R_STACK		0x04
#define	DATA_RW_STACK		0x06

// C ... Conforming. omit privileged level check
#define	CODE_X			0x00
#define	CODE_RX			0x02
#define	CODE_XC			0x04
#define	CODE_RXC		0x06

#define	CODE_SEGMENT	(PRESENT | SEGMENT_APPLICATION | APP_CODE | CODE_RX)
#define	DATA_SEGMENT	(PRESENT | SEGMENT_APPLICATION | APP_DATA | DATA_RW)
#define	STACK_SEGMENT	(PRESENT | SEGMENT_APPLICATION | APP_DATA | DATA_RW_STACK)

// Upper Attribute field.
// Granularity bit
#define	SIZE_UNIT_4KB		0x80
#define	SIZE_UNIT_1B		0x00
// Default bit. application descriptor only.
#define	CODE_32			0x40
#define	CODE_16			0x00

// Type filed for System Segment.
#define	SYS_LDT			0x02
#define	SYS_TASKGATE		0x05
#define	SYS_TSS_AVAILABLE	0x09
#define	SYS_TSS_BUSY		0x0b

#define	SYS_TRAPGATE		0x0f
#define	SYS_INTRGATE		0x0e
#define	SYS_CALLGATE		0x0c

struct application_descriptor // including system descriptor
{
  uint16_t size_0_15;
  uint16_t base_0_15;
  uint8_t base_16_23;
  uint8_t access_byte;
  uint8_t size_16_19_GD;
  uint8_t base_24_31;
} __attribute ((packed));

/*
  System descriptor type filed.
  2 ... LDT
  5 ... Task gate
  9 ... 386TSS available
  b ... 386TSS busy.
  c ... 386call gate
  e ... 386intr gate
  f ... 386trap gate
 */

struct gate_descriptor // call gate, interrupt gate, trap gate.
{
  uint16_t offset_0_15;
  uint16_t selector;
  uint8_t parameter_0_4;// dword count.
  uint8_t access_byte;
  /*
    System:
    P DPL 0 1 1 1 1 trap gate
    P DPL 0 1 1 1 0 interrupt gate
    P DPL 0 1 1 0 0 call gate
    Application:
    P DPL 1 0 . . . data/stack
    P DPL 1 1 . . . code
   */
  uint16_t offset_16_31;
} __attribute ((packed));

struct gdt_config
{
  uint32_t base;
  uint32_t size;
  uint8_t unit;
  uint8_t mode;
  uint8_t type;
} gdt_config [] = {
  { 0x0,	0x200,	SIZE_UNIT_4KB, CODE_32, CODE_SEGMENT },
  { 0x0,	0x200,	SIZE_UNIT_4KB, CODE_32, DATA_SEGMENT },
  { 0x200000,	0x1,	SIZE_UNIT_4KB, CODE_32, STACK_SEGMENT },
};

struct lgdt_arg
{
  uint16_t limit;
  uint32_t base;
} __attribute ((packed));

main ()
{
  union
  {
    struct application_descriptor desc;
    struct gate_descriptor gate;
    uint16_t u[4];
  } descriptor;
  struct gdt_config *conf = gdt_config;
  struct application_descriptor *d = &descriptor.desc;
  int32_t limit;
  int i, j;

  printf ("\t.arch i486\n");

  // GDT
  printf ("\t.section .data\n\t.balign 4\n");
  printf ("\t.global _gdt\n_gdt:\n");

  // Null Descriptor #0
  for (j = 0; j < 4; j++)
    printf ("\t.short 0x0000\n");

  // Application Descriptor. (code, data, stack)
  for (i = 0; i < sizeof gdt_config / sizeof (gdt_config[0]); i++, conf++)
    {
      memset (d, 0, sizeof *d);
      d->access_byte = conf->type;
      d->base_0_15 = conf->base & 0xffff;
      d->base_16_23 = (conf->base >> 16) & 0xff;
      d->base_24_31 = (conf->base >> 24) & 0xff;
      limit = conf->size;
      if (conf->type == STACK_SEGMENT)
	{
	  limit = -limit;
	}
      limit--;

      d->size_0_15 = limit & 0xffff;
      d->size_16_19_GD = ((limit >> 16) & 0xf) | conf->unit | conf->mode;
      for (j = 0; j < 4; j++)
	printf ("\t.short 0x%04x\n", descriptor.u[j]);
    }

  return 0;
}

これを
	lgdt	lgdt_arg
	movl	%cr0,	%eax
	orl	$0x1,	%eax
	movl	%eax,	%cr0
	ljmp	$0x8,	$flush	// Load CS(0x08) with pipeline flush.
flush:	.code32
	// Load DS(0x10),ES,FS,GS
	movw	$0x10,	%ax
	movw	%ax,	%ds
	movw	%ax,	%es
	movw	%ax,	%fs
	movw	%ax,	%gs
	// Load SS
	movw	$0x18,	%ax
	movw	%ax,	%ss

	call	c_main
infinite_loop:
	jmp	infinite_loop

で保護モードに移行。これでCでプログラムが書けるようになる。(A20はまだだけど)

LMSW, SMSW (load/store machine status word)命令は286との互換性のために
残してある。IA-32では使ってはいけない。MOV命令を使ってCR0にアクセスする
こと。

リアルモードのうちに

	movb	$0x00,	%ah
	movb	$0x13,	%al	// 320x240 8bit color VRAM 0xa0000 - 0xafa00
	int	$0x10

のBIOSコールでグラフィックモードにしておいて、

void
c_main ()
{
  uint8_t f[] = {
/* code 52 (R) */    0x7e,0x41,0x41,0x7e,0x44,0x42,0x41,0x00,
  };
  uint8_t (*p)[320] = (void *)0xa0000;
  int x, y;

  for (y = 0; y < 8; y++)
    {
      for (x = 0; x < 8; x++)
	{
	  p[y][x] = (f[y] & (1 << (7-x))) ? 7 : 6;
/* 0 black, 1 blue, 2 green, 3 cyan, 4 red, 5 magenta, 6 orange, 7 white, 8 grey, 9 skyblue */
	}
    }
}

qemu  -serial stdio -std-vga -hda boot1

これで画面に"R"(BGオレンジ、FG白)の文字が書かれる。
ここでついにブートセクタの510byteを使いきってしまった。これからはどこか らかロードしないといけない。歴史的に、パーティションはシリンダ境界から とることになっている。なので最初のシリンダは先頭のブートセクタ以降は使 われていない。ちょっと大きなブートローダーはこの領域を使っている。
今日日、設定としてのセクタ/トラックは大抵63なのであと31KB(512byte/ セク タ)はブートローダとしてに使えそうな場所。
わかってはいたことだけど、お膳立てが長い...。



雨走行の後の洗い物、干し物にはいい天気です。あぁ。こんな天気の日にレー
スがしたかった...。



グリスアップもしないといけないし、ついでに思いっきり掃除。フレームもお そうじマイルックでジャブジャブ洗い。

スイングアームのニードルローラーはガソリンに漬けて歯ブラシでごしごし洗い。

大体洗い物は済みました。ステアリングダンパーがかなりエア噛みしていた。 これもそろそろ交換か、あるいはもうダンパーなしか。ダンパーなしってどう しても怖い。大丈夫そうだとは思ってはいるのだけど。
SP250時代に(20年前だ)ストレートでチャッタって喉から心臓が飛びだしそうな 思いをして以来どうもないと不安で。

テストベッド用にNTT-XでML115 G5買ったのが届きました。11750円。安いねー。



筑波選手権第一戦です。

暴風雨という天気予報だったので、交通規制で下道に降ろされてしまうとか、事故渋滞も考えて1時間早目に出発。道端にいろんなものが転がっていてかなりの暴風だったようだ。幸い何も問題なく、5:40に到着。6:30まで仮眠。
起きてみても雨は降っている。風が不安なので、タープも出さずに、バイクカ バーで。幸い気温が高い。車検前は14℃もあった。

予選。 ずっと雨。ファイナルの16:37はフルウェットにはちょいロングだったか も。CXの切り返しでイン側のゼブラに乗ってみるのを試してみた。結構段差が あって、ボコンっとなる。最初乗るのはかなり緊張したけれど、乗ってみると 乗れないこともない。もうちょっとゼブラがフラットならいいんだけど...。
2ヘアのクリップで二回ほどドリフト。結構コントローラブルなのね...。タイ ヤの性能に驚いた。といっても怖いので翌周はビビりです。
僕は雨の時は、かなり上体を下げて路面に近いとこまで持っていった方が リラックスして走れるみたい。昔のミニバイク乗りみたいな感じで。
9:15 152m 12.2℃ 78.1% 993.1hPa 雨、フルウェット。
6枚 55℃
2.0/2.0
F10巻き
16:37(ちょいロング)
best 16.2


予選は12位でした。

決勝。雨の中じゃ面倒くさ過ぎるのでウォーマーはなし。スタート前チェック を受けてマシンを並べた所で不具合に気付いた。サイレンサーステーのナット が落ちてる。このままでも別に問題はないけれど...(ボルトがステーにナット で固定されてるので、ステーにははまってる。)。やっぱり!と、駐車場まで走っ て戻ってM6ナットとスパナを持ってきた。全身汗だく。激疲れ。幸い、 TC250/TC400の表彰式が長かったので体力回復できました。
ブリーフィングの宇井アドバイザーのアドバイスに従って、ウォーミングアッ プラップで加速減速でタイヤを潰すというのをやってみたのだけど、どのくら いでやったらいいのか...うまくできなかった。とりあえずコーナー後の急加速 とコーナー前の急減速だけ思いきりやってみた。
スタートは失敗。でも雨でみんなビビってるのか、一ヘアまでに妥当なところ に納まった。3周目くらいまで周りに人がいてテンション上がってウェットながらも楽しく。
4周目くらいに後を振り返った時にうっかりシールドをぴっちり閉めてしまって、 (僕は古い人なので、振り返る時にはシールドを手で押さえる。80年代のシール ドは振り返った時の風圧でバカッと開いてしまったり最悪シールドが吹き飛ば されてしまうのだ) シールドが曇って焦る。焦ってハーハーしてさらに曇ってしまう。そんなこんな してるうちに、さっきまでちょっとアドバンテージを築いていた野澤選手に 2ヘアで刺される。よしこれからついていこうと頑張るも、みるみる離されて 見えなくなってしまう。後を振りかえると、結構アドバンテージがある。 (後番手で後を振り返るのってちょっとどきどきするんだよ。もしかすると 本当に誰もいないかもしれないから。)
ここでテンションが落ちてしまった。後半8周、毎周ごとにペースが落ちて いってしまいました。興奮剤をドーピングする気持ちがよくわかるよ。
今日の走りは。1コーナーは75m。立ちあがりがロングで困る。1ヘアは雰囲気。 ダンロップ進入はドライのちょい甘くらいで突っこめたけど、CX立ちあがりが スピード乗らない。2ヘアは緑に入ったとこ。最終は50mでちょいブレーキで進 入でした。次ウェットだったら15:35かな。
10位でした。

ポンダー返して、決勝結果もらおうとしたら、まだ正式が出てなかったので、 しばらくGP-MONOを観戦。レース見るの久々。

雨足は止んで筑波山が見えるくらいに。僕のレースが終われば雨も止むだろう。

自分のレースだと、コースインしてスタートするまでってあっという間なんだ けど、観戦すると随分とのんびりだね。

スタート!

見始めると心魅かれて色々場所移動しながら最後まで見た。

あまり見てると首都高の渋滞に巻きこまれてしまうので、帰宅。
小菅Jct.からC2に入ってすぐくらい。

板橋Jct.

ホームジョイ本田石下店のレジの脇にジャガイモの種イモが売ってたので 買ってきました。今年の菜園の第一弾はこれで。

クランクx1,シリンダーx2,ピストンx2,ヘッドx2潰して臨んだ一戦は雨。てんこ もりに、レースできました。満腹です^^。



05ヘッドをベースにします。単体で測ると9.7cc。04は10.0ccだったから、ちょっ
と圧縮比アップしてる。

ベース0.8mm、Oリング仕様で、組み込みの容量を測ると8.2cc。その通りだ。単 体9.5ccで8.0ccになる。面研しても0.1mm(0.18cc)だ。なので、このままで。時 間ないし。

スキッシュは1.3mm。ちょっと拡いな。前に潰したベストヘッドが0.9mm、水曜 潰したのが0.6-0.8mm。RS125(NF)は0.65mmだったはず(うろ覚え)。

いいマイクロメータでしょ^^。

シリンダは2/28に壊したやつにしました。この前壊したのに較べれば多少いい し、実際、走った感じも充分に使える感じだったし。一応、暖機して一回だけ 上までまわしてみて確認。 さてここから渋々雨仕様に。ファイナルは16:37で。最近はドライは15:34です。
最近、常に裏目に出るから、むしろ完全な雨仕様で臨むのが裏目に出たらいい なぁ...などとこの時は考えていた。

なんか朝は暴風雨っぽい。筑波に行くのすら大変そうだよ。意外に前線の動き が超速で、起きてみたらピーカン!...なんてことないかな。




さっそくバラしです。B/Oのクランクが届いてればいいなとホンダに行ってみる
もまだだった。残念。



クランクを取り出して、じっくり観察してみると...ローラーは全てあるけれど、 リテーナーが3つ落ちてた! 昨日の二本目はこれで走ってたのか。
この写真では左側のローラーの左にはリテーナがついているけれど、右は抜け 落ちてしまっている。ピストンとヘッドの傷の形からも納得がいく。
このクランクは去年の8月に交換したばっかりなのに。

旧クランクに交換。080817まで使っていたやつだ。ちょっと振れが大きくてギ ヤ側が0.3mm(測定値そのまま)、ローター側が0.2mm(測定値そのまま)。クラン クの芯出しに挑戦してる暇はないので、このまま組み込み。

ギヤ、シフト廻りは問題なし。ちょっとクランクとベアリングの嵌め合いがゆ るい。ここでギヤを1速から6速まで確認。一度間違えて組んでE/Gかけた瞬間ギ ヤ割ったことあるからね...。

組んだところで、混合ガスを入れて気密を確認。これも昔、ガスケットがずれ て組んでしまって、E/Gかけたら白煙もうもう(ギヤオイルがケース室に漏れ出 て)で組み直しになったよ。ケースの廻りは長目のボルトを軽く入れておいてず れないようにして合わせるといいみたい。

後は通常整備のとこまで。しかしヘッドを新しく作らないといけないので、明 日の特走はパス。気合いでなんとかならなくもないけれど、レースを前に燃え 尽きそうだ。

昨日は風が強かったから、砂も大量。チェーンの替え頃(一年交換)なので、 D'sで買おうと思ったら在庫切れだった...。



今日も筑波にマシン壊しに行ってきましたよ^^。

とにかく風強い。気温は6℃ないし延々とビュービュー吹くわで極寒。一本目の 8:30は6℃。新品ローターなので、表面のメッキ剥きに3周ほどナラシ。その後 全開走行するもどうにも風がきつく(バックストレッチはずっと向い風)、10秒 も切れなかった。
それと、この走行ではじめてRX-7RRのロスマンズスペンサーを被ってみたのだ けど、なんか視点が合わない。寒さのせいかとも思ったけれど、あまりにも気 持ちが悪いので、ピットインして1ヘア裏までかけっていってトリコロールスペ ンサーに変更した。やっぱりこっちの方が頭にしっくりくる。それとラパイド の方が口の前に隙間が多くていいな。僕は無意識に口開けて走っているので、 RX-7RRだと唇がヘルメットのベロにあたる。
走行終了して、なんか後半廻りが重い気がしたので、トランポまで戻ってきた ところで、レーシングしてみる。普通に14000rpmまで廻るけれど、気持ち吹け が重い気もしなくもないけど...と思っていた。
しばらくボケーっとして、プラグ穴からLEDライトを入れて焼けの様子を見てみたら....!!!!。傷がある...。向い風が強くなったのかなと思ってたけれど、E/Gだったのか。
ちょっと心が折れそうになったけれど、後1時間あるので組み直すことに。寒風 に吹かれながら、かじかむ手でなのでなかなか進まない。準備完了とともに 10:30の走行開始。暖機してないのでしばらくピットロードで暖機するも全然温 度上がらないし。やっとのことでコースイン。9000一周、10000二周、12000一 周でピストンのナラシ終わり。ピットインして、タンク外してレーシングして 点検して、走りだそうというとこで赤旗。
その後は思いっきり走るも、やはり寒いし、風がきつい。厳しかったのがブレー キングでちょっと意識が朦朧とする(特に1コーナー)。景色は見えるのだけど、 焦点が合わない。寒くて血行が悪くなってたからかも。9.2がやっと。
食堂に入ると、手の先じわーっと暖まって血が流れるのを感じるよう。食べ物を 口に入れると歯茎の芯まで冷えきっていて歯が浮くようだ。とにかく寒かった。


帰り、クレーン車がひっくり返ってました。

これは二本目の新品ピストン。シリンダは一本目で爪で段を感じる傷が入ってしまったので、旧旧シリンダで。

せっかく排気ポート削ったのに。旧シリンダも、お釈迦だ。

見ると掃気ポートの端に噛んだ後がある。





サイドが溶けてるのは、深く傷が入って、そこに熱がこもって溶けたのではな いかと想像。異物はかなり鋭利な形のものっぽい。

何を噛みこんだんだ。風が強かったから舞いあがったなにかを吸ってしまった のか、それともクランク大端部のローラーが割れたのか(しかし、その状態でそ の後全開走行できるのだろうか。二本目はきっちり走りきったし)。一戦は予備 E/Gで行く準備で、このE/Gは一度バラそう。
お払いに行こうかな。マジで。



先週、もつ定を食べに筑波に行った日のせいでハイエースが泥んこ。水洗いだ
けしました。ボンネットに汚れが沈着してしまっているのが前から気になって
いた。パーツクリーナーでも落ちないのでプラスチックコンパウンドで削り落
とした。イヤらしいくらいテカテカに。



x86もなんとか保護モードにまで入りました。x86はとにかくセグメントだ。保 護モードに入る前に少なくともメモリセグメントの設定をロードしないといけ ない。286の設定を引き継ぎ、そして割り込み、例外、トラップ、タスクもセグ メントとして扱えるようになっているのでその設定は混迷を極める。このあた りはインテルの初期のツールチェーンでは設定をビルドファイルに記述して、 「BLD オブジェクト BF(ビルドファイル)」というようにして、複雑さを包み込ん でいたようだ。
気をつけるのは、セグメントにはサイズじゃなくリミットを設定すること。 そうしないと4G設定できないしね。
スタックの時の設定はコード、データと違う。
下方伸張型セグメント(スタック)ではリミットは、設定の仕方が異なる。

上方伸張型: リミット+1 以上は違反
下方伸張型: リミット+1 以上(0xffffffffまで)が合法
となるので、
リミットはサイズをマイナスにして、さらに1を引いたものになる。

ESP <=>

プロテクトモードには
	lgdt	lgdt_arg
	movl	%cr0,	%eax
	orl	$0x1,	%eax
	movl	%eax,	%cr0
	ljmp	$0x8,	$flush	// Load CS(0x08) with pipeline flush.
flush:	.code32
	// Load DS(0x10),ES,FS,GS
	movw	$0x10,	%ax
	movw	%ax,	%ds
	movw	%ax,	%es
	movw	%ax,	%fs
	movw	%ax,	%gs
	// Load SS
	movw	$0x18,	%ax
	movw	%ax,	%ss
この入り方しかない。movl %eax, %cr0で、セグメントユニットのアドレス変換 機能が変わるので、パイプラインがある場合、それに入っているのをフラッシュ するのはいいとして、ljmpをどうフェッチするかだ。セグメント変換機能は変 更されたけれど、CSはまだ保護モード用に変更されてないし、既にリアルモー ドじゃない。
これはリアルモードで動いてるうちはプロセッサが自動的に保護モードのセグ メントデスクリプタをそれに矛盾のないように更新しているから大丈夫らしい。 このljmpの後が、gdtで設定したCS。このサンプルコードは、保護モードのCSを 設定(リアルモードのオフセット==保護モードのオフセット)してある。



ツナギのメンテ。皮革用石鹸で白いところだけ汚れをとって、オイルを塗りま
した。買ってもう1年4ヶ月。セクレは動きやすくてとてもいいです。

自分で染めQで入れたチェッカー模様の部分の色落ちが心配だったけれど、問題 なかった。



CRの整備を続けました。オイル交換。大体規定量(600cc)でてきました。



前回の走行から使ってるのは、去年作った新作。作ったはいいけど、あまり使 わなかった。ちょっとスキッシュの角度が浅過ぎたのがちょっと怖い。このヘッ ドは天頂部が平たいのが特徴。ノーマルと同じくらいはパワーでる感じ。(これ はそこそこ成功したということなんだよ。)無難にはノーマルへッドのまま面研 して、シリンダ、ピストン組み込んだ状態でプラグ穴上面すりきりで、8.0ccに するのがいい。

前回のシリンダ、付着アルミを落としてみてもやはりシリンダ自体がエグれて る。去年の岡山とMCFAJの二戦しか使ってないのにTT。ショック過ぎる。
仕方ないので、旧シリンダに。これは全体的に摩耗してるんだけれど...。
排気ポートを、今の仕様に削りました。削るというより全体的にザラザラが消 えるところまで一枚剥ぐ感じ。メッキ部分の端がちょっと盛りあがってるとこ ろは砥石で削りこんでポート面と面一に。あまりビビらなくてもメッキが剥が れることはないです。ポートの端はゴム砥石で滑らかに。
僕はベースガスケットで0.3mmポートタイミングを上げているので、ポート下面を 気持ち多めに削りました。
去年はノーマルのベースガスケットとの組み合わせを序盤試したのだけど、やっ ぱり僕はこっちの方が好き。

排気ポートも下手に形変えるとすぐパワー落ちる感じ。

ダイレクトポートはこの程度。もっとやってもいいのかな...。あんまり削って シリンダ割れるのも怖いし。

傷が多くて嫌だな...。

超硬の土筆でおおまかに削って、ピンクの砥石で整えて、緑の砥石とサンドペー パー頭で仕上げ。最後は#400のペーパーで手磨き。

ゼッケンも貼り替えて09仕様。






絶好のチェーン洗い日和。ついでに洗浄台もきっちり掃除。ヘドロが沈殿して
いた。



天気も良かったのでplusμまで自転車で。90のインナーに新品のローター (35000円)と、ピン(6000円)で組んでもらいました。おととい注文に行って、工 場に発注したのだけど、5mm厚(元々のは4.5mm厚)でスリットのなら在庫があっ た電話があったので、これに。
「随分古い、うちのですね〜」と^^ そう、考えてみれば19年物だ。
去年の後半から、ステン派から鋳鉄派になってしまったので、ドライ用のホイ ル2セットとも鋳鉄じゃないと。ローターの交換は出来る限りしたくない。

これは、この前の二本目に入れた新品ピストン。クリップの手前の二本傷は シリンダーの傷を受けてる。

ちょいカジり。np





ここ、ピストンの溶け落ちが一番激しかったところが、ダメージを与えてしまっ た。上のピストンの傷跡からすると、アルミが乗っただけかも。ピストンが押されてる感じだし。
これなら前のシリンダの方がまだいいような気もしたり、悩み中。実は新品も今日買ってきた。37600円。高くなった。クランクはB/Oだった。

ホイールは、おそうじマイペットで洗ってみたら、これがよく落ちる。あなどっ ていた。マジックリンだとアルカリ強すぎて塗装物は塗装が溶けてしまうので。
今となってはスリットの方が新鮮で、かっこいいかも。イカついし。

ブレーキもマイペットで洗ってみた。これもいい。ピストンちょっとだしてシ リコングリスを筆でちょっと塗ってふきとって終了。ピンが摩耗してたので注 文しておかないと。




昨日は新宿に本を買いに行ったついでにDISK UNIONに。IMPELLITTERI御大の新
作と、90年のリマスター盤を。ボーカルがRob Rockに戻った。一曲目いきなり
のシャウトがいい! 雰囲気も僕の一番好きな"Victim Of The System"っぽい。
もちろん御大のことだから弾きまくりなのだけど、もっとはっちゃけてくれて
もいいかな...。筑波選手権の表彰式で最初の部分だけちょこっとかかるのは御
大の"STAND IN LINE"の中の"Somewhere Over The Rainbow"。これ、好きなんだ
よね。

やはり新宿に降り立つとその後は呑みに。来週レースなのでほどほどに。 菊姫の先一杯がうまかった。
これは3回目のニス塗り。#400でペーパーかけて、エアブローして、脱脂剤(プ レソルベント)で、削りくずをきっちり落としてから塗ります。透明感ある仕上 りを目指したい。
3回目でやっと目止めが終わった感じかな。

x86続き。ちょっと書きはじめた。どうもx86に対する苦手意識が強くて手が動かない。 まずはhello worldから。BIOSルーチンを使って"ohayo"と画面に表示するプログラム。 QEMUは楽でいいね。
----------------------------------------------------------------------
	.arch i8086
	.section .text
	.code16
	.balign 4
	cld			/* increment.*/
	movw	$_test_data, %si
loop:
	lodsb
	cmp	$0,	%al
	jz	end
	movb	$0x0e,	%ah
	movb	$0x00,	%bh
	movb	$0x07,	%bl
	int	$0x10
	jmp	loop
end:
	jmp	end

	.balign 4
	.section .data
	.global _test_data
_test_data:
	.string "ohayo"
----------------------------------------------------------------------

----------------------------------------------------------------------
OUTPUT_FORMAT ("binary")

MEMORY
{
	mbr_vma		: o = 0x7c00,	l = 0x1fe
	mbr_lma		: o = 0,	l = 0x1fe
	signature	: o = 0x1fe,	l = 2
}

SECTIONS
{
	_stack_start = 0xfff0;

	 .text :
	 {
	 	 *(.text)
		 *(.rodata)
		 . = ALIGN (4);
	 } > mbr_vma AT > mbr_lma

	 .data :
	 {
		 *(.data)
		 . = ALIGN (4);
	 } > mbr_vma AT > mbr_lma

	 .bss :
	 {
		 *(.bss)
	 } > mbr_vma AT > mbr_lma

	 .signature :
	 {
		SHORT (0xaa55)
	 }  > signature
}
----------------------------------------------------------------------

----------------------------------------------------------------------
AS	= gcc
LD	= ld
OBJCOPY	= objcopy
OBJDUMP	= objdump

OBJS	= simple_test.o
PROG	= boot1

.S.o:
	${AS} ${INCLUDES} ${ASFLAGS} ${DEPEND_UPDATE} -c -o $@ $<

all:	${PROG} check

${PROG}:	${OBJS}
	${LD} -T mbr.ldscript -o $@  ${OBJS}

clean:
	-rm -f ${OBJS} ${PROG}

check:
	${OBJDUMP} -b binary -m i8086 -D ${PROG}

test:
#	qemu -fda ${PROG}
#	qemu -nographic -serial stdio -hda ${PROG}
	qemu  -serial stdio -hda ${PROG}
# C-a x : exit QEMU
----------------------------------------------------------------------



気合いで掃除して塗装開始。壁からなにから粉塵にまみれていて、防塵マスク
して送風ファンで換気しながら部屋中エアブローしました。サイクロンは空気
漏れが激しくなってきてガラクタと化しています。これも作り直したいな。次
作るなら45lのゴミバケツで受けるようにしたい。20lじゃすぐ満杯になってし
まう。

マキタのトリマ3707Fが届きました。ベースプレートのピッチが違うので今迄作っ たプレートがそのまま使えないのが残念。

A20について。

PC/ATではキーボードコントローラの8042の出力ポートでサポートした。(出力
ポート2) 8042は8048系の1チップ8bitマイクロコントローラ。レジスタはアキュ
ムレータとフラグのみで、メモリの一部分が8本のレジスタになっている。それ
が2セットでレジスタバンクになっていて、スタックは8段のハードウェアスタッ
ク。使わないときはRAMとして使えるようになっている。メモリも2バンクに分
かれている。Port1(8bit)とPort2(8bit)と入力専用のTEST0,TEST1がある。
TEST0: Keyboard Clock (IN)
TEST1: Mouse Clock (IN)
入力ポート(Port1)が使われているのはキーボードとマウスのデータの二つだけ。
出力ポートはPort2

このI/Oでキーボードとシリアル通信をする。キーボード側にも8048系のチップ
が乗っている。余りの入力ポートを、かつてはボード上のジャンパの設定を読
むのに使っていたりしたようだ。

PS/2では新しく0x92に"PS/2 System Control Port A"を作り、そこで設定でき
るようにした。

なのでPC/ATの場合0x92は必須なポートではない。
OADG(http://www.oadg.or.jp/)のリファレンスではPS/2との互換を保つ時のみ
必要としている。

最近のBIOSではINT 15H,AH=24Hで設定できるものがある。調べたところ、2000
年のPhoenix BIOS 4.0のユーザマニュアルには記載がなかった。AMIはマニュア
ルを探せず。General Software Inc.のEmbeded BIOS 4.1のマニュアルに記載が
あった。

AH: 24h, indicating query port 92h A20 gate capability function.
[Input]
AL: subfunctions
    01h: enable A20 gate
    02h: disable A20 gate
    03h: determine if port 92h support is available.
[Output]
CY set if failure (no port 92h support), else clear if success.
(CY ... carry flag set)
AH if failure, 86h
BX if subfunction 03h, regurns the value 2, indecating support available.


8042の場合
入力ポートの設定は
PC/AT
7 Keyboard Inhibit switch
6 Display switch
5 Manufacturing Jumper
4 RAM on the System Board
3-0 reserved.
PS/2
7-2 reserved
1 Mouse data in
0 Keyboard data in
???どっち???

出力ポートの設定は
7 Keyboard Data Out
6 Keyboard Clock Out
5 Input Buffer Empty / IRQ12
4 IRQ1
3 Auxiliary Clock Out
2 Auxiliary Data Out
1 Gate A20
0 Reset Microprocessor.

ポートはR/W。コントローラコマンド->0x64
0xd0 出力ポート読み出し。出力バッファーが空の時、出力ポートの状態を0x60に置く。
0xd1 出力ポート書き込み。次に0x60に書き込まれるのデータが出力ポートに設定される。

0x64でコマンドを設定しデータを0x60で送受信する。
0x64の読み出しはコントローラステータス。

実際の実装はどうなっているのか
Winbond Super I/O 83977では0xd1のコマンドはA20の出力ポート(bit 1)にしか
影響を与えない。
このチップ独自のレジスタでPS/2の0x92を有効/無効にできる(P92EN)。これは
BIOS用か。




机の引出しの取手の本番。昨日試作してみたところ、ちょっと面倒でも先にほとんどくり抜いておいた方がよさそうなので、まずは糸ノコで。




治具をセット。治具のセット面が張り合わせの裏面になるので、ビス止め。こ こまでやっておくと治具ズレがないので安心。

表面から面取りカッターで。前段階のムシれが気になる...。

また裏面にもうひとつの治具をつけ直して丸面カッターで。

いい感じ!

割り楔通しホゾの仕上。アサリのない鋸を持ってないので、ポリプロピレン板 でガードを作って。

トリマで表面慣らし。この後アクリル板狭んだオービタルサンダーで。

あまりきれいに仕上らなかった。もともとのホゾ穴のバリがやはりそのまま出てしまう。割楔による圧縮効果でぴしっとなるかな..と期待してたのだけど。

クランプが適切でなく、押しつぶしてしまったり、うっかりぶつけて潰してし まった所を、スチームアイロンで補修してみました。これは初めての試み。 最初、こうだったのが、

ここまで復活。ちょこっとぶつけた程度のなら、ちょっとアイロンあてるだけ でどこだかわからなくなるくらいまで元に戻る。これはびっくりだ。
表面をサンディングして、エアブローして粉塵を払って、濡れ雑巾で拭いて塗 装の準備完了です。

PC/ATについて。遺構の確認。
----------------------------------------
IBM PC
CPU: 8088
Bus: XTバス (8bit ISA)
----------------------------------------
メモリマップ。

-------------------- 0xfffff
64KB Boot ROM        
-------------------- 0xf0000
		     0xeffff
64KB Option ROM	     
-------------------- 0xe0000
                     0xdffff
128KB Reserved
Device ROM
                     
-------------------- 0xc0000
                     0xbffff
128KB 
Video Memory
                     
-------------------- 0xa0000
                     0x9ffff


640KB Conventional Memory


-------------------- 0x00000

Option ROMはボードの空きソケットに差して追加デバイス用のBIOSを提供する
ものだった。このメモリマップは以降変わらない。PC/XTはIBM PCの一種。


----------------------------------------
IBM PC/AT
CPU: 80286
Bus: ISA
----------------------------------------

ISAバスの割り込み。
3 COM2
4 COM1
5 LPT2
6 FDC
7 LPT1
9 (2)
10
11
12 Mouse
14 Hard disk
15

ISAバスでない(結線がない)割り込み
0 System Timer
1 Keyboard
2 Cascade interrupt from slave PIC
8 RTC
13 FPU

ISAバスの割り込みでマウスになっているけれど、IRQ12が内部のマウス割り込
みとORになっているので、ISAバスからもそのIRQを使えるという意味。マウス
自体はキーボードと同じ8042が受けもつ。




机の引き出しの取手部分を切削する治具を作りました。簡単なものなのに試作
の切削で失敗を繰り返してしまった。うっかりして治具まで削ってしまって作
り直したり。


ちょっと切り込み深くし過ぎたと思ったらモーター火吹いた。そろそろ代替機 を用意しておいてもいいかなとマキタの3707F を道具道楽 で注文。トリマ作業は 仕上面の綺麗さが欲しい作業だ。となると、できるだけ高回転がいいと思うの で35000rpmの3707F(電子制御の3707FCだと26000rpm)。重量も1.2kgと軽い。

x86リセットから。
アドレス0xfffffff0から命令を実行する。
最初のセグメント間ジャンプあるいはCALL命令が実行されるとアドレスライン
A20-A31はCD相対メモリサイクルではLOWにドライブされ、物理メモリの下位の
1Mバイトの命令だけを実行する。これによってシステムを初期化するために物
理メモリの一番上位のROMを使用できる。


セグメント間を移行しなければハードウェアサポートで、上位空間での実行に
なる。セグメント間移行をするとCSは0xf000に、EIPは0xfff0に初期化されてい
るので、リアルモードとなる。

セグメント間移行をするまでに保護モードまでのお膳立てをすれば(上位64KB
の中で)保護モードから出発もできる設計
ここからはPC/ATについて。
ターゲットのストレージの最初の1セクタ(512byte)の510byteからが0xaa55なら
ブートセクタとして0x7c00にロードする。
7c00はCS:IP=(0:0x7c00)と(0x7c0:0)の2パターンがあるのでljmpして
CS:IPを想定した位置に再設定すると確実。
JMP addr
 EA  kk jj hh gg
kk IPの下位8bit
jj IPの上位8bit
hh CSの下位8bit  JMP命令が自動的にCSレジスタにロードする。
gg CSの上位8bit



首が筋肉痛だ。ナラシで上体上げて走るのって(伏せれば楽なのだけど、「ナラ
シ」であることをアピールするために)翌日辛いのよね。午前中はボーッとして
いた。


ピストンの溶け方三種
  • セットが薄い→サイドから (端ちょいデトネ)
  • 二次圧縮上げ過ぎ→トップ、排気側からデローンと一気に溶ける。
  • 点火時期早過ぎ→ピストンの外周均等にちょっとづつ溶ける。
だろうか。
机の引き出しを作りはじめました。この前作った整理箱と同じように。材料は 本体と同じSPF。組み立てに失敗。もっと慎重に合い口を合わせながら組まない と。

ショックなことが。なんか針が埋まってた。SPFの場合、端によくタグ用に打っ てあることがあるので気をつけているのだけど、まさか真中にあるとは思わな かった...。自動カンナの刃が欠けてしまった。