;-------------------------------------------------------------------- ; サンプルスタートアップルーチン CS3048.ASM ; CS3048 ; (イエロースコープROMデバッグ対応) ; 2002/7 ; Copyright 1998-2002 YellowSoft Co.,Ltd. ; ; ユーザが変更する所は全部で3か所あります。 ; それぞれ<<変更@>>〜<<変更B>>で示してあります。 ; ;-------------------------------------------------------------------- INCLUDE(YIDESYM.DEF) ; STACK_SIZE HEAP_SIZE STRUCT_SIZEの読み込み IFDEF __YIDE_ROM_DEBUG__ DEFLIB(ROM-MON\H8300H\MONRH8.LIB) ;ROMデバッグモニタの指定 ENDIF ;==================================================================== ; I/Oアドレスの定義 ; H8/3048以外のCPUの場合はIOアドレスを確認してください。 ;==================================================================== ;SCI0 SMR0 EQU H'FFFFB0 BRR0 EQU H'FFFFB1 SCR0 EQU H'FFFFB2 TDR0 EQU H'FFFFB3 SSR0 EQU H'FFFFB4 RDR0 EQU H'FFFFB5 ;SCI1 SMR1 EQU H'FFFFB8 BRR1 EQU H'FFFFB9 SCR1 EQU H'FFFFBA TDR1 EQU H'FFFFBB SSR1 EQU H'FFFFBC RDR1 EQU H'FFFFBD ;インタラプトプライオリティレベルレジスタB IPRB EQU H'FFFFF9 ;==================================================================== ; シリアルチャンネルの割り当て ; ユーザが自由に割り当てることができます。 ;==================================================================== ;デバッグ用シリアルチャンネルの割り当て ;デバッグ用シリアルチャンネルはフラッシュの書込みチャンネルと ;同一にすると便利です。 ;<<変更@>> DEFINE DBG_SCI 1 ;<- チャンネル1に割り当て この例ではSCI1 ;なお、上記の設定はROMデバッグ、およびROM化の時のみ有効です。 ;RAMへダウンロードする場合はダウンローダがシリアルの設定をします。 ;リモートデバッグの時はモニタがシリアルの設定をします。 ;従って、RAMへダウンロードおよびリモートデバッグの時はここで ;デバッグ用シリアルチャンネルを変更することはできません。 ;std_sioの割り当て fgetc(std_sio1)、fprintf(std_sio1, ...)などの入出力先 DEFINE STD_SIO1 SMR0 ; <- デバッグ用SCI以外ならどのチャンネルも可能 DEFINE STD_SIO2 SMR0 ; <- デバッグ用SCI以外ならどのチャンネルも可能 DEFINE STD_SIO3 SMR0 ; <- デバッグ用SCI以外ならどのチャンネルも可能 DEFINE STD_SIO4 SMR0 ; <- デバッグ用SCI以外ならどのチャンネルも可能 DEFINE STD_SIO5 SMR0 ; <- デバッグ用SCI以外ならどのチャンネルも可能 IF (DBG_SCI==0) DEFINE DBG_SMR SMR0 DEFINE DBG_BRR BRR0 DEFINE DBG_SCR SCR0 DEFINE DBG_TDR TDR0 DEFINE DBG_SSR SSR0 DEFINE DBG_RDR RDR0 ENDIF IF (DBG_SCI==1) DEFINE DBG_SMR SMR1 DEFINE DBG_BRR BRR1 DEFINE DBG_SCR SCR1 DEFINE DBG_TDR TDR1 DEFINE DBG_SSR SSR1 DEFINE DBG_RDR RDR1 ENDIF ;==================================================================== ; ボーレートの設定 ; 以下の表をもとにBRRレジスタに入れる値(BRR_CNT)を設定します。 ;==================================================================== ;クロック 9600bps 38400bps ;4 12 2 ;4.9152 15 3 ;6 19 4 ;7.3728 23 5 ;8 25 6 ;9.8304 31 7 ;10 32 7 ;11.0592 35 8 ;12 38 9 ;12.288 39 9 ;14 45 10 ;14.7456 47 11 ;16 51 12 ;17.2032 55 13 ;18 58 14 ;18.432 59 14 ;19.6608 63 15 ;20 64 15 ;22 71 17 ;22.1184 71 17 ;24 77 19 ;24.576 79 19 ;25.8048 83 20 ;26 84 20 ;27.0336 87 21 ;28 90 22 ;29.4912 95 23 ;30 97 23 ;31.9488 103 25 ;32 103 25 ;33 106 26 ;33.1776 107 26 ;<<<<<<<<<<<<<<<<<<<<クロックによって書き換えて下さい。>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;<<変更A>> DEFINE BRR_CNT 19 ;<- 24/25MHz で38400bpsの設定です。 ;DEFINE BRR_CNT 12 ; 16MHで38400bpsの設定です。 segment main ATR_CODE ;--------------------------------------------------------------------- ; 割込みベクタテーブル ;(変更しないで下さい) ;--------------------------------------------------------------------- ;-----割込みベクタテーブルはじまり----- __VECTDEF__ 0 , START ; リセットベクタ 変更しないで下さい INCLUDE(INTVECT.DEF) ;YellowIDEが自動生成する割込みベクタ IFDEF __YIDE_ROM_DEBUG__ ;デバッガが使う割込みベクタ 10 , syscall ; 変更しないでください 11 , break ; 変更しないでください 24 , adrs_break ; 変更しないでください IF (DBG_SCI==0) 53 , _sci_int ; SCI0受信割り込み 変更しないで下さい ENDIF IF (DBG_SCI==1) 57 , _sci_int ; SCI1受信割り込み 変更しないで下さい ENDIF ENDIF __VECTDEFEND__ ;-----------------ベクタテーブル終わり------------------------------- segment TEXT ATR_CODE PUBLIC START ;ベクタのpublic宣言は必ず必要 START: ; プログラムはここから始まる ;-------------------------------------------------------------------- ; スタックポインタの初期化 ;(変更しないで下さい) ;-------------------------------------------------------------------- MOV.L #STACK_TOP,ER7 ;--------------------------------------------------------------------- ; 割込み制御モードの設定 ; 割込み制御モードは1に設定されています。 ; それ以外にしたい場合は下記を変更して下さい。 ; ただし、ROMデバッグする場合は必ず1でなければなりません ;--------------------------------------------------------------------- SYSCR EQU H'FFFFF2 MOV.B @SYSCR,R0L AND.B #B'11110111,R0L MOV.B R0L,@SYSCR ;===================================================================== ; !!!!!!場合によって修正必須!!!!!! ; イエローソフトのCPUボード以外を使用される場合は修正 ; が必要です。 ; ; 外部メモリの設定 ; 下記の例はエリア1にバス幅8ビットのRAMが接続されている場合の例です ;===================================================================== ;アドレスバス ポート P1DDR EQU H'FFFFC0 P2DDR EQU H'FFFFC1 P5DDR EQU H'FFFFC8 P8DDR EQU H'FFFFCD ;バスコントローラ ABWCR EQU H'FFFFEC ASTCR EQU H'FFFFED WCR EQU H'FFFFEE WCER EQU H'FFFFEF IF ((DEFD __YIDE_ROM__) || (DEFD __YIDE_ROM_DEBUG__)) ;<- ROM化とROMデバッグ時のみ必要 ;<<変更B>> MOV.B #H'FF,R0L MOV.B R0L,@P1DDR ;ポートをアドレスバスとして使うため MOV.B R0L,@P2DDR ;P1,P2,P5を出力設定する MOV.B R0L,@P5DDR ;内蔵ROM起動モードでは必須 MOV.B #H'E8,R0L MOV.B R0L,@P8DDR ; CS1有効 ;MOV.B #B'11111101,R0L ;MOV.B R0L,@ASTCR ;2ステートアクセスの場合、コメントはずす MOV.B #0,R0L MOV.B R0L,@WCR ; RAM WAIT 禁止 WAIT挿入する場合はコメントに ;MOV.B #1,R0L ;MOV.B R0L,@WCR ; 1WAIT挿入する場合はコメントはずす ;BCLR.B #1,@ABWCR ;16ビットバス幅の場合、コメントはずす。 ENDIF ;===================================================================== ; デバッグ用シリアルの初期設定 ; ; シリアルを使う場合はシリアルの初期設定が必要です。 ; 特別な理由がない限り、特に変更の必要はありません。 ;===================================================================== IF ((DEFD __YIDE_ROM__) || (DEFD __YIDE_ROM_DEBUG__)) MOV.B #BRR_CNT,R0L MOV.B R0L,@DBG_BRR MOV.B #B'00000000,R0L MOV.B R0L,@DBG_SMR MOV.B #B'00110000,R0L ; 受信データフル割り込み禁止 MOV.B R0L,@DBG_SCR IF (DBG_SCI==0) BSET.B #3,@IPRB:8 ;割込みのレヴェルをあげる ENDIF IF (DBG_SCI==1) BSET.B #2,@IPRB:8 ENDIF ;しばらくウエイト MOV.W #1000,R0 wait_loop: DEC.W #1,R0 BNE wait_loop ENDIF ;---------- ユーザが変更するのはここまでです --------------------- ;---------- 以下のコードは変更の必要はありません -------------- ;-------------------------------------------------------------------- ; ヒープ領域の初期化 ; malloc等の関数を使用しないのであれば必要なし ;-------------------------------------------------------------------- IF HEAP_SIZE MOV.L #__Heapbase, ER0 MOV.W #(HEAP_SIZE + 6), R1 XOR.B R2L, R2L _loop1: MOV.B R2L, @ER0 INC.L #1, ER0 DEC.W #1, R1 BNE _loop1 ENDIF ;-------------------------------------------------------------------- ; DATAセグメントをROMからRAMにコピーする ;-------------------------------------------------------------------- IF ((DEFD __YIDE_ROM__) || (DEFD __YIDE_ROM_DEBUG__) || (DEFD __YIDE_SIM_DEBUG__)) EXTERN DATA_rom DATA_start DATA_size MOV.L #DATA_rom, ER0 ; コピー元アドレス MOV.L #DATA_start, ER1 ; コピー先アドレス MOV.L #DATA_size, ER2 ; コピーサイズ copy_loop: CMP.L #0,ER2 BEQ copy_loop_end MOV.B @ER0+, R3L MOV.B R3L, @ER1 INC.L #1, ER1 DEC.L #1, ER2 BRA copy_loop copy_loop_end: ENDIF ;--------------------------------------------------------------------- ; モニタをコール ;--------------------------------------------------------------------- IFDEF __YIDE_ROM_DEBUG__ extern monitor jsr @monitor ENDIF ;-------------------------------------------------------------------- ; main関数を呼ぶ ;-------------------------------------------------------------------- extern _main JSR @_main ;-------------------------------------------------------------------- ; mainから戻った後の処理 ; ラベル__exitは、exit、raise関数で必要 ;-------------------------------------------------------------------- public __exit __exit: IF ((DEFD __YIDE_REM_DEBUG__) || (DEFD __YIDE_ROM_DEBUG__) || (DEFD __YIDE_SIM_DEBUG__)) TRAPA #2 ; SYSTEM CALL DC.W 0c8h ; モニタへ戻る ENDIF BRA __exit ; return to monitor MOV R0L,@__dummy__ ;ダミー参照 ;==================================================================== ; TEXTセグメント (関数) ; スタックがオーバーフローした時の処理を書く ;==================================================================== segment TEXT ATR_CODE public _stack_over_task _stack_over_task: IF ((DEFD __YIDE_REM_DEBUG__) || (DEFD __YIDE_ROM_DEBUG__) || (DEFD __YIDE_SIM_DEBUG__)) MOV.L ER7,ER0 TRAPA #2 ;イエロースコープ使用時 DC.W 0cch ;モニタにスタックオーバフローを知らせる ENDIF ;------------------------------------------------------------------------ ;<- ここにポートを立てるとかの処理を書いて下さい。 ;------------------------------------------------------------------------ BRA __exit ;終了 ;注意 この関数はリターンできません。 ;-------------------------------------------------------------------- ; 標準入出力関数の入出力先の割り当て ;-------------------------------------------------------------------- segment DATA_CONST ATR_CDATA public __smr_adr __smr_adr: DC.L DBG_SMR ;stdin DC.L DBG_SMR ;stdout DC.L DBG_SMR ;stderr DC.L STD_SIO1 ;std_sio1 DC.L STD_SIO2 ;std_sio2 DC.L STD_SIO3 ;std_sio3 DC.L STD_SIO4 ;std_sio4 DC.L STD_SIO5 ;std_sio5 ;-------------------------------------------------------------------- ; DATA_CONSTセグメント (constがつくデータ) ;-------------------------------------------------------------------- segment DATA_CONST ATR_CDATA IF HEAP_SIZE public __HeapSize __HeapSize: dc.w HEAP_SIZE ENDIF public __dbg_flag IF ((DEFD __YIDE_REM_DEBUG__) || (DEFD __YIDE_ROM_DEBUG__)) __dbg_flag: dc.b 1 ELSE IFDEF __YIDE_SIM_DEBUG__ __dbg_flag: dc.b 3 ELSE __dbg_flag: dc.b 0 ENDIF ENDIF ;-------------------------------------------------------------------- ; DATAセグメント (constがつかないデータ) ;-------------------------------------------------------------------- segment DATA ATR_DATA IF RET_STRUCT_SIZE public __struct_ret __struct_ret: ds.b RET_STRUCT_SIZE ENDIF __dummy__: ds.b 1 ;ダミーデータ ;-------------------------------------------------------------------- ; BSSセグメント (初期化されないデータ) ;(変更しないで下さい) ;-------------------------------------------------------------------- segment BSS ATR_BSS ;-------------------------------------------------------------------- ; HEAPセグメント ; malloc等の関数を使用しないのなら、必要なし ;(変更しないで下さい) ;-------------------------------------------------------------------- segment HEAP ATR_BSS IF HEAP_SIZE public __Heapbase __Heapbase: ds.b HEAP_SIZE + 6 ; 6 = sizeof(HEADER) ENDIF ;-------------------------------------------------------------------- ; スタックセグメント ;-------------------------------------------------------------------- segment STACK ATR_BSS public _STACK_BTM DS.B 64 ;余裕分 _STACK_BTM: DS.B STACK_SIZE STACK_TOP: ;******************************************************************** ;*** 割込禁止 ;******************************************************************** public _di _di: ORC #H'80, CCR rts ;******************************************************************** ;*** 割込許可 ;******************************************************************** public _ei _ei: ANDC #H'7F, CCR rts ;******************************************************************** ;***** シリアルポートへの1バイト出力 ***** ;***** 引数 R0L 出力する1バイト ***** ;***** 戻り値 R0L 出力する1バイト ***** ;***** レジスタER6の値は壊さないでください ***** ;******************************************************************** segment TEXT public sio_out sio_out: BTST.B #7,@DBG_SSR:8 BEQ sio_out MOV.B R0L,@DBG_TDR:8 BCLR.B #7,@DBG_SSR:8 RTS ;******************************************************************** ;***** シリアルポートから1バイト入力 ***** ;***** 引数 なし ***** ;***** 戻り値 R0L 入力した1バイト ***** ;***** レジスタER6の値は壊さないでください ***** ;******************************************************************** segment TEXT public sio_in sio_in: MOV.B @DBG_SSR:8,R0L MOV.B R0L,R0H AND.B #B'01111000,R0L BEQ sio_in MOV.B @DBG_RDR:8,R0L AND.B #B'10000111,R0H MOV.B R0H,@DBG_SSR:8 SUB.B R0H,R0H RTS ;******************************************************************** ;***** 受信割り込み許可 ***** ;***** 受信割り込みを許可する命令を記述してください ***** ;******************************************************************** segment TEXT public ___mm_ei_sci_int ___mm_ei_sci_int: BSET #6, @DBG_SCR:8 RTS ;******************************************************************** ;***** 受信割り込み不許可 ***** ;***** 受信割り込みを不許可する命令を記述してください ***** ;******************************************************************** segment TEXT public ___mm_di_sci_int ___mm_di_sci_int: BCLR #6, @DBG_SCR:8 RTS ;******************************************************************** ;***** シリアルポートから1バイト入力(ポーリングなし) ***** ;***** 受信割り込みルーチンから呼ばれる ***** ;***** 引数 なし ***** ;***** 戻り値 R0L 入力した1バイト ***** ;***** レジスタER6の値は壊さないでください ***** ;******************************************************************** segment TEXT public load_rsin load_rsin: MOV.B @DBG_RDR:8 ,R0L ;1バイト入力 MOV.B @DBG_SSR:8 ,R0H ;各種フラグクリア AND.B #B'10000111,R0H MOV.B R0H,@DBG_SSR:8 RTS ;******************************************************************** ;***** 以下のコードはROMモニタ用のコードです。 ***** ;***** イエローソフトの指示なしに変更しないで下さい ***** ;******************************************************************** TSTR EQU H'FFFF60 TCR0 EQU H'FFFF64 TIER0 EQU H'FFFF66 TSR0 EQU H'FFFF67 TCNT0 EQU H'FFFF68 GRA0 EQU H'FFFF6A IPRA EQU H'FFFFF8 ;******************************************************************** ;***** タイマー割込みクリア ***** ;******************************************************************** segment TEXT public ___mm_timer_int_clr ___mm_timer_int_clr: MOV.B @TSR0:8,R0L AND.B #H'FE,R0L ;割込み要求フラグクリア MOV.B R0L,@TSR0:8 MOV.W #0,R0 MOV.W R0,@TCNT0:8 ;カウンタをクリア RTS ;******************************************************************** ;***** タイマーカウンタをストップ ***** ;******************************************************************** segment TEXT public ___mm_timer_count_stop ___mm_timer_count_stop: BCLR #0,@TSTR:8 ;カウンタを止める RTS ;******************************************************************** ;***** タイマーカウンタをスタート ***** ;******************************************************************** segment TEXT public ___mm_timer_count_start ___mm_timer_count_start: BSET #0,@TSTR:8 ;カウンタをスタート RTS ;******************************************************************** ;***** タイマー割込み初期化 ***** ;******************************************************************** segment TEXT public ___mm_init_timer_int ___mm_init_timer_int: ;RTS命令の実行時間を測定する MOV.W #0,R0 MOV.W R0,@TCNT0:8 ;カウンタをクリア MOV.L #___mm_init_timer_int2,ER0 PUSH.L ER0 ;戻り番地をスタックへ積む BSET #0,@TSTR:8 ;カウンタをスタート RTS ___mm_init_timer_int2: BCLR #0,@TSTR:8 ;カウンタをストップ MOV.W @TCNT0:8,R1 SUB.W #10,R1 ;BCLRのオーバヘッドは10サイクルだから10を引く SHLL.W R1 ;2倍する RTSおよびRTEでユーザプログラムへ戻るため MOV.W #0,R0 MOV.W R0,@TCNT0:8 ;カウンタをクリア ; RTS命令の実行時間測定終了 MOV.B #H'A0,R0L MOV.B R0L,@TCR0 ; GRAコンペアマッチでTCNTクリア 分周なし BSET.B #0,@TIER0:8 ; コンペアマッチA割込みイネーブル MOV.W R1,@GRA0 ; カウンタの設定 BSET.B #2,@IPRA:8 ; ITU0の割り込み優先順位を1に設定 RTS