;===============================================================================
;
;       PD4435表示テスト
;
;               Author          : K.Takahashi(tokoya)
;               Version         : 0.1
;               Last Update     : 2002/01/25
;               Target          : AT90S2313
;               Comment         : 外部クロック4MHz使用
;
;       2002/01/21      : 初版
;       2002/01/25      : BLINK/CURSOR機能に対応
;
;===============================================================================

.include "2313def.inc"

.def    tp_0            = r16                                   ; ワーク0
.def    tp_1            = r17                                   ; ワーク1
.def    tp_send         = r18
.def    receive_cmd     = r19
.def    disp_addr       = r20
.def    disp_char       = r21
.def	bright_mode	= r22
.def	attr_addr	= r23
.def	attr_mode	= r24

.equ    A0              = 2
.equ    A1              = 3
.equ    A2              = 4
.equ    WR              = 5

.equ	ATTR_ENABLE	= 4

.DSEG
.ORG	$60
;---------------------------------------
;	SRAM
;---------------------------------------
DIGIT_BUF:	.byte	4
		
.CSEG
.ORG    $0
                rjmp    RESET
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    UART_RXC                                ; シリアル受信割り込み
                rjmp    DUMMY
                rjmp    DUMMY
                rjmp    DUMMY

DUMMY:
                reti

;---------------------------------------
;       初期化
;---------------------------------------
RESET:
                ldi     tp_0,low(RAMEND)                        ; スタックポインタ設定
                out     SPL,tp_0
        
                ldi     tp_0,0b11111111                         ; ポートＢを出力に設定
                out     DDRB,tp_0
                ldi     tp_0,0b00000000
                out     PORTB,tp_0

                ldi     tp_0,0b01111111                         ; ポートＤを出力に設定
                out     DDRD,tp_0

                ldi     tp_0,0b00111100                         ; PD2～PD5をHにしておく
                out     PORTD,tp_0

                ldi     tp_0,(1<<RXCIE)|(1<<RXEN)|(1<<TXEN)     ; 送受信許可、受信割り込み許可
                out     UCR,tp_0        
                ldi     tp_0,25                                 ; クロック4MHz時のUBRR値(9600bps)
                out     UBRR,tp_0

		clr	tp_0
		sts	DIGIT_BUF,tp_0
		sts	DIGIT_BUF+1,tp_0
		sts	DIGIT_BUF+2,tp_0
		sts	DIGIT_BUF+3,tp_0

                ldi     bright_mode,0b00000011
                clr	attr_mode
                rcall   SET_CONTROL
                rcall   CLEAR
                
                clr     disp_addr
                ldi     disp_char,'R'
                rcall   SET_DIGIT
                inc     disp_addr
                ldi     disp_char,'D'
                rcall   SET_DIGIT
                inc     disp_addr
                ldi     disp_char,'Y'
                rcall   SET_DIGIT
                inc     disp_addr
                ldi     disp_char,'!'
                rcall   SET_DIGIT

                clr     disp_addr
                clr     receive_cmd

                sei                                             ; 割り込み許可

;---------------------------------------
;       メインループ
;---------------------------------------
MAIN:
                rjmp    MAIN    

;---------------------------------------
;       送信
;---------------------------------------
SEND:
                sbis    USR,UDRE                                ; 送信終了まで待つ
                rjmp    SEND
                out     UDR,tp_send
                ret

;---------------------------------------
;       シリアル受信割り込み
;---------------------------------------
UART_RXC:
                in      r0,SREG                                 ; SREGレジスタを待避する
                push    r0
                push    tp_0

                in      tp_0,UDR                                ; 受信文字を取り出す
                mov     tp_send,tp_0
                rcall   SEND                                    ; エコーバック
                tst     receive_cmd                                ; コマンド受信済み？
                breq    UART_RXC_0
                rjmp    CMD_RX
UART_RXC_0:
                mov     receive_cmd,tp_0
                cpi     tp_0,'B'                                ; ブライトネス設定
                brne    UART_RXC_1
                rjmp    UART_RXC_EXIT
UART_RXC_1:
                cpi     tp_0,'A'                                ; アドレス設定
                brne    UART_RXC_2
                rjmp    UART_RXC_EXIT
UART_RXC_2:
                cpi     tp_0,'D'                                ; データ設定
                brne    UART_RXC_3
                rjmp    UART_RXC_EXIT
UART_RXC_3:
                cpi     tp_0,'C'                                ; クリア
                brne    UART_RXC_4
                rcall   CLEAR
                clr	receive_cmd
                rjmp    UART_RXC_EXIT
UART_RXC_4:
                cpi     tp_0,'N'                                ; アトリビュートON
                brne    UART_RXC_5
                rjmp    UART_RXC_EXIT
UART_RXC_5:
                cpi     tp_0,'F'                                ; アトリビュートOFF
                brne    UART_RXC_6
                rjmp    UART_RXC_EXIT
UART_RXC_6:
                cpi     tp_0,'M'                                ; アトリビュートモード
                brne    UART_RXC_7
                rjmp    UART_RXC_EXIT
UART_RXC_7:
                clr	receive_cmd
UART_RXC_EXIT:
                pop     tp_0
                pop     r0                                      ; SREGレジスタを復帰する
                out     SREG,r0
                reti                                            ; 割り込みから戻る

;---------------------------------------
;       コマンド受信＆実行
;---------------------------------------
CMD_RX:
                cpi     receive_cmd,'B'                            ; ブライトネス設定
                breq    CMD_RX_0
                cpi     receive_cmd,'A'                            ; アドレス設定
                breq    CMD_RX_1
                cpi     receive_cmd,'D'                            ; データ設定
                breq    CMD_RX_2
                cpi     receive_cmd,'N'                            ; アトリビュートON
                breq    CMD_RX_3
                cpi     receive_cmd,'F'                            ; アトリビュートOFF
                breq    CMD_RX_4
                cpi     receive_cmd,'M'                            ; アトリビュートモード設定
                breq    CMD_RX_5
                rjmp    CMD_RX_EXIT
CMD_RX_0:
                andi    tp_0,0b00000011                         ; 下2ビットのみ有効
                mov     bright_mode,tp_0
                rcall   SET_CONTROL
                rjmp    CMD_RX_EXIT
CMD_RX_1:
                andi    tp_0,0b00000111                         ; 下3ビットのみ有効
                mov     disp_addr,tp_0
                rjmp    CMD_RX_EXIT
CMD_RX_2:
                mov     disp_char,tp_0
                rcall   SET_DIGIT
                rjmp    CMD_RX_EXIT
CMD_RX_3:
                andi    tp_0,0b00000011                         ; 下2ビットのみ有効
                mov	attr_addr,tp_0
		rcall	SET_ATTR_ON
                rjmp    CMD_RX_EXIT
CMD_RX_4:
                andi    tp_0,0b00000011                         ; 下2ビットのみ有効
                mov	attr_addr,tp_0
		rcall	SET_ATTR_OFF
                rjmp    CMD_RX_EXIT
CMD_RX_5:
		andi	tp_0,0b00000111				; 下3ビットのみ有効(0～4)
		brne	CMD_RX_6
		clr	attr_mode
		rcall	SET_CONTROL
                rjmp    CMD_RX_EXIT
CMD_RX_6:
		dec	tp_0
		cpi	tp_0,4
		brge	CMD_RX_EXIT
		andi	tp_0,0b00000011
		lsl	tp_0
		lsl	tp_0
		mov	attr_mode,tp_0		
		sbr	attr_mode,(1<<ATTR_ENABLE)
		rcall	SET_CONTROL
                rjmp    CMD_RX_EXIT
CMD_RX_EXIT:
                clr     receive_cmd
                rjmp    UART_RXC_EXIT

;---------------------------------------
;       全デジットクリア
;---------------------------------------
CLEAR:
                ldi     disp_addr,0
                ldi     disp_char,0x20
                rcall   SET_DIGIT
                inc     disp_addr
                rcall   SET_DIGIT
                inc     disp_addr
                rcall   SET_DIGIT
                inc     disp_addr
                rcall   SET_DIGIT
                ret

;---------------------------------------
;       コントロールコマンド設定
;---------------------------------------
SET_CONTROL:
		mov	tp_0,attr_mode
                or     	tp_0,bright_mode
                out     PORTB,tp_0
                ldi     tp_0,0b00000000                         ; WR=L
                out     PORTD,tp_0
                nop
                nop
                nop
                nop
                sbi     PORTD,WR                                ; WR=H
                ret
        
;---------------------------------------
;       文字表示
;---------------------------------------
SET_DIGIT:
		ldi	ZH,high(DIGIT_BUF)			; 出力文字を保存
		ldi	ZL,low(DIGIT_BUF)
                mov     tp_0,disp_addr
                add	ZL,tp_0
		ld	tp_1,Z
		andi	tp_1,0b10000000
		or	tp_1,disp_char
		st	Z,tp_1
SET_DIGIT_0:
                com     tp_0					; A0～A2は負論理なので反転
                andi    tp_0,0b00000111				; 下位3ビットのみ有効
                lsl     tp_0					; PD2～PD4に合わせるため2ビット左シフト
                lsl     tp_0
                out     PORTB,tp_1				; 文字コードセット
                out     PORTD,tp_0				; アドレスセット(WR=L)
                nop
                nop
                nop
                nop
                sbi     PORTD,WR				; WR=H
                ret

;---------------------------------------
;       アトリビュートON
;---------------------------------------
SET_ATTR_ON:
		ldi	ZH,high(DIGIT_BUF)			; 出力文字を保存
		ldi	ZL,low(DIGIT_BUF)
                mov     tp_0,attr_addr
                add	ZL,tp_0
		ld	tp_1,Z
		ori	tp_1,0b10000000				; D7=H
		st	Z,tp_1
		rjmp	SET_DIGIT_0

;---------------------------------------
;       アトリビュートOFF
;---------------------------------------
SET_ATTR_OFF:
		ldi	ZH,high(DIGIT_BUF)			; 出力文字を保存
		ldi	ZL,low(DIGIT_BUF)
                mov     tp_0,attr_addr
                add	ZL,tp_0
		ld	tp_1,Z
		andi	tp_1,0b01111111				; D7=L
		st	Z,tp_1
		rjmp	SET_DIGIT_0
