090916

|


SH4A続き。Cのプログラムを呼ぶためにスタックを設定します。_stack_startは
リンカスクリプトで指定。
	.align	2
	.section .text
	.globl	start
start:
1:	mov.l	.L_led, r0
	mov	#0x4,	r1
	mov.l	r1,	@r0
	mov.l	.L_startup, r0
	mov.l	.L_stack_start, r15
	jmp	@r0
	 nop
	/* NOTREACHED */
	.align	2
.L_led:
	.long	0xa4000008
.L_startup:
	.long	_startup
.L_stack_start:
	.long	_stack_start

ユーザ開放のディップスイッチを読みとって、そこからLEDを点灯します。

#include <types.h>
#include <system.h>

//R0P7786LC0011RL PLD internal LED register.
#define	LEDCR	((volatile uint8_t *)0xa4000008)
//R0P7786LC0011RL PLD internal switch register.
#define	SWSR	((volatile uint8_t *)0xa400000a)

uint8_t dip_switch (void);
void led (uint8_t);

void
startup ()
{

  while (/*CONSTCOND*/1)
    {
      led (dip_switch ());
    }
  // NOTREACHED
}

uint8_t
dip_switch ()
{

  return *SWSR;
}

void
led (uint8_t sw)
{
  int i;

  for (i = 1; i < 16; i <<= 1)
    {
      uint8_t r = i | i << 4;
      if (sw & i)
	*LEDCR |= r;
      else
	*LEDCR &= ~r;
    }
}
ちょっとはまりました。スタック(R15)を設定してCの関数にジャンプする部分
	mov.l	.L_startup, r0
	mov.l	.L_stack_start, r15
	jmp	@r0
	 nop
ここを最初
	mov.l	.L_startup, r0
	jmp	@r0
 	 mov.l	.L_stack_start, r15
と分岐遅延スロットに入れていて失敗。分岐遅延スロットにはPC相対MOV命令は 入れれないのだ。こんなブートの一回だけしか通らないところで遅延スロット を使ったところでなんの意味もないのだけど、ついついスロットがあると入れ たくなってしまい。