; ***************************************************************
; Logi_picas 20211106
;  Language: PIC-AS (v2.32)
;            MPLABX (v5.50)
;
; MPLAB X IDE 設定の追加:
;     project properties ダイアログ pic-as Linker の
;     Custom linker options 欄に以下の2文を追加する
;        -pPor_Vec=0h   -pIsr_Vec=4h
; ***************************************************************
PROCESSOR 16F18326
a#include <xc.inc>

Cflag  equ  0x00
Zflag  equ  0x02
; *********************** Bank RAMエリア ************
;      CBLOCK   0x20   ; Bank 0x10  Linear 2500
bRxbuf0  equ  0x20    ; コマンド受信バッファ
bRxbuf1  equ  0x21
bRxbuf2  equ  0x22
bRxbuf3  equ  0x23
bRxbuf4  equ  0x24
bRxbuf5  equ  0x25
bRxbuf6  equ  0x26
iFSR0L   equ  0x27   ; 割込み処理で使用のFSR0 退避用
iFSR0H   equ  0x28   ; 割込み処理で使用のFSR0 退避用
bErr_Cmd equ  0x29   ; 受信文字列のエラー確認
;
; *********************** 共通RAMエリア **************
;   CBLOCK   0x70
cRxComd     equ  0x70   ; コマンド受信フラグ
cRxDATA     equ  0x71   ; 受信データ一時保管
cDATAptr    equ  0x72   ; メッセージ送信ポインタ
cTemp_1     equ  0x73   ; 共用変数メモリ
cTemp_2     equ  0x74   ; 共用変数メモリ
cTemp_3     equ  0x75   ; 共用変数メモリ
cFreRun     equ  0x76   ; フリーラン モード
cBfrAqH     equ  0x77   ; トリガ前収集数
cBfrAqL     equ  0x78   ; トリガ前収集数
cAftAqH     equ  0x79   ; トリガ後収集数
cAftAqL     equ  0x7A   ; トリガ後収集数
;
; *********************** config **************************
config FEXTOSC = OFF, RSTOSC = HFINT32, CLKOUTEN = OFF
config CSWEN = ON   , FCMEN = ON      , MCLRE = ON
config PWRTE = OFF  , WDTE = OFF      , LPBOREN = OFF
config BOREN = OFF  , BORV = LOW      , PPS1WAY = OFF
config STVREN = ON  , DEBUG = OFF     , WRT = OFF
config LVP = ON     , CP = OFF        , CPD = OFF

; 電源ONリセット 開始番地 ----------------
  PSECT   Por_Vec,class=CODE,delta=2
Start:
  GOTO  Main

;   割り込み処理 開始番地 ---------------
  PSECT   Isr_Vec,class=CODE,delta=2
IsrVec:
  MOVLB 0x10          ; Bank 16
  MOVF  iFSR0L, W     ; 割り込みに使用している
  MOVWF FSR0L         ; FSR0 の値をロード
  MOVF  iFSR0H, W
  MOVWF FSR0H

  MOVLB 0x0           ; Bank 0 PIR1
  BTFSS RCIF          ; uart 受信からの割り込みか
  GOTO  RTNINT        ; 受信で無いなら復帰
             ; 受信なら ------------------------
  MOVLB 0x3           ; Bank 3 RC1STA
  BTFSS OERR          ; OERR 受信エラーか
  GOTO RX_OK          ;   受信エラー無しなら
  BCF CREN            ;   エラーなら CREN OFF/ONで RC1STA
  BSF CREN            ;              エラークリア
  GOTO RTNINT         ;   復帰

             ; 正常受信なら -----------------------
RX_OK:
  MOVLB 0x3                 ; Bank 3
  MOVF  BANKMASK(RC1REG), W
  MOVWF cRxDATA             ; 受信データをRxDataに保管;
  XORLW 0x21                ;   '!' STOP か
  BTFSC STATUS, Zflag       ;   '!' なら Zflag
  GOTO  CASRST              ;   case re-startへ

  MOVF cRxDATA, W
  XORLW 0x0A             ;   'CR' か
  BTFSC STATUS, Zflag    ;   'CR' か
  GOTO C_CRLF            ;   case C_CRLFへ

  MOVF cRxDATA, W
  XORLW 0x0D             ;   'LF' か
  BTFSC STATUS, Zflag    ;   'LF' なら
  GOTO C_CRLF            ;   case C_CRLFへ
  GOTO C_OTHR

CASRST:
  RESET                   ; デバイスのリセット
  GOTO RTNINT
C_CRLF:
  MOVF FSR0L, W           ; 受信ポインタを W に
  XORLW 0x07              ; 受信データ数を
  BTFSC STATUS, Zflag     ; 確認
  BSF   cRxComd, 0        ;   7 ならフラグセット
  CLRF  FSR0L             ; 受信ポインタをリセット
  GOTO RTNINT
C_OTHR:
  MOVLW   0x07            ; Buff満杯か
  SUBWF   FSR0L, w        ;   ポインタを確認
  MOVF    cRxDATA, W      ; 受信データを W に
  BTFSS   STATUS, Cflag   ; 満杯でなければ
  MOVWF   INDF0           ;   Buffに保存
  INCF    FSR0L, F        ; 満杯でもポインタは進める
  GOTO    RTNINT
RTNINT:
  MOVLB 0x10         ; Bank 16
  MOVF  FSR0L, W     ; PUSH FSR0 退避する
  MOVWF iFSR0L
  MOVF  FSR0H, W
  MOVWF iFSR0H
  RETFIE

;void main =====================================
Main:
  MOVLB 0x1              ; Bank 1
  MOVLW 0x3F             ; 0b111111;
  MOVWF BANKMASK(TRISA)  ; すべて入力
  MOVLW 0x3F             ; 0b111111;
  MOVWF BANKMASK(TRISC)  ; Port すべて入力
  MOVLB 0x3              ; Bank 3
  CLRF BANKMASK(ANSELA)  ; すべてデジタル
  CLRF BANKMASK(ANSELC)  ; すべてデジタル
  MOVLB 0x4              ; Bank 4
  MOVLW 0xF              ; 0b001111;
  MOVWF BANKMASK(WPUA)   ; RA0-RA3 弱プルアップ ON
  MOVLW 0x20             ; 0b100000;
  MOVWF BANKMASK(WPUC)   ; RC5 弱プルアップ ON
  MOVLB 0x1C             ; Bank 1C
  MOVLW 0x4              ; RXPPS  = 0x04;
  MOVWF BANKMASK(RXPPS)  ; RA4->EUSART RX
  MOVLB 0x1D             ; Bank 1D
  MOVLW 0x14             ; RA5PPS = 0x14;
  MOVWF BANKMASK(RA5PPS)     ; RA5->EUSART TX
;
;//------------ Initialize timer 0 -------------------------------
  MOVLB 0x0                ; Bank 0x0 選択
  MOVLW 0x4D               ; 0b01001101;
  MOVWF BANKMASK(T0CON1)   ; Fosc/4 Sync PreS 1/8192
  CLRF  BANKMASK(T0CON0)   ; T0 OFF 8bit Post 1/1
  MOVLW 0xFF               ; TMR0 PR を FF にセット
  MOVWF BANKMASK(TMR0H)        ; TMR0H = 0xFF
;
;//------------ Initialize UART ----------------------------
  MOVLB 0x3                  ; Bank 3
  MOVLW 0x90                 ; 0b10010000;
  MOVWF BANKMASK(RC1STA)     ; 8 bit 連続受信
  MOVLW 0x24                 ; 0b00100100;
  MOVWF BANKMASK(TX1STA)     ; 非同期送受信 High Baud Rate選択
  MOVLW 0x8                  ; 0b00001000;
  MOVWF BANKMASK(BAUD1CON)   ; 115200 baud
  CLRF BANKMASK(SP1BRGH)     ; SP1BRGH  = 0;
  MOVLW 0x44
  MOVWF BANKMASK(SP1BRGL)    ; SP1BRG   = 68;

; CLC 設定 ------------------------------------
  MOVLB 0x1C                  ; Bank 0x1C
  MOVLW 0x10
  MOVWF BANKMASK(CLCIN0PPS)   ; RC0->CLCIN0
  MOVLW 0x11
  MOVWF BANKMASK(CLCIN1PPS)   ; RC1->CLCIN1
  MOVLW 0x12
  MOVWF BANKMASK(CLCIN2PPS)   ; RC2->CLCIN2
;// Set the CLC1
  MOVLB 0x1E                  ; Bank 0x1E
  MOVLW 0x2
  MOVWF BANKMASK(CLC1POL)     ; G2出力は負極性 他出力は正極性
  CLRF  BANKMASK(CLC1SEL0)    ; LC1D1S (CLCIN0PPS)
  MOVLW 0x1
  MOVWF BANKMASK(CLC1SEL1)    ; LC1D2S (CLCIN1PPS)
  MOVLW 0x2
  MOVWF BANKMASK(CLC1SEL2)    ; LC1D3S (CLCIN2PPS)
  MOVLW 0x18
  MOVWF BANKMASK(CLC1SEL3)    ; LC1D4S T0_overflow
  MOVLW 0x80
  MOVWF BANKMASK(CLC1GLS0)    ; G1D1-3 Vss G1D4 正接続
  MOVLW 0x2
  MOVWF BANKMASK(CLC1GLS1)    ; G2D1 負接続 G2D2-4 Vss
  CLRF  BANKMASK(CLC1GLS2)    ;  全てVss
  CLRF  BANKMASK(CLC1GLS3)    ;  全てVss
  MOVLW 0x84
  MOVWF BANKMASK(CLC1CON)     ;  1-input D ff
;// Set the CLC2
  MOVLW 0x2
  MOVWF BANKMASK(CLC2POL)
  CLRF  BANKMASK(CLC2SEL0)
  MOVLW 0x4
  MOVWF BANKMASK(CLC2SEL1)    ; LC1_out
  MOVLW 0x2
  MOVWF BANKMASK(CLC2SEL2)
  MOVLW 0x18
  MOVWF BANKMASK(CLC2SEL3)
  MOVLW 0x80
  MOVWF BANKMASK(CLC2GLS0)
  MOVLW 0x5           ; G1D1-2 正接続 G2D3-4 Vss
  MOVWF BANKMASK(CLC2GLS1)
  CLRF  BANKMASK(CLC2GLS2)
  CLRF  BANKMASK(CLC2GLS3)
  MOVLW 0x84
  MOVWF BANKMASK(CLC2CON)
; 変数初期設定 ------------------------------------
  CLRF   cRxComd     ; コマンド受信フラグ
  CLRF   cTemp_1

  MOVLB  0x10       ; Bank 16
  CLRF   iFSR0L     ; 受信ポインタ(FSR0退避)をリセット
  MOVLW  0x25
  MOVWF  iFSR0H
; UART Rx 割込みを使用許可
  MOVLB 0x1        ; Bank 1
  BSF RCIE         ; UART Rx 割込みを使用許可 PIE1
  BSF PEIE         ; 周辺機能割込みの使用許可 INTCON
  BSF GIE          ; 全割込みの使用許可 INTCON
;   !!\r\n   準備完了を送信
  CLRW
  CALL PRINT_MSG
;    // ----------- メイン 繰返し ---------------------
LOOP:
  BTFSS  cRxComd, 0   ; コマンドを受信したか
  GOTO   LOOP         ;   否 繰返しに戻る
  BCF    cRxComd, 0   ; フラグ クリア
  call   CkValidity
  MOVLB  0x10         ; Bank 16 設定
  BTFSS  bErr_Cmd, 0
  goto   Cmd_OK
Cmd_NG:
  movlw  0x1         ; コマンドエラー検知
  call   PRINT_MSG   ; 1 ![CRLF]を送信
  goto   LOOP        ; コマンド受信待ちへ
Cmd_OK:
  MOVLW  0x6             ; コマンド OK
  call   PRINT_MSG       ;  #[CRLF]を送信
  CALL   SetTrigger      ; トリガ条件の設定
  call   SetSampRate     ; サンプルレートの設定
  CALL   SetTrgPosition  ; トリガ位置の設定
  CALL   Aquition        ; データの取得
  CALL   OutAqData       ; データの送信
  GOTO   LOOP            ; LOOP を繰り返す


; ***********************************************
cTstNum   equ   cTemp_1              ; テスト文字変換数値
PrePtn    equ   BANKMASK(CLC1GLS1)   ; CLC1 Gate2 入力
PstPtn    equ   BANKMASK(CLC2GLS1)   ; CLC2 Gate2 入力
TrgChn    equ   BANKMASK(CLC2SEL0)   ; CLC2 入力1 選択

; // ----------- 各ChのTrigger条件設定 --------
SetTrigger:
  MOVLW 0x25      ; FSR0 にBank RAM番地
  MOVWF FSR0H     ; 設定し受信データ取得
  MOVLW 0x03      ; FSR0 = 2503
  MOVWF FSR0L     ; 3chから処理開始
  MOVLB 0x1E      ; CLC ファイルの Bank
  CLRF  PrePtn    ; CLC1 Gate2 入力 クリア
  CLRF  PstPtn    ; CLC2 Gate2 入力 クリア
  CLRF  TrgChn    ; CLC2 入力1 選択  クリア
TrgDo:
  LSLF  PrePtn, F  ; PrePtnを左シフト
  LSLF  PrePtn, F  ; PrePtnを左シフト
  MOVIW FSR0--     ; 設定文字を取得
  ANDLW 0x07       ; 設定文字を数値に変換
  MOVWF cTstNum    ; 設定数値を保存
  ; 立上り の設定
  CALL   PreData       ; PreData取得
  IORWF  PrePtn, F     ; PrePtnに結合
  ; PrePtn の設定
  MOVF  cTstNum, W     ; 処理する数値を取得
  xorlw 0x3            ; 立上り'3'指定か
  btfss STATUS, Zflag  ;   立上りはスキップ
  goto  TgCk4          ; 異なれば、次
  movlw 0x05           ; Ch CLC1out 反転入力
  movwf PstPtn         ; CLC2 Gate2 入力 に設定
  movf  FSR0L, W       ; Ch番号 - 1
  movwf TrgChn         ; CLC2 入力1 選択に設定
TgCk4:  ; 立下り の設定
  MOVF  cTstNum, W     ; 処理する数値を取得
  xorlw 0x4            ; 立下り'4'指定か
  btfss STATUS, Zflag
  goto  TgCkNx
  movlw 0x06
  movwf PstPtn
  movf  FSR0L, W
  movwf TrgChn
TgCkNx: ; Ch処理の終了か
  MOVF  FSR0L, F       ; 次処理Chを取得
  BTFSS STATUS, Zflag  ;   ch 0 で終了
  GOTO  TrgDo          ; 0 でなければ次のchを処理
  return
PreData:
  BRW
  IRP number,0,1,2,2,1
  retlw number
  ENDM
;
; // ----------- サンプルレート設定 --------------
;       TMR0 の プリスケラーとPR(TMR0H) を設定する
; // -------------------------------------------
SetSampRate:
  MOVLB  0x10               ; Bank 16
  MOVF   bRxbuf5, W         ; 受信データSampRateを取得
  ANDLW  0x0F               ; 設定文字を数値に変換
  MOVWF  cTstNum            ; 設定数値を保存
  call   T0_CON1            ; T0CON1設定値に変換
  MOVLB  0x0                ; Bank 0
  MOVWF  BANKMASK(T0CON1)   ; T0CON1設定を保存
  movf   cTstNum, W         ; 設定数値を取得
  call   TMR0_H             ; TMR0H設定値に変換
  MOVWF  BANKMASK(TMR0H)    ; TMR0H設定を保存
  RETURN
T0_CON1:     ; サンプルレート毎の T0CON1 設定値
  BRW       ; 1us,   2,   5,  10,  20,  50, 100, 200, 500, 1ms
  IRP number,0x40,0x40,0x40,0x43,0x43,0x43,0x43,0x43,0x45,0x45
  retlw number
  ENDM
TMR0_H:      ; サンプルレート毎の TMR0H 設定値
  BRW       ; 1us,   2,   5,  10,  20,  50, 100, 200, 500, 1ms
  IRP number,0x7, 0xF,0x27, 0x9,0x13,0x31,0x63,0xC7,0x7C,0xF9
  retlw number
  ENDM

; =========================================
; トリガ前後の収集数を設定
;        cBfrAqH  cBfrAqL      ; トリガ前収集数
;        cAftAqH  cAftAqL      ; トリガ後収集数
;        フリーラン時は cFreRun [1]にする
; =========================================
SetTrgPosition:
  clrf   cFreRun      ; フリーラン解除
  MOVLB  0x10         ; Bank 16
  movf   bRxbuf6, W
  ANDLW  0x07         ; 設定文字を数値に変換
  MOVWF  cTstNum      ; 設定数値を保存
  call   Bfr_AqH      ; cBfrAqH 設定値に変換保存
  MOVWF  cBfrAqH      ;
  movf   cTstNum, W   ; 設定数値を取得
  call   Bfr_AqL      ; cBfrAqL 設定値に変換保存
  MOVWF  cBfrAqL      ;
  movf   cTstNum, W   ; 設定数値を取得
  call   Aft_AqH      ; cAftAqH 設定値に変換保存
  MOVWF  cAftAqH      ;
  movf   cTstNum, W   ; 設定数値を取得
  call   Aft_AqL      ; cAftAqL 設定値に変換保存
  MOVWF  cAftAqL      ;
  movf   cTstNum, W   ; 設定数値を取得
  xorlw  0x03
  BTFSC  STATUS, Zflag   ; フリーラン なら
  bsf    cFreRun, 0      ; フリーランフラグ設定
  RETURN

Bfr_AqH:     ; トリガ前データ取得 パス 設定値
  BRW  ;        前,   1,   2,Free,中央,  後
  IRP number, 0x01,0x01,0x01,0x04,0x03,0x04
  retlw number
  ENDM
Bfr_AqL:     ; トリガ前データ取得 端数 設定値
  BRW  ;       前,   1,   2,Free,中央,  後
  IRP number,0x64,0x01,0x01,0x00,0x26,0xE8
  retlw number
  ENDM
Aft_AqH:     ; トリガ後データ取得 パス 設定値
  BRW       ;  前,   1,   2,Free,中央,  後
  IRP number,0x04,0x08,0x0C,0x01,0x02,0x01
  retlw number
  ENDM
Aft_AqL:     ; トリガ後データ取得 端数 設定値
  BRW   ;      前,   1,   2,Free,中央,  後
  IRP number,0x9C,0x84,0x6C,0x01,0xDA,0x18
  retlw number
  ENDM

; データ収集 ===============================================
Aquition:
  MOVLB 0x0        ; Bank 0x0 設定 T0CON0
  BSF  T0EN        ; Timer1スタート
  MOVLW  0x20      ; FSR0 に番地設定
  MOVWF  FSR0H
  MOVLW  0x00
  MOVWF  FSR0L
  MOVLB 0x0          ; Bank 0x0 設定 PIR0
  BCF   TMR0IF       ; TMR0IF リセット

; -------------- トリガ前保存 および FreeRun --------------
BfrTrg:
  BTFSS  TMR0IF       ; 取得タイミングを待つ
  GOTO   BfrTrg
  BCF    TMR0IF        ; TMR0IF リセット
  MOVF   PORTC, W      ; PORTC 取得
  MOVWI  FSR0++        ; データを保存
  movlw  0x23          ; リングバッファ
  andwf  FSR0H, f      ; のための処理
  DECFSZ cBfrAqL, F    ; 保存数を確認
  GOTO   BfrTrg        ;   端数を確認
  DECFSZ cBfrAqH, F    ;   パス数を確認
  GOTO   BfrTrg
  BTFSC cFreRun, 0     ; cFreRun なら
  RETURN               ; FreeRun時は、収集完了

; ---------------- トリガ条件の確認 ------------------
WatTrg:
  MOVLB 0x0         ; Bank 0x0 設定
WaitTm:
  BTFSS TMR0IF      ; 取得タイミングを
  GOTO  WaitTm      ;   待つ
  BCF TMR0IF        ; TMR0IF リセット
  MOVF   PORTC, W   ; PORTC 取得
  MOVWI  FSR0++     ; データを保存
  movlw  0x23       ; リングバッファ
  andwf  FSR0H, f   ; のための処理
  MOVLB 0x1E        ; Bank 0x1E 設定 CLC2CON
  BTFSS  LC2OUT     ;  LC2OUT 確認
  GOTO   WatTrg
  MOVLB  0x0        ; Bank 0x0 設定

; -------------- トリガ後保存 -------------------------
AftTrg:
  BTFSS  TMR0IF           ; 取得タイミングを PIR0
  GOTO   AftTrg           ;    待つ
  BCF    TMR0IF           ; TMR0IF リセット
  MOVF   PORTC, W         ; PORTC 取得
  MOVWI  FSR0++           ; データを保存
  movlw  0x23             ; リングバッファ
  andwf  FSR0H, f         ; のための処理
  DECFSZ cAftAqL, F       ; 保存数を循環
  GOTO   AftTrg
  DECFSZ cAftAqH, F
  GOTO   AftTrg
  RETURN                ; 収集完了

;--------------------------------------------------
; 収集データを送信
;   ESR0 に、送信開始あそれえ雨を持っている
;   cTemp_1 cTemp_2 に
;--------------------------------------------------
OutAqData:
  MOVLW  0x40       ; 行の文字数を
  MOVWF  cTemp_1    ;   64文字に設定
  MOVLW  0x10       ; 行数を16行にし
  MOVWF  cTemp_2    ;   64 x 16行 = 1024
OutAq1:
  moviw  FSR0++     ; データを読み
  ANDLW  0x1F       ; 不要ビットを削除
  IORLW  0x40       ; @ からの文字に変換
  call   PUTCH      ; === 一文字出力 ===
  movlw  0x23       ; FSR0 の
  andwf  FSR0H, f   ;   リングバッファ処理
  DECFSZ cTemp_1, F ; 64文字送信したか
  GOTO   OutAq1     ;   まだなら戻る
  MOVLW  0x40       ; 次の準備で
  MOVWF  cTemp_1    ;   cTemp_1 初期化
  MOVLW  0x2        ; 行末の
  call   PRINT_MSG  ;   CRLFを送信
  DECFSZ cTemp_2, F ; 16行送信したか
  GOTO   OutAq1     ;   まだなら戻る
  MOVLW  0x5        ; データ送信完了したので
  call   PRINT_MSG  ; ##[CRLF]を送信
  RETURN

;--------------------------------------------------
; コマンドを処理
;
;--------------------------------------------------
CkValidity:
  MOVLB  0x10          ; Bank 16
  bsf    bErr_Cmd, 0   ;  エラー『有』に設定
CkCha0:
  MOVF   bRxbuf0, W    ; 受信データ1を取得
  XORLW  '#'
  BTFSS  STATUS, Zflag     ; '#' か
  RETURN                   ;  否 ならエラーで復帰
CkCha4:
  MOVF   bRxbuf4, W        ; 受信データ1を取得
  XORLW  '#'
  BTFSS  STATUS, Zflag     ; '#' か
  RETURN                   ;  否 ならエラーで復帰

  clrf   bErr_Cmd          ;  エラー『無』に設定
  movlw  0x5               ; 5 以上はエラー
  movwf  cTemp_1
  MOVF   bRxbuf1, W    ; 受信データ1を取得
  call   CkRange
  MOVF   bRxbuf2, W    ; 受信データ2を取得
  call   CkRange
  MOVF   bRxbuf3, W    ; 受信データ3を取得
  call   CkRange
  movlw  0xA           ; A 以上はエラー
  movwf  cTemp_1
  MOVF   bRxbuf5, W    ; 受信データ5を取得
  call   CkRange
  movlw  0x6           ; 6 以上はエラー
  movwf  cTemp_1
  MOVF   bRxbuf6, W    ; 受信データ6を取得
  call   CkRange
  RETURN                ;  復帰

CkRange:  ; 上下限を確認し、超えていればエラービットをセット
  sublw  0x2F             ; L - W 下限確認 0以上でOK
  BTFSC  STATUS, Cflag    ; 引くことができれば C set
  GOTO   Rerror           ; エラー
  addwf  cTemp_1, w       ; 上限確認 
  BTFSS  STATUS, Cflag    ; 引くことができれば C set
Rerror:
  bsf  bErr_Cmd, 0        ; エラービットをセット
  return


;--------------------------------------------------
; 送信
;   WREG に送信する文字の先頭番号を持ってCALL
;--------------------------------------------------
PRINT_MSG:
  MOVWF   cDATAptr     ; 文字INDEXを 設定
P_NEXT:
  MOVF    cDATAptr,W   ; 文字INDEXを W に取得
  CALL    MSG_DT         ; 文字を W に取得
  MOVF    WREG,F         ; 文字終端かテスト
  BTFSC   STATUS, Zflag  ; 終端文字なら
  RETURN                 ;   リターン
  ; 送信する文字なら
  CALL    PUTCH          ;   一文字出力
  ; 次の文字を準備
  INCF    cDATAptr,F     ;   文字INDEXを +1
  GOTO    P_NEXT         ;   次の文字へ
MSG_DT:
  BRW    ;    !    !    \r   \n ,0x00, #    #    \r   \n ,0x00
  IRP number,0x21,0x21,0x0A,0x0D,0x00,0x23,0x23,0x0A,0x0D,0x00
  retlw number
  ENDM

;--------------------------------------------------
;   一文字出力 WREG に送信する文字を持ってCALL
;--------------------------------------------------
PUTCH:
  MOVLB   0x0               ; BANK 0 を選択 PIR1
W_TXIF:
  BTFSS  TXIF               ; 送信終了待ち
  GOTO    W_TXIF
  MOVLB   0x3               ; BANK 3 選択
  MOVWF   BANKMASK(TX1REG)  ; 文字出力
  RETURN

  END   Start