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

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

3664の続きです。サブルーチンコールからスレッドをスイッチするところは こう変更。__NORMAL_MODE__は-mnオプションで自動的にgccがデファインしてくれる。
rtsとrteのスタック状態を合わせるために2byteインクリメントしてます。ポイ ンタから値をとってくる部分も全部変更しないとだめ。mov.lのままだとお目当 ての部分は上位のe3に入ってしまう。リトルエンディアンだったらよかったの にね...。

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

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