改行コードは扱う場所によってコードを変えなくてはいけないようです。
めんどくさいというかこんなことやめてほしいです。

UNIX:\n
シリアル通信:\r
シリアル出力:\r\n
⇒シリアル通信とシリアル出力は何が違うんだ????★

このようなコード変換を実施することを一般に端末変換というそうです。
シリアルからの入力時も変換が必要。

UNIX<-------->シリアル出力
\n         \r\n


/* 1文字送信 */
int putc(unsigned char c)
{
if(c == '\n')
{
serial_send_byte(SERIAL_DEFAULT_DEVICE,'\r');←★シリアル出力時に\rを付加。
}

return serial_send_byte(SERIAL_DEFAULT_DEVICE,c);
}

/* 文字列送信 */
int puts(unsigned char *str)
{
while(*str)
{
putc(*(str++));
}
return 0;
}
シリアルへの1文字出力の方法についての説明。

SCIでは1文字送信で2つのレジスタを使用します。

とりあえず以下の内容がビットごとの設定内容のようです。
(詳細はH8/3069Fのマニュアルの13.2.7節)

■TDR
TDR は、シリアル送信するデータを格納する8 ビットのレジスタです。
SCI は、TSR の空を検出すると、TDR にライトされた送信データを TSR に転送してシリアル送信を開始します。TSR のシリアルデータ送信中に TDR に次の送信データをライトしておくと、連続シリアル送信ができます。TDR は、常にCPU によるリード/ライトが可能です。TDR は、リセット、またはスタンバイモード時にH'FF にイニシャルライズされます。

SCIは、TDRから送信データをいったんTSRに転送し、LSB(ビット0)から順にTxD端子に送り出すことでシリアルデータ送信を行います。1 バイトのデータ送信を終了すると自動的にTDRからTSRへ次の送信データを転送し、送信を開始します。ただし SSR の TDRE ビットが 1 にセットされている場合には、TDRからTSR へのデータ転送は行いません。CPU から、直接TSR をリード/ライトすることはできません。

■SSR
ビット7:トランスミットデータレジスタエンプティ( TDRE)
TDR からTSRにデータ転送が行われTDRに次のシリアル送信データをライトすることが可能になったことを示します。

0 TDR に有効な送信データがライトされていることを表示
[クリア条件]
(1) TDRE=1 の状態をリードした後、0 をライトしたとき
(2) DMAC でTDR へデータをライトしたとき
1 TDR に有効な送信データがないことを表示(初期値)
[セット条件]
(1) リセット、またはスタンバイモード時
(2) SCR のTE ビットが0 のとき
(3) TDR からTSR にデータ転送が行われてTDR にデータライトが可能になったとき


ビット6:レシーブデータレジスタフル( RDRF)
受信したデータがRDR に格納されていることを示します。

0 RDR に受信データが格納されていないことを表示(初期値)
[クリア条件]
(1) リセット、またはスタンバイモード時
(2) RDRF=1 の状態をリードした後、0 をライトしたとき
(3) DMAC でRDR のデータをリードしたとき
1 RDR に受信データが格納されていることを表示
[セット条件]
シリアル受信が正常終了し、RSR からRDR へ受信データが転送されたとき
【注】受信時にエラーを検出したとき、およびSCR のRE ビットを0 にクリアしたときにはRDRおよびRDRF フラグは影響を受けず以前の状態を保持します。
RDRF フラグが1 にセットされたまま次のデータを受信完了すると、オーバランエラーを発生し、受信データが失われますので注意してください。


ビット5:オーバランエラー( ORER)
受信時にオーバランエラーが発生して異常終了したことを示します。
(本では省略されていて紹介されていませんでした。)

ビット4:フレーミングエラー( FER)/エラーシグナルステータス(ERS)通常のシリア ルコミュニ ケーション インタフェー スとスマー トカードイ ンタフェー ス
では、機能が異なります。また、SCMR のSMIF ビットによって切り替わります。
(a)シリアルコミュニケーションインタフェースのとき(SCMR のSMIF ビットが0)
調歩同期式モ ードで受信 時にフレー ミングエラー が発生して 異常終了し たことを示します。
(b)スマートカードインタフェースのとき(SCMR のSMIF ビットが1)
スマートカードインタフェースモードでは、送信時に受信側から送り返されるエラーシグナルのステータスを示します。
なお、スマートカードインタフェースではフレーミングエラーは検出しません。
(本では省略されていて紹介されていませんでした。)

ビット3:パリティエラー( PER)
調歩同期式モードで、パリティを付加した受信時にパリティが発生して異常終了したことを示します。
(本では省略されていて紹介されていませんでした。)

ビット2:トランスミットエンド( TEND)
通常のシリア ルコミュニ ケーション インタフェー スとスマー トカードイ ンタフェー スでは、機能が異なります。
また、SCMR のSMIF ビットによって切り替わります。
(a)シリアルコミュニケーションインタフェースのとき(SCMR のSMIF ビットが0)送信キャラクタの最終尾の送信時に TDR に有効なデータがなく、送信を終了したこと
を示します。TEND フラグはリード専用ですので、ライトすることはできません。
(b)スマートカードインタフェースのとき(SCMR のSMIF ビットが1)
送信キャラクタの最後尾ビットの送信時に TDR に有効なデータがなく、送信を終了したことを示します。
TEND フラグはリード専用ですので、ライトすることはできません。
(本では省略されていて紹介されていませんでした。)

ビット1:マルチプロセッサビット( MPB)
調歩同期式モードで受信をマルチプロセッサフォーマットで行うときに、受信データ中のマルチプロセッサビットを格納します。
MPB ビットは、リード専用であり、ライトすることはできません。
(本では省略されていて紹介されていませんでした。)

ビット0:マルチプロセッサビットトランスファ( MPBT)
調歩同期式モードで送信をマルチプロセッサフォーマットで行うときに、送信データに付加するマルチプロセッサビットを格納します。
クロック同期式モードやマルチプロセッサフォーマットでないとき、あるいは送信できないときにはMPBT ビットの設定は無効です。
(本では省略されていて紹介されていませんでした。)



SSRではエラー検出もできるような内容が紹介されていますが本書では取り扱わないようだ。
一番基本的なところを抑えればOKという配慮があるのだろう。
今の時点で異常終了みたいなところやっても意味ないしね。
とにかく、これからSSRのビット0からビット5はお目にかからない可能性もあるのでせっかくだから、ザッ~と通して記載してみました。
目的はOSを作成すること。
とりあえず、紹介されている文字送信の手順は以下のとおり。
①SSRの送信完了ビットが落ちていないことを確認する。
②TDRに送信したい文字を書き込む。
③SSRの送信完了ビットを落とす。
④送信が完了すると、コントローラがSSRの送信完了ビットを立てる。


それに準じて出来上がったソースは以下のとおり。

/* SSRの各ビットの定義 */
#define H8_3069F_SCI_SSR_MPBT (1<<0)
#define H8_3069F_SCI_SSR_MPB (1<<1)
#define H8_3069F_SCI_SSR_TEND (1<<2)
#define H8_3069F_SCI_SSR_PER (1<<3)
#define H8_3069F_SCI_SSR_FERERS (1<<4)
#define H8_3069F_SCI_SSR_ORER (1<<5)
#define H8_3069F_SCI_SSR_RDRF (1<<6) /* 受信完了 */
#define H8_3069F_SCI_SSR_TDRE (1<<7) /* 送信完了 */

/* 送信可能か? */
int serial_is_send_enable(int index)
{
volatile struct h8_3069f_sci *sci = regs[index].sci;
return(sci->ssr & H8_3069F_SCI_SSR_TDRE);
}

/* 1文字送信 */
int serial_send_byte(int index, unsigned char c)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;

/* 送信可能になるまで待つ */
while(!serial_is_send_enable(index)) ←★①
;
sci->tdr=c;←★②
sci->ssr &= ~H8_3069F_SCI_SSR_TDRE; /* 送信開始 */←★③

return 0;
}
シリアル通信の速度(ボーレート)の設定を行う。

BRR は、SMRのCKS1、CKS0 ビットで選択されるボーレートジェネレータの動作クロックとあわせて、シリアル送信/受信のビットレートを設定する8 ビットのレジスタです。



BRR の設定値は以下の計算式で求められます。
(詳細はH8/3069Fのマニュアルの13.2.8節)

〔調歩同期式モード〕
N=(φ÷(64×2^(2n-1)×B)×10^6)-1

〔クロック同期式モード〕
N=(φ÷( 8×2^(2n-1)×B)×10^6)-1

B:ビットレート(bit/s)
N :ボーレートジェネレータのBRR の設定値(0≦N≦255)
φ :動作周波数(MHz)
n :ボーレートジェネレータ入力クロック(n=0、1、2、3)
 (n とクロックの関係は下表を参照してください)

n  クロック  SMRの設定値
         CKS1 CKS0
0  φ        0  0
1  φ/ 4    0  1
2  φ/16    1  0
3  φ/64    1  1


SCIのボーレートは、SCIに供給されるクロックにより決定。
CPUがI/O用に持っているクロックを分周することで得られるため、分周比をレジスタで設定するとのこと。
分周比はSMRのクロックセレクトで指定できますが、とりあえずは分周比は1で設定とのこと。

クロック:20MHz
分周比:1
ビットレート:9600bps

調歩同期式ッモードの方程式にあてはめたら「64.104166666666666666666666666667」になる。
ということでN=64。

ところで分周比とはここ
パルス信号送出をすることが目的の様で、それを他のパルス信号入力を基準にしてN回に1回の周期で出せるようにしたものみたい。おそらくCPUがI/O用にどんだけ資源を裂けるかを表しているのだろう。


/* デバイス初期化 */
int serial_init(int index)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;

sci->scr = 0;
sci->smr = 0;
sci->brr = 64; /* ★20MHZのクロックから9600BPSを生成(25MHZの場合は80にする) */
sci->scr = H8_3069F_SCI_SCR_RE | H8_3069F_SCI_SCR_TE; /* 送受信可能 */
sci->ssr = 0;

return 0;
}


ボーレートは115200bpsもよく使われるようですがH8/3069FはDCIに供給できるクロック数がそれほど高くないためボーレートを高く設定するとうまく通信がいかないことがあるようです。
もし115200bpsを設定したければN=4(4.4253472222222222222222222222222)になると計算してみるもののマニュアルには115200bpsがのっていないなぁ。


う~む、ここもいろいろ突っ込みたいところだが今はやめて次に進んでおこう。