2009年2月アーカイブ




筑波に行ってきました。早朝の段階では昨日の雨で路面はウェット。9時まで日
が差さなかったこともあり、なかなか乾かなかったけれど、一本目の10時半に
はドライに。しかしオイル処理のオガクズが1コーナーとCXに盛大に蒔かれてい
て、ちょっと残念。

ベストラインがとれないとはいえ9秒に入れるのがやっとだ。チェッカー真近、 S字でシフトミスしてオーバーレブしてしまう。その後のバックストレッチで明 らかにE/Gおかしい。次の周、ピットインして、ちょっと空吹かししてみると段々 おかしくなって、ついに失火してしまった。
E/Gをかけようとリアホイールを手で廻してみると、圧縮がなくなっていた。 開けてみると....うわわ。

プラグの電極が落ちたかと思いきや、そうでもない。しかしギャップが狭すぎ。 なんと0.13mmしかない。シリンダー外してみると、シリンダーのダメージは まったくない。ピンクリップもちゃんとついている。
これはこのプラグギャップのせいで異常に早く点火してしまって、そのための デトネーションかな?
このプラグをつける時にギャップを点検しなかった。でもこのギャップじゃ まず普通に走らないと思うんだよね。最初はいい感じに走ってたし。いや、 久々だから、走ってたような気がしてただけかもしれない。
幸い、次の走行まで1時半あるので、組み直しました。

まずはクランクケースを洗浄。スポイトもシリンジも持ってきてなかったので、 最後はチューブを口にくわえて吸ってチマチマと。ちょっとアルミ片が落ちて ました。クランクにペーパータオルを狭んで一回転させてアルミ片を掃き出し。 クランク大腿部にダメージがないことを祈る。
ピストンとピストンリングだけ新品。ヘッドは今のと容量が同じやつを選んで。 05の新品も持ってたのだけど、このE/G用の面研が済んでなかった。作業は1時 間程度かかった。

二本目は12:45から。オイル処理も消え、気温も12℃と絶好のコンディションな のにナラシからなのが悔しい...。二周して2ヘアを立ちあがると、最終手前で コース上に残った転倒車両が...。赤旗中断です。怖かった。
さらに3周ほど10000までで周回して、2周ほど12000までで周回してみると、 E/GはOKっぽい。ピットインして「ナ」印を外して、思いっきり走ります。我慢 できなくなった。今日は台数も多く、テンションが上がって7.7まで出た。上出 来だ。
なんとか二本目も走れてよかった。
守谷SAで給油 734.0km/57.6l=12.74km/l

R7376-9。やっぱりEGVの方がよかった気がしてきて、帰りのD'sではB95EGVを購 入。

こんなピストン作ったのは人生初だよ。

サイドは綺麗。





10:30 D.alt -146m 12.3℃ 46.6% 1020.5hPa
1.8/1.8
F12巻き
3枚50℃
9.8

12:30 D.alt -120m 12.8℃ 48.9% 1019.3hPa
3枚60℃
残ストF7/R3
best 7.7


天板の固定をします。M8の鬼目ナットを埋めこみます。このドリルアダプタは
10mmまでしかくわえられない。鬼目ナットの下穴指定は11.2-11.5。端材でテス
トしてみたところ、SPFなら10mmでもいけるので10mmで。



下穴の縁は面取りしておかないと、最後で縁がまくれあがる。

こんな感じ。天板が取り外し可能なら、搬入性が格段に上がるはず。

x86の命令セットについて。ちょっとびっくりしたLOOPとストリング命令について。 MOVはフラグを更新しない。XLATもびっくり命令かな。
8086
------------------------------
ループ命令
------------------------------
LOOP
if (--cx != 0) フラグに影響を与えない。
   goto label;

LOOPZ, LOOPNZ
if ((--cx != 0) && ZF)	// LOOPZ 
   goto label;


------------------------------
ストリング命令
------------------------------
					アドレッシング
MOVS	メモリ-メモリの移動		DS:SI -> ES:DI
LODS	メモリからAレジスタへの移動	DS:SI -> A
STOS	Aレジスタからメモリへの移動	A     -> ES:DI
SCAS	メモリとAレジスタの比較		A    <-> ES:DI   
CMPS	メモリとメモリの比較		DS:SI<-> ES:DI

SEG前置命令でSIはDS以外のセグメントにアクセスできるが、DIはES固定。
一命令で自動的にSI,DIはインクリメントする。

方向はディレクションフラグで設定する。CLD(++),STD(--)
フラグの状態を退避しておきたい時はPUSHF, POPF命令を使う。


REP前置命令で、ストリング命令をループする。
終了条件
	MOVS, LODS, STOS : CXレジスタがカウンタでCX==0で終了
	CMPS, SCAS	 : 上記条件 + 比較結果(Zフラグ) -> repz, repnz

while (cx != 0)
{
	operate pending interrupt.
	(MOVS, LODS, STOS, CMPS, SCAS)
	cx--
	if (MOVS, LODS, STOS)
	   continue;
	if (!ZF) // REPNZ
	   break;
}

------------------------------
フラグ
------------------------------
算術演算フラグに影響する命令
ADC, ADD, CMP, CMPS, NEG, SBB, SCAS, SUB

キャリーを除く算術演算フラグに影響する命令
DEC, INC

キャリーとハーフキャリーに意味がある命令
AAA, AAS

オーバーフローに意味がない命令
DAA, DAS

キャリーとオーバーフローに影響を与え、他を不定とする命令。
IMUL, MUL

ハーフキャリーを未定義とする命令
AND, OR, SAR, SHL, SHR, TEST, XOR

キャリーとオーバーフローだけに影響を与える命令
RCL, RCR, ROL, ROR

パリティ、サイン、ゼロに影響を与え、他を不定とする命令
AAD, AAM

全ての算術演算フラグを不定にする命令
DIV, IDIV (除算エラーの時さらにIF,TFに影響する)

特定のフラグの設定
CLC, CLD, CLI, CMC, SAHF, STC, STD, STI
Store AH into Flags: AHレジスタからSF,ZF,AF,PF,CFにロード。

スタックかフラグを復帰する命令
IRET, POPF

割り込みとトラップのフラグをクリアする命令
INT, INTO

フラグに関係のない命令
CALL, CBW, CWD, CWD, ESC, HLT, Jcc, JCXZ, JMP
LAHF, LDS, LEA, LES, LOCK, LODS, LOOP, MOV,
MOVS, NOP, NOT, OUT, POP, PUSH, PUSHF, REP,
RET, SEG, STOS, WAIT, XCHG, XLAT



机の組みたてです。地獄ホゾで。楔はラワンの端材から。



二箇所ほど、ホゾが長かったり、サイズが妙に合わなくて失敗してしまった。 もうちょっと仮組みをしっかりやっておくべきだった。

足掛けは割り楔通しホゾにしてみました。これは初めての試み。地獄ホゾより 安心感ある作業ができる感じ。



久々にもつ定を食べに行ってきました。本当にそれだけ...。一本目、さーっ
ウォーマー外してっ...というとこでパラついてきた。多少パラつくくらいなら、
とコースインゲートに並ぶと、どんどん雨足が。コースインする時にはウェッ
ト。一応コース入ってみるも、こりゃだめだということでピットイン。その後
雨足がやむこともなく。二本目はフルウェット。



まだ準備の最中は、まぁ持ちそうかなという雰囲気だったのだけど...

8:50 -238m 6.6℃ 75% 1009.6hPa。この後...TT。スクリーンに狭んだ走行券が 憐れです。土曜が雨っぽいから無理して今日にしたのに。


16-bitコードについて。gccできっちりリアルモード用のコードを吐かせるのは 無理そうなので(djgppがあるけれど、吐くのはNASM用)、ちゃっちゃと32bitに もっていってしまうのがよさそうだ。
gasは対応している。
	.arch i8086
	.code16
のように書けばいい。

.code16gccはi386から導入された前置命令0x66(operand-size override
prefix), 0x67(address-size override prefix)を使って、デフォルトビットで
選択されたデフォルトでないサイズに変更させる。(フリップする)(Processor
extension instructions) 8086では未定義(0x60-0x6f)

なのでi386以降で16bitモードで0x66(op)が最初につくと、アドレスは16bit、データは
32bitで実行される。0x67(addr)だと、アドレスは32bit、データは16bit。両方つくと
両方とも32bit。32bitモードの時はこの逆になる。

asm (".code16gcc");を入れたもの。
$ cc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -c a1.c
$ objdump -D a1.o

a1.o:     file format elf32-i386

Disassembly of section .text:

00000000 <a>:
   0:	66 01 d0             	add    %dx,%ax
   3:	66 01 c8             	add    %cx,%ax
   6:	67 66 2b 44 24       	addr16 sub 36(%si),%ax
   b:	04 67                	add    $0x67,%al
   d:	66 03 44 24 08       	add    0x8(%esp),%ax
  12:	66 c3                	retw   

00000014 <b>:
  14:	66 6a 21             	pushw  $0x21
  17:	66 6a 03             	pushw  $0x3
  1a:	66 b9 02 00          	mov    $0x2,%cx
  1e:	00 00                	add    %al,(%eax)
  20:	66 ba 01 00          	mov    $0x1,%dx
  24:	00 00                	add    %al,(%eax)
  26:	66 31 c0             	xor    %ax,%ax
  29:	66 e8 fc ff          	callw  29 <b+0x15>
  2d:	ff                   	(bad)  
  2e:	ff 66 5a             	jmp    *0x5a(%esi)
  31:	66 59                	pop    %cx
  33:	66 c3                	retw   
  35:	8d 74 00 67          	lea    0x67(%eax,%eax,1),%esi

00000038 <main>:
  38:	67 66 8d 4c 24       	addr16 lea 36(%si),%cx
  3d:	04 66                	add    $0x66,%al
  3f:	83 e4 f0             	and    $0xfffffff0,%esp
  42:	67 66 ff 71 fc       	addr16 pushw -4(%bx,%di)
  47:	66 51                	push   %cx
  49:	66 59                	pop    %cx
  4b:	67 66 8d 61 fc       	addr16 lea -4(%bx,%di),%sp
  50:	66 c3                	retw   


asm  (".code16gcc");を入れてないもの。
$ cc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -c a1.c
$ objdump -D a1.o

a1.o:     file format elf32-i386

Disassembly of section .text:

00000000 <a>:
   0:	01 d0                	add    %edx,%eax
   2:	01 c8                	add    %ecx,%eax
   4:	2b 44 24 04          	sub    0x4(%esp),%eax
   8:	03 44 24 08          	add    0x8(%esp),%eax
   c:	c3                   	ret    
   d:	8d 76 00             	lea    0x0(%esi),%esi

00000010 <b>:
  10:	6a 21                	push   $0x21
  12:	6a 03                	push   $0x3
  14:	b9 02 00 00 00       	mov    $0x2,%ecx
  19:	ba 01 00 00 00       	mov    $0x1,%edx
  1e:	31 c0                	xor    %eax,%eax
  20:	e8 fc ff ff ff       	call   21 <b+0x11>
  25:	5a                   	pop    %edx
  26:	59                   	pop    %ecx
  27:	c3                   	ret    

00000028 <main>:
  28:	8d 4c 24 04          	lea    0x4(%esp),%ecx
  2c:	83 e4 f0             	and    $0xfffffff0,%esp
  2f:	ff 71 fc             	pushl  0xfffffffc(%ecx)
  32:	51                   	push   %ecx
  33:	59                   	pop    %ecx
  34:	8d 61 fc             	lea    0xfffffffc(%ecx),%esp
  37:	c3                   	ret    
$ 

ショックだ…
2009/02/25/093333.jpg



実際にSPFをエンドミルでフライスを最高速で廻して切削してみました。そこそ
こいけるかも。下面はやはりムシれてしまうけれど、端面はいいし、角が崩れ
ないのもいい。これは成功。

金属の切削の場合、切削時に発生する熱のかなりの量(ちょっと忘れた)は切子 がもっていってくれるのだけど、木の場合はそれがない。木工ルーター程、高 回転でもないし、杞憂だとは思う。


愛用のPORTEGE3440CTがこの有様で、悩んでいる。去年は結局このまま使いきっ てしまった。なんとか使えないことはないんだけど...

i386-gccの呼出規約について。

Caller saved: eax, ecx, edx
Callee saved: ebx, esi, edi, ebp, esp
Return value: eax
Frame pointer ebp
Stack pointer esp

引数は全てスタックに右から積む。引数のスタックの巻戻しはcallerがやる。
__attribute__((regparm (NUM)))や、コンパイルオプションの-mregparm=NUMで
最大3つまで(順番はeax, edx, ecx)レジスタ渡しとすることができる。
残りは右からスタックに積む。


fastcallの場合はecx, edxの順で最初の二つをレジスタ渡し。これはi386のみ。


`fastcall'
     On the Intel 386, the `fastcall' attribute causes the compiler to
     pass the first argument (if of integral type) in the register ECX
     and the second argument (if of integral type) in the register EDX.
     Subsequent and other typed arguments are passed on the stack.
     The called function will pop the arguments off the stack.  If the
     number of arguments is variable all arguments are pushed on the
     stack.

`regparm (NUMBER)'
     On the Intel 386, the `regparm' attribute causes the compiler to
     pass arguments number one to NUMBER if they are of integral type
     in registers EAX, EDX, and ECX instead of on the stack.  Functions
     that take a variable number of arguments will continue to be
     passed all of their arguments on the stack.

     Beware that on some ELF systems this attribute is unsuitable for
     global functions in shared libraries with lazy binding (which is
     the default).  Lazy binding will send the first call via resolving
     code in the loader, which might assume EAX, EDX and ECX can be
     clobbered, as per the standard calling conventions.  Solaris 8 is
     affected by this.  GNU systems with GLIBC 2.1 or higher, and
     FreeBSD, are believed to be safe since the loaders there save all
     registers.  (Lazy binding can be disabled with the linker or the
     loader if desired, to avoid the problem.)

`-mregparm=NUM'
     Control how many registers are used to pass integer arguments.  By
     default, no registers are used to pass arguments, and at most 3
     registers can be used.  You can control this behavior for a
     specific function by using the function attribute `regparm'.
     *Note Function Attributes::.

     *Warning:* if you use this switch, and NUM is nonzero, then you
     must build all modules with the same value, including any
     libraries.  This includes the system libraries and startup modules.



int
a (int a0, int a1, int a2, int a3)
{

  return a0 + a1 + a2 - a3;
}

int
b ()
{
  return a (0, 1, 2, 3);
}

main ()
{

  a (0xaa55, 4, 3, 2);
}

cc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -S a.c

	.file	"a.c"
	.text
	.p2align 2,,3
.globl a
	.type	a, @function
a:
	movl	8(%esp), %eax
	addl	4(%esp), %eax
	addl	12(%esp), %eax
	subl	16(%esp), %eax
	ret

	.p2align 2,,3
.globl b
	.type	b, @function
b:
	pushl	$3 右から詰む。(cdecl)
	pushl	$2
	pushl	$1
	pushl	$0
	call	a
	addl	$16, %esp 引数領域の巻戻しはcallerがやる。
	ret

	.p2align 2,,3
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx; lea フラグレジスタを書きかえない。
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ecx
	popl	%ecx
	leal	-4(%ecx), %esp
	ret

cdecl 右側の引数から積む。callarがスタックを戻す。
Pascal 左側から。calleeがスタックを戻す。

レジスタ渡しについて。

int
a (int a0, int a1, int a2, int a3)
{

  return a0 + a1 + a2 - a3;
}

int
b ()
{
  return a (0, 1, 2, 3);
}

main ()
{

  a (0xaa55, 4, 3, 2);
}

gcc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -mregparm=3 -S a.c

	.file	"a.c"
	.text
	.p2align 2,,3
.globl a
	.type	a, @function
a:
	addl	%edx, %eax
	addl	%ecx, %eax
	subl	4(%esp), %eax
	ret
	.p2align 2,,3
.globl b
	.type	b, @function
b:
	pushl	$3          ;(引数4)
	movl	$2, %ecx    ;(引数3)
	movl	$1, %edx    ;(引数2)
	xorl	%eax, %eax  ;(引数1)
	call	a
	popl	%edx ;callerがスタックを戻す。2つまでならpoplを重ねる。
	ret
	.p2align 2,,3
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ecx
	popl	%ecx
	leal	-4(%ecx), %esp
	ret

3引数までeax, edx, ecxで渡される。ボーランド__fastcall

attributeを使う場合は定義にもattributeをつける。

int a (int, int, int, int, int) __attribute__((regparm (3)));

int __attribute__((regparm (3)))
a (int a0, int a1, int a2, int a3, int a4)
{

  return a0 + a1 + a2 - a3 + a4;
}

int
b ()
{
  return a (0, 1, 2, 3, 4);
}
	pushl	$4  レジスタに乗せきれない分は右から。
	pushl	$3
	movl	$2, %ecx
	movl	$1, %edx
	xorl	%eax, %eax
	call	a



面取りする前に治具を。トリマ用の巨大ベースプレート(自作)に、スリット加
工。6mmで開けたいので、6mmのエンドミルでやってみたら端面がガタガタになっ
てしまった。バックラッシュでだめ。せめて4mmからやるべきだったかな。

実用上はまったく問題ない。

アングル材にビットの逃げを作って装着。使ってみるととても快適。手持ちだと どうしても端でぶれてしまったりするのだけど、これなら確実。
面取りまで終わりました。SPFを面取りすると、元の2x4材に戻ってしまったような 感じでちょっと寂しい。

次は天板を固定するボルト穴のザグり。ドリルだとマクれがひどくて痛々しい 結果になってしまったので、フライスを最高速で廻してエンドミルで掘ってみ ます。これは今の通常のセッティング。

x86はオペランドにレジスタの制限がある。その歴史を遡ってみた。
------------------------------
8008
------------------------------
I/O
 |
 A F(SZHPC)Sign,Zero,Half Carry,Parity,Carry
 B C
 D E
 H L ---> メモリ
 PC

Half-Carry flag: This flag holds the carry from bit 3 to bit 4. It is
used by the DAA instruction to convert the contents of the A register
to BCD form.

Aレジスタ アキュムレータ
B,C,D,E,H,L 汎用

AレジスタしかI/Oとアクセスできない。
H, Lしかメモリにアクセスできない

8段ハードウェアスタック

------------------------------
8080A
------------------------------

A F
B C
D E
H L
PC

SP	スタックが導入された。
------------------------------
8086
------------------------------
()内は対応する8080A
(A)  AX	アキュムレータ
(HL) BX	ベース
(BC) CX カウンタ (loop、shift, rotate)
(DE) DX データ  (div, mult)
(F)  Flag ODIT(SZHPC) Overflow,Direction(ストリング命令群),Interrupt,Trap

(PC) PC

(SP) SP Stack Pointer
--以下新設
     BP Base Pointer (フレームポインタ)
     SI Source Index
     DI Destination Index

     CS	Code Segment
     DS	Data Segment
     SS	Stack Segment
     ES	Extra Segment

レジスタをアドレスとして使えるのはBX,SI,DI,BPだけ。
指定しない場合DS。BP,SPはSS。

[CS,DS,SS,ES]:[BX,BP]+[SI,DI]+disp(8,16) (80286まで)

32bitからは制限なし。
[CS,DS,SS,ES]:[EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI]+[EAX,EBX,ECX,EDX,EBP,ESI,EDI] * [1,2,3,4] + disp(8,32)




なんとか刻み終わって仮り組みまで。やっぱりバランス悪い。幕板の厚みを落
として、もっと下まで伸ばして、足は両辺とも3mmくらいつつ増やしたいかな。

穴開けに失敗してしまってがっくり。まぁ下面だから見えないといえば見えな いのだけど。

どう面取りするかで悩み中。


机用に荒木取りしておいた木材が3週間たったので、製材。木工部屋も、もっと使いやすくしたいのだけど...。



ケガキまで終了。一部、部材の厚さを間違えてしまって、ちょっと設計変更。節が 多いのにも参った。




CR85の整備。ピストンリングを新品にしただけ。最終戦でサイレンサーステー
が折れてしまったので、作り直しておかないと。





仕分け終了。これで3年は持つかな。






シーズンインに向けて、黙々とガレージの掃除を。もう開幕戦まで一ヶ月切っ
てるんだよね。ついでにネジ箱の整理をはじめてしまったので大変。やっと
M6,M8,M10まで終わった後はM3,M4,M5。



DROは配線をまとめて、軸の表示をして仕上げ。はやく実戦で使いたい。




イサギダ450mmのノギスの電源部分にパスコンをつけてみた。まさにつけてくれ
というようなパターンがある。しかし、これはまったく効果がなかった。

今回はじめてホットボンドを使ってみたのだけど、これって結構強力。剥すのに 一苦労。

600mmと交換したり、いろいろ試してみたところ、このようにノギスの背面が旋 盤になるように取りつけるとノイズを拾わなくなった。以前はこのアルミアン グルの反対側に液晶面が旋盤側になるように取りつけていた。
旋盤本体から放射されるノイズを拾ってしまったのかも。これならばノギスボ ディーでそれは緩和される。
よかった。よかった。

芯押し台のスケールは特に迷うこともなく、失敗もなく。

ついに旋盤4軸DRO完成! 長かった!




刃物台につけるスケールの台を作り直しました。前回の失敗から、台を厚くし
たのだけど、これは微妙だな。



カバーまでつけると、こんなにとびでてしまう。作業中にワークと干渉してし まうかも。しかし反対側にはジブの調整ネジとグリスニップルがあるんだよね。

刃物台はこの機会に灯油でシャブシャブ洗って、グリスアップしました。

最後の軸、芯押し台です。今日はクランプする部分を作った。これの作業では じめて旋盤DROを使ってみたのだけど、問題が発生。ノイズだ。どうもイサギダ の450mmだけ、やたらノイズを拾う。電源をOFFした時を拾ってしまう。電源ラ インを別系統にしてみたり、追加のアースをとりつけてみたものの、変わらず。 近くにあるモーターのオフが、かなり確実にノイズを拾う。




この陽気で家のカエルがみんな起きたようだ。コッコッコッ鳴いている。気が
早いのは先週から起きていた。起きたてのカエルは皮膚がヌラヌラしているの
ですぐわかる。寝惚けっぷりがおかしい。近づいてみると、逃げたい気持ちは
伝わってくるのだけど、体がうまく動かないらしくモゾモゾしてるだけなのだ。

これからの季節は雨が降っている日は気をつけないといけない。雨が降ると敷 石の上で呑気に水浴びしていることが多いのだ。大人まで大きくなったのだと 踏んだ瞬間気付くので、そこでずらせるのだけど、子供だと気付いた瞬間には 時既に遅し。去年は一匹踏み潰してしまった。
刃物台もとりあえずあまり考えずに台にネジを切って(台はM4、スライドはM3。台 もM3で良かったかも)、ABSで台つくって取りつけてみたところ、下過ぎて回転 テーブルのボルトと干渉してしまった。

スケールの固定もとても厳しい位置にネジがきてしまった。これはやり直し。

こんな感じかな。やっぱり場所が狭いだけあって辛い。




往復台のスケール取り付けが終わりました。



次は刃物台にスケールを付けます。ここもまた考えどころ。




長手方向はなんとか終了。次はクロス方向。この刃物台もドリルで穴を開けて
みると、かなり柔い材料でした。

逆にイサギダから買ったデジタルキャリパーは、焼き入れがきっちり入ってい て、うちのドリルじゃ歯がたちませんでした。コバルトハイスでも。

クロス方向はこんな感じで。2017 t10から削り出し。

スケールとの絶縁部分はABS t10から。




イサギダ450mmノギスです。最初600mmを買っていたのだけれど、実は長すぎる
ことがわかって450mmを買い足しました。600mmはテーブルソーにつけてもいい
かな。

スイッチの部分がタクトスイッチになってたりして、奢ってます。600mmの方は inch/mmのスイッチが動いてないので、こうしたからといってよくなっているわ けでもない。

向きはこう。

こんな感じかな。

3664のモニタを進めてユーザプログラムは割り込みを使えるようにしました。 3052で作っていたのを3664用に。後は共通部分のくくりだして終了かな。
$ tip hmon57600
connected
stack_start: 0xff80
ROM data: 0x14dc-0x14f8
RAM data: 0xfe00-0xfe1c 28byte
bss: 0xfe1c-0xfe7a 94byte
NMI return address|CCR: 80000154
load NMI (0xfda)
load TRAPA#0 (0xfda)
load TRAPA#1 (0xfda)
load TRAPA#2 (0xfda)
load TRAPA#3 (0xfda)
load Adress Break (0xfda)
load Sleep (0xfda)
load IRQ0 (0xfda)
load IRQ1 (0xfda)
load IRQ2 (0xfda)
load IRQ3 (0xfda)
load Wakeup (0xfda)
load Timer A (0xfda)
load reserved20 (0xfda)
load Timer W (0xfda)
load Timer V (0xfda)
load SCI3 (0xfda)
load I2C (0xfda)
load A/D (0xfda)
H8/3664 Monitor Build Feb 10 2009 22:39:18
>> l
~>Local file name? tiny_overlay.mot
98 lines transferred in 1 second 
!
Read 1982 byte. success
Start address: 0xf888
load NMI (0xf9c0)
load TRAPA#0 (0xf9c0)
load TRAPA#1 (0xf9c0)
load TRAPA#2 (0xf9c0)
load TRAPA#3 (0xf9c0)
load Adress Break (0xf9c0)
load Sleep (0xf9c0)
load IRQ0 (0xf9c0)
load IRQ1 (0xf9c0)
load IRQ2 (0xf9c0)
load IRQ3 (0xf9c0)
load Wakeup (0xf9c0)
load Timer A (0xf9e2)
load reserved20 (0xf9c0)
load Timer W (0xf9c0)
load Timer V (0xf9c0)
load SCI3 (0xf9c0)
load I2C (0xf9c0)
load A/D (0xf9c0)
stack_start: 0xfe00
ROM data: 0xfa94-0xfa9a
RAM data: 0xfa94-0xfa9a 6byte
bss: 0xfa9a-0xfa9a 0byte
NMI return address|CCR: f8a0
Process mode.
board_main
done.
>> 
>> oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo


3664Tips。
  • 外部割り込み(IRQ0-3)など、PMR(ポートモードレジスタ)を設定する場合、 PMRを設定して、最低でも一命令(nopでいい)経ってから割り込みステータスを クリアしないと迷い込み割込み(spurious)が入る時がある。
  • 16MHzの場合なんとか57600bpsまでいける。115200bpsはどうあがいても無理。

3664用のモニタ(SRECローダ)まで書きました。モニタはスタックに128byte,デー タセクションとBSSに128byteまでで。RAMの一番てっぺんに配置。スレッドは使 えない。
ここからロードされるプログラムはオーバーレイで。割り込みは使えない。ス タックはモニタの.dataの真下から。使い方的にはシェルコマンドをモニタに登 録したらそのままモニタにリターン。そのコマンドをモニタから起動する。
これでprintfとシェルをモニタに押しこめたので、そこそこ使えそう。

$ tip hmon57600
connected
stack_start: 0xff80
ROM data: 0x12a8-0x12c4
RAM data: 0xfe00-0xfe1c 28byte
bss: 0xfe1c-0xfe7a 94byte
NMI return address|CCR: 80000130
H8/3664 Monitor Build Feb  9 2009 23:02:08
>> test 34 ohayo
>> l
~>Local file name? tiny_process.mot
84 lines transferred in 1 second 
!
Read 1717 byte. success
Start address: 0xf844
stack_start: 0xfe00
ROM data: 0xfa1c-0xfa22
RAM data: 0xfa1c-0xfa22 6byte
bss: 0xfa22-0xfa22 0byte
NMI return address|CCR: f85c
Process mode.
board_main
done.
>>   ここで元のモニタのシェルに戻ってきています。
>> test 19 ohayo   これはロードしたプログラムから登録されたコマンド。
0: test
1: 19
2: ohayo
>> 
これでH8/Tiny開発環境もかなり整ってきた。



旋盤にデジタルスケールを取りつける作業に入りました。なかなかイメージが
あがってこなく半日唸ってました。「迷ったら考えずに手を動かす」といっても
どこから手をつけるものか...と。



刃物台を裏から。

まずは構造的に無難そうな位置に、15mm深さでM5x0.8を切りました。鋳物なの で(それにドリルを入れた感覚、かなり柔い)リコイルを入れておきたいところ だけど、それは必要になったら。M5x0.8のリコイル手持ちにないし。
そこに100x22x30のABSを取りつけ。ここでまず絶縁して、この先にステーで とりつけることにしました。
作業性を考えて、邪魔にならない奥方向にスケールをつけることにしました。

刃物台。






整理箱が全部組みあがった。先に一個だけ仕上げたのを入れて今回は6箱作った
のだけど、トランジスタ/レギュレータ/ダイオード、汎用ロジック、コンデン
サ、半固定抵抗/集合抵抗、コネクタ(2箱)、ダイオードで使いきってしまって、
固定抵抗の分割までは足りなかった。あともうちょっと欲しいか。全部並べると
秋葉の店のよう。



これを引き出しとして入れる外枠も欲しいけど、来年かな...。




今回作成する5個のうち3つまで組み立てました。これだけ合い口があると、ボ
ンドを塗るだけでもかなり手間がかかります。あと二つ!



3664の続きです。周辺デバイスについて。 3664のシリアルコミュニケーションユニットはSCI3。この3はチャネル番号ではなく、'SCI3'というデバイス名。これは結構大きな変更が入っている。
TDRに書きこんだ後の、TDREビットのクリア、RDRを読みこんだ後のRDRFビットの クリアをコントローラ側で行なうように変更されているので、ユーザ側でビット を落としてはだめ。(出力だと、ダブって出力されるようなことになります。)
後はRXI,TXI,ERI,TEIの割り込み要因が3052ではそれぞれ別のベクタだったのが 一つのベクタになってSSRを参照するようになっている。これは妥当なとこかな。
タイマは
Timer A
オーバーフロー時の設定でその後カウントするかしないかが決まる。クリアは
TMR3,TMR2ビット(プリスケーラもリセットされる) カウンタはリードオンリー
オーバーフローフラグは割り込みコントローラのIRRを参照TCAは内部クロック
によりカウントアップ。時計用タイムベースの時は参照できない。
時計用の時はオーバーフローの割りこみのみ。

Timer V
動作クロックを指定するとカウントしはじめる。
止めるにはクロックの入力を禁止に設定する。

カウンタはR/W
オーバーフローフラグはTCSRV

Timer W
3052のITUに近い。
Timer A,Vはレジスタの使い方がとりわけトリッキー。単純なデバイスだし多少 びっくりするくらいで、このくらいでもいいのかもねというような気もする。
ということで、なんとかカーネルは動いた。ほとんどメモリ2KBを使いきってるけど。 3スレッドくらいまでならいけるかな。

$ tip hmon38400
connected
stack_start: 0xffffff7c
ROM data: 0x2c58-0x2c70
RAM data: 0xfffff780-0xfffff798 24byte
bss: 0xfffff798-0xfffffe7a 1762byte
NMI return address|CCR: 800003aa
div=125 mult=63: 100msec 238-7
,,,,,,,,,,board_device_init
regs.sp = f94c
regs.sp = fb44
board_main
>hoelp
[0] help
3: 270
2: 262
1: 162
---Ready Queue---
<0>: 
<1>: 
<2>: 
<3>: 1 
---Thread Status---
id   pri(used/total)
[3] W 1 (114/384) sci send
[2] W 0 (122/384) sci recv
[1] R 3 (222/384) root
---Monitor---
W ringbuffer
        lock : 
        event: 3(sci send) 
avaliable command: help reset 
>oo



ちょっと気合い入れて全部刻みました。ベニヤ板の切断には下にスタイロフォー
ムを置いてその上から丸ノコで切るととても調子がいいです。今迄気付かなかっ
たのが悔やまれる。



今回、溝の正確さは今迄で一番なのだけど、そうなるとケガキの適当さが組み立ての時に問題に。ガタがないから歪んでしまって。なかなか難しい。

3664の続きです。サブルーチンコールからスレッドをスイッチするところは こう変更。__NORMAL_MODE__は-mnオプションで自動的にgccがデファインしてくれる。
rtsとrteのスタック状態を合わせるために2byteインクリメントしてます。ポイ ンタから値をとってくる部分も全部変更しないとだめ。mov.lのままだとお目当 ての部分は上位のe3に入ってしまう。リトルエンディアンだったらよかったの にね...。
	.globl _do_thread_switch
_do_thread_switch:
	; save context.
#ifdef __NORMAL_MODE__
	subs	#2,	er7
	mov.w	@_current_thread, r3
#else
	mov.l	@_current_thread, er3
#endif
	stc.b	ccr,	r0l
	mov.b	r0l,	@er7	; set CCR to MSB of return address.
	mov.l	er7, @(0x1c, er3) ; sp
	mov.l	er6, @(0x18, er3) ; callee saved
	mov.l	er5, @(0x14, er3) ; callee saved
	mov.l	er4, @(0x10, er3) ; callee saved
	; no need to store caller saved. (this is subroutine call.)

	jsr	@_thread_context_switch
#ifdef __NORMAL_MODE__
	mov.w	@_current_thread, r0
#else
	mov.l	@_current_thread, er0
#endif
	mov.l	@(0x1c, er0), er7  ; sp
	mov.l	@(0x18, er0), er6 ; callee saved
	mov.l	@(0x14, er0), er5 ; callee saved
	mov.l	@(0x10, er0), er4 ; callee saved
	mov.l	@(0x0c, er0), er3 ; caller saved
	mov.l	@(0x08, er0), er2 ; caller saved
	mov.l	@(0x04, er0), er1 ; caller saved
	mov.l	@(0x00, er0), er0 ; caller saved
	; resume interrupt. and return
	rte
スレッドの初期設定の部分も書き替えます。もうかなりイヤーなコードになっ てます。intを使ってもうちょっとすっきりさせることはできるけれど、逆に intもポインタもコロコロ変わる状況だと、できるだけ確定しておきたいという 気持ちもあって。あっと思ったらオーバーフローしてたというのがつらい。
thread_t
thread_create (uint8_t *thread_area, size_t stack_size, const char *name,
	       void (*start)(uint32_t), uint32_t arg)
{
  uint8_t s = intr_suspend ();
  struct thread_control *tc = (struct thread_control *)thread_area;

  __thread_setup (tc, stack_size, name);
  tc->regs.er0 = arg; // pass 1st arg.

#ifdef __NORMAL_MODE__
  tc->regs.sp = (uint32_t)(uint16_t)tc->stack_bottom;
  iprintf ("regs.sp = %x\n", tc->regs.sp);
#else
  tc->regs.sp = (uint32_t)tc->stack_bottom;
#endif
  // install return address for 'rts/rte'
#ifdef __NORMAL_MODE__
  *(uint32_t *)tc->stack_bottom = (uint16_t)start;
#else
  //  tc->regs.sp = (uint32_t)start;
  *(uint32_t *)tc->regs.sp = (uint32_t)start;
#endif
  intr_resume (s);
  LPRINTF ("[%d]:%s pc=%A sp=%x *sp=%x stack=%dbyte\n", tc->id, tc->name,
	   start, tc->regs.sp, *(uint32_t *)tc->stack_bottom, stack_size);

  return tc;
}
なんとかスレッドは動いたっぽい。まだタイマを実装してなく、遅延ディスパッ チが動かないので本当に動いているかまだ微妙。



整理箱の部材の裁断まで終わりました。よくよく数えてみたら5箱でした。節が
きついところは手押しカンナで平面だしても、しばらくするとまた内部の応力
から反ってしまう。厚さが10mmと薄いし。



3664サポートを続けました。ハマったポイントは
  • SCI3のTXDの端子はデフォルトでI/Oポート。TXDにするにはPMR1を設定。 RXDはSCR3.REを立てるだけでいい。
  • ベクタは16bitなのでスタートアドレスの指定はSHORT (ABSOLUTE (start))
  • ノーマルモードの場合、割り込み時のPCの退避とサブルーチンコール時の PCの退避に違いがある。
  • タイマAのスタートは
      *TMA |= _TMA2;	// Counter clear.
      *TMA &= ~_TMA2;	// Counter clear.
    
    立てて、落とす。立てたままだと0のまま。
  • gcc -mn (ノーマルモード)だと
    mov.l	sp,  @(0x1c, er3)
    これを、
    6f b7 00 1c 	mov.w	r7,@(0x1c:16,er3)
    としてしまう。32bitで退避したい場合はspを使わずに明示的にer7で指定しないとだめ。
    
  • ポインタが16bit....
PCの退避の問題は
アドバンスドモード           ノーマルモード
割り込み     JSR             割り込み     JSR
--------  ---------	     --------  ---------
CCR			     CCR       PC(8-15)
--------  ---------	     --------  ---------
PC(16-23) PC(16-23)	               PC(0-7)
--------  ---------	     --------  ---------
PC(8-15)  PC(8-15)	     PC(8-15)
--------  ---------	     --------
PC(0-7)   PC(0-7)	     PC(0-7)
--------  ---------	     --------
明示的なサブルーチンコールからのコンテキストスイッチ部分は割り込まれた 時と同じ形式にスタックを変更するようにしてみたのだけれど、まだちょっと 未完成。そこまでトリッキーなことしてもRAMが2KBしかないのでスレッドはま ず使えないと思う。最低でも1スレッドに384byteのスタックはいるし。
ポインタが16bitなのが広範囲に問題。ポインタを32bitだとしてるコードが多 いんだ。だめね。amd64でも、なんどかハマってる。これは逆にポインタが 64bitで。



整理箱量産に向けて、テーブルソー用の押し具を作りました。これで安心に作
業できる。



4箱分、製材しました。

H8/Tinyサポートをはじめてみました。実際に手をつけてみるとこれは結構キツ い。H8/300Hがアドバンスドモードで、メモリ空間が1M-16Mだったのに対してこ れはノーマルモードで64KB。なのでポインタが16bitなのだ。ベクタテーブルも 16bitになるし、いろいろ気をつけないといけない。周辺デバイスも扱いが違っ てて、タイマはまったく別物。コンパイラから別モードになってしまうのでど こまで信用できるのかからも見極めないといけない。うーん。


筑波一戦のエントリーを済ませました。

旋盤にどうやってデジタルスケールを取りつけるか検討。左側の部分は移動振 れ止めをつける場所だし、右側はカミソリ調整ネジがある。カミソリ調整はそ ういつもやるわけじゃないので、右側に取りつけでもいいかとも思いつつ。 それか奥かのどっちかだね。



電子部品の整理箱を作りました。前回作ったのとまったく同じ仕様。



最近はイヤーマフもしています。イヤーマフをしてみると思いの他、落ちつい て作業できる。木工機械の爆音はどこかそわそわさせるもののよう。

ホゾはテーブルソーで加工。今迄、じっくりガイドを調整して作業していたの だけどれど、刃のブレがあるのでどうしてもずれてしまう。思いきってガイド なしで目視で加工してみたら、実はそっちの方が早くて精度が高かった。

前作より多少うまくできました。

机のフレーム部分の荒木取りも終わらせておきました。SPFで作るにはちょっと 華奢に設計し過ぎたかも。

MonotaRO(モノタロウ)
あわせて読みたい