HOME

shc諸々

 このコンパイラはSH専用なんで、CPUに合わせてあれこれと特殊な命令がある。
 大体は普通のコンパイラみたいに #pragma で書くんだけど、ちょいと特殊な関数みたいなのもあるんで整理しておくべ。

組み込み関数

<2008/11/30記>
 
HARD取説 P276に全関数の一覧表があるけど、自分で使ったのだけ書いておくじゃ。

 void set_cr(int cr)
SR(ステータスレジスタ)のWriteだ。
普通はReadしてから指定ビットだけオンオフするから get_cr と組み合わせて使うわな。
ところでなんで set_sr じゃないんだ?まぁいいけど。
 
 int get_cr(void)
SRのRead。
 
 void set_imask(int mask)
割り込みマスクのWriteだ。これも先に読み出してから指定ビットだけを動かすよな。
 
 int get_imask(void)
割り込みマスクのRead。
 
 void sleep(void)
これって死んだふりするのに使えるよね(笑)
 
 void nop(void)
これはPALMICEでブレークポイントを決めるときに割と便利だよ。
関数の出口直前に置いといて、そこにブレークポイントをセットすれば、関数内の全変数が見られたりする。
最適化しちゃうとブレークポイントをセットする場所が見つけにくくなったりするんだけど、そう言うときにも nop() はOKみたいだ。
 


#pragma指令

 HARD取説 P258

 今のところ使ってるのは #pragma section と #pragma stacksize だけ。
 セクション指定は図6を参照。
 #pragma stacksize はHEWが自動で作り出す stacksct.h 内にあるよ。

 割り込み関数定義の #pragma interrupt は使ってない。
 HEWのサンプルを見るとSH3やSH4では使わないみたいなんだよ。
 HEWのサンプルでは割り込みハンドラをアセンブラで作り、そこでベクターテーブルを参照して直接コールしてるんだ。
 で、割り込みからの戻り処理もアセンブラで書いてる。vhandler.src を覗いてみるのじゃ。
 この辺の詳しいことは近日中にアップするです。ここにアップ


I/Oへのアクセス方法

 SHってI/Oのビット幅が色々あるんだよな。
 Z80みたいに全部8ビットってわけじゃない。
 この辺をカバーするために、HEWが作り出す _iodefine.h のI/O定義は複雑怪奇で、どうも良く分からないのだ。
 まだ慣れてないんで、今のところはPALMICEに付属してるI/O定義を使ってる。↓こんな感じの普通のアドレス定義ね。
 んま、この辺は好みなんで適当にやってます。

// TMU                              サイズ(ビット) アクセスサイズ(ビット)
#define TSTR    0xA412FE92  //        8                8
#define TCOR0  0xA412FE94  //      32               32
#define TCNT0  0xA412FE98  //      32               32
#define TCR0    0xA412FE9C  //      16               16
             :
             :


 ビットはこんな感じで定義してみた。

typedef enum {
    BIT00=0x1u,BIT01=0x2u,BIT02=0x4u,BIT03=0x8u,
    BIT04=0x10u,BIT05=0x20u,BIT06=0x40u,BIT07=0x80u,
    BIT08=0x100u,BIT09=0x200u,BIT10=0x400u,BIT11=0x800u,
    BIT12=0x1000u,BIT13=0x2000u,BIT14=0x4000u,BIT15=0x8000u,
    BIT16=0x10000u,BIT17=0x20000u,BIT18=0x40000u,BIT19=0x80000u,
    BIT20=0x100000u,BIT21=0x200000u,BIT22=0x400000u,BIT23=0x800000u,
    BIT24=0x1000000u,BIT25=0x2000000u,BIT26=0x4000000u,BIT27=0x8000000u,
    BIT28=0x10000000u,BIT29=0x20000000u,BIT30=0x40000000u,BIT31=0x80000000u
} BIT;

       

 で、I/Oアクセス用の関数を使って実際にI/Oする。
 こうしておくとデバッガで追いやすいんだ。

// バイトリード
uchar rdb(ulong addr)
{
    uchar *paddr = ((uchar *) addr);
    return *paddr;
}
// ワードリード
ushort rdw(ulong addr)
{
    ushort *paddr = ((ushort *) addr);
    return *paddr;
}
// ロングリード
ulong rdl(ulong addr)
{
    ulong *paddr = ((ulong *) addr);
    return *paddr;
}
// バイトライト
void wrb(ulong addr, uchar data)
{
    uchar *paddr = ((uchar *) addr);
    *paddr = data;
}
// ワードライト
void wrw(ulong addr, ushort data)
{
    ushort *paddr = ((ushort *) addr);
    *paddr = data;
}
// ロングライト
void wrl(ulong addr, ulong data)
{
    ulong *paddr = ((ulong *) addr);
    *paddr = data;
}


HOME